Merge remote branch 'origin/master' into glsl2
authorEric Anholt <eric@anholt.net>
Tue, 27 Jul 2010 00:47:59 +0000 (17:47 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 27 Jul 2010 00:53:27 +0000 (17:53 -0700)
This pulls in multiple i965 driver fixes which will help ensure better
testing coverage during development, and also gets past the conflicts
of the src/mesa/shader -> src/mesa/program move.

Conflicts:
src/mesa/Makefile
src/mesa/main/shaderapi.c
src/mesa/main/shaderobj.h

913 files changed:
Makefile
SConstruct
common.py
configs/autoconf.in
configs/default
configure.ac
docs/egl.html
docs/relnotes-7.9.html
include/EGL/eglext.h
include/EGL/eglplatform.h
include/GL/glx.h
include/GL/internal/dri_interface.h
scons/gallium.py
src/driclient/src/XF86dri.c
src/egl/drivers/dri2/Makefile
src/egl/drivers/dri2/egl_dri2.c
src/egl/drivers/glx/egl_glx.c
src/egl/main/Makefile
src/egl/main/SConscript
src/egl/main/eglapi.c
src/egl/main/eglarray.c [new file with mode: 0644]
src/egl/main/eglarray.h [new file with mode: 0644]
src/egl/main/eglconfig.c
src/egl/main/egldisplay.c
src/egl/main/egldisplay.h
src/egl/main/egldriver.c
src/egl/main/egldriver.h
src/egl/main/eglglobals.c
src/egl/main/eglglobals.h
src/egl/main/eglmisc.c
src/egl/main/eglmode.c
src/egl/main/eglscreen.c
src/egl/main/egltypedefs.h
src/gallium/Makefile.template
src/gallium/auxiliary/Makefile
src/gallium/auxiliary/SConscript
src/gallium/auxiliary/cso_cache/cso_context.c
src/gallium/auxiliary/draw/draw_context.c
src/gallium/auxiliary/draw/draw_context.h
src/gallium/auxiliary/draw/draw_llvm.c
src/gallium/auxiliary/draw/draw_llvm.h
src/gallium/auxiliary/draw/draw_llvm_sample.c [new file with mode: 0644]
src/gallium/auxiliary/draw/draw_llvm_translate.c
src/gallium/auxiliary/draw/draw_pipe.c
src/gallium/auxiliary/draw/draw_pipe_aaline.c
src/gallium/auxiliary/draw/draw_pipe_clip.c
src/gallium/auxiliary/draw/draw_pipe_pstipple.c
src/gallium/auxiliary/draw/draw_pipe_wide_point.c
src/gallium/auxiliary/draw/draw_private.h
src/gallium/auxiliary/draw/draw_pt.c
src/gallium/auxiliary/draw/draw_pt.h
src/gallium/auxiliary/draw/draw_pt_fetch.c
src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
src/gallium/auxiliary/draw/draw_pt_fetch_shade_emit.c
src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
src/gallium/auxiliary/draw/draw_pt_post_vs.c
src/gallium/auxiliary/draw/draw_pt_varray.c
src/gallium/auxiliary/draw/draw_pt_vcache.c
src/gallium/auxiliary/draw/draw_vs.c
src/gallium/auxiliary/draw/draw_vs.h
src/gallium/auxiliary/draw/draw_vs_llvm.c [new file with mode: 0644]
src/gallium/auxiliary/gallivm/lp_bld_arit.c
src/gallium/auxiliary/gallivm/lp_bld_const.h
src/gallium/auxiliary/gallivm/lp_bld_conv.c
src/gallium/auxiliary/gallivm/lp_bld_format.h
src/gallium/auxiliary/gallivm/lp_bld_format_aos.c
src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c [new file with mode: 0644]
src/gallium/auxiliary/gallivm/lp_bld_gather.c [new file with mode: 0644]
src/gallium/auxiliary/gallivm/lp_bld_gather.h [new file with mode: 0644]
src/gallium/auxiliary/gallivm/lp_bld_init.c
src/gallium/auxiliary/gallivm/lp_bld_init.h
src/gallium/auxiliary/gallivm/lp_bld_logic.c
src/gallium/auxiliary/gallivm/lp_bld_pack.c
src/gallium/auxiliary/gallivm/lp_bld_pack.h
src/gallium/auxiliary/gallivm/lp_bld_quad.c
src/gallium/auxiliary/gallivm/lp_bld_sample.c
src/gallium/auxiliary/gallivm/lp_bld_sample.h
src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
src/gallium/auxiliary/gallivm/lp_bld_swizzle.c
src/gallium/auxiliary/gallivm/lp_bld_swizzle.h
src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
src/gallium/auxiliary/gallivm/lp_bld_type.h
src/gallium/auxiliary/os/os_thread.h
src/gallium/auxiliary/target-helpers/inline_debug_helper.h [new file with mode: 0644]
src/gallium/auxiliary/target-helpers/inline_sw_helper.h [new file with mode: 0644]
src/gallium/auxiliary/target-helpers/inline_wrapper_sw_helper.h [new file with mode: 0644]
src/gallium/auxiliary/tgsi/tgsi_dump.c
src/gallium/auxiliary/tgsi/tgsi_scan.c
src/gallium/auxiliary/tgsi/tgsi_scan.h
src/gallium/auxiliary/tgsi/tgsi_text.c
src/gallium/auxiliary/util/u_blitter.c
src/gallium/auxiliary/util/u_blitter.h
src/gallium/auxiliary/util/u_caps.c
src/gallium/auxiliary/util/u_cpu_detect.c
src/gallium/auxiliary/util/u_debug.c
src/gallium/auxiliary/util/u_double_list.h
src/gallium/auxiliary/util/u_format.c
src/gallium/auxiliary/util/u_format.h
src/gallium/auxiliary/util/u_format_table.py
src/gallium/auxiliary/util/u_math.h
src/gallium/auxiliary/util/u_mempool.c [new file with mode: 0644]
src/gallium/auxiliary/util/u_mempool.h [new file with mode: 0644]
src/gallium/auxiliary/util/u_network.c
src/gallium/docs/source/cso/blend.rst
src/gallium/docs/source/cso/velems.rst
src/gallium/docs/source/screen.rst
src/gallium/docs/source/tgsi.rst
src/gallium/drivers/galahad/Makefile [new file with mode: 0644]
src/gallium/drivers/galahad/SConscript [new file with mode: 0644]
src/gallium/drivers/galahad/glhd_context.c [new file with mode: 0644]
src/gallium/drivers/galahad/glhd_context.h [new file with mode: 0644]
src/gallium/drivers/galahad/glhd_objects.c [new file with mode: 0644]
src/gallium/drivers/galahad/glhd_objects.h [new file with mode: 0644]
src/gallium/drivers/galahad/glhd_public.h [new file with mode: 0644]
src/gallium/drivers/galahad/glhd_screen.c [new file with mode: 0644]
src/gallium/drivers/galahad/glhd_screen.h [new file with mode: 0644]
src/gallium/drivers/i915/Makefile
src/gallium/drivers/i915/SConscript
src/gallium/drivers/i915/i915_batch.h
src/gallium/drivers/i915/i915_batchbuffer.h
src/gallium/drivers/i915/i915_blit.c
src/gallium/drivers/i915/i915_context.h
src/gallium/drivers/i915/i915_debug.c
src/gallium/drivers/i915/i915_debug.h
src/gallium/drivers/i915/i915_debug_fp.c
src/gallium/drivers/i915/i915_debug_private.h [new file with mode: 0644]
src/gallium/drivers/i915/i915_flush.c
src/gallium/drivers/i915/i915_prim_vbuf.c
src/gallium/drivers/i915/i915_public.h [new file with mode: 0644]
src/gallium/drivers/i915/i915_resource_texture.c
src/gallium/drivers/i915/i915_screen.c
src/gallium/drivers/i915/i915_state.h
src/gallium/drivers/i915/i915_state_derived.c
src/gallium/drivers/i915/i915_state_dynamic.c
src/gallium/drivers/i915/i915_state_emit.c
src/gallium/drivers/i915/i915_state_fpc.c [new file with mode: 0644]
src/gallium/drivers/i915/i915_state_immediate.c
src/gallium/drivers/i915/i915_state_sampler.c
src/gallium/drivers/i915/i915_state_static.c [new file with mode: 0644]
src/gallium/drivers/i915/i915_winsys.h
src/gallium/drivers/i965/brw_public.h [new file with mode: 0644]
src/gallium/drivers/i965/brw_screen.c
src/gallium/drivers/i965/brw_winsys.h
src/gallium/drivers/i965/brw_wm_fp.c
src/gallium/drivers/identity/Makefile
src/gallium/drivers/identity/SConscript
src/gallium/drivers/identity/id_drm.c [deleted file]
src/gallium/drivers/identity/id_drm.h [deleted file]
src/gallium/drivers/identity/id_objects.c
src/gallium/drivers/identity/id_objects.h
src/gallium/drivers/llvmpipe/.gitignore
src/gallium/drivers/llvmpipe/Makefile
src/gallium/drivers/llvmpipe/SConscript
src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
src/gallium/drivers/llvmpipe/lp_bld_interp.c
src/gallium/drivers/llvmpipe/lp_context.h
src/gallium/drivers/llvmpipe/lp_draw_arrays.c
src/gallium/drivers/llvmpipe/lp_fence.c
src/gallium/drivers/llvmpipe/lp_fence.h
src/gallium/drivers/llvmpipe/lp_flush.c
src/gallium/drivers/llvmpipe/lp_jit.c
src/gallium/drivers/llvmpipe/lp_jit.h
src/gallium/drivers/llvmpipe/lp_memory.c [new file with mode: 0644]
src/gallium/drivers/llvmpipe/lp_memory.h [new file with mode: 0644]
src/gallium/drivers/llvmpipe/lp_perf.c
src/gallium/drivers/llvmpipe/lp_perf.h
src/gallium/drivers/llvmpipe/lp_query.c
src/gallium/drivers/llvmpipe/lp_rast.c
src/gallium/drivers/llvmpipe/lp_rast.h
src/gallium/drivers/llvmpipe/lp_rast_priv.h
src/gallium/drivers/llvmpipe/lp_rast_tri.c
src/gallium/drivers/llvmpipe/lp_rast_tri_tmp.h [new file with mode: 0644]
src/gallium/drivers/llvmpipe/lp_scene.c
src/gallium/drivers/llvmpipe/lp_scene.h
src/gallium/drivers/llvmpipe/lp_screen.c
src/gallium/drivers/llvmpipe/lp_screen.h
src/gallium/drivers/llvmpipe/lp_setup.c
src/gallium/drivers/llvmpipe/lp_setup.h
src/gallium/drivers/llvmpipe/lp_setup_context.h
src/gallium/drivers/llvmpipe/lp_setup_tri.c
src/gallium/drivers/llvmpipe/lp_setup_vbuf.c
src/gallium/drivers/llvmpipe/lp_state.h
src/gallium/drivers/llvmpipe/lp_state_derived.c
src/gallium/drivers/llvmpipe/lp_state_fs.c
src/gallium/drivers/llvmpipe/lp_state_fs.h
src/gallium/drivers/llvmpipe/lp_state_sampler.c
src/gallium/drivers/llvmpipe/lp_state_so.c
src/gallium/drivers/llvmpipe/lp_surface.c
src/gallium/drivers/llvmpipe/lp_test_conv.c
src/gallium/drivers/llvmpipe/lp_test_format.c
src/gallium/drivers/llvmpipe/lp_test_round.c [new file with mode: 0644]
src/gallium/drivers/llvmpipe/lp_test_sincos.c
src/gallium/drivers/llvmpipe/lp_texture.c
src/gallium/drivers/llvmpipe/lp_texture.h
src/gallium/drivers/llvmpipe/lp_tile_image.c
src/gallium/drivers/llvmpipe/lp_tile_shuffle_mask.py [new file with mode: 0644]
src/gallium/drivers/llvmpipe/lp_tile_soa.h
src/gallium/drivers/llvmpipe/lp_tile_soa.py
src/gallium/drivers/nouveau/nouveau_screen.c
src/gallium/drivers/nouveau/nouveau_screen.h
src/gallium/drivers/nouveau/nouveau_util.h
src/gallium/drivers/nouveau/nouveau_winsys.h
src/gallium/drivers/nv50/nv50_context.h
src/gallium/drivers/nv50/nv50_screen.c
src/gallium/drivers/nv50/nv50_state.c
src/gallium/drivers/nv50/nv50_state_validate.c
src/gallium/drivers/nvfx/nvfx_fragprog.c
src/gallium/drivers/nvfx/nvfx_screen.c
src/gallium/drivers/r300/Makefile
src/gallium/drivers/r300/SConscript
src/gallium/drivers/r300/r300_blit.c
src/gallium/drivers/r300/r300_cb.h
src/gallium/drivers/r300/r300_chipset.c
src/gallium/drivers/r300/r300_chipset.h
src/gallium/drivers/r300/r300_context.c
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_cs.h
src/gallium/drivers/r300/r300_debug.c
src/gallium/drivers/r300/r300_defines.h
src/gallium/drivers/r300/r300_emit.c
src/gallium/drivers/r300/r300_emit.h
src/gallium/drivers/r300/r300_flush.c
src/gallium/drivers/r300/r300_fs.c
src/gallium/drivers/r300/r300_hyperz.c
src/gallium/drivers/r300/r300_public.h [new file with mode: 0644]
src/gallium/drivers/r300/r300_query.c
src/gallium/drivers/r300/r300_reg.h
src/gallium/drivers/r300/r300_render.c
src/gallium/drivers/r300/r300_render_stencilref.c
src/gallium/drivers/r300/r300_screen.c
src/gallium/drivers/r300/r300_screen.h
src/gallium/drivers/r300/r300_screen_buffer.c
src/gallium/drivers/r300/r300_screen_buffer.h
src/gallium/drivers/r300/r300_state.c
src/gallium/drivers/r300/r300_state_derived.c
src/gallium/drivers/r300/r300_state_invariant.c [deleted file]
src/gallium/drivers/r300/r300_state_invariant.h [deleted file]
src/gallium/drivers/r300/r300_texture.c
src/gallium/drivers/r300/r300_texture.h
src/gallium/drivers/r300/r300_texture_desc.c [new file with mode: 0644]
src/gallium/drivers/r300/r300_texture_desc.h [new file with mode: 0644]
src/gallium/drivers/r300/r300_tgsi_to_rc.c
src/gallium/drivers/r300/r300_transfer.c
src/gallium/drivers/r300/r300_vs_draw.c
src/gallium/drivers/r300/r300_winsys.h
src/gallium/drivers/r600/Makefile
src/gallium/drivers/r600/SConscript
src/gallium/drivers/r600/r600_asm.c [new file with mode: 0644]
src/gallium/drivers/r600/r600_asm.h [new file with mode: 0644]
src/gallium/drivers/r600/r600_buffer.c
src/gallium/drivers/r600/r600_compiler.c [deleted file]
src/gallium/drivers/r600/r600_compiler.h [deleted file]
src/gallium/drivers/r600/r600_compiler_dump.c [deleted file]
src/gallium/drivers/r600/r600_compiler_r600.c [deleted file]
src/gallium/drivers/r600/r600_compiler_r700.c [deleted file]
src/gallium/drivers/r600/r600_compiler_tgsi.c [deleted file]
src/gallium/drivers/r600/r600_context.c
src/gallium/drivers/r600/r600_context.h
src/gallium/drivers/r600/r600_helper.c
src/gallium/drivers/r600/r600_public.h [new file with mode: 0644]
src/gallium/drivers/r600/r600_screen.c
src/gallium/drivers/r600/r600_shader.c
src/gallium/drivers/r600/r600_shader.h
src/gallium/drivers/r600/r600_sq.h
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/r600/r600_texture.c
src/gallium/drivers/r600/r600d.h
src/gallium/drivers/r600/r700_asm.c [new file with mode: 0644]
src/gallium/drivers/r600/r700_sq.h
src/gallium/drivers/r600/radeon.h
src/gallium/drivers/rbug/rbug_context.c
src/gallium/drivers/rbug/rbug_core.c
src/gallium/drivers/softpipe/sp_draw_arrays.c
src/gallium/drivers/softpipe/sp_quad_blend.c
src/gallium/drivers/softpipe/sp_quad_depth_test.c
src/gallium/drivers/softpipe/sp_quad_fs.c
src/gallium/drivers/softpipe/sp_screen.c
src/gallium/drivers/softpipe/sp_tex_sample.c
src/gallium/drivers/softpipe/sp_tex_tile_cache.c
src/gallium/drivers/softpipe/sp_tile_cache.c
src/gallium/drivers/svga/svga_public.h [new file with mode: 0644]
src/gallium/drivers/svga/svga_screen.c
src/gallium/drivers/svga/svga_winsys.h
src/gallium/drivers/trace/Makefile
src/gallium/drivers/trace/SConscript
src/gallium/drivers/trace/tr_drm.c [deleted file]
src/gallium/drivers/trace/tr_drm.h [deleted file]
src/gallium/include/pipe/p_compiler.h
src/gallium/include/pipe/p_config.h
src/gallium/include/pipe/p_defines.h
src/gallium/include/pipe/p_state.h
src/gallium/include/state_tracker/drm_api.h [deleted file]
src/gallium/include/state_tracker/drm_driver.h [new file with mode: 0644]
src/gallium/include/state_tracker/st_api.h
src/gallium/state_trackers/dri/common/dri_screen.h
src/gallium/state_trackers/dri/drm/dri2.c
src/gallium/state_trackers/dri/sw/drisw.c
src/gallium/state_trackers/egl/Makefile
src/gallium/state_trackers/egl/SConscript
src/gallium/state_trackers/egl/common/egl_g3d.c
src/gallium/state_trackers/egl/common/egl_g3d.h
src/gallium/state_trackers/egl/common/egl_g3d_api.c
src/gallium/state_trackers/egl/common/egl_g3d_image.c
src/gallium/state_trackers/egl/common/egl_g3d_loader.h [new file with mode: 0644]
src/gallium/state_trackers/egl/common/egl_g3d_st.c
src/gallium/state_trackers/egl/common/egl_g3d_st.h
src/gallium/state_trackers/egl/common/native.h
src/gallium/state_trackers/egl/common/native_helper.c
src/gallium/state_trackers/egl/common/native_helper.h
src/gallium/state_trackers/egl/common/native_probe.h [deleted file]
src/gallium/state_trackers/egl/fbdev/native_fbdev.c
src/gallium/state_trackers/egl/gdi/native_gdi.c
src/gallium/state_trackers/egl/kms/native_kms.c
src/gallium/state_trackers/egl/kms/native_kms.h
src/gallium/state_trackers/egl/x11/glxinit.c
src/gallium/state_trackers/egl/x11/native_dri2.c
src/gallium/state_trackers/egl/x11/native_x11.c
src/gallium/state_trackers/egl/x11/native_x11.h
src/gallium/state_trackers/egl/x11/native_ximage.c
src/gallium/state_trackers/egl/x11/x11_screen.c
src/gallium/state_trackers/egl/x11/x11_screen.h
src/gallium/state_trackers/vega/image.c
src/gallium/state_trackers/vega/mask.c
src/gallium/state_trackers/vega/paint.c
src/gallium/state_trackers/vega/path.c
src/gallium/state_trackers/vega/renderer.c
src/gallium/state_trackers/vega/shader.c
src/gallium/state_trackers/vega/shaders_cache.c
src/gallium/state_trackers/vega/vg_context.c
src/gallium/state_trackers/vega/vg_context.h
src/gallium/state_trackers/vega/vg_manager.c
src/gallium/state_trackers/xorg/xorg_crtc.c
src/gallium/state_trackers/xorg/xorg_dri2.c
src/gallium/state_trackers/xorg/xorg_driver.c
src/gallium/state_trackers/xorg/xorg_exa.c
src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
src/gallium/state_trackers/xorg/xorg_output.c
src/gallium/state_trackers/xorg/xorg_tracker.h
src/gallium/targets/Makefile.egl [deleted file]
src/gallium/targets/Makefile.xorg
src/gallium/targets/SConscript
src/gallium/targets/SConscript.dri
src/gallium/targets/dri-i915/Makefile
src/gallium/targets/dri-i915/SConscript
src/gallium/targets/dri-i915/dummy.c [deleted file]
src/gallium/targets/dri-i915/target.c [new file with mode: 0644]
src/gallium/targets/dri-i965/Makefile
src/gallium/targets/dri-i965/SConscript
src/gallium/targets/dri-i965/dummy.c [deleted file]
src/gallium/targets/dri-i965/target.c [new file with mode: 0644]
src/gallium/targets/dri-nouveau/Makefile
src/gallium/targets/dri-nouveau/target.c [new file with mode: 0644]
src/gallium/targets/dri-r600/Makefile
src/gallium/targets/dri-r600/SConscript
src/gallium/targets/dri-r600/dummy.c [deleted file]
src/gallium/targets/dri-r600/target.c [new file with mode: 0644]
src/gallium/targets/dri-radeong/Makefile
src/gallium/targets/dri-radeong/SConscript
src/gallium/targets/dri-radeong/dummy.c [deleted file]
src/gallium/targets/dri-radeong/target.c [new file with mode: 0644]
src/gallium/targets/dri-swrast/Makefile
src/gallium/targets/dri-swrast/SConscript
src/gallium/targets/dri-swrast/swrast_drm_api.c
src/gallium/targets/dri-vmwgfx/Makefile
src/gallium/targets/dri-vmwgfx/SConscript
src/gallium/targets/dri-vmwgfx/dummy.c [deleted file]
src/gallium/targets/dri-vmwgfx/target.c [new file with mode: 0644]
src/gallium/targets/egl-apis/Makefile [deleted file]
src/gallium/targets/egl-apis/SConscript [deleted file]
src/gallium/targets/egl-apis/api_GL.c [deleted file]
src/gallium/targets/egl-apis/api_GLESv1_CM.c [deleted file]
src/gallium/targets/egl-apis/api_GLESv2.c [deleted file]
src/gallium/targets/egl-apis/api_OpenVG.c [deleted file]
src/gallium/targets/egl-gdi/SConscript [new file with mode: 0644]
src/gallium/targets/egl-gdi/egl-static.c [new file with mode: 0644]
src/gallium/targets/egl-i915/Makefile [deleted file]
src/gallium/targets/egl-i915/dummy.c [deleted file]
src/gallium/targets/egl-i965/Makefile [deleted file]
src/gallium/targets/egl-i965/dummy.c [deleted file]
src/gallium/targets/egl-nouveau/Makefile [deleted file]
src/gallium/targets/egl-nouveau/dummy.c [deleted file]
src/gallium/targets/egl-radeon/Makefile [deleted file]
src/gallium/targets/egl-radeon/dummy.c [deleted file]
src/gallium/targets/egl-swrast/Makefile [deleted file]
src/gallium/targets/egl-swrast/SConscript [deleted file]
src/gallium/targets/egl-swrast/swrast_glue.c [deleted file]
src/gallium/targets/egl-vmwgfx/Makefile [deleted file]
src/gallium/targets/egl-vmwgfx/dummy.c [deleted file]
src/gallium/targets/egl/Makefile [new file with mode: 0644]
src/gallium/targets/egl/egl.c [new file with mode: 0644]
src/gallium/targets/egl/pipe_i915.c [new file with mode: 0644]
src/gallium/targets/egl/pipe_i965.c [new file with mode: 0644]
src/gallium/targets/egl/pipe_nouveau.c [new file with mode: 0644]
src/gallium/targets/egl/pipe_radeon.c [new file with mode: 0644]
src/gallium/targets/egl/pipe_swrast.c [new file with mode: 0644]
src/gallium/targets/egl/pipe_vmwgfx.c [new file with mode: 0644]
src/gallium/targets/egl/st_GL.c [new file with mode: 0644]
src/gallium/targets/egl/st_GLESv1_CM.c [new file with mode: 0644]
src/gallium/targets/egl/st_GLESv2.c [new file with mode: 0644]
src/gallium/targets/egl/st_OpenVG.c [new file with mode: 0644]
src/gallium/targets/libgl-xlib/Makefile
src/gallium/targets/xorg-i915/Makefile
src/gallium/targets/xorg-i915/intel_target.c [new file with mode: 0644]
src/gallium/targets/xorg-i965/Makefile
src/gallium/targets/xorg-i965/intel_target.c [new file with mode: 0644]
src/gallium/targets/xorg-nouveau/Makefile
src/gallium/targets/xorg-nouveau/nouveau_target.c [new file with mode: 0644]
src/gallium/targets/xorg-radeon/Makefile
src/gallium/targets/xorg-radeon/radeon_target.c [new file with mode: 0644]
src/gallium/targets/xorg-vmwgfx/Makefile
src/gallium/targets/xorg-vmwgfx/vmw_ctrl.c
src/gallium/targets/xorg-vmwgfx/vmw_driver.h
src/gallium/targets/xorg-vmwgfx/vmw_screen.c
src/gallium/targets/xorg-vmwgfx/vmw_target.c [new file with mode: 0644]
src/gallium/tests/graw/SConscript
src/gallium/tests/graw/tri-instanced.c [new file with mode: 0644]
src/gallium/tests/trivial/Makefile
src/gallium/tests/trivial/quad-tex.c
src/gallium/tests/trivial/tri.c
src/gallium/winsys/SConscript
src/gallium/winsys/i915/drm/i915_drm_batchbuffer.c
src/gallium/winsys/i915/drm/i915_drm_buffer.c
src/gallium/winsys/i915/drm/i915_drm_public.h [new file with mode: 0644]
src/gallium/winsys/i915/drm/i915_drm_winsys.c
src/gallium/winsys/i915/drm/i915_drm_winsys.h
src/gallium/winsys/i915/sw/i915_sw_public.h [new file with mode: 0644]
src/gallium/winsys/i915/sw/i915_sw_winsys.c
src/gallium/winsys/i915/sw/i915_sw_winsys.h
src/gallium/winsys/i965/drm/Makefile
src/gallium/winsys/i965/drm/SConscript
src/gallium/winsys/i965/drm/i965_drm_api.c [deleted file]
src/gallium/winsys/i965/drm/i965_drm_buffer.c
src/gallium/winsys/i965/drm/i965_drm_public.h [new file with mode: 0644]
src/gallium/winsys/i965/drm/i965_drm_winsys.c [new file with mode: 0644]
src/gallium/winsys/i965/drm/i965_drm_winsys.h
src/gallium/winsys/i965/xlib/xlib_i965.c
src/gallium/winsys/nouveau/drm/Makefile
src/gallium/winsys/nouveau/drm/nouveau_drm_api.c [deleted file]
src/gallium/winsys/nouveau/drm/nouveau_drm_api.h [deleted file]
src/gallium/winsys/nouveau/drm/nouveau_drm_public.h [new file with mode: 0644]
src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c [new file with mode: 0644]
src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.h [new file with mode: 0644]
src/gallium/winsys/r600/drm/r600_drm.c
src/gallium/winsys/r600/drm/r600_drm_public.h [new file with mode: 0644]
src/gallium/winsys/r600/drm/radeon.c
src/gallium/winsys/radeon/drm/radeon_buffer.h
src/gallium/winsys/radeon/drm/radeon_drm.c
src/gallium/winsys/radeon/drm/radeon_drm.h
src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
src/gallium/winsys/radeon/drm/radeon_drm_public.h [new file with mode: 0644]
src/gallium/winsys/radeon/drm/radeon_r300.c
src/gallium/winsys/radeon/drm/radeon_winsys.h
src/gallium/winsys/svga/drm/svga_drm_public.h [new file with mode: 0644]
src/gallium/winsys/svga/drm/vmw_screen_dri.c
src/gallium/winsys/svga/drm/vmwgfx_drm.h
src/gallium/winsys/sw/drm/Makefile [deleted file]
src/gallium/winsys/sw/drm/SConscript [deleted file]
src/gallium/winsys/sw/drm/sw_drm_api.c [deleted file]
src/gallium/winsys/sw/drm/sw_drm_api.h [deleted file]
src/glsl/Makefile
src/glsl/apps/compile.c
src/glsl/apps/process.c
src/glsl/apps/purify.c
src/glsl/apps/tokenise.c
src/glsl/apps/version.c
src/glsl/cl/sl_cl_parse.c
src/glsl/glsl_symbol_table.h
src/glsl/linker.cpp
src/glsl/program.h
src/glu/sgi/libtess/geom.c
src/glu/sgi/libtess/mesh.c
src/glu/sgi/libtess/normal.c
src/glu/sgi/libtess/priorityq-heap.c
src/glu/sgi/libtess/priorityq.c
src/glu/sgi/libtess/render.c
src/glu/sgi/libtess/sweep.c
src/glu/sgi/libtess/tess.c
src/glu/sgi/libutil/mipmap.c
src/glut/glx/Makefile
src/glut/glx/win32_menu.c
src/glw/Makefile
src/glx/XF86dri.c
src/glx/apple/appledri.c
src/glx/apple/gen_exports.tcl
src/glx/apple/glx_empty.c
src/glx/dri2.c
src/glx/dri2_glx.c
src/glx/dri_common.c
src/glx/dri_common.h
src/glx/dri_glx.c
src/glx/drisw_glx.c
src/glx/glx_pbuffer.c
src/glx/glxclient.h
src/glx/glxcmds.c
src/glx/glxcurrent.c
src/glx/glxext.c
src/glx/glxextensions.c
src/glx/glxextensions.h
src/glx/xfont.c
src/mapi/glapi/gen/ARB_geometry_shader4.xml [new file with mode: 0644]
src/mapi/glapi/gen/Makefile
src/mapi/glapi/gen/gl_API.xml
src/mapi/glapi/gen/gl_enums.py
src/mapi/glapi/glapi_sparc.S
src/mapi/glapi/glapi_x86-64.S
src/mapi/glapi/glapi_x86.S
src/mapi/glapi/glapidispatch.h
src/mapi/glapi/glapioffsets.h
src/mapi/glapi/glapitable.h
src/mapi/glapi/glapitemp.h
src/mapi/glapi/glprocs.h
src/mesa/Makefile
src/mesa/Makefile.mgw
src/mesa/SConscript
src/mesa/drivers/common/driverfuncs.c
src/mesa/drivers/common/meta.c
src/mesa/drivers/dri/common/dri_metaops.c
src/mesa/drivers/dri/common/dri_util.c
src/mesa/drivers/dri/common/dri_util.h
src/mesa/drivers/dri/i915/i915_fragprog.c
src/mesa/drivers/dri/i965/brw_clip.c
src/mesa/drivers/dri/i965/brw_clip.h
src/mesa/drivers/dri/i965/brw_clip_line.c
src/mesa/drivers/dri/i965/brw_clip_point.c
src/mesa/drivers/dri/i965/brw_clip_tri.c
src/mesa/drivers/dri/i965/brw_clip_unfilled.c
src/mesa/drivers/dri/i965/brw_clip_util.c
src/mesa/drivers/dri/i965/brw_context.c
src/mesa/drivers/dri/i965/brw_curbe.c
src/mesa/drivers/dri/i965/brw_defines.h
src/mesa/drivers/dri/i965/brw_disasm.c
src/mesa/drivers/dri/i965/brw_eu.h
src/mesa/drivers/dri/i965/brw_eu_emit.c
src/mesa/drivers/dri/i965/brw_gs_emit.c
src/mesa/drivers/dri/i965/brw_optimize.c
src/mesa/drivers/dri/i965/brw_program.c
src/mesa/drivers/dri/i965/brw_sf.h
src/mesa/drivers/dri/i965/brw_sf_state.c
src/mesa/drivers/dri/i965/brw_structs.h
src/mesa/drivers/dri/i965/brw_util.c
src/mesa/drivers/dri/i965/brw_vs.c
src/mesa/drivers/dri/i965/brw_vs.h
src/mesa/drivers/dri/i965/brw_vs_emit.c
src/mesa/drivers/dri/i965/brw_vs_surface_state.c
src/mesa/drivers/dri/i965/brw_wm.h
src/mesa/drivers/dri/i965/brw_wm_emit.c
src/mesa/drivers/dri/i965/brw_wm_fp.c
src/mesa/drivers/dri/i965/brw_wm_glsl.c
src/mesa/drivers/dri/i965/brw_wm_pass0.c
src/mesa/drivers/dri/i965/brw_wm_state.c
src/mesa/drivers/dri/i965/brw_wm_surface_state.c
src/mesa/drivers/dri/i965/gen6_sf_state.c
src/mesa/drivers/dri/i965/gen6_vs_state.c
src/mesa/drivers/dri/i965/gen6_wm_state.c
src/mesa/drivers/dri/intel/intel_batchbuffer.c
src/mesa/drivers/dri/intel/intel_chipset.h
src/mesa/drivers/dri/intel/intel_decode.c
src/mesa/drivers/dri/intel/intel_decode.h
src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
src/mesa/drivers/dri/mach64/mach64_screen.c
src/mesa/drivers/dri/mga/mga_xmesa.c
src/mesa/drivers/dri/r128/r128_screen.c
src/mesa/drivers/dri/r128/r128_state.c
src/mesa/drivers/dri/r128/r128_tex.c
src/mesa/drivers/dri/r200/r200_fragshader.c
src/mesa/drivers/dri/r200/r200_ioctl.c
src/mesa/drivers/dri/r200/r200_ioctl.h
src/mesa/drivers/dri/r200/r200_vertprog.c
src/mesa/drivers/dri/r300/compiler/Makefile
src/mesa/drivers/dri/r300/compiler/SConscript
src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
src/mesa/drivers/dri/r300/compiler/r500_fragprog.h
src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
src/mesa/drivers/dri/r300/compiler/radeon_code.h
src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c
src/mesa/drivers/dri/r300/compiler/radeon_emulate_loops.c
src/mesa/drivers/dri/r300/compiler/radeon_emulate_loops.h
src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c
src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h
src/mesa/drivers/dri/r300/compiler/radeon_optimize.c
src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c
src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
src/mesa/drivers/dri/r300/compiler/radeon_program_alu.h
src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.c [new file with mode: 0644]
src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.h [new file with mode: 0644]
src/mesa/drivers/dri/r300/r300_context.c
src/mesa/drivers/dri/r300/r300_context.h
src/mesa/drivers/dri/r300/r300_draw.c
src/mesa/drivers/dri/r300/r300_fragprog_common.c
src/mesa/drivers/dri/r300/r300_reg.h
src/mesa/drivers/dri/r300/r300_shader.c
src/mesa/drivers/dri/r300/r300_state.c
src/mesa/drivers/dri/r300/r300_vertprog.c
src/mesa/drivers/dri/r300/radeon_mesa_to_rc.c
src/mesa/drivers/dri/r600/r600_cmdbuf.c
src/mesa/drivers/dri/r600/r600_cmdbuf.h
src/mesa/drivers/dri/r600/r600_context.c
src/mesa/drivers/dri/r600/r700_assembler.c
src/mesa/drivers/dri/r600/r700_assembler.h
src/mesa/drivers/dri/r600/r700_chip.h
src/mesa/drivers/dri/r600/r700_fragprog.c
src/mesa/drivers/dri/r600/r700_oglprog.c
src/mesa/drivers/dri/r600/r700_oglprog.h
src/mesa/drivers/dri/r600/r700_state.c
src/mesa/drivers/dri/r600/r700_vertprog.c
src/mesa/drivers/dri/radeon/radeon_common_context.c
src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
src/mesa/drivers/dri/radeon/radeon_screen.c
src/mesa/drivers/dri/radeon/radeon_tex_getimage.c
src/mesa/drivers/dri/sis/sis_state.c
src/mesa/drivers/dri/unichrome/via_screen.c
src/mesa/drivers/glslcompiler/glslcompiler.c
src/mesa/drivers/osmesa/osmesa.c
src/mesa/drivers/x11/glxapi.c
src/mesa/main/api_exec.c
src/mesa/main/api_validate.c
src/mesa/main/arbprogram.c [new file with mode: 0644]
src/mesa/main/arbprogram.h [new file with mode: 0644]
src/mesa/main/atifragshader.c [new file with mode: 0644]
src/mesa/main/atifragshader.h [new file with mode: 0644]
src/mesa/main/bufferobj.c
src/mesa/main/config.h
src/mesa/main/context.c
src/mesa/main/dd.h
src/mesa/main/depthstencil.c
src/mesa/main/dlist.c
src/mesa/main/enums.c
src/mesa/main/extensions.c
src/mesa/main/fbobject.c
src/mesa/main/fbobject.h
src/mesa/main/ffvertex_prog.c
src/mesa/main/formats.c
src/mesa/main/formats.h
src/mesa/main/framebuffer.c
src/mesa/main/get.c
src/mesa/main/getstring.c
src/mesa/main/image.c
src/mesa/main/image.h
src/mesa/main/imports.c
src/mesa/main/imports.h
src/mesa/main/macros.h
src/mesa/main/mfeatures.h
src/mesa/main/mtypes.h
src/mesa/main/nvprogram.c [new file with mode: 0644]
src/mesa/main/nvprogram.h [new file with mode: 0644]
src/mesa/main/querymatrix.c
src/mesa/main/remap_helper.h
src/mesa/main/restart.c [new file with mode: 0644]
src/mesa/main/restart.h [new file with mode: 0644]
src/mesa/main/shaderapi.c [new file with mode: 0644]
src/mesa/main/shaderapi.h [new file with mode: 0644]
src/mesa/main/shaderobj.c [new file with mode: 0644]
src/mesa/main/shaderobj.h [new file with mode: 0644]
src/mesa/main/shaders.c [deleted file]
src/mesa/main/shaders.h [deleted file]
src/mesa/main/shared.c
src/mesa/main/state.c
src/mesa/main/texenvprogram.c
src/mesa/main/texfetch.c
src/mesa/main/texfetch_tmp.h
src/mesa/main/texformat.c
src/mesa/main/teximage.c
src/mesa/main/teximage.h
src/mesa/main/texobj.c
src/mesa/main/texparam.c
src/mesa/main/texstate.c
src/mesa/main/texstore.c
src/mesa/main/transformfeedback.c
src/mesa/main/transformfeedback.h
src/mesa/main/uniforms.c [new file with mode: 0644]
src/mesa/main/uniforms.h [new file with mode: 0644]
src/mesa/main/varray.c
src/mesa/main/version.c
src/mesa/program/.gitignore [new file with mode: 0644]
src/mesa/program/Makefile [new file with mode: 0644]
src/mesa/program/arbprogparse.c [new file with mode: 0644]
src/mesa/program/arbprogparse.h [new file with mode: 0644]
src/mesa/program/descrip.mms [new file with mode: 0644]
src/mesa/program/hash_table.c [new file with mode: 0644]
src/mesa/program/hash_table.h [new file with mode: 0644]
src/mesa/program/ir_to_mesa.cpp [new file with mode: 0644]
src/mesa/program/ir_to_mesa.h [new file with mode: 0644]
src/mesa/program/lex.yy.c [new file with mode: 0644]
src/mesa/program/nvfragparse.c [new file with mode: 0644]
src/mesa/program/nvfragparse.h [new file with mode: 0644]
src/mesa/program/nvvertparse.c [new file with mode: 0644]
src/mesa/program/nvvertparse.h [new file with mode: 0644]
src/mesa/program/prog_cache.c [new file with mode: 0644]
src/mesa/program/prog_cache.h [new file with mode: 0644]
src/mesa/program/prog_execute.c [new file with mode: 0644]
src/mesa/program/prog_execute.h [new file with mode: 0644]
src/mesa/program/prog_instruction.c [new file with mode: 0644]
src/mesa/program/prog_instruction.h [new file with mode: 0644]
src/mesa/program/prog_noise.c [new file with mode: 0644]
src/mesa/program/prog_noise.h [new file with mode: 0644]
src/mesa/program/prog_optimize.c [new file with mode: 0644]
src/mesa/program/prog_optimize.h [new file with mode: 0644]
src/mesa/program/prog_parameter.c [new file with mode: 0644]
src/mesa/program/prog_parameter.h [new file with mode: 0644]
src/mesa/program/prog_parameter_layout.c [new file with mode: 0644]
src/mesa/program/prog_parameter_layout.h [new file with mode: 0644]
src/mesa/program/prog_print.c [new file with mode: 0644]
src/mesa/program/prog_print.h [new file with mode: 0644]
src/mesa/program/prog_statevars.c [new file with mode: 0644]
src/mesa/program/prog_statevars.h [new file with mode: 0644]
src/mesa/program/prog_uniform.c [new file with mode: 0644]
src/mesa/program/prog_uniform.h [new file with mode: 0644]
src/mesa/program/program.c [new file with mode: 0644]
src/mesa/program/program.h [new file with mode: 0644]
src/mesa/program/program_lexer.l [new file with mode: 0644]
src/mesa/program/program_parse.tab.c [new file with mode: 0644]
src/mesa/program/program_parse.tab.h [new file with mode: 0644]
src/mesa/program/program_parse.y [new file with mode: 0644]
src/mesa/program/program_parse_extra.c [new file with mode: 0644]
src/mesa/program/program_parser.h [new file with mode: 0644]
src/mesa/program/programopt.c [new file with mode: 0644]
src/mesa/program/programopt.h [new file with mode: 0644]
src/mesa/program/symbol_table.c [new file with mode: 0644]
src/mesa/program/symbol_table.h [new file with mode: 0644]
src/mesa/shader/.gitignore [deleted file]
src/mesa/shader/Makefile [deleted file]
src/mesa/shader/arbprogparse.c [deleted file]
src/mesa/shader/arbprogparse.h [deleted file]
src/mesa/shader/arbprogram.c [deleted file]
src/mesa/shader/arbprogram.h [deleted file]
src/mesa/shader/atifragshader.c [deleted file]
src/mesa/shader/atifragshader.h [deleted file]
src/mesa/shader/descrip.mms [deleted file]
src/mesa/shader/hash_table.c [deleted file]
src/mesa/shader/hash_table.h [deleted file]
src/mesa/shader/ir_to_mesa.cpp [deleted file]
src/mesa/shader/ir_to_mesa.h [deleted file]
src/mesa/shader/lex.yy.c [deleted file]
src/mesa/shader/nvfragparse.c [deleted file]
src/mesa/shader/nvfragparse.h [deleted file]
src/mesa/shader/nvprogram.c [deleted file]
src/mesa/shader/nvprogram.h [deleted file]
src/mesa/shader/nvvertparse.c [deleted file]
src/mesa/shader/nvvertparse.h [deleted file]
src/mesa/shader/prog_cache.c [deleted file]
src/mesa/shader/prog_cache.h [deleted file]
src/mesa/shader/prog_execute.c [deleted file]
src/mesa/shader/prog_execute.h [deleted file]
src/mesa/shader/prog_instruction.c [deleted file]
src/mesa/shader/prog_instruction.h [deleted file]
src/mesa/shader/prog_noise.c [deleted file]
src/mesa/shader/prog_noise.h [deleted file]
src/mesa/shader/prog_optimize.c [deleted file]
src/mesa/shader/prog_optimize.h [deleted file]
src/mesa/shader/prog_parameter.c [deleted file]
src/mesa/shader/prog_parameter.h [deleted file]
src/mesa/shader/prog_parameter_layout.c [deleted file]
src/mesa/shader/prog_parameter_layout.h [deleted file]
src/mesa/shader/prog_print.c [deleted file]
src/mesa/shader/prog_print.h [deleted file]
src/mesa/shader/prog_statevars.c [deleted file]
src/mesa/shader/prog_statevars.h [deleted file]
src/mesa/shader/prog_uniform.c [deleted file]
src/mesa/shader/prog_uniform.h [deleted file]
src/mesa/shader/program.c [deleted file]
src/mesa/shader/program.h [deleted file]
src/mesa/shader/program_lexer.l [deleted file]
src/mesa/shader/program_parse.tab.c [deleted file]
src/mesa/shader/program_parse.tab.h [deleted file]
src/mesa/shader/program_parse.y [deleted file]
src/mesa/shader/program_parse_extra.c [deleted file]
src/mesa/shader/program_parser.h [deleted file]
src/mesa/shader/programopt.c [deleted file]
src/mesa/shader/programopt.h [deleted file]
src/mesa/shader/shader_api.c [deleted file]
src/mesa/shader/shader_api.h [deleted file]
src/mesa/shader/slang/descrip.mms [deleted file]
src/mesa/shader/slang/library/.gitignore [deleted file]
src/mesa/shader/slang/library/Makefile [deleted file]
src/mesa/shader/slang/library/SConscript [deleted file]
src/mesa/shader/slang/library/slang_120_core.gc [deleted file]
src/mesa/shader/slang/library/slang_builtin_120_common.gc [deleted file]
src/mesa/shader/slang/library/slang_builtin_120_fragment.gc [deleted file]
src/mesa/shader/slang/library/slang_common_builtin.gc [deleted file]
src/mesa/shader/slang/library/slang_core.gc [deleted file]
src/mesa/shader/slang/library/slang_fragment_builtin.gc [deleted file]
src/mesa/shader/slang/library/slang_vertex_builtin.gc [deleted file]
src/mesa/shader/slang/slang_builtin.c [deleted file]
src/mesa/shader/slang/slang_builtin.h [deleted file]
src/mesa/shader/slang/slang_codegen.c [deleted file]
src/mesa/shader/slang/slang_codegen.h [deleted file]
src/mesa/shader/slang/slang_compile.c [deleted file]
src/mesa/shader/slang/slang_compile.h [deleted file]
src/mesa/shader/slang/slang_compile_function.c [deleted file]
src/mesa/shader/slang/slang_compile_function.h [deleted file]
src/mesa/shader/slang/slang_compile_operation.c [deleted file]
src/mesa/shader/slang/slang_compile_operation.h [deleted file]
src/mesa/shader/slang/slang_compile_struct.c [deleted file]
src/mesa/shader/slang/slang_compile_struct.h [deleted file]
src/mesa/shader/slang/slang_compile_variable.c [deleted file]
src/mesa/shader/slang/slang_compile_variable.h [deleted file]
src/mesa/shader/slang/slang_emit.c [deleted file]
src/mesa/shader/slang/slang_emit.h [deleted file]
src/mesa/shader/slang/slang_ir.c [deleted file]
src/mesa/shader/slang/slang_ir.h [deleted file]
src/mesa/shader/slang/slang_label.c [deleted file]
src/mesa/shader/slang/slang_label.h [deleted file]
src/mesa/shader/slang/slang_link.c [deleted file]
src/mesa/shader/slang/slang_link.h [deleted file]
src/mesa/shader/slang/slang_log.c [deleted file]
src/mesa/shader/slang/slang_log.h [deleted file]
src/mesa/shader/slang/slang_mem.c [deleted file]
src/mesa/shader/slang/slang_mem.h [deleted file]
src/mesa/shader/slang/slang_print.c [deleted file]
src/mesa/shader/slang/slang_print.h [deleted file]
src/mesa/shader/slang/slang_simplify.c [deleted file]
src/mesa/shader/slang/slang_simplify.h [deleted file]
src/mesa/shader/slang/slang_storage.c [deleted file]
src/mesa/shader/slang/slang_storage.h [deleted file]
src/mesa/shader/slang/slang_typeinfo.c [deleted file]
src/mesa/shader/slang/slang_typeinfo.h [deleted file]
src/mesa/shader/slang/slang_utility.c [deleted file]
src/mesa/shader/slang/slang_utility.h [deleted file]
src/mesa/shader/slang/slang_vartable.c [deleted file]
src/mesa/shader/slang/slang_vartable.h [deleted file]
src/mesa/shader/symbol_table.c [deleted file]
src/mesa/shader/symbol_table.h [deleted file]
src/mesa/shader/uniforms.c [deleted file]
src/mesa/shader/uniforms.h [deleted file]
src/mesa/slang/descrip.mms [new file with mode: 0644]
src/mesa/slang/library/.gitignore [new file with mode: 0644]
src/mesa/slang/library/Makefile [new file with mode: 0644]
src/mesa/slang/library/SConscript [new file with mode: 0644]
src/mesa/slang/library/slang_120_core.gc [new file with mode: 0644]
src/mesa/slang/library/slang_builtin_120_common.gc [new file with mode: 0644]
src/mesa/slang/library/slang_builtin_120_fragment.gc [new file with mode: 0644]
src/mesa/slang/library/slang_common_builtin.gc [new file with mode: 0644]
src/mesa/slang/library/slang_core.gc [new file with mode: 0644]
src/mesa/slang/library/slang_fragment_builtin.gc [new file with mode: 0644]
src/mesa/slang/library/slang_geometry_builtin.gc [new file with mode: 0644]
src/mesa/slang/library/slang_vertex_builtin.gc [new file with mode: 0644]
src/mesa/slang/slang_builtin.c [new file with mode: 0644]
src/mesa/slang/slang_builtin.h [new file with mode: 0644]
src/mesa/slang/slang_codegen.c [new file with mode: 0644]
src/mesa/slang/slang_codegen.h [new file with mode: 0644]
src/mesa/slang/slang_compile.c [new file with mode: 0644]
src/mesa/slang/slang_compile.h [new file with mode: 0644]
src/mesa/slang/slang_compile_function.c [new file with mode: 0644]
src/mesa/slang/slang_compile_function.h [new file with mode: 0644]
src/mesa/slang/slang_compile_operation.c [new file with mode: 0644]
src/mesa/slang/slang_compile_operation.h [new file with mode: 0644]
src/mesa/slang/slang_compile_struct.c [new file with mode: 0644]
src/mesa/slang/slang_compile_struct.h [new file with mode: 0644]
src/mesa/slang/slang_compile_variable.c [new file with mode: 0644]
src/mesa/slang/slang_compile_variable.h [new file with mode: 0644]
src/mesa/slang/slang_emit.c [new file with mode: 0644]
src/mesa/slang/slang_emit.h [new file with mode: 0644]
src/mesa/slang/slang_ir.c [new file with mode: 0644]
src/mesa/slang/slang_ir.h [new file with mode: 0644]
src/mesa/slang/slang_label.c [new file with mode: 0644]
src/mesa/slang/slang_label.h [new file with mode: 0644]
src/mesa/slang/slang_link.c [new file with mode: 0644]
src/mesa/slang/slang_link.h [new file with mode: 0644]
src/mesa/slang/slang_log.c [new file with mode: 0644]
src/mesa/slang/slang_log.h [new file with mode: 0644]
src/mesa/slang/slang_mem.c [new file with mode: 0644]
src/mesa/slang/slang_mem.h [new file with mode: 0644]
src/mesa/slang/slang_print.c [new file with mode: 0644]
src/mesa/slang/slang_print.h [new file with mode: 0644]
src/mesa/slang/slang_simplify.c [new file with mode: 0644]
src/mesa/slang/slang_simplify.h [new file with mode: 0644]
src/mesa/slang/slang_storage.c [new file with mode: 0644]
src/mesa/slang/slang_storage.h [new file with mode: 0644]
src/mesa/slang/slang_typeinfo.c [new file with mode: 0644]
src/mesa/slang/slang_typeinfo.h [new file with mode: 0644]
src/mesa/slang/slang_utility.c [new file with mode: 0644]
src/mesa/slang/slang_utility.h [new file with mode: 0644]
src/mesa/slang/slang_vartable.c [new file with mode: 0644]
src/mesa/slang/slang_vartable.h [new file with mode: 0644]
src/mesa/sources.mak
src/mesa/state_tracker/st_atom.c
src/mesa/state_tracker/st_atom.h
src/mesa/state_tracker/st_atom_clip.c
src/mesa/state_tracker/st_atom_constbuf.c
src/mesa/state_tracker/st_atom_pixeltransfer.c
src/mesa/state_tracker/st_atom_sampler.c
src/mesa/state_tracker/st_atom_shader.c
src/mesa/state_tracker/st_atom_texture.c
src/mesa/state_tracker/st_cb_bitmap.c
src/mesa/state_tracker/st_cb_clear.c
src/mesa/state_tracker/st_cb_drawpixels.c
src/mesa/state_tracker/st_cb_drawtex.c
src/mesa/state_tracker/st_cb_fbo.c
src/mesa/state_tracker/st_cb_program.c
src/mesa/state_tracker/st_cb_texture.c
src/mesa/state_tracker/st_context.c
src/mesa/state_tracker/st_context.h
src/mesa/state_tracker/st_debug.c
src/mesa/state_tracker/st_draw.c
src/mesa/state_tracker/st_extensions.c
src/mesa/state_tracker/st_gl_api.h
src/mesa/state_tracker/st_manager.c
src/mesa/state_tracker/st_manager.h
src/mesa/state_tracker/st_mesa_to_tgsi.c
src/mesa/state_tracker/st_program.c
src/mesa/state_tracker/st_program.h
src/mesa/swrast/s_atifragshader.c
src/mesa/swrast/s_context.c
src/mesa/swrast/s_context.h
src/mesa/swrast/s_fragprog.c
src/mesa/swrast/s_texcombine.c
src/mesa/swrast/s_triangle.c
src/mesa/tnl/t_vb_program.c
src/mesa/vbo/vbo_exec_api.c

index 2f83ce99f198e2724ac8f879199eadc0e8826d36..ca465047158f874fc094f31728cd76641a05ce9d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -243,13 +243,13 @@ MAIN_FILES = \
        $(DIRECTORY)/src/mesa/main/descrip.mms                          \
        $(DIRECTORY)/src/mesa/math/*.[ch]                               \
        $(DIRECTORY)/src/mesa/math/descrip.mms                          \
-       $(DIRECTORY)/src/mesa/shader/*.[chly]                           \
-       $(DIRECTORY)/src/mesa/shader/Makefile                           \
-       $(DIRECTORY)/src/mesa/shader/descrip.mms                        \
-       $(DIRECTORY)/src/mesa/shader/slang/*.[ch]                       \
-       $(DIRECTORY)/src/mesa/shader/slang/descrip.mms                  \
-       $(DIRECTORY)/src/mesa/shader/slang/library/*.gc                 \
-       $(DIRECTORY)/src/mesa/shader/slang/library/Makefile             \
+       $(DIRECTORY)/src/mesa/program/*.[chly]                          \
+       $(DIRECTORY)/src/mesa/program/Makefile                          \
+       $(DIRECTORY)/src/mesa/program/descrip.mms                       \
+       $(DIRECTORY)/src/mesa/slang/*.[ch]                              \
+       $(DIRECTORY)/src/mesa/slang/descrip.mms                         \
+       $(DIRECTORY)/src/mesa/slang/library/*.gc                        \
+       $(DIRECTORY)/src/mesa/slang/library/Makefile                    \
        $(DIRECTORY)/src/mesa/swrast/*.[ch]                             \
        $(DIRECTORY)/src/mesa/swrast/descrip.mms                        \
        $(DIRECTORY)/src/mesa/swrast_setup/*.[ch]                       \
index 83c29c06c3a4b2221a9813137399835528de1f82..a187d8d1b6faba6e4cf77bb0a3f87880c1e73714 100644 (file)
@@ -131,6 +131,8 @@ if 'trace' not in env['drivers']:
     env['drivers'].append('trace')
 if 'rbug' not in env['drivers']:
     env['drivers'].append('rbug')
+if 'galahad' not in env['drivers']:
+    env['drivers'].append('galahad')
 if 'identity' not in env['drivers']:
     env['drivers'].append('identity')
 if 'softpipe' not in env['drivers']:
index f7dbe55aa8a3c47bbb7dc2d903c978ead6a2ecf8..9141699ffec994e1f914103c0f1b504b4e9e9221 100644 (file)
--- a/common.py
+++ b/common.py
@@ -87,7 +87,7 @@ def AddOptions(opts):
        opts.Add(EnumOption('machine', 'use machine-specific assembly code', default_machine,
                                                                                         allowed_values=('generic', 'ppc', 'x86', 'x86_64')))
        opts.Add(EnumOption('platform', 'target platform', default_platform,
-                                                                                        allowed_values=('linux', 'cell', 'windows', 'winddk', 'wince', 'darwin', 'embedded', 'cygwin')))
+                                                                                        allowed_values=('linux', 'cell', 'windows', 'winddk', 'wince', 'darwin', 'embedded', 'cygwin', 'sunos5')))
        opts.Add('toolchain', 'compiler toolchain', 'default')
        opts.Add(BoolOption('llvm', 'use LLVM', default_llvm))
        opts.Add(BoolOption('dri', 'build DRI drivers', default_dri))
index 417138b2a1f58ba04824bb859d596239366265ef..7c6f123cac040e138fa4ab0434a04de7aebafb76 100644 (file)
@@ -31,7 +31,11 @@ X11_CFLAGS = @X11_CFLAGS@
 LLVM_CFLAGS = @LLVM_CFLAGS@
 LLVM_LDFLAGS = @LLVM_LDFLAGS@
 LLVM_LIBS = @LLVM_LIBS@
+GLW_CFLAGS = @GLW_CFLAGS@
+GLUT_CFLAGS = @GLUT_CFLAGS@
 
+# dlopen
+DLOPEN_LIBS = @DLOPEN_LIBS@
 
 # Source selection
 MESA_ASM_SOURCES = @MESA_ASM_SOURCES@
@@ -176,8 +180,10 @@ EGL_PC_REQ_PRIV = @GL_PC_REQ_PRIV@
 EGL_PC_LIB_PRIV = @GL_PC_LIB_PRIV@
 EGL_PC_CFLAGS = @GL_PC_CFLAGS@
 
-EGL_DRI2_CFLAGS = @EGL_DRI2_CFLAGS@
-EGL_DRI2_LIBS = @EGL_DRI2_LIBS@
+XCB_DRI2_CFLAGS = @XCB_DRI2_CFLAGS@
+XCB_DRI2_LIBS = @XCB_DRI2_LIBS@
+LIBUDEV_CFLAGS = @LIBUDEV_CFLAGS@
+LIBUDEV_LIBS = @LIBUDEV_LIBS@
 
 MESA_LLVM = @MESA_LLVM@
 
index 3d9744409ae4a6fbcf6f37150c4fd224b6957fe9..8711a382cc0807f0b11745b6012e2ef4bec72bf8 100644 (file)
@@ -131,6 +131,8 @@ VG_LIB_DEPS    = $(EXTRA_LIB_PATH) -lpthread
 APP_LIB_DEPS = -lm
 X11_LIBS = -lX11
 
+DLOPEN_LIBS = -ldl
+
 # Installation directories (for make install)
 INSTALL_DIR = /usr/local
 INSTALL_LIB_DIR = $(INSTALL_DIR)/$(LIB_DIR)
index bf42992b2fd67f9d4e89bff897de95c1bd8b6b62..7dfec39cd4d0258bc8d8d24b21dea571fb208260 100644 (file)
@@ -410,6 +410,7 @@ dnl Check to see if dlopen is in default libraries (like Solaris, which
 dnl has it in libc), or if libdl is needed to get it.
 AC_CHECK_FUNC([dlopen], [],
     [AC_CHECK_LIB([dl], [dlopen], [DLOPEN_LIBS="-ldl"])])
+AC_SUBST([DLOPEN_LIBS])
 
 dnl See if posix_memalign is available
 AC_CHECK_FUNC([posix_memalign], [DEFINES="$DEFINES -DHAVE_POSIX_MEMALIGN"])
@@ -476,7 +477,7 @@ GLU_DIRS="sgi"
 GALLIUM_DIRS="auxiliary drivers state_trackers"
 GALLIUM_TARGET_DIRS=""
 GALLIUM_WINSYS_DIRS="sw"
-GALLIUM_DRIVERS_DIRS="softpipe failover trace rbug identity"
+GALLIUM_DRIVERS_DIRS="softpipe failover galahad trace rbug identity"
 GALLIUM_STATE_TRACKERS_DIRS=""
 
 case "$mesa_driver" in
@@ -488,7 +489,7 @@ xlib)
 dri)
     SRC_DIRS="$SRC_DIRS glx"
     DRIVER_DIRS="dri"
-    GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/xlib sw/dri sw/drm"
+    GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/xlib sw/dri"
     ;;
 osmesa)
     DRIVER_DIRS="osmesa"
@@ -682,7 +683,7 @@ AC_SUBST([DRI_DRIVER_SEARCH_DIR])
 dnl Direct rendering or just indirect rendering
 AC_ARG_ENABLE([driglx-direct],
     [AS_HELP_STRING([--disable-driglx-direct],
-        [enable direct rendering in GLX for DRI @<:@default=enabled@:>@])],
+        [enable direct rendering in GLX and EGL for DRI @<:@default=enabled@:>@])],
     [driglx_direct="$enableval"],
     [driglx_direct="yes"])
 dnl Which drivers to build - default is chosen by platform
@@ -963,12 +964,23 @@ if test "x$enable_egl" = xyes; then
             EGL_DRIVERS_DIRS="glx"
         fi
 
-        # build egl_dri2 when xcb-dri2 is available
-        PKG_CHECK_MODULES([EGL_DRI2], [x11-xcb xcb-dri2 xcb-xfixes libdrm],
-                         [have_xcb_dri2=yes],[have_xcb_dri2=no])
-        if test "$have_xcb_dri2" = yes; then
-            EGL_DRIVERS_DIRS="$EGL_DRIVERS_DIRS dri2"
-        fi
+        if test "$mesa_driver" = dri; then
+            # build egl_dri2 when xcb-dri2 is available
+            PKG_CHECK_MODULES([XCB_DRI2], [x11-xcb xcb-dri2 xcb-xfixes],
+                         [have_xcb_dri2=yes],[have_xcb_dri2=no])
+            PKG_CHECK_MODULES([LIBUDEV], [libudev > 150],
+                         [have_libudev=yes],[have_libudev=no])
+            
+            if test "$have_xcb_dri2" = yes; then
+                EGL_DRIVER_DRI2=dri2
+                DEFINES="$DEFINES -DHAVE_XCB_DRI2"
+                if test "$have_libudev" = yes; then
+                    DEFINES="$DEFINES -DHAVE_LIBUDEV"
+                fi
+            fi
+       fi
+
+        EGL_DRIVERS_DIRS="$EGL_DRIVERS_DIRS $EGL_DRIVER_DRI2"
     fi
 fi
 AC_SUBST([EGL_LIB_DEPS])
@@ -1120,10 +1132,6 @@ fi
 
 if test "x$enable_glut" = xyes; then
     SRC_DIRS="$SRC_DIRS glut/glx"
-    GLUT_CFLAGS=""
-    if test "x$GCC" = xyes; then
-        GLUT_CFLAGS="-fexceptions"
-    fi
     if test "$x11_pkgconfig" = yes; then
         PKG_CHECK_MODULES([GLUT],[x11 xmu xi])
         GLUT_PC_REQ_PRIV="x11 xmu xi"
@@ -1134,6 +1142,9 @@ if test "x$enable_glut" = xyes; then
         GLUT_PC_LIB_PRIV="$GLUT_LIB_DEPS"
         GLUT_PC_CFLAGS="$X11_INCLUDES"
     fi
+    if test "x$GCC" = xyes; then
+        GLUT_CFLAGS="$GLUT_CFLAGS -fexceptions"
+    fi
     GLUT_LIB_DEPS="$GLUT_LIB_DEPS -lm"
     GLUT_PC_LIB_PRIV="$GLUT_PC_LIB_PRIV -lm"
 
@@ -1253,6 +1264,7 @@ yes)
             HAVE_ST_EGL="yes"
             ;;
         xorg)
+            PKG_CHECK_MODULES([XORG], [xorg-server >= 1.6.0])
             PKG_CHECK_MODULES([LIBDRM_XORG], [libdrm >= $LIBDRM_XORG_REQUIRED])
             PKG_CHECK_MODULES([LIBKMS_XORG], [libkms >= $LIBKMS_XORG_REQUIRED])
             HAVE_ST_XORG="yes"
@@ -1294,7 +1306,11 @@ AC_SUBST([VG_LIB_DEPS])
 AC_SUBST([EGL_CLIENT_APIS])
 
 if test "x$HAVE_ST_EGL" = xyes; then
-       GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS egl-apis"
+       GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS egl"
+       # define GLX_DIRECT_RENDERING even when the driver is not dri
+       if test "x$mesa_driver" != xdri -a "x$driglx_direct" = xyes; then
+            DEFINES="$DEFINES -DGLX_DIRECT_RENDERING"
+       fi
 fi
 
 if test "x$HAVE_ST_XORG" = xyes; then
@@ -1401,18 +1417,15 @@ dnl
 dnl Gallium helper functions
 dnl
 gallium_check_st() {
-    if test "x$HAVE_ST_DRI" = xyes || test "x$HAVE_ST_EGL" = xyes || test "x$HAVE_ST_XORG" = xyes; then
+    if test "x$HAVE_ST_DRI" = xyes || test "x$HAVE_ST_XORG" = xyes; then
          GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS $1"
     fi
     if test "x$HAVE_ST_DRI" = xyes && test "x$2" != x; then
          GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $2"
     fi
-    if test "x$HAVE_ST_EGL" = xyes && test "x$3" != x; then
+    if test "x$HAVE_ST_XORG" = xyes && test "x$3" != x; then
          GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $3"
     fi
-    if test "x$HAVE_ST_XORG" = xyes && test "x$4" != x; then
-         GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $4"
-    fi
 }
 
 
@@ -1426,26 +1439,41 @@ AC_ARG_ENABLE([gallium-svga],
     [enable_gallium_svga=auto])
 if test "x$enable_gallium_svga" = xyes; then
     GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS svga"
-    gallium_check_st "svga/drm" "dri-vmwgfx" "egl-vmwgfx" "xorg-vmwgfx"
+    gallium_check_st "svga/drm" "dri-vmwgfx" "xorg-vmwgfx"
 elif test "x$enable_gallium_svga" = xauto; then
     GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS svga"
 fi
 
 dnl
-dnl Gallium Intel configuration
+dnl Gallium i915 configuration
 dnl
-AC_ARG_ENABLE([gallium-intel],
-    [AS_HELP_STRING([--enable-gallium-intel],
-        [build gallium intel @<:@default=disabled@:>@])],
-    [enable_gallium_intel="$enableval"],
-    [enable_gallium_intel=auto])
-if test "x$enable_gallium_intel" = xyes; then
+AC_ARG_ENABLE([gallium-i915],
+    [AS_HELP_STRING([--enable-gallium-i915],
+        [build gallium i915 @<:@default=disabled@:>@])],
+    [enable_gallium_i915="$enableval"],
+    [enable_gallium_i915=auto])
+if test "x$enable_gallium_i915" = xyes; then
     GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS i915/sw"
-    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915 i965"
-    gallium_check_st "i915/drm i965/drm" "dri-i915 dri-i965" "egl-i915 egl-i965" "xorg-i915 xorg-i965"
-elif test "x$enable_gallium_intel" = xauto; then
+    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915"
+    gallium_check_st "i915/drm" "dri-i915" "xorg-i915"
+elif test "x$enable_gallium_i915" = xauto; then
     GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS i915/sw"
-    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915 i965"
+    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915"
+fi
+
+dnl
+dnl Gallium i965 configuration
+dnl
+AC_ARG_ENABLE([gallium-i965],
+    [AS_HELP_STRING([--enable-gallium-i965],
+        [build gallium i965 @<:@default=disabled@:>@])],
+    [enable_gallium_i965="$enableval"],
+    [enable_gallium_i965=auto])
+if test "x$enable_gallium_i965" = xyes; then
+    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i965"
+    gallium_check_st "i965/drm" "dri-i965" "xorg-i965"
+elif test "x$enable_gallium_i965" = xauto; then
+    GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i965"
 fi
 
 dnl
@@ -1458,7 +1486,7 @@ AC_ARG_ENABLE([gallium-radeon],
     [enable_gallium_radeon=auto])
 if test "x$enable_gallium_radeon" = xyes; then
     GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r300"
-    gallium_check_st "radeon/drm" "dri-radeong" "egl-radeon" "xorg-radeon"
+    gallium_check_st "radeon/drm" "dri-radeong" "xorg-radeon"
 elif test "x$enable_gallium_radeon" = xauto; then
     GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r300"
 fi
@@ -1486,7 +1514,7 @@ AC_ARG_ENABLE([gallium-nouveau],
     [enable_gallium_nouveau=no])
 if test "x$enable_gallium_nouveau" = xyes; then
     GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau nvfx nv50"
-    gallium_check_st "nouveau/drm" "dri-nouveau" "egl-nouveau" "xorg-nouveau"
+    gallium_check_st "nouveau/drm" "dri-nouveau" "xorg-nouveau"
 fi
 
 dnl
@@ -1501,9 +1529,6 @@ if test "x$enable_gallium_swrast" = xyes || test "x$enable_gallium_swrast" = xau
     if test "x$HAVE_ST_DRI" = xyes; then
         GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS dri-swrast"
     fi
-    if test "x$HAVE_ST_EGL" = xyes; then
-        GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS egl-swrast"
-    fi
 fi
 
 dnl prepend CORE_DIRS to SRC_DIRS
index b2198e931d078035bd1f075c68150c283a2ddbde..a6cd111f87524fb0f1999237d1f4c2d675982236 100644 (file)
@@ -32,7 +32,7 @@ cards.</p>
 the Gallium driver for your hardware.  For example</p>
 
 <pre>
-  $ ./configure --enable-gles-overlay --with-state-trackers=egl,vega --enable-gallium-{swrast,intel}
+  $ ./configure --enable-gles-overlay --with-state-trackers=egl,vega --enable-gallium-intel
 </pre>
 
 <p>The main library and OpenGL is enabled by default.  The first option enables
@@ -71,12 +71,12 @@ drivers will be installed to <code>${libdir}/egl</code>.</p>
 
 <li><code>--with-egl-platforms</code>
 
-<p>List the native platform window system(s) to support.  It is by default
-<code>x11</code>, which supports the X Window System.  Its argument is a comma
-separated string like, for example, <code>--with-egl-platforms=x11,kms</code>.
-Because an EGL driver decides which window system to support, this example will
-enable two (sets of) EGL drivers.  One supports the X window system and the
-other supports bare KMS (kernel modesetting).</p>
+<p>List the platforms (window systems) to support.  Its argument is a comma
+seprated string such as <code>--with-egl-platforms=x11,kms</code>.  It decides
+the platforms a driver may support.  The first listed platform is also used by
+the main library to decide the native platform: the platform the EGL native
+types such as <code>EGLNativeDisplayType</code> or
+<code>EGLNativeWindowType</code> defined for.</p>
 
 <p>The available platforms are <code>x11</code>, <code>kms</code>,
 <code>fbdev</code>, and <code>gdi</code>.  The <code>gdi</code> platform can
@@ -87,9 +87,8 @@ only be built with SCons.</p>
 <li><code>--with-state-trackers</code>
 
 <p>The argument is a comma separated string.  It is usually used to specify the
-rendering APIs, such as OpenVG, to build.  But it should be noted that a number
-of EGL drivers depend on the <code>egl</code> state tracker.  They will
-<em>not</em> be built without the <code>egl</code> state tracker.</p>
+rendering APIs, such as OpenVG, to build.  But it is also used to specify
+<code>egl</code> state tracker that <code>egl_gallium</code> depends on.</p>
 
 </li>
 
@@ -105,19 +104,10 @@ ES, this option must be explicitly given.</p>
 
 <p>Unlike <code>--enable-gles-overlay</code>, which builds one library for each
 rendering API, these options enable OpenGL ES support in OpenGL.  The result is
-one big library that supports multiple APIs.  This is used by DRI drivers and
-<code>egl_dri2</code> EGL driver.
+one big library that supports multiple APIs.</p>
 
 </li>
 
-<li><code>--enable-gallium-swrast</code>
-
-<p>This option is not specific to EGL.  But if there is no driver for your
-hardware, or you are experiencing problems with the hardware driver, you can
-enable the swrast DRM driver.  It is a dummy driver and EGL will fallback to
-software rendering automatically.</p>
-
-</li>
 </ul>
 
 <h2>Use EGL</h2>
@@ -153,12 +143,10 @@ specific driver.  This variable is ignored for setuid/setgid binaries.</p>
 
 <li><code>EGL_PLATFORM</code>
 
-<p>When <code>EGL_DRIVER</code> is not set, the main library loads <em>all</em>
-EGL drivers that support a certain window system.  <code>EGL_PLATFORM</code>
-can be used to specify the window system and the valid values are, for example,
-<code>x11</code> or <code>kms</code>.  When the variable is not set, the main
-library defaults the value to the first window system listed in
-<code>--with-egl-platforms</code> at configuration time.
+<p>This variable specifies the native platform.  The valid values are the same
+as those for <code>--with-egl-platforms</code>.  When the variable is not set,
+the main library uses the first platform listed in
+<code>--with-egl-platforms</code> as the native platform</p>
 
 </li>
 
@@ -180,31 +168,15 @@ variable to true forces the use of software rendering.</p>
 
 <h2>EGL Drivers</h2>
 
-<p>There are two categories of EGL drivers: Gallium and classic.</p>
-
-<p>Gallium EGL drivers supports all rendering APIs specified in EGL 1.4.  These
-drivers depend on the <code>egl</code> state tracker to build.  The available
-drivers are</p>
-
 <ul>
-<li><code>egl_&lt;dpy&gt;_i915</code></li>
-<li><code>egl_&lt;dpy&gt;_i965</code></li>
-<li><code>egl_&lt;dpy&gt;_nouveau</code></li>
-<li><code>egl_&lt;dpy&gt;_radeon</code></li>
-<li><code>egl_&lt;dpy&gt;_swrast</code></li>
-<li><code>egl_&lt;dpy&gt;_vmwgfx</code></li>
-</ul>
+<li><code>egl_gallium</code>
 
-<p><code>&lt;dpy&gt;</code> is given by <code>--with-egl-platforms</code> at
-configuration time.  There is usually one EGL driver for each combination of
-the platforms listed and the pipe drivers enabled.  When the platform is pure
-software or pure hardware, non-working combinations will not be built.</p>
+<p>This driver is based on Gallium3D.  It supports all rendering APIs and
+hardwares supported by Gallium3D.  It is the only driver that supports OpenVG.
+The supported platforms are X11, KMS, FBDEV, and GDI.</p>
 
-<p>Classic EGL drivers, on the other hand, support only a subset of the
-available rendering APIs.  They can be found under
-<code>src/egl/drivers/</code>.  There are 3 of them</p>
+</li>
 
-<ul>
 <li><code>egl_glx</code>
 
 <p>This driver provides a wrapper to GLX.  It uses exclusively GLX to implement
@@ -231,9 +203,6 @@ are phasing out, it might eventually be replaced by <code>egl_dri2</code>.</p>
 </li>
 </ul>
 
-<p>To use the classic drivers, one must manually set <code>EGL_DRIVER</code> at
-runtime.</p>
-
 <h2>Developers</h2>
 
 <p>The sources of the main library and the classic drivers can be found at
index 211978b813954ead765e43b5a89e87babfe7f4fa..457dd8fd05d9ef864945ff2438984ee3782225a3 100644 (file)
@@ -36,6 +36,8 @@ tbd
 <ul>
 <li>GL_EXT_timer_query extension (i965 driver only)
 <li>GL_ARB_texture_swizzle extension (alias of GL_EXT_texture_swizzle)
+<li>GL_ARB_draw_elements_base_vertex, GL_ARB_fragment_program_shadow
+    and GL_EXT_draw_buffers2 in Gallium drivers
 </ul>
 
 
index ce1dca3d8e5563904f8cc61bdff8f2accee43abf..68591bdeb8c5adca5be59badadffd9d9cc24a155 100644 (file)
@@ -208,6 +208,17 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLCOPYCONTEXTMESA) (EGLDisplay dpy, EGLCont
 
 #endif /* EGL_MESA_copy_context */
 
+#ifndef EGL_MESA_drm_display
+#define EGL_MESA_drm_display 1
+
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLDisplay EGLAPIENTRY eglGetDRMDisplayMESA(int fd);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+
+typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETDRMDISPLAYMESA) (int fd);
+
+#endif /* EGL_MESA_drm_display */
+
 #ifndef EGL_KHR_image_base
 #define EGL_KHR_image_base 1
 /* Most interfaces defined by EGL_KHR_image_pixmap above */
index c625088d6cba07c23eecd2abde15d6007c1ed918..33a3e5f889135bd83558e516c2e8c0b21e6cb7c7 100644 (file)
@@ -80,6 +80,14 @@ typedef void *EGLNativePixmapType;
 
 #elif defined(__unix__) || defined(__unix)
 
+#ifdef MESA_EGL_NO_X11_HEADERS
+
+typedef void            *EGLNativeDisplayType;
+typedef khronos_uint32_t EGLNativePixmapType;
+typedef khronos_uint32_t EGLNativeWindowType;
+
+#else
+
 /* X11 (tentative)  */
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
@@ -88,6 +96,8 @@ typedef Display *EGLNativeDisplayType;
 typedef Pixmap   EGLNativePixmapType;
 typedef Window   EGLNativeWindowType;
 
+#endif /* MESA_EGL_NO_X11_HEADERS */
+
 #else
 #error "Platform not recognized"
 #endif
index fd53964ea06b0123bc27f8810c4bc6044b0bee6e..a3a7d97c9328d824bac8d62cc39420311b005953 100644 (file)
@@ -367,22 +367,6 @@ typedef void ( * PFNGLXFREEMEMORYNVPROC) (GLvoid *pointer);
 #endif /* GLX_NV_vertex_array_range */
 
 
-/*
- * ???. GLX_MESA_allocate_memory
- */ 
-#ifndef GLX_MESA_allocate_memory
-#define GLX_MESA_allocate_memory 1
-
-extern void *glXAllocateMemoryMESA(Display *dpy, int scrn, size_t size, float readfreq, float writefreq, float priority);
-extern void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer);
-extern GLuint glXGetMemoryOffsetMESA(Display *dpy, int scrn, const void *pointer);
-typedef void * ( * PFNGLXALLOCATEMEMORYMESAPROC) (Display *dpy, int scrn, size_t size, float readfreq, float writefreq, float priority);
-typedef void ( * PFNGLXFREEMEMORYMESAPROC) (Display *dpy, int scrn, void *pointer);
-typedef GLuint (* PFNGLXGETMEMORYOFFSETMESAPROC) (Display *dpy, int scrn, const void *pointer);
-
-#endif /* GLX_MESA_allocate_memory */
-
-
 /*
  * ARB ?. GLX_ARB_render_texture
  * XXX This was never finalized!
index e4c2b3a3eba76f8484d4d79bf5934ef69516bee4..2c8546499c5dc8847794b43c540963645246a473 100644 (file)
@@ -74,7 +74,6 @@ typedef struct __DRIcoreExtensionRec          __DRIcoreExtension;
 typedef struct __DRIextensionRec               __DRIextension;
 typedef struct __DRIcopySubBufferExtensionRec  __DRIcopySubBufferExtension;
 typedef struct __DRIswapControlExtensionRec    __DRIswapControlExtension;
-typedef struct __DRIallocateExtensionRec       __DRIallocateExtension;
 typedef struct __DRIframeTrackingExtensionRec  __DRIframeTrackingExtension;
 typedef struct __DRImediaStreamCounterExtensionRec     __DRImediaStreamCounterExtension;
 typedef struct __DRItexOffsetExtensionRec      __DRItexOffsetExtension;
@@ -149,23 +148,6 @@ struct __DRIswapControlExtensionRec {
     unsigned int (*getSwapInterval)(__DRIdrawable *drawable);
 };
 
-/**
- * Used by drivers that implement the GLX_MESA_allocate_memory.
- */
-#define __DRI_ALLOCATE "DRI_Allocate"
-#define __DRI_ALLOCATE_VERSION 1
-struct __DRIallocateExtensionRec {
-    __DRIextension base;
-
-    void *(*allocateMemory)(__DRIscreen *screen, GLsizei size,
-                           GLfloat readfreq, GLfloat writefreq,
-                           GLfloat priority);
-   
-    void (*freeMemory)(__DRIscreen *screen, GLvoid *pointer);
-   
-    GLuint (*memoryOffset)(__DRIscreen *screen, const GLvoid *pointer);
-};
-
 /**
  * Used by drivers that implement the GLX_MESA_swap_frame_usage extension.
  */
index dd7275460dae08b595f2db04256c95f3502976ec..03a4ef58815f1cf434ecaf9a40709f01fd93214c 100644 (file)
@@ -282,6 +282,9 @@ def generate(env):
                 ccflags += [
                     '-mmmx', '-msse', '-msse2', # enable SIMD intrinsics
                 ]
+            if platform in ['windows', 'darwin']:
+                # Workaround http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37216
+                ccflags += ['-fno-common']
             if distutils.version.LooseVersion(ccversion) >= distutils.version.LooseVersion('4.2'):
                 ccflags += [
                     '-mstackrealign', # ensure stack is aligned
@@ -292,7 +295,6 @@ def generate(env):
         # - http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
         ccflags += [
             '-Wall',
-            '-Wmissing-field-initializers',
             '-Wno-long-long',
             '-ffast-math',
             '-fmessage-length=0', # be nice to Eclipse
@@ -301,6 +303,10 @@ def generate(env):
             '-Wmissing-prototypes',
             '-std=gnu99',
         ]
+        if distutils.version.LooseVersion(ccversion) >= distutils.version.LooseVersion('4.0'):
+            ccflags += [
+                '-Wmissing-field-initializers',
+            ]
         if distutils.version.LooseVersion(ccversion) >= distutils.version.LooseVersion('4.2'):
             ccflags += [
                 '-Werror=pointer-arith',
index 9e359a92384b6e6861c2d82e3de166bc1d908c67..831a7603396959b3cc3a71b857a5179d5d5c737a 100644 (file)
@@ -36,7 +36,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 /* THIS IS NOT AN X CONSORTIUM STANDARD */
 
-#define NEED_REPLIES
 #include <X11/Xlibint.h>
 #include <X11/extensions/Xext.h>
 #include <X11/extensions/extutil.h>
index 4e760aec4c87554603338ffeb9084bafbee4b6f2..8a3c9b6a0aa9c7409c8b65d2a117a35f622c86be 100644 (file)
@@ -11,8 +11,10 @@ EGL_INCLUDES = \
        -I$(TOP)/src/egl/main \
        -I$(TOP)/src/mapi \
        -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \
-       $(EGL_DRI2_CFLAGS)
+       $(XCB_DRI2_CFLAGS) \
+       $(LIBUDEV_CFLAGS) \
+       $(LIBDRM_CFLAGS)
 
-EGL_LIBS = $(EGL_DRI2_LIBS)
+EGL_LIBS = $(XCB_DRI2_LIBS) $(LIBUDEV_LIBS) $(LIBDRM_LIBS)
 
 include ../Makefile.template
index aa384cb11725a0fca85a208101948e58d6afa9d4..c6d79a64e8aaeabcf7c732f15b09060cf8d51545 100644 (file)
 #include <xcb/dri2.h>
 #include <xcb/xfixes.h>
 #include <X11/Xlib-xcb.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_LIBUDEV
+#include <libudev.h>
+#endif
 
 #include <glapi/glapi.h>
 #include "eglconfig.h"
@@ -79,7 +85,6 @@ struct dri2_egl_display
    char                     *driver_name;
 
    __DRIdri2LoaderExtension  loader_extension;
-   __DRIimageLookupExtension image_lookup_extension;
    const __DRIextension     *extensions[3];
 };
 
@@ -117,6 +122,10 @@ struct dri2_egl_image
 _EGL_DRIVER_STANDARD_TYPECASTS(dri2_egl)
 _EGL_DRIVER_TYPECAST(dri2_egl_image, _EGLImage, obj)
 
+static const __DRIuseInvalidateExtension use_invalidate = {
+   { __DRI_USE_INVALIDATE, 1 }
+};
+
 EGLint dri2_to_egl_attribute_map[] = {
    0,
    EGL_BUFFER_SIZE,            /* __DRI_ATTRIB_BUFFER_SIZE */
@@ -381,6 +390,11 @@ dri2_lookup_egl_image(__DRIcontext *context, void *image, void *data)
    return dri2_img->dri_image;
 }
 
+static const __DRIimageLookupExtension image_lookup_extension = {
+   { __DRI_IMAGE_LOOKUP, 1 },
+   dri2_lookup_egl_image
+};
+
 static __DRIbuffer *
 dri2_get_buffers_with_format(__DRIdrawable * driDrawable,
                             int *width, int *height,
@@ -620,7 +634,7 @@ dri2_add_configs_for_visuals(struct dri2_egl_display *dri2_dpy,
       xcb_depth_next(&d);      
    }
 
-   if (!disp->NumConfigs) {
+   if (!_eglGetArraySize(disp->Configs)) {
       _eglLog(_EGL_WARNING, "DRI2: failed to create any config");
       return EGL_FALSE;
    }
@@ -690,27 +704,63 @@ dri2_load_driver(_EGLDisplay *disp)
    return EGL_TRUE;
 }
 
-
-/**
- * Called via eglInitialize(), GLX_drv->API.Initialize().
- */
 static EGLBoolean
-dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
-               EGLint *major, EGLint *minor)
+dri2_create_screen(_EGLDisplay *disp)
 {
    const __DRIextension **extensions;
    struct dri2_egl_display *dri2_dpy;
    unsigned int api_mask;
 
+   dri2_dpy = disp->DriverData;
+   dri2_dpy->dri_screen =
+      dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, dri2_dpy->extensions,
+                                     &dri2_dpy->driver_configs, dri2_dpy);
+
+   if (dri2_dpy->dri_screen == NULL) {
+      _eglLog(_EGL_WARNING, "DRI2: failed to create dri screen");
+      return EGL_FALSE;
+   }
+
+   extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen);
+   if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions))
+      goto cleanup_dri_screen;
+
+   if (dri2_dpy->dri2->base.version >= 2)
+      api_mask = dri2_dpy->dri2->getAPIMask(dri2_dpy->dri_screen);
+   else
+      api_mask = __DRI_API_OPENGL;
+
+   disp->ClientAPIsMask = 0;
+   if (api_mask & (1 <<__DRI_API_OPENGL))
+      disp->ClientAPIsMask |= EGL_OPENGL_BIT;
+   if (api_mask & (1 <<__DRI_API_GLES))
+      disp->ClientAPIsMask |= EGL_OPENGL_ES_BIT;
+   if (api_mask & (1 << __DRI_API_GLES2))
+      disp->ClientAPIsMask |= EGL_OPENGL_ES2_BIT;
+
+   return EGL_TRUE;
+
+ cleanup_dri_screen:
+   dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
+
+   return EGL_FALSE;
+}
+
+static EGLBoolean
+dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp,
+                   EGLint *major, EGLint *minor)
+{
+   struct dri2_egl_display *dri2_dpy;
+
    dri2_dpy = malloc(sizeof *dri2_dpy);
    if (!dri2_dpy)
       return _eglError(EGL_BAD_ALLOC, "eglInitialize");
 
    disp->DriverData = (void *) dri2_dpy;
-   if (disp->NativeDisplay == NULL) {
+   if (disp->PlatformDisplay == NULL) {
       dri2_dpy->conn = xcb_connect(0, 0);
    } else {
-      dri2_dpy->conn = XGetXCBConnection(disp->NativeDisplay);
+      dri2_dpy->conn = XGetXCBConnection((Display *) disp->PlatformDisplay);
    }
 
    if (xcb_connection_has_error(dri2_dpy->conn)) {
@@ -754,39 +804,12 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
       dri2_dpy->loader_extension.getBuffersWithFormat = NULL;
    }
       
-   dri2_dpy->image_lookup_extension.base.name = __DRI_IMAGE_LOOKUP;
-   dri2_dpy->image_lookup_extension.base.version = 1;
-   dri2_dpy->image_lookup_extension.lookupEGLImage = dri2_lookup_egl_image;
-
    dri2_dpy->extensions[0] = &dri2_dpy->loader_extension.base;
-   dri2_dpy->extensions[1] = &dri2_dpy->image_lookup_extension.base;
+   dri2_dpy->extensions[1] = &image_lookup_extension.base;
    dri2_dpy->extensions[2] = NULL;
 
-   dri2_dpy->dri_screen =
-      dri2_dpy->dri2->createNewScreen(0, dri2_dpy->fd, dri2_dpy->extensions,
-                                     &dri2_dpy->driver_configs, dri2_dpy);
-
-   if (dri2_dpy->dri_screen == NULL) {
-      _eglLog(_EGL_WARNING, "DRI2: failed to create dri screen");
+   if (!dri2_create_screen(disp))
       goto cleanup_fd;
-   }
-
-   extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen);
-   if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions))
-      goto cleanup_dri_screen;
-
-   if (dri2_dpy->dri2->base.version >= 2)
-      api_mask = dri2_dpy->dri2->getAPIMask(dri2_dpy->dri_screen);
-   else
-      api_mask = __DRI_API_OPENGL;
-
-   disp->ClientAPIsMask = 0;
-   if (api_mask & (1 <<__DRI_API_OPENGL))
-      disp->ClientAPIsMask |= EGL_OPENGL_BIT;
-   if (api_mask & (1 <<__DRI_API_GLES))
-      disp->ClientAPIsMask |= EGL_OPENGL_ES_BIT;
-   if (api_mask & (1 << __DRI_API_GLES2))
-      disp->ClientAPIsMask |= EGL_OPENGL_ES2_BIT;
 
    if (dri2_dpy->conn) {
       if (!dri2_add_configs_for_visuals(dri2_dpy, disp))
@@ -808,14 +831,13 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
 
  cleanup_configs:
    _eglCleanupDisplay(disp);
- cleanup_dri_screen:
    dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
  cleanup_fd:
    close(dri2_dpy->fd);
  cleanup_driver:
    dlclose(dri2_dpy->driver);
  cleanup_conn:
-   if (disp->NativeDisplay == NULL)
+   if (disp->PlatformDisplay == NULL)
       xcb_disconnect(dri2_dpy->conn);
  cleanup_dpy:
    free(dri2_dpy);
@@ -823,6 +845,168 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
    return EGL_FALSE;
 }
 
+#ifdef HAVE_LIBUDEV
+
+struct dri2_driver_map {
+   int vendor_id;
+   const char *driver;
+   const int *chip_ids;
+   int num_chips_ids;
+};
+
+const int i915_chip_ids[] = {
+   0x3577, /* PCI_CHIP_I830_M */
+   0x2562, /* PCI_CHIP_845_G */
+   0x3582, /* PCI_CHIP_I855_GM */
+   0x2572, /* PCI_CHIP_I865_G */
+   0x2582, /* PCI_CHIP_I915_G */
+   0x258a, /* PCI_CHIP_E7221_G */
+   0x2592, /* PCI_CHIP_I915_GM */
+   0x2772, /* PCI_CHIP_I945_G */
+   0x27a2, /* PCI_CHIP_I945_GM */
+   0x27ae, /* PCI_CHIP_I945_GME */
+   0x29b2, /* PCI_CHIP_Q35_G */
+   0x29c2, /* PCI_CHIP_G33_G */
+   0x29d2, /* PCI_CHIP_Q33_G */
+};
+
+const int i965_chip_ids[] = {
+   0x29a2, /* PCI_CHIP_I965_G */
+   0x2992, /* PCI_CHIP_I965_Q */
+   0x2982, /* PCI_CHIP_I965_G_1 */
+   0x2972, /* PCI_CHIP_I946_GZ */
+   0x2a02, /* PCI_CHIP_I965_GM */
+   0x2a12, /* PCI_CHIP_I965_GME */
+   0x2a42, /* PCI_CHIP_GM45_GM */
+   0x2e02, /* PCI_CHIP_IGD_E_G */
+   0x2e12, /* PCI_CHIP_Q45_G */
+   0x2e22, /* PCI_CHIP_G45_G */
+   0x2e32, /* PCI_CHIP_G41_G */
+};
+
+const struct dri2_driver_map driver_map[] = {
+   { 0x8086, "i915", i915_chip_ids, ARRAY_SIZE(i915_chip_ids) },
+   { 0x8086, "i965", i965_chip_ids, ARRAY_SIZE(i965_chip_ids) },
+};
+
+static char *
+dri2_get_driver_for_fd(int fd)
+{
+   struct udev *udev;
+   struct udev_device *device, *parent;
+   struct stat buf;
+   const char *pci_id;
+   char *driver = NULL;
+   int vendor_id, chip_id, i, j;
+
+   udev = udev_new();
+   if (fstat(fd, &buf) < 0) {
+      _eglLog(_EGL_WARNING, "EGL-DRI2: failed to stat fd %d", fd);
+      goto out;
+   }
+
+   device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev);
+   if (device == NULL) {
+      _eglLog(_EGL_WARNING,
+             "EGL-DRI2: could not create udev device for fd %d", fd);
+      goto out;
+   }
+
+   parent = udev_device_get_parent(device);
+   if (parent == NULL) {
+      _eglLog(_EGL_WARNING, "DRI2: could not get parent device");
+      goto out;
+   }
+
+   pci_id = udev_device_get_property_value(parent, "PCI_ID");
+   if (pci_id == NULL || sscanf(pci_id, "%x:%x", &vendor_id, &chip_id) != 2) {
+      _eglLog(_EGL_WARNING, "EGL-DRI2: malformed or no PCI ID");
+      goto out;
+   }
+
+   for (i = 0; i < ARRAY_SIZE(driver_map); i++) {
+      if (vendor_id != driver_map[i].vendor_id)
+        continue;
+      for (j = 0; j < driver_map[i].num_chips_ids; j++)
+        if (driver_map[i].chip_ids[j] == chip_id) {
+           driver = strdup(driver_map[i].driver);
+           _eglLog(_EGL_DEBUG, "pci id for %d: %04x:%04x, driver %s",
+                   fd, vendor_id, chip_id, driver);
+           goto out;
+        }
+   }
+
+ out:
+   udev_device_unref(device);
+   udev_unref(udev);
+
+   return driver;
+}
+
+static EGLBoolean
+dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp,
+                   EGLint *major, EGLint *minor)
+{
+   struct dri2_egl_display *dri2_dpy;
+
+   dri2_dpy = malloc(sizeof *dri2_dpy);
+   if (!dri2_dpy)
+      return _eglError(EGL_BAD_ALLOC, "eglInitialize");
+
+   disp->DriverData = (void *) dri2_dpy;
+   dri2_dpy->fd = (int) disp->PlatformDisplay;
+
+   dri2_dpy->driver_name = dri2_get_driver_for_fd(dri2_dpy->fd);
+   if (dri2_dpy->driver_name == NULL)
+      return _eglError(EGL_BAD_ALLOC, "DRI2: failed to get driver name");
+
+   if (!dri2_load_driver(disp))
+      goto cleanup_driver_name;
+
+   dri2_dpy->extensions[0] = &image_lookup_extension.base;
+   dri2_dpy->extensions[1] = &use_invalidate.base;
+   dri2_dpy->extensions[2] = NULL;
+
+   if (!dri2_create_screen(disp))
+      goto cleanup_driver;
+
+   disp->Extensions.KHR_image_base = EGL_TRUE;
+   disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
+   disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
+
+   return EGL_TRUE;
+
+ cleanup_driver:
+   dlclose(dri2_dpy->driver);
+ cleanup_driver_name:
+   free(dri2_dpy->driver_name);
+
+   return EGL_FALSE;
+}
+
+#endif
+
+/**
+ * Called via eglInitialize(), GLX_drv->API.Initialize().
+ */
+static EGLBoolean
+dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
+               EGLint *major, EGLint *minor)
+{
+   switch (disp->Platform) {
+   case _EGL_PLATFORM_X11:
+      return dri2_initialize_x11(drv, disp, major, minor);
+
+#ifdef HAVE_LIBUDEV
+   case _EGL_PLATFORM_DRM:
+      return dri2_initialize_drm(drv, disp, major, minor);
+#endif
+
+   default:
+      return EGL_FALSE;
+   }
+}
+
 /**
  * Called via eglTerminate(), drv->API.Terminate().
  */
@@ -837,7 +1021,7 @@ dri2_terminate(_EGLDriver *drv, _EGLDisplay *disp)
    dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
    close(dri2_dpy->fd);
    dlclose(dri2_dpy->driver);
-   if (disp->NativeDisplay == NULL)
+   if (disp->PlatformDisplay == NULL)
       xcb_disconnect(dri2_dpy->conn);
    free(dri2_dpy);
    disp->DriverData = NULL;
index e08ef5f2228111f3d387190b2be41f193bd7c322..b4a40d14377201680329a45180709e75c735ba94 100644 (file)
@@ -498,11 +498,14 @@ GLX_eglInitialize(_EGLDriver *drv, _EGLDisplay *disp,
 {
    struct GLX_egl_display *GLX_dpy;
 
+   if (disp->Platform != _EGL_PLATFORM_X11)
+      return EGL_FALSE;
+
    GLX_dpy = CALLOC_STRUCT(GLX_egl_display);
    if (!GLX_dpy)
       return _eglError(EGL_BAD_ALLOC, "eglInitialize");
 
-   GLX_dpy->dpy = (Display *) disp->NativeDisplay;
+   GLX_dpy->dpy = (Display *) disp->PlatformDisplay;
    if (!GLX_dpy->dpy) {
       GLX_dpy->dpy = XOpenDisplay(NULL);
       if (!GLX_dpy->dpy) {
@@ -514,7 +517,7 @@ GLX_eglInitialize(_EGLDriver *drv, _EGLDisplay *disp,
 
    if (!glXQueryVersion(GLX_dpy->dpy, &GLX_dpy->glx_maj, &GLX_dpy->glx_min)) {
       _eglLog(_EGL_WARNING, "GLX: glXQueryVersion failed");
-      if (!disp->NativeDisplay)
+      if (!disp->PlatformDisplay)
          XCloseDisplay(GLX_dpy->dpy);
       free(GLX_dpy);
       return EGL_FALSE;
@@ -524,9 +527,9 @@ GLX_eglInitialize(_EGLDriver *drv, _EGLDisplay *disp,
    check_quirks(GLX_dpy, DefaultScreen(GLX_dpy->dpy));
 
    create_configs(disp, GLX_dpy, DefaultScreen(GLX_dpy->dpy));
-   if (!disp->NumConfigs) {
+   if (!_eglGetArraySize(disp->Configs)) {
       _eglLog(_EGL_WARNING, "GLX: failed to create any config");
-      if (!disp->NativeDisplay)
+      if (!disp->PlatformDisplay)
          XCloseDisplay(GLX_dpy->dpy);
       free(GLX_dpy);
       return EGL_FALSE;
@@ -558,7 +561,7 @@ GLX_eglTerminate(_EGLDriver *drv, _EGLDisplay *disp)
    if (GLX_dpy->fbconfigs)
       XFree(GLX_dpy->fbconfigs);
 
-   if (!disp->NativeDisplay)
+   if (!disp->PlatformDisplay)
       XCloseDisplay(GLX_dpy->dpy);
    free(GLX_dpy);
 
@@ -617,10 +620,11 @@ GLX_eglCreateContext(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
 static void
 destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
 {
+   struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
    struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf);
 
    if (GLX_surf->destroy)
-      GLX_surf->destroy(disp->NativeDisplay, GLX_surf->glx_drawable);
+      GLX_surf->destroy(GLX_dpy->dpy, GLX_surf->glx_drawable);
 
    free(GLX_surf);
 }
index d9e9e4fcd6d5214401b7eb70df732dfdbee84fb6..41d301fc14056b6b3a02f659b354308a1b0f060d 100644 (file)
@@ -30,6 +30,7 @@ HEADERS = \
 
 SOURCES = \
        eglapi.c \
+       eglarray.c \
        eglconfig.c \
        eglconfigutil.c \
        eglcontext.c \
@@ -51,10 +52,20 @@ OBJECTS = $(SOURCES:.c=.o)
 # use dl*() to load drivers
 LOCAL_CFLAGS = -D_EGL_OS_UNIX=1
 
-EGL_DEFAULT_PLATFORM = $(firstword $(EGL_PLATFORMS))
+# translate --with-egl-platforms to _EGLPlatformType
+EGL_NATIVE_PLATFORM=_EGL_INVALID_PLATFORM
+ifeq ($(firstword $(EGL_PLATFORMS)),x11)
+EGL_NATIVE_PLATFORM=_EGL_PLATFORM_X11
+endif
+ifeq ($(firstword $(EGL_PLATFORMS)),kms)
+EGL_NATIVE_PLATFORM=_EGL_PLATFORM_DRM
+endif
+ifeq ($(firstword $(EGL_PLATFORMS)),fbdev)
+EGL_NATIVE_PLATFORM=_EGL_PLATFORM_FBDEV
+endif
 
 LOCAL_CFLAGS += \
-       -D_EGL_DEFAULT_PLATFORM=\"$(EGL_DEFAULT_PLATFORM)\" \
+       -D_EGL_NATIVE_PLATFORM=$(EGL_NATIVE_PLATFORM) \
        -D_EGL_DRIVER_SEARCH_DIR=\"$(EGL_DRIVER_INSTALL_DIR)\"
 
 .c.o:
index a331c9711ec636d893863b7577d56898340ede72..3d7ae3a8e4ebe8c355694538d5aa6cd25e205e8f 100644 (file)
@@ -9,7 +9,7 @@ if env['platform'] != 'winddk':
        env = env.Clone()
 
        env.Append(CPPDEFINES = [
-               '_EGL_DEFAULT_DISPLAY=\\"gdi\\"',
+               '_EGL_NATIVE_PLATFORM=_EGL_PLATFORM_WINDOWS',
                '_EGL_DRIVER_SEARCH_DIR=\\"\\"',
                '_EGL_OS_WINDOWS',
                'KHRONOS_DLL_EXPORTS',
@@ -21,6 +21,7 @@ if env['platform'] != 'winddk':
 
        egl_sources = [
                'eglapi.c',
+               'eglarray.c',
                'eglconfig.c',
                'eglconfigutil.c',
                'eglcontext.c',
index 9912043e06c61eab3103586f0fd2768de173aea0..09271140b132a40e22c8ac1a3476635b329ef910 100644 (file)
@@ -61,7 +61,6 @@
 #include "eglcontext.h"
 #include "egldisplay.h"
 #include "egltypedefs.h"
-#include "eglglobals.h"
 #include "eglcurrent.h"
 #include "egldriver.h"
 #include "eglsurface.h"
@@ -250,7 +249,8 @@ _eglUnlockDisplay(_EGLDisplay *dpy)
 EGLDisplay EGLAPIENTRY
 eglGetDisplay(EGLNativeDisplayType nativeDisplay)
 {
-   _EGLDisplay *dpy = _eglFindDisplay(nativeDisplay);
+   _EGLPlatformType plat = _eglGetNativePlatform();
+   _EGLDisplay *dpy = _eglFindDisplay(plat, (void *) nativeDisplay);
    return _eglGetDisplayHandle(dpy);
 }
 
@@ -263,46 +263,24 @@ EGLBoolean EGLAPIENTRY
 eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
-   EGLint major_int = 0, minor_int = 0;
 
    if (!disp)
       RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
 
    if (!disp->Initialized) {
-      _EGLDriver *drv = disp->Driver;
-
-      if (!drv) {
-         _eglPreloadDrivers();
-         drv = _eglMatchDriver(disp);
-        /* Initialize the particular display now */
-        if (drv && !drv->API.Initialize(drv, disp, &major_int, &minor_int))
-           RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
-      }
-      if (!drv)
-        /* Load and initialize the first default driver that works */
-        drv = _eglLoadDefaultDriver(disp, &major_int, &minor_int);
-      if (!drv)
-        RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
-
-      disp->APImajor = major_int;
-      disp->APIminor = minor_int;
-      _eglsnprintf(disp->Version, sizeof(disp->Version),
-               "%d.%d (%s)", major_int, minor_int, drv->Name);
+      if (!_eglMatchDriver(disp, EGL_FALSE))
+         RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
 
+      _eglsnprintf(disp->Version, sizeof(disp->Version), "%d.%d (%s)",
+            disp->APImajor, disp->APIminor, disp->Driver->Name);
       /* limit to APIs supported by core */
       disp->ClientAPIsMask &= _EGL_API_ALL_BITS;
-
-      disp->Driver = drv;
-      disp->Initialized = EGL_TRUE;
-   } else {
-      major_int = disp->APImajor;
-      minor_int = disp->APIminor;
    }
 
    /* Update applications version of major and minor if not NULL */
    if ((major != NULL) && (minor != NULL)) {
-      *major = major_int;
-      *minor = minor_int;
+      *major = disp->APImajor;
+      *minor = disp->APIminor;
    }
 
    RETURN_EGL_SUCCESS(disp, EGL_TRUE);
@@ -491,6 +469,8 @@ eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
    EGLSurface ret;
 
    _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
+   if (disp->Platform != _eglGetNativePlatform())
+      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
 
    surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list);
    ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
@@ -510,6 +490,8 @@ eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
    EGLSurface ret;
 
    _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE, drv);
+   if (disp->Platform != _eglGetNativePlatform())
+      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
 
    surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list);
    ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE;
@@ -667,6 +649,8 @@ eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
    EGLBoolean ret;
 
    _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
+   if (disp->Platform != _eglGetNativePlatform())
+      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_FALSE);
    ret = drv->API.CopyBuffers(drv, disp, surf, target);
 
    RETURN_EGL_EVAL(disp, ret);
@@ -836,6 +820,9 @@ eglGetProcAddress(const char *procname)
       { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },
       { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },
 #endif /* EGL_MESA_screen_surface */
+#ifdef EGL_MESA_drm_display
+      { "eglGetDRMDisplayMESA", (_EGLProc) eglGetDRMDisplayMESA },
+#endif
 #ifdef EGL_KHR_image_base
       { "eglCreateImageKHR", (_EGLProc) eglCreateImageKHR },
       { "eglDestroyImageKHR", (_EGLProc) eglDestroyImageKHR },
@@ -860,18 +847,8 @@ eglGetProcAddress(const char *procname)
          }
       }
    }
-   if (ret)
-      RETURN_EGL_SUCCESS(NULL, ret);
-
-   _eglPreloadDrivers();
-
-   /* now loop over drivers to query their procs */
-   for (i = 0; i < _eglGlobal.NumDrivers; i++) {
-      _EGLDriver *drv = _eglGlobal.Drivers[i];
-      ret = drv->API.GetProcAddress(drv, procname);
-      if (ret)
-         break;
-   }
+   if (!ret)
+      ret = _eglGetDriverProc(procname);
 
    RETURN_EGL_SUCCESS(NULL, ret);
 }
@@ -955,7 +932,7 @@ eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest,
 }
 
 
-EGLBoolean
+EGLBoolean EGLAPIENTRY
 eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
                   EGLint max_screens, EGLint *num_screens)
 {
@@ -970,7 +947,7 @@ eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
 }
 
 
-EGLSurface
+EGLSurface EGLAPIENTRY
 eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
                            const EGLint *attrib_list)
 {
@@ -989,7 +966,7 @@ eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
 }
 
 
-EGLBoolean
+EGLBoolean EGLAPIENTRY
 eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen,
                          EGLSurface surface, EGLModeMESA mode)
 {
@@ -1012,7 +989,7 @@ eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen,
 }
 
 
-EGLBoolean
+EGLBoolean EGLAPIENTRY
 eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
@@ -1027,7 +1004,7 @@ eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
 }
 
 
-EGLBoolean
+EGLBoolean EGLAPIENTRY
 eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
                    EGLint attribute, EGLint *value)
 {
@@ -1043,7 +1020,7 @@ eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
 }
 
 
-EGLBoolean
+EGLBoolean EGLAPIENTRY
 eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
                           EGLSurface *surface)
 {
@@ -1062,7 +1039,7 @@ eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
 }
 
 
-EGLBoolean
+EGLBoolean EGLAPIENTRY
 eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
@@ -1080,7 +1057,7 @@ eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
 }
 
 
-const char *
+const char * EGLAPIENTRY
 eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
@@ -1098,6 +1075,17 @@ eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
 #endif /* EGL_MESA_screen_surface */
 
 
+#ifdef EGL_MESA_drm_display
+
+EGLDisplay EGLAPIENTRY
+eglGetDRMDisplayMESA(int fd)
+{
+   _EGLDisplay *dpy = _eglFindDisplay(_EGL_PLATFORM_DRM, (void *) fd);
+   return _eglGetDisplayHandle(dpy);
+}
+
+#endif /* EGL_MESA_drm_display */
+
 /**
  ** EGL 1.2
  **/
@@ -1116,7 +1104,7 @@ eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
  *  eglWaitNative()
  * See section 3.7 "Rendering Context" in the EGL specification for details.
  */
-EGLBoolean
+EGLBoolean EGLAPIENTRY
 eglBindAPI(EGLenum api)
 {
    _EGLThreadInfo *t = _eglGetCurrentThread();
@@ -1136,7 +1124,7 @@ eglBindAPI(EGLenum api)
 /**
  * Return the last value set with eglBindAPI().
  */
-EGLenum
+EGLenum EGLAPIENTRY
 eglQueryAPI(void)
 {
    _EGLThreadInfo *t = _eglGetCurrentThread();
@@ -1149,7 +1137,7 @@ eglQueryAPI(void)
 }
 
 
-EGLSurface
+EGLSurface EGLAPIENTRY
 eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
                                  EGLClientBuffer buffer, EGLConfig config,
                                  const EGLint *attrib_list)
@@ -1170,7 +1158,7 @@ eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
 }
 
 
-EGLBoolean
+EGLBoolean EGLAPIENTRY
 eglReleaseThread(void)
 {
    /* unbind current contexts */
@@ -1209,7 +1197,7 @@ eglReleaseThread(void)
 #ifdef EGL_KHR_image_base
 
 
-EGLImageKHR
+EGLImageKHR EGLAPIENTRY
 eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
                   EGLClientBuffer buffer, const EGLint *attr_list)
 {
@@ -1231,7 +1219,7 @@ eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
 }
 
 
-EGLBoolean
+EGLBoolean EGLAPIENTRY
 eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
@@ -1255,7 +1243,7 @@ eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
 
 #ifdef EGL_NOK_swap_region
 
-EGLBoolean
+EGLBoolean EGLAPIENTRY
 eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
                        EGLint numRects, const EGLint *rects)
 {
diff --git a/src/egl/main/eglarray.c b/src/egl/main/eglarray.c
new file mode 100644 (file)
index 0000000..d686fa1
--- /dev/null
@@ -0,0 +1,180 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include "egllog.h"
+#include "eglarray.h"
+
+
+/**
+ * Grow the size of the array.
+ */
+static EGLBoolean
+_eglGrowArray(_EGLArray *array)
+{
+   EGLint new_size;
+   void **elems;
+
+   new_size = array->MaxSize;
+   while (new_size <= array->Size)
+      new_size *= 2;
+
+   elems = realloc(array->Elements, new_size * sizeof(array->Elements[0]));
+   if (!elems) {
+      _eglLog(_EGL_DEBUG, "failed to grow %s array to %d",
+            array->Name, new_size);
+      return EGL_FALSE;
+   }
+
+   array->Elements = elems;
+   array->MaxSize = new_size;
+
+   return EGL_TRUE;
+}
+
+
+/**
+ * Create an array.
+ */
+_EGLArray *
+_eglCreateArray(const char *name, EGLint init_size)
+{
+   _EGLArray *array;
+
+   array = calloc(1, sizeof(*array));
+   if (array) {
+      array->Name = name;
+      array->MaxSize = (init_size > 0) ? init_size : 1;
+      if (!_eglGrowArray(array)) {
+         free(array);
+         array = NULL;
+      }
+   }
+
+   return array;
+}
+
+
+/**
+ * Destroy an array, optionally free the data.
+ */
+void
+_eglDestroyArray(_EGLArray *array, void (*free_cb)(void *))
+{
+   if (free_cb) {
+      EGLint i;
+      for (i = 0; i < array->Size; i++)
+         free_cb(array->Elements[i]);
+   }
+   free(array->Elements);
+   free(array);
+}
+
+
+/**
+ * Append a element to an array.
+ */
+void
+_eglAppendArray(_EGLArray *array, void *elem)
+{
+   if (array->Size >= array->MaxSize && !_eglGrowArray(array))
+      return;
+
+   array->Elements[array->Size++] = elem;
+}
+
+
+/**
+ * Erase an element from an array.
+ */
+void
+_eglEraseArray(_EGLArray *array, EGLint i, void (*free_cb)(void *))
+{
+   if (free_cb)
+      free_cb(array->Elements[i]);
+   if (i < array->Size - 1) {
+      memmove(&array->Elements[i], &array->Elements[i + 1],
+            (array->Size - i - 1) * sizeof(array->Elements[0]));
+   }
+   array->Size--;
+}
+
+
+/**
+ * Find in an array for the given element.
+ */
+void *
+_eglFindArray(_EGLArray *array, void *elem)
+{
+   EGLint i;
+
+   if (!array)
+      return NULL;
+
+   for (i = 0; i < array->Size; i++)
+      if (array->Elements[i] == elem)
+         return elem;
+   return NULL;
+}
+
+
+/**
+ * Filter an array and return the filtered data.  The returned data pointer
+ * should be freed.
+ */
+void **
+_eglFilterArray(_EGLArray *array, EGLint *size,
+                _EGLArrayForEach filter, void *filter_data)
+{
+   void **data;
+   EGLint count = 0, i;
+
+   if (!array) {
+      *size = 0;
+      return malloc(0);
+   }
+
+   data = malloc(array->Size * sizeof(array->Elements[0]));
+   if (!data)
+      return NULL;
+
+   if (filter) {
+      for (i = 0; i < array->Size; i++) {
+         if (filter(array->Elements[i], filter_data))
+            data[count++] = array->Elements[i];
+      }
+   }
+   else {
+      memcpy(data, array->Elements, array->Size * sizeof(array->Elements[0]));
+   }
+
+   *size = count;
+
+   return data;
+}
+
+
+/**
+ * Flatten an array by converting array elements into another form and store
+ * them in a buffer.
+ */
+EGLint
+_eglFlattenArray(_EGLArray *array, void *buffer, EGLint elem_size, EGLint size,
+                 _EGLArrayForEach flatten)
+{
+   EGLint i, count;
+
+   if (!array)
+      return 0;
+
+   count = array->Size;
+   if (buffer) {
+      /* do not exceed buffer size */
+      if (count > size)
+         count = size;
+      for (i = 0; i < count; i++)
+         flatten(array->Elements[i],
+               (void *) ((char *) buffer + elem_size * i));
+   }
+
+   return count;
+}
diff --git a/src/egl/main/eglarray.h b/src/egl/main/eglarray.h
new file mode 100644 (file)
index 0000000..fe92efc
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef EGLARRAY_INCLUDED
+#define EGLARRAY_INCLUDED
+
+
+#include "egltypedefs.h"
+
+
+typedef EGLBoolean (*_EGLArrayForEach)(void *elem, void *foreach_data);
+
+
+struct _egl_array {
+   const char *Name;
+   EGLint MaxSize;
+
+   void **Elements;
+   EGLint Size;
+};
+
+
+extern _EGLArray *
+_eglCreateArray(const char *name, EGLint init_size);
+
+
+PUBLIC void
+_eglDestroyArray(_EGLArray *array, void (*free_cb)(void *));
+
+
+extern void
+_eglAppendArray(_EGLArray *array, void *elem);
+
+
+extern void
+_eglEraseArray(_EGLArray *array, EGLint i, void (*free_cb)(void *));
+
+
+void *
+_eglFindArray(_EGLArray *array, void *elem);
+
+
+void **
+_eglFilterArray(_EGLArray *array, EGLint *size,
+                _EGLArrayForEach filter, void *filter_data);
+
+
+EGLint
+_eglFlattenArray(_EGLArray *array, void *buffer, EGLint elem_size, EGLint size,
+                 _EGLArrayForEach flatten);
+
+
+static INLINE EGLint
+_eglGetArraySize(_EGLArray *array)
+{
+   return (array) ? array->Size : 0;
+}
+
+
+#endif /* EGLARRAY_INCLUDED */
index fa947d7688759510eb80640b8346eaf5d27ba238..a9af3200976bf0b1f290ac1e3c34468c23a77798 100644 (file)
@@ -50,26 +50,17 @@ _eglInitConfig(_EGLConfig *config, _EGLDisplay *dpy, EGLint id)
 EGLConfig
 _eglAddConfig(_EGLDisplay *dpy, _EGLConfig *conf)
 {
-   _EGLConfig **configs;
-
    /* sanity check */
    assert(GET_CONFIG_ATTRIB(conf, EGL_CONFIG_ID) > 0);
 
-   configs = dpy->Configs;
-   if (dpy->NumConfigs >= dpy->MaxConfigs) {
-      EGLint new_size = dpy->MaxConfigs + 16;
-      assert(dpy->NumConfigs < new_size);
-
-      configs = realloc(dpy->Configs, new_size * sizeof(dpy->Configs[0]));
-      if (!configs)
+   if (!dpy->Configs) {
+      dpy->Configs = _eglCreateArray("Config", 16);
+      if (!dpy->Configs)
          return (EGLConfig) NULL;
-
-      dpy->Configs = configs;
-      dpy->MaxConfigs = new_size;
    }
 
    conf->Display = dpy;
-   dpy->Configs[dpy->NumConfigs++] = conf;
+   _eglAppendArray(dpy->Configs, (void *) conf);
 
    return (EGLConfig) conf;
 }
@@ -78,17 +69,13 @@ _eglAddConfig(_EGLDisplay *dpy, _EGLConfig *conf)
 EGLBoolean
 _eglCheckConfigHandle(EGLConfig config, _EGLDisplay *dpy)
 {
-   EGLint num_configs = (dpy) ? dpy->NumConfigs : 0;
-   EGLint i;
+   _EGLConfig *conf;
 
-   for (i = 0; i < num_configs; i++) {
-      _EGLConfig *conf = dpy->Configs[i];
-      if (conf == (_EGLConfig *) config) {
-         assert(conf->Display == dpy);
-         break;
-      }
-   }
-   return (i < num_configs);
+   conf = (_EGLConfig *) _eglFindArray(dpy->Configs, (void *) config);
+   if (conf)
+      assert(conf->Display == dpy);
+
+   return (conf != NULL);
 }
 
 
@@ -776,19 +763,11 @@ _eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list,
    if (!_eglParseConfigAttribList(&criteria, attrib_list))
       return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
 
-   /* allocate array of config pointers */
-   configList = (_EGLConfig **)
-      malloc(disp->NumConfigs * sizeof(_EGLConfig *));
+   configList = (_EGLConfig **) _eglFilterArray(disp->Configs, &count,
+         (_EGLArrayForEach) _eglMatchConfig, (void *) &criteria);
    if (!configList)
       return _eglError(EGL_BAD_ALLOC, "eglChooseConfig(out of memory)");
 
-   /* perform selection of configs */
-   count = 0;
-   for (i = 0; i < disp->NumConfigs; i++) {
-      if (_eglMatchConfig(disp->Configs[i], &criteria))
-         configList[count++] = disp->Configs[i];
-   }
-
    /* perform sorting of configs */
    if (configs && count) {
       _eglSortConfigs((const _EGLConfig **) configList, count,
@@ -823,6 +802,15 @@ _eglGetConfigAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
 }
 
 
+static EGLBoolean
+_eglFlattenConfig(void *elem, void *buffer)
+{
+   _EGLConfig *conf = (_EGLConfig *) elem;
+   EGLConfig *handle = (EGLConfig *) buffer;
+   *handle = _eglGetConfigHandle(conf);
+   return EGL_TRUE;
+}
+
 /**
  * Fallback for eglGetConfigs.
  */
@@ -833,16 +821,8 @@ _eglGetConfigs(_EGLDriver *drv, _EGLDisplay *disp, EGLConfig *configs,
    if (!num_config)
       return _eglError(EGL_BAD_PARAMETER, "eglGetConfigs");
 
-   if (configs) {
-      EGLint i;
-      *num_config = MIN2(disp->NumConfigs, config_size);
-      for (i = 0; i < *num_config; i++)
-         configs[i] = _eglGetConfigHandle(disp->Configs[i]);
-   }
-   else {
-      /* just return total number of supported configs */
-      *num_config = disp->NumConfigs;
-   }
+   *num_config = _eglFlattenArray(disp->Configs, (void *) configs,
+         sizeof(configs[0]), config_size, _eglFlattenConfig);
 
    return EGL_TRUE;
 }
index 5dc5fd9719a682e029be8a470d3efbe2e8a0e691..31ff090484ce4790ff35e3c243c06c1179bd7422 100644 (file)
 #include "egllog.h"
 
 
+/**
+ * Return the native platform by parsing EGL_PLATFORM.
+ */
+static _EGLPlatformType
+_eglGetNativePlatformFromEnv(void)
+{
+   /* map --with-egl-platforms names to platform types */
+   static const struct {
+      _EGLPlatformType platform;
+      const char *name;
+   } egl_platforms[_EGL_NUM_PLATFORMS] = {
+      { _EGL_PLATFORM_WINDOWS, "gdi" },
+      { _EGL_PLATFORM_X11, "x11" },
+      { _EGL_PLATFORM_DRM, "kms" },
+      { _EGL_PLATFORM_FBDEV, "fbdev" }
+   };
+   _EGLPlatformType plat = _EGL_INVALID_PLATFORM;
+   const char *plat_name;
+   EGLint i;
+
+   plat_name = getenv("EGL_PLATFORM");
+   /* try deprecated env variable */
+   if (!plat_name || !plat_name[0])
+      plat_name = getenv("EGL_DISPLAY");
+   if (!plat_name || !plat_name[0])
+      return _EGL_INVALID_PLATFORM;
+
+   for (i = 0; i < _EGL_NUM_PLATFORMS; i++) {
+      if (strcmp(egl_platforms[i].name, plat_name) == 0) {
+         plat = egl_platforms[i].platform;
+         break;
+      }
+   }
+
+   return plat;
+}
+
+
+/**
+ * Return the native platform.  It is the platform of the EGL native types.
+ */
+_EGLPlatformType
+_eglGetNativePlatform(void)
+{
+   static _EGLPlatformType native_platform = _EGL_INVALID_PLATFORM;
+
+   if (native_platform == _EGL_INVALID_PLATFORM) {
+      native_platform = _eglGetNativePlatformFromEnv();
+      if (native_platform == _EGL_INVALID_PLATFORM)
+         native_platform = _EGL_NATIVE_PLATFORM;
+   }
+
+   return native_platform;
+}
+
+
 /**
  * Finish display management.
  */
@@ -49,16 +105,19 @@ _eglFiniDisplay(void)
  * new one.
  */
 _EGLDisplay *
-_eglFindDisplay(EGLNativeDisplayType nativeDisplay)
+_eglFindDisplay(_EGLPlatformType plat, void *plat_dpy)
 {
    _EGLDisplay *dpy;
 
+   if (plat == _EGL_INVALID_PLATFORM)
+      return NULL;
+
    _eglLockMutex(_eglGlobal.Mutex);
 
    /* search the display list first */
    dpy = _eglGlobal.DisplayList;
    while (dpy) {
-      if (dpy->NativeDisplay == nativeDisplay)
+      if (dpy->Platform == plat && dpy->PlatformDisplay == plat_dpy)
          break;
       dpy = dpy->Next;
    }
@@ -68,7 +127,8 @@ _eglFindDisplay(EGLNativeDisplayType nativeDisplay)
       dpy = (_EGLDisplay *) calloc(1, sizeof(_EGLDisplay));
       if (dpy) {
          _eglInitMutex(&dpy->Mutex);
-         dpy->NativeDisplay = nativeDisplay;
+         dpy->Platform = plat;
+         dpy->PlatformDisplay = plat_dpy;
 
          /* add to the display list */ 
          dpy->Next = _eglGlobal.DisplayList;
@@ -119,15 +179,9 @@ _eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *display)
 void
 _eglCleanupDisplay(_EGLDisplay *disp)
 {
-   EGLint i;
-
    if (disp->Configs) {
-      for (i = 0; i < disp->NumConfigs; i++)
-         free(disp->Configs[i]);
-      free(disp->Configs);
+      _eglDestroyArray(disp->Configs, free);
       disp->Configs = NULL;
-      disp->NumConfigs = 0;
-      disp->MaxConfigs = 0;
    }
 
    /* XXX incomplete */
index 42e305f91ac34073d248f6ad19ff86377d782b1b..0b2f26a4c07f6611157fd8b127a4c81731f41b07 100644 (file)
@@ -5,6 +5,19 @@
 #include "egltypedefs.h"
 #include "egldefines.h"
 #include "eglmutex.h"
+#include "eglarray.h"
+
+
+enum _egl_platform_type {
+   _EGL_PLATFORM_WINDOWS,
+   _EGL_PLATFORM_X11,
+   _EGL_PLATFORM_DRM,
+   _EGL_PLATFORM_FBDEV,
+
+   _EGL_NUM_PLATFORMS,
+   _EGL_INVALID_PLATFORM = -1
+};
+typedef enum _egl_platform_type _EGLPlatformType;
 
 
 enum _egl_resource_type {
@@ -39,6 +52,7 @@ struct _egl_extensions
 {
    EGLBoolean MESA_screen_surface;
    EGLBoolean MESA_copy_context;
+   EGLBoolean MESA_drm_display;
    EGLBoolean KHR_image_base;
    EGLBoolean KHR_image_pixmap;
    EGLBoolean KHR_vg_parent_image;
@@ -53,14 +67,15 @@ struct _egl_extensions
 };
 
 
-struct _egl_display 
+struct _egl_display
 {
    /* used to link displays */
    _EGLDisplay *Next;
 
    _EGLMutex Mutex;
 
-   EGLNativeDisplayType NativeDisplay;
+   _EGLPlatformType Platform;
+   void *PlatformDisplay;
 
    EGLBoolean Initialized; /**< True if the display is initialized */
    _EGLDriver *Driver;
@@ -75,24 +90,24 @@ struct _egl_display
 
    _EGLExtensions Extensions;
 
-   EGLint NumScreens;
-   _EGLScreen **Screens;  /* array [NumScreens] */
-
-   EGLint MaxConfigs;
-   EGLint NumConfigs;
-   _EGLConfig **Configs;  /* array [NumConfigs] of ptr to _EGLConfig */
+   _EGLArray *Screens;
+   _EGLArray *Configs;
 
    /* lists of resources */
    _EGLResource *ResourceLists[_EGL_NUM_RESOURCES];
 };
 
 
+extern _EGLPlatformType
+_eglGetNativePlatform(void);
+
+
 extern void
 _eglFiniDisplay(void);
 
 
 extern _EGLDisplay *
-_eglFindDisplay(EGLNativeDisplayType displayName);
+_eglFindDisplay(_EGLPlatformType plat, void *plat_dpy);
 
 
 PUBLIC void
index f56214472e92a1fae1b796205d02b17dc18e56fe..1e3d7d24aa7308bd496d2fa3fb309c94a4bc3e60 100644 (file)
@@ -22,6 +22,7 @@
 #include "eglstring.h"
 #include "eglsurface.h"
 #include "eglimage.h"
+#include "eglmutex.h"
 
 #if defined(_EGL_OS_UNIX)
 #include <dlfcn.h>
 #endif
 
 
+typedef struct _egl_module {
+   char *Path;
+   void *Handle;
+   _EGLDriver *Driver;
+} _EGLModule;
+
+static _EGL_DECLARE_MUTEX(_eglModuleMutex);
+static _EGLArray *_eglModules;
+
+
 /**
  * Wrappers for dlopen/dlclose()
  */
 #if defined(_EGL_OS_WINDOWS)
 
 
-/* XXX Need to decide how to do dynamic name lookup on Windows */
-static const char *DefaultDriverNames[] = {
-   "egl_gdi_swrast"
-};
-
 typedef HMODULE lib_handle;
 
 static HMODULE
@@ -67,11 +73,6 @@ library_suffix(void)
 #elif defined(_EGL_OS_UNIX)
 
 
-static const char *DefaultDriverNames[] = {
-   "egl_dri2",
-   "egl_glx"
-};
-
 typedef void * lib_handle;
 
 static void *
@@ -97,13 +98,6 @@ library_suffix(void)
 #endif
 
 
-#define NUM_PROBE_CACHE_SLOTS 8
-static struct {
-   EGLint keys[NUM_PROBE_CACHE_SLOTS];
-   const void *values[NUM_PROBE_CACHE_SLOTS];
-} _eglProbeCache;
-
-
 /**
  * Open the named driver and find its bootstrap function: _eglMain().
  */
@@ -163,85 +157,106 @@ _eglOpenLibrary(const char *driverPath, lib_handle *handle)
 
 
 /**
- * Load the named driver.
+ * Load a module and create the driver object.
  */
-static _EGLDriver *
-_eglLoadDriver(const char *path, const char *args)
+static EGLBoolean
+_eglLoadModule(_EGLModule *mod)
 {
    _EGLMain_t mainFunc;
    lib_handle lib;
-   _EGLDriver *drv = NULL;
+   _EGLDriver *drv;
 
-   mainFunc = _eglOpenLibrary(path, &lib);
+   mainFunc = _eglOpenLibrary(mod->Path, &lib);
    if (!mainFunc)
-      return NULL;
+      return EGL_FALSE;
 
-   drv = mainFunc(args);
+   drv = mainFunc(NULL);
    if (!drv) {
       if (lib)
          close_library(lib);
-      return NULL;
+      return EGL_FALSE;
    }
 
    if (!drv->Name) {
-      _eglLog(_EGL_WARNING, "Driver loaded from %s has no name", path);
+      _eglLog(_EGL_WARNING, "Driver loaded from %s has no name", mod->Path);
       drv->Name = "UNNAMED";
    }
 
-   drv->Path = _eglstrdup(path);
-   drv->Args = (args) ? _eglstrdup(args) : NULL;
-   if (!drv->Path || (args && !drv->Args)) {
-      if (drv->Path)
-         free((char *) drv->Path);
-      if (drv->Args)
-         free((char *) drv->Args);
-      drv->Unload(drv);
-      if (lib)
-         close_library(lib);
-      return NULL;
-   }
+   mod->Handle = (void *) lib;
+   mod->Driver = drv;
+
+   return EGL_TRUE;
+}
 
-   drv->LibHandle = lib;
 
-   return drv;
+/**
+ * Unload a module.
+ */
+static void
+_eglUnloadModule(_EGLModule *mod)
+{
+   /* destroy the driver */
+   if (mod->Driver && mod->Driver->Unload)
+      mod->Driver->Unload(mod->Driver);
+   if (mod->Handle)
+      close_library(mod->Handle);
+
+   mod->Driver = NULL;
+   mod->Handle = NULL;
 }
 
 
 /**
- * Match a display to a preloaded driver.
- *
- * The matching is done by finding the driver with the highest score.
+ * Add a module to the module array.
  */
-_EGLDriver *
-_eglMatchDriver(_EGLDisplay *dpy)
+static _EGLModule *
+_eglAddModule(const char *path)
 {
-   _EGLDriver *best_drv = NULL;
-   EGLint best_score = -1, i;
+   _EGLModule *mod;
+   EGLint i;
 
-   /*
-    * this function is called after preloading and the drivers never change
-    * after preloading.
-    */
-   for (i = 0; i < _eglGlobal.NumDrivers; i++) {
-      _EGLDriver *drv = _eglGlobal.Drivers[i];
-      EGLint score;
-
-      score = (drv->Probe) ? drv->Probe(drv, dpy) : 0;
-      if (score > best_score) {
-         if (best_drv) {
-            _eglLog(_EGL_DEBUG, "driver %s has higher score than %s",
-                  drv->Name, best_drv->Name);
-         }
+   if (!_eglModules) {
+      _eglModules = _eglCreateArray("Module", 8);
+      if (!_eglModules)
+         return NULL;
+   }
 
-         best_drv = drv;
-         best_score = score;
-         /* perfect match */
-         if (score >= 100)
-            break;
+   /* find duplicates */
+   for (i = 0; i < _eglModules->Size; i++) {
+      mod = _eglModules->Elements[i];
+      if (strcmp(mod->Path, path) == 0)
+         return mod;
+   }
+
+   /* allocate a new one */
+   mod = calloc(1, sizeof(*mod));
+   if (mod) {
+      mod->Path = _eglstrdup(path);
+      if (!mod->Path) {
+         free(mod);
+         mod = NULL;
       }
    }
+   if (mod) {
+      _eglAppendArray(_eglModules, (void *) mod);
+      _eglLog(_EGL_DEBUG, "added %s to module array", mod->Path);
+   }
 
-   return best_drv;
+   return mod;
+}
+
+
+/**
+ * Free a module.
+ */
+static void
+_eglFreeModule(void *module)
+{
+   _EGLModule *mod = (_EGLModule *) module;
+
+   _eglUnloadModule(mod);
+   free(mod->Path);
+   free(mod);
 }
 
 
@@ -252,7 +267,6 @@ _eglMatchDriver(_EGLDisplay *dpy)
 static EGLBoolean
 _eglLoaderFile(const char *dir, size_t len, void *loader_data)
 {
-   _EGLDriver *drv;
    char path[1024];
    const char *filename = (const char *) loader_data;
    size_t flen = strlen(filename);
@@ -268,9 +282,7 @@ _eglLoaderFile(const char *dir, size_t len, void *loader_data)
    len += flen;
    path[len] = '\0';
 
-   if (library_suffix() == NULL || strstr(path, library_suffix()))
-      drv = _eglLoadDriver(path, NULL);
-   else {
+   if (library_suffix()) {
       const char *suffix = library_suffix();
       size_t slen = strlen(suffix);
       const char *p;
@@ -278,19 +290,23 @@ _eglLoaderFile(const char *dir, size_t len, void *loader_data)
 
       p = filename + flen - slen;
       need_suffix = (p < filename || strcmp(p, suffix) != 0);
-      if (need_suffix && len + slen + 1 <= sizeof(path)) {
+      if (need_suffix) {
+         /* overflow */
+         if (len + slen + 1 > sizeof(path))
+            return EGL_TRUE;
          strcpy(path + len, suffix);
-         drv = _eglLoadDriver(path, NULL);
-      } else {
-         drv = NULL;
       }
    }
-   if (!drv)
+
+#if defined(_EGL_OS_UNIX)
+   /* check if the file exists */
+   if (access(path, F_OK))
       return EGL_TRUE;
+#endif
 
-   /* remember the driver and stop */
-   _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv;
-   return EGL_FALSE;
+   _eglAddModule(path);
+
+   return EGL_TRUE;
 }
 
 
@@ -326,7 +342,6 @@ _eglLoaderPattern(const char *dir, size_t len, void *loader_data)
    suffix_len = (suffix) ? strlen(suffix) : 0;
 
    while ((dirent = readdir(dirp))) {
-      _EGLDriver *drv;
       size_t dirent_len = strlen(dirent->d_name);
       const char *p;
 
@@ -340,12 +355,10 @@ _eglLoaderPattern(const char *dir, size_t len, void *loader_data)
             continue;
       }
 
-      /* make a full path and load the driver */
+      /* make a full path and add it to the module array */
       if (len + dirent_len + 1 <= sizeof(path)) {
          strcpy(path + len, dirent->d_name);
-         drv = _eglLoadDriver(path, NULL);
-         if (drv)
-            _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv;
+         _eglAddModule(path);
       }
    }
 
@@ -360,19 +373,17 @@ _eglLoaderPattern(const char *dir, size_t len, void *loader_data)
 
 
 /**
- * Run the preload function on each driver directory and return the number of
- * drivers loaded.
+ * Run the callback function on each driver directory.
  *
  * The process may end prematurely if the callback function returns false.
  */
-static EGLint
+static void
 _eglPreloadForEach(const char *search_path,
                    EGLBoolean (*loader)(const char *, size_t, void *),
                    void *loader_data)
 {
    const char *cur, *next;
    size_t len;
-   EGLint num_drivers = _eglGlobal.NumDrivers;
 
    cur = search_path;
    while (cur) {
@@ -384,8 +395,6 @@ _eglPreloadForEach(const char *search_path,
 
       cur = (next) ? next + 1 : NULL;
    }
-
-   return (_eglGlobal.NumDrivers - num_drivers);
 }
 
 
@@ -430,12 +439,12 @@ _eglGetSearchPath(void)
 
 
 /**
- * Preload a user driver.
+ * Add the user driver to the module array.
  *
- * A user driver can be specified by EGL_DRIVER.
+ * The user driver is specified by EGL_DRIVER.
  */
-static EGLBoolean
-_eglPreloadUserDriver(void)
+static void
+_eglAddUserDriver(void)
 {
    const char *search_path = _eglGetSearchPath();
    char *env;
@@ -451,132 +460,206 @@ _eglPreloadUserDriver(void)
       }
    }
 #endif /* _EGL_OS_UNIX */
-   if (!env)
-      return EGL_FALSE;
+   if (env)
+      _eglPreloadForEach(search_path, _eglLoaderFile, (void *) env);
+}
 
-   if (!_eglPreloadForEach(search_path, _eglLoaderFile, (void *) env)) {
-      _eglLog(_EGL_WARNING, "EGL_DRIVER is set to an invalid driver");
-      return EGL_FALSE;
-   }
 
-   return EGL_TRUE;
+/**
+ * Add default drivers to the module array.
+ */
+static void
+_eglAddDefaultDrivers(void)
+{
+   const char *search_path = _eglGetSearchPath();
+   EGLint i;
+#if defined(_EGL_OS_WINDOWS)
+   const char *DefaultDriverNames[] = {
+      "egl_gallium"
+   };
+#elif defined(_EGL_OS_UNIX)
+   const char *DefaultDriverNames[] = {
+      "egl_gallium",
+      "egl_dri2",
+      "egl_glx"
+   };
+#endif
+
+   for (i = 0; i < ARRAY_SIZE(DefaultDriverNames); i++) {
+      void *name = (void *) DefaultDriverNames[i];
+      _eglPreloadForEach(search_path, _eglLoaderFile, name);
+   }
 }
 
 
 /**
- * Preload platform drivers.
- *
- * Platform drivers are a set of drivers that support a certain window system.
- * The window system may be specified by EGL_PLATFORM.
- *
- * FIXME This makes libEGL a memory hog if an user driver is not specified and
- * there are many platform drivers.
+ * Add drivers to the module array.  Drivers will be loaded as they are matched
+ * to displays.
  */
 static EGLBoolean
-_eglPreloadPlatformDrivers(void)
+_eglAddDrivers(void)
 {
-   const char *dpy;
-   char prefix[32];
-   int ret;
-
-   dpy = getenv("EGL_PLATFORM");
-   /* try deprecated env variable */
-   if (!dpy || !dpy[0])
-      dpy = getenv("EGL_DISPLAY");
-   if (!dpy || !dpy[0])
-      dpy = _EGL_DEFAULT_PLATFORM;
-   if (!dpy || !dpy[0])
-      return EGL_FALSE;
+   if (_eglModules)
+      return EGL_TRUE;
 
-   ret = _eglsnprintf(prefix, sizeof(prefix), "egl_%s_", dpy);
-   if (ret < 0 || ret >= sizeof(prefix))
-      return EGL_FALSE;
+   /* the order here decides the priorities of the drivers */
+   _eglAddUserDriver();
+   _eglAddDefaultDrivers();
+   _eglPreloadForEach(_eglGetSearchPath(), _eglLoaderPattern, (void *) "egl_");
 
-   return (_eglPreloadForEach(_eglGetSearchPath(),
-            _eglLoaderPattern, (void *) prefix) > 0);
+   return (_eglModules != NULL);
 }
 
 
 /**
- * Preload drivers.
+ * Match a display to a driver.  The display is initialized unless use_probe is
+ * true.
  *
- * This function loads the driver modules and creates the corresponding
- * _EGLDriver objects.
+ * The matching is done by finding the first driver that can initialize the
+ * display, or when use_probe is true, the driver with highest score.
  */
-EGLBoolean
-_eglPreloadDrivers(void)
+_EGLDriver *
+_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean use_probe)
 {
-   EGLBoolean loaded;
+   _EGLModule *mod;
+   _EGLDriver *best_drv = NULL;
+   EGLint best_score = 0;
+   EGLint major, minor, i;
 
-   /* protect the preloading process */
-   _eglLockMutex(_eglGlobal.Mutex);
+   _eglLockMutex(&_eglModuleMutex);
 
-   /* already preloaded */
-   if (_eglGlobal.NumDrivers) {
-      _eglUnlockMutex(_eglGlobal.Mutex);
-      return EGL_TRUE;
+   if (!_eglAddDrivers()) {
+      _eglUnlockMutex(&_eglModuleMutex);
+      return EGL_FALSE;
+   }
+
+   /* match the loaded modules */
+   for (i = 0; i < _eglModules->Size; i++) {
+      mod = (_EGLModule *) _eglModules->Elements[i];
+      if (!mod->Driver)
+         break;
+
+      if (use_probe) {
+         EGLint score = (mod->Driver->Probe) ?
+            mod->Driver->Probe(mod->Driver, dpy) : 1;
+         if (score > best_score) {
+            best_drv = mod->Driver;
+            best_score = score;
+         }
+      }
+      else {
+         if (mod->Driver->API.Initialize(mod->Driver, dpy, &major, &minor)) {
+            best_drv = mod->Driver;
+            best_score = 100;
+         }
+      }
+      /* perfect match */
+      if (best_score >= 100)
+         break;
+   }
+
+   /* load more modules */
+   if (!best_drv) {
+      EGLint first_unloaded = i;
+
+      while (i < _eglModules->Size) {
+         mod = (_EGLModule *) _eglModules->Elements[i];
+         assert(!mod->Driver);
+
+         if (!_eglLoadModule(mod)) {
+            /* remove invalid modules */
+            _eglEraseArray(_eglModules, i, _eglFreeModule);
+            continue;
+         }
+
+         if (use_probe) {
+            best_score = (mod->Driver->Probe) ?
+               mod->Driver->Probe(mod->Driver, dpy) : 1;
+         }
+         else {
+            if (mod->Driver->API.Initialize(mod->Driver, dpy, &major, &minor))
+               best_score = 100;
+         }
+
+         if (best_score > 0) {
+            best_drv = mod->Driver;
+            /* loaded modules come before unloaded ones */
+            if (first_unloaded != i) {
+               void *tmp = _eglModules->Elements[i];
+               _eglModules->Elements[i] =
+                  _eglModules->Elements[first_unloaded];
+               _eglModules->Elements[first_unloaded] = tmp;
+            }
+            break;
+         }
+         else {
+            _eglUnloadModule(mod);
+            i++;
+         }
+      }
    }
 
-   loaded = (_eglPreloadUserDriver() ||
-             _eglPreloadPlatformDrivers());
+   _eglUnlockMutex(&_eglModuleMutex);
 
-   _eglUnlockMutex(_eglGlobal.Mutex);
+   if (best_drv) {
+      _eglLog(_EGL_DEBUG, "the best driver is %s (score %d)",
+            best_drv->Name, best_score);
+      if (!use_probe) {
+         dpy->Driver = best_drv;
+         dpy->Initialized = EGL_TRUE;
+         dpy->APImajor = major;
+         dpy->APIminor = minor;
+      }
+   }
 
-   return loaded;
+   return best_drv;
 }
 
-/**
- * Unload preloaded drivers.
- */
-void
-_eglUnloadDrivers(void)
+
+__eglMustCastToProperFunctionPointerType
+_eglGetDriverProc(const char *procname)
 {
    EGLint i;
+   _EGLProc proc = NULL;
+
+   if (!_eglModules) {
+      /* load the driver for the default display */
+      EGLDisplay egldpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+      _EGLDisplay *dpy = _eglLookupDisplay(egldpy);
+      if (!dpy || !_eglMatchDriver(dpy, EGL_TRUE))
+         return NULL;
+   }
 
-   /* this is called at atexit time */
-   for (i = 0; i < _eglGlobal.NumDrivers; i++) {
-      _EGLDriver *drv = _eglGlobal.Drivers[i];
-      lib_handle handle = drv->LibHandle;
-
-      if (drv->Path)
-         free((char *) drv->Path);
-      if (drv->Args)
-         free((char *) drv->Args);
-
-      /* destroy driver */
-      if (drv->Unload)
-         drv->Unload(drv);
-
-      if (handle)
-         close_library(handle);
-      _eglGlobal.Drivers[i] = NULL;
+   for (i = 0; i < _eglModules->Size; i++) {
+      _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i];
+
+      if (!mod->Driver)
+         break;
+      proc = mod->Driver->API.GetProcAddress(mod->Driver, procname);
+      if (proc)
+         break;
    }
 
-   _eglGlobal.NumDrivers = 0;
+   return proc;
 }
 
-_EGLDriver *
-_eglLoadDefaultDriver(EGLDisplay dpy, EGLint *major, EGLint *minor)
-{
-   _EGLDriver *drv = NULL;
-   int i;
-
-   _eglLockMutex(_eglGlobal.Mutex);
 
-   for (i = 0; i < ARRAY_SIZE(DefaultDriverNames); i++) {
-      _eglPreloadForEach(_eglGetSearchPath(),
-                        _eglLoaderFile, (void *) DefaultDriverNames[i]);
-      if (_eglGlobal.NumDrivers == 0)
-        continue;
-      drv = _eglGlobal.Drivers[0];
-      if (drv->API.Initialize(drv, dpy, major, minor))
-        break;
-      _eglUnloadDrivers();
-   }      
-
-   _eglUnlockMutex(_eglGlobal.Mutex);
-
-   return _eglGlobal.NumDrivers > 0 ? drv : NULL;
+/**
+ * Unload all drivers.
+ */
+void
+_eglUnloadDrivers(void)
+{
+   /* this is called at atexit time */
+   if (_eglModules) {
+#if defined(_EGL_OS_UNIX)
+      _eglDestroyArray(_eglModules, _eglFreeModule);
+#elif defined(_EGL_OS_WINDOWS)
+      /* XXX Windows unloads DLLs before atexit */
+      _eglDestroyArray(_eglModules, NULL);
+#endif
+      _eglModules = NULL;
+   }
 }
 
 
@@ -656,44 +739,3 @@ _eglSearchPathForEach(EGLBoolean (*callback)(const char *, size_t, void *),
    const char *search_path = _eglGetSearchPath();
    _eglPreloadForEach(search_path, callback, callback_data);
 }
-
-
-/**
- * Set the probe cache at the given key.
- *
- * A key, instead of a _EGLDriver, is used to allow the probe cache to be share
- * by multiple drivers.
- */
-void
-_eglSetProbeCache(EGLint key, const void *val)
-{
-   EGLint idx;
-
-   for (idx = 0; idx < NUM_PROBE_CACHE_SLOTS; idx++) {
-      if (!_eglProbeCache.keys[idx] || _eglProbeCache.keys[idx] == key)
-         break;
-   }
-   assert(key > 0);
-   assert(idx < NUM_PROBE_CACHE_SLOTS);
-
-   _eglProbeCache.keys[idx] = key;
-   _eglProbeCache.values[idx] = val;
-}
-
-
-/**
- * Return the probe cache at the given key.
- */
-const void *
-_eglGetProbeCache(EGLint key)
-{
-   EGLint idx;
-
-   for (idx = 0; idx < NUM_PROBE_CACHE_SLOTS; idx++) {
-      if (!_eglProbeCache.keys[idx] || _eglProbeCache.keys[idx] == key)
-         break;
-   }
-
-   return (idx < NUM_PROBE_CACHE_SLOTS && _eglProbeCache.keys[idx] == key) ?
-      _eglProbeCache.values[idx] : NULL;
-}
index 8b34c43b924dcba4873dbf479ea163cbd1b9815d..c618feb6b02d91cbea3a200815969243e4197792 100644 (file)
@@ -41,10 +41,6 @@ typedef _EGLDriver *(*_EGLMain_t)(const char *args);
  */
 struct _egl_driver
 {
-   void *LibHandle; /**< dlopen handle */
-   const char *Path;  /**< path to this driver */
-   const char *Args;  /**< args to load this driver */
-
    const char *Name;  /**< name of this driver */
 
    /**
@@ -73,21 +69,17 @@ _eglMain(const char *args);
 
 
 extern _EGLDriver *
-_eglMatchDriver(_EGLDisplay *dpy);
+_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean probe_only);
 
 
-extern EGLBoolean
-_eglPreloadDrivers(void);
+extern __eglMustCastToProperFunctionPointerType
+_eglGetDriverProc(const char *procname);
 
 
 extern void
 _eglUnloadDrivers(void);
 
 
-extern _EGLDriver *
-_eglLoadDefaultDriver(EGLDisplay dpy, EGLint *major, EGLint *minor);
-
-
 PUBLIC void
 _eglInitDriverFallbacks(_EGLDriver *drv);
 
@@ -97,12 +89,4 @@ _eglSearchPathForEach(EGLBoolean (*callback)(const char *, size_t, void *),
                       void *callback_data);
 
 
-PUBLIC void
-_eglSetProbeCache(EGLint key, const void *val);
-
-
-PUBLIC const void *
-_eglGetProbeCache(EGLint key);
-
-
 #endif /* EGLDRIVER_INCLUDED */
index e63819e08a20ad4625196731ca868515c5387e65..725a25eca63429ede71947170647be62c3d50861 100644 (file)
@@ -12,8 +12,6 @@ struct _egl_global _eglGlobal =
    &_eglGlobalMutex,       /* Mutex */
    NULL,                   /* DisplayList */
    1,                      /* FreeScreenHandle */
-   0,                      /* NumDrivers */
-   { NULL },               /* Drivers */
    2,                      /* NumAtExitCalls */
    {
       /* default AtExitCalls, called in reverse order */
index 436889802080d2886b2d7dfa7f7f110fb18be832..e8bf5416e2a0e90a1f94e9be5233cb68c4dd24c9 100644 (file)
@@ -18,10 +18,6 @@ struct _egl_global
 
    EGLScreenMESA FreeScreenHandle;
 
-   /* these never change after preloading */
-   EGLint NumDrivers;
-   _EGLDriver *Drivers[10];
-
    EGLint NumAtExitCalls;
    void (*AtExitCalls[10])(void);
 };
index 4652969659b77ef13936783e2def93f1268e24b8..281138c7523b408470404eddaa361e227ccd991a 100644 (file)
@@ -84,6 +84,7 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy)
 
    _EGL_CHECK_EXTENSION(MESA_screen_surface);
    _EGL_CHECK_EXTENSION(MESA_copy_context);
+   _EGL_CHECK_EXTENSION(MESA_drm_display);
 
    _EGL_CHECK_EXTENSION(KHR_image_base);
    _EGL_CHECK_EXTENSION(KHR_image_pixmap);
index 66446c0495d2fe55ab654a25636c9994867528e3..859e9318b4ad6a0416b2db894a10859b6418d251 100644 (file)
@@ -22,9 +22,12 @@ _eglLookupMode(EGLModeMESA mode, _EGLDisplay *disp)
 {
    EGLint scrnum;
 
+   if (!disp->Screens)
+      return NULL;
+
    /* loop over all screens on the display */
-   for (scrnum = 0; scrnum < disp->NumScreens; scrnum++) {
-      const _EGLScreen *scrn = disp->Screens[scrnum];
+   for (scrnum = 0; scrnum < disp->Screens->Size; scrnum++) {
+      const _EGLScreen *scrn = disp->Screens->Elements[scrnum];
       EGLint i;
       /* search list of modes for handle */
       for (i = 0; i < scrn->NumModes; i++) {
index c47afd6abdab78f6a66433f1161a84c6507d02a6..8f96fd935c7a8a9ea74a85c9e96fea802df61b76 100644 (file)
@@ -62,9 +62,13 @@ _eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *display)
 {
    EGLint i;
 
-   for (i = 0; i < display->NumScreens; i++) {
-      if (display->Screens[i]->Handle == screen)
-         return display->Screens[i];
+   if (!display->Screens)
+      return NULL;
+
+   for (i = 0; i < display->Screens->Size; i++) {
+      _EGLScreen *scr = (_EGLScreen *) display->Screens->Elements[i];
+      if (scr->Handle == screen)
+         return scr;
    }
    return NULL;
 }
@@ -76,40 +80,36 @@ _eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *display)
 void
 _eglAddScreen(_EGLDisplay *display, _EGLScreen *screen)
 {
-   EGLint n;
-
    assert(display);
    assert(screen);
 
+   if (!display->Screens) {
+      display->Screens = _eglCreateArray("Screen", 4);
+      if (!display->Screens)
+         return;
+   }
    screen->Handle = _eglAllocScreenHandle();
-   n = display->NumScreens;
-   display->Screens = realloc(display->Screens, (n+1) * sizeof(_EGLScreen *));
-   display->Screens[n] = screen;
-   display->NumScreens++;
+   _eglAppendArray(display->Screens, (void *) screen);
 }
 
 
 
+static EGLBoolean
+_eglFlattenScreen(void *elem, void *buffer)
+{
+   _EGLScreen *scr = (_EGLScreen *) elem;
+   EGLScreenMESA *handle = (EGLScreenMESA *) buffer;
+   *handle = scr->Handle;
+   return EGL_TRUE;
+}
+
+
 EGLBoolean
 _eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *display, EGLScreenMESA *screens,
                    EGLint max_screens, EGLint *num_screens)
 {
-   EGLint n;
-
-   if (display->NumScreens > max_screens) {
-      n = max_screens;
-   }
-   else {
-      n = display->NumScreens;
-   }
-
-   if (screens) {
-      EGLint i;
-      for (i = 0; i < n; i++)
-         screens[i] = display->Screens[i]->Handle;
-   }
-   if (num_screens)
-      *num_screens = n;
+   *num_screens = _eglFlattenArray(display->Screens, (void *) screens,
+         sizeof(screens[0]), max_screens, _eglFlattenScreen);
 
    return EGL_TRUE;
 }
index 166b133909e3b699f6dab58009508bf8f554f2f2..0e29e9aa47e9148a152a17228112cb99446d64ad 100644 (file)
@@ -10,6 +10,8 @@
 
 typedef struct _egl_api _EGLAPI;
 
+typedef struct _egl_array _EGLArray;
+
 typedef struct _egl_config _EGLConfig;
 
 typedef struct _egl_context _EGLContext;
index 1ba0724949a71dd7aed1a5be758e676f881ae65e..bff399ec64f6252f59efcde36b62edc06062a1cf 100644 (file)
@@ -23,6 +23,10 @@ INCLUDES = \
        -I$(TOP)/src/gallium/drivers \
        $(LIBRARY_INCLUDES)
 
+ifeq ($(MESA_LLVM),1)
+LIBRARY_DEFINES += $(LLVM_CFLAGS)
+endif
+
 
 ##### TARGETS #####
 
@@ -45,7 +49,7 @@ tags:
 
 # Remove .o and backup files
 clean:
-       rm -f $(OBJECTS) $(GENERATED_SOURCES) $(PROGS) lib$(LIBNAME).a depend depend.bak
+       rm -f $(OBJECTS) $(GENERATED_SOURCES) $(PROGS) lib$(LIBNAME).a depend depend.bak $(CLEAN_EXTRA)
 
 # Dummy target
 install:
index 7c8db19f5c34df81cc227e8c78ca59616e195ff8..dcebab7c0f26e1c6340e0b7d9e14246cc7aebea7 100644 (file)
@@ -124,6 +124,7 @@ C_SOURCES = \
        util/u_linear.c \
        util/u_network.c \
        util/u_math.c \
+       util/u_mempool.c \
        util/u_mm.c \
        util/u_rect.c \
        util/u_ringbuffer.c \
@@ -154,6 +155,8 @@ GALLIVM_SOURCES = \
         gallivm/lp_bld_flow.c \
         gallivm/lp_bld_format_aos.c \
         gallivm/lp_bld_format_soa.c \
+        gallivm/lp_bld_format_yuv.c \
+        gallivm/lp_bld_gather.c \
         gallivm/lp_bld_init.c \
         gallivm/lp_bld_intr.c \
         gallivm/lp_bld_logic.c \
@@ -167,8 +170,10 @@ GALLIVM_SOURCES = \
         gallivm/lp_bld_tgsi_soa.c \
         gallivm/lp_bld_type.c \
         draw/draw_llvm.c \
+        draw/draw_vs_llvm.c \
         draw/draw_pt_fetch_shade_pipeline_llvm.c \
-        draw/draw_llvm_translate.c
+        draw/draw_llvm_translate.c \
+        draw/draw_llvm_sample.c
 
 GALLIVM_CPP_SOURCES = \
     gallivm/lp_bld_misc.cpp
index 6242ab0c59d8e23cde674fa8e381bf4151fdfe65..72a16617db8d187ac2675fe90d3abd5b1642691f 100644 (file)
@@ -32,8 +32,8 @@ env.CodeGenerate(
 
 env.CodeGenerate(
     target = 'util/u_format_table.c',
-    script = 'util/u_format_table.py',
-    source = ['util/u_format.csv'],
+    script = '#src/gallium/auxiliary/util/u_format_table.py',
+    source = ['#src/gallium/auxiliary/util/u_format.csv'],
     command = 'python $SCRIPT $SOURCE > $TARGET'
 )
 
@@ -45,7 +45,7 @@ env.CodeGenerate(
 )
 
 env.Depends('util/u_format_table.c', [
-    'util/u_format_parse.py', 
+    '#src/gallium/auxiliary/util/u_format_parse.py',
     'util/u_format_pack.py', 
 ])
 
@@ -172,6 +172,7 @@ source = [
     'util/u_keymap.c',
     'util/u_network.c',
     'util/u_math.c',
+    'util/u_mempool.c',
     'util/u_mm.c',
     'util/u_rect.c',
     'util/u_resource.c',
@@ -203,6 +204,8 @@ if env['llvm']:
     'gallivm/lp_bld_flow.c',
     'gallivm/lp_bld_format_aos.c',
     'gallivm/lp_bld_format_soa.c',
+    'gallivm/lp_bld_format_yuv.c',
+    'gallivm/lp_bld_gather.c',
     'gallivm/lp_bld_intr.c',
     'gallivm/lp_bld_logic.c',
     'gallivm/lp_bld_init.c',
@@ -218,7 +221,9 @@ if env['llvm']:
     'gallivm/lp_bld_type.c',
     'draw/draw_llvm.c',
     'draw/draw_pt_fetch_shade_pipeline_llvm.c',
-    'draw/draw_llvm_translate.c'
+    'draw/draw_llvm_translate.c',
+    'draw/draw_vs_llvm.c',
+    'draw/draw_llvm_sample.c'
     ]
 
 gallium = env.ConvenienceLibrary(
index 20a8612dcae7e3a403b91f049d7269565213f82f..58b022d531db97916aeb1948b9f638ba9c8cb9dc 100644 (file)
@@ -289,6 +289,9 @@ void cso_release_all( struct cso_context *ctx )
       ctx->pipe->bind_fs_state( ctx->pipe, NULL );
       ctx->pipe->bind_vs_state( ctx->pipe, NULL );
       ctx->pipe->bind_vertex_elements_state( ctx->pipe, NULL );
+      ctx->pipe->set_fragment_sampler_views(ctx->pipe, 0, NULL);
+      if (ctx->pipe->set_vertex_sampler_views)
+         ctx->pipe->set_vertex_sampler_views(ctx->pipe, 0, NULL);
    }
 
    for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
@@ -1029,6 +1032,7 @@ static INLINE void
 clip_state_cpy(struct pipe_clip_state *dst,
                const struct pipe_clip_state *src)
 {
+   dst->depth_clamp = src->depth_clamp;
    dst->nr = src->nr;
    if (src->nr) {
       memcpy(dst->ucp, src->ucp, src->nr * sizeof(src->ucp[0]));
@@ -1039,6 +1043,9 @@ static INLINE int
 clip_state_cmp(const struct pipe_clip_state *a,
                const struct pipe_clip_state *b)
 {
+   if (a->depth_clamp != b->depth_clamp) {
+      return 1;
+   }
    if (a->nr != b->nr) {
       return 1;
    }
index dab95e50515ceb35c9ef8f7e8f4ef5dcae34bab6..c127f74188148b97cbf8102e50f0d7952dbbaca7 100644 (file)
@@ -40,6 +40,7 @@
 
 #if HAVE_LLVM
 #include "gallivm/lp_bld_init.h"
+#include "draw_llvm.h"
 #endif
 
 struct draw_context *draw_create( struct pipe_context *pipe )
@@ -52,6 +53,7 @@ struct draw_context *draw_create( struct pipe_context *pipe )
    lp_build_init();
    assert(lp_build_engine);
    draw->engine = lp_build_engine;
+   draw->llvm = draw_llvm_create(draw);
 #endif
 
    if (!draw_init(draw))
@@ -132,6 +134,9 @@ void draw_destroy( struct draw_context *draw )
    draw_pt_destroy( draw );
    draw_vs_destroy( draw );
    draw_gs_destroy( draw );
+#ifdef HAVE_LLVM
+   draw_llvm_destroy( draw->llvm );
+#endif
 
    FREE( draw );
 }
@@ -211,6 +216,7 @@ void draw_set_clip_state( struct draw_context *draw,
    assert(clip->nr <= PIPE_MAX_CLIP_PLANES);
    memcpy(&draw->plane[6], clip->ucp, clip->nr * sizeof(clip->ucp[0]));
    draw->nr_planes = 6 + clip->nr;
+   draw->depth_clamp = clip->depth_clamp;
 }
 
 
@@ -601,3 +607,54 @@ draw_set_so_state(struct draw_context *draw,
           state,
           sizeof(struct pipe_stream_output_state));
 }
+
+void
+draw_set_sampler_views(struct draw_context *draw,
+                       struct pipe_sampler_view **views,
+                       unsigned num)
+{
+   unsigned i;
+
+   debug_assert(num <= PIPE_MAX_VERTEX_SAMPLERS);
+
+   for (i = 0; i < num; ++i)
+      draw->sampler_views[i] = views[i];
+   for (i = num; i < PIPE_MAX_VERTEX_SAMPLERS; ++i)
+      draw->sampler_views[i] = NULL;
+
+   draw->num_sampler_views = num;
+}
+
+void
+draw_set_samplers(struct draw_context *draw,
+                  struct pipe_sampler_state **samplers,
+                  unsigned num)
+{
+   unsigned i;
+
+   debug_assert(num <= PIPE_MAX_VERTEX_SAMPLERS);
+
+   for (i = 0; i < num; ++i)
+      draw->samplers[i] = samplers[i];
+   for (i = num; i < PIPE_MAX_VERTEX_SAMPLERS; ++i)
+      draw->samplers[i] = NULL;
+
+   draw->num_samplers = num;
+}
+
+void
+draw_set_mapped_texture(struct draw_context *draw,
+                        unsigned sampler_idx,
+                        uint32_t width, uint32_t height, uint32_t depth,
+                        uint32_t last_level,
+                        uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS],
+                        uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS],
+                        const void *data[DRAW_MAX_TEXTURE_LEVELS])
+{
+#ifdef HAVE_LLVM
+   draw_llvm_set_mapped_texture(draw,
+                                sampler_idx,
+                                width, height, depth, last_level,
+                                row_stride, img_stride, data);
+#endif
+}
index c0122f2aca5f8e3992c575913e728fd7dbe2555b..116716af6f0aa65a07b8ba0ba7df6e9163d7bd32 100644 (file)
@@ -47,11 +47,14 @@ struct draw_vertex_shader;
 struct draw_geometry_shader;
 struct tgsi_sampler;
 
+#define DRAW_MAX_TEXTURE_LEVELS 13  /* 4K x 4K for now */
 
 struct draw_context *draw_create( struct pipe_context *pipe );
 
 void draw_destroy( struct draw_context *draw );
 
+void draw_flush(struct draw_context *draw);
+
 void draw_set_viewport_state( struct draw_context *draw,
                               const struct pipe_viewport_state *viewport );
 
@@ -101,6 +104,23 @@ draw_texture_samplers(struct draw_context *draw,
                       uint num_samplers,
                       struct tgsi_sampler **samplers);
 
+void
+draw_set_sampler_views(struct draw_context *draw,
+                       struct pipe_sampler_view **views,
+                       unsigned num);
+void
+draw_set_samplers(struct draw_context *draw,
+                  struct pipe_sampler_state **samplers,
+                  unsigned num);
+
+void
+draw_set_mapped_texture(struct draw_context *draw,
+                        unsigned sampler_idx,
+                        uint32_t width, uint32_t height, uint32_t depth,
+                        uint32_t last_level,
+                        uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS],
+                        uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS],
+                        const void *data[DRAW_MAX_TEXTURE_LEVELS]);
 
 
 /*
@@ -173,7 +193,7 @@ draw_set_so_state(struct draw_context *draw,
 
 
 /***********************************************************************
- * draw_prim.c 
+ * draw_pt.c 
  */
 
 void draw_arrays(struct draw_context *draw, unsigned prim,
@@ -187,8 +207,6 @@ draw_arrays_instanced(struct draw_context *draw,
                       unsigned startInstance,
                       unsigned instanceCount);
 
-void draw_flush(struct draw_context *draw);
-
 
 /*******************************************************************************
  * Driver backend interface 
index 9117c1303dc8e5fcf04d5b6b35706cd267735cc9..19f96c37ab42dd9d76d2ec9452c7253df5770864 100644 (file)
@@ -1,3 +1,30 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE 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 "draw_llvm.h"
 
 #include "draw_context.h"
 #include "tgsi/tgsi_dump.h"
 
 #include "util/u_cpu_detect.h"
-#include "util/u_string.h"
 #include "util/u_pointer.h"
+#include "util/u_string.h"
 
 #include <llvm-c/Transforms/Scalar.h>
 
 #define DEBUG_STORE 0
 
-
 /* generates the draw jit function */
 static void
 draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *var);
@@ -36,12 +62,19 @@ init_globals(struct draw_llvm *llvm)
 
    /* struct draw_jit_texture */
    {
-      LLVMTypeRef elem_types[4];
+      LLVMTypeRef elem_types[DRAW_JIT_TEXTURE_NUM_FIELDS];
 
       elem_types[DRAW_JIT_TEXTURE_WIDTH]  = LLVMInt32Type();
       elem_types[DRAW_JIT_TEXTURE_HEIGHT] = LLVMInt32Type();
-      elem_types[DRAW_JIT_TEXTURE_STRIDE] = LLVMInt32Type();
-      elem_types[DRAW_JIT_TEXTURE_DATA]   = LLVMPointerType(LLVMInt8Type(), 0);
+      elem_types[DRAW_JIT_TEXTURE_DEPTH] = LLVMInt32Type();
+      elem_types[DRAW_JIT_TEXTURE_LAST_LEVEL] = LLVMInt32Type();
+      elem_types[DRAW_JIT_TEXTURE_ROW_STRIDE] =
+         LLVMArrayType(LLVMInt32Type(), DRAW_MAX_TEXTURE_LEVELS);
+      elem_types[DRAW_JIT_TEXTURE_IMG_STRIDE] =
+         LLVMArrayType(LLVMInt32Type(), DRAW_MAX_TEXTURE_LEVELS);
+      elem_types[DRAW_JIT_TEXTURE_DATA] =
+         LLVMArrayType(LLVMPointerType(LLVMInt8Type(), 0),
+                       DRAW_MAX_TEXTURE_LEVELS);
 
       texture_type = LLVMStructType(elem_types, Elements(elem_types), 0);
 
@@ -51,9 +84,18 @@ init_globals(struct draw_llvm *llvm)
       LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, height,
                              llvm->target, texture_type,
                              DRAW_JIT_TEXTURE_HEIGHT);
-      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, stride,
+      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, depth,
+                             llvm->target, texture_type,
+                             DRAW_JIT_TEXTURE_DEPTH);
+      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, last_level,
+                             llvm->target, texture_type,
+                             DRAW_JIT_TEXTURE_LAST_LEVEL);
+      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, row_stride,
                              llvm->target, texture_type,
-                             DRAW_JIT_TEXTURE_STRIDE);
+                             DRAW_JIT_TEXTURE_ROW_STRIDE);
+      LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, img_stride,
+                             llvm->target, texture_type,
+                             DRAW_JIT_TEXTURE_IMG_STRIDE);
       LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, data,
                              llvm->target, texture_type,
                              DRAW_JIT_TEXTURE_DATA);
@@ -71,7 +113,8 @@ init_globals(struct draw_llvm *llvm)
 
       elem_types[0] = LLVMPointerType(LLVMFloatType(), 0); /* vs_constants */
       elem_types[1] = LLVMPointerType(LLVMFloatType(), 0); /* vs_constants */
-      elem_types[2] = LLVMArrayType(texture_type, PIPE_MAX_SAMPLERS); /* textures */
+      elem_types[2] = LLVMArrayType(texture_type,
+                                    PIPE_MAX_VERTEX_SAMPLERS); /* textures */
 
       context_type = LLVMStructType(elem_types, Elements(elem_types), 0);
 
@@ -81,7 +124,7 @@ init_globals(struct draw_llvm *llvm)
                              llvm->target, context_type, 1);
       LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, textures,
                              llvm->target, context_type,
-                             DRAW_JIT_CONTEXT_TEXTURES_INDEX);
+                             DRAW_JIT_CTX_TEXTURES);
       LP_CHECK_STRUCT_SIZE(struct draw_jit_context,
                            llvm->target, context_type);
 
@@ -195,9 +238,22 @@ draw_llvm_create(struct draw_context *draw)
       /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
        * but there are more on SVN. */
       /* TODO: Add more passes */
+
       LLVMAddCFGSimplificationPass(llvm->pass);
-      LLVMAddPromoteMemoryToRegisterPass(llvm->pass);
-      LLVMAddConstantPropagationPass(llvm->pass);
+
+      if (HAVE_LLVM >= 0x207 && sizeof(void*) == 4) {
+         /* For LLVM >= 2.7 and 32-bit build, use this order of passes to
+          * avoid generating bad code.
+          * Test with piglit glsl-vs-sqrt-zero test.
+          */
+         LLVMAddConstantPropagationPass(llvm->pass);
+         LLVMAddPromoteMemoryToRegisterPass(llvm->pass);
+      }
+      else {
+         LLVMAddPromoteMemoryToRegisterPass(llvm->pass);
+         LLVMAddConstantPropagationPass(llvm->pass);
+      }
+
       if(util_cpu_caps.has_sse4_1) {
          /* FIXME: There is a bug in this pass, whereby the combination of fptosi
           * and sitofp (necessary for trunc/floor/ceil/round implementation)
@@ -219,6 +275,9 @@ draw_llvm_create(struct draw_context *draw)
       LLVMDumpModule(llvm->module);
    }
 
+   llvm->nr_variants = 0;
+   make_empty_list(&llvm->vs_variants_list);
+
    return llvm;
 }
 
@@ -231,9 +290,13 @@ draw_llvm_destroy(struct draw_llvm *llvm)
 }
 
 struct draw_llvm_variant *
-draw_llvm_prepare(struct draw_llvm *llvm, int num_inputs)
+draw_llvm_create_variant(struct draw_llvm *llvm, int num_inputs)
 {
    struct draw_llvm_variant *variant = MALLOC(sizeof(struct draw_llvm_variant));
+   struct llvm_vertex_shader *shader =
+      llvm_vertex_shader(llvm->draw->vs.vertex_shader);
+
+   variant->llvm = llvm;
 
    draw_llvm_make_variant_key(llvm, &variant->key);
 
@@ -242,6 +305,12 @@ draw_llvm_prepare(struct draw_llvm *llvm, int num_inputs)
    draw_llvm_generate(llvm, variant);
    draw_llvm_generate_elts(llvm, variant);
 
+   variant->shader = shader;
+   variant->list_item_global.base = variant;
+   variant->list_item_local.base = variant;
+   /*variant->no = */shader->variants_created++;
+   variant->list_item_global.base = variant;
+
    return variant;
 }
 
@@ -250,11 +319,13 @@ generate_vs(struct draw_llvm *llvm,
             LLVMBuilderRef builder,
             LLVMValueRef (*outputs)[NUM_CHANNELS],
             const LLVMValueRef (*inputs)[NUM_CHANNELS],
-            LLVMValueRef context_ptr)
+            LLVMValueRef context_ptr,
+            struct lp_build_sampler_soa *draw_sampler)
 {
    const struct tgsi_token *tokens = llvm->draw->vs.vertex_shader->state.tokens;
    struct lp_type vs_type;
    LLVMValueRef consts_ptr = draw_jit_context_vs_constants(builder, context_ptr);
+   struct lp_build_sampler_soa *sampler = 0;
 
    memset(&vs_type, 0, sizeof vs_type);
    vs_type.floating = TRUE; /* floating point values */
@@ -270,6 +341,10 @@ generate_vs(struct draw_llvm *llvm,
       tgsi_dump(tokens, 0);
    }
 
+   if (llvm->draw->num_sampler_views &&
+       llvm->draw->num_samplers)
+      sampler = draw_sampler;
+
    lp_build_tgsi_soa(builder,
                      tokens,
                      vs_type,
@@ -278,7 +353,7 @@ generate_vs(struct draw_llvm *llvm,
                      NULL /*pos*/,
                      inputs,
                      outputs,
-                     NULL/*sampler*/,
+                     sampler,
                      &llvm->draw->vs.vertex_shader->info);
 }
 
@@ -306,7 +381,8 @@ generate_fetch(LLVMBuilderRef builder,
                LLVMValueRef *res,
                struct pipe_vertex_element *velem,
                LLVMValueRef vbuf,
-               LLVMValueRef index)
+               LLVMValueRef index,
+               LLVMValueRef instance_id)
 {
    LLVMValueRef indices = LLVMConstInt(LLVMInt64Type(), velem->vertex_buffer_index, 0);
    LLVMValueRef vbuffer_ptr = LLVMBuildGEP(builder, vbuffers_ptr,
@@ -317,8 +393,15 @@ generate_fetch(LLVMBuilderRef builder,
    LLVMValueRef cond;
    LLVMValueRef stride;
 
-   cond = LLVMBuildICmp(builder, LLVMIntULE, index, vb_max_index, "");
+   if (velem->instance_divisor) {
+      /* array index = instance_id / instance_divisor */
+      index = LLVMBuildUDiv(builder, instance_id,
+                            LLVMConstInt(LLVMInt32Type(), velem->instance_divisor, 0),
+                            "instance_divisor");
+   }
 
+   /* limit index to min(inex, vb_max_index) */
+   cond = LLVMBuildICmp(builder, LLVMIntULE, index, vb_max_index, "");
    index = LLVMBuildSelect(builder, cond, index, vb_max_index, "");
 
    stride = LLVMBuildMul(builder, vb_stride, index, "");
@@ -586,13 +669,14 @@ convert_to_aos(LLVMBuilderRef builder,
 static void
 draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
 {
-   LLVMTypeRef arg_types[7];
+   LLVMTypeRef arg_types[8];
    LLVMTypeRef func_type;
    LLVMValueRef context_ptr;
    LLVMBasicBlockRef block;
    LLVMBuilderRef builder;
    LLVMValueRef start, end, count, stride, step, io_itr;
    LLVMValueRef io_ptr, vbuffers_ptr, vb_ptr;
+   LLVMValueRef instance_id;
    struct draw_context *draw = llvm->draw;
    unsigned i, j;
    struct lp_build_context bld;
@@ -601,6 +685,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
    const int max_vertices = 4;
    LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
    void *code;
+   struct lp_build_sampler_soa *sampler = 0;
 
    arg_types[0] = llvm->context_ptr_type;           /* context */
    arg_types[1] = llvm->vertex_header_ptr_type;     /* vertex_header */
@@ -609,6 +694,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
    arg_types[4] = LLVMInt32Type();                  /* count */
    arg_types[5] = LLVMInt32Type();                  /* stride */
    arg_types[6] = llvm->vb_ptr_type;                /* pipe_vertex_buffer's */
+   arg_types[7] = LLVMInt32Type();                  /* instance_id */
 
    func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0);
 
@@ -625,6 +711,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
    count        = LLVMGetParam(variant->function, 4);
    stride       = LLVMGetParam(variant->function, 5);
    vb_ptr       = LLVMGetParam(variant->function, 6);
+   instance_id  = LLVMGetParam(variant->function, 7);
 
    lp_build_name(context_ptr, "context");
    lp_build_name(io_ptr, "io");
@@ -633,6 +720,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
    lp_build_name(count, "count");
    lp_build_name(stride, "stride");
    lp_build_name(vb_ptr, "vb");
+   lp_build_name(instance_id, "instance_id");
 
    /*
     * Function body
@@ -648,6 +736,10 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
 
    step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0);
 
+   /* code generated texture sampling */
+   sampler = draw_llvm_sampler_soa_create(variant->key.sampler,
+                                          context_ptr);
+
 #if DEBUG_STORE
    lp_build_printf(builder, "start = %d, end = %d, step = %d\n",
                    start, end, step);
@@ -678,7 +770,8 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
             LLVMValueRef vb = LLVMBuildGEP(builder, vb_ptr,
                                            &vb_index, 1, "");
             generate_fetch(builder, vbuffers_ptr,
-                           &aos_attribs[j][i], velem, vb, true_index);
+                           &aos_attribs[j][i], velem, vb, true_index,
+                           instance_id);
          }
       }
       convert_to_soa(builder, aos_attribs, inputs,
@@ -689,7 +782,8 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
                   builder,
                   outputs,
                   ptr_aos,
-                  context_ptr);
+                  context_ptr,
+                  sampler);
 
       convert_to_aos(builder, io, outputs,
                      draw->vs.vertex_shader->info.num_outputs,
@@ -697,6 +791,8 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
    }
    lp_build_loop_end_cond(builder, end, step, LLVMIntUGE, &lp_loop);
 
+   sampler->destroy(sampler);
+
    LLVMBuildRetVoid(builder);
 
    LLVMDisposeBuilder(builder);
@@ -730,13 +826,14 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
 static void
 draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
 {
-   LLVMTypeRef arg_types[7];
+   LLVMTypeRef arg_types[8];
    LLVMTypeRef func_type;
    LLVMValueRef context_ptr;
    LLVMBasicBlockRef block;
    LLVMBuilderRef builder;
    LLVMValueRef fetch_elts, fetch_count, stride, step, io_itr;
    LLVMValueRef io_ptr, vbuffers_ptr, vb_ptr;
+   LLVMValueRef instance_id;
    struct draw_context *draw = llvm->draw;
    unsigned i, j;
    struct lp_build_context bld;
@@ -747,6 +844,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
    LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
    LLVMValueRef fetch_max;
    void *code;
+   struct lp_build_sampler_soa *sampler = 0;
 
    arg_types[0] = llvm->context_ptr_type;               /* context */
    arg_types[1] = llvm->vertex_header_ptr_type;         /* vertex_header */
@@ -755,14 +853,17 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
    arg_types[4] = LLVMInt32Type();                      /* fetch_count */
    arg_types[5] = LLVMInt32Type();                      /* stride */
    arg_types[6] = llvm->vb_ptr_type;                    /* pipe_vertex_buffer's */
+   arg_types[7] = LLVMInt32Type();                      /* instance_id */
 
    func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0);
 
-   variant->function_elts = LLVMAddFunction(llvm->module, "draw_llvm_shader_elts", func_type);
+   variant->function_elts = LLVMAddFunction(llvm->module, "draw_llvm_shader_elts",
+                                            func_type);
    LLVMSetFunctionCallConv(variant->function_elts, LLVMCCallConv);
    for(i = 0; i < Elements(arg_types); ++i)
       if(LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind)
-         LLVMAddAttribute(LLVMGetParam(variant->function_elts, i), LLVMNoAliasAttribute);
+         LLVMAddAttribute(LLVMGetParam(variant->function_elts, i),
+                          LLVMNoAliasAttribute);
 
    context_ptr  = LLVMGetParam(variant->function_elts, 0);
    io_ptr       = LLVMGetParam(variant->function_elts, 1);
@@ -771,6 +872,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
    fetch_count  = LLVMGetParam(variant->function_elts, 4);
    stride       = LLVMGetParam(variant->function_elts, 5);
    vb_ptr       = LLVMGetParam(variant->function_elts, 6);
+   instance_id  = LLVMGetParam(variant->function_elts, 7);
 
    lp_build_name(context_ptr, "context");
    lp_build_name(io_ptr, "io");
@@ -779,6 +881,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
    lp_build_name(fetch_count, "fetch_count");
    lp_build_name(stride, "stride");
    lp_build_name(vb_ptr, "vb");
+   lp_build_name(instance_id, "instance_id");
 
    /*
     * Function body
@@ -793,6 +896,10 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
 
    step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0);
 
+   /* code generated texture sampling */
+   sampler = draw_llvm_sampler_soa_create(variant->key.sampler,
+                                          context_ptr);
+
    fetch_max = LLVMBuildSub(builder, fetch_count,
                             LLVMConstInt(LLVMInt32Type(), 1, 0),
                             "fetch_max");
@@ -833,7 +940,8 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
             LLVMValueRef vb = LLVMBuildGEP(builder, vb_ptr,
                                            &vb_index, 1, "");
             generate_fetch(builder, vbuffers_ptr,
-                           &aos_attribs[j][i], velem, vb, true_index);
+                           &aos_attribs[j][i], velem, vb, true_index,
+                           instance_id);
          }
       }
       convert_to_soa(builder, aos_attribs, inputs,
@@ -844,7 +952,8 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
                   builder,
                   outputs,
                   ptr_aos,
-                  context_ptr);
+                  context_ptr,
+                  sampler);
 
       convert_to_aos(builder, io, outputs,
                      draw->vs.vertex_shader->info.num_outputs,
@@ -852,6 +961,8 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
    }
    lp_build_loop_end_cond(builder, fetch_count, step, LLVMIntUGE, &lp_loop);
 
+   sampler->destroy(sampler);
+
    LLVMBuildRetVoid(builder);
 
    LLVMDisposeBuilder(builder);
@@ -885,6 +996,8 @@ void
 draw_llvm_make_variant_key(struct draw_llvm *llvm,
                            struct draw_llvm_variant_key *key)
 {
+   unsigned i;
+
    memset(key, 0, sizeof(struct draw_llvm_variant_key));
 
    key->nr_vertex_elements = llvm->draw->pt.nr_vertex_elements;
@@ -896,4 +1009,72 @@ draw_llvm_make_variant_key(struct draw_llvm *llvm,
    memcpy(&key->vs,
           &llvm->draw->vs.vertex_shader->state,
           sizeof(struct pipe_shader_state));
+
+   /* if the driver implemented the sampling hooks then
+    * setup our sampling state */
+   if (llvm->draw->num_sampler_views && llvm->draw->num_samplers) {
+      for(i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; ++i) {
+         struct draw_vertex_shader *shader = llvm->draw->vs.vertex_shader;
+         if(shader->info.file_mask[TGSI_FILE_SAMPLER] & (1 << i))
+            lp_sampler_static_state(&key->sampler[i],
+                                    llvm->draw->sampler_views[i],
+                                    llvm->draw->samplers[i]);
+      }
+   }
+}
+
+void
+draw_llvm_set_mapped_texture(struct draw_context *draw,
+                             unsigned sampler_idx,
+                             uint32_t width, uint32_t height, uint32_t depth,
+                             uint32_t last_level,
+                             uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS],
+                             uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS],
+                             const void *data[DRAW_MAX_TEXTURE_LEVELS])
+{
+   unsigned j;
+   struct draw_jit_texture *jit_tex;
+
+   assert(sampler_idx < PIPE_MAX_VERTEX_SAMPLERS);
+
+
+   jit_tex = &draw->llvm->jit_context.textures[sampler_idx];
+
+   jit_tex->width = width;
+   jit_tex->height = height;
+   jit_tex->depth = depth;
+   jit_tex->last_level = last_level;
+
+   for (j = 0; j <= last_level; j++) {
+      jit_tex->data[j] = data[j];
+      jit_tex->row_stride[j] = row_stride[j];
+      jit_tex->img_stride[j] = img_stride[j];
+   }
+}
+
+void
+draw_llvm_destroy_variant(struct draw_llvm_variant *variant)
+{
+   struct draw_llvm *llvm = variant->llvm;
+   struct draw_context *draw = llvm->draw;
+
+   if (variant->function_elts) {
+      if (variant->function_elts)
+         LLVMFreeMachineCodeForFunction(draw->engine,
+                                        variant->function_elts);
+      LLVMDeleteFunction(variant->function_elts);
+   }
+
+   if (variant->function) {
+      if (variant->function)
+         LLVMFreeMachineCodeForFunction(draw->engine,
+                                        variant->function);
+      LLVMDeleteFunction(variant->function);
+   }
+
+   remove_from_list(&variant->list_item_local);
+   variant->shader->variants_cached--;
+   remove_from_list(&variant->list_item_global);
+   llvm->nr_variants--;
+   FREE(variant);
 }
index 58fee7f9d6064560b5db5c17af1dc2db8e206d02..4addb47d2d83c484336bf5784ab0f6144a8c19be 100644 (file)
@@ -1,28 +1,71 @@
-#ifndef HAVE_LLVM_H
-#define HAVE_LLVM_H
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE 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 DRAW_LLVM_H
+#define DRAW_LLVM_H
 
 #include "draw/draw_private.h"
 
+#include "draw/draw_vs.h"
+#include "gallivm/lp_bld_sample.h"
+
 #include "pipe/p_context.h"
+#include "util/u_simple_list.h"
 
 #include <llvm-c/Core.h>
 #include <llvm-c/Analysis.h>
 #include <llvm-c/Target.h>
 #include <llvm-c/ExecutionEngine.h>
 
+#define DRAW_MAX_TEXTURE_LEVELS 13  /* 4K x 4K for now */
+
+struct draw_llvm;
+struct llvm_vertex_shader;
+
 struct draw_jit_texture
 {
    uint32_t width;
    uint32_t height;
-   uint32_t stride;
-   const void *data;
+   uint32_t depth;
+   uint32_t last_level;
+   uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS];
+   uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS];
+   const void *data[DRAW_MAX_TEXTURE_LEVELS];
 };
 
 enum {
    DRAW_JIT_TEXTURE_WIDTH = 0,
    DRAW_JIT_TEXTURE_HEIGHT,
-   DRAW_JIT_TEXTURE_STRIDE,
-   DRAW_JIT_TEXTURE_DATA
+   DRAW_JIT_TEXTURE_DEPTH,
+   DRAW_JIT_TEXTURE_LAST_LEVEL,
+   DRAW_JIT_TEXTURE_ROW_STRIDE,
+   DRAW_JIT_TEXTURE_IMG_STRIDE,
+   DRAW_JIT_TEXTURE_DATA,
+   DRAW_JIT_TEXTURE_NUM_FIELDS  /* number of fields above */
 };
 
 enum {
@@ -48,7 +91,7 @@ struct draw_jit_context
    const float *gs_constants;
 
 
-   struct draw_jit_texture textures[PIPE_MAX_SAMPLERS];
+   struct draw_jit_texture textures[PIPE_MAX_VERTEX_SAMPLERS];
 };
 
 
@@ -58,10 +101,10 @@ struct draw_jit_context
 #define draw_jit_context_gs_constants(_builder, _ptr) \
    lp_build_struct_get(_builder, _ptr, 1, "gs_constants")
 
-#define DRAW_JIT_CONTEXT_TEXTURES_INDEX 2
+#define DRAW_JIT_CTX_TEXTURES 2
 
 #define draw_jit_context_textures(_builder, _ptr) \
-   lp_build_struct_get_ptr(_builder, _ptr, DRAW_JIT_CONTEXT_TEXTURES_INDEX, "textures")
+   lp_build_struct_get_ptr(_builder, _ptr, DRAW_JIT_CTX_TEXTURES, "textures")
 
 
 
@@ -92,7 +135,8 @@ typedef void
                       unsigned start,
                       unsigned count,
                       unsigned stride,
-                      struct pipe_vertex_buffer *vertex_buffers);
+                      struct pipe_vertex_buffer *vertex_buffers,
+                      unsigned instance_id);
 
 
 typedef void
@@ -102,13 +146,54 @@ typedef void
                            const unsigned *fetch_elts,
                            unsigned fetch_count,
                            unsigned stride,
-                           struct pipe_vertex_buffer *vertex_buffers);
+                           struct pipe_vertex_buffer *vertex_buffers,
+                           unsigned instance_id);
+
+struct draw_llvm_variant_key
+{
+   struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
+   unsigned                   nr_vertex_elements;
+   struct pipe_shader_state   vs;
+   struct lp_sampler_static_state sampler[PIPE_MAX_VERTEX_SAMPLERS];
+};
+
+struct draw_llvm_variant_list_item
+{
+   struct draw_llvm_variant *base;
+   struct draw_llvm_variant_list_item *next, *prev;
+};
+
+struct draw_llvm_variant
+{
+   struct draw_llvm_variant_key key;
+   LLVMValueRef function;
+   LLVMValueRef function_elts;
+   draw_jit_vert_func jit_func;
+   draw_jit_vert_func_elts jit_func_elts;
+
+   struct llvm_vertex_shader *shader;
+
+   struct draw_llvm *llvm;
+   struct draw_llvm_variant_list_item list_item_global;
+   struct draw_llvm_variant_list_item list_item_local;
+};
+
+struct llvm_vertex_shader {
+   struct draw_vertex_shader base;
+
+   struct draw_llvm_variant_list_item variants;
+   unsigned variants_created;
+   unsigned variants_cached;
+};
 
 struct draw_llvm {
    struct draw_context *draw;
 
    struct draw_jit_context jit_context;
 
+   struct draw_llvm_variant_list_item vs_variants_list;
+   int nr_variants;
+
    LLVMModuleRef module;
    LLVMExecutionEngineRef engine;
    LLVMModuleProviderRef provider;
@@ -121,23 +206,12 @@ struct draw_llvm {
    LLVMTypeRef vb_ptr_type;
 };
 
-struct draw_llvm_variant_key
+static INLINE struct llvm_vertex_shader *
+llvm_vertex_shader(struct draw_vertex_shader *vs)
 {
-   struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
-   unsigned                   nr_vertex_elements;
-   struct pipe_shader_state   vs;
-};
+   return (struct llvm_vertex_shader *)vs;
+}
 
-struct draw_llvm_variant
-{
-   struct draw_llvm_variant_key key;
-   LLVMValueRef function;
-   LLVMValueRef function_elts;
-   draw_jit_vert_func jit_func;
-   draw_jit_vert_func_elts jit_func_elts;
-
-   struct draw_llvm_variant *next;
-};
 
 struct draw_llvm *
 draw_llvm_create(struct draw_context *draw);
@@ -146,7 +220,10 @@ void
 draw_llvm_destroy(struct draw_llvm *llvm);
 
 struct draw_llvm_variant *
-draw_llvm_prepare(struct draw_llvm *llvm, int num_inputs);
+draw_llvm_create_variant(struct draw_llvm *llvm, int num_inputs);
+
+void
+draw_llvm_destroy_variant(struct draw_llvm_variant *variant);
 
 void
 draw_llvm_make_variant_key(struct draw_llvm *llvm,
@@ -156,4 +233,18 @@ LLVMValueRef
 draw_llvm_translate_from(LLVMBuilderRef builder,
                          LLVMValueRef vbuffer,
                          enum pipe_format from_format);
+
+struct lp_build_sampler_soa *
+draw_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
+                             LLVMValueRef context_ptr);
+
+void
+draw_llvm_set_mapped_texture(struct draw_context *draw,
+                             unsigned sampler_idx,
+                             uint32_t width, uint32_t height, uint32_t depth,
+                             uint32_t last_level,
+                             uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS],
+                             uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS],
+                             const void *data[DRAW_MAX_TEXTURE_LEVELS]);
+
 #endif
diff --git a/src/gallium/auxiliary/draw/draw_llvm_sample.c b/src/gallium/auxiliary/draw/draw_llvm_sample.c
new file mode 100644 (file)
index 0000000..e981101
--- /dev/null
@@ -0,0 +1,215 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE 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.
+ *
+ **************************************************************************/
+
+/**
+ * Texture sampling code generation
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+#include "pipe/p_defines.h"
+#include "pipe/p_shader_tokens.h"
+#include "gallivm/lp_bld_debug.h"
+#include "gallivm/lp_bld_type.h"
+#include "gallivm/lp_bld_sample.h"
+#include "gallivm/lp_bld_tgsi.h"
+
+
+#include "util/u_debug.h"
+#include "util/u_memory.h"
+#include "util/u_pointer.h"
+#include "util/u_string.h"
+
+#include "draw_llvm.h"
+
+
+/**
+ * This provides the bridge between the sampler state store in
+ * lp_jit_context and lp_jit_texture and the sampler code
+ * generator. It provides the texture layout information required by
+ * the texture sampler code generator in terms of the state stored in
+ * lp_jit_context and lp_jit_texture in runtime.
+ */
+struct draw_llvm_sampler_dynamic_state
+{
+   struct lp_sampler_dynamic_state base;
+
+   const struct lp_sampler_static_state *static_state;
+
+   LLVMValueRef context_ptr;
+};
+
+
+/**
+ * This is the bridge between our sampler and the TGSI translator.
+ */
+struct draw_llvm_sampler_soa
+{
+   struct lp_build_sampler_soa base;
+
+   struct draw_llvm_sampler_dynamic_state dynamic_state;
+};
+
+
+/**
+ * Fetch the specified member of the lp_jit_texture structure.
+ * \param emit_load  if TRUE, emit the LLVM load instruction to actually
+ *                   fetch the field's value.  Otherwise, just emit the
+ *                   GEP code to address the field.
+ *
+ * @sa http://llvm.org/docs/GetElementPtr.html
+ */
+static LLVMValueRef
+draw_llvm_texture_member(const struct lp_sampler_dynamic_state *base,
+                         LLVMBuilderRef builder,
+                         unsigned unit,
+                         unsigned member_index,
+                         const char *member_name,
+                         boolean emit_load)
+{
+   struct draw_llvm_sampler_dynamic_state *state =
+      (struct draw_llvm_sampler_dynamic_state *)base;
+   LLVMValueRef indices[4];
+   LLVMValueRef ptr;
+   LLVMValueRef res;
+
+   debug_assert(unit < PIPE_MAX_VERTEX_SAMPLERS);
+
+   /* context[0] */
+   indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
+   /* context[0].textures */
+   indices[1] = LLVMConstInt(LLVMInt32Type(), DRAW_JIT_CTX_TEXTURES, 0);
+   /* context[0].textures[unit] */
+   indices[2] = LLVMConstInt(LLVMInt32Type(), unit, 0);
+   /* context[0].textures[unit].member */
+   indices[3] = LLVMConstInt(LLVMInt32Type(), member_index, 0);
+
+   ptr = LLVMBuildGEP(builder, state->context_ptr, indices, Elements(indices), "");
+
+   if (emit_load)
+      res = LLVMBuildLoad(builder, ptr, "");
+   else
+      res = ptr;
+
+   lp_build_name(res, "context.texture%u.%s", unit, member_name);
+
+   return res;
+}
+
+
+/**
+ * Helper macro to instantiate the functions that generate the code to
+ * fetch the members of lp_jit_texture to fulfill the sampler code
+ * generator requests.
+ *
+ * This complexity is the price we have to pay to keep the texture
+ * sampler code generator a reusable module without dependencies to
+ * llvmpipe internals.
+ */
+#define DRAW_LLVM_TEXTURE_MEMBER(_name, _index, _emit_load)  \
+   static LLVMValueRef \
+   draw_llvm_texture_##_name( const struct lp_sampler_dynamic_state *base, \
+                              LLVMBuilderRef builder,                   \
+                              unsigned unit)                            \
+   { \
+      return draw_llvm_texture_member(base, builder, unit, _index, #_name, _emit_load ); \
+   }
+
+
+DRAW_LLVM_TEXTURE_MEMBER(width,      DRAW_JIT_TEXTURE_WIDTH, TRUE)
+DRAW_LLVM_TEXTURE_MEMBER(height,     DRAW_JIT_TEXTURE_HEIGHT, TRUE)
+DRAW_LLVM_TEXTURE_MEMBER(depth,      DRAW_JIT_TEXTURE_DEPTH, TRUE)
+DRAW_LLVM_TEXTURE_MEMBER(last_level, DRAW_JIT_TEXTURE_LAST_LEVEL, TRUE)
+DRAW_LLVM_TEXTURE_MEMBER(row_stride, DRAW_JIT_TEXTURE_ROW_STRIDE, FALSE)
+DRAW_LLVM_TEXTURE_MEMBER(img_stride, DRAW_JIT_TEXTURE_IMG_STRIDE, FALSE)
+DRAW_LLVM_TEXTURE_MEMBER(data_ptr,   DRAW_JIT_TEXTURE_DATA, FALSE)
+
+
+static void
+draw_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler)
+{
+   FREE(sampler);
+}
+
+
+/**
+ * Fetch filtered values from texture.
+ * The 'texel' parameter returns four vectors corresponding to R, G, B, A.
+ */
+static void
+draw_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base,
+                                       LLVMBuilderRef builder,
+                                       struct lp_type type,
+                                       unsigned unit,
+                                       unsigned num_coords,
+                                       const LLVMValueRef *coords,
+                                       const LLVMValueRef *ddx,
+                                       const LLVMValueRef *ddy,
+                                       LLVMValueRef lod_bias, /* optional */
+                                       LLVMValueRef explicit_lod, /* optional */
+                                       LLVMValueRef *texel)
+{
+   struct draw_llvm_sampler_soa *sampler = (struct draw_llvm_sampler_soa *)base;
+
+   assert(unit < PIPE_MAX_VERTEX_SAMPLERS);
+
+   lp_build_sample_soa(builder,
+                       &sampler->dynamic_state.static_state[unit],
+                       &sampler->dynamic_state.base,
+                       type,
+                       unit,
+                       num_coords, coords,
+                       ddx, ddy,
+                       lod_bias, explicit_lod,
+                       texel);
+}
+
+
+struct lp_build_sampler_soa *
+draw_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
+                             LLVMValueRef context_ptr)
+{
+   struct draw_llvm_sampler_soa *sampler;
+
+   sampler = CALLOC_STRUCT(draw_llvm_sampler_soa);
+   if(!sampler)
+      return NULL;
+
+   sampler->base.destroy = draw_llvm_sampler_soa_destroy;
+   sampler->base.emit_fetch_texel = draw_llvm_sampler_soa_emit_fetch_texel;
+   sampler->dynamic_state.base.width = draw_llvm_texture_width;
+   sampler->dynamic_state.base.height = draw_llvm_texture_height;
+   sampler->dynamic_state.base.depth = draw_llvm_texture_depth;
+   sampler->dynamic_state.base.last_level = draw_llvm_texture_last_level;
+   sampler->dynamic_state.base.row_stride = draw_llvm_texture_row_stride;
+   sampler->dynamic_state.base.img_stride = draw_llvm_texture_img_stride;
+   sampler->dynamic_state.base.data_ptr = draw_llvm_texture_data_ptr;
+   sampler->dynamic_state.static_state = static_state;
+   sampler->dynamic_state.context_ptr = context_ptr;
+
+   return &sampler->base;
+}
+
index d7da7ed357d0ef47e7e3f66e07d65b8a4d63983b..6ebe1f7de474fd68f332b34a38fe44ba7aed6a56 100644 (file)
@@ -7,6 +7,7 @@
 #include "gallivm/lp_bld_struct.h"
 #include "gallivm/lp_bld_format.h"
 #include "gallivm/lp_bld_debug.h"
+#include "gallivm/lp_bld_type.h"
 
 #include "util/u_memory.h"
 #include "util/u_format.h"
@@ -466,6 +467,7 @@ draw_llvm_translate_from(LLVMBuilderRef builder,
    const struct util_format_description *format_desc;
    LLVMValueRef zero;
    int i;
+   struct lp_type type = lp_float32_vec4_type();
 
    /*
     * The above can only cope with straight arrays: no bitfields,
@@ -493,5 +495,5 @@ draw_llvm_translate_from(LLVMBuilderRef builder,
 
    format_desc = util_format_description(from_format);
    zero = LLVMConstNull(LLVMInt32Type());
-   return lp_build_fetch_rgba_aos(builder, format_desc, vbuffer, zero, zero);
+   return lp_build_fetch_rgba_aos(builder, format_desc, type, vbuffer, zero, zero, zero);
 }
index 83556f10a8b3fb8749e29003f0d588a7a52aa1ae..8cd75ecf9a36b12be06fcd69e36a557694476d3e 100644 (file)
@@ -177,15 +177,15 @@ static void do_triangle( struct draw_context *draw,
                 ( DRAW_PIPE_RESET_STIPPLE |     \
                   DRAW_PIPE_EDGE_FLAG_0 |       \
                   DRAW_PIPE_EDGE_FLAG_1 ),      \
-                verts + stride * elts[i0],      \
-                verts + stride * elts[i1],      \
-                verts + stride * elts[i2]);     \
+                verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK),     \
+                verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK),     \
+                verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK));    \
    do_triangle( draw,                           \
                 ( DRAW_PIPE_EDGE_FLAG_1 |       \
                   DRAW_PIPE_EDGE_FLAG_2 ),      \
-                verts + stride * elts[i0],      \
-                verts + stride * elts[i2],      \
-                verts + stride * elts[i3])
+                verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK),     \
+                verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK),     \
+                verts + stride * (elts[i3] & ~DRAW_PIPE_FLAG_MASK))
 
 /* emit last quad vertex as last vertex in triangles */
 #define QUAD_LAST_PV(i0,i1,i2,i3)               \
@@ -193,15 +193,15 @@ static void do_triangle( struct draw_context *draw,
                 ( DRAW_PIPE_RESET_STIPPLE |     \
                   DRAW_PIPE_EDGE_FLAG_0 |       \
                   DRAW_PIPE_EDGE_FLAG_2 ),      \
-                verts + stride * elts[i0],      \
-                verts + stride * elts[i1],      \
-                verts + stride * elts[i3]);     \
+                verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK),     \
+                verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK),     \
+                verts + stride * (elts[i3] & ~DRAW_PIPE_FLAG_MASK));    \
    do_triangle( draw,                           \
                 ( DRAW_PIPE_EDGE_FLAG_0 |       \
                   DRAW_PIPE_EDGE_FLAG_1 ),      \
-                verts + stride * elts[i1],      \
-                verts + stride * elts[i2],      \
-                verts + stride * elts[i3])
+                verts + stride * (elts[i1] & ~DRAW_PIPE_FLAG_MASK),     \
+                verts + stride * (elts[i2] & ~DRAW_PIPE_FLAG_MASK),     \
+                verts + stride * (elts[i3] & ~DRAW_PIPE_FLAG_MASK))
 
 #define TRIANGLE(flags,i0,i1,i2)                                        \
    do_triangle( draw,                                                   \
@@ -218,7 +218,7 @@ static void do_triangle( struct draw_context *draw,
 
 #define POINT(i0)                               \
    do_point( draw,                              \
-             verts + stride * elts[i0] )
+             verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK) )
 
 #define FUNC pipe_run
 #define ARGS                                    \
@@ -260,7 +260,7 @@ void draw_pipeline_run( struct draw_context *draw,
                         const struct draw_prim_info *prim_info)
 {
    unsigned i, start;
-   
+
    draw->pipeline.verts = (char *)vert_info->verts;
    draw->pipeline.vertex_stride = vert_info->stride;
    draw->pipeline.vertex_count = vert_info->count;
@@ -296,14 +296,14 @@ void draw_pipeline_run( struct draw_context *draw,
                   DRAW_PIPE_EDGE_FLAG_0 |                        \
                   DRAW_PIPE_EDGE_FLAG_1 ),                       \
                 verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK),  \
-                verts + stride * (i1),                           \
-                verts + stride * (i2));                          \
+                verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK),  \
+                verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK)); \
    do_triangle( draw,                                            \
                 ( DRAW_PIPE_EDGE_FLAG_1 |                        \
                   DRAW_PIPE_EDGE_FLAG_2 ),                       \
                 verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK),  \
-                verts + stride * (i2),                           \
-                verts + stride * (i3))
+                verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK),  \
+                verts + stride * ((i3) & ~DRAW_PIPE_FLAG_MASK))
 
 /* emit last quad vertex as last vertex in triangles */
 #define QUAD_LAST_PV(i0,i1,i2,i3)                                \
@@ -312,31 +312,31 @@ void draw_pipeline_run( struct draw_context *draw,
                   DRAW_PIPE_EDGE_FLAG_0 |                        \
                   DRAW_PIPE_EDGE_FLAG_2 ),                       \
                 verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK),  \
-                verts + stride * (i1),                           \
-                verts + stride * (i3));                          \
+                verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK),  \
+                verts + stride * ((i3) & ~DRAW_PIPE_FLAG_MASK)); \
    do_triangle( draw,                                            \
                 ( DRAW_PIPE_EDGE_FLAG_0 |                        \
                   DRAW_PIPE_EDGE_FLAG_1 ),                       \
                 verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK),  \
-                verts + stride * (i2),                           \
-                verts + stride * (i3))
+                verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK),  \
+                verts + stride * ((i3) & ~DRAW_PIPE_FLAG_MASK))
 
 #define TRIANGLE(flags,i0,i1,i2)                                 \
    do_triangle( draw,                                            \
                 flags,  /* flags */                              \
                 verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK),  \
-                verts + stride * (i1),                           \
-                verts + stride * (i2))
+                verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK),  \
+                verts + stride * ((i2) & ~DRAW_PIPE_FLAG_MASK))
 
 #define LINE(flags,i0,i1)                                   \
    do_line( draw,                                           \
             flags,                                          \
             verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
-            verts + stride * (i1))
+            verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK))
 
 #define POINT(i0)                               \
    do_point( draw,                              \
-             verts + stride * i0 )
+             verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK) )
 
 #define FUNC pipe_run_linear
 #define ARGS                                    \
index debd17fd74b0bf53de7ebf36dc9e3093f7ba6b8c..c0135f5bb7bd9100829542d02823830880489098 100644 (file)
@@ -425,7 +425,8 @@ aaline_create_texture(struct aaline_stage *aaline)
 
    /* Fill in mipmap images.
     * Basically each level is solid opaque, except for the outermost
-    * texels which are zero.  Special case the 1x1 and 2x2 levels.
+    * texels which are zero.  Special case the 1x1 and 2x2 levels
+    * (though, those levels shouldn't be used - see the max_lod setting).
     */
    for (level = 0; level <= MAX_TEXTURE_LEVEL; level++) {
       struct pipe_transfer *transfer;
@@ -497,7 +498,8 @@ aaline_create_sampler(struct aaline_stage *aaline)
    sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
    sampler.normalized_coords = 1;
    sampler.min_lod = 0.0f;
-   sampler.max_lod = MAX_TEXTURE_LEVEL;
+   /* avoid using the 1x1 and 2x2 mipmap levels */
+   sampler.max_lod = MAX_TEXTURE_LEVEL - 2;
 
    aaline->sampler_cso = pipe->create_sampler_state(pipe, &sampler);
    if (aaline->sampler_cso == NULL)
@@ -669,8 +671,8 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
 
    assert(draw->rasterizer->line_smooth);
 
-   if (draw->rasterizer->line_width <= 3.0)
-      aaline->half_line_width = 1.5f;
+   if (draw->rasterizer->line_width <= 2.2)
+      aaline->half_line_width = 1.1f;
    else
       aaline->half_line_width = 0.5f * draw->rasterizer->line_width;
 
index 122b1c796895a3513711f3c1513d8f9c6695e089..1cf6ee7a7f965e7b26a331b08dacf0b0e89d7712 100644 (file)
@@ -262,6 +262,7 @@ do_clip_tri( struct draw_stage *stage,
 
       clipmask &= ~(1<<plane_idx);
 
+      assert(n < MAX_CLIPPED_VERTICES);
       inlist[n] = inlist[0]; /* prevent rotation of vertices */
 
       for (i = 1; i <= n; i++) {
@@ -270,11 +271,17 @@ do_clip_tri( struct draw_stage *stage,
         float dp = dot4( vert->clip, plane );
 
         if (!IS_NEGATIVE(dp_prev)) {
+            assert(outcount < MAX_CLIPPED_VERTICES);
            outlist[outcount++] = vert_prev;
         }
 
         if (DIFFERENT_SIGNS(dp, dp_prev)) {
-           struct vertex_header *new_vert = clipper->stage.tmp[tmpnr++];
+           struct vertex_header *new_vert;
+
+            assert(tmpnr < MAX_CLIPPED_VERTICES+1);
+            new_vert = clipper->stage.tmp[tmpnr++];
+
+            assert(outcount < MAX_CLIPPED_VERTICES);
            outlist[outcount++] = new_vert;
 
            if (IS_NEGATIVE(dp)) {
@@ -317,12 +324,14 @@ do_clip_tri( struct draw_stage *stage,
    if (clipper->flat) {
       if (stage->draw->rasterizer->flatshade_first) {
          if (inlist[0] != header->v[0]) {
+            assert(tmpnr < MAX_CLIPPED_VERTICES + 1);
             inlist[0] = dup_vert(stage, inlist[0], tmpnr++);
             copy_colors(stage, inlist[0], header->v[0]);
          }
       }
       else {
          if (inlist[0] != header->v[2]) {
+            assert(tmpnr < MAX_CLIPPED_VERTICES + 1);
             inlist[0] = dup_vert(stage, inlist[0], tmpnr++);
             copy_colors(stage, inlist[0], header->v[2]);
          }
index fff960c7eb5ea726c0be84b3e60fe43c58098971..ed9a53e154dbe4bcf4aaff82dd98cf2c9afb7055 100644 (file)
@@ -363,8 +363,12 @@ generate_pstip_fs(struct pstip_stage *pstip)
    assert(pstip->fs->sampler_unit < PIPE_MAX_SAMPLERS);
 
    pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs);
-
+   
    FREE((void *)pstip_fs.tokens);
+
+   if (!pstip->fs->pstip_fs)
+      return FALSE;
+
    return TRUE;
 }
 
@@ -603,13 +607,16 @@ pstip_destroy(struct draw_stage *stage)
 }
 
 
+/** Create a new polygon stipple drawing stage object */
 static struct pstip_stage *
-draw_pstip_stage(struct draw_context *draw)
+draw_pstip_stage(struct draw_context *draw, struct pipe_context *pipe)
 {
    struct pstip_stage *pstip = CALLOC_STRUCT(pstip_stage);
    if (pstip == NULL)
       goto fail;
 
+   pstip->pipe = pipe;
+
    pstip->stage.draw = draw;
    pstip->stage.name = "pstip";
    pstip->stage.next = NULL;
@@ -765,14 +772,12 @@ draw_install_pstipple_stage(struct draw_context *draw,
    /*
     * Create / install pgon stipple drawing / prim stage
     */
-   pstip = draw_pstip_stage( draw );
+   pstip = draw_pstip_stage( draw, pipe );
    if (pstip == NULL)
       goto fail;
 
    draw->pipeline.pstipple = &pstip->stage;
 
-   pstip->pipe = pipe;
-
    /* create special texture, sampler state */
    if (!pstip_create_texture(pstip))
       goto fail;
index 3e6e5389950779a0b543faf377864ea6c2dc278e..ee2945c7c97363d8e90c26651c7247565d9ad283 100644 (file)
@@ -226,6 +226,7 @@ static void widepoint_first_point( struct draw_stage *stage,
 
    if (rast->gl_rasterization_rules) {
       wide->xbias = 0.125;
+      wide->ybias = -0.125;
    }
 
    /* Disable triangle culling, stippling, unfilled mode etc. */
index 4584033bc2bda52c4475638ede197e6293e3f947..058aeedc17a03707737c8c980cca4a6215c7b484 100644 (file)
@@ -48,6 +48,7 @@
 
 #ifdef HAVE_LLVM
 #include <llvm-c/ExecutionEngine.h>
+struct draw_llvm;
 #endif
 
 
@@ -81,6 +82,9 @@ struct vertex_header {
 #define UNDEFINED_VERTEX_ID 0xffff
 
 
+/* maximum number of shader variants we can cache */
+#define DRAW_MAX_SHADER_VARIANTS 1024
+
 /**
  * Private context for the drawing module.
  */
@@ -245,6 +249,7 @@ struct draw_context
     */
    float plane[12][4];
    unsigned nr_planes;
+   boolean depth_clamp;
 
    /* If a prim stage introduces new vertex attributes, they'll be stored here
     */
@@ -259,9 +264,15 @@ struct draw_context
    unsigned instance_id;
 
 #ifdef HAVE_LLVM
+   struct draw_llvm *llvm;
    LLVMExecutionEngineRef engine;
 #endif
 
+   struct pipe_sampler_view *sampler_views[PIPE_MAX_VERTEX_SAMPLERS];
+   unsigned num_sampler_views;
+   const struct pipe_sampler_state *samplers[PIPE_MAX_VERTEX_SAMPLERS];
+   unsigned num_samplers;
+
    void *driver_private;
 };
 
index 02c97fec817302fb1650801d373352c508706a7e..92d4113b4c6116ff547a84e7a9a0e6eff3c82776 100644 (file)
 #include "draw/draw_gs.h"
 #include "draw/draw_private.h"
 #include "draw/draw_pt.h"
+#include "draw/draw_vs.h"
 #include "tgsi/tgsi_dump.h"
 #include "util/u_math.h"
 #include "util/u_prim.h"
+#include "util/u_format.h"
 
 
 DEBUG_GET_ONCE_BOOL_OPTION(draw_fse, "DRAW_FSE", FALSE)
@@ -69,7 +71,6 @@ draw_pt_arrays(struct draw_context *draw,
    struct draw_pt_front_end *frontend = NULL;
    struct draw_pt_middle_end *middle = NULL;
    unsigned opt = 0;
-   unsigned out_prim = prim;
 
    /* Sanitize primitive length:
     */
@@ -80,18 +81,19 @@ draw_pt_arrays(struct draw_context *draw,
       if (count < first)
          return TRUE;
    }
-   if (draw->gs.geometry_shader) {
-      out_prim = draw->gs.geometry_shader->output_primitive;
-   }
 
    if (!draw->force_passthrough) {
+      unsigned gs_out_prim = (draw->gs.geometry_shader ? 
+                              draw->gs.geometry_shader->output_primitive :
+                              prim);
+
       if (!draw->render) {
          opt |= PT_PIPELINE;
       }
 
       if (draw_need_pipeline(draw,
                              draw->rasterizer,
-                             out_prim)) {
+                             gs_out_prim)) {
          opt |= PT_PIPELINE;
       }
 
@@ -102,7 +104,7 @@ draw_pt_arrays(struct draw_context *draw,
       opt |= PT_SHADE;
    }
 
-   if (draw->pt.middle.llvm && !draw->gs.geometry_shader) {
+   if (draw->pt.middle.llvm) {
       middle = draw->pt.middle.llvm;
    } else {
       if (opt == 0)
@@ -122,7 +124,7 @@ draw_pt_arrays(struct draw_context *draw,
       frontend = draw->pt.front.varray;
    }
 
-   frontend->prepare( frontend, prim, out_prim, middle, opt );
+   frontend->prepare( frontend, prim, middle, opt );
 
    frontend->run(frontend,
                  draw_pt_elt_func(draw),
@@ -265,31 +267,38 @@ draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count)
          case PIPE_FORMAT_R32_FLOAT:
             {
                float *v = (float *) ptr;
-               debug_printf("%f  @ %p\n", v[0], (void *) v);
+               debug_printf("%f  @ %p\n", v[0], (void *) v);
             }
             break;
          case PIPE_FORMAT_R32G32_FLOAT:
             {
                float *v = (float *) ptr;
-               debug_printf("%f %f  @ %p\n", v[0], v[1], (void *) v);
+               debug_printf("RG %f %f  @ %p\n", v[0], v[1], (void *) v);
             }
             break;
          case PIPE_FORMAT_R32G32B32_FLOAT:
             {
                float *v = (float *) ptr;
-               debug_printf("%f %f %f  @ %p\n", v[0], v[1], v[2], (void *) v);
+               debug_printf("RGB %f %f %f  @ %p\n", v[0], v[1], v[2], (void *) v);
             }
             break;
          case PIPE_FORMAT_R32G32B32A32_FLOAT:
             {
                float *v = (float *) ptr;
-               debug_printf("%f %f %f %f  @ %p\n", v[0], v[1], v[2], v[3],
+               debug_printf("RGBA %f %f %f %f  @ %p\n", v[0], v[1], v[2], v[3],
                             (void *) v);
             }
             break;
+         case PIPE_FORMAT_B8G8R8A8_UNORM:
+            {
+               ubyte *u = (ubyte *) ptr;
+               debug_printf("BGRA %d %d %d %d  @ %p\n", u[0], u[1], u[2], u[3],
+                            (void *) u);
+            }
+            break;
          default:
-            debug_printf("other format (fix me)\n");
-            ;
+            debug_printf("other format %s (fix me)\n",
+                     util_format_name(draw->pt.vertex_element[j].src_format));
          }
       }
    }
@@ -297,11 +306,8 @@ draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count)
 
 
 /**
- * Draw vertex arrays
- * This is the main entrypoint into the drawing module.
- * \param prim  one of PIPE_PRIM_x
- * \param start  index of first vertex to draw
- * \param count  number of vertices to draw
+ * Non-instanced drawing.
+ * \sa draw_arrays_instanced
  */
 void
 draw_arrays(struct draw_context *draw, unsigned prim,
@@ -310,6 +316,20 @@ draw_arrays(struct draw_context *draw, unsigned prim,
    draw_arrays_instanced(draw, prim, start, count, 0, 1);
 }
 
+
+/**
+ * Draw vertex arrays.
+ * This is the main entrypoint into the drawing module.
+ * If drawing an indexed primitive, the draw_set_mapped_element_buffer_range()
+ * function should have already been called to specify the element/index buffer
+ * information.
+ *
+ * \param prim  one of PIPE_PRIM_x
+ * \param start  index of first vertex to draw
+ * \param count  number of vertices to draw
+ * \param startInstance  number for the first primitive instance (usually 0).
+ * \param instanceCount  number of instances to draw (1=non-instanced)
+ */
 void
 draw_arrays_instanced(struct draw_context *draw,
                       unsigned mode,
@@ -329,26 +349,30 @@ draw_arrays_instanced(struct draw_context *draw,
    if (0)
       draw_print_arrays(draw, mode, start, MIN2(count, 20));
 
-#if 0
-   {
-      int i;
+   if (0) {
+      unsigned int i;
       debug_printf("draw_arrays(mode=%u start=%u count=%u):\n",
                    mode, start, count);
       tgsi_dump(draw->vs.vertex_shader->state.tokens, 0);
       debug_printf("Elements:\n");
       for (i = 0; i < draw->pt.nr_vertex_elements; i++) {
-         debug_printf("  format=%s\n",
+         debug_printf("  %u: src_offset=%u  inst_div=%u   vbuf=%u  format=%s\n",
+                      i,
+                      draw->pt.vertex_element[i].src_offset,
+                      draw->pt.vertex_element[i].instance_divisor,
+                      draw->pt.vertex_element[i].vertex_buffer_index,
                       util_format_name(draw->pt.vertex_element[i].src_format));
       }
       debug_printf("Buffers:\n");
       for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
-         debug_printf("  stride=%u offset=%u ptr=%p\n",
+         debug_printf("  %u: stride=%u maxindex=%u offset=%u ptr=%p\n",
+                      i,
                       draw->pt.vertex_buffer[i].stride,
+                      draw->pt.vertex_buffer[i].max_index,
                       draw->pt.vertex_buffer[i].buffer_offset,
                       draw->pt.user.vbuffer[i]);
       }
    }
-#endif
 
    for (instance = 0; instance < instanceCount; instance++) {
       draw->instance_id = instance + startInstance;
index b6741ca83ce267b67c396eb7cfb7d399479935d9..44356fba4c553f81f553da3bb007e8eeb2a887ae 100644 (file)
@@ -62,8 +62,7 @@ struct draw_vertex_info;
  */
 struct draw_pt_front_end {
    void (*prepare)( struct draw_pt_front_end *,
-                    unsigned input_prim,
-                    unsigned output_prim,
+                    unsigned prim,
                     struct draw_pt_middle_end *,
                    unsigned opt );
 
@@ -87,8 +86,7 @@ struct draw_pt_front_end {
  */
 struct draw_pt_middle_end {
    void (*prepare)( struct draw_pt_middle_end *,
-                    unsigned input_prim,
-                    unsigned output_prim,
+                    unsigned prim,
                    unsigned opt,
                     unsigned *max_vertices );
 
index bf799db3524489af7adba5009ae89e0f0b39ace9..ae12ee24bdc36b2b7cfad30345a5712a4085e7a3 100644 (file)
@@ -68,31 +68,12 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch,
 
    fetch->vertex_size = vertex_size;
 
-   /* Always emit/leave space for a vertex header.
-    *
-    * It's worth considering whether the vertex headers should contain
-    * a pointer to the 'data', rather than having it inline.
-    * Something to look at after we've fully switched over to the pt
-    * paths.
+   /* Leave the clipmask/edgeflags/pad/vertex_id untouched
     */
-   {
-      /* Need to set header->vertex_id = 0xffff somehow.
-       */
-      key.element[nr].type = TRANSLATE_ELEMENT_NORMAL;
-      key.element[nr].input_format = PIPE_FORMAT_R32_FLOAT;
-      key.element[nr].input_buffer = draw->pt.nr_vertex_buffers;
-      key.element[nr].input_offset = 0;
-      key.element[nr].instance_divisor = 0;
-      key.element[nr].output_format = PIPE_FORMAT_R32_FLOAT;
-      key.element[nr].output_offset = dst_offset;
-      dst_offset += 1 * sizeof(float);
-      nr++;
-
-
-      /* Just leave the clip[] array untouched.
-       */
-      dst_offset += 4 * sizeof(float);
-   }
+   dst_offset += 1 * sizeof(float);
+   /* Just leave the clip[] array untouched.
+    */
+   dst_offset += 4 * sizeof(float);
 
    if (instance_id_index != ~0) {
       num_extra_inputs++;
@@ -131,26 +112,11 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch,
    key.nr_elements = nr;
    key.output_stride = vertex_size;
 
-
    if (!fetch->translate ||
        translate_key_compare(&fetch->translate->key, &key) != 0)
    {
       translate_key_sanitize(&key);
       fetch->translate = translate_cache_find(fetch->cache, &key);
-
-      {
-         static struct vertex_header vh = { 0,
-                                            1,
-                                            0,
-                                            UNDEFINED_VERTEX_ID,
-                                            { .0f, .0f, .0f, .0f } };
-
-        fetch->translate->set_buffer(fetch->translate,
-                                     draw->pt.nr_vertex_buffers,
-                                     &vh,
-                                     0,
-                                     ~0);
-      }
    }
 
 }
index c629d55563699cccf0cbd15069d69036c6012e3d..5c8af17c8e36d6382a0b39e815ab22788fe33592 100644 (file)
@@ -36,6 +36,7 @@
 #include "draw/draw_vbuf.h"
 #include "draw/draw_vertex.h"
 #include "draw/draw_pt.h"
+#include "draw/draw_gs.h"
 #include "translate/translate.h"
 #include "translate/translate_cache.h"
 
@@ -90,7 +91,6 @@ struct fetch_emit_middle_end {
 
 static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
                                 unsigned prim,
-                                unsigned out_prim,
                                unsigned opt,
                                 unsigned *max_vertices )
 {
@@ -101,9 +101,14 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
    boolean ok;
    struct translate_key key;
 
+   unsigned gs_out_prim = (draw->gs.geometry_shader ? 
+                           draw->gs.geometry_shader->output_primitive :
+                           prim);
+
+
 
    ok = draw->render->set_primitive( draw->render, 
-                                     out_prim );
+                                     gs_out_prim );
    if (!ok) {
       assert(0);
       return;
index 5483a25f1dc41a80c81f993956c9c0923fab2a05..b8270280b648175edb6055e2779312686cef2ff1 100644 (file)
@@ -68,8 +68,7 @@ struct fetch_shade_emit {
 
 
 static void fse_prepare( struct draw_pt_middle_end *middle,
-                         unsigned in_prim,
-                         unsigned out_prim,
+                         unsigned prim,
                          unsigned opt,
                          unsigned *max_vertices )
 {
@@ -80,9 +79,12 @@ static void fse_prepare( struct draw_pt_middle_end *middle,
    unsigned i;
    unsigned nr_vbs = 0;
 
+   /* Can't support geometry shader on this path.
+    */
+   assert(!draw->gs.geometry_shader);
 
    if (!draw->render->set_primitive( draw->render,
-                                     out_prim )) {
+                                     prim )) {
       assert(0);
       return;
    }
index 43b08a030cfec71facac8a0db513f3dbf7d97592..121dfc414a474330808f46e71b135eba6173d5f4 100644 (file)
@@ -48,13 +48,11 @@ struct fetch_pipeline_middle_end {
    unsigned vertex_data_offset;
    unsigned vertex_size;
    unsigned input_prim;
-   unsigned output_prim;
    unsigned opt;
 };
 
 static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
-                                    unsigned in_prim,
-                                    unsigned out_prim,
+                                    unsigned prim,
                                    unsigned opt,
                                     unsigned *max_vertices )
 {
@@ -64,6 +62,10 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
    unsigned i;
    unsigned instance_id_index = ~0;
 
+   unsigned gs_out_prim = (draw->gs.geometry_shader ? 
+                           draw->gs.geometry_shader->output_primitive :
+                           prim);
+
    /* Add one to num_outputs because the pipeline occasionally tags on
     * an additional texcoord, eg for AA lines.
     */
@@ -79,8 +81,7 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
       }
    }
 
-   fpme->input_prim = in_prim;
-   fpme->output_prim = out_prim;
+   fpme->input_prim = prim;
    fpme->opt = opt;
 
    /* Always leave room for the vertex header whether we need it or
@@ -102,13 +103,13 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
                            (boolean)draw->bypass_clipping,
                            (boolean)draw->identity_viewport,
                            (boolean)draw->rasterizer->gl_rasterization_rules,
-                           (draw->vs.edgeflag_output ? true : false) );
+                           (draw->vs.edgeflag_output ? TRUE : FALSE) );
 
    draw_pt_so_emit_prepare( fpme->so_emit );
 
    if (!(opt & PT_PIPELINE)) {
       draw_pt_emit_prepare( fpme->emit,
-                           out_prim,
+                           gs_out_prim,
                             max_vertices );
 
       *max_vertices = MAX2( *max_vertices,
@@ -183,7 +184,7 @@ static void draw_vertex_shader_run(struct draw_vertex_shader *vshader,
    output_verts->count = input_verts->count;
    output_verts->verts =
       (struct vertex_header *)MALLOC(output_verts->vertex_size *
-                                     output_verts->count);
+                                     align(output_verts->count, 4));
 
    vshader->run_linear(vshader,
                        (const float (*)[4])input_verts->verts->data,
index 7d2de58e733cbf68e9b83d49c6119f29f9d6d858..bc074df8c2ac6b25c211f6f81bb70f2b46c4acb2 100644 (file)
@@ -49,48 +49,50 @@ struct llvm_middle_end {
    unsigned vertex_data_offset;
    unsigned vertex_size;
    unsigned input_prim;
-   unsigned output_prim;
    unsigned opt;
 
    struct draw_llvm *llvm;
-   struct draw_llvm_variant *variants;
    struct draw_llvm_variant *current_variant;
-   int nr_variants;
 };
 
 
 static void
 llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
                          unsigned in_prim,
-                         unsigned out_prim,
                          unsigned opt,
                          unsigned *max_vertices )
 {
    struct llvm_middle_end *fpme = (struct llvm_middle_end *)middle;
    struct draw_context *draw = fpme->draw;
-   struct draw_vertex_shader *vs = draw->vs.vertex_shader;
+   struct llvm_vertex_shader *shader =
+      llvm_vertex_shader(draw->vs.vertex_shader);
    struct draw_llvm_variant_key key;
    struct draw_llvm_variant *variant = NULL;
+   struct draw_llvm_variant_list_item *li;
    unsigned i;
    unsigned instance_id_index = ~0;
 
+
+   unsigned out_prim = (draw->gs.geometry_shader ? 
+                        draw->gs.geometry_shader->output_primitive :
+                        in_prim);
+
    /* Add one to num_outputs because the pipeline occasionally tags on
     * an additional texcoord, eg for AA lines.
     */
-   unsigned nr = MAX2( vs->info.num_inputs,
-                      vs->info.num_outputs + 1 );
+   unsigned nr = MAX2( shader->base.info.num_inputs,
+                      shader->base.info.num_outputs + 1 );
 
    /* Scan for instanceID system value.
     */
-   for (i = 0; i < vs->info.num_inputs; i++) {
-      if (vs->info.input_semantic_name[i] == TGSI_SEMANTIC_INSTANCEID) {
+   for (i = 0; i < shader->base.info.num_inputs; i++) {
+      if (shader->base.info.input_semantic_name[i] == TGSI_SEMANTIC_INSTANCEID) {
          instance_id_index = i;
          break;
       }
    }
 
    fpme->input_prim = in_prim;
-   fpme->output_prim = out_prim;
    fpme->opt = opt;
 
    /* Always leave room for the vertex header whether we need it or
@@ -107,7 +109,7 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
                            (boolean)draw->bypass_clipping,
                            (boolean)(draw->identity_viewport),
                            (boolean)draw->rasterizer->gl_rasterization_rules,
-                           (draw->vs.edgeflag_output ? true : false) );
+                           (draw->vs.edgeflag_output ? TRUE : FALSE) );
 
    draw_pt_so_emit_prepare( fpme->so_emit );
 
@@ -128,20 +130,41 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
 
    draw_llvm_make_variant_key(fpme->llvm, &key);
 
-   variant = fpme->variants;
-   while(variant) {
-      if(memcmp(&variant->key, &key, sizeof key) == 0)
+   li = first_elem(&shader->variants);
+   while(!at_end(&shader->variants, li)) {
+      if(memcmp(&li->base->key, &key, sizeof key) == 0) {
+         variant = li->base;
          break;
+      }
+      li = next_elem(li);
+   }
 
-      variant = variant->next;
+   if (variant) {
+      move_to_head(&fpme->llvm->vs_variants_list, &variant->list_item_global);
    }
+   else {
+      unsigned i;
+      if (fpme->llvm->nr_variants >= DRAW_MAX_SHADER_VARIANTS) {
+         /*
+          * XXX: should we flush here ?
+          */
+         for (i = 0; i < DRAW_MAX_SHADER_VARIANTS / 4; i++) {
+            struct draw_llvm_variant_list_item *item =
+               last_elem(&fpme->llvm->vs_variants_list);
+            draw_llvm_destroy_variant(item->base);
+         }
+      }
+
+      variant = draw_llvm_create_variant(fpme->llvm, nr);
 
-   if (!variant) {
-      variant = draw_llvm_prepare(fpme->llvm, nr);
-      variant->next = fpme->variants;
-      fpme->variants = variant;
-      ++fpme->nr_variants;
+      if (variant) {
+         insert_at_head(&shader->variants, &variant->list_item_local);
+         insert_at_head(&fpme->llvm->vs_variants_list, &variant->list_item_global);
+         fpme->llvm->nr_variants++;
+         shader->variants_cached++;
+      }
    }
+
    fpme->current_variant = variant;
 
    /*XXX we only support one constant buffer */
@@ -210,7 +233,8 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle,
                                        fetch_info->start,
                                        fetch_info->count,
                                        fpme->vertex_size,
-                                       draw->pt.vertex_buffer );
+                                       draw->pt.vertex_buffer,
+                                       draw->instance_id);
    else
       fpme->current_variant->jit_func_elts( &fpme->llvm->jit_context,
                                             llvm_vert_info.verts,
@@ -218,7 +242,8 @@ llvm_pipeline_generic( struct draw_pt_middle_end *middle,
                                             fetch_info->elts,
                                             fetch_info->count,
                                             fpme->vertex_size,
-                                            draw->pt.vertex_buffer);
+                                            draw->pt.vertex_buffer,
+                                            draw->instance_id);
 
    /* Finished with fetch and vs:
     */
@@ -356,31 +381,7 @@ static void llvm_middle_end_finish( struct draw_pt_middle_end *middle )
 static void llvm_middle_end_destroy( struct draw_pt_middle_end *middle )
 {
    struct llvm_middle_end *fpme = (struct llvm_middle_end *)middle;
-   struct draw_context *draw = fpme->draw;
-   struct draw_llvm_variant *variant = NULL;
-
-   variant = fpme->variants;
-   while(variant) {
-      struct draw_llvm_variant *next = variant->next;
 
-      if (variant->function_elts) {
-         if (variant->function_elts)
-            LLVMFreeMachineCodeForFunction(draw->engine,
-                                           variant->function_elts);
-         LLVMDeleteFunction(variant->function_elts);
-      }
-
-      if (variant->function) {
-         if (variant->function)
-            LLVMFreeMachineCodeForFunction(draw->engine,
-                                           variant->function);
-         LLVMDeleteFunction(variant->function);
-      }
-
-      FREE(variant);
-
-      variant = next;
-   }
    if (fpme->fetch)
       draw_pt_fetch_destroy( fpme->fetch );
 
@@ -393,14 +394,12 @@ static void llvm_middle_end_destroy( struct draw_pt_middle_end *middle )
    if (fpme->post_vs)
       draw_pt_post_vs_destroy( fpme->post_vs );
 
-   if (fpme->llvm)
-      draw_llvm_destroy( fpme->llvm );
-
    FREE(middle);
 }
 
 
-struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit_llvm( struct draw_context *draw )
+struct draw_pt_middle_end *
+draw_pt_fetch_pipeline_or_emit_llvm(struct draw_context *draw)
 {
    struct llvm_middle_end *fpme = 0;
 
@@ -436,13 +435,11 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit_llvm( struct draw_cont
    if (!fpme->so_emit)
       goto fail;
 
-   fpme->llvm = draw_llvm_create(draw);
+   fpme->llvm = draw->llvm;
    if (!fpme->llvm)
       goto fail;
 
-   fpme->variants = NULL;
    fpme->current_variant = NULL;
-   fpme->nr_variants = 0;
 
    return &fpme->base;
 
index 112be50f9ae469abff82e0eb71d63ef8fc484687..308f927b778652f0f55aca658d60dd139d101a20 100644 (file)
@@ -38,7 +38,14 @@ struct pt_post_vs {
                    struct draw_vertex_info *info );
 };
 
-
+static INLINE void
+initialize_vertex_header(struct vertex_header *header)
+{
+   header->clipmask = 0;
+   header->edgeflag = 1;
+   header->pad = 0;
+   header->vertex_id = UNDEFINED_VERTEX_ID;
+}
 
 static INLINE float
 dot4(const float *a, const float *b)
@@ -49,10 +56,9 @@ dot4(const float *a, const float *b)
            a[3]*b[3]);
 }
 
-
-
 static INLINE unsigned
-compute_clipmask_gl(const float *clip, /*const*/ float plane[][4], unsigned nr)
+compute_clipmask_gl(const float *clip, /*const*/ float plane[][4], unsigned nr,
+                    boolean clip_depth)
 {
    unsigned mask = 0x0;
    unsigned i;
@@ -69,8 +75,10 @@ compute_clipmask_gl(const float *clip, /*const*/ float plane[][4], unsigned nr)
    if ( clip[0] + clip[3] < 0) mask |= (1<<1);
    if (-clip[1] + clip[3] < 0) mask |= (1<<2);
    if ( clip[1] + clip[3] < 0) mask |= (1<<3);
-   if ( clip[2] + clip[3] < 0) mask |= (1<<4); /* match mesa clipplane numbering - for now */
-   if (-clip[2] + clip[3] < 0) mask |= (1<<5); /* match mesa clipplane numbering - for now */
+   if (clip_depth) {
+      if ( clip[2] + clip[3] < 0) mask |= (1<<4); /* match mesa clipplane numbering - for now */
+      if (-clip[2] + clip[3] < 0) mask |= (1<<5); /* match mesa clipplane numbering - for now */
+   }
 
    /* Followed by any remaining ones:
     */
@@ -103,6 +111,7 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs,
    for (j = 0; j < info->count; j++) {
       float *position = out->data[pos];
 
+      initialize_vertex_header(out);
 #if 0
       debug_printf("%d) io = %p, data = %p = [%f, %f, %f, %f]\n",
                    j, out, position, position[0], position[1], position[2], position[3]);
@@ -114,9 +123,11 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs,
       out->clip[3] = position[3];
 
       out->vertex_id = 0xffff;
+      /* Disable depth clipping if depth clamping is enabled. */
       out->clipmask = compute_clipmask_gl(out->clip, 
                                          pvs->draw->plane,
-                                         pvs->draw->nr_planes);
+                                          pvs->draw->nr_planes,
+                                          !pvs->draw->depth_clamp);
       clipped += out->clipmask;
 
       if (out->clipmask == 0)
@@ -192,6 +203,7 @@ static boolean post_vs_viewport( struct pt_post_vs *pvs,
    for (j = 0; j < info->count; j++) {
       float *position = out->data[pos];
 
+      initialize_vertex_header(out);
       /* Viewport mapping only, no cliptest/rhw divide
        */
       position[0] = position[0] * scale[0] + trans[0];
@@ -211,7 +223,16 @@ static boolean post_vs_viewport( struct pt_post_vs *pvs,
 static boolean post_vs_none( struct pt_post_vs *pvs,
                             struct draw_vertex_info *info )
 {
+   struct vertex_header *out = info->verts;
+   unsigned j;
+
    if (0) debug_printf("%s\n", __FUNCTION__);
+   /* just initialize the vertex_id in all headers */
+   for (j = 0; j < info->count; j++) {
+      initialize_vertex_header(out);
+
+      out = (struct vertex_header *)((char *)out + info->stride);
+   }
    return FALSE;
 }
 
index 5ea833032f322da20762a4da5988a6b36f458711..cd7bb7bf25327deca5c4748f318ef7c9f8fddac7 100644 (file)
@@ -120,24 +120,27 @@ static void varray_fan_segment(struct varray_frontend *varray,
 #define FUNC varray_run
 #include "draw_pt_varray_tmp_linear.h"
 
-static unsigned decompose_prim[PIPE_PRIM_POLYGON + 1] = {
+static unsigned decompose_prim[PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY + 1] = {
    PIPE_PRIM_POINTS,
    PIPE_PRIM_LINES,
    PIPE_PRIM_LINE_STRIP,        /* decomposed LINELOOP */
    PIPE_PRIM_LINE_STRIP,
    PIPE_PRIM_TRIANGLES,
    PIPE_PRIM_TRIANGLE_STRIP,
-   PIPE_PRIM_TRIANGLE_FAN, 
+   PIPE_PRIM_TRIANGLE_FAN,
    PIPE_PRIM_QUADS,
    PIPE_PRIM_QUAD_STRIP,
-   PIPE_PRIM_POLYGON
+   PIPE_PRIM_POLYGON,
+   PIPE_PRIM_LINES_ADJACENCY,
+   PIPE_PRIM_LINE_STRIP_ADJACENCY,
+   PIPE_PRIM_TRIANGLES_ADJACENCY,
+   PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY
 };
 
 
 
 static void varray_prepare(struct draw_pt_front_end *frontend,
                            unsigned in_prim,
-                           unsigned out_prim,
                            struct draw_pt_middle_end *middle,
                            unsigned opt)
 {
@@ -146,11 +149,13 @@ static void varray_prepare(struct draw_pt_front_end *frontend,
    varray->base.run = varray_run;
 
    varray->input_prim = in_prim;
-   varray->output_prim = decompose_prim[out_prim];
+   assert(in_prim < Elements(decompose_prim));
+   varray->output_prim = decompose_prim[in_prim];
 
    varray->middle = middle;
-   middle->prepare(middle, varray->input_prim,
-                   varray->output_prim, opt, &varray->driver_fetch_max );
+   middle->prepare(middle,
+                   varray->output_prim,
+                   opt, &varray->driver_fetch_max );
 
    /* check that the max is even */
    assert((varray->driver_fetch_max & 1) == 0);
index 914c87a9dc485a38c8d63c4a6a7f51d8431a8b57..8ef94c3163c2283b2b6fd86d4e3996a873c82e76 100644 (file)
@@ -41,6 +41,7 @@
 #define FETCH_MAX 256
 #define DRAW_MAX (16*1024)
 
+
 struct vcache_frontend {
    struct draw_pt_front_end base;
    struct draw_context *draw;
@@ -64,13 +65,13 @@ struct vcache_frontend {
    unsigned opt;
 };
 
+
 static INLINE void
 vcache_flush( struct vcache_frontend *vcache )
 {
    if (vcache->middle_prim != vcache->output_prim) {
       vcache->middle_prim = vcache->output_prim;
       vcache->middle->prepare( vcache->middle,
-                               vcache->input_prim,
                                vcache->middle_prim,
                                vcache->opt,
                                &vcache->fetch_max );
@@ -89,12 +90,12 @@ vcache_flush( struct vcache_frontend *vcache )
    vcache->draw_count = 0;
 }
 
+
 static INLINE void 
 vcache_check_flush( struct vcache_frontend *vcache )
 {
-   if ( vcache->draw_count + 6 >= DRAW_MAX ||
-        vcache->fetch_count + 4 >= FETCH_MAX )
-   {
+   if (vcache->draw_count + 6 >= DRAW_MAX ||
+       vcache->fetch_count + 4 >= FETCH_MAX) {
       vcache_flush( vcache );
    }
 }
@@ -146,6 +147,7 @@ vcache_triangle_flags( struct vcache_frontend *vcache,
    vcache_check_flush(vcache);
 }
 
+
 static INLINE void 
 vcache_line( struct vcache_frontend *vcache,
              unsigned i0,
@@ -177,6 +179,7 @@ vcache_point( struct vcache_frontend *vcache,
    vcache_check_flush(vcache);
 }
 
+
 static INLINE void 
 vcache_quad( struct vcache_frontend *vcache,
              unsigned i0,
@@ -196,6 +199,7 @@ vcache_quad( struct vcache_frontend *vcache,
    }
 }
 
+
 static INLINE void 
 vcache_ef_quad( struct vcache_frontend *vcache,
                 unsigned i0,
@@ -231,6 +235,7 @@ vcache_ef_quad( struct vcache_frontend *vcache,
    }
 }
 
+
 /* At least for now, we're back to using a template include file for
  * this.  The two paths aren't too different though - it may be
  * possible to reunify them.
@@ -256,23 +261,23 @@ rebase_uint_elts( const unsigned *src,
                   ushort *dest )
 {
    unsigned i;
-
    for (i = 0; i < count; i++) 
       dest[i] = (ushort)(src[i] + delta);
 }
 
+
 static INLINE void 
 rebase_ushort_elts( const ushort *src,
                     unsigned count,
                     int delta,
-                                ushort *dest )
+                    ushort *dest )
 {
    unsigned i;
-
    for (i = 0; i < count; i++) 
       dest[i] = (ushort)(src[i] + delta);
 }
 
+
 static INLINE void 
 rebase_ubyte_elts( const ubyte *src,
                    unsigned count,
@@ -280,42 +285,39 @@ rebase_ubyte_elts( const ubyte *src,
                    ushort *dest )
 {
    unsigned i;
-
    for (i = 0; i < count; i++) 
       dest[i] = (ushort)(src[i] + delta);
 }
 
 
-
 static INLINE void 
 translate_uint_elts( const unsigned *src,
                      unsigned count,
                      ushort *dest )
 {
    unsigned i;
-
    for (i = 0; i < count; i++) 
       dest[i] = (ushort)(src[i]);
 }
 
+
 static INLINE void 
 translate_ushort_elts( const ushort *src,
                        unsigned count,
                        ushort *dest )
 {
    unsigned i;
-
    for (i = 0; i < count; i++) 
       dest[i] = (ushort)(src[i]);
 }
 
+
 static INLINE void 
 translate_ubyte_elts( const ubyte *src,
                       unsigned count,
                       ushort *dest )
 {
    unsigned i;
-
    for (i = 0; i < count; i++) 
       dest[i] = (ushort)(src[i]);
 }
@@ -336,6 +338,7 @@ format_from_get_elt( pt_elt_func get_elt )
 }
 #endif
 
+
 static INLINE void 
 vcache_check_run( struct draw_pt_front_end *frontend, 
                   pt_elt_func get_elt,
@@ -345,18 +348,46 @@ vcache_check_run( struct draw_pt_front_end *frontend,
 {
    struct vcache_frontend *vcache = (struct vcache_frontend *)frontend; 
    struct draw_context *draw = vcache->draw;
-   unsigned min_index = draw->pt.user.min_index;
-   unsigned max_index = draw->pt.user.max_index;
-   unsigned index_size = draw->pt.user.eltSize;
-   unsigned fetch_count = max_index + 1 - min_index;
+   const unsigned min_index = draw->pt.user.min_index;
+   const unsigned max_index = draw->pt.user.max_index;
+   const unsigned index_size = draw->pt.user.eltSize;
+   unsigned fetch_count;
    const ushort *transformed_elts;
    ushort *storage = NULL;
    boolean ok = FALSE;
 
+   /* debug: verify indexes are in range [min_index, max_index] */
+   if (0) {
+      unsigned i;
+      for (i = 0; i < draw_count; i++) {
+         if (index_size == 1) {
+            assert( ((const ubyte *) elts)[i] >= min_index);
+            assert( ((const ubyte *) elts)[i] <= max_index);
+         }
+         else if (index_size == 2) {
+            assert( ((const ushort *) elts)[i] >= min_index);
+            assert( ((const ushort *) elts)[i] <= max_index);
+         }
+         else {
+            assert(index_size == 4);
+            assert( ((const uint *) elts)[i] >= min_index);
+            assert( ((const uint *) elts)[i] <= max_index);
+         }
+      }
+   }
+
+   /* Note: max_index is frequently 0xffffffff so we have to be sure
+    * that any arithmetic involving max_index doesn't overflow!
+    */
+   if (max_index >= (unsigned) DRAW_PIPE_MAX_VERTICES)
+      goto fail;
 
-   if (0) debug_printf("fetch_count %d fetch_max %d draw_count %d\n", fetch_count, 
-                       vcache->fetch_max,
-                       draw_count);
+   fetch_count = max_index + 1 - min_index;
+
+   if (0)
+      debug_printf("fetch_count %d fetch_max %d draw_count %d\n", fetch_count, 
+                   vcache->fetch_max,
+                   draw_count);
 
    if (elt_bias + max_index >= DRAW_PIPE_MAX_VERTICES ||
        fetch_count >= UNDEFINED_VERTEX_ID ||
@@ -368,23 +399,19 @@ vcache_check_run( struct draw_pt_front_end *frontend,
    if (vcache->middle_prim != vcache->input_prim) {
       vcache->middle_prim = vcache->input_prim;
       vcache->middle->prepare( vcache->middle,
-                               vcache->input_prim,
                                vcache->middle_prim,
                                vcache->opt,
                                &vcache->fetch_max );
    }
 
-
    assert((elt_bias >= 0 && min_index + elt_bias >= min_index) ||
           (elt_bias <  0 && min_index + elt_bias <  min_index));
 
    if (min_index == 0 &&
-       index_size == 2)
-   {
+       index_size == 2) {
       transformed_elts = (const ushort *)elts;
    }
-   else 
-   {
+   else {
       storage = MALLOC( draw_count * sizeof(ushort) );
       if (!storage)
          goto fail;
@@ -419,23 +446,23 @@ vcache_check_run( struct draw_pt_front_end *frontend,
          switch(index_size) {
          case 1:
             rebase_ubyte_elts( (const ubyte *)elts,
-                                  draw_count,
-                                  0 - (int)min_index,
-                                  storage );
+                               draw_count,
+                               0 - (int)min_index,
+                               storage );
             break;
 
          case 2:
             rebase_ushort_elts( (const ushort *)elts,
-                                   draw_count,
-                                   0 - (int)min_index,
-                                   storage );
+                                draw_count,
+                                0 - (int)min_index,
+                                storage );
             break;
 
          case 4:
             rebase_uint_elts( (const uint *)elts,
-                                 draw_count,
-                                 0 - (int)min_index,
-                                 storage );
+                              draw_count,
+                              0 - (int)min_index,
+                              storage );
             break;
 
          default:
@@ -462,7 +489,7 @@ vcache_check_run( struct draw_pt_front_end *frontend,
    debug_printf("failed to execute atomic draw elts for %d/%d, splitting up\n",
                 fetch_count, draw_count);
 
- fail:
+fail:
    vcache_run( frontend, get_elt, elts, elt_bias, draw_count );
 }
 
@@ -472,23 +499,26 @@ vcache_check_run( struct draw_pt_front_end *frontend,
 static void
 vcache_prepare( struct draw_pt_front_end *frontend,
                 unsigned in_prim,
-                unsigned out_prim,
                 struct draw_pt_middle_end *middle,
                 unsigned opt )
 {
    struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
 
-   if (opt & PT_PIPELINE)
-   {
+   if (opt & PT_PIPELINE) {
       vcache->base.run = vcache_run_extras;
    }
-   else
-   {
+   else {
       vcache->base.run = vcache_check_run;
    }
 
+   /* VCache will always emit the reduced version of its input
+    * primitive, ie STRIP/FANS become TRIS, etc.
+    *
+    * This is not to be confused with what the GS might be up to,
+    * which is a separate issue.
+    */
    vcache->input_prim = in_prim;
-   vcache->output_prim = u_reduced_prim(out_prim);
+   vcache->output_prim = u_reduced_prim(in_prim);
 
    vcache->middle = middle;
    vcache->opt = opt;
@@ -496,12 +526,13 @@ vcache_prepare( struct draw_pt_front_end *frontend,
    /* Have to run prepare here, but try and guess a good prim for
     * doing so:
     */
-   vcache->middle_prim = (opt & PT_PIPELINE) ? vcache->output_prim : vcache->input_prim;
-   middle->prepare( middle, vcache->input_prim,
-                    vcache->middle_prim, opt, &vcache->fetch_max );
-}
-
+   vcache->middle_prim = (opt & PT_PIPELINE)
+      ? vcache->output_prim : vcache->input_prim;
 
+   middle->prepare( middle,
+                    vcache->middle_prim,
+                    opt, &vcache->fetch_max );
+}
 
 
 static void 
@@ -512,6 +543,7 @@ vcache_finish( struct draw_pt_front_end *frontend )
    vcache->middle = NULL;
 }
 
+
 static void 
 vcache_destroy( struct draw_pt_front_end *frontend )
 {
index b9db886a24da41a98466298a77b40daddd0f3c2a..57ea63fc060a3c085d2c7d8095903fd1e90c04ec 100644 (file)
@@ -98,6 +98,11 @@ draw_create_vertex_shader(struct draw_context *draw,
       vs = draw_create_vs_ppc( draw, shader );
 #endif
    }
+#if HAVE_LLVM
+   else {
+      vs = draw_create_vs_llvm(draw, shader);
+   }
+#endif
 
    if (!vs) {
       vs = draw_create_vs_exec( draw, shader );
index 6c7e94db43344f33a6c68411b5d8343fc8c844a4..a731994523442b5b6f8fb242f9811620b2570f42 100644 (file)
@@ -165,7 +165,6 @@ draw_create_vs_ppc(struct draw_context *draw,
                   const struct pipe_shader_state *templ);
 
 
-
 struct draw_vs_varient_key;
 struct draw_vertex_shader;
 
@@ -173,6 +172,11 @@ struct draw_vs_varient *
 draw_vs_create_varient_aos_sse( struct draw_vertex_shader *vs,
                                 const struct draw_vs_varient_key *key );
 
+#if HAVE_LLVM
+struct draw_vertex_shader *
+draw_create_vs_llvm(struct draw_context *draw,
+                   const struct pipe_shader_state *state);
+#endif
 
 
 /********************************************************************************
diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c
new file mode 100644 (file)
index 0000000..6c13df7
--- /dev/null
@@ -0,0 +1,120 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE 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 "util/u_math.h"
+#include "util/u_memory.h"
+#include "pipe/p_shader_tokens.h"
+
+#include "draw_private.h"
+#include "draw_context.h"
+#include "draw_vs.h"
+#include "draw_llvm.h"
+
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_scan.h"
+
+static void
+vs_llvm_prepare(struct draw_vertex_shader *shader,
+                struct draw_context *draw)
+{
+   /*struct llvm_vertex_shader *evs = llvm_vertex_shader(shader);*/
+}
+
+static void
+vs_llvm_run_linear( struct draw_vertex_shader *shader,
+                   const float (*input)[4],
+                   float (*output)[4],
+                    const void *constants[PIPE_MAX_CONSTANT_BUFFERS],
+                   unsigned count,
+                   unsigned input_stride,
+                   unsigned output_stride )
+{
+   /* we should never get here since the entire pipeline is
+    * generated in draw_pt_fetch_shade_pipeline_llvm.c */
+   debug_assert(0);
+}
+
+
+static void
+vs_llvm_delete( struct draw_vertex_shader *dvs )
+{
+   struct llvm_vertex_shader *shader = llvm_vertex_shader(dvs);
+   struct pipe_fence_handle *fence = NULL;
+   struct draw_llvm_variant_list_item *li;
+   struct pipe_context *pipe = dvs->draw->pipe;
+
+   /*
+    * XXX: This might be not neccessary at all.
+    */
+   pipe->flush(pipe, 0, &fence);
+   if (fence) {
+      pipe->screen->fence_finish(pipe->screen, fence, 0);
+      pipe->screen->fence_reference(pipe->screen, &fence, NULL);
+   }
+
+
+   li = first_elem(&shader->variants);
+   while(!at_end(&shader->variants, li)) {
+      struct draw_llvm_variant_list_item *next = next_elem(li);
+      draw_llvm_destroy_variant(li->base);
+      li = next;
+   }
+
+   assert(shader->variants_cached == 0);
+   FREE((void*) dvs->state.tokens);
+   FREE( dvs );
+}
+
+
+struct draw_vertex_shader *
+draw_create_vs_llvm(struct draw_context *draw,
+                   const struct pipe_shader_state *state)
+{
+   struct llvm_vertex_shader *vs = CALLOC_STRUCT( llvm_vertex_shader );
+
+   if (vs == NULL)
+      return NULL;
+
+   /* we make a private copy of the tokens */
+   vs->base.state.tokens = tgsi_dup_tokens(state->tokens);
+   if (!vs->base.state.tokens) {
+      FREE(vs);
+      return NULL;
+   }
+
+   tgsi_scan_shader(state->tokens, &vs->base.info);
+
+   vs->base.draw = draw;
+   vs->base.prepare = vs_llvm_prepare;
+   vs->base.run_linear = vs_llvm_run_linear;
+   vs->base.delete = vs_llvm_delete;
+   vs->base.create_varient = draw_vs_create_varient_generic;
+
+   make_empty_list(&vs->variants);
+
+   return &vs->base;
+}
index d926b2de18977b23b2b4df550c27c8956f7576d4..f5f2623e467850de886d45cb699fb1d10ff6040c 100644 (file)
@@ -56,7 +56,6 @@
 #include "lp_bld_intr.h"
 #include "lp_bld_logic.h"
 #include "lp_bld_pack.h"
-#include "lp_bld_debug.h"
 #include "lp_bld_arit.h"
 
 
@@ -847,6 +846,11 @@ lp_build_round_sse41(struct lp_build_context *bld,
 }
 
 
+/**
+ * Return the integer part of a float (vector) value.  The returned value is
+ * a float (vector).
+ * Ex: trunc(-1.5) = 1.0
+ */
 LLVMValueRef
 lp_build_trunc(struct lp_build_context *bld,
                LLVMValueRef a)
@@ -869,6 +873,12 @@ lp_build_trunc(struct lp_build_context *bld,
 }
 
 
+/**
+ * Return float (vector) rounded to nearest integer (vector).  The returned
+ * value is a float (vector).
+ * Ex: round(0.9) = 1.0
+ * Ex: round(-1.5) = -2.0
+ */
 LLVMValueRef
 lp_build_round(struct lp_build_context *bld,
                LLVMValueRef a)
@@ -890,6 +900,11 @@ lp_build_round(struct lp_build_context *bld,
 }
 
 
+/**
+ * Return floor of float (vector), result is a float (vector)
+ * Ex: floor(1.1) = 1.0
+ * Ex: floor(-1.1) = -2.0
+ */
 LLVMValueRef
 lp_build_floor(struct lp_build_context *bld,
                LLVMValueRef a)
@@ -911,6 +926,11 @@ lp_build_floor(struct lp_build_context *bld,
 }
 
 
+/**
+ * Return ceiling of float (vector), returning float (vector).
+ * Ex: ceil( 1.1) = 2.0
+ * Ex: ceil(-1.1) = -1.0
+ */
 LLVMValueRef
 lp_build_ceil(struct lp_build_context *bld,
               LLVMValueRef a)
@@ -933,7 +953,7 @@ lp_build_ceil(struct lp_build_context *bld,
 
 
 /**
- * Return fractional part of 'a' computed as a - floor(f)
+ * Return fractional part of 'a' computed as a - floor(a)
  * Typically used in texture coord arithmetic.
  */
 LLVMValueRef
@@ -946,8 +966,9 @@ lp_build_fract(struct lp_build_context *bld,
 
 
 /**
- * Convert to integer, through whichever rounding method that's fastest,
- * typically truncating toward zero.
+ * Return the integer part of a float (vector) value.  The returned value is
+ * an integer (vector).
+ * Ex: itrunc(-1.5) = 1
  */
 LLVMValueRef
 lp_build_itrunc(struct lp_build_context *bld,
@@ -964,7 +985,10 @@ lp_build_itrunc(struct lp_build_context *bld,
 
 
 /**
- * Convert float[] to int[] with round().
+ * Return float (vector) rounded to nearest integer (vector).  The returned
+ * value is an integer (vector).
+ * Ex: iround(0.9) = 1
+ * Ex: iround(-1.5) = -2
  */
 LLVMValueRef
 lp_build_iround(struct lp_build_context *bld,
@@ -1007,7 +1031,9 @@ lp_build_iround(struct lp_build_context *bld,
 
 
 /**
- * Convert float[] to int[] with floor().
+ * Return floor of float (vector), result is an int (vector)
+ * Ex: ifloor(1.1) = 1.0
+ * Ex: ifloor(-1.1) = -2.0
  */
 LLVMValueRef
 lp_build_ifloor(struct lp_build_context *bld,
@@ -1034,29 +1060,31 @@ lp_build_ifloor(struct lp_build_context *bld,
       /* sign = a < 0 ? ~0 : 0 */
       sign = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
       sign = LLVMBuildAnd(bld->builder, sign, mask, "");
-      sign = LLVMBuildAShr(bld->builder, sign, lp_build_const_int_vec(type, type.width - 1), "");
-      lp_build_name(sign, "floor.sign");
+      sign = LLVMBuildAShr(bld->builder, sign, lp_build_const_int_vec(type, type.width - 1), "ifloor.sign");
 
       /* offset = -0.99999(9)f */
-      offset = lp_build_const_vec(type, -(double)(((unsigned long long)1 << mantissa) - 1)/((unsigned long long)1 << mantissa));
+      offset = lp_build_const_vec(type, -(double)(((unsigned long long)1 << mantissa) - 10)/((unsigned long long)1 << mantissa));
       offset = LLVMConstBitCast(offset, int_vec_type);
 
-      /* offset = a < 0 ? -0.99999(9)f : 0.0f */
+      /* offset = a < 0 ? offset : 0.0f */
       offset = LLVMBuildAnd(bld->builder, offset, sign, "");
-      offset = LLVMBuildBitCast(bld->builder, offset, vec_type, "");
-      lp_build_name(offset, "floor.offset");
+      offset = LLVMBuildBitCast(bld->builder, offset, vec_type, "ifloor.offset");
 
-      res = LLVMBuildAdd(bld->builder, a, offset, "");
-      lp_build_name(res, "floor.res");
+      res = LLVMBuildAdd(bld->builder, a, offset, "ifloor.res");
    }
 
-   res = LLVMBuildFPToSI(bld->builder, res, int_vec_type, "");
-   lp_build_name(res, "floor");
+   /* round to nearest (toward zero) */
+   res = LLVMBuildFPToSI(bld->builder, res, int_vec_type, "ifloor.res");
 
    return res;
 }
 
 
+/**
+ * Return ceiling of float (vector), returning int (vector).
+ * Ex: iceil( 1.1) = 2
+ * Ex: iceil(-1.1) = -1
+ */
 LLVMValueRef
 lp_build_iceil(struct lp_build_context *bld,
                LLVMValueRef a)
@@ -1072,12 +1100,31 @@ lp_build_iceil(struct lp_build_context *bld,
       res = lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_CEIL);
    }
    else {
-      /* TODO: mimic lp_build_ifloor() here */
-      assert(0);
-      res = bld->undef;
+      LLVMTypeRef vec_type = lp_build_vec_type(type);
+      unsigned mantissa = lp_mantissa(type);
+      LLVMValueRef mask = lp_build_const_int_vec(type, (unsigned long long)1 << (type.width - 1));
+      LLVMValueRef sign;
+      LLVMValueRef offset;
+
+      /* sign = a < 0 ? 0 : ~0 */
+      sign = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
+      sign = LLVMBuildAnd(bld->builder, sign, mask, "");
+      sign = LLVMBuildAShr(bld->builder, sign, lp_build_const_int_vec(type, type.width - 1), "iceil.sign");
+      sign = LLVMBuildNot(bld->builder, sign, "iceil.not");
+
+      /* offset = 0.99999(9)f */
+      offset = lp_build_const_vec(type, (double)(((unsigned long long)1 << mantissa) - 10)/((unsigned long long)1 << mantissa));
+      offset = LLVMConstBitCast(offset, int_vec_type);
+
+      /* offset = a < 0 ? 0.0 : offset */
+      offset = LLVMBuildAnd(bld->builder, offset, sign, "");
+      offset = LLVMBuildBitCast(bld->builder, offset, vec_type, "iceil.offset");
+
+      res = LLVMBuildAdd(bld->builder, a, offset, "iceil.res");
    }
 
-   res = LLVMBuildFPToSI(bld->builder, res, int_vec_type, "");
+   /* round to nearest (toward zero) */
+   res = LLVMBuildFPToSI(bld->builder, res, int_vec_type, "iceil.res");
 
    return res;
 }
index d46b9f882b0fa38ba8bc44aaa988337b7269a306..7ee8fff1407db33472416a78f203558a046bd39c 100644 (file)
@@ -107,4 +107,12 @@ lp_build_const_mask_aos(struct lp_type type,
                         const boolean cond[4]);
 
 
+static INLINE LLVMValueRef
+lp_build_const_int32(int i)
+{
+   return LLVMConstInt(LLVMInt32Type(), i, 0);
+}
+
+
+
 #endif /* !LP_BLD_CONST_H */
index 3f7f2ebde9ce700b99e88e50ae0b8249b43ebb97..77012f1fac62ec524273399bcab1c30fac333761 100644 (file)
@@ -83,6 +83,9 @@
  *
  * Although the result values can be scaled to an arbitrary bit width specified
  * by dst_width, the actual result type will have the same width.
+ *
+ * Ex: src = { float, float, float, float }
+ * return { i32, i32, i32, i32 } where each value is in [0, 2^dst_width-1].
  */
 LLVMValueRef
 lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
@@ -152,6 +155,8 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
 
 /**
  * Inverse of lp_build_clamped_float_to_unsigned_norm above.
+ * Ex: src = { i32, i32, i32, i32 } with values in range [0, 2^src_width-1]
+ * return {float, float, float, float} with values in range [0, 1].
  */
 LLVMValueRef
 lp_build_unsigned_norm_to_float(LLVMBuilderRef builder,
@@ -219,18 +224,19 @@ lp_build_conv(LLVMBuilderRef builder,
    unsigned num_tmps;
    unsigned i;
 
-   /* Register width must remain constant */
-   assert(src_type.width * src_type.length == dst_type.width * dst_type.length);
-
    /* We must not loose or gain channels. Only precision */
    assert(src_type.length * num_srcs == dst_type.length * num_dsts);
 
    assert(src_type.length <= LP_MAX_VECTOR_LENGTH);
    assert(dst_type.length <= LP_MAX_VECTOR_LENGTH);
+   assert(num_srcs <= LP_MAX_VECTOR_LENGTH);
+   assert(num_dsts <= LP_MAX_VECTOR_LENGTH);
 
    tmp_type = src_type;
-   for(i = 0; i < num_srcs; ++i)
+   for(i = 0; i < num_srcs; ++i) {
+      assert(lp_check_value(src_type, src[i]));
       tmp[i] = src[i];
+   }
    num_tmps = num_srcs;
 
    /*
@@ -326,30 +332,25 @@ lp_build_conv(LLVMBuilderRef builder,
 
    /*
     * Truncate or expand bit width
+    *
+    * No data conversion should happen here, although the sign bits are
+    * crucial to avoid bad clamping.
     */
 
-   assert(!tmp_type.floating || tmp_type.width == dst_type.width);
+   {
+      struct lp_type new_type;
 
-   if(tmp_type.width > dst_type.width) {
-      assert(num_dsts == 1);
-      tmp[0] = lp_build_pack(builder, tmp_type, dst_type, TRUE, tmp, num_tmps);
-      tmp_type.width = dst_type.width;
-      tmp_type.length = dst_type.length;
-      num_tmps = 1;
-   }
+      new_type = tmp_type;
+      new_type.sign   = dst_type.sign;
+      new_type.width  = dst_type.width;
+      new_type.length = dst_type.length;
+
+      lp_build_resize(builder, tmp_type, new_type, tmp, num_srcs, tmp, num_dsts);
 
-   if(tmp_type.width < dst_type.width) {
-      assert(num_tmps == 1);
-      lp_build_unpack(builder, tmp_type, dst_type, tmp[0], tmp, num_dsts);
-      tmp_type.width = dst_type.width;
-      tmp_type.length = dst_type.length;
+      tmp_type = new_type;
       num_tmps = num_dsts;
    }
 
-   assert(tmp_type.width == dst_type.width);
-   assert(tmp_type.length == dst_type.length);
-   assert(num_tmps == num_dsts);
-
    /*
     * Scale to the widest range
     */
@@ -406,8 +407,10 @@ lp_build_conv(LLVMBuilderRef builder,
        }
     }
 
-   for(i = 0; i < num_dsts; ++i)
+   for(i = 0; i < num_dsts; ++i) {
       dst[i] = tmp[i];
+      assert(lp_check_value(dst_type, dst[i]));
+   }
 }
 
 
index 5f5036e7bdc2672e1f3e2364c2649c407f97af69..60e22d727ad456ef33b1117db1ed8057edee4ff3 100644 (file)
@@ -48,9 +48,9 @@ struct lp_build_context;
  */
 
 LLVMValueRef
-lp_build_unpack_rgba_aos(LLVMBuilderRef builder,
-                         const struct util_format_description *desc,
-                         LLVMValueRef packed);
+lp_build_format_swizzle_aos(const struct util_format_description *desc,
+                            struct lp_build_context *bld,
+                            LLVMValueRef unswizzled);
 
 LLVMValueRef
 lp_build_pack_rgba_aos(LLVMBuilderRef builder,
@@ -60,7 +60,9 @@ lp_build_pack_rgba_aos(LLVMBuilderRef builder,
 LLVMValueRef
 lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
                         const struct util_format_description *format_desc,
-                        LLVMValueRef ptr,
+                        struct lp_type type,
+                        LLVMValueRef base_ptr,
+                        LLVMValueRef offset,
                         LLVMValueRef i,
                         LLVMValueRef j);
 
@@ -72,7 +74,7 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
 void
 lp_build_format_swizzle_soa(const struct util_format_description *format_desc,
                             struct lp_build_context *bld,
-                            const LLVMValueRef *unswizzled,
+                            const LLVMValueRef unswizzled[4],
                             LLVMValueRef swizzled_out[4]);
 
 void
@@ -82,6 +84,11 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
                          LLVMValueRef packed,
                          LLVMValueRef rgba_out[4]);
 
+void
+lp_build_rgba8_to_f32_soa(LLVMBuilderRef builder,
+                          struct lp_type dst_type,
+                          LLVMValueRef packed,
+                          LLVMValueRef *rgba);
 
 void
 lp_build_fetch_rgba_soa(LLVMBuilderRef builder,
@@ -93,5 +100,18 @@ lp_build_fetch_rgba_soa(LLVMBuilderRef builder,
                         LLVMValueRef j,
                         LLVMValueRef rgba_out[4]);
 
+/*
+ * YUV
+ */
+
+
+LLVMValueRef
+lp_build_fetch_subsampled_rgba_aos(LLVMBuilderRef builder,
+                                   const struct util_format_description *format_desc,
+                                   unsigned n,
+                                   LLVMValueRef base_ptr,
+                                   LLVMValueRef offset,
+                                   LLVMValueRef i,
+                                   LLVMValueRef j);
 
 #endif /* !LP_BLD_FORMAT_H */
index 87e3e72a6e865fe3240ab3de5ae09998dbea7bb8..0f01fc1d75fa50a0a51abbbcd3c99b71299b0e16 100644 (file)
 #include "util/u_math.h"
 #include "util/u_string.h"
 
+#include "lp_bld_arit.h"
 #include "lp_bld_init.h"
 #include "lp_bld_type.h"
 #include "lp_bld_flow.h"
+#include "lp_bld_const.h"
+#include "lp_bld_conv.h"
+#include "lp_bld_swizzle.h"
+#include "lp_bld_gather.h"
 #include "lp_bld_format.h"
 
 
+/**
+ * Basic swizzling.  Rearrange the order of the unswizzled array elements
+ * according to the format description.  PIPE_SWIZZLE_ZERO/ONE are supported
+ * too.
+ * Ex: if unswizzled[4] = {B, G, R, x}, then swizzled_out[4] = {R, G, B, 1}.
+ */
+LLVMValueRef
+lp_build_format_swizzle_aos(const struct util_format_description *desc,
+                            struct lp_build_context *bld,
+                            LLVMValueRef unswizzled)
+{
+   unsigned char swizzles[4];
+   unsigned chan;
+
+   assert(bld->type.length % 4 == 0);
+
+   for (chan = 0; chan < 4; ++chan) {
+      enum util_format_swizzle swizzle;
+
+      if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
+         /*
+          * For ZS formats do RGBA = ZZZ1
+          */
+         if (chan == 3) {
+            swizzle = UTIL_FORMAT_SWIZZLE_1;
+         } else if (desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_NONE) {
+            swizzle = UTIL_FORMAT_SWIZZLE_0;
+         } else {
+            swizzle = desc->swizzle[0];
+         }
+      } else {
+         swizzle = desc->swizzle[chan];
+      }
+      swizzles[chan] = swizzle;
+   }
+
+   return lp_build_swizzle_aos(bld, unswizzled, swizzles);
+}
+
+
+/**
+ * Whether the format matches the vector type, apart of swizzles.
+ */
+static INLINE boolean
+format_matches_type(const struct util_format_description *desc,
+                    struct lp_type type)
+{
+   enum util_format_type chan_type;
+   unsigned chan;
+
+   assert(type.length % 4 == 0);
+
+   if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN ||
+       desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB ||
+       desc->block.width != 1 ||
+       desc->block.height != 1) {
+      return FALSE;
+   }
+
+   if (type.floating) {
+      chan_type = UTIL_FORMAT_TYPE_FLOAT;
+   } else if (type.fixed) {
+      chan_type = UTIL_FORMAT_TYPE_FIXED;
+   } else if (type.sign) {
+      chan_type = UTIL_FORMAT_TYPE_SIGNED;
+   } else {
+      chan_type = UTIL_FORMAT_TYPE_UNSIGNED;
+   }
+
+   for (chan = 0; chan < desc->nr_channels; ++chan) {
+      if (desc->channel[chan].size != type.width) {
+         return FALSE;
+      }
+
+      if (desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID) {
+         if (desc->channel[chan].type != chan_type ||
+             desc->channel[chan].normalized != type.norm) {
+            return FALSE;
+         }
+      }
+   }
+
+   return TRUE;
+}
+
+
 /**
  * Unpack a single pixel into its RGBA components.
  *
  * @param desc  the pixel format for the packed pixel value
  * @param packed integer pixel in a format such as PIPE_FORMAT_B8G8R8A8_UNORM
  *
- * @return RGBA in a 4 floats vector.
+ * @return RGBA in a float[4] or ubyte[4] or ushort[4] vector.
  */
-LLVMValueRef
-lp_build_unpack_rgba_aos(LLVMBuilderRef builder,
-                         const struct util_format_description *desc,
-                         LLVMValueRef packed)
+static INLINE LLVMValueRef
+lp_build_unpack_arith_rgba_aos(LLVMBuilderRef builder,
+                               const struct util_format_description *desc,
+                               LLVMValueRef packed)
 {
    LLVMValueRef shifted, casted, scaled, masked;
    LLVMValueRef shifts[4];
    LLVMValueRef masks[4];
    LLVMValueRef scales[4];
-   LLVMValueRef swizzles[4];
-   LLVMValueRef aux[4];
+
    boolean normalized;
-   int empty_channel;
    boolean needs_uitofp;
    unsigned shift;
    unsigned i;
@@ -77,8 +166,7 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder,
 
    /* Do the intermediate integer computations with 32bit integers since it
     * matches floating point size */
-   if (desc->block.bits < 32)
-      packed = LLVMBuildZExt(builder, packed, LLVMInt32Type(), "");
+   assert (LLVMTypeOf(packed) == LLVMInt32Type());
 
    /* Broadcast the packed value to all four channels
     * before: packed = BGRA
@@ -98,7 +186,6 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder,
    /* Initialize vector constants */
    normalized = FALSE;
    needs_uitofp = FALSE;
-   empty_channel = -1;
    shift = 0;
 
    /* Loop over 4 color components */
@@ -109,7 +196,6 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder,
          shifts[i] = LLVMGetUndef(LLVMInt32Type());
          masks[i] = LLVMConstNull(LLVMInt32Type());
          scales[i] =  LLVMConstNull(LLVMFloatType());
-         empty_channel = i;
       }
       else {
          unsigned long long mask = (1ULL << bits) - 1;
@@ -158,52 +244,7 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder,
    else
       scaled = casted;
 
-   for (i = 0; i < 4; ++i)
-      aux[i] = LLVMGetUndef(LLVMFloatType());
-
-   /* Build swizzles vector to put components into R,G,B,A order */
-   for (i = 0; i < 4; ++i) {
-      enum util_format_swizzle swizzle;
-
-      if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
-         /*
-          * For ZS formats do RGBA = ZZZ1
-          */
-         if (i == 3) {
-            swizzle = UTIL_FORMAT_SWIZZLE_1;
-         } else if (desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_NONE) {
-            swizzle = UTIL_FORMAT_SWIZZLE_0;
-         } else {
-            swizzle = desc->swizzle[0];
-         }
-      } else {
-         swizzle = desc->swizzle[i];
-      }
-
-      switch (swizzle) {
-      case UTIL_FORMAT_SWIZZLE_X:
-      case UTIL_FORMAT_SWIZZLE_Y:
-      case UTIL_FORMAT_SWIZZLE_Z:
-      case UTIL_FORMAT_SWIZZLE_W:
-         swizzles[i] = LLVMConstInt(LLVMInt32Type(), swizzle, 0);
-         break;
-      case UTIL_FORMAT_SWIZZLE_0:
-         assert(empty_channel >= 0);
-         swizzles[i] = LLVMConstInt(LLVMInt32Type(), empty_channel, 0);
-         break;
-      case UTIL_FORMAT_SWIZZLE_1:
-         swizzles[i] = LLVMConstInt(LLVMInt32Type(), 4, 0);
-         aux[0] = LLVMConstReal(LLVMFloatType(), 1.0);
-         break;
-      case UTIL_FORMAT_SWIZZLE_NONE:
-         swizzles[i] = LLVMGetUndef(LLVMFloatType());
-         assert(0);
-         break;
-      }
-   }
-
-   return LLVMBuildShuffleVector(builder, scaled, LLVMConstVector(aux, 4),
-                                 LLVMConstVector(swizzles, 4), "");
+   return scaled;
 }
 
 
@@ -310,22 +351,65 @@ lp_build_pack_rgba_aos(LLVMBuilderRef builder,
 }
 
 
+
+
 /**
  * Fetch a pixel into a 4 float AoS.
  *
  * \param format_desc  describes format of the image we're fetching from
  * \param ptr  address of the pixel block (or the texel if uncompressed)
  * \param i, j  the sub-block pixel coordinates.  For non-compressed formats
- *              these will always be (0,).
- * \return  valueRef with the float[4] RGBA pixel
+ *              these will always be (0, 0).
+ * \return  a 4 element vector with the pixel's RGBA values.
  */
 LLVMValueRef
 lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
                         const struct util_format_description *format_desc,
-                        LLVMValueRef ptr,
+                        struct lp_type type,
+                        LLVMValueRef base_ptr,
+                        LLVMValueRef offset,
                         LLVMValueRef i,
                         LLVMValueRef j)
 {
+   unsigned num_pixels = type.length / 4;
+   struct lp_build_context bld;
+
+   assert(type.length <= LP_MAX_VECTOR_LENGTH);
+   assert(type.length % 4 == 0);
+
+   lp_build_context_init(&bld, builder, type);
+
+   /*
+    * Trivial case
+    *
+    * The format matches the type (apart of a swizzle) so no need for
+    * scaling or converting.
+    */
+
+   if (format_matches_type(format_desc, type) &&
+       format_desc->block.bits <= type.width * 4 &&
+       util_is_pot(format_desc->block.bits)) {
+      LLVMValueRef packed;
+
+      /*
+       * The format matches the type (apart of a swizzle) so no need for
+       * scaling or converting.
+       */
+
+      packed = lp_build_gather(builder, type.length/4,
+                               format_desc->block.bits, type.width*4,
+                               base_ptr, offset);
+
+      assert(format_desc->block.bits <= type.width * type.length);
+
+      packed = LLVMBuildBitCast(builder, packed, lp_build_vec_type(type), "");
+
+      return lp_build_format_swizzle_aos(format_desc, &bld, packed);
+   }
+
+   /*
+    * Bit arithmetic
+    */
 
    if (format_desc->layout == UTIL_FORMAT_LAYOUT_PLAIN &&
        (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
@@ -337,21 +421,77 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
        format_desc->is_bitmask &&
        !format_desc->is_mixed &&
        (format_desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED ||
-        format_desc->channel[1].type == UTIL_FORMAT_TYPE_UNSIGNED))
-   {
-      LLVMValueRef packed;
+        format_desc->channel[1].type == UTIL_FORMAT_TYPE_UNSIGNED)) {
+
+      LLVMValueRef tmps[LP_MAX_VECTOR_LENGTH/4];
+      LLVMValueRef res;
+      unsigned k;
+
+      /*
+       * Unpack a pixel at a time into a <4 x float> RGBA vector
+       */
+
+      for (k = 0; k < num_pixels; ++k) {
+         LLVMValueRef packed;
+
+         packed = lp_build_gather_elem(builder, num_pixels,
+                                       format_desc->block.bits, 32,
+                                       base_ptr, offset, k);
 
-      ptr = LLVMBuildBitCast(builder, ptr,
-                             LLVMPointerType(LLVMIntType(format_desc->block.bits), 0) ,
-                             "");
+         tmps[k] = lp_build_unpack_arith_rgba_aos(builder, format_desc,
+                                                  packed);
+      }
+
+      /*
+       * Type conversion.
+       *
+       * TODO: We could avoid floating conversion for integer to
+       * integer conversions.
+       */
 
-      packed = LLVMBuildLoad(builder, ptr, "packed");
+      lp_build_conv(builder,
+                    lp_float32_vec4_type(),
+                    type,
+                    tmps, num_pixels, &res, 1);
 
-      return lp_build_unpack_rgba_aos(builder, format_desc, packed);
+      return lp_build_format_swizzle_aos(format_desc, &bld, res);
    }
-   else if (format_desc->fetch_rgba_float) {
+
+   /*
+    * YUV / subsampled formats
+    */
+
+   if (format_desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
+      struct lp_type tmp_type;
+      LLVMValueRef tmp;
+
+      memset(&tmp_type, 0, sizeof tmp_type);
+      tmp_type.width = 8;
+      tmp_type.length = num_pixels * 4;
+      tmp_type.norm = TRUE;
+
+      tmp = lp_build_fetch_subsampled_rgba_aos(builder,
+                                               format_desc,
+                                               num_pixels,
+                                               base_ptr,
+                                               offset,
+                                               i, j);
+
+      lp_build_conv(builder,
+                    tmp_type, type,
+                    &tmp, 1, &tmp, 1);
+
+      return tmp;
+   }
+
+   /*
+    * Fallback to util_format_description::fetch_rgba_8unorm().
+    */
+
+   if (format_desc->fetch_rgba_8unorm &&
+       !type.floating && type.width == 8 && !type.sign && type.norm) {
       /*
-       * Fallback to calling util_format_description::fetch_rgba_float.
+       * Fallback to calling util_format_description::fetch_rgba_8unorm.
        *
        * This is definitely not the most efficient way of fetching pixels, as
        * we miss the opportunity to do vectorization, but this it is a
@@ -361,9 +501,113 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
 
       LLVMModuleRef module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder)));
       char name[256];
+      LLVMTypeRef i8t = LLVMInt8Type();
+      LLVMTypeRef pi8t = LLVMPointerType(i8t, 0);
+      LLVMTypeRef i32t = LLVMInt32Type();
       LLVMValueRef function;
+      LLVMValueRef tmp_ptr;
       LLVMValueRef tmp;
-      LLVMValueRef args[4];
+      LLVMValueRef res;
+      unsigned k;
+
+      util_snprintf(name, sizeof name, "util_format_%s_fetch_rgba_8unorm",
+                    format_desc->short_name);
+
+      /*
+       * Declare and bind format_desc->fetch_rgba_8unorm().
+       */
+
+      function = LLVMGetNamedFunction(module, name);
+      if (!function) {
+         LLVMTypeRef ret_type;
+         LLVMTypeRef arg_types[4];
+         LLVMTypeRef function_type;
+
+         ret_type = LLVMVoidType();
+         arg_types[0] = pi8t;
+         arg_types[1] = pi8t;
+         arg_types[3] = arg_types[2] = LLVMIntType(sizeof(unsigned) * 8);
+         function_type = LLVMFunctionType(ret_type, arg_types, Elements(arg_types), 0);
+         function = LLVMAddFunction(module, name, function_type);
+
+         LLVMSetFunctionCallConv(function, LLVMCCallConv);
+         LLVMSetLinkage(function, LLVMExternalLinkage);
+
+         assert(LLVMIsDeclaration(function));
+
+         LLVMAddGlobalMapping(lp_build_engine, function,
+                              func_to_pointer((func_pointer)format_desc->fetch_rgba_8unorm));
+      }
+
+      tmp_ptr = lp_build_alloca(builder, i32t, "");
+
+      res = LLVMGetUndef(LLVMVectorType(i32t, num_pixels));
+
+      /*
+       * Invoke format_desc->fetch_rgba_8unorm() for each pixel and insert the result
+       * in the SoA vectors.
+       */
+
+      for (k = 0; k < num_pixels; ++k) {
+         LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), k, 0);
+         LLVMValueRef args[4];
+
+         args[0] = LLVMBuildBitCast(builder, tmp_ptr, pi8t, "");
+         args[1] = lp_build_gather_elem_ptr(builder, num_pixels,
+                                            base_ptr, offset, k);
+
+         if (num_pixels == 1) {
+            args[2] = i;
+            args[3] = j;
+         }
+         else {
+            args[2] = LLVMBuildExtractElement(builder, i, index, "");
+            args[3] = LLVMBuildExtractElement(builder, j, index, "");
+         }
+
+         LLVMBuildCall(builder, function, args, Elements(args), "");
+
+         tmp = LLVMBuildLoad(builder, tmp_ptr, "");
+
+         if (num_pixels == 1) {
+            res = tmp;
+         }
+         else {
+            res = LLVMBuildInsertElement(builder, res, tmp, index, "");
+         }
+      }
+
+      /* Bitcast from <n x i32> to <4n x i8> */
+      res = LLVMBuildBitCast(builder, res, bld.vec_type, "");
+
+      return res;
+   }
+
+
+   /*
+    * Fallback to util_format_description::fetch_rgba_float().
+    */
+
+   if (format_desc->fetch_rgba_float) {
+      /*
+       * Fallback to calling util_format_description::fetch_rgba_float.
+       *
+       * This is definitely not the most efficient way of fetching pixels, as
+       * we miss the opportunity to do vectorization, but this it is a
+       * convenient for formats or scenarios for which there was no opportunity
+       * or incentive to optimize.
+       */
+
+      LLVMModuleRef module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder)));
+      char name[256];
+      LLVMTypeRef f32t = LLVMFloatType();
+      LLVMTypeRef f32x4t = LLVMVectorType(f32t, 4);
+      LLVMTypeRef pf32t = LLVMPointerType(f32t, 0);
+      LLVMValueRef function;
+      LLVMValueRef tmp_ptr;
+      LLVMValueRef tmps[LP_MAX_VECTOR_LENGTH/4];
+      LLVMValueRef res;
+      unsigned k;
 
       util_snprintf(name, sizeof name, "util_format_%s_fetch_rgba_float",
                     format_desc->short_name);
@@ -379,7 +623,7 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
          LLVMTypeRef function_type;
 
          ret_type = LLVMVoidType();
-         arg_types[0] = LLVMPointerType(LLVMFloatType(), 0);
+         arg_types[0] = pf32t;
          arg_types[1] = LLVMPointerType(LLVMInt8Type(), 0);
          arg_types[3] = arg_types[2] = LLVMIntType(sizeof(unsigned) * 8);
          function_type = LLVMFunctionType(ret_type, arg_types, Elements(arg_types), 0);
@@ -394,25 +638,43 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
                               func_to_pointer((func_pointer)format_desc->fetch_rgba_float));
       }
 
-      tmp = lp_build_alloca(builder, LLVMVectorType(LLVMFloatType(), 4), "");
+      tmp_ptr = lp_build_alloca(builder, f32x4t, "");
 
       /*
        * Invoke format_desc->fetch_rgba_float() for each pixel and insert the result
        * in the SoA vectors.
        */
 
-      args[0] = LLVMBuildBitCast(builder, tmp,
-                                 LLVMPointerType(LLVMFloatType(), 0), "");
-      args[1] = ptr;
-      args[2] = i;
-      args[3] = j;
+      for (k = 0; k < num_pixels; ++k) {
+         LLVMValueRef args[4];
 
-      LLVMBuildCall(builder, function, args, Elements(args), "");
+         args[0] = LLVMBuildBitCast(builder, tmp_ptr, pf32t, "");
+         args[1] = lp_build_gather_elem_ptr(builder, num_pixels,
+                                            base_ptr, offset, k);
 
-      return LLVMBuildLoad(builder, tmp, "");
-   }
-   else {
-      assert(0);
-      return LLVMGetUndef(LLVMVectorType(LLVMFloatType(), 4));
+         if (num_pixels == 1) {
+            args[2] = i;
+            args[3] = j;
+         }
+         else {
+            LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), k, 0);
+            args[2] = LLVMBuildExtractElement(builder, i, index, "");
+            args[3] = LLVMBuildExtractElement(builder, j, index, "");
+         }
+
+         LLVMBuildCall(builder, function, args, Elements(args), "");
+
+         tmps[k] = LLVMBuildLoad(builder, tmp_ptr, "");
+      }
+
+      lp_build_conv(builder,
+                    lp_float32_vec4_type(),
+                    type,
+                    tmps, num_pixels, &res, 1);
+
+      return res;
    }
+
+   assert(0);
+   return lp_build_undef(type);
 }
index e1b94adc85a4a070cdd86e34ff0971610d294113..9f405921b0a51f355b48fad74114e14c295ce22b 100644 (file)
@@ -36,7 +36,7 @@
 #include "lp_bld_const.h"
 #include "lp_bld_conv.h"
 #include "lp_bld_swizzle.h"
-#include "lp_bld_sample.h" /* for lp_build_gather */
+#include "lp_bld_gather.h"
 #include "lp_bld_format.h"
 
 
@@ -251,6 +251,41 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
 }
 
 
+void
+lp_build_rgba8_to_f32_soa(LLVMBuilderRef builder,
+                          struct lp_type dst_type,
+                          LLVMValueRef packed,
+                          LLVMValueRef *rgba)
+{
+   LLVMValueRef mask = lp_build_const_int_vec(dst_type, 0xff);
+   unsigned chan;
+
+   packed = LLVMBuildBitCast(builder, packed,
+                             lp_build_int_vec_type(dst_type), "");
+
+   /* Decode the input vector components */
+   for (chan = 0; chan < 4; ++chan) {
+      unsigned start = chan*8;
+      unsigned stop = start + 8;
+      LLVMValueRef input;
+
+      input = packed;
+
+      if (start)
+         input = LLVMBuildLShr(builder, input,
+                               lp_build_const_int_vec(dst_type, start), "");
+
+      if (stop < 32)
+         input = LLVMBuildAnd(builder, input, mask, "");
+
+      input = lp_build_unsigned_norm_to_float(builder, 8, dst_type, input);
+
+      rgba[chan] = input;
+   }
+}
+
+
+
 /**
  * Fetch a texels from a texture, returning them in SoA layout.
  *
@@ -311,20 +346,49 @@ lp_build_fetch_rgba_soa(LLVMBuilderRef builder,
                                format_desc,
                                type,
                                packed, rgba_out);
+      return;
    }
-   else {
-      /*
-       * Fallback to calling lp_build_fetch_rgba_aos for each pixel.
-       *
-       * This is not the most efficient way of fetching pixels, as we
-       * miss some opportunities to do vectorization, but this is
-       * convenient for formats or scenarios for which there was no
-       * opportunity or incentive to optimize.
-       */
 
+   /*
+    * Try calling lp_build_fetch_rgba_aos for all pixels.
+    */
+
+   if (util_format_fits_8unorm(format_desc) &&
+       type.floating && type.width == 32 && type.length == 4) {
+      struct lp_type tmp_type;
+      LLVMValueRef tmp;
+
+      memset(&tmp_type, 0, sizeof tmp_type);
+      tmp_type.width = 8;
+      tmp_type.length = type.length * 4;
+      tmp_type.norm = TRUE;
+
+      tmp = lp_build_fetch_rgba_aos(builder, format_desc, tmp_type,
+                                    base_ptr, offset, i, j);
+
+      lp_build_rgba8_to_f32_soa(builder,
+                                type,
+                                tmp,
+                                rgba_out);
+
+      return;
+   }
+
+   /*
+    * Fallback to calling lp_build_fetch_rgba_aos for each pixel.
+    *
+    * This is not the most efficient way of fetching pixels, as we
+    * miss some opportunities to do vectorization, but this is
+    * convenient for formats or scenarios for which there was no
+    * opportunity or incentive to optimize.
+    */
+
+   {
       unsigned k, chan;
+      struct lp_type tmp_type;
 
-      assert(type.floating);
+      tmp_type = type;
+      tmp_type.length = 4;
 
       for (chan = 0; chan < 4; ++chan) {
          rgba_out[chan] = lp_build_undef(type);
@@ -334,18 +398,17 @@ lp_build_fetch_rgba_soa(LLVMBuilderRef builder,
       for(k = 0; k < type.length; ++k) {
          LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), k, 0);
          LLVMValueRef offset_elem;
-         LLVMValueRef ptr;
          LLVMValueRef i_elem, j_elem;
          LLVMValueRef tmp;
 
          offset_elem = LLVMBuildExtractElement(builder, offset, index, "");
-         ptr = LLVMBuildGEP(builder, base_ptr, &offset_elem, 1, "");
 
          i_elem = LLVMBuildExtractElement(builder, i, index, "");
          j_elem = LLVMBuildExtractElement(builder, j, index, "");
 
          /* Get a single float[4]={R,G,B,A} pixel */
-         tmp = lp_build_fetch_rgba_aos(builder, format_desc, ptr,
+         tmp = lp_build_fetch_rgba_aos(builder, format_desc, tmp_type,
+                                       base_ptr, offset_elem,
                                        i_elem, j_elem);
 
          /*
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c b/src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c
new file mode 100644 (file)
index 0000000..0a5038b
--- /dev/null
@@ -0,0 +1,399 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+
+/**
+ * @file
+ * YUV pixel format manipulation.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#include "util/u_format.h"
+
+#include "lp_bld_arit.h"
+#include "lp_bld_type.h"
+#include "lp_bld_const.h"
+#include "lp_bld_conv.h"
+#include "lp_bld_gather.h"
+#include "lp_bld_format.h"
+
+
+/**
+ * Extract Y, U, V channels from packed UYVY.
+ * @param packed  is a <n x i32> vector with the packed UYVY blocks
+ * @param i  is a <n x i32> vector with the x pixel coordinate (0 or 1)
+ */
+static void
+uyvy_to_yuv_soa(LLVMBuilderRef builder,
+                unsigned n,
+                LLVMValueRef packed,
+                LLVMValueRef i,
+                LLVMValueRef *y,
+                LLVMValueRef *u,
+                LLVMValueRef *v)
+{
+   struct lp_type type;
+   LLVMValueRef shift, mask;
+
+   memset(&type, 0, sizeof type);
+   type.width = 32;
+   type.length = n;
+
+   assert(lp_check_value(type, packed));
+   assert(lp_check_value(type, i));
+
+   /*
+    * y = (uyvy >> 16*i) & 0xff
+    * u = (uyvy        ) & 0xff
+    * v = (uyvy >> 16  ) & 0xff
+    */
+
+   shift = LLVMBuildMul(builder, i, lp_build_const_int_vec(type, 16), "");
+   shift = LLVMBuildAdd(builder, shift, lp_build_const_int_vec(type, 8), "");
+   *y = LLVMBuildLShr(builder, packed, shift, "");
+   *u = packed;
+   *v = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(type, 16), "");
+
+   mask = lp_build_const_int_vec(type, 0xff);
+
+   *y = LLVMBuildAnd(builder, *y, mask, "y");
+   *u = LLVMBuildAnd(builder, *u, mask, "u");
+   *v = LLVMBuildAnd(builder, *v, mask, "v");
+}
+
+
+/**
+ * Extract Y, U, V channels from packed YUYV.
+ * @param packed  is a <n x i32> vector with the packed YUYV blocks
+ * @param i  is a <n x i32> vector with the x pixel coordinate (0 or 1)
+ */
+static void
+yuyv_to_yuv_soa(LLVMBuilderRef builder,
+                unsigned n,
+                LLVMValueRef packed,
+                LLVMValueRef i,
+                LLVMValueRef *y,
+                LLVMValueRef *u,
+                LLVMValueRef *v)
+{
+   struct lp_type type;
+   LLVMValueRef shift, mask;
+
+   memset(&type, 0, sizeof type);
+   type.width = 32;
+   type.length = n;
+
+   assert(lp_check_value(type, packed));
+   assert(lp_check_value(type, i));
+
+   /*
+    * y = (yuyv >> 16*i) & 0xff
+    * u = (yuyv >> 8   ) & 0xff
+    * v = (yuyv >> 24  ) & 0xff
+    */
+
+   shift = LLVMBuildMul(builder, i, lp_build_const_int_vec(type, 16), "");
+   *y = LLVMBuildLShr(builder, packed, shift, "");
+   *u = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(type, 8), "");
+   *v = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(type, 24), "");
+
+   mask = lp_build_const_int_vec(type, 0xff);
+
+   *y = LLVMBuildAnd(builder, *y, mask, "y");
+   *u = LLVMBuildAnd(builder, *u, mask, "u");
+   *v = LLVMBuildAnd(builder, *v, mask, "v");
+}
+
+
+static INLINE void
+yuv_to_rgb_soa(LLVMBuilderRef builder,
+               unsigned n,
+               LLVMValueRef y, LLVMValueRef u, LLVMValueRef v,
+               LLVMValueRef *r, LLVMValueRef *g, LLVMValueRef *b)
+{
+   struct lp_type type;
+   struct lp_build_context bld;
+
+   LLVMValueRef c0;
+   LLVMValueRef c8;
+   LLVMValueRef c16;
+   LLVMValueRef c128;
+   LLVMValueRef c255;
+
+   LLVMValueRef cy;
+   LLVMValueRef cug;
+   LLVMValueRef cub;
+   LLVMValueRef cvr;
+   LLVMValueRef cvg;
+
+   memset(&type, 0, sizeof type);
+   type.sign = TRUE;
+   type.width = 32;
+   type.length = n;
+
+   lp_build_context_init(&bld, builder, type);
+
+   assert(lp_check_value(type, y));
+   assert(lp_check_value(type, u));
+   assert(lp_check_value(type, v));
+
+   /*
+    * Constants
+    */
+
+   c0   = lp_build_const_int_vec(type,   0);
+   c8   = lp_build_const_int_vec(type,   8);
+   c16  = lp_build_const_int_vec(type,  16);
+   c128 = lp_build_const_int_vec(type, 128);
+   c255 = lp_build_const_int_vec(type, 255);
+
+   cy  = lp_build_const_int_vec(type,  298);
+   cug = lp_build_const_int_vec(type, -100);
+   cub = lp_build_const_int_vec(type,  516);
+   cvr = lp_build_const_int_vec(type,  409);
+   cvg = lp_build_const_int_vec(type, -208);
+
+   /*
+    *  y -= 16;
+    *  u -= 128;
+    *  v -= 128;
+    */
+
+   y = LLVMBuildSub(builder, y, c16, "");
+   u = LLVMBuildSub(builder, u, c128, "");
+   v = LLVMBuildSub(builder, v, c128, "");
+
+   /*
+    * r = 298 * _y            + 409 * _v + 128;
+    * g = 298 * _y - 100 * _u - 208 * _v + 128;
+    * b = 298 * _y + 516 * _u            + 128;
+    */
+
+   y = LLVMBuildMul(builder, y, cy, "");
+   y = LLVMBuildAdd(builder, y, c128, "");
+
+   *r = LLVMBuildMul(builder, v, cvr, "");
+   *g = LLVMBuildAdd(builder,
+                     LLVMBuildMul(builder, u, cug, ""),
+                     LLVMBuildMul(builder, v, cvg, ""),
+                     "");
+   *b = LLVMBuildMul(builder, u, cub, "");
+
+   *r = LLVMBuildAdd(builder, *r, y, "");
+   *g = LLVMBuildAdd(builder, *g, y, "");
+   *b = LLVMBuildAdd(builder, *b, y, "");
+
+   /*
+    * r >>= 8;
+    * g >>= 8;
+    * b >>= 8;
+    */
+
+   *r = LLVMBuildAShr(builder, *r, c8, "r");
+   *g = LLVMBuildAShr(builder, *g, c8, "g");
+   *b = LLVMBuildAShr(builder, *b, c8, "b");
+
+   /*
+    * Clamp
+    */
+
+   *r = lp_build_clamp(&bld, *r, c0, c255);
+   *g = lp_build_clamp(&bld, *g, c0, c255);
+   *b = lp_build_clamp(&bld, *b, c0, c255);
+}
+
+
+static LLVMValueRef
+rgb_to_rgba_aos(LLVMBuilderRef builder,
+                unsigned n,
+                LLVMValueRef r, LLVMValueRef g, LLVMValueRef b)
+{
+   struct lp_type type;
+   LLVMValueRef a;
+   LLVMValueRef rgba;
+
+   memset(&type, 0, sizeof type);
+   type.sign = TRUE;
+   type.width = 32;
+   type.length = n;
+
+   assert(lp_check_value(type, r));
+   assert(lp_check_value(type, g));
+   assert(lp_check_value(type, b));
+
+   /*
+    * Make a 4 x unorm8 vector
+    */
+
+   r = r;
+   g = LLVMBuildShl(builder, g, lp_build_const_int_vec(type, 8), "");
+   b = LLVMBuildShl(builder, b, lp_build_const_int_vec(type, 16), "");
+   a = lp_build_const_int_vec(type, 0xff000000);
+
+   rgba = r;
+   rgba = LLVMBuildOr(builder, rgba, g, "");
+   rgba = LLVMBuildOr(builder, rgba, b, "");
+   rgba = LLVMBuildOr(builder, rgba, a, "");
+
+   rgba = LLVMBuildBitCast(builder, rgba,
+                           LLVMVectorType(LLVMInt8Type(), 4*n), "");
+
+   return rgba;
+}
+
+
+/**
+ * Convert from <n x i32> packed UYVY to <4n x i8> RGBA AoS
+ */
+static LLVMValueRef
+uyvy_to_rgba_aos(LLVMBuilderRef builder,
+                 unsigned n,
+                 LLVMValueRef packed,
+                 LLVMValueRef i)
+{
+   LLVMValueRef y, u, v;
+   LLVMValueRef r, g, b;
+   LLVMValueRef rgba;
+
+   uyvy_to_yuv_soa(builder, n, packed, i, &y, &u, &v);
+   yuv_to_rgb_soa(builder, n, y, u, v, &r, &g, &b);
+   rgba = rgb_to_rgba_aos(builder, n, r, g, b);
+
+   return rgba;
+}
+
+
+/**
+ * Convert from <n x i32> packed YUYV to <4n x i8> RGBA AoS
+ */
+static LLVMValueRef
+yuyv_to_rgba_aos(LLVMBuilderRef builder,
+                 unsigned n,
+                 LLVMValueRef packed,
+                 LLVMValueRef i)
+{
+   LLVMValueRef y, u, v;
+   LLVMValueRef r, g, b;
+   LLVMValueRef rgba;
+
+   yuyv_to_yuv_soa(builder, n, packed, i, &y, &u, &v);
+   yuv_to_rgb_soa(builder, n, y, u, v, &r, &g, &b);
+   rgba = rgb_to_rgba_aos(builder, n, r, g, b);
+
+   return rgba;
+}
+
+
+/**
+ * Convert from <n x i32> packed RG_BG to <4n x i8> RGBA AoS
+ */
+static LLVMValueRef
+rgbg_to_rgba_aos(LLVMBuilderRef builder,
+                 unsigned n,
+                 LLVMValueRef packed,
+                 LLVMValueRef i)
+{
+   LLVMValueRef r, g, b;
+   LLVMValueRef rgba;
+
+   uyvy_to_yuv_soa(builder, n, packed, i, &g, &r, &b);
+   rgba = rgb_to_rgba_aos(builder, n, r, g, b);
+
+   return rgba;
+}
+
+
+/**
+ * Convert from <n x i32> packed GR_GB to <4n x i8> RGBA AoS
+ */
+static LLVMValueRef
+grgb_to_rgba_aos(LLVMBuilderRef builder,
+                 unsigned n,
+                 LLVMValueRef packed,
+                 LLVMValueRef i)
+{
+   LLVMValueRef r, g, b;
+   LLVMValueRef rgba;
+
+   yuyv_to_yuv_soa(builder, n, packed, i, &g, &r, &b);
+   rgba = rgb_to_rgba_aos(builder, n, r, g, b);
+
+   return rgba;
+}
+
+
+/**
+ * @param n  is the number of pixels processed
+ * @param packed  is a <n x i32> vector with the packed YUYV blocks
+ * @param i  is a <n x i32> vector with the x pixel coordinate (0 or 1)
+ * @return  a <4*n x i8> vector with the pixel RGBA values in AoS
+ */
+LLVMValueRef
+lp_build_fetch_subsampled_rgba_aos(LLVMBuilderRef builder,
+                                   const struct util_format_description *format_desc,
+                                   unsigned n,
+                                   LLVMValueRef base_ptr,
+                                   LLVMValueRef offset,
+                                   LLVMValueRef i,
+                                   LLVMValueRef j)
+{
+   LLVMValueRef packed;
+   LLVMValueRef rgba;
+
+   assert(format_desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED);
+   assert(format_desc->block.bits == 32);
+   assert(format_desc->block.width == 2);
+   assert(format_desc->block.height == 1);
+
+   packed = lp_build_gather(builder, n, 32, 32, base_ptr, offset);
+
+   (void)j;
+
+   switch (format_desc->format) {
+   case PIPE_FORMAT_UYVY:
+      rgba = uyvy_to_rgba_aos(builder, n, packed, i);
+      break;
+   case PIPE_FORMAT_YUYV:
+      rgba = yuyv_to_rgba_aos(builder, n, packed, i);
+      break;
+   case PIPE_FORMAT_R8G8_B8G8_UNORM:
+      rgba = rgbg_to_rgba_aos(builder, n, packed, i);
+      break;
+   case PIPE_FORMAT_G8R8_G8B8_UNORM:
+      rgba = grgb_to_rgba_aos(builder, n, packed, i);
+      break;
+   default:
+      assert(0);
+      rgba =  LLVMGetUndef(LLVMVectorType(LLVMInt8Type(), 4*n));
+      break;
+   }
+
+   return rgba;
+}
+
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_gather.c b/src/gallium/auxiliary/gallivm/lp_bld_gather.c
new file mode 100644 (file)
index 0000000..d60472e
--- /dev/null
@@ -0,0 +1,148 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+
+#include "util/u_debug.h"
+#include "lp_bld_debug.h"
+#include "lp_bld_const.h"
+#include "lp_bld_format.h"
+#include "lp_bld_gather.h"
+
+
+/**
+ * Get the pointer to one element from scatter positions in memory.
+ *
+ * @sa lp_build_gather()
+ */
+LLVMValueRef
+lp_build_gather_elem_ptr(LLVMBuilderRef builder,
+                         unsigned length,
+                         LLVMValueRef base_ptr,
+                         LLVMValueRef offsets,
+                         unsigned i)
+{
+   LLVMValueRef offset;
+   LLVMValueRef ptr;
+
+   assert(LLVMTypeOf(base_ptr) == LLVMPointerType(LLVMInt8Type(), 0));
+
+   if (length == 1) {
+      assert(i == 0);
+      offset = offsets;
+   } else {
+      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+      offset = LLVMBuildExtractElement(builder, offsets, index, "");
+   }
+
+   ptr = LLVMBuildGEP(builder, base_ptr, &offset, 1, "");
+
+   return ptr;
+}
+
+
+/**
+ * Gather one element from scatter positions in memory.
+ *
+ * @sa lp_build_gather()
+ */
+LLVMValueRef
+lp_build_gather_elem(LLVMBuilderRef builder,
+                     unsigned length,
+                     unsigned src_width,
+                     unsigned dst_width,
+                     LLVMValueRef base_ptr,
+                     LLVMValueRef offsets,
+                     unsigned i)
+{
+   LLVMTypeRef src_type = LLVMIntType(src_width);
+   LLVMTypeRef src_ptr_type = LLVMPointerType(src_type, 0);
+   LLVMTypeRef dst_elem_type = LLVMIntType(dst_width);
+   LLVMValueRef ptr;
+   LLVMValueRef res;
+
+   assert(LLVMTypeOf(base_ptr) == LLVMPointerType(LLVMInt8Type(), 0));
+
+   ptr = lp_build_gather_elem_ptr(builder, length, base_ptr, offsets, i);
+   ptr = LLVMBuildBitCast(builder, ptr, src_ptr_type, "");
+   res = LLVMBuildLoad(builder, ptr, "");
+
+   assert(src_width <= dst_width);
+   if (src_width > dst_width)
+      res = LLVMBuildTrunc(builder, res, dst_elem_type, "");
+   if (src_width < dst_width)
+      res = LLVMBuildZExt(builder, res, dst_elem_type, "");
+
+   return res;
+}
+
+
+/**
+ * Gather elements from scatter positions in memory into a single vector.
+ * Use for fetching texels from a texture.
+ * For SSE, typical values are length=4, src_width=32, dst_width=32.
+ *
+ * @param length length of the offsets
+ * @param src_width src element width in bits
+ * @param dst_width result element width in bits (src will be expanded to fit)
+ * @param base_ptr base pointer, should be a i8 pointer type.
+ * @param offsets vector with offsets
+ */
+LLVMValueRef
+lp_build_gather(LLVMBuilderRef builder,
+                unsigned length,
+                unsigned src_width,
+                unsigned dst_width,
+                LLVMValueRef base_ptr,
+                LLVMValueRef offsets)
+{
+   LLVMValueRef res;
+
+   if (length == 1) {
+      /* Scalar */
+      return lp_build_gather_elem(builder, length,
+                                  src_width, dst_width,
+                                  base_ptr, offsets, 0);
+   } else {
+      /* Vector */
+
+      LLVMTypeRef dst_elem_type = LLVMIntType(dst_width);
+      LLVMTypeRef dst_vec_type = LLVMVectorType(dst_elem_type, length);
+      unsigned i;
+
+      res = LLVMGetUndef(dst_vec_type);
+      for (i = 0; i < length; ++i) {
+         LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+         LLVMValueRef elem;
+         elem = lp_build_gather_elem(builder, length,
+                                     src_width, dst_width,
+                                     base_ptr, offsets, i);
+         res = LLVMBuildInsertElement(builder, res, elem, index, "");
+      }
+   }
+
+   return res;
+}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_gather.h b/src/gallium/auxiliary/gallivm/lp_bld_gather.h
new file mode 100644 (file)
index 0000000..131af8e
--- /dev/null
@@ -0,0 +1,61 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+
+#ifndef LP_BLD_GATHER_H_
+#define LP_BLD_GATHER_H_
+
+
+#include "gallivm/lp_bld.h"
+
+
+LLVMValueRef
+lp_build_gather_elem_ptr(LLVMBuilderRef builder,
+                         unsigned length,
+                         LLVMValueRef base_ptr,
+                         LLVMValueRef offsets,
+                         unsigned i);
+
+LLVMValueRef
+lp_build_gather_elem(LLVMBuilderRef builder,
+                     unsigned length,
+                     unsigned src_width,
+                     unsigned dst_width,
+                     LLVMValueRef base_ptr,
+                     LLVMValueRef offsets,
+                     unsigned i);
+
+LLVMValueRef
+lp_build_gather(LLVMBuilderRef builder,
+                unsigned length,
+                unsigned src_width,
+                unsigned dst_width,
+                LLVMValueRef base_ptr,
+                LLVMValueRef offsets);
+
+
+#endif /* LP_BLD_GATHER_H_ */
index 44cfdc4d3fbea794a8770485e7a5497507921c3c..69353dea09e40c2a431a0486c68d76949253ee9a 100644 (file)
@@ -32,6 +32,8 @@
 #include "lp_bld_debug.h"
 #include "lp_bld_init.h"
 
+#include <llvm-c/Transforms/Scalar.h>
+
 
 #ifdef DEBUG
 unsigned gallivm_debug = 0;
@@ -50,6 +52,7 @@ LLVMModuleRef lp_build_module = NULL;
 LLVMExecutionEngineRef lp_build_engine = NULL;
 LLVMModuleProviderRef lp_build_provider = NULL;
 LLVMTargetDataRef lp_build_target = NULL;
+LLVMPassManagerRef lp_build_pass = NULL;
 
 
 /*
@@ -127,6 +130,33 @@ lp_build_init(void)
    if (!lp_build_target)
       lp_build_target = LLVMGetExecutionEngineTargetData(lp_build_engine);
 
+   if (!lp_build_pass) {
+      lp_build_pass = LLVMCreateFunctionPassManager(lp_build_provider);
+      LLVMAddTargetData(lp_build_target, lp_build_pass);
+
+      if ((gallivm_debug & GALLIVM_DEBUG_NO_OPT) == 0) {
+         /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
+          * but there are more on SVN. */
+         /* TODO: Add more passes */
+         LLVMAddCFGSimplificationPass(lp_build_pass);
+         LLVMAddPromoteMemoryToRegisterPass(lp_build_pass);
+         LLVMAddConstantPropagationPass(lp_build_pass);
+         if(util_cpu_caps.has_sse4_1) {
+            /* FIXME: There is a bug in this pass, whereby the combination of fptosi
+             * and sitofp (necessary for trunc/floor/ceil/round implementation)
+             * somehow becomes invalid code.
+             */
+            LLVMAddInstructionCombiningPass(lp_build_pass);
+         }
+         LLVMAddGVNPass(lp_build_pass);
+      } else {
+         /* We need at least this pass to prevent the backends to fail in
+          * unexpected ways.
+          */
+         LLVMAddPromoteMemoryToRegisterPass(lp_build_pass);
+      }
+   }
+
    util_cpu_detect();
 
 #if 0
index 0ec2afcd1be153c35ee04aff64ab7b307071367e..a32ced9b4c3a526c73806300e8a37f65f2dda97f 100644 (file)
@@ -38,6 +38,7 @@ extern LLVMModuleRef lp_build_module;
 extern LLVMExecutionEngineRef lp_build_engine;
 extern LLVMModuleProviderRef lp_build_provider;
 extern LLVMTargetDataRef lp_build_target;
+extern LLVMPassManagerRef lp_build_pass;
 
 
 void
index d13fa1a5d043b4f5cf9c9f8e23a477647fe534bd..39854e43b194057e81ee0914d91a2c1245b7ac47 100644 (file)
@@ -34,6 +34,7 @@
 
 
 #include "util/u_cpu_detect.h"
+#include "util/u_memory.h"
 #include "util/u_debug.h"
 
 #include "lp_bld_type.h"
@@ -187,12 +188,10 @@ lp_build_compare(LLVMBuilderRef builder,
             return lp_build_undef(type);
          }
 
-         /* There are no signed byte and unsigned word/dword comparison
-          * instructions. So flip the sign bit so that the results match.
+         /* There are no unsigned comparison instructions. So flip the sign bit
+          * so that the results match.
           */
-         if(table[func].gt &&
-            ((type.width == 8 && type.sign) ||
-             (type.width != 8 && !type.sign))) {
+         if (table[func].gt && !type.sign) {
             LLVMValueRef msb = lp_build_const_int_vec(type, (unsigned long long)1 << (type.width - 1));
             a = LLVMBuildXor(builder, a, msb, "");
             b = LLVMBuildXor(builder, b, msb, "");
@@ -384,6 +383,46 @@ lp_build_select(struct lp_build_context *bld,
       mask = LLVMBuildTrunc(bld->builder, mask, LLVMInt1Type(), "");
       res = LLVMBuildSelect(bld->builder, mask, a, b, "");
    }
+   else if (util_cpu_caps.has_sse4_1 &&
+            type.width * type.length == 128 &&
+            !LLVMIsConstant(a) &&
+            !LLVMIsConstant(b) &&
+            !LLVMIsConstant(mask)) {
+      const char *intrinsic;
+      LLVMTypeRef arg_type;
+      LLVMValueRef args[3];
+
+      if (type.width == 64) {
+         intrinsic = "llvm.x86.sse41.blendvpd";
+         arg_type = LLVMVectorType(LLVMDoubleType(), 2);
+      } else if (type.width == 32) {
+         intrinsic = "llvm.x86.sse41.blendvps";
+         arg_type = LLVMVectorType(LLVMFloatType(), 4);
+      } else {
+         intrinsic = "llvm.x86.sse41.pblendvb";
+         arg_type = LLVMVectorType(LLVMInt8Type(), 16);
+      }
+
+      if (arg_type != bld->int_vec_type) {
+         mask = LLVMBuildBitCast(bld->builder, mask, arg_type, "");
+      }
+
+      if (arg_type != bld->vec_type) {
+         a = LLVMBuildBitCast(bld->builder, a, arg_type, "");
+         b = LLVMBuildBitCast(bld->builder, b, arg_type, "");
+      }
+
+      args[0] = b;
+      args[1] = a;
+      args[2] = mask;
+
+      res = lp_build_intrinsic(bld->builder, intrinsic,
+                               arg_type, args, Elements(args));
+
+      if (arg_type != bld->vec_type) {
+         res = LLVMBuildBitCast(bld->builder, res, bld->vec_type, "");
+      }
+   }
    else {
       if(type.floating) {
          LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
index 186f8849b8dacb3a437764196349e58a0fca2ef7..7748f8f09994132db7e4165c2676671fd4f129f6 100644 (file)
@@ -427,3 +427,123 @@ lp_build_pack(LLVMBuilderRef builder,
 
    return tmp[0];
 }
+
+
+/**
+ * Truncate or expand the bitwidth.
+ *
+ * NOTE: Getting the right sign flags is crucial here, as we employ some
+ * intrinsics that do saturation.
+ */
+void
+lp_build_resize(LLVMBuilderRef builder,
+                struct lp_type src_type,
+                struct lp_type dst_type,
+                const LLVMValueRef *src, unsigned num_srcs,
+                LLVMValueRef *dst, unsigned num_dsts)
+{
+   LLVMValueRef tmp[LP_MAX_VECTOR_LENGTH];
+   unsigned i;
+
+   /*
+    * We don't support float <-> int conversion here. That must be done
+    * before/after calling this function.
+    */
+   assert(src_type.floating == dst_type.floating);
+
+   /*
+    * We don't support double <-> float conversion yet, although it could be
+    * added with little effort.
+    */
+   assert((!src_type.floating && !dst_type.floating) ||
+          src_type.width == dst_type.width);
+
+   /* We must not loose or gain channels. Only precision */
+   assert(src_type.length * num_srcs == dst_type.length * num_dsts);
+
+   /* We don't support M:N conversion, only 1:N, M:1, or 1:1 */
+   assert(num_srcs == 1 || num_dsts == 1);
+
+   assert(src_type.length <= LP_MAX_VECTOR_LENGTH);
+   assert(dst_type.length <= LP_MAX_VECTOR_LENGTH);
+   assert(num_srcs <= LP_MAX_VECTOR_LENGTH);
+   assert(num_dsts <= LP_MAX_VECTOR_LENGTH);
+
+   if (src_type.width > dst_type.width) {
+      /*
+       * Truncate bit width.
+       */
+
+      assert(num_dsts == 1);
+
+      if (src_type.width * src_type.length == dst_type.width * dst_type.length) {
+        /*
+         * Register width remains constant -- use vector packing intrinsics
+         */
+
+         tmp[0] = lp_build_pack(builder, src_type, dst_type, TRUE, src, num_srcs);
+      }
+      else {
+         /*
+          * Do it element-wise.
+          */
+
+         assert(src_type.length == dst_type.length);
+         tmp[0] = lp_build_undef(dst_type);
+         for (i = 0; i < dst_type.length; ++i) {
+            LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+            LLVMValueRef val = LLVMBuildExtractElement(builder, src[0], index, "");
+            val = LLVMBuildTrunc(builder, val, lp_build_elem_type(dst_type), "");
+            tmp[0] = LLVMBuildInsertElement(builder, tmp[0], val, index, "");
+         }
+      }
+   }
+   else if (src_type.width < dst_type.width) {
+      /*
+       * Expand bit width.
+       */
+
+      assert(num_srcs == 1);
+
+      if (src_type.width * src_type.length == dst_type.width * dst_type.length) {
+         /*
+          * Register width remains constant -- use vector unpack intrinsics
+          */
+         lp_build_unpack(builder, src_type, dst_type, src[0], tmp, num_dsts);
+      }
+      else {
+         /*
+          * Do it element-wise.
+          */
+
+         assert(src_type.length == dst_type.length);
+         tmp[0] = lp_build_undef(dst_type);
+         for (i = 0; i < dst_type.length; ++i) {
+            LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+            LLVMValueRef val = LLVMBuildExtractElement(builder, src[0], index, "");
+
+            if (src_type.sign && dst_type.sign) {
+               val = LLVMBuildSExt(builder, val, lp_build_elem_type(dst_type), "");
+            } else {
+               val = LLVMBuildZExt(builder, val, lp_build_elem_type(dst_type), "");
+            }
+            tmp[0] = LLVMBuildInsertElement(builder, tmp[0], val, index, "");
+         }
+      }
+   }
+   else {
+      /*
+       * No-op
+       */
+
+      assert(num_srcs == 1);
+      assert(num_dsts == 1);
+
+      tmp[0] = src[0];
+   }
+
+   for(i = 0; i < num_dsts; ++i)
+      dst[i] = tmp[i];
+}
+
+
index 41adeed220c7d8fd6cbb226ea963542dedc43857..e470082b97747ce9916af3c1b21a7d527d62e2a5 100644 (file)
@@ -92,4 +92,12 @@ lp_build_pack(LLVMBuilderRef builder,
               const LLVMValueRef *src, unsigned num_srcs);
 
 
+void
+lp_build_resize(LLVMBuilderRef builder,
+                struct lp_type src_type,
+                struct lp_type dst_type,
+                const LLVMValueRef *src, unsigned num_srcs,
+                LLVMValueRef *dst, unsigned num_dsts);
+
+
 #endif /* !LP_BLD_PACK_H */
index 38fd5a39efa5c26b526aaceba313f3321180e4fd..ca36046d222a508ef8db024ec3ba0018630b9767 100644 (file)
@@ -61,8 +61,8 @@ LLVMValueRef
 lp_build_ddx(struct lp_build_context *bld,
              LLVMValueRef a)
 {
-   LLVMValueRef a_left  = lp_build_swizzle1_aos(bld, a, swizzle_left);
-   LLVMValueRef a_right = lp_build_swizzle1_aos(bld, a, swizzle_right);
+   LLVMValueRef a_left  = lp_build_swizzle_aos(bld, a, swizzle_left);
+   LLVMValueRef a_right = lp_build_swizzle_aos(bld, a, swizzle_right);
    return lp_build_sub(bld, a_right, a_left);
 }
 
@@ -71,8 +71,8 @@ LLVMValueRef
 lp_build_ddy(struct lp_build_context *bld,
              LLVMValueRef a)
 {
-   LLVMValueRef a_top    = lp_build_swizzle1_aos(bld, a, swizzle_top);
-   LLVMValueRef a_bottom = lp_build_swizzle1_aos(bld, a, swizzle_bottom);
+   LLVMValueRef a_top    = lp_build_swizzle_aos(bld, a, swizzle_top);
+   LLVMValueRef a_bottom = lp_build_swizzle_aos(bld, a, swizzle_bottom);
    return lp_build_sub(bld, a_bottom, a_top);
 }
 
index 946c23e317a79c062e486103132efd98dfd99d8e..0fd014ab9b3632d6db2b061c35e6da52da59a9bd 100644 (file)
@@ -40,7 +40,6 @@
 #include "lp_bld_const.h"
 #include "lp_bld_arit.h"
 #include "lp_bld_type.h"
-#include "lp_bld_format.h"
 #include "lp_bld_sample.h"
 
 
@@ -124,74 +123,54 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
 }
 
 
-/**
- * Gather elements from scatter positions in memory into a single vector.
- * Use for fetching texels from a texture.
- * For SSE, typical values are length=4, src_width=32, dst_width=32.
- *
- * @param length length of the offsets
- * @param src_width src element width in bits
- * @param dst_width result element width in bits (src will be expanded to fit)
- * @param base_ptr base pointer, should be a i8 pointer type.
- * @param offsets vector with offsets
- */
-LLVMValueRef
-lp_build_gather(LLVMBuilderRef builder,
-                unsigned length,
-                unsigned src_width,
-                unsigned dst_width,
-                LLVMValueRef base_ptr,
-                LLVMValueRef offsets)
-{
-   LLVMTypeRef src_type = LLVMIntType(src_width);
-   LLVMTypeRef src_ptr_type = LLVMPointerType(src_type, 0);
-   LLVMTypeRef dst_elem_type = LLVMIntType(dst_width);
-   LLVMTypeRef dst_vec_type = LLVMVectorType(dst_elem_type, length);
-   LLVMValueRef res;
-   unsigned i;
-
-   res = LLVMGetUndef(dst_vec_type);
-   for(i = 0; i < length; ++i) {
-      LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
-      LLVMValueRef elem_offset;
-      LLVMValueRef elem_ptr;
-      LLVMValueRef elem;
-
-      elem_offset = LLVMBuildExtractElement(builder, offsets, index, "");
-      elem_ptr = LLVMBuildGEP(builder, base_ptr, &elem_offset, 1, "");
-      elem_ptr = LLVMBuildBitCast(builder, elem_ptr, src_ptr_type, "");
-      elem = LLVMBuildLoad(builder, elem_ptr, "");
-
-      assert(src_width <= dst_width);
-      if(src_width > dst_width)
-         elem = LLVMBuildTrunc(builder, elem, dst_elem_type, "");
-      if(src_width < dst_width)
-         elem = LLVMBuildZExt(builder, elem, dst_elem_type, "");
-
-      res = LLVMBuildInsertElement(builder, res, elem, index, "");
-   }
-
-   return res;
-}
-
-
 /**
  * Compute the offset of a pixel block.
  *
- * x, y, z, y_stride, z_stride are vectors, and they refer to pixel blocks, as
- * per format description, and not individual pixels.
+ * x, y, z, y_stride, z_stride are vectors, and they refer to pixels.
+ *
+ * Returns the relative offset and i,j sub-block coordinates
  */
-LLVMValueRef
+void
 lp_build_sample_offset(struct lp_build_context *bld,
                        const struct util_format_description *format_desc,
                        LLVMValueRef x,
                        LLVMValueRef y,
                        LLVMValueRef z,
                        LLVMValueRef y_stride,
-                       LLVMValueRef z_stride)
+                       LLVMValueRef z_stride,
+                       LLVMValueRef *out_offset,
+                       LLVMValueRef *out_i,
+                       LLVMValueRef *out_j)
 {
    LLVMValueRef x_stride;
    LLVMValueRef offset;
+   LLVMValueRef i;
+   LLVMValueRef j;
+
+   /*
+    * Describe the coordinates in terms of pixel blocks.
+    *
+    * TODO: pixel blocks are power of two. LLVM should convert rem/div to
+    * bit arithmetic. Verify this.
+    */
+
+   if (format_desc->block.width == 1) {
+      i = bld->zero;
+   }
+   else {
+      LLVMValueRef block_width = lp_build_const_int_vec(bld->type, format_desc->block.width);
+      i = LLVMBuildURem(bld->builder, x, block_width, "");
+      x = LLVMBuildUDiv(bld->builder, x, block_width, "");
+   }
+
+   if (format_desc->block.height == 1) {
+      j = bld->zero;
+   }
+   else {
+      LLVMValueRef block_height = lp_build_const_int_vec(bld->type, format_desc->block.height);
+      j = LLVMBuildURem(bld->builder, y, block_height, "");
+      y = LLVMBuildUDiv(bld->builder, y, block_height, "");
+   }
 
    x_stride = lp_build_const_vec(bld->type, format_desc->block.bits/8);
    offset = lp_build_mul(bld, x, x_stride);
@@ -206,5 +185,7 @@ lp_build_sample_offset(struct lp_build_context *bld,
       offset = lp_build_add(bld, offset, z_offset);
    }
 
-   return offset;
+   *out_offset = offset;
+   *out_i = i;
+   *out_j = j;
 }
index 51e98ab2f9eb03c90de346081d932f54d56c3e74..5b8f478094b1aa95564c8894396e803d64de53b1 100644 (file)
@@ -146,23 +146,17 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
                         const struct pipe_sampler_state *sampler);
 
 
-LLVMValueRef
-lp_build_gather(LLVMBuilderRef builder,
-                unsigned length,
-                unsigned src_width,
-                unsigned dst_width,
-                LLVMValueRef base_ptr,
-                LLVMValueRef offsets);
-
-
-LLVMValueRef
+void
 lp_build_sample_offset(struct lp_build_context *bld,
                        const struct util_format_description *format_desc,
                        LLVMValueRef x,
                        LLVMValueRef y,
                        LLVMValueRef z,
                        LLVMValueRef y_stride,
-                       LLVMValueRef z_stride);
+                       LLVMValueRef z_stride,
+                       LLVMValueRef *out_offset,
+                       LLVMValueRef *out_i,
+                       LLVMValueRef *out_j);
 
 
 void
index 84c04fe272f5c8b13a540f6c3a7b44595afdf3ff..1a20d74cac8b5295487054f3e083adcb182be883 100644 (file)
 #include "lp_bld_swizzle.h"
 #include "lp_bld_pack.h"
 #include "lp_bld_flow.h"
+#include "lp_bld_gather.h"
 #include "lp_bld_format.h"
 #include "lp_bld_sample.h"
+#include "lp_bld_quad.h"
 
 
 /**
@@ -264,35 +266,11 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
       }
    }
 
-   /*
-    * Describe the coordinates in terms of pixel blocks.
-    *
-    * TODO: pixel blocks are power of two. LLVM should convert rem/div to
-    * bit arithmetic. Verify this.
-    */
-
-   if (bld->format_desc->block.width == 1) {
-      i = bld->uint_coord_bld.zero;
-   }
-   else {
-      LLVMValueRef block_width = lp_build_const_int_vec(bld->uint_coord_bld.type, bld->format_desc->block.width);
-      i = LLVMBuildURem(bld->builder, x, block_width, "");
-      x = LLVMBuildUDiv(bld->builder, x, block_width, "");
-   }
-
-   if (bld->format_desc->block.height == 1) {
-      j = bld->uint_coord_bld.zero;
-   }
-   else {
-      LLVMValueRef block_height = lp_build_const_int_vec(bld->uint_coord_bld.type, bld->format_desc->block.height);
-      j = LLVMBuildURem(bld->builder, y, block_height, "");
-      y = LLVMBuildUDiv(bld->builder, y, block_height, "");
-   }
-
    /* convert x,y,z coords to linear offset from start of texture, in bytes */
-   offset = lp_build_sample_offset(&bld->uint_coord_bld,
-                                   bld->format_desc,
-                                   x, y, z, y_stride, z_stride);
+   lp_build_sample_offset(&bld->uint_coord_bld,
+                          bld->format_desc,
+                          x, y, z, y_stride, z_stride,
+                          &offset, &i, &j);
 
    if (use_border) {
       /* If we can sample the border color, it means that texcoords may
@@ -344,6 +322,9 @@ lp_build_sample_texel_soa(struct lp_build_sample_context *bld,
 }
 
 
+/**
+ * Fetch the texels as <4n x i8> in AoS form.
+ */
 static LLVMValueRef
 lp_build_sample_packed(struct lp_build_sample_context *bld,
                        LLVMValueRef x,
@@ -351,25 +332,46 @@ lp_build_sample_packed(struct lp_build_sample_context *bld,
                        LLVMValueRef y_stride,
                        LLVMValueRef data_array)
 {
-   LLVMValueRef offset;
+   LLVMValueRef offset, i, j;
    LLVMValueRef data_ptr;
+   LLVMValueRef res;
 
-   offset = lp_build_sample_offset(&bld->uint_coord_bld,
-                                   bld->format_desc,
-                                   x, y, NULL, y_stride, NULL);
-
-   assert(bld->format_desc->block.width == 1);
-   assert(bld->format_desc->block.height == 1);
-   assert(bld->format_desc->block.bits <= bld->texel_type.width);
+   /* convert x,y,z coords to linear offset from start of texture, in bytes */
+   lp_build_sample_offset(&bld->uint_coord_bld,
+                          bld->format_desc,
+                          x, y, NULL, y_stride, NULL,
+                          &offset, &i, &j);
 
    /* get pointer to mipmap level 0 data */
    data_ptr = lp_build_get_const_mipmap_level(bld, data_array, 0);
 
-   return lp_build_gather(bld->builder,
-                          bld->texel_type.length,
-                          bld->format_desc->block.bits,
-                          bld->texel_type.width,
-                          data_ptr, offset);
+   if (util_format_is_rgba8_variant(bld->format_desc)) {
+      /* Just fetch the data directly without swizzling */
+      assert(bld->format_desc->block.width == 1);
+      assert(bld->format_desc->block.height == 1);
+      assert(bld->format_desc->block.bits <= bld->texel_type.width);
+
+      res = lp_build_gather(bld->builder,
+                            bld->texel_type.length,
+                            bld->format_desc->block.bits,
+                            bld->texel_type.width,
+                            data_ptr, offset);
+   }
+   else {
+      struct lp_type type;
+
+      assert(bld->texel_type.width == 32);
+
+      memset(&type, 0, sizeof type);
+      type.width = 8;
+      type.length = bld->texel_type.length*4;
+      type.norm = TRUE;
+
+      res = lp_build_fetch_rgba_aos(bld->builder, bld->format_desc, type,
+                                    data_ptr, offset, i, j);
+   }
+
+   return res;
 }
 
 
@@ -817,9 +819,8 @@ lp_build_minify(struct lp_build_sample_context *bld,
 
 /**
  * Generate code to compute texture level of detail (lambda).
- * \param s  vector of texcoord s values
- * \param t  vector of texcoord t values
- * \param r  vector of texcoord r values
+ * \param ddx  partial derivatives of (s, t, r, q) with respect to X
+ * \param ddy  partial derivatives of (s, t, r, q) with respect to Y
  * \param lod_bias  optional float vector with the shader lod bias
  * \param explicit_lod  optional float vector with the explicit lod
  * \param width  scalar int texture width
@@ -831,11 +832,8 @@ lp_build_minify(struct lp_build_sample_context *bld,
  */
 static LLVMValueRef
 lp_build_lod_selector(struct lp_build_sample_context *bld,
-                      LLVMValueRef s,
-                      LLVMValueRef t,
-                      LLVMValueRef r,
-                      const LLVMValueRef *ddx,
-                      const LLVMValueRef *ddy,
+                      const LLVMValueRef ddx[4],
+                      const LLVMValueRef ddy[4],
                       LLVMValueRef lod_bias, /* optional */
                       LLVMValueRef explicit_lod, /* optional */
                       LLVMValueRef width,
@@ -870,14 +868,6 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
          LLVMValueRef dtdx = NULL, dtdy = NULL, drdx = NULL, drdy = NULL;
          LLVMValueRef rho;
 
-         /*
-          * dsdx = abs(s[1] - s[0]);
-          * dsdy = abs(s[2] - s[0]);
-          * dtdx = abs(t[1] - t[0]);
-          * dtdy = abs(t[2] - t[0]);
-          * drdx = abs(r[1] - r[0]);
-          * drdy = abs(r[2] - r[0]);
-          */
          dsdx = LLVMBuildExtractElement(bld->builder, ddx[0], index0, "dsdx");
          dsdx = lp_build_abs(float_bld, dsdx);
          dsdy = LLVMBuildExtractElement(bld->builder, ddy[0], index0, "dsdy");
@@ -1287,7 +1277,7 @@ lp_build_cube_face(struct lp_build_sample_context *bld,
 
 
 /**
- * Generate code to do cube face selection and per-face texcoords.
+ * Generate code to do cube face selection and compute per-face texcoords.
  */
 static void
 lp_build_cube_lookup(struct lp_build_sample_context *bld,
@@ -1411,7 +1401,6 @@ lp_build_cube_lookup(struct lp_build_sample_context *bld,
          lp_build_endif(&if_ctx2);
          lp_build_flow_scope_end(flow_ctx2);
          lp_build_flow_destroy(flow_ctx2);
-
          *face_s = face_s2;
          *face_t = face_t2;
          *face = face2;
@@ -1457,13 +1446,14 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
    int chan;
 
    if (img_filter == PIPE_TEX_FILTER_NEAREST) {
+      /* sample the first mipmap level */
       lp_build_sample_image_nearest(bld,
                                     width0_vec, height0_vec, depth0_vec,
                                     row_stride0_vec, img_stride0_vec,
                                     data_ptr0, s, t, r, colors0);
 
       if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
-         /* sample the second mipmap level, and interp */
+         /* sample the second mipmap level */
          lp_build_sample_image_nearest(bld,
                                        width1_vec, height1_vec, depth1_vec,
                                        row_stride1_vec, img_stride1_vec,
@@ -1473,13 +1463,14 @@ lp_build_sample_mipmap(struct lp_build_sample_context *bld,
    else {
       assert(img_filter == PIPE_TEX_FILTER_LINEAR);
 
+      /* sample the first mipmap level */
       lp_build_sample_image_linear(bld,
                                    width0_vec, height0_vec, depth0_vec,
                                    row_stride0_vec, img_stride0_vec,
                                    data_ptr0, s, t, r, colors0);
 
       if (mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
-         /* sample the second mipmap level, and interp */
+         /* sample the second mipmap level */
          lp_build_sample_image_linear(bld,
                                       width1_vec, height1_vec, depth1_vec,
                                       row_stride1_vec, img_stride1_vec,
@@ -1542,12 +1533,37 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
    LLVMValueRef row_stride0_vec = NULL, row_stride1_vec = NULL;
    LLVMValueRef img_stride0_vec = NULL, img_stride1_vec = NULL;
    LLVMValueRef data_ptr0, data_ptr1 = NULL;
+   LLVMValueRef face_ddx[4], face_ddy[4];
 
    /*
    printf("%s mip %d  min %d  mag %d\n", __FUNCTION__,
           mip_filter, min_filter, mag_filter);
    */
 
+   /*
+    * Choose cube face, recompute texcoords and derivatives for the chosen face.
+    */
+   if (bld->static_state->target == PIPE_TEXTURE_CUBE) {
+      LLVMValueRef face, face_s, face_t;
+      lp_build_cube_lookup(bld, s, t, r, &face, &face_s, &face_t);
+      s = face_s; /* vec */
+      t = face_t; /* vec */
+      /* use 'r' to indicate cube face */
+      r = lp_build_broadcast_scalar(&bld->int_coord_bld, face); /* vec */
+
+      /* recompute ddx, ddy using the new (s,t) face texcoords */
+      face_ddx[0] = lp_build_ddx(&bld->coord_bld, s);
+      face_ddx[1] = lp_build_ddx(&bld->coord_bld, t);
+      face_ddx[2] = NULL;
+      face_ddx[3] = NULL;
+      face_ddy[0] = lp_build_ddy(&bld->coord_bld, s);
+      face_ddy[1] = lp_build_ddy(&bld->coord_bld, t);
+      face_ddy[2] = NULL;
+      face_ddy[3] = NULL;
+      ddx = face_ddx;
+      ddy = face_ddy;
+   }
+
    /*
     * Compute the level of detail (float).
     */
@@ -1556,7 +1572,7 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
       /* Need to compute lod either to choose mipmap levels or to
        * distinguish between minification/magnification with one mipmap level.
        */
-      lod = lp_build_lod_selector(bld, s, t, r, ddx, ddy,
+      lod = lp_build_lod_selector(bld, ddx, ddy,
                                   lod_bias, explicit_lod,
                                   width, height, depth);
    }
@@ -1566,9 +1582,20 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
     */
    if (mip_filter == PIPE_TEX_MIPFILTER_NONE) {
       /* always use mip level 0 */
-      ilevel0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
+      if (bld->static_state->target == PIPE_TEXTURE_CUBE) {
+         /* XXX this is a work-around for an apparent bug in LLVM 2.7.
+          * We should be able to set ilevel0 = const(0) but that causes
+          * bad x86 code to be emitted.
+          */
+         lod = lp_build_const_elem(bld->coord_bld.type, 0.0);
+         lp_build_nearest_mip_level(bld, unit, lod, &ilevel0);
+      }
+      else {
+         ilevel0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
+      }
    }
    else {
+      assert(lod);
       if (mip_filter == PIPE_TEX_MIPFILTER_NEAREST) {
          lp_build_nearest_mip_level(bld, unit, lod, &ilevel0);
       }
@@ -1622,18 +1649,6 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
       }
    }
 
-   /*
-    * Choose cube face, recompute per-face texcoords.
-    */
-   if (bld->static_state->target == PIPE_TEXTURE_CUBE) {
-      LLVMValueRef face, face_s, face_t;
-      lp_build_cube_lookup(bld, s, t, r, &face, &face_s, &face_t);
-      s = face_s; /* vec */
-      t = face_t; /* vec */
-      /* use 'r' to indicate cube face */
-      r = lp_build_broadcast_scalar(&bld->int_coord_bld, face); /* vec */
-   }
-
    /*
     * Get pointer(s) to image data for mipmap level(s).
     */
@@ -1711,36 +1726,6 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
 
 
 
-static void
-lp_build_rgba8_to_f32_soa(LLVMBuilderRef builder,
-                          struct lp_type dst_type,
-                          LLVMValueRef packed,
-                          LLVMValueRef *rgba)
-{
-   LLVMValueRef mask = lp_build_const_int_vec(dst_type, 0xff);
-   unsigned chan;
-
-   /* Decode the input vector components */
-   for (chan = 0; chan < 4; ++chan) {
-      unsigned start = chan*8;
-      unsigned stop = start + 8;
-      LLVMValueRef input;
-
-      input = packed;
-
-      if(start)
-         input = LLVMBuildLShr(builder, input, lp_build_const_int_vec(dst_type, start), "");
-
-      if(stop < 32)
-         input = LLVMBuildAnd(builder, input, mask, "");
-
-      input = lp_build_unsigned_norm_to_float(builder, 8, dst_type, input);
-
-      rgba[chan] = input;
-   }
-}
-
-
 static void
 lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
                               LLVMValueRef s,
@@ -1935,15 +1920,20 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
     * Convert to SoA and swizzle.
     */
 
-   packed = LLVMBuildBitCast(builder, packed, i32_vec_type, "");
-
    lp_build_rgba8_to_f32_soa(bld->builder,
                              bld->texel_type,
                              packed, unswizzled);
 
-   lp_build_format_swizzle_soa(bld->format_desc,
-                               &bld->texel_bld,
-                               unswizzled, texel_out);
+   if (util_format_is_rgba8_variant(bld->format_desc)) {
+      lp_build_format_swizzle_soa(bld->format_desc,
+                                  &bld->texel_bld,
+                                  unswizzled, texel_out);
+   } else {
+      texel_out[0] = unswizzled[0];
+      texel_out[1] = unswizzled[1];
+      texel_out[2] = unswizzled[2];
+      texel_out[3] = unswizzled[3];
+   }
 
    apply_sampler_swizzle(bld, texel_out);
 }
@@ -2007,6 +1997,8 @@ lp_build_sample_nop(struct lp_build_sample_context *bld,
  * 'texel' will return a vector of four LLVMValueRefs corresponding to
  * R, G, B, A.
  * \param type  vector float type to use for coords, etc.
+ * \param ddx  partial derivatives of (s,t,r,q) with respect to x
+ * \param ddy  partial derivatives of (s,t,r,q) with respect to y
  */
 void
 lp_build_sample_soa(LLVMBuilderRef builder,
@@ -2016,8 +2008,8 @@ lp_build_sample_soa(LLVMBuilderRef builder,
                     unsigned unit,
                     unsigned num_coords,
                     const LLVMValueRef *coords,
-                    const LLVMValueRef *ddx,
-                    const LLVMValueRef *ddy,
+                    const LLVMValueRef ddx[4],
+                    const LLVMValueRef ddy[4],
                     LLVMValueRef lod_bias, /* optional */
                     LLVMValueRef explicit_lod, /* optional */
                     LLVMValueRef texel_out[4])
@@ -2079,7 +2071,8 @@ lp_build_sample_soa(LLVMBuilderRef builder,
       /* For debug: no-op texture sampling */
       lp_build_sample_nop(&bld, texel_out);
    }
-   else if (util_format_is_rgba8_variant(bld.format_desc) &&
+   else if (util_format_fits_8unorm(bld.format_desc) &&
+            bld.format_desc->nr_channels > 1 &&
             static_state->target == PIPE_TEXTURE_2D &&
             static_state->min_img_filter == PIPE_TEX_FILTER_LINEAR &&
             static_state->mag_img_filter == PIPE_TEX_FILTER_LINEAR &&
index 3c8a7bc09ea03ba4e94f4ec15c1c34dd007500e5..20cf96ca66991ed28303aecf1fa47cb1dcd4da65 100644 (file)
@@ -110,7 +110,7 @@ lp_build_broadcast_aos(struct lp_build_context *bld,
    /* XXX: SSE3 has PSHUFB which should be better than bitmasks, but forcing
     * using shuffles here actually causes worst results. More investigation is
     * needed. */
-   if (n <= 4) {
+   if (type.width >= 16) {
       /*
        * Shuffle.
        */
@@ -132,7 +132,7 @@ lp_build_broadcast_aos(struct lp_build_context *bld,
        *   YY00 YY00 .... YY00
        *   YYYY YYYY .... YYYY  <= output
        */
-      struct lp_type type4 = type;
+      struct lp_type type4;
       const char shifts[4][2] = {
          { 1,  2},
          {-1,  2},
@@ -147,6 +147,13 @@ lp_build_broadcast_aos(struct lp_build_context *bld,
 
       a = LLVMBuildAnd(bld->builder, a, lp_build_const_mask_aos(type, cond), "");
 
+      /*
+       * Build a type where each element is an integer that cover the four
+       * channels.
+       */
+
+      type4 = type;
+      type4.floating = FALSE;
       type4.width *= 4;
       type4.length /= 4;
 
@@ -176,80 +183,170 @@ lp_build_broadcast_aos(struct lp_build_context *bld,
 
 
 LLVMValueRef
-lp_build_swizzle1_aos(struct lp_build_context *bld,
-                      LLVMValueRef a,
-                      const unsigned char swizzle[4])
+lp_build_swizzle_aos(struct lp_build_context *bld,
+                     LLVMValueRef a,
+                     const unsigned char swizzles[4])
 {
-   const unsigned n = bld->type.length;
+   const struct lp_type type = bld->type;
+   const unsigned n = type.length;
    unsigned i, j;
 
-   if(a == bld->undef || a == bld->zero || a == bld->one)
+   if (swizzles[0] == PIPE_SWIZZLE_RED &&
+       swizzles[1] == PIPE_SWIZZLE_GREEN &&
+       swizzles[2] == PIPE_SWIZZLE_BLUE &&
+       swizzles[3] == PIPE_SWIZZLE_ALPHA) {
       return a;
+   }
 
-   if(swizzle[0] == swizzle[1] && swizzle[1] == swizzle[2] && swizzle[2] == swizzle[3])
-      return lp_build_broadcast_aos(bld, a, swizzle[0]);
+   if (swizzles[0] == swizzles[1] &&
+       swizzles[1] == swizzles[2] &&
+       swizzles[2] == swizzles[3]) {
+      switch (swizzles[0]) {
+      case PIPE_SWIZZLE_RED:
+      case PIPE_SWIZZLE_GREEN:
+      case PIPE_SWIZZLE_BLUE:
+      case PIPE_SWIZZLE_ALPHA:
+         return lp_build_broadcast_aos(bld, a, swizzles[0]);
+      case PIPE_SWIZZLE_ZERO:
+         return bld->zero;
+      case PIPE_SWIZZLE_ONE:
+         return bld->one;
+      default:
+         assert(0);
+         return bld->undef;
+      }
+   }
 
-   {
+   if (type.width >= 16) {
       /*
        * Shuffle.
        */
-      LLVMTypeRef elem_type = LLVMInt32Type();
+      LLVMValueRef undef = LLVMGetUndef(lp_build_elem_type(type));
+      LLVMTypeRef i32t = LLVMInt32Type();
       LLVMValueRef shuffles[LP_MAX_VECTOR_LENGTH];
+      LLVMValueRef aux[LP_MAX_VECTOR_LENGTH];
+
+      memset(aux, 0, sizeof aux);
+
+      for(j = 0; j < n; j += 4) {
+         for(i = 0; i < 4; ++i) {
+            unsigned shuffle;
+            switch (swizzles[i]) {
+            default:
+               assert(0);
+               /* fall through */
+            case PIPE_SWIZZLE_RED:
+            case PIPE_SWIZZLE_GREEN:
+            case PIPE_SWIZZLE_BLUE:
+            case PIPE_SWIZZLE_ALPHA:
+               shuffle = j + swizzles[i];
+               break;
+            case PIPE_SWIZZLE_ZERO:
+               shuffle = type.length + 0;
+               if (!aux[0]) {
+                  aux[0] = lp_build_const_elem(type, 0.0);
+               }
+               break;
+            case PIPE_SWIZZLE_ONE:
+               shuffle = type.length + 1;
+               if (!aux[1]) {
+                  aux[1] = lp_build_const_elem(type, 1.0);
+               }
+               break;
+            }
+            shuffles[j + i] = LLVMConstInt(i32t, shuffle, 0);
+         }
+      }
 
-      for(j = 0; j < n; j += 4)
-         for(i = 0; i < 4; ++i)
-            shuffles[j + i] = LLVMConstInt(elem_type, j + swizzle[i], 0);
-
-      return LLVMBuildShuffleVector(bld->builder, a, bld->undef, LLVMConstVector(shuffles, n), "");
-   }
-}
-
+      for (i = 0; i < n; ++i) {
+         if (!aux[i]) {
+            aux[i] = undef;
+         }
+      }
 
-LLVMValueRef
-lp_build_swizzle2_aos(struct lp_build_context *bld,
-                      LLVMValueRef a,
-                      LLVMValueRef b,
-                      const unsigned char swizzle[4])
-{
-   const unsigned n = bld->type.length;
-   unsigned i, j;
+      return LLVMBuildShuffleVector(bld->builder, a,
+                                    LLVMConstVector(aux, n),
+                                    LLVMConstVector(shuffles, n), "");
+   } else {
+      /*
+       * Bit mask and shifts.
+       *
+       * For example, this will convert BGRA to RGBA by doing
+       *
+       *   rgba = (bgra & 0x00ff0000) >> 16
+       *        | (bgra & 0xff00ff00)
+       *        | (bgra & 0x000000ff) << 16
+       *
+       * This is necessary not only for faster cause, but because X86 backend
+       * will refuse shuffles of <4 x i8> vectors
+       */
+      LLVMValueRef res;
+      struct lp_type type4;
+      boolean cond[4];
+      unsigned chan;
+      int shift;
 
-   if(swizzle[0] < 4 && swizzle[1] < 4 && swizzle[2] < 4 && swizzle[3] < 4)
-      return lp_build_swizzle1_aos(bld, a, swizzle);
+      /*
+       * Start with a mixture of 1 and 0.
+       */
+      for (chan = 0; chan < 4; ++chan) {
+         cond[chan] = swizzles[chan] == PIPE_SWIZZLE_ONE ? TRUE : FALSE;
+      }
+      res = lp_build_select_aos(bld, bld->one, bld->zero, cond);
 
-   if(a == b) {
-      unsigned char swizzle1[4];
-      swizzle1[0] = swizzle[0] % 4;
-      swizzle1[1] = swizzle[1] % 4;
-      swizzle1[2] = swizzle[2] % 4;
-      swizzle1[3] = swizzle[3] % 4;
-      return lp_build_swizzle1_aos(bld, a, swizzle1);
-   }
+      /*
+       * Build a type where each element is an integer that cover the four
+       * channels.
+       */
+      type4 = type;
+      type4.floating = FALSE;
+      type4.width *= 4;
+      type4.length /= 4;
 
-   if(swizzle[0] % 4 == 0 &&
-      swizzle[1] % 4 == 1 &&
-      swizzle[2] % 4 == 2 &&
-      swizzle[3] % 4 == 3) {
-      boolean cond[4];
-      cond[0] = swizzle[0] / 4;
-      cond[1] = swizzle[1] / 4;
-      cond[2] = swizzle[2] / 4;
-      cond[3] = swizzle[3] / 4;
-      return lp_build_select_aos(bld, a, b, cond);
-   }
+      a = LLVMBuildBitCast(bld->builder, a, lp_build_vec_type(type4), "");
+      res = LLVMBuildBitCast(bld->builder, res, lp_build_vec_type(type4), "");
 
-   {
       /*
-       * Shuffle.
+       * Mask and shift the channels, trying to group as many channels in the
+       * same shift as possible
        */
-      LLVMTypeRef elem_type = LLVMInt32Type();
-      LLVMValueRef shuffles[LP_MAX_VECTOR_LENGTH];
-
-      for(j = 0; j < n; j += 4)
-         for(i = 0; i < 4; ++i)
-            shuffles[j + i] = LLVMConstInt(elem_type, j + (swizzle[i] % 4) + (swizzle[i] / 4 * n), 0);
+      for (shift = -3; shift <= 3; ++shift) {
+         unsigned long long mask = 0;
+
+         assert(type4.width <= sizeof(mask)*8);
+
+         for (chan = 0; chan < 4; ++chan) {
+            /* FIXME: big endian */
+            if (swizzles[chan] < 4 &&
+                chan - swizzles[chan] == shift) {
+               mask |= ((1ULL << type.width) - 1) << (swizzles[chan] * type.width);
+            }
+         }
+
+         if (mask) {
+            LLVMValueRef masked;
+            LLVMValueRef shifted;
+
+            if (0)
+               debug_printf("shift = %i, mask = 0x%08llx\n", shift, mask);
+
+            masked = LLVMBuildAnd(bld->builder, a,
+                                  lp_build_const_int_vec(type4, mask), "");
+            if (shift > 0) {
+               shifted = LLVMBuildShl(bld->builder, masked,
+                                      lp_build_const_int_vec(type4, shift*type.width), "");
+            } else if (shift < 0) {
+               shifted = LLVMBuildLShr(bld->builder, masked,
+                                       lp_build_const_int_vec(type4, -shift*type.width), "");
+            } else {
+               shifted = masked;
+            }
+
+            res = LLVMBuildOr(bld->builder, res, shifted, "");
+         }
+      }
 
-      return LLVMBuildShuffleVector(bld->builder, a, b, LLVMConstVector(shuffles, n), "");
+      return LLVMBuildBitCast(bld->builder, res, lp_build_vec_type(type), "");
    }
 }
 
index 4f4fa777c930fa433213acf01f1109f94b5ff7a4..315e1bcb548b0a00b1dafe77bda4e8651b215b9d 100644 (file)
@@ -68,24 +68,12 @@ lp_build_broadcast_aos(struct lp_build_context *bld,
 /**
  * Swizzle a vector consisting of an array of XYZW structs.
  *
- * @param swizzle is the in [0,4[ range.
+ * @param swizzles is the in [0,4[ range.
  */
 LLVMValueRef
-lp_build_swizzle1_aos(struct lp_build_context *bld,
-                      LLVMValueRef a,
-                      const unsigned char swizzle[4]);
-
-
-/**
- * Swizzle two vector consisting of an array of XYZW structs.
- *
- * @param swizzle is the in [0,8[ range. Values in [4,8[ range refer to b.
- */
-LLVMValueRef
-lp_build_swizzle2_aos(struct lp_build_context *bld,
-                      LLVMValueRef a,
-                      LLVMValueRef b,
-                      const unsigned char swizzle[4]);
+lp_build_swizzle_aos(struct lp_build_context *bld,
+                     LLVMValueRef a,
+                     const unsigned char swizzles[4]);
 
 
 LLVMValueRef
index dec7556138cc23a67795eb1ebba56edf8f705d28..21236839fb730ae5e9fb9917f398ed3167a98733 100644 (file)
@@ -49,6 +49,7 @@
 #include "lp_bld_type.h"
 #include "lp_bld_const.h"
 #include "lp_bld_arit.h"
+#include "lp_bld_gather.h"
 #include "lp_bld_logic.h"
 #include "lp_bld_swizzle.h"
 #include "lp_bld_flow.h"
@@ -132,10 +133,14 @@ struct lp_build_tgsi_soa_context
    LLVMValueRef addr[LP_MAX_TGSI_ADDRS][NUM_CHANNELS];
    LLVMValueRef preds[LP_MAX_TGSI_PREDS][NUM_CHANNELS];
 
-   /* we allocate an array of temps if we have indirect
-    * addressing and then the temps above is unused */
+   /* We allocate/use this array of temps if (1 << TGSI_FILE_TEMPORARY) is
+    * set in the indirect_files field.
+    * The temps[] array above is unused then.
+    */
    LLVMValueRef temps_array;
-   boolean has_indirect_addressing;
+
+   /** bitmask indicating which register files are accessed indirectly */
+   unsigned indirect_files;
 
    struct lp_build_mask_context *mask;
    struct lp_exec_mask exec_mask;
@@ -404,25 +409,92 @@ static void lp_exec_mask_endsub(struct lp_exec_mask *mask, int *pc)
    lp_exec_mask_update(mask);
 }
 
+
+/**
+ * Return pointer to a temporary register channel (src or dest).
+ * Note that indirect addressing cannot be handled here.
+ * \param index  which temporary register
+ * \param chan  which channel of the temp register.
+ */
 static LLVMValueRef
 get_temp_ptr(struct lp_build_tgsi_soa_context *bld,
              unsigned index,
-             unsigned chan,
-             boolean is_indirect,
-             LLVMValueRef addr)
+             unsigned chan)
 {
    assert(chan < 4);
-   if (!bld->has_indirect_addressing) {
-      return bld->temps[index][chan];
-   } else {
-      LLVMValueRef lindex =
-         LLVMConstInt(LLVMInt32Type(), index * 4 + chan, 0);
-      if (is_indirect)
-         lindex = lp_build_add(&bld->base, lindex, addr);
+   if (bld->indirect_files & (1 << TGSI_FILE_TEMPORARY)) {
+      LLVMValueRef lindex = lp_build_const_int32(index * 4 + chan);
       return LLVMBuildGEP(bld->base.builder, bld->temps_array, &lindex, 1, "");
    }
+   else {
+      return bld->temps[index][chan];
+   }
 }
 
+
+/**
+ * Gather vector.
+ * XXX the lp_build_gather() function should be capable of doing this
+ * with a little work.
+ */
+static LLVMValueRef
+build_gather(struct lp_build_tgsi_soa_context *bld,
+             LLVMValueRef base_ptr,
+             LLVMValueRef indexes)
+{
+   LLVMValueRef res = bld->base.undef;
+   unsigned i;
+
+   /*
+    * Loop over elements of index_vec, load scalar value, insert it into 'res'.
+    */
+   for (i = 0; i < bld->base.type.length; i++) {
+      LLVMValueRef ii = LLVMConstInt(LLVMInt32Type(), i, 0);
+      LLVMValueRef index = LLVMBuildExtractElement(bld->base.builder,
+                                                   indexes, ii, "");
+      LLVMValueRef scalar_ptr = LLVMBuildGEP(bld->base.builder, base_ptr,
+                                             &index, 1, "");
+      LLVMValueRef scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
+
+      res = LLVMBuildInsertElement(bld->base.builder, res, scalar, ii, "");
+   }
+
+   return res;
+}
+
+
+/**
+ * Read the current value of the ADDR register, convert the floats to
+ * ints, multiply by four and return the vector of offsets.
+ * The offsets will be used to index into the constant buffer or
+ * temporary register file.
+ */
+static LLVMValueRef
+get_indirect_offsets(struct lp_build_tgsi_soa_context *bld,
+                     const struct tgsi_src_register *indirect_reg)
+{
+   /* always use X component of address register */
+   const int x = indirect_reg->SwizzleX;
+   LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->base.type);
+   uint swizzle = tgsi_util_get_src_register_swizzle(indirect_reg, x);
+   LLVMValueRef vec4 = lp_build_const_int_vec(bld->int_bld.type, 4); 
+   LLVMValueRef addr_vec;
+
+   addr_vec = LLVMBuildLoad(bld->base.builder,
+                            bld->addr[indirect_reg->Index][swizzle],
+                            "load addr reg");
+
+   /* for indexing we want integers */
+   addr_vec = LLVMBuildFPToSI(bld->base.builder, addr_vec,
+                              int_vec_type, "");
+
+   /* addr_vec = addr_vec * 4 */
+   addr_vec = lp_build_mul(&bld->base, addr_vec, vec4);
+
+   return addr_vec;
+}
+
+
 /**
  * Register fetch.
  */
@@ -430,14 +502,14 @@ static LLVMValueRef
 emit_fetch(
    struct lp_build_tgsi_soa_context *bld,
    const struct tgsi_full_instruction *inst,
-   unsigned index,
+   unsigned src_op,
    const unsigned chan_index )
 {
-   const struct tgsi_full_src_register *reg = &inst->Src[index];
+   const struct tgsi_full_src_register *reg = &inst->Src[src_op];
    const unsigned swizzle =
       tgsi_util_get_full_src_register_swizzle(reg, chan_index);
    LLVMValueRef res;
-   LLVMValueRef addr = NULL;
+   LLVMValueRef addr_vec = NULL;
 
    if (swizzle > 3) {
       assert(0 && "invalid swizzle in emit_fetch()");
@@ -445,32 +517,33 @@ emit_fetch(
    }
 
    if (reg->Register.Indirect) {
-      LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->base.type);
-      unsigned swizzle = tgsi_util_get_src_register_swizzle( &reg->Indirect, chan_index );
-      addr = LLVMBuildLoad(bld->base.builder,
-                           bld->addr[reg->Indirect.Index][swizzle],
-                           "");
-      /* for indexing we want integers */
-      addr = LLVMBuildFPToSI(bld->base.builder, addr,
-                             int_vec_type, "");
-      addr = LLVMBuildExtractElement(bld->base.builder,
-                                     addr, LLVMConstInt(LLVMInt32Type(), 0, 0),
-                                     "");
-      addr = lp_build_mul(&bld->base, addr, LLVMConstInt(LLVMInt32Type(), 4, 0));
+      assert(bld->indirect_files);
+      addr_vec = get_indirect_offsets(bld, &reg->Indirect);
    }
 
    switch (reg->Register.File) {
    case TGSI_FILE_CONSTANT:
-      {
-         LLVMValueRef index = LLVMConstInt(LLVMInt32Type(),
-                                           reg->Register.Index*4 + swizzle, 0);
+      if (reg->Register.Indirect) {
+         LLVMValueRef index_vec;  /* index into the const buffer */
+
+         assert(bld->indirect_files & (1 << TGSI_FILE_CONSTANT));
+
+         /* index_vec = broadcast(reg->Register.Index * 4 + swizzle) */
+         index_vec = lp_build_const_int_vec(bld->int_bld.type,
+                                            reg->Register.Index * 4 + swizzle);
+
+         /* index_vec = index_vec + addr_vec */
+         index_vec = lp_build_add(&bld->base, index_vec, addr_vec);
+
+         /* Gather values from the constant buffer */
+         res = build_gather(bld, bld->consts_ptr, index_vec);
+      }
+      else {
+         LLVMValueRef index;  /* index into the const buffer */
          LLVMValueRef scalar, scalar_ptr;
 
-         if (reg->Register.Indirect) {
-            /*lp_build_printf(bld->base.builder,
-              "\taddr = %d\n", addr);*/
-            index = lp_build_add(&bld->base, index, addr);
-         }
+         index = lp_build_const_int32(reg->Register.Index*4 + swizzle);
+
          scalar_ptr = LLVMBuildGEP(bld->base.builder, bld->consts_ptr,
                                    &index, 1, "");
          scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
@@ -490,13 +563,38 @@ emit_fetch(
       break;
 
    case TGSI_FILE_TEMPORARY:
-      {
-         LLVMValueRef temp_ptr = get_temp_ptr(bld, reg->Register.Index,
-                                              swizzle,
-                                              reg->Register.Indirect,
-                                              addr);
+      if (reg->Register.Indirect) {
+         LLVMValueRef vec_len =
+            lp_build_const_int_vec(bld->int_bld.type, bld->base.type.length);
+         LLVMValueRef index_vec;  /* index into the const buffer */
+         LLVMValueRef temps_array;
+         LLVMTypeRef float4_ptr_type;
+
+         assert(bld->indirect_files & (1 << TGSI_FILE_TEMPORARY));
+
+         /* index_vec = broadcast(reg->Register.Index * 4 + swizzle) */
+         index_vec = lp_build_const_int_vec(bld->int_bld.type,
+                                            reg->Register.Index * 4 + swizzle);
+
+         /* index_vec += addr_vec */
+         index_vec = lp_build_add(&bld->int_bld, index_vec, addr_vec);
+
+         /* index_vec *= vector_length */
+         index_vec = lp_build_mul(&bld->int_bld, index_vec, vec_len);
+
+         /* cast temps_array pointer to float* */
+         float4_ptr_type = LLVMPointerType(LLVMFloatType(), 0);
+         temps_array = LLVMBuildBitCast(bld->int_bld.builder, bld->temps_array,
+                                        float4_ptr_type, "");
+
+         /* Gather values from the temporary register array */
+         res = build_gather(bld, temps_array, index_vec);
+      }
+      else {
+         LLVMValueRef temp_ptr;
+         temp_ptr = get_temp_ptr(bld, reg->Register.Index, swizzle);
          res = LLVMBuildLoad(bld->base.builder, temp_ptr, "");
-         if(!res)
+         if (!res)
             return bld->base.undef;
       }
       break;
@@ -660,8 +758,12 @@ emit_store(
    }
 
    if (reg->Register.Indirect) {
+      /* XXX use get_indirect_offsets() here eventually */
       LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->base.type);
       unsigned swizzle = tgsi_util_get_src_register_swizzle( &reg->Indirect, chan_index );
+
+      assert(bld->indirect_files);
+
       addr = LLVMBuildLoad(bld->base.builder,
                            bld->addr[reg->Indirect.Index][swizzle],
                            "");
@@ -680,14 +782,18 @@ emit_store(
                          bld->outputs[reg->Register.Index][chan_index]);
       break;
 
-   case TGSI_FILE_TEMPORARY: {
-      LLVMValueRef temp_ptr = get_temp_ptr(bld, reg->Register.Index,
-                                           chan_index,
-                                           reg->Register.Indirect,
-                                           addr);
-      lp_exec_mask_store(&bld->exec_mask, pred, value, temp_ptr);
+   case TGSI_FILE_TEMPORARY:
+      if (reg->Register.Indirect) {
+         /* XXX not done yet */
+         debug_printf("WARNING: LLVM scatter store of temp regs"
+                      " not implemented\n");
+      }
+      else {
+         LLVMValueRef temp_ptr = get_temp_ptr(bld, reg->Register.Index,
+                                              chan_index);
+         lp_exec_mask_store(&bld->exec_mask, pred, value, temp_ptr);
+      }
       break;
-   }
 
    case TGSI_FILE_ADDRESS:
       lp_exec_mask_store(&bld->exec_mask, pred, value,
@@ -905,7 +1011,7 @@ emit_declaration(
       switch (decl->Declaration.File) {
       case TGSI_FILE_TEMPORARY:
          assert(idx < LP_MAX_TGSI_TEMPS);
-         if (bld->has_indirect_addressing) {
+         if (bld->indirect_files & (1 << TGSI_FILE_TEMPORARY)) {
             LLVMValueRef array_size = LLVMConstInt(LLVMInt32Type(),
                                                    last*4 + 4, 0);
             bld->temps_array = lp_build_array_alloca(bld->base.builder,
@@ -1929,8 +2035,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
    bld.outputs = outputs;
    bld.consts_ptr = consts_ptr;
    bld.sampler = sampler;
-   bld.has_indirect_addressing = info->opcode_count[TGSI_OPCODE_ARR] > 0 ||
-                                 info->opcode_count[TGSI_OPCODE_ARL] > 0;
+   bld.indirect_files = info->indirect_files;
    bld.instructions = (struct tgsi_full_instruction *)
                       MALLOC( LP_MAX_INSTRUCTIONS * sizeof(struct tgsi_full_instruction) );
    bld.max_instructions = LP_MAX_INSTRUCTIONS;
index df77ef2155130cd3341cbcf4fe10f29e646fe977..3ffe916f8e42da9d807d24d066512305edb4057a 100644 (file)
@@ -316,6 +316,54 @@ LLVMTypeRef
 lp_build_int32_vec4_type(void);
 
 
+static INLINE struct lp_type
+lp_float32_vec4_type(void)
+{
+   struct lp_type type;
+
+   memset(&type, 0, sizeof(type));
+   type.floating = TRUE;
+   type.sign = TRUE;
+   type.norm = FALSE;
+   type.width = 32;
+   type.length = 4;
+
+   return type;
+}
+
+
+static INLINE struct lp_type
+lp_int32_vec4_type(void)
+{
+   struct lp_type type;
+
+   memset(&type, 0, sizeof(type));
+   type.floating = FALSE;
+   type.sign = TRUE;
+   type.norm = FALSE;
+   type.width = 32;
+   type.length = 4;
+
+   return type;
+}
+
+
+static INLINE struct lp_type
+lp_unorm8_vec4_type(void)
+{
+   struct lp_type type;
+
+   memset(&type, 0, sizeof(type));
+   type.floating = FALSE;
+   type.sign = FALSE;
+   type.norm = TRUE;
+   type.width = 8;
+   type.length = 4;
+
+   return type;
+}
+
+
 struct lp_type
 lp_uint_type(struct lp_type type);
 
index 0238308d20b72b5be131e238cd849b5f907203d4..a084310d4ff1bb17190a1136beaa51e70243568c 100644 (file)
@@ -45,7 +45,6 @@
 #include <pthread.h> /* POSIX threads headers */
 #include <stdio.h> /* for perror() */
 
-#define PIPE_THREAD_HAVE_CONDVAR
 
 /* pipe_thread
  */
@@ -168,19 +167,59 @@ typedef CRITICAL_SECTION pipe_mutex;
 #define pipe_mutex_unlock(mutex) \
    LeaveCriticalSection(&mutex)
 
+/* TODO: Need a macro to declare "I don't care about WinXP compatibilty" */
+#if 0 && defined (_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)
+/* CONDITION_VARIABLE is only available on newer versions of Windows
+ * (Server 2008/Vista or later).
+ * http://msdn.microsoft.com/en-us/library/ms682052(VS.85).aspx
+ *
+ * pipe_condvar
+ */
+typedef CONDITION_VARIABLE pipe_condvar;
+
+#define pipe_static_condvar(cond) \
+   /*static*/ pipe_condvar cond = CONDITION_VARIABLE_INIT
+
+#define pipe_condvar_init(cond) \
+   InitializeConditionVariable(&(cond))
+
+#define pipe_condvar_destroy(cond) \
+   (void) cond /* nothing to do */
+
+#define pipe_condvar_wait(cond, mutex) \
+   SleepConditionVariableCS(&(cond), &(mutex), INFINITE)
+
+#define pipe_condvar_signal(cond) \
+   WakeConditionVariable(&(cond))
+
+#define pipe_condvar_broadcast(cond) \
+   WakeAllConditionVariable(&(cond))
+
+#else /* need compatibility with pre-Vista Win32 */
 
 /* pipe_condvar (XXX FIX THIS)
+ * See http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
+ * for potential pitfalls in implementation.
  */
-typedef unsigned pipe_condvar;
+typedef DWORD pipe_condvar;
+
+#define pipe_static_condvar(cond) \
+   /*static*/ pipe_condvar cond = 1
 
 #define pipe_condvar_init(cond) \
-   (void) cond
+   (void) (cond = 1)
 
 #define pipe_condvar_destroy(cond) \
    (void) cond
 
+/* Poor man's pthread_cond_wait():
+   Just release the mutex and sleep for one millisecond.
+   The caller's while() loop does all the work. */
 #define pipe_condvar_wait(cond, mutex) \
-   (void) cond; (void) mutex
+   do { pipe_mutex_unlock(mutex); \
+        Sleep(cond); \
+        pipe_mutex_lock(mutex); \
+   } while (0)
 
 #define pipe_condvar_signal(cond) \
    (void) cond
@@ -188,9 +227,12 @@ typedef unsigned pipe_condvar;
 #define pipe_condvar_broadcast(cond) \
    (void) cond
 
+#endif /* pre-Vista win32 */
 
 #else
 
+#include "os/os_time.h"
+
 /** Dummy definitions */
 
 typedef unsigned pipe_thread;
@@ -214,7 +256,6 @@ static INLINE int pipe_thread_destroy( pipe_thread thread )
 }
 
 typedef unsigned pipe_mutex;
-typedef unsigned pipe_condvar;
 
 #define pipe_static_mutex(mutex) \
    static pipe_mutex mutex = 0
@@ -231,17 +272,25 @@ typedef unsigned pipe_condvar;
 #define pipe_mutex_unlock(mutex) \
    (void) mutex
 
+typedef int64_t pipe_condvar;
+
 #define pipe_static_condvar(condvar) \
-   static unsigned condvar = 0
+   static pipe_condvar condvar = 1000
 
 #define pipe_condvar_init(condvar) \
-   (void) condvar
+   (void) (condvar = 1000)
 
 #define pipe_condvar_destroy(condvar) \
    (void) condvar
 
+/* Poor man's pthread_cond_wait():
+   Just release the mutex and sleep for one millisecond.
+   The caller's while() loop does all the work. */
 #define pipe_condvar_wait(condvar, mutex) \
-   (void) condvar
+   do { pipe_mutex_unlock(mutex); \
+        os_time_sleep(condvar); \
+        pipe_mutex_lock(mutex); \
+   } while (0)
 
 #define pipe_condvar_signal(condvar) \
    (void) condvar
@@ -277,27 +326,7 @@ static INLINE void pipe_barrier_wait(pipe_barrier *barrier)
 }
 
 
-#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
-
-/* XXX FIX THIS */
-typedef unsigned pipe_barrier;
-
-static INLINE void pipe_barrier_init(pipe_barrier *barrier, unsigned count)
-{
-   /* XXX we could implement barriers with a mutex and condition var */
-}
-
-static INLINE void pipe_barrier_destroy(pipe_barrier *barrier)
-{
-}
-
-static INLINE void pipe_barrier_wait(pipe_barrier *barrier)
-{
-   assert(0);
-}
-
-
-#else
+#else /* If the OS doesn't have its own, implement barriers using a mutex and a condvar */
 
 typedef struct {
    unsigned count;
diff --git a/src/gallium/auxiliary/target-helpers/inline_debug_helper.h b/src/gallium/auxiliary/target-helpers/inline_debug_helper.h
new file mode 100644 (file)
index 0000000..0433da6
--- /dev/null
@@ -0,0 +1,44 @@
+
+#ifndef INLINE_DEBUG_HELPER_H
+#define INLINE_DEBUG_HELPER_H
+
+#include "pipe/p_compiler.h"
+#include "util/u_debug.h"
+
+
+/* Helper function to wrap a screen with
+ * one or more debug driver: rbug, trace.
+ */
+
+#ifdef GALLIUM_TRACE
+#include "trace/tr_public.h"
+#endif
+
+#ifdef GALLIUM_RBUG
+#include "rbug/rbug_public.h"
+#endif
+
+#ifdef GALLIUM_GALAHAD
+#include "galahad/glhd_public.h"
+#endif
+
+static INLINE struct pipe_screen *
+debug_screen_wrap(struct pipe_screen *screen)
+{
+
+#if defined(GALLIUM_RBUG)
+   screen = rbug_screen_create(screen);
+#endif
+
+#if defined(GALLIUM_TRACE)
+   screen = trace_screen_create(screen);
+#endif
+
+#if defined(GALLIUM_GALAHAD)
+   screen = galahad_screen_create(screen);
+#endif
+
+   return screen;
+}
+
+#endif
diff --git a/src/gallium/auxiliary/target-helpers/inline_sw_helper.h b/src/gallium/auxiliary/target-helpers/inline_sw_helper.h
new file mode 100644 (file)
index 0000000..036c1ee
--- /dev/null
@@ -0,0 +1,63 @@
+
+#ifndef INLINE_SW_HELPER_H
+#define INLINE_SW_HELPER_H
+
+#include "pipe/p_compiler.h"
+#include "util/u_debug.h"
+#include "state_tracker/sw_winsys.h"
+
+
+/* Helper function to choose and instantiate one of the software rasterizers:
+ * cell, llvmpipe, softpipe.
+ */
+
+#ifdef GALLIUM_SOFTPIPE
+#include "softpipe/sp_public.h"
+#endif
+
+#ifdef GALLIUM_LLVMPIPE
+#include "llvmpipe/lp_public.h"
+#endif
+
+#ifdef GALLIUM_CELL
+#include "cell/ppu/cell_public.h"
+#endif
+
+static INLINE struct pipe_screen *
+sw_screen_create(struct sw_winsys *winsys)
+{
+   const char *default_driver;
+   const char *driver;
+   struct pipe_screen *screen = NULL;
+
+#if defined(GALLIUM_CELL)
+   default_driver = "cell";
+#elif defined(GALLIUM_LLVMPIPE)
+   default_driver = "llvmpipe";
+#elif defined(GALLIUM_SOFTPIPE)
+   default_driver = "softpipe";
+#else
+   default_driver = "";
+#endif
+
+   driver = debug_get_option("GALLIUM_DRIVER", default_driver);
+
+#if defined(GALLIUM_CELL)
+   if (screen == NULL && strcmp(driver, "cell") == 0)
+      screen = cell_create_screen(winsys);
+#endif
+
+#if defined(GALLIUM_LLVMPIPE)
+   if (screen == NULL && strcmp(driver, "llvmpipe") == 0)
+      screen = llvmpipe_create_screen(winsys);
+#endif
+
+#if defined(GALLIUM_SOFTPIPE)
+   if (screen == NULL)
+      screen = softpipe_create_screen(winsys);
+#endif
+
+   return screen;
+}
+
+#endif
diff --git a/src/gallium/auxiliary/target-helpers/inline_wrapper_sw_helper.h b/src/gallium/auxiliary/target-helpers/inline_wrapper_sw_helper.h
new file mode 100644 (file)
index 0000000..0b4e740
--- /dev/null
@@ -0,0 +1,34 @@
+
+#ifndef INLINE_WRAPPER_SW_HELPER_H
+#define INLINE_WRAPPER_SW_HELPER_H
+
+#include "target-helpers/inline_sw_helper.h"
+#include "sw/wrapper/wrapper_sw_winsys.h"
+
+/**
+ * Try to wrap a hw screen with a software screen.
+ * On failure will return given screen.
+ */
+static INLINE struct pipe_screen *
+sw_screen_wrap(struct pipe_screen *screen)
+{
+   struct sw_winsys *sws;
+   struct pipe_screen *sw_screen;
+
+   sws = wrapper_sw_winsys_warp_pipe_screen(screen);
+   if (!sws)
+      goto err;
+
+   sw_screen = sw_screen_create(sws);
+   if (sw_screen == screen)
+      goto err_winsys;
+
+   return sw_screen;
+
+err_winsys:
+   sws->destroy(sws);
+err:
+  return screen;
+}
+
+#endif
index 9fcc28f4c96a20c0410e6f26f1dcb571c831af73..f71ffb70308562ae0fb67de6a227deb3b96d9e2e 100644 (file)
@@ -176,7 +176,11 @@ static const char *primitive_names[] =
    "TRIANGLE_FAN",
    "QUADS",
    "QUAD_STRIP",
-   "POLYGON"
+   "POLYGON",
+   "LINES_ADJACENCY",
+   "LINE_STRIP_ADJACENCY",
+   "TRIANGLES_ADJACENCY",
+   "TRIANGLE_STRIP_ADJACENCY"
 };
 
 static const char *fs_coord_origin_names[] =
index ced9c94f46887f281b212c42f2833dcc8ee324cb..90198a4f6049a6f265da80648b84c9865f086087 100644 (file)
@@ -109,6 +109,19 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
                      info->input_usage_mask[ind] |= usage_mask;
                   }
                }
+
+               /* check for indirect register reads */
+               if (src->Register.Indirect) {
+                  info->indirect_files |= (1 << src->Register.File);
+               }
+            }
+
+            /* check for indirect register writes */
+            for (i = 0; i < fullinst->Instruction.NumDstRegs; i++) {
+               const struct tgsi_full_dst_register *dst = &fullinst->Dst[i];
+               if (dst->Register.Indirect) {
+                  info->indirect_files |= (1 << dst->Register.File);
+               }
             }
 
             info->num_instructions++;
index e75280336f0d4f987413d23d80f429fb7bc8933a..f8aa90cf065095cbbde51601fc30cab11870793b 100644 (file)
@@ -63,6 +63,12 @@ struct tgsi_shader_info
    boolean writes_edgeflag; /**< vertex shader outputs edgeflag */
    boolean uses_kill;  /**< KIL or KILP instruction used? */
 
+   /**
+    * Bitmask indicating which register files are accessed with
+    * indirect addressing.  The bits are (1 << TGSI_FILE_x), etc.
+    */
+   unsigned indirect_files;
+
    struct {
       unsigned name;
       unsigned data[8];
index 55fccba4d8c5b45e02b3af24b493cf264f1d6956..b01d2ff4689b850028e8611abb007f14227f84da 100644 (file)
@@ -58,7 +58,7 @@ static boolean is_digit_alpha_underscore( const char *cur )
 static char uprcase( char c )
 {
    if (c >= 'a' && c <= 'z')
-      return c += 'A' - 'a';
+      return c + 'A' - 'a';
    return c;
 }
 
@@ -732,7 +732,7 @@ parse_optional_swizzle(
          else if (uprcase( *cur ) == 'W')
             swizzle[i] = TGSI_SWIZZLE_W;
          else {
-           report_error( ctx, "Expected register swizzle component `x', `y', `z', `w', `0' or `1'" );
+           report_error( ctx, "Expected register swizzle component `x', `y', `z' or `w'" );
            return FALSE;
          }
          cur++;
index dfe2101c2e5c1cfdc94f2c01bf9827134b95b090..0d94aaae95601b7f035724169ab751474bcdd86b 100644 (file)
@@ -52,9 +52,8 @@
 
 struct blitter_context_priv
 {
-   struct blitter_context blitter;
+   struct blitter_context base;
 
-   struct pipe_context *pipe; /**< pipe context */
    struct pipe_resource *vbuf;  /**< quad */
 
    float vertices[4][2][4];   /**< {pos, color} or {pos, texcoord} */
@@ -97,15 +96,25 @@ struct blitter_context_priv
    /* Rasterizer state. */
    void *rs_state;
 
-   struct pipe_sampler_view *sampler_view;
-
    /* Viewport state. */
    struct pipe_viewport_state viewport;
 
    /* Clip state. */
    struct pipe_clip_state clip;
+
+   /* Destination surface dimensions. */
+   unsigned dst_width;
+   unsigned dst_height;
 };
 
+static void blitter_draw_rectangle(struct blitter_context *blitter,
+                                   unsigned x, unsigned y,
+                                   unsigned width, unsigned height,
+                                   float depth,
+                                   enum blitter_attrib_type type,
+                                   const float attrib[4]);
+
+
 struct blitter_context *util_blitter_create(struct pipe_context *pipe)
 {
    struct blitter_context_priv *ctx;
@@ -120,19 +129,20 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
    if (!ctx)
       return NULL;
 
-   ctx->pipe = pipe;
+   ctx->base.pipe = pipe;
+   ctx->base.draw_rectangle = blitter_draw_rectangle;
 
    /* init state objects for them to be considered invalid */
-   ctx->blitter.saved_blend_state = INVALID_PTR;
-   ctx->blitter.saved_dsa_state = INVALID_PTR;
-   ctx->blitter.saved_rs_state = INVALID_PTR;
-   ctx->blitter.saved_fs = INVALID_PTR;
-   ctx->blitter.saved_vs = INVALID_PTR;
-   ctx->blitter.saved_velem_state = INVALID_PTR;
-   ctx->blitter.saved_fb_state.nr_cbufs = ~0;
-   ctx->blitter.saved_num_sampler_views = ~0;
-   ctx->blitter.saved_num_sampler_states = ~0;
-   ctx->blitter.saved_num_vertex_buffers = ~0;
+   ctx->base.saved_blend_state = INVALID_PTR;
+   ctx->base.saved_dsa_state = INVALID_PTR;
+   ctx->base.saved_rs_state = INVALID_PTR;
+   ctx->base.saved_fs = INVALID_PTR;
+   ctx->base.saved_vs = INVALID_PTR;
+   ctx->base.saved_velem_state = INVALID_PTR;
+   ctx->base.saved_fb_state.nr_cbufs = ~0;
+   ctx->base.saved_num_sampler_views = ~0;
+   ctx->base.saved_num_sampler_states = ~0;
+   ctx->base.saved_num_vertex_buffers = ~0;
 
    /* blend state objects */
    memset(&blend, 0, sizeof(blend));
@@ -219,17 +229,17 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
       ctx->vertices[i][0][3] = 1; /*v.w*/
 
    /* create the vertex buffer */
-   ctx->vbuf = pipe_buffer_create(ctx->pipe->screen,
+   ctx->vbuf = pipe_buffer_create(ctx->base.pipe->screen,
                                   PIPE_BIND_VERTEX_BUFFER,
                                   sizeof(ctx->vertices));
 
-   return &ctx->blitter;
+   return &ctx->base;
 }
 
 void util_blitter_destroy(struct blitter_context *blitter)
 {
    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
-   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_context *pipe = blitter->pipe;
    int i;
 
    pipe->delete_blend_state(pipe, ctx->blend_write_color);
@@ -260,10 +270,6 @@ void util_blitter_destroy(struct blitter_context *blitter)
       if (ctx->sampler_state[i])
          pipe->delete_sampler_state(pipe, ctx->sampler_state[i]);
 
-   if (ctx->sampler_view) {
-      pipe_sampler_view_reference(&ctx->sampler_view, NULL);
-   }
-
    pipe_resource_reference(&ctx->vbuf, NULL);
    FREE(ctx);
 }
@@ -271,112 +277,117 @@ void util_blitter_destroy(struct blitter_context *blitter)
 static void blitter_check_saved_CSOs(struct blitter_context_priv *ctx)
 {
    /* make sure these CSOs have been saved */
-   assert(ctx->blitter.saved_blend_state != INVALID_PTR &&
-          ctx->blitter.saved_dsa_state != INVALID_PTR &&
-          ctx->blitter.saved_rs_state != INVALID_PTR &&
-          ctx->blitter.saved_fs != INVALID_PTR &&
-          ctx->blitter.saved_vs != INVALID_PTR &&
-          ctx->blitter.saved_velem_state != INVALID_PTR);
+   assert(ctx->base.saved_blend_state != INVALID_PTR &&
+          ctx->base.saved_dsa_state != INVALID_PTR &&
+          ctx->base.saved_rs_state != INVALID_PTR &&
+          ctx->base.saved_fs != INVALID_PTR &&
+          ctx->base.saved_vs != INVALID_PTR &&
+          ctx->base.saved_velem_state != INVALID_PTR);
 }
 
 static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
 {
-   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_context *pipe = ctx->base.pipe;
    unsigned i;
 
    /* restore the state objects which are always required to be saved */
-   pipe->bind_blend_state(pipe, ctx->blitter.saved_blend_state);
-   pipe->bind_depth_stencil_alpha_state(pipe, ctx->blitter.saved_dsa_state);
-   pipe->bind_rasterizer_state(pipe, ctx->blitter.saved_rs_state);
-   pipe->bind_fs_state(pipe, ctx->blitter.saved_fs);
-   pipe->bind_vs_state(pipe, ctx->blitter.saved_vs);
-   pipe->bind_vertex_elements_state(pipe, ctx->blitter.saved_velem_state);
+   pipe->bind_blend_state(pipe, ctx->base.saved_blend_state);
+   pipe->bind_depth_stencil_alpha_state(pipe, ctx->base.saved_dsa_state);
+   pipe->bind_rasterizer_state(pipe, ctx->base.saved_rs_state);
+   pipe->bind_fs_state(pipe, ctx->base.saved_fs);
+   pipe->bind_vs_state(pipe, ctx->base.saved_vs);
+   pipe->bind_vertex_elements_state(pipe, ctx->base.saved_velem_state);
 
-   ctx->blitter.saved_blend_state = INVALID_PTR;
-   ctx->blitter.saved_dsa_state = INVALID_PTR;
-   ctx->blitter.saved_rs_state = INVALID_PTR;
-   ctx->blitter.saved_fs = INVALID_PTR;
-   ctx->blitter.saved_vs = INVALID_PTR;
-   ctx->blitter.saved_velem_state = INVALID_PTR;
+   ctx->base.saved_blend_state = INVALID_PTR;
+   ctx->base.saved_dsa_state = INVALID_PTR;
+   ctx->base.saved_rs_state = INVALID_PTR;
+   ctx->base.saved_fs = INVALID_PTR;
+   ctx->base.saved_vs = INVALID_PTR;
+   ctx->base.saved_velem_state = INVALID_PTR;
 
-   pipe->set_stencil_ref(pipe, &ctx->blitter.saved_stencil_ref);
+   pipe->set_stencil_ref(pipe, &ctx->base.saved_stencil_ref);
 
-   pipe->set_viewport_state(pipe, &ctx->blitter.saved_viewport);
-   pipe->set_clip_state(pipe, &ctx->blitter.saved_clip);
+   pipe->set_viewport_state(pipe, &ctx->base.saved_viewport);
+   pipe->set_clip_state(pipe, &ctx->base.saved_clip);
 
    /* restore the state objects which are required to be saved before copy/fill
     */
-   if (ctx->blitter.saved_fb_state.nr_cbufs != ~0) {
-      pipe->set_framebuffer_state(pipe, &ctx->blitter.saved_fb_state);
-      ctx->blitter.saved_fb_state.nr_cbufs = ~0;
+   if (ctx->base.saved_fb_state.nr_cbufs != ~0) {
+      pipe->set_framebuffer_state(pipe, &ctx->base.saved_fb_state);
+      util_assign_framebuffer_state(&ctx->base.saved_fb_state, NULL);
+      ctx->base.saved_fb_state.nr_cbufs = ~0;
    }
 
-   if (ctx->blitter.saved_num_sampler_states != ~0) {
+   if (ctx->base.saved_num_sampler_states != ~0) {
       pipe->bind_fragment_sampler_states(pipe,
-                                         ctx->blitter.saved_num_sampler_states,
-                                         ctx->blitter.saved_sampler_states);
-      ctx->blitter.saved_num_sampler_states = ~0;
+                                         ctx->base.saved_num_sampler_states,
+                                         ctx->base.saved_sampler_states);
+      ctx->base.saved_num_sampler_states = ~0;
    }
 
-   if (ctx->blitter.saved_num_sampler_views != ~0) {
+   if (ctx->base.saved_num_sampler_views != ~0) {
       pipe->set_fragment_sampler_views(pipe,
-                                       ctx->blitter.saved_num_sampler_views,
-                                       ctx->blitter.saved_sampler_views);
-      ctx->blitter.saved_num_sampler_views = ~0;
+                                       ctx->base.saved_num_sampler_views,
+                                       ctx->base.saved_sampler_views);
+
+      for (i = 0; i < ctx->base.saved_num_sampler_views; i++)
+         pipe_sampler_view_reference(&ctx->base.saved_sampler_views[i],
+                                     NULL);
+
+      ctx->base.saved_num_sampler_views = ~0;
    }
 
-   if (ctx->blitter.saved_num_vertex_buffers != ~0) {
+   if (ctx->base.saved_num_vertex_buffers != ~0) {
       pipe->set_vertex_buffers(pipe,
-                               ctx->blitter.saved_num_vertex_buffers,
-                               ctx->blitter.saved_vertex_buffers);
+                               ctx->base.saved_num_vertex_buffers,
+                               ctx->base.saved_vertex_buffers);
 
-      for (i = 0; i < ctx->blitter.saved_num_vertex_buffers; i++) {
-         if (ctx->blitter.saved_vertex_buffers[i].buffer) {
-            pipe_resource_reference(&ctx->blitter.saved_vertex_buffers[i].buffer,
+      for (i = 0; i < ctx->base.saved_num_vertex_buffers; i++) {
+         if (ctx->base.saved_vertex_buffers[i].buffer) {
+            pipe_resource_reference(&ctx->base.saved_vertex_buffers[i].buffer,
                                     NULL);
          }
       }
-      ctx->blitter.saved_num_vertex_buffers = ~0;
+      ctx->base.saved_num_vertex_buffers = ~0;
    }
 }
 
 static void blitter_set_rectangle(struct blitter_context_priv *ctx,
                                   unsigned x1, unsigned y1,
                                   unsigned x2, unsigned y2,
-                                  unsigned width, unsigned height,
                                   float depth)
 {
    int i;
 
    /* set vertex positions */
-   ctx->vertices[0][0][0] = (float)x1 / width * 2.0f - 1.0f; /*v0.x*/
-   ctx->vertices[0][0][1] = (float)y1 / height * 2.0f - 1.0f; /*v0.y*/
+   ctx->vertices[0][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v0.x*/
+   ctx->vertices[0][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v0.y*/
 
-   ctx->vertices[1][0][0] = (float)x2 / width * 2.0f - 1.0f; /*v1.x*/
-   ctx->vertices[1][0][1] = (float)y1 / height * 2.0f - 1.0f; /*v1.y*/
+   ctx->vertices[1][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v1.x*/
+   ctx->vertices[1][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v1.y*/
 
-   ctx->vertices[2][0][0] = (float)x2 / width * 2.0f - 1.0f; /*v2.x*/
-   ctx->vertices[2][0][1] = (float)y2 / height * 2.0f - 1.0f; /*v2.y*/
+   ctx->vertices[2][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v2.x*/
+   ctx->vertices[2][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v2.y*/
 
-   ctx->vertices[3][0][0] = (float)x1 / width * 2.0f - 1.0f; /*v3.x*/
-   ctx->vertices[3][0][1] = (float)y2 / height * 2.0f - 1.0f; /*v3.y*/
+   ctx->vertices[3][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v3.x*/
+   ctx->vertices[3][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v3.y*/
 
    for (i = 0; i < 4; i++)
       ctx->vertices[i][0][2] = depth; /*z*/
 
    /* viewport */
-   ctx->viewport.scale[0] = 0.5f * width;
-   ctx->viewport.scale[1] = 0.5f * height;
+   ctx->viewport.scale[0] = 0.5f * ctx->dst_width;
+   ctx->viewport.scale[1] = 0.5f * ctx->dst_height;
    ctx->viewport.scale[2] = 1.0f;
    ctx->viewport.scale[3] = 1.0f;
-   ctx->viewport.translate[0] = 0.5f * width;
-   ctx->viewport.translate[1] = 0.5f * height;
+   ctx->viewport.translate[0] = 0.5f * ctx->dst_width;
+   ctx->viewport.translate[1] = 0.5f * ctx->dst_height;
    ctx->viewport.translate[2] = 0.0f;
    ctx->viewport.translate[3] = 0.0f;
-   ctx->pipe->set_viewport_state(ctx->pipe, &ctx->viewport);
+   ctx->base.pipe->set_viewport_state(ctx->base.pipe, &ctx->viewport);
 
    /* clip */
-   ctx->pipe->set_clip_state(ctx->pipe, &ctx->clip);
+   ctx->base.pipe->set_clip_state(ctx->base.pipe, &ctx->clip);
 }
 
 static void blitter_set_clear_color(struct blitter_context_priv *ctx,
@@ -401,29 +412,45 @@ static void blitter_set_clear_color(struct blitter_context_priv *ctx,
    }
 }
 
+static void get_normalized_texcoords(struct pipe_resource *src,
+                                     struct pipe_subresource subsrc,
+                                     unsigned x1, unsigned y1,
+                                     unsigned x2, unsigned y2,
+                                     float out[4])
+{
+   out[0] = x1 / (float)u_minify(src->width0,  subsrc.level);
+   out[1] = y1 / (float)u_minify(src->height0, subsrc.level);
+   out[2] = x2 / (float)u_minify(src->width0,  subsrc.level);
+   out[3] = y2 / (float)u_minify(src->height0, subsrc.level);
+}
+
+static void set_texcoords_in_vertices(const float coord[4],
+                                      float *out, unsigned stride)
+{
+   out[0] = coord[0]; /*t0.s*/
+   out[1] = coord[1]; /*t0.t*/
+   out += stride;
+   out[0] = coord[2]; /*t1.s*/
+   out[1] = coord[1]; /*t1.t*/
+   out += stride;
+   out[0] = coord[2]; /*t2.s*/
+   out[1] = coord[3]; /*t2.t*/
+   out += stride;
+   out[0] = coord[0]; /*t3.s*/
+   out[1] = coord[3]; /*t3.t*/
+}
+
 static void blitter_set_texcoords_2d(struct blitter_context_priv *ctx,
                                      struct pipe_resource *src,
                                      struct pipe_subresource subsrc,
                                      unsigned x1, unsigned y1,
                                      unsigned x2, unsigned y2)
 {
-   int i;
-   float s1 = x1 / (float)u_minify(src->width0,  subsrc.level);
-   float t1 = y1 / (float)u_minify(src->height0, subsrc.level);
-   float s2 = x2 / (float)u_minify(src->width0,  subsrc.level);
-   float t2 = y2 / (float)u_minify(src->height0, subsrc.level);
-
-   ctx->vertices[0][1][0] = s1; /*t0.s*/
-   ctx->vertices[0][1][1] = t1; /*t0.t*/
-
-   ctx->vertices[1][1][0] = s2; /*t1.s*/
-   ctx->vertices[1][1][1] = t1; /*t1.t*/
-
-   ctx->vertices[2][1][0] = s2; /*t2.s*/
-   ctx->vertices[2][1][1] = t2; /*t2.t*/
+   unsigned i;
+   float coord[4];
 
-   ctx->vertices[3][1][0] = s1; /*t3.s*/
-   ctx->vertices[3][1][1] = t2; /*t3.t*/
+   get_normalized_texcoords(src, subsrc, x1, y1, x2, y2, coord);
+   set_texcoords_in_vertices(coord, &ctx->vertices[0][1][0], 8);
 
    for (i = 0; i < 4; i++) {
       ctx->vertices[i][1][2] = 0; /*r*/
@@ -454,20 +481,11 @@ static void blitter_set_texcoords_cube(struct blitter_context_priv *ctx,
                                        unsigned x2, unsigned y2)
 {
    int i;
-   float s1 = x1 / (float)u_minify(src->width0,  subsrc.level);
-   float t1 = y1 / (float)u_minify(src->height0, subsrc.level);
-   float s2 = x2 / (float)u_minify(src->width0,  subsrc.level);
-   float t2 = y2 / (float)u_minify(src->height0, subsrc.level);
+   float coord[4];
    float st[4][2];
 
-   st[0][0] = s1;
-   st[0][1] = t1;
-   st[1][0] = s2;
-   st[1][1] = t1;
-   st[2][0] = s2;
-   st[2][1] = t2;
-   st[3][0] = s1;
-   st[3][1] = t2;
+   get_normalized_texcoords(src, subsrc, x1, y1, x2, y2, coord);
+   set_texcoords_in_vertices(coord, &st[0][0], 2);
 
    util_map_texcoords2d_onto_cubemap(subsrc.face,
                                      /* pointer, stride in floats */
@@ -478,9 +496,16 @@ static void blitter_set_texcoords_cube(struct blitter_context_priv *ctx,
       ctx->vertices[i][1][3] = 1; /*q*/
 }
 
+static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx,
+                                       unsigned width, unsigned height)
+{
+   ctx->dst_width = width;
+   ctx->dst_height = height;
+}
+
 static void blitter_draw_quad(struct blitter_context_priv *ctx)
 {
-   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_context *pipe = ctx->base.pipe;
 
    /* write vertices and draw them */
    pipe_buffer_write(pipe, ctx->vbuf,
@@ -495,7 +520,7 @@ static INLINE
 void **blitter_get_sampler_state(struct blitter_context_priv *ctx,
                                  int miplevel)
 {
-   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_context *pipe = ctx->base.pipe;
    struct pipe_sampler_state *sampler_state = &ctx->template_sampler_state;
 
    assert(miplevel < PIPE_MAX_TEXTURE_LEVELS);
@@ -518,7 +543,7 @@ void **blitter_get_sampler_state(struct blitter_context_priv *ctx,
 static INLINE
 void *blitter_get_fs_col(struct blitter_context_priv *ctx, unsigned num_cbufs)
 {
-   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_context *pipe = ctx->base.pipe;
 
    assert(num_cbufs <= PIPE_MAX_COLOR_BUFS);
 
@@ -531,7 +556,7 @@ void *blitter_get_fs_col(struct blitter_context_priv *ctx, unsigned num_cbufs)
 
 /** Convert PIPE_TEXTURE_x to TGSI_TEXTURE_x */
 static unsigned
-pipe_tex_to_tgsi_tex(unsigned pipe_tex_target)
+pipe_tex_to_tgsi_tex(enum pipe_texture_target pipe_tex_target)
 {
    switch (pipe_tex_target) {
    case PIPE_TEXTURE_1D:
@@ -553,7 +578,7 @@ static INLINE
 void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
                                   unsigned tex_target)
 {
-   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_context *pipe = ctx->base.pipe;
 
    assert(tex_target < PIPE_MAX_TEXTURE_TYPES);
 
@@ -572,7 +597,7 @@ static INLINE
 void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx,
                                     unsigned tex_target)
 {
-   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_context *pipe = ctx->base.pipe;
 
    assert(tex_target < PIPE_MAX_TEXTURE_TYPES);
 
@@ -588,6 +613,31 @@ void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx,
    return ctx->fs_texfetch_depth[tex_target];
 }
 
+static void blitter_draw_rectangle(struct blitter_context *blitter,
+                                   unsigned x1, unsigned y1,
+                                   unsigned x2, unsigned y2,
+                                   float depth,
+                                   enum blitter_attrib_type type,
+                                   const float attrib[4])
+{
+   struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
+
+   switch (type) {
+      case UTIL_BLITTER_ATTRIB_COLOR:
+         blitter_set_clear_color(ctx, attrib);
+         break;
+
+      case UTIL_BLITTER_ATTRIB_TEXCOORD:
+         set_texcoords_in_vertices(attrib, &ctx->vertices[0][1][0], 8);
+         break;
+
+      default:;
+   }
+
+   blitter_set_rectangle(ctx, x1, y1, x2, y2, depth);
+   blitter_draw_quad(ctx);
+}
+
 void util_blitter_clear(struct blitter_context *blitter,
                         unsigned width, unsigned height,
                         unsigned num_cbufs,
@@ -596,7 +646,7 @@ void util_blitter_clear(struct blitter_context *blitter,
                         double depth, unsigned stencil)
 {
    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
-   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_context *pipe = ctx->base.pipe;
    struct pipe_stencil_ref sr = { { 0 } };
 
    assert(num_cbufs <= PIPE_MAX_COLOR_BUFS);
@@ -630,9 +680,9 @@ void util_blitter_clear(struct blitter_context *blitter,
    pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, num_cbufs));
    pipe->bind_vs_state(pipe, ctx->vs_col);
 
-   blitter_set_clear_color(ctx, rgba);
-   blitter_set_rectangle(ctx, 0, 0, width, height, width, height, depth);
-   blitter_draw_quad(ctx);
+   blitter_set_dst_dimensions(ctx, width, height);
+   blitter->draw_rectangle(blitter, 0, 0, width, height, depth,
+                           UTIL_BLITTER_ATTRIB_COLOR, rgba);
    blitter_restore_CSOs(ctx);
 }
 
@@ -654,7 +704,7 @@ void util_blitter_copy_region(struct blitter_context *blitter,
                               boolean ignore_stencil)
 {
    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
-   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_context *pipe = ctx->base.pipe;
    struct pipe_screen *screen = pipe->screen;
    struct pipe_surface *dstsurf;
    struct pipe_framebuffer_state fb_state;
@@ -736,11 +786,6 @@ void util_blitter_copy_region(struct blitter_context *blitter,
    u_sampler_view_default_template(&viewTempl, src, src->format);
    view = pipe->create_sampler_view(pipe, src, &viewTempl);
 
-   if (ctx->sampler_view) {
-      pipe_sampler_view_reference(&ctx->sampler_view, NULL);
-   }
-   ctx->sampler_view = view;
-
    /* Set rasterizer state, shaders, and textures. */
    pipe->bind_rasterizer_state(pipe, ctx->rs_state);
    pipe->bind_vs_state(pipe, ctx->vs_tex);
@@ -750,32 +795,49 @@ void util_blitter_copy_region(struct blitter_context *blitter,
    pipe->set_fragment_sampler_views(pipe, 1, &view);
    pipe->set_framebuffer_state(pipe, &fb_state);
 
-   /* Set texture coordinates. */
+   blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
+
    switch (src->target) {
+      /* Draw the quad with the draw_rectangle callback. */
       case PIPE_TEXTURE_1D:
       case PIPE_TEXTURE_2D:
-         blitter_set_texcoords_2d(ctx, src, subsrc,
-                                  srcx, srcy, srcx+width, srcy+height);
+         {
+            /* Set texture coordinates. */
+            float coord[4];
+            get_normalized_texcoords(src, subsrc, srcx, srcy,
+                                     srcx+width, srcy+height, coord);
+
+            /* Draw. */
+            blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0,
+                                    UTIL_BLITTER_ATTRIB_TEXCOORD, coord);
+         }
          break;
+
+      /* Draw the quad with the generic codepath. */
       case PIPE_TEXTURE_3D:
-         blitter_set_texcoords_3d(ctx, src, subsrc, srcz,
-                                  srcx, srcy, srcx+width, srcy+height);
-         break;
       case PIPE_TEXTURE_CUBE:
-         blitter_set_texcoords_cube(ctx, src, subsrc,
-                                    srcx, srcy, srcx+width, srcy+height);
+         /* Set texture coordinates. */
+         if (src->target == PIPE_TEXTURE_3D)
+            blitter_set_texcoords_3d(ctx, src, subsrc, srcz,
+                                     srcx, srcy, srcx+width, srcy+height);
+         else
+            blitter_set_texcoords_cube(ctx, src, subsrc,
+                                       srcx, srcy, srcx+width, srcy+height);
+
+         /* Draw. */
+         blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, 0);
+         blitter_draw_quad(ctx);
          break;
+
       default:
          assert(0);
          return;
    }
 
-   blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height,
-                         dstsurf->width, dstsurf->height, 0);
-   blitter_draw_quad(ctx);
    blitter_restore_CSOs(ctx);
 
    pipe_surface_reference(&dstsurf, NULL);
+   pipe_sampler_view_reference(&view, NULL);
 }
 
 /* Clear a region of a color surface to a constant value. */
@@ -786,7 +848,7 @@ void util_blitter_clear_render_target(struct blitter_context *blitter,
                                       unsigned width, unsigned height)
 {
    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
-   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_context *pipe = ctx->base.pipe;
    struct pipe_framebuffer_state fb_state;
 
    assert(dstsurf->texture);
@@ -813,9 +875,9 @@ void util_blitter_clear_render_target(struct blitter_context *blitter,
    fb_state.zsbuf = 0;
    pipe->set_framebuffer_state(pipe, &fb_state);
 
-   blitter_set_clear_color(ctx, rgba);
-   blitter_set_rectangle(ctx, 0, 0, width, height, dstsurf->width, dstsurf->height, 0);
-   blitter_draw_quad(ctx);
+   blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
+   blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0,
+                           UTIL_BLITTER_ATTRIB_COLOR, rgba);
    blitter_restore_CSOs(ctx);
 }
 
@@ -829,7 +891,7 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
                                       unsigned width, unsigned height)
 {
    struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
-   struct pipe_context *pipe = ctx->pipe;
+   struct pipe_context *pipe = ctx->base.pipe;
    struct pipe_framebuffer_state fb_state;
    struct pipe_stencil_ref sr = { { 0 } };
 
@@ -873,7 +935,8 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
    fb_state.zsbuf = dstsurf;
    pipe->set_framebuffer_state(pipe, &fb_state);
 
-   blitter_set_rectangle(ctx, 0, 0, width, height, dstsurf->width, dstsurf->height, depth);
-   blitter_draw_quad(ctx);
+   blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
+   blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, depth,
+                           UTIL_BLITTER_ATTRIB_NONE, NULL);
    blitter_restore_CSOs(ctx);
 }
index 22849280ab9be272b6ddf135932fa57317182df4..ba3f92eca8584a326328928cce8f6a47c95f4ec4 100644 (file)
@@ -39,9 +39,48 @@ extern "C" {
 
 struct pipe_context;
 
+enum blitter_attrib_type {
+   UTIL_BLITTER_ATTRIB_NONE,
+   UTIL_BLITTER_ATTRIB_COLOR,
+   UTIL_BLITTER_ATTRIB_TEXCOORD
+};
+
 struct blitter_context
 {
+   /**
+    * Draw a rectangle.
+    *
+    * \param x1      An X coordinate of the top-left corner.
+    * \param y1      A Y coordinate of the top-left corner.
+    * \param x2      An X coordinate of the bottom-right corner.
+    * \param y2      A Y coordinate of the bottom-right corner.
+    * \param depth  A depth which the rectangle is rendered at.
+    *
+    * \param type   Semantics of the attributes "attrib".
+    *               If type is UTIL_BLITTER_ATTRIB_NONE, ignore them.
+    *               If type is UTIL_BLITTER_ATTRIB_COLOR, the attributes
+    *               make up a constant RGBA color, and should go to the COLOR0
+    *               varying slot of a fragment shader.
+    *               If type is UTIL_BLITTER_ATTRIB_TEXCOORD, {a1, a2} and
+    *               {a3, a4} specify top-left and bottom-right texture
+    *               coordinates of the rectangle, respectively, and should go
+    *               to the GENERIC0 varying slot of a fragment shader.
+    *
+    * \param attrib See type.
+    *
+    * \note A driver may optionally override this callback to implement
+    *       a specialized hardware path for drawing a rectangle, e.g. using
+    *       a rectangular point sprite.
+    */
+   void (*draw_rectangle)(struct blitter_context *blitter,
+                          unsigned x1, unsigned y1, unsigned x2, unsigned y2,
+                          float depth,
+                          enum blitter_attrib_type type,
+                          const float attrib[4]);
+
    /* Private members, really. */
+   struct pipe_context *pipe; /**< pipe context */
+
    void *saved_blend_state;   /**< blend state */
    void *saved_dsa_state;     /**< depth stencil alpha state */
    void *saved_velem_state;   /**< vertex elements state */
@@ -73,6 +112,15 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe);
  */
 void util_blitter_destroy(struct blitter_context *blitter);
 
+/**
+ * Return the pipe context associated with a blitter context.
+ */
+static INLINE
+struct pipe_context *util_blitter_get_pipe(struct blitter_context *blitter)
+{
+   return blitter->pipe;
+}
+
 /*
  * These CSOs must be saved before any of the following functions is called:
  * - blend state
@@ -208,11 +256,45 @@ void util_blitter_save_vertex_shader(struct blitter_context *blitter,
    blitter->saved_vs = vs;
 }
 
+/* XXX This should probably be moved elsewhere. */
+static INLINE
+void util_assign_framebuffer_state(struct pipe_framebuffer_state *dst,
+                                   const struct pipe_framebuffer_state *src)
+{
+   unsigned i;
+
+   if (src) {
+      /* Reference all surfaces. */
+      for (i = 0; i < src->nr_cbufs; i++) {
+         pipe_surface_reference(&dst->cbufs[i], src->cbufs[i]);
+      }
+      for (; i < dst->nr_cbufs; i++) {
+         pipe_surface_reference(&dst->cbufs[i], NULL);
+      }
+
+      pipe_surface_reference(&dst->zsbuf, src->zsbuf);
+
+      dst->nr_cbufs = src->nr_cbufs;
+      dst->width = src->width;
+      dst->height = src->height;
+   } else {
+      /* Set all surfaces to NULL. */
+      for (i = 0; i < dst->nr_cbufs; i++) {
+         pipe_surface_reference(&dst->cbufs[i], NULL);
+      }
+
+      pipe_surface_reference(&dst->zsbuf, NULL);
+
+      dst->nr_cbufs = 0;
+   }
+}
+
 static INLINE
 void util_blitter_save_framebuffer(struct blitter_context *blitter,
-                                   struct pipe_framebuffer_state *state)
+                                   const struct pipe_framebuffer_state *state)
 {
-   blitter->saved_fb_state = *state;
+   blitter->saved_fb_state.nr_cbufs = 0; /* It's ~0 now, meaning it's unsaved. */
+   util_assign_framebuffer_state(&blitter->saved_fb_state, state);
 }
 
 static INLINE
@@ -247,12 +329,13 @@ util_blitter_save_fragment_sampler_views(struct blitter_context *blitter,
                                          int num_views,
                                          struct pipe_sampler_view **views)
 {
+   unsigned i;
    assert(num_views <= Elements(blitter->saved_sampler_views));
 
    blitter->saved_num_sampler_views = num_views;
-   memcpy(blitter->saved_sampler_views,
-          views,
-          num_views * sizeof(struct pipe_sampler_view *));
+   for (i = 0; i < num_views; i++)
+      pipe_sampler_view_reference(&blitter->saved_sampler_views[i],
+                                  views[i]);
 }
 
 static INLINE void
index 294ee37033d65499df0a3bcd690450e340166561..94d5bd30278f0697624f27cc2bd067b6c6b1f004 100644 (file)
@@ -186,6 +186,22 @@ static unsigned caps_opengl_2_1[] = {
 /* OpenGL 3.0 */
 /* UTIL_CHECK_INT(MAX_RENDER_TARGETS, 8), */
 
+/* Shader Model 3 */
+static unsigned caps_sm3[] = {
+    UTIL_CHECK_INT(MAX_FS_INSTRUCTIONS, 512),
+    UTIL_CHECK_INT(MAX_FS_INPUTS, 10),
+    UTIL_CHECK_INT(MAX_FS_TEMPS, 32),
+    UTIL_CHECK_INT(MAX_FS_ADDRS, 1),
+    UTIL_CHECK_INT(MAX_FS_CONSTS, 224),
+
+    UTIL_CHECK_INT(MAX_VS_INSTRUCTIONS, 512),
+    UTIL_CHECK_INT(MAX_VS_INPUTS, 16),
+    UTIL_CHECK_INT(MAX_VS_TEMPS, 32),
+    UTIL_CHECK_INT(MAX_VS_ADDRS, 2),
+    UTIL_CHECK_INT(MAX_VS_CONSTS, 256),
+
+    UTIL_CHECK_TERMINATE
+};
 
 /**
  * Demo function which checks against theoretical caps needed for different APIs.
@@ -203,6 +219,7 @@ void util_caps_demo_print(struct pipe_screen *screen)
       {"DX 11", caps_dx_11},
       {"OpenGL 2.1", caps_opengl_2_1},
 /*    {"OpenGL 3.0", caps_opengl_3_0},*/
+      {"SM3", caps_sm3},
       {NULL, NULL}
    };
    int i, out = 0;
index a08241971ca1a95e56f186da9e057dffb8696df2..23d33af4e413d25d44d474ffe5398bf00f78f8fe 100644 (file)
@@ -38,7 +38,7 @@
 #include "u_cpu_detect.h"
 
 #if defined(PIPE_ARCH_PPC)
-#if defined(PIPE_OS_DARWIN)
+#if defined(PIPE_OS_APPLE)
 #include <sys/sysctl.h>
 #else
 #include <signal.h>
@@ -132,7 +132,7 @@ win32_sig_handler_sse(EXCEPTION_POINTERS* ep)
 #endif /* PIPE_ARCH_X86 */
 
 
-#if defined(PIPE_ARCH_PPC) && !defined(PIPE_OS_DARWIN)
+#if defined(PIPE_ARCH_PPC) && !defined(PIPE_OS_APPLE)
 static jmp_buf  __lv_powerpc_jmpbuf;
 static volatile sig_atomic_t __lv_powerpc_canjump = 0;
 
@@ -153,7 +153,7 @@ sigill_handler(int sig)
 static void
 check_os_altivec_support(void)
 {
-#if defined(PIPE_OS_DARWIN)
+#if defined(PIPE_OS_APPLE)
    int sels[2] = {CTL_HW, HW_VECTORUNIT};
    int has_vu = 0;
    int len = sizeof (has_vu);
@@ -166,8 +166,8 @@ check_os_altivec_support(void)
          util_cpu_caps.has_altivec = 1;
       }
    }
-#else /* !PIPE_OS_DARWIN */
-   /* no Darwin, do it the brute-force way */
+#else /* !PIPE_OS_APPLE */
+   /* not on Apple/Darwin, do it the brute-force way */
    /* this is borrowed from the libmpeg2 library */
    signal(SIGILL, sigill_handler);
    if (setjmp(__lv_powerpc_jmpbuf)) {
@@ -184,7 +184,7 @@ check_os_altivec_support(void)
       signal(SIGILL, SIG_DFL);
       util_cpu_caps.has_altivec = 1;
    }
-#endif /* PIPE_OS_DARWIN */
+#endif /* !PIPE_OS_APPLE */
 }
 #endif /* PIPE_ARCH_PPC */
 
index 5e373ff24c46581e880b4674b0c20fdcf6bc5689..ad162558bc149abcc3c36f2414a895ef7bea6ac4 100644 (file)
@@ -190,11 +190,11 @@ debug_get_flags_option(const char *name,
       result = dfault;
    else if (!util_strcmp(str, "help")) {
       result = dfault;
-      debug_printf("%s: help for %s:\n", __FUNCTION__, name);
+      _debug_printf("%s: help for %s:\n", __FUNCTION__, name);
       for (; flags->name; ++flags)
          namealign = MAX2(namealign, strlen(flags->name));
       for (flags = orig; flags->name; ++flags)
-         debug_printf("| %*s [0x%0*lx]%s%s\n", namealign, flags->name,
+         _debug_printf("| %*s [0x%0*lx]%s%s\n", namealign, flags->name,
                       (int)sizeof(unsigned long)*CHAR_BIT/4, flags->value,
                       flags->desc ? " " : "", flags->desc ? flags->desc : "");
    }
index 53bb1342ddcba9e1712e0d11f3f44ecd2c22d130..42adb1f069996ee8c989a1671edf2ce4638d00b8 100644 (file)
@@ -98,5 +98,20 @@ struct list_head
 #define LIST_IS_EMPTY(__list)                   \
     ((__list)->next == (__list))
 
-
+#ifndef container_of
+#define container_of(ptr, sample, member)                              \
+    (void *)((char *)(ptr)                                             \
+            - ((char *)&(sample)->member - (char *)(sample)))
+#endif
+
+#define LIST_FOR_EACH_ENTRY(pos, head, member)                         \
+   for (pos = container_of((head)->next, pos, member);                 \
+       &pos->member != (head);                                         \
+       pos = container_of(pos->member.next, pos, member))
+
+#define LIST_FOR_EACH_ENTRY_SAFE(pos, storage, head, member)   \
+   for (pos = container_of((head)->next, pos, member),                 \
+       storage = container_of(pos->member.next, pos, member);  \
+       &pos->member != (head);                                         \
+       pos = storage, storage = container_of(storage->member.next, storage, member))
 #endif /*_U_DOUBLE_LIST_H_*/
index 3168a1fab4807b9576834f9ccf39e132aa86d4c6..43d09f1960779965dbdfc9d233c63761c5ab00c4 100644 (file)
@@ -120,7 +120,7 @@ util_format_write_4ub(enum pipe_format format, const uint8_t *src, unsigned src_
 }
 
 
-static INLINE boolean
+boolean
 util_format_fits_8unorm(const struct util_format_description *format_desc)
 {
    unsigned chan;
index fd95bea1a7bf897f53cfe5a3c9c1adf8f844a414..38254b1096dfe7063ee19819f8567c8fa3c22e4d 100644 (file)
@@ -212,6 +212,16 @@ struct util_format_description
                        const uint8_t *src, unsigned src_stride,
                        unsigned width, unsigned height);
 
+   /**
+    * Fetch a single pixel (i, j) from a block.
+    *
+    * XXX: Only defined for a very few select formats.
+    */
+   void
+   (*fetch_rgba_8unorm)(uint8_t *dst,
+                        const uint8_t *src,
+                        unsigned i, unsigned j);
+
    /**
     * Unpack pixel blocks to R32G32B32A32_FLOAT.
     * Note: strides are in bytes.
@@ -663,6 +673,9 @@ util_format_write_4ub(enum pipe_format format,
  * Generic format conversion;
  */
 
+boolean
+util_format_fits_8unorm(const struct util_format_description *format_desc);
+
 void
 util_format_translate(enum pipe_format dst_format,
                       void *dst, unsigned dst_stride,
index ae9a59819736c42b0a4ce5862f177bac058eb96d..f0b407b8b8e3840664215e249fc66f5fe0040bd6 100755 (executable)
@@ -132,12 +132,17 @@ def write_format_table(formats):
         if format.colorspace != ZS:
             print "   &util_format_%s_unpack_rgba_8unorm," % format.short_name() 
             print "   &util_format_%s_pack_rgba_8unorm," % format.short_name() 
+            if format.layout == 's3tc':
+                print "   &util_format_%s_fetch_rgba_8unorm," % format.short_name()
+            else:
+                print "   NULL, /* fetch_rgba_8unorm */" 
             print "   &util_format_%s_unpack_rgba_float," % format.short_name() 
             print "   &util_format_%s_pack_rgba_float," % format.short_name() 
             print "   &util_format_%s_fetch_rgba_float," % format.short_name()
         else:
             print "   NULL, /* unpack_rgba_8unorm */" 
             print "   NULL, /* pack_rgba_8unorm */" 
+            print "   NULL, /* fetch_rgba_8unorm */" 
             print "   NULL, /* unpack_rgba_float */" 
             print "   NULL, /* pack_rgba_float */" 
             print "   NULL, /* fetch_rgba_float */" 
index 6370e77986502a8f6384c5e83a68a4045c0c04c9..fe19466436a089ef1fb04ef2ef6e819ad78dfe38 100644 (file)
@@ -567,12 +567,26 @@ util_bswap16(uint16_t n)
 #define MAX3( A, B, C ) MAX2( MAX2( A, B ), C )
 
 
+/**
+ * Align a value, only works pot alignemnts.
+ */
 static INLINE int
 align(int value, int alignment)
 {
    return (value + alignment - 1) & ~(alignment - 1);
 }
 
+/**
+ * Works like align but on npot alignments.
+ */
+static INLINE size_t
+util_align_npot(size_t value, size_t alignment)
+{
+   if (value % alignment)
+      return value + (alignment - (value % alignment));
+   return value;
+}
+
 static INLINE unsigned
 u_minify(unsigned value, unsigned levels)
 {
diff --git a/src/gallium/auxiliary/util/u_mempool.c b/src/gallium/auxiliary/util/u_mempool.c
new file mode 100644 (file)
index 0000000..1f336b3
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2010 Marek Olšák <maraeo@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "util/u_mempool.h"
+
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "util/u_simple_list.h"
+
+#include <stdio.h>
+
+#define UTIL_MEMPOOL_MAGIC 0xcafe4321
+
+/* The block is either allocated memory or free space. */
+struct util_mempool_block {
+   /* The header. */
+   /* The first next free block. */
+   struct util_mempool_block *next_free;
+
+   intptr_t magic;
+
+   /* Memory after the last member is dedicated to the block itself.
+    * The allocated size is always larger than this structure. */
+};
+
+static struct util_mempool_block *
+util_mempool_get_block(struct util_mempool *pool,
+                       struct util_mempool_page *page, unsigned index)
+{
+   return (struct util_mempool_block*)
+          ((uint8_t*)page + sizeof(struct util_mempool_page) +
+           (pool->block_size * index));
+}
+
+static void util_mempool_add_new_page(struct util_mempool *pool)
+{
+   struct util_mempool_page *page;
+   struct util_mempool_block *block;
+   int i;
+
+   page = MALLOC(pool->page_size);
+   insert_at_tail(&pool->list, page);
+
+   /* Mark all blocks as free. */
+   for (i = 0; i < pool->num_blocks-1; i++) {
+      block = util_mempool_get_block(pool, page, i);
+      block->next_free = util_mempool_get_block(pool, page, i+1);
+      block->magic = UTIL_MEMPOOL_MAGIC;
+   }
+
+   block = util_mempool_get_block(pool, page, pool->num_blocks-1);
+   block->next_free = pool->first_free;
+   block->magic = UTIL_MEMPOOL_MAGIC;
+   pool->first_free = util_mempool_get_block(pool, page, 0);
+   pool->num_pages++;
+
+#if 0
+   fprintf(stderr, "New page! Num of pages: %i\n", pool->num_pages);
+#endif
+}
+
+static void *util_mempool_malloc_st(struct util_mempool *pool)
+{
+   struct util_mempool_block *block;
+
+   if (!pool->first_free)
+      util_mempool_add_new_page(pool);
+
+   block = pool->first_free;
+   assert(block->magic == UTIL_MEMPOOL_MAGIC);
+   pool->first_free = block->next_free;
+
+   return (uint8_t*)block + sizeof(struct util_mempool_block);
+}
+
+static void util_mempool_free_st(struct util_mempool *pool, void *ptr)
+{
+   struct util_mempool_block *block =
+         (struct util_mempool_block*)
+         ((uint8_t*)ptr - sizeof(struct util_mempool_block));
+
+   assert(block->magic == UTIL_MEMPOOL_MAGIC);
+   block->next_free = pool->first_free;
+   pool->first_free = block;
+}
+
+static void *util_mempool_malloc_mt(struct util_mempool *pool)
+{
+   void *mem;
+
+   pipe_mutex_lock(pool->mutex);
+   mem = util_mempool_malloc_st(pool);
+   pipe_mutex_unlock(pool->mutex);
+   return mem;
+}
+
+static void util_mempool_free_mt(struct util_mempool *pool, void *ptr)
+{
+   pipe_mutex_lock(pool->mutex);
+   util_mempool_free_st(pool, ptr);
+   pipe_mutex_unlock(pool->mutex);
+}
+
+void util_mempool_set_thread_safety(struct util_mempool *pool,
+                                    enum util_mempool_threading threading)
+{
+   pool->threading = threading;
+
+   if (threading) {
+      pool->malloc = util_mempool_malloc_mt;
+      pool->free = util_mempool_free_mt;
+   } else {
+      pool->malloc = util_mempool_malloc_st;
+      pool->free = util_mempool_free_st;
+   }
+}
+
+void util_mempool_create(struct util_mempool *pool,
+                         unsigned item_size,
+                         unsigned num_blocks,
+                         enum util_mempool_threading threading)
+{
+   item_size = align(item_size, sizeof(intptr_t));
+
+   pool->num_pages = 0;
+   pool->num_blocks = num_blocks;
+   pool->block_size = sizeof(struct util_mempool_block) + item_size;
+   pool->block_size = align(pool->block_size, sizeof(intptr_t));
+   pool->page_size = sizeof(struct util_mempool_page) +
+                     num_blocks * pool->block_size;
+   pool->first_free = NULL;
+
+   make_empty_list(&pool->list);
+
+   pipe_mutex_init(pool->mutex);
+
+   util_mempool_set_thread_safety(pool, threading);
+}
+
+void util_mempool_destroy(struct util_mempool *pool)
+{
+   struct util_mempool_page *page, *temp;
+
+   foreach_s(page, temp, &pool->list) {
+      remove_from_list(page);
+      FREE(page);
+   }
+
+   pipe_mutex_destroy(pool->mutex);
+}
diff --git a/src/gallium/auxiliary/util/u_mempool.h b/src/gallium/auxiliary/util/u_mempool.h
new file mode 100644 (file)
index 0000000..a5b5d6a
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2010 Marek Olšák <maraeo@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) 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. */
+
+/**
+ * @file
+ * Simple memory pool for equally sized memory allocations.
+ * util_mempool_malloc and util_mempool_free are in O(1).
+ *
+ * Good for allocations which have very low lifetime and are allocated
+ * and freed very often. Use a profiler first!
+ *
+ * Candidates: get_transfer, user_buffer_create
+ *
+ * @author Marek Olšák
+ */
+
+#ifndef U_MEMPOOL_H
+#define U_MEMPOOL_H
+
+#include "os/os_thread.h"
+
+enum util_mempool_threading {
+   UTIL_MEMPOOL_SINGLETHREADED = FALSE,
+   UTIL_MEMPOOL_MULTITHREADED = TRUE
+};
+
+/* The page is an array of blocks (allocations). */
+struct util_mempool_page {
+   /* The header (linked-list pointers). */
+   struct util_mempool_page *prev, *next;
+
+   /* Memory after the last member is dedicated to the page itself.
+    * The allocated size is always larger than this structure. */
+};
+
+struct util_mempool {
+   /* Public members. */
+   void *(*malloc)(struct util_mempool *pool);
+   void (*free)(struct util_mempool *pool, void *ptr);
+
+   /* Private members. */
+   struct util_mempool_block *first_free;
+
+   struct util_mempool_page list;
+
+   unsigned block_size;
+   unsigned page_size;
+   unsigned num_blocks;
+   unsigned num_pages;
+   enum util_mempool_threading threading;
+
+   pipe_mutex mutex;
+};
+
+void util_mempool_create(struct util_mempool *pool,
+                         unsigned item_size,
+                         unsigned num_blocks,
+                         enum util_mempool_threading threading);
+
+void util_mempool_destroy(struct util_mempool *pool);
+
+void util_mempool_set_thread_safety(struct util_mempool *pool,
+                                    enum util_mempool_threading threading);
+
+#define util_mempool_malloc(pool)    (pool)->malloc(pool)
+#define util_mempool_free(pool, ptr) (pool)->free(pool, ptr)
+
+#endif
index 87ee0e476852485fc04263b18f6302146a9e3d49..77f2c5fc7de658623c501d93210bb50656610af1 100644 (file)
@@ -6,7 +6,7 @@
 #if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
 #  include <winsock2.h>
 #  include <windows.h>
-#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_APPLE)
+#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_CYGWIN)
 #  include <sys/socket.h>
 #  include <netinet/in.h>
 #  include <unistd.h>
index c74396284cce1dd8b4d57d9e60b693185e531a95..7bde10c124597e6b428cd76c5b5594b8e4c3c5c3 100644 (file)
@@ -14,21 +14,74 @@ in other modern and legacy drawing APIs.
 
 XXX blurb about dual-source blends
 
+Logical Operations
+------------------
+
+Logical operations, also known as logicops, lops, or rops, are supported.
+Only two-operand logicops are available. When logicops are enabled, all other
+blend state is ignored, including per-render-target state, so logicops are
+performed on all render targets.
+
+.. warning::
+   The blend_enable flag is ignored for all render targets when logical
+   operations are enabled.
+
+For a source component `s` and destination component `d`, the logical
+operations are defined as taking the bits of each channel of each component,
+and performing one of the following operations per-channel:
+
+* ``CLEAR``: 0
+* ``NOR``: :math:`\lnot(s \lor d)`
+* ``AND_INVERTED``: :math:`\lnot s \land d`
+* ``COPY_INVERTED``: :math:`\lnot s`
+* ``AND_REVERSE``: :math:`s \land \lnot d`
+* ``INVERT``: :math:`\lnot d`
+* ``XOR``: :math:`s \oplus d`
+* ``NAND``: :math:`\lnot(s \land d)`
+* ``AND``: :math:`s \land d`
+* ``EQUIV``: :math:`\lnot(s \oplus d)`
+* ``NOOP``: :math:`d`
+* ``OR_INVERTED``: :math:`\lnot s \lor d`
+* ``COPY``: :math:`s`
+* ``OR_REVERSE``: :math:`s \lor \lnot d`
+* ``OR``: :math:`s \lor d`
+* ``SET``: 1
+
+.. note::
+   The logical operation names and definitions match those of the OpenGL API,
+   and are similar to the ROP2 and ROP3 definitions of GDI. This is
+   intentional, to ease transitions to Gallium.
+
 Members
 -------
 
+These members affect all render targets.
+
+dither
+%%%%%%
+
+Whether dithering is enabled.
+
+.. note::
+   Dithering is completely implementation-dependent. It may be ignored by
+   drivers for any reason, and some render targets may always or never be
+   dithered depending on their format or usage flags.
+
+logicop_enable
+%%%%%%%%%%%%%%
+
+Whether the blender should perform a logicop instead of blending.
+
+logicop_func
+%%%%%%%%%%%%
+
+The logicop to use. One of ``PIPE_LOGICOP``.
+
 independent_blend_enable
    If enabled, blend state is different for each render target, and
    for each render target set in the respective member of the rt array.
    If disabled, blend state is the same for all render targets, and only
    the first member of the rt array contains valid data.
-logicop_enable
-   Enables logic ops. Cannot be enabled at the same time as blending, and
-   is always the same for all render targets.
-logicop_func
-   The logic operation to use if logic ops are enabled. One of PIPE_LOGICOP.
-dither
-   Whether dithering is enabled. Note: Dithering is implementation-dependent.
 rt
    Contains the per-rendertarget blend state.
 
index 92cde014fb8c8d726b374b174805ad5c1efda8bc..978ad4a2434da4807a230477987896a2cb0c663c 100644 (file)
@@ -3,9 +3,44 @@
 Vertex Elements
 ===============
 
-This state controls format etc. of the input attributes contained
-in the pipe_vertex_buffer(s). There's one pipe_vertex_element array member
-for each input attribute.
+This state controls the format of the input attributes contained in
+pipe_vertex_buffers. There is one pipe_vertex_element array member for each
+input attribute.
+
+Input Formats
+-------------
+
+Gallium supports a diverse range of formats for vertex data. Drivers are
+guaranteed to support 32-bit floating-point vectors of one to four components.
+Additionally, they may support the following formats:
+
+* Integers, signed or unsigned, normalized or non-normalized, 8, 16, or 32
+  bits wide
+* Floating-point, 16, 32, or 64 bits wide
+
+At this time, support for varied vertex data formats is limited by driver
+deficiencies. It is planned to support a single uniform set of formats for all
+Gallium drivers at some point.
+
+Rather than attempt to specify every small nuance of behavior, Gallium uses a
+very simple set of rules for padding out unspecified components. If an input
+uses less than four components, it will be padded out with the constant vector
+``(0, 0, 0, 1)``.
+
+Fog, point size, the facing bit, and edgeflags, all are in the standard format
+of ``(x, 0, 0, 1)``, and so only the first component of those inputs is used.
+
+Position
+%%%%%%%%
+
+Vertex position may be specified with two to four components. Using less than
+two components is not allowed.
+
+Colors
+%%%%%%
+
+Colors, both front- and back-facing, may omit the alpha component, only using
+three components. Using less than three components is not allowed.
 
 Members
 -------
index 48d9d570b6fcfc9f581e071634786c90e8a4bf23..e3ef49c862c3f290eeb0150a49d39ce4193137bc 100644 (file)
@@ -36,7 +36,9 @@ The integer capabilities:
   bound.
 * ``OCCLUSION_QUERY``: Whether occlusion queries are available.
 * ``TIMER_QUERY``: Whether timer queries are available.
-* ``TEXTURE_SHADOW_MAP``: XXX
+* ``TEXTURE_SHADOW_MAP``: indicates whether the fragment shader hardware
+  can do the depth texture / Z comparison operation in TEX instructions
+  for shadow testing.
 * ``MAX_TEXTURE_2D_LEVELS``: The maximum number of mipmap levels available
   for a 2D texture.
 * ``MAX_TEXTURE_3D_LEVELS``: The maximum number of mipmap levels available
@@ -55,7 +57,13 @@ The integer capabilities:
   from color blend equations, in :ref:`Blend` state.
 * ``SM3``: Whether the vertex shader and fragment shader support equivalent
   opcodes to the Shader Model 3 specification. XXX oh god this is horrible
-* ``MAX_PREDICATE_REGISTERS``: XXX
+* ``MAX_PREDICATE_REGISTERS``: indicates the number of predicate registers
+  available.  Predicate register may be set as a side-effect of ALU
+  instructions to indicate less than, greater than or equal to zero.
+  Later instructions can use a predicate register to control writing to
+  each channel of destination registers.  NOTE: predicate registers have
+  not been fully implemented in Gallium at this time.  See the
+  GL_NV_fragment_program extension for more info (look for "condition codes").
 * ``MAX_COMBINED_SAMPLERS``: The total number of samplers accessible from
   the vertex and fragment shader, inclusive.
 * ``MAX_CONST_BUFFERS``: Maximum number of constant buffers that can be bound
index ecab7cb8097bba02831174a295918f804157915f..e588c5b7bd8bca9d53ab8c1f4c26157cb8faa9b3 100644 (file)
@@ -1286,6 +1286,8 @@ wrapping rules.
 Declaration Semantic
 ^^^^^^^^^^^^^^^^^^^^^^^^
 
+  Vertex and fragment shader input and output registers may be labeled
+  with semantic information consisting of a name and index.
 
   Follows Declaration token if Semantic bit is set.
 
@@ -1306,90 +1308,115 @@ Declaration Semantic
 TGSI_SEMANTIC_POSITION
 """"""""""""""""""""""
 
-Position, sometimes known as HPOS or WPOS for historical reasons, is the
-location of the vertex in space, in ``(x, y, z, w)`` format. ``x``, ``y``, and ``z``
-are the Cartesian coordinates, and ``w`` is the homogenous coordinate and used
-for the perspective divide, if enabled.
+For vertex shaders, TGSI_SEMANTIC_POSITION indicates the vertex shader
+output register which contains the homogeneous vertex position in the clip
+space coordinate system.  After clipping, the X, Y and Z components of the
+vertex will be divided by the W value to get normalized device coordinates.
 
-As a vertex shader output, position should be scaled to the viewport. When
-used in fragment shaders, position will be in window coordinates. The convention
-used depends on the FS_COORD_ORIGIN and FS_COORD_PIXEL_CENTER properties.
+For fragment shaders, TGSI_SEMANTIC_POSITION is used to indicate that
+fragment shader input contains the fragment's window position.  The X
+component starts at zero and always increases from left to right.
+The Y component starts at zero and always increases but Y=0 may either
+indicate the top of the window or the bottom depending on the fragment
+coordinate origin convention (see TGSI_PROPERTY_FS_COORD_ORIGIN).
+The Z coordinate ranges from 0 to 1 to represent depth from the front
+to the back of the Z buffer.  The W component contains the reciprocol
+of the interpolated vertex position W component.
 
-XXX additionally, is there a way to configure the perspective divide? it's
-accelerated on most chipsets AFAIK...
+Fragment shaders may also declare an output register with
+TGSI_SEMANTIC_POSITION.  Only the Z component is writable.  This allows
+the fragment shader to change the fragment's Z position.
 
-Position, if not specified, usually defaults to ``(0, 0, 0, 1)``, and can
-be partially specified as ``(x, y, 0, 1)`` or ``(x, y, z, 1)``.
 
-XXX usually? can we solidify that?
 
 TGSI_SEMANTIC_COLOR
 """""""""""""""""""
 
-Colors are used to, well, color the primitives. Colors are always in
-``(r, g, b, a)`` format.
+For vertex shader outputs or fragment shader inputs/outputs, this
+label indicates that the resister contains an R,G,B,A color.
+
+Several shader inputs/outputs may contain colors so the semantic index
+is used to distinguish them.  For example, color[0] may be the diffuse
+color while color[1] may be the specular color.
+
+This label is needed so that the flat/smooth shading can be applied
+to the right interpolants during rasterization.
+
 
-If alpha is not specified, it defaults to 1.
 
 TGSI_SEMANTIC_BCOLOR
 """"""""""""""""""""
 
 Back-facing colors are only used for back-facing polygons, and are only valid
 in vertex shader outputs. After rasterization, all polygons are front-facing
-and COLOR and BCOLOR end up occupying the same slots in the fragment, so
-all BCOLORs effectively become regular COLORs in the fragment shader.
+and COLOR and BCOLOR end up occupying the same slots in the fragment shader,
+so all BCOLORs effectively become regular COLORs in the fragment shader.
+
 
 TGSI_SEMANTIC_FOG
 """""""""""""""""
 
-The fog coordinate historically has been used to replace the depth coordinate
-for generation of fog in dedicated fog blocks. Gallium, however, does not use
-dedicated fog acceleration, placing it entirely in the fragment shader
-instead.
+Vertex shader inputs and outputs and fragment shader inputs may be
+labeled with TGSI_SEMANTIC_FOG to indicate that the register contains
+a fog coordinate in the form (F, 0, 0, 1).  Typically, the fragment
+shader will use the fog coordinate to compute a fog blend factor which
+is used to blend the normal fragment color with a constant fog color.
+
+Only the first component matters when writing from the vertex shader;
+the driver will ensure that the coordinate is in this format when used
+as a fragment shader input.
 
-The fog coordinate should be written in ``(f, 0, 0, 1)`` format. Only the first
-component matters when writing from the vertex shader; the driver will ensure
-that the coordinate is in this format when used as a fragment shader input.
 
 TGSI_SEMANTIC_PSIZE
 """""""""""""""""""
 
-PSIZE, or point size, is used to specify point sizes per-vertex. It should
-be in ``(s, 0, 0, 1)`` format, where ``s`` is the (possibly clamped) point size.
-Only the first component matters when writing from the vertex shader.
+Vertex shader input and output registers may be labeled with
+TGIS_SEMANTIC_PSIZE to indicate that the register contains a point size
+in the form (S, 0, 0, 1).  The point size controls the width or diameter
+of points for rasterization.  This label cannot be used in fragment
+shaders.
 
 When using this semantic, be sure to set the appropriate state in the
 :ref:`rasterizer` first.
 
+
 TGSI_SEMANTIC_GENERIC
 """""""""""""""""""""
 
-Generic semantics are nearly always used for texture coordinate attributes,
-in ``(s, t, r, q)`` format. ``t`` and ``r`` may be unused for certain kinds
-of lookups, and ``q`` is the level-of-detail bias for biased sampling.
+All vertex/fragment shader inputs/outputs not labeled with any other
+semantic label can be considered to be generic attributes.  Typical
+uses of generic inputs/outputs are texcoords and user-defined values.
 
-These attributes are called "generic" because they may be used for anything
-else, including parameters, texture generation information, or anything that
-can be stored inside a four-component vector.
 
 TGSI_SEMANTIC_NORMAL
 """"""""""""""""""""
 
-Vertex normal; could be used to implement per-pixel lighting for legacy APIs
-that allow mixing fixed-function and programmable stages.
+Indicates that a vertex shader input is a normal vector.  This is
+typically only used for legacy graphics APIs.
+
 
 TGSI_SEMANTIC_FACE
 """"""""""""""""""
 
-FACE is the facing bit, to store the facing information for the fragment
-shader. ``(f, 0, 0, 1)`` is the format. The first component will be positive
-when the fragment is front-facing, and negative when the component is
-back-facing.
+This label applies to fragment shader inputs only and indicates that
+the register contains front/back-face information of the form (F, 0,
+0, 1).  The first component will be positive when the fragment belongs
+to a front-facing polygon, and negative when the fragment belongs to a
+back-facing polygon.
+
 
 TGSI_SEMANTIC_EDGEFLAG
 """"""""""""""""""""""
 
-XXX no clue
+For vertex shaders, this sematic label indicates that an input or
+output is a boolean edge flag.  The register layout is [F, x, x, x]
+where F is 0.0 or 1.0 and x = don't care.  Normally, the vertex shader
+simply copies the edge flag input to the edgeflag output.
+
+Edge flags are used to control which lines or points are actually
+drawn when the polygon mode converts triangles/quads/polygons into
+points or lines.
+
 
 
 Properties
diff --git a/src/gallium/drivers/galahad/Makefile b/src/gallium/drivers/galahad/Makefile
new file mode 100644 (file)
index 0000000..e9c4f7e
--- /dev/null
@@ -0,0 +1,11 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBNAME = galahad
+
+C_SOURCES = \
+       glhd_objects.c \
+       glhd_context.c \
+       glhd_screen.c
+
+include ../../Makefile.template
diff --git a/src/gallium/drivers/galahad/SConscript b/src/gallium/drivers/galahad/SConscript
new file mode 100644 (file)
index 0000000..b398a3f
--- /dev/null
@@ -0,0 +1,13 @@
+Import('*')
+
+env = env.Clone()
+
+galahad = env.ConvenienceLibrary(
+       target = 'identity',
+       source = [
+               'glhd_context.c',
+               'glhd_objects.c',
+               'glhd_screen.c',
+       ])
+
+Export('galahad')
diff --git a/src/gallium/drivers/galahad/glhd_context.c b/src/gallium/drivers/galahad/glhd_context.c
new file mode 100644 (file)
index 0000000..ab6f17b
--- /dev/null
@@ -0,0 +1,997 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE 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_context.h"
+
+#include "util/u_format.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+#include "glhd_context.h"
+#include "glhd_objects.h"
+
+
+static void
+galahad_destroy(struct pipe_context *_pipe)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->destroy(pipe);
+
+   FREE(glhd_pipe);
+}
+
+static void
+galahad_draw_arrays(struct pipe_context *_pipe,
+                     unsigned prim,
+                     unsigned start,
+                     unsigned count)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->draw_arrays(pipe,
+                     prim,
+                     start,
+                     count);
+}
+
+static void
+galahad_draw_elements(struct pipe_context *_pipe,
+                       struct pipe_resource *_indexResource,
+                       unsigned indexSize,
+                       int indexBias,
+                       unsigned prim,
+                       unsigned start,
+                       unsigned count)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct galahad_resource *glhd_resource = galahad_resource(_indexResource);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+   struct pipe_resource *indexResource = glhd_resource->resource;
+
+   pipe->draw_elements(pipe,
+                       indexResource,
+                       indexSize,
+                       indexBias,
+                       prim,
+                       start,
+                       count);
+}
+
+static void
+galahad_draw_range_elements(struct pipe_context *_pipe,
+                             struct pipe_resource *_indexResource,
+                             unsigned indexSize,
+                             int indexBias,
+                             unsigned minIndex,
+                             unsigned maxIndex,
+                             unsigned mode,
+                             unsigned start,
+                             unsigned count)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct galahad_resource *glhd_resource = galahad_resource(_indexResource);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+   struct pipe_resource *indexResource = glhd_resource->resource;
+
+   pipe->draw_range_elements(pipe,
+                             indexResource,
+                             indexSize,
+                             indexBias,
+                             minIndex,
+                             maxIndex,
+                             mode,
+                             start,
+                             count);
+}
+
+static struct pipe_query *
+galahad_create_query(struct pipe_context *_pipe,
+                      unsigned query_type)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   if (query_type == PIPE_QUERY_OCCLUSION_COUNTER &&
+      !pipe->screen->get_param(pipe->screen, PIPE_CAP_OCCLUSION_QUERY)) {
+      glhd_error("Occlusion query requested but not supported");
+   }
+
+   if (query_type == PIPE_QUERY_TIME_ELAPSED &&
+      !pipe->screen->get_param(pipe->screen, PIPE_CAP_TIMER_QUERY)) {
+      glhd_error("Timer query requested but not supported");
+   }
+
+   return pipe->create_query(pipe,
+                             query_type);
+}
+
+static void
+galahad_destroy_query(struct pipe_context *_pipe,
+                       struct pipe_query *query)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->destroy_query(pipe,
+                       query);
+}
+
+static void
+galahad_begin_query(struct pipe_context *_pipe,
+                     struct pipe_query *query)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->begin_query(pipe,
+                     query);
+}
+
+static void
+galahad_end_query(struct pipe_context *_pipe,
+                   struct pipe_query *query)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->end_query(pipe,
+                   query);
+}
+
+static boolean
+galahad_get_query_result(struct pipe_context *_pipe,
+                          struct pipe_query *query,
+                          boolean wait,
+                          void *result)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   return pipe->get_query_result(pipe,
+                                 query,
+                                 wait,
+                                 result);
+}
+
+static void *
+galahad_create_blend_state(struct pipe_context *_pipe,
+                            const struct pipe_blend_state *blend)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   if (blend->logicop_enable) {
+      if (blend->rt[0].blend_enable) {
+         glhd_warn("Blending enabled for render target 0, but logicops "
+            "are enabled");
+      }
+   }
+
+   return pipe->create_blend_state(pipe,
+                                   blend);
+}
+
+static void
+galahad_bind_blend_state(struct pipe_context *_pipe,
+                          void *blend)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->bind_blend_state(pipe,
+                              blend);
+}
+
+static void
+galahad_delete_blend_state(struct pipe_context *_pipe,
+                            void *blend)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->delete_blend_state(pipe,
+                            blend);
+}
+
+static void *
+galahad_create_sampler_state(struct pipe_context *_pipe,
+                              const struct pipe_sampler_state *sampler)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   return pipe->create_sampler_state(pipe,
+                                     sampler);
+}
+
+static void
+galahad_bind_fragment_sampler_states(struct pipe_context *_pipe,
+                                      unsigned num_samplers,
+                                      void **samplers)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->bind_fragment_sampler_states(pipe,
+                                      num_samplers,
+                                      samplers);
+}
+
+static void
+galahad_bind_vertex_sampler_states(struct pipe_context *_pipe,
+                                    unsigned num_samplers,
+                                    void **samplers)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->bind_vertex_sampler_states(pipe,
+                                    num_samplers,
+                                    samplers);
+}
+
+static void
+galahad_delete_sampler_state(struct pipe_context *_pipe,
+                              void *sampler)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->delete_sampler_state(pipe,
+                              sampler);
+}
+
+static void *
+galahad_create_rasterizer_state(struct pipe_context *_pipe,
+                                 const struct pipe_rasterizer_state *rasterizer)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   if (rasterizer->point_quad_rasterization) {
+       if (rasterizer->point_smooth) {
+           glhd_warn("Point smoothing requested but ignored");
+       }
+   } else {
+       if (rasterizer->sprite_coord_enable) {
+           glhd_warn("Point sprites requested but ignored");
+       }
+   }
+
+   return pipe->create_rasterizer_state(pipe,
+                                        rasterizer);
+}
+
+static void
+galahad_bind_rasterizer_state(struct pipe_context *_pipe,
+                               void *rasterizer)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->bind_rasterizer_state(pipe,
+                               rasterizer);
+}
+
+static void
+galahad_delete_rasterizer_state(struct pipe_context *_pipe,
+                                 void *rasterizer)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->delete_rasterizer_state(pipe,
+                                 rasterizer);
+}
+
+static void *
+galahad_create_depth_stencil_alpha_state(struct pipe_context *_pipe,
+                                          const struct pipe_depth_stencil_alpha_state *depth_stencil_alpha)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   return pipe->create_depth_stencil_alpha_state(pipe,
+                                                 depth_stencil_alpha);
+}
+
+static void
+galahad_bind_depth_stencil_alpha_state(struct pipe_context *_pipe,
+                                        void *depth_stencil_alpha)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->bind_depth_stencil_alpha_state(pipe,
+                                        depth_stencil_alpha);
+}
+
+static void
+galahad_delete_depth_stencil_alpha_state(struct pipe_context *_pipe,
+                                          void *depth_stencil_alpha)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->delete_depth_stencil_alpha_state(pipe,
+                                          depth_stencil_alpha);
+}
+
+static void *
+galahad_create_fs_state(struct pipe_context *_pipe,
+                         const struct pipe_shader_state *fs)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   return pipe->create_fs_state(pipe,
+                                fs);
+}
+
+static void
+galahad_bind_fs_state(struct pipe_context *_pipe,
+                       void *fs)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->bind_fs_state(pipe,
+                       fs);
+}
+
+static void
+galahad_delete_fs_state(struct pipe_context *_pipe,
+                         void *fs)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->delete_fs_state(pipe,
+                         fs);
+}
+
+static void *
+galahad_create_vs_state(struct pipe_context *_pipe,
+                         const struct pipe_shader_state *vs)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   return pipe->create_vs_state(pipe,
+                                vs);
+}
+
+static void
+galahad_bind_vs_state(struct pipe_context *_pipe,
+                       void *vs)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->bind_vs_state(pipe,
+                       vs);
+}
+
+static void
+galahad_delete_vs_state(struct pipe_context *_pipe,
+                         void *vs)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->delete_vs_state(pipe,
+                         vs);
+}
+
+
+static void *
+galahad_create_vertex_elements_state(struct pipe_context *_pipe,
+                                      unsigned num_elements,
+                                      const struct pipe_vertex_element *vertex_elements)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   return pipe->create_vertex_elements_state(pipe,
+                                             num_elements,
+                                             vertex_elements);
+}
+
+static void
+galahad_bind_vertex_elements_state(struct pipe_context *_pipe,
+                                    void *velems)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->bind_vertex_elements_state(pipe,
+                                    velems);
+}
+
+static void
+galahad_delete_vertex_elements_state(struct pipe_context *_pipe,
+                                      void *velems)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->delete_vertex_elements_state(pipe,
+                                      velems);
+}
+
+static void
+galahad_set_blend_color(struct pipe_context *_pipe,
+                         const struct pipe_blend_color *blend_color)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->set_blend_color(pipe,
+                         blend_color);
+}
+
+static void
+galahad_set_stencil_ref(struct pipe_context *_pipe,
+                         const struct pipe_stencil_ref *stencil_ref)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->set_stencil_ref(pipe,
+                         stencil_ref);
+}
+
+static void
+galahad_set_clip_state(struct pipe_context *_pipe,
+                        const struct pipe_clip_state *clip)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->set_clip_state(pipe,
+                        clip);
+}
+
+static void
+galahad_set_sample_mask(struct pipe_context *_pipe,
+                         unsigned sample_mask)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->set_sample_mask(pipe,
+                         sample_mask);
+}
+
+static void
+galahad_set_constant_buffer(struct pipe_context *_pipe,
+                             uint shader,
+                             uint index,
+                             struct pipe_resource *_resource)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+   struct pipe_resource *unwrapped_resource;
+   struct pipe_resource *resource = NULL;
+
+   /* XXX hmm? unwrap the input state */
+   if (_resource) {
+      unwrapped_resource = galahad_resource_unwrap(_resource);
+      resource = unwrapped_resource;
+   }
+
+   pipe->set_constant_buffer(pipe,
+                             shader,
+                             index,
+                             resource);
+}
+
+static void
+galahad_set_framebuffer_state(struct pipe_context *_pipe,
+                               const struct pipe_framebuffer_state *_state)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+   struct pipe_framebuffer_state unwrapped_state;
+   struct pipe_framebuffer_state *state = NULL;
+   unsigned i;
+
+   if (_state->nr_cbufs > PIPE_MAX_COLOR_BUFS) {
+      glhd_error("%d render targets bound, but only %d are permitted by API",
+         _state->nr_cbufs, PIPE_MAX_COLOR_BUFS);
+   } else if (_state->nr_cbufs >
+      pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_RENDER_TARGETS)) {
+      glhd_warn("%d render targets bound, but only %d are supported",
+         _state->nr_cbufs,
+         pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_RENDER_TARGETS));
+   }
+
+   /* unwrap the input state */
+   if (_state) {
+      memcpy(&unwrapped_state, _state, sizeof(unwrapped_state));
+      for(i = 0; i < _state->nr_cbufs; i++)
+         unwrapped_state.cbufs[i] = galahad_surface_unwrap(_state->cbufs[i]);
+      for (; i < PIPE_MAX_COLOR_BUFS; i++)
+         unwrapped_state.cbufs[i] = NULL;
+      unwrapped_state.zsbuf = galahad_surface_unwrap(_state->zsbuf);
+      state = &unwrapped_state;
+   }
+
+   pipe->set_framebuffer_state(pipe,
+                               state);
+}
+
+static void
+galahad_set_polygon_stipple(struct pipe_context *_pipe,
+                             const struct pipe_poly_stipple *poly_stipple)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->set_polygon_stipple(pipe,
+                             poly_stipple);
+}
+
+static void
+galahad_set_scissor_state(struct pipe_context *_pipe,
+                           const struct pipe_scissor_state *scissor)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->set_scissor_state(pipe,
+                           scissor);
+}
+
+static void
+galahad_set_viewport_state(struct pipe_context *_pipe,
+                            const struct pipe_viewport_state *viewport)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->set_viewport_state(pipe,
+                            viewport);
+}
+
+static void
+galahad_set_fragment_sampler_views(struct pipe_context *_pipe,
+                                    unsigned num,
+                                    struct pipe_sampler_view **_views)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+   struct pipe_sampler_view *unwrapped_views[PIPE_MAX_SAMPLERS];
+   struct pipe_sampler_view **views = NULL;
+   unsigned i;
+
+   if (_views) {
+      for (i = 0; i < num; i++)
+         unwrapped_views[i] = galahad_sampler_view_unwrap(_views[i]);
+      for (; i < PIPE_MAX_SAMPLERS; i++)
+         unwrapped_views[i] = NULL;
+
+      views = unwrapped_views;
+   }
+
+   pipe->set_fragment_sampler_views(pipe, num, views);
+}
+
+static void
+galahad_set_vertex_sampler_views(struct pipe_context *_pipe,
+                                  unsigned num,
+                                  struct pipe_sampler_view **_views)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+   struct pipe_sampler_view *unwrapped_views[PIPE_MAX_VERTEX_SAMPLERS];
+   struct pipe_sampler_view **views = NULL;
+   unsigned i;
+
+   if (_views) {
+      for (i = 0; i < num; i++)
+         unwrapped_views[i] = galahad_sampler_view_unwrap(_views[i]);
+      for (; i < PIPE_MAX_VERTEX_SAMPLERS; i++)
+         unwrapped_views[i] = NULL;
+
+      views = unwrapped_views;
+   }
+
+   pipe->set_vertex_sampler_views(pipe, num, views);
+}
+
+static void
+galahad_set_vertex_buffers(struct pipe_context *_pipe,
+                            unsigned num_buffers,
+                            const struct pipe_vertex_buffer *_buffers)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+   struct pipe_vertex_buffer unwrapped_buffers[PIPE_MAX_SHADER_INPUTS];
+   struct pipe_vertex_buffer *buffers = NULL;
+   unsigned i;
+
+   if (num_buffers) {
+      memcpy(unwrapped_buffers, _buffers, num_buffers * sizeof(*_buffers));
+      for (i = 0; i < num_buffers; i++)
+         unwrapped_buffers[i].buffer = galahad_resource_unwrap(_buffers[i].buffer);
+      buffers = unwrapped_buffers;
+   }
+
+   pipe->set_vertex_buffers(pipe,
+                            num_buffers,
+                            buffers);
+}
+static void
+galahad_resource_copy_region(struct pipe_context *_pipe,
+                              struct pipe_resource *_dst,
+                              struct pipe_subresource subdst,
+                              unsigned dstx,
+                              unsigned dsty,
+                              unsigned dstz,
+                              struct pipe_resource *_src,
+                              struct pipe_subresource subsrc,
+                              unsigned srcx,
+                              unsigned srcy,
+                              unsigned srcz,
+                              unsigned width,
+                              unsigned height)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct galahad_resource *glhd_resource_dst = galahad_resource(_dst);
+   struct galahad_resource *glhd_resource_src = galahad_resource(_src);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+   struct pipe_resource *dst = glhd_resource_dst->resource;
+   struct pipe_resource *src = glhd_resource_src->resource;
+
+   if (_dst->format != _src->format) {
+      glhd_warn("Format mismatch: Source is %s, destination is %s",
+         util_format_short_name(_src->format),
+         util_format_short_name(_dst->format));
+   }
+
+   pipe->resource_copy_region(pipe,
+                              dst,
+                              subdst,
+                              dstx,
+                              dsty,
+                              dstz,
+                              src,
+                              subsrc,
+                              srcx,
+                              srcy,
+                              srcz,
+                              width,
+                              height);
+}
+
+static void
+galahad_clear(struct pipe_context *_pipe,
+               unsigned buffers,
+               const float *rgba,
+               double depth,
+               unsigned stencil)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->clear(pipe,
+               buffers,
+               rgba,
+               depth,
+               stencil);
+}
+
+static void
+galahad_clear_render_target(struct pipe_context *_pipe,
+                             struct pipe_surface *_dst,
+                             const float *rgba,
+                             unsigned dstx, unsigned dsty,
+                             unsigned width, unsigned height)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct galahad_surface *glhd_surface_dst = galahad_surface(_dst);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+   struct pipe_surface *dst = glhd_surface_dst->surface;
+
+   pipe->clear_render_target(pipe,
+                             dst,
+                             rgba,
+                             dstx,
+                             dsty,
+                             width,
+                             height);
+}
+static void
+galahad_clear_depth_stencil(struct pipe_context *_pipe,
+                             struct pipe_surface *_dst,
+                             unsigned clear_flags,
+                             double depth,
+                             unsigned stencil,
+                             unsigned dstx, unsigned dsty,
+                             unsigned width, unsigned height)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct galahad_surface *glhd_surface_dst = galahad_surface(_dst);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+   struct pipe_surface *dst = glhd_surface_dst->surface;
+
+   pipe->clear_depth_stencil(pipe,
+                             dst,
+                             clear_flags,
+                             depth,
+                             stencil,
+                             dstx,
+                             dsty,
+                             width,
+                             height);
+
+}
+
+static void
+galahad_flush(struct pipe_context *_pipe,
+               unsigned flags,
+               struct pipe_fence_handle **fence)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+
+   pipe->flush(pipe,
+               flags,
+               fence);
+}
+
+static unsigned int
+galahad_is_resource_referenced(struct pipe_context *_pipe,
+                                struct pipe_resource *_resource,
+                                unsigned face,
+                                unsigned level)
+{
+   struct galahad_context *glhd_pipe = galahad_context(_pipe);
+   struct galahad_resource *glhd_resource = galahad_resource(_resource);
+   struct pipe_context *pipe = glhd_pipe->pipe;
+   struct pipe_resource *resource = glhd_resource->resource;
+
+   return pipe->is_resource_referenced(pipe,
+                                       resource,
+                                       face,
+                                       level);
+}
+
+static struct pipe_sampler_view *
+galahad_context_create_sampler_view(struct pipe_context *_pipe,
+                                     struct pipe_resource *_resource,
+                                     const struct pipe_sampler_view *templ)
+{
+   struct galahad_context *glhd_context = galahad_context(_pipe);
+   struct galahad_resource *glhd_resource = galahad_resource(_resource);
+   struct pipe_context *pipe = glhd_context->pipe;
+   struct pipe_resource *resource = glhd_resource->resource;
+   struct pipe_sampler_view *result;
+
+   result = pipe->create_sampler_view(pipe,
+                                      resource,
+                                      templ);
+
+   if (result)
+      return galahad_sampler_view_create(glhd_context, glhd_resource, result);
+   return NULL;
+}
+
+static void
+galahad_context_sampler_view_destroy(struct pipe_context *_pipe,
+                                      struct pipe_sampler_view *_view)
+{
+   galahad_sampler_view_destroy(galahad_context(_pipe),
+                                 galahad_sampler_view(_view));
+}
+
+static struct pipe_transfer *
+galahad_context_get_transfer(struct pipe_context *_context,
+                              struct pipe_resource *_resource,
+                              struct pipe_subresource sr,
+                              unsigned usage,
+                              const struct pipe_box *box)
+{
+   struct galahad_context *glhd_context = galahad_context(_context);
+   struct galahad_resource *glhd_resource = galahad_resource(_resource);
+   struct pipe_context *context = glhd_context->pipe;
+   struct pipe_resource *resource = glhd_resource->resource;
+   struct pipe_transfer *result;
+
+   result = context->get_transfer(context,
+                                  resource,
+                                  sr,
+                                  usage,
+                                  box);
+
+   if (result)
+      return galahad_transfer_create(glhd_context, glhd_resource, result);
+   return NULL;
+}
+
+static void
+galahad_context_transfer_destroy(struct pipe_context *_pipe,
+                                  struct pipe_transfer *_transfer)
+{
+   galahad_transfer_destroy(galahad_context(_pipe),
+                             galahad_transfer(_transfer));
+}
+
+static void *
+galahad_context_transfer_map(struct pipe_context *_context,
+                              struct pipe_transfer *_transfer)
+{
+   struct galahad_context *glhd_context = galahad_context(_context);
+   struct galahad_transfer *glhd_transfer = galahad_transfer(_transfer);
+   struct pipe_context *context = glhd_context->pipe;
+   struct pipe_transfer *transfer = glhd_transfer->transfer;
+
+   return context->transfer_map(context,
+                                transfer);
+}
+
+
+
+static void
+galahad_context_transfer_flush_region(struct pipe_context *_context,
+                                       struct pipe_transfer *_transfer,
+                                       const struct pipe_box *box)
+{
+   struct galahad_context *glhd_context = galahad_context(_context);
+   struct galahad_transfer *glhd_transfer = galahad_transfer(_transfer);
+   struct pipe_context *context = glhd_context->pipe;
+   struct pipe_transfer *transfer = glhd_transfer->transfer;
+
+   context->transfer_flush_region(context,
+                                  transfer,
+                                  box);
+}
+
+
+static void
+galahad_context_transfer_unmap(struct pipe_context *_context,
+                                struct pipe_transfer *_transfer)
+{
+   struct galahad_context *glhd_context = galahad_context(_context);
+   struct galahad_transfer *glhd_transfer = galahad_transfer(_transfer);
+   struct pipe_context *context = glhd_context->pipe;
+   struct pipe_transfer *transfer = glhd_transfer->transfer;
+
+   context->transfer_unmap(context,
+                           transfer);
+}
+
+
+static void
+galahad_context_transfer_inline_write(struct pipe_context *_context,
+                                       struct pipe_resource *_resource,
+                                       struct pipe_subresource sr,
+                                       unsigned usage,
+                                       const struct pipe_box *box,
+                                       const void *data,
+                                       unsigned stride,
+                                       unsigned slice_stride)
+{
+   struct galahad_context *glhd_context = galahad_context(_context);
+   struct galahad_resource *glhd_resource = galahad_resource(_resource);
+   struct pipe_context *context = glhd_context->pipe;
+   struct pipe_resource *resource = glhd_resource->resource;
+
+   context->transfer_inline_write(context,
+                                  resource,
+                                  sr,
+                                  usage,
+                                  box,
+                                  data,
+                                  stride,
+                                  slice_stride);
+}
+
+
+struct pipe_context *
+galahad_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
+{
+   struct galahad_context *glhd_pipe;
+   (void)galahad_screen(_screen);
+
+   glhd_pipe = CALLOC_STRUCT(galahad_context);
+   if (!glhd_pipe) {
+      return NULL;
+   }
+
+   glhd_pipe->base.winsys = NULL;
+   glhd_pipe->base.screen = _screen;
+   glhd_pipe->base.priv = pipe->priv; /* expose wrapped data */
+   glhd_pipe->base.draw = NULL;
+
+   glhd_pipe->base.destroy = galahad_destroy;
+   glhd_pipe->base.draw_arrays = galahad_draw_arrays;
+   glhd_pipe->base.draw_elements = galahad_draw_elements;
+   glhd_pipe->base.draw_range_elements = galahad_draw_range_elements;
+   glhd_pipe->base.create_query = galahad_create_query;
+   glhd_pipe->base.destroy_query = galahad_destroy_query;
+   glhd_pipe->base.begin_query = galahad_begin_query;
+   glhd_pipe->base.end_query = galahad_end_query;
+   glhd_pipe->base.get_query_result = galahad_get_query_result;
+   glhd_pipe->base.create_blend_state = galahad_create_blend_state;
+   glhd_pipe->base.bind_blend_state = galahad_bind_blend_state;
+   glhd_pipe->base.delete_blend_state = galahad_delete_blend_state;
+   glhd_pipe->base.create_sampler_state = galahad_create_sampler_state;
+   glhd_pipe->base.bind_fragment_sampler_states = galahad_bind_fragment_sampler_states;
+   glhd_pipe->base.bind_vertex_sampler_states = galahad_bind_vertex_sampler_states;
+   glhd_pipe->base.delete_sampler_state = galahad_delete_sampler_state;
+   glhd_pipe->base.create_rasterizer_state = galahad_create_rasterizer_state;
+   glhd_pipe->base.bind_rasterizer_state = galahad_bind_rasterizer_state;
+   glhd_pipe->base.delete_rasterizer_state = galahad_delete_rasterizer_state;
+   glhd_pipe->base.create_depth_stencil_alpha_state = galahad_create_depth_stencil_alpha_state;
+   glhd_pipe->base.bind_depth_stencil_alpha_state = galahad_bind_depth_stencil_alpha_state;
+   glhd_pipe->base.delete_depth_stencil_alpha_state = galahad_delete_depth_stencil_alpha_state;
+   glhd_pipe->base.create_fs_state = galahad_create_fs_state;
+   glhd_pipe->base.bind_fs_state = galahad_bind_fs_state;
+   glhd_pipe->base.delete_fs_state = galahad_delete_fs_state;
+   glhd_pipe->base.create_vs_state = galahad_create_vs_state;
+   glhd_pipe->base.bind_vs_state = galahad_bind_vs_state;
+   glhd_pipe->base.delete_vs_state = galahad_delete_vs_state;
+   glhd_pipe->base.create_vertex_elements_state = galahad_create_vertex_elements_state;
+   glhd_pipe->base.bind_vertex_elements_state = galahad_bind_vertex_elements_state;
+   glhd_pipe->base.delete_vertex_elements_state = galahad_delete_vertex_elements_state;
+   glhd_pipe->base.set_blend_color = galahad_set_blend_color;
+   glhd_pipe->base.set_stencil_ref = galahad_set_stencil_ref;
+   glhd_pipe->base.set_clip_state = galahad_set_clip_state;
+   glhd_pipe->base.set_sample_mask = galahad_set_sample_mask;
+   glhd_pipe->base.set_constant_buffer = galahad_set_constant_buffer;
+   glhd_pipe->base.set_framebuffer_state = galahad_set_framebuffer_state;
+   glhd_pipe->base.set_polygon_stipple = galahad_set_polygon_stipple;
+   glhd_pipe->base.set_scissor_state = galahad_set_scissor_state;
+   glhd_pipe->base.set_viewport_state = galahad_set_viewport_state;
+   glhd_pipe->base.set_fragment_sampler_views = galahad_set_fragment_sampler_views;
+   glhd_pipe->base.set_vertex_sampler_views = galahad_set_vertex_sampler_views;
+   glhd_pipe->base.set_vertex_buffers = galahad_set_vertex_buffers;
+   glhd_pipe->base.resource_copy_region = galahad_resource_copy_region;
+   glhd_pipe->base.clear = galahad_clear;
+   glhd_pipe->base.clear_render_target = galahad_clear_render_target;
+   glhd_pipe->base.clear_depth_stencil = galahad_clear_depth_stencil;
+   glhd_pipe->base.flush = galahad_flush;
+   glhd_pipe->base.is_resource_referenced = galahad_is_resource_referenced;
+   glhd_pipe->base.create_sampler_view = galahad_context_create_sampler_view;
+   glhd_pipe->base.sampler_view_destroy = galahad_context_sampler_view_destroy;
+   glhd_pipe->base.get_transfer = galahad_context_get_transfer;
+   glhd_pipe->base.transfer_destroy = galahad_context_transfer_destroy;
+   glhd_pipe->base.transfer_map = galahad_context_transfer_map;
+   glhd_pipe->base.transfer_unmap = galahad_context_transfer_unmap;
+   glhd_pipe->base.transfer_flush_region = galahad_context_transfer_flush_region;
+   glhd_pipe->base.transfer_inline_write = galahad_context_transfer_inline_write;
+
+   glhd_pipe->pipe = pipe;
+
+   return &glhd_pipe->base;
+}
diff --git a/src/gallium/drivers/galahad/glhd_context.h b/src/gallium/drivers/galahad/glhd_context.h
new file mode 100644 (file)
index 0000000..4e71753
--- /dev/null
@@ -0,0 +1,64 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE 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 GLHD_CONTEXT_H
+#define GLHD_CONTEXT_H
+
+#include <stdio.h>
+
+#include "pipe/p_state.h"
+#include "pipe/p_context.h"
+
+
+struct galahad_context {
+   struct pipe_context base;  /**< base class */
+
+   struct pipe_context *pipe;
+};
+
+
+struct pipe_context *
+galahad_context_create(struct pipe_screen *screen, struct pipe_context *pipe);
+
+
+static INLINE struct galahad_context *
+galahad_context(struct pipe_context *pipe)
+{
+   return (struct galahad_context *)pipe;
+}
+
+#define glhd_warn(...) \
+do { \
+    fprintf(stderr, "galahad: %s: ", __FUNCTION__); \
+    fprintf(stderr, __VA_ARGS__); \
+    fprintf(stderr, "\n"); \
+} while (0)
+
+#define glhd_error(...) \
+    glhd_warn(__VA_ARGS__);
+
+#endif /* GLHD_CONTEXT_H */
diff --git a/src/gallium/drivers/galahad/glhd_objects.c b/src/gallium/drivers/galahad/glhd_objects.c
new file mode 100644 (file)
index 0000000..6c5a21a
--- /dev/null
@@ -0,0 +1,187 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE 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 "util/u_inlines.h"
+#include "util/u_memory.h"
+
+#include "glhd_screen.h"
+#include "glhd_objects.h"
+#include "glhd_context.h"
+
+
+
+struct pipe_resource *
+galahad_resource_create(struct galahad_screen *glhd_screen,
+                        struct pipe_resource *resource)
+{
+   struct galahad_resource *glhd_resource;
+
+   if(!resource)
+      goto error;
+
+   assert(resource->screen == glhd_screen->screen);
+
+   glhd_resource = CALLOC_STRUCT(galahad_resource);
+   if(!glhd_resource)
+      goto error;
+
+   memcpy(&glhd_resource->base, resource, sizeof(struct pipe_resource));
+
+   pipe_reference_init(&glhd_resource->base.reference, 1);
+   glhd_resource->base.screen = &glhd_screen->base;
+   glhd_resource->resource = resource;
+
+   return &glhd_resource->base;
+
+error:
+   pipe_resource_reference(&resource, NULL);
+   return NULL;
+}
+
+void
+galahad_resource_destroy(struct galahad_resource *glhd_resource)
+{
+   pipe_resource_reference(&glhd_resource->resource, NULL);
+   FREE(glhd_resource);
+}
+
+
+struct pipe_surface *
+galahad_surface_create(struct galahad_resource *glhd_resource,
+                        struct pipe_surface *surface)
+{
+   struct galahad_surface *glhd_surface;
+
+   if(!surface)
+      goto error;
+
+   assert(surface->texture == glhd_resource->resource);
+
+   glhd_surface = CALLOC_STRUCT(galahad_surface);
+   if(!glhd_surface)
+      goto error;
+
+   memcpy(&glhd_surface->base, surface, sizeof(struct pipe_surface));
+
+   pipe_reference_init(&glhd_surface->base.reference, 1);
+   glhd_surface->base.texture = NULL;
+   pipe_resource_reference(&glhd_surface->base.texture, &glhd_resource->base);
+   glhd_surface->surface = surface;
+
+   return &glhd_surface->base;
+
+error:
+   pipe_surface_reference(&surface, NULL);
+   return NULL;
+}
+
+void
+galahad_surface_destroy(struct galahad_surface *glhd_surface)
+{
+   pipe_resource_reference(&glhd_surface->base.texture, NULL);
+   pipe_surface_reference(&glhd_surface->surface, NULL);
+   FREE(glhd_surface);
+}
+
+
+struct pipe_sampler_view *
+galahad_sampler_view_create(struct galahad_context *glhd_context,
+                             struct galahad_resource *glhd_resource,
+                             struct pipe_sampler_view *view)
+{
+   struct galahad_sampler_view *glhd_view;
+
+   if (!view)
+      goto error;
+
+   assert(view->texture == glhd_resource->resource);
+
+   glhd_view = CALLOC_STRUCT(galahad_sampler_view);
+
+   glhd_view->base = *view;
+   glhd_view->base.reference.count = 1;
+   glhd_view->base.texture = NULL;
+   pipe_resource_reference(&glhd_view->base.texture, glhd_resource->resource);
+   glhd_view->base.context = glhd_context->pipe;
+   glhd_view->sampler_view = view;
+
+   return &glhd_view->base;
+error:
+   return NULL;
+}
+
+void
+galahad_sampler_view_destroy(struct galahad_context *glhd_context,
+                              struct galahad_sampler_view *glhd_view)
+{
+   pipe_resource_reference(&glhd_view->base.texture, NULL);
+   glhd_context->pipe->sampler_view_destroy(glhd_context->pipe,
+                                          glhd_view->sampler_view);
+   FREE(glhd_view);
+}
+
+
+struct pipe_transfer *
+galahad_transfer_create(struct galahad_context *glhd_context,
+                         struct galahad_resource *glhd_resource,
+                         struct pipe_transfer *transfer)
+{
+   struct galahad_transfer *glhd_transfer;
+
+   if(!transfer)
+      goto error;
+
+   assert(transfer->resource == glhd_resource->resource);
+
+   glhd_transfer = CALLOC_STRUCT(galahad_transfer);
+   if(!glhd_transfer)
+      goto error;
+
+   memcpy(&glhd_transfer->base, transfer, sizeof(struct pipe_transfer));
+
+   glhd_transfer->base.resource = NULL;
+   glhd_transfer->transfer = transfer;
+
+   pipe_resource_reference(&glhd_transfer->base.resource, &glhd_resource->base);
+   assert(glhd_transfer->base.resource == &glhd_resource->base);
+
+   return &glhd_transfer->base;
+
+error:
+   glhd_context->pipe->transfer_destroy(glhd_context->pipe, transfer);
+   return NULL;
+}
+
+void
+galahad_transfer_destroy(struct galahad_context *glhd_context,
+                          struct galahad_transfer *glhd_transfer)
+{
+   pipe_resource_reference(&glhd_transfer->base.resource, NULL);
+   glhd_context->pipe->transfer_destroy(glhd_context->pipe,
+                                        glhd_transfer->transfer);
+   FREE(glhd_transfer);
+}
diff --git a/src/gallium/drivers/galahad/glhd_objects.h b/src/gallium/drivers/galahad/glhd_objects.h
new file mode 100644 (file)
index 0000000..9358039
--- /dev/null
@@ -0,0 +1,175 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE 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 GLHD_OBJECTS_H
+#define GLHD_OBJECTS_H
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+
+#include "glhd_screen.h"
+
+struct galahad_context;
+
+
+struct galahad_resource
+{
+   struct pipe_resource base;
+
+   struct pipe_resource *resource;
+};
+
+
+struct galahad_sampler_view
+{
+   struct pipe_sampler_view base;
+
+   struct pipe_sampler_view *sampler_view;
+};
+
+
+struct galahad_surface
+{
+   struct pipe_surface base;
+
+   struct pipe_surface *surface;
+};
+
+
+struct galahad_transfer
+{
+   struct pipe_transfer base;
+
+   struct pipe_transfer *transfer;
+};
+
+
+static INLINE struct galahad_resource *
+galahad_resource(struct pipe_resource *_resource)
+{
+   if(!_resource)
+      return NULL;
+   (void)galahad_screen(_resource->screen);
+   return (struct galahad_resource *)_resource;
+}
+
+static INLINE struct galahad_sampler_view *
+galahad_sampler_view(struct pipe_sampler_view *_sampler_view)
+{
+   if (!_sampler_view) {
+      return NULL;
+   }
+   return (struct galahad_sampler_view *)_sampler_view;
+}
+
+static INLINE struct galahad_surface *
+galahad_surface(struct pipe_surface *_surface)
+{
+   if(!_surface)
+      return NULL;
+   (void)galahad_resource(_surface->texture);
+   return (struct galahad_surface *)_surface;
+}
+
+static INLINE struct galahad_transfer *
+galahad_transfer(struct pipe_transfer *_transfer)
+{
+   if(!_transfer)
+      return NULL;
+   (void)galahad_resource(_transfer->resource);
+   return (struct galahad_transfer *)_transfer;
+}
+
+static INLINE struct pipe_resource *
+galahad_resource_unwrap(struct pipe_resource *_resource)
+{
+   if(!_resource)
+      return NULL;
+   return galahad_resource(_resource)->resource;
+}
+
+static INLINE struct pipe_sampler_view *
+galahad_sampler_view_unwrap(struct pipe_sampler_view *_sampler_view)
+{
+   if (!_sampler_view) {
+      return NULL;
+   }
+   return galahad_sampler_view(_sampler_view)->sampler_view;
+}
+
+static INLINE struct pipe_surface *
+galahad_surface_unwrap(struct pipe_surface *_surface)
+{
+   if(!_surface)
+      return NULL;
+   return galahad_surface(_surface)->surface;
+}
+
+static INLINE struct pipe_transfer *
+galahad_transfer_unwrap(struct pipe_transfer *_transfer)
+{
+   if(!_transfer)
+      return NULL;
+   return galahad_transfer(_transfer)->transfer;
+}
+
+
+struct pipe_resource *
+galahad_resource_create(struct galahad_screen *glhd_screen,
+                         struct pipe_resource *resource);
+
+void
+galahad_resource_destroy(struct galahad_resource *glhd_resource);
+
+struct pipe_surface *
+galahad_surface_create(struct galahad_resource *glhd_resource,
+                        struct pipe_surface *surface);
+
+void
+galahad_surface_destroy(struct galahad_surface *glhd_surface);
+
+struct pipe_sampler_view *
+galahad_sampler_view_create(struct galahad_context *glhd_context,
+                             struct galahad_resource *glhd_resource,
+                             struct pipe_sampler_view *view);
+
+void
+galahad_sampler_view_destroy(struct galahad_context *glhd_context,
+                              struct galahad_sampler_view *glhd_sampler_view);
+
+struct pipe_transfer *
+galahad_transfer_create(struct galahad_context *glhd_context,
+                         struct galahad_resource *glhd_resource,
+                         struct pipe_transfer *transfer);
+
+void
+galahad_transfer_destroy(struct galahad_context *glhd_context,
+                          struct galahad_transfer *glhd_transfer);
+
+
+#endif /* GLHD_OBJECTS_H */
diff --git a/src/gallium/drivers/galahad/glhd_public.h b/src/gallium/drivers/galahad/glhd_public.h
new file mode 100644 (file)
index 0000000..77a3801
--- /dev/null
@@ -0,0 +1,37 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE 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 GLHD_PUBLIC_H
+#define GLHD_PUBLIC_H
+
+struct pipe_screen;
+struct pipe_context;
+
+struct pipe_screen *
+galahad_screen_create(struct pipe_screen *screen);
+
+#endif /* GLHD_PUBLIC_H */
diff --git a/src/gallium/drivers/galahad/glhd_screen.c b/src/gallium/drivers/galahad/glhd_screen.c
new file mode 100644 (file)
index 0000000..4117485
--- /dev/null
@@ -0,0 +1,334 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * 2010 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and 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 VMWARE 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_screen.h"
+#include "pipe/p_state.h"
+#include "util/u_memory.h"
+
+#include "glhd_public.h"
+#include "glhd_screen.h"
+#include "glhd_context.h"
+#include "glhd_objects.h"
+
+DEBUG_GET_ONCE_BOOL_OPTION(galahad, "GALLIUM_GALAHAD", FALSE)
+
+static void
+galahad_screen_destroy(struct pipe_screen *_screen)
+{
+   struct galahad_screen *glhd_screen = galahad_screen(_screen);
+   struct pipe_screen *screen = glhd_screen->screen;
+
+   screen->destroy(screen);
+
+   FREE(glhd_screen);
+}
+
+static const char *
+galahad_screen_get_name(struct pipe_screen *_screen)
+{
+   struct galahad_screen *glhd_screen = galahad_screen(_screen);
+   struct pipe_screen *screen = glhd_screen->screen;
+
+   return screen->get_name(screen);
+}
+
+static const char *
+galahad_screen_get_vendor(struct pipe_screen *_screen)
+{
+   struct galahad_screen *glhd_screen = galahad_screen(_screen);
+   struct pipe_screen *screen = glhd_screen->screen;
+
+   return screen->get_vendor(screen);
+}
+
+static int
+galahad_screen_get_param(struct pipe_screen *_screen,
+                          enum pipe_cap param)
+{
+   struct galahad_screen *glhd_screen = galahad_screen(_screen);
+   struct pipe_screen *screen = glhd_screen->screen;
+
+   return screen->get_param(screen,
+                            param);
+}
+
+static float
+galahad_screen_get_paramf(struct pipe_screen *_screen,
+                           enum pipe_cap param)
+{
+   struct galahad_screen *glhd_screen = galahad_screen(_screen);
+   struct pipe_screen *screen = glhd_screen->screen;
+
+   return screen->get_paramf(screen,
+                             param);
+}
+
+static boolean
+galahad_screen_is_format_supported(struct pipe_screen *_screen,
+                                    enum pipe_format format,
+                                    enum pipe_texture_target target,
+                                    unsigned sample_count,
+                                    unsigned tex_usage,
+                                    unsigned geom_flags)
+{
+   struct galahad_screen *glhd_screen = galahad_screen(_screen);
+   struct pipe_screen *screen = glhd_screen->screen;
+
+   if (target >= PIPE_MAX_TEXTURE_TYPES) {
+      glhd_warn("Received bogus texture target %d", target);
+   }
+
+   return screen->is_format_supported(screen,
+                                      format,
+                                      target,
+                                      sample_count,
+                                      tex_usage,
+                                      geom_flags);
+}
+
+static struct pipe_context *
+galahad_screen_context_create(struct pipe_screen *_screen,
+                               void *priv)
+{
+   struct galahad_screen *glhd_screen = galahad_screen(_screen);
+   struct pipe_screen *screen = glhd_screen->screen;
+   struct pipe_context *result;
+
+   result = screen->context_create(screen, priv);
+   if (result)
+      return galahad_context_create(_screen, result);
+   return NULL;
+}
+
+static struct pipe_resource *
+galahad_screen_resource_create(struct pipe_screen *_screen,
+                                const struct pipe_resource *templat)
+{
+   struct galahad_screen *glhd_screen = galahad_screen(_screen);
+   struct pipe_screen *screen = glhd_screen->screen;
+   struct pipe_resource *result;
+
+   result = screen->resource_create(screen,
+                                    templat);
+
+   if (result)
+      return galahad_resource_create(glhd_screen, result);
+   return NULL;
+}
+
+static struct pipe_resource *
+galahad_screen_resource_from_handle(struct pipe_screen *_screen,
+                                     const struct pipe_resource *templ,
+                                     struct winsys_handle *handle)
+{
+   struct galahad_screen *glhd_screen = galahad_screen(_screen);
+   struct pipe_screen *screen = glhd_screen->screen;
+   struct pipe_resource *result;
+
+   /* TODO trace call */
+
+   result = screen->resource_from_handle(screen, templ, handle);
+
+   result = galahad_resource_create(galahad_screen(_screen), result);
+
+   return result;
+}
+
+static boolean
+galahad_screen_resource_get_handle(struct pipe_screen *_screen,
+                                    struct pipe_resource *_resource,
+                                    struct winsys_handle *handle)
+{
+   struct galahad_screen *glhd_screen = galahad_screen(_screen);
+   struct galahad_resource *glhd_resource = galahad_resource(_resource);
+   struct pipe_screen *screen = glhd_screen->screen;
+   struct pipe_resource *resource = glhd_resource->resource;
+
+   /* TODO trace call */
+
+   return screen->resource_get_handle(screen, resource, handle);
+}
+
+
+
+static void
+galahad_screen_resource_destroy(struct pipe_screen *screen,
+                                 struct pipe_resource *_resource)
+{
+   galahad_resource_destroy(galahad_resource(_resource));
+}
+
+static struct pipe_surface *
+galahad_screen_get_tex_surface(struct pipe_screen *_screen,
+                                struct pipe_resource *_resource,
+                                unsigned face,
+                                unsigned level,
+                                unsigned zslice,
+                                unsigned usage)
+{
+   struct galahad_screen *glhd_screen = galahad_screen(_screen);
+   struct galahad_resource *glhd_resource = galahad_resource(_resource);
+   struct pipe_screen *screen = glhd_screen->screen;
+   struct pipe_resource *resource = glhd_resource->resource;
+   struct pipe_surface *result;
+
+   result = screen->get_tex_surface(screen,
+                                    resource,
+                                    face,
+                                    level,
+                                    zslice,
+                                    usage);
+
+   if (result)
+      return galahad_surface_create(glhd_resource, result);
+   return NULL;
+}
+
+static void
+galahad_screen_tex_surface_destroy(struct pipe_surface *_surface)
+{
+   galahad_surface_destroy(galahad_surface(_surface));
+}
+
+
+
+static struct pipe_resource *
+galahad_screen_user_buffer_create(struct pipe_screen *_screen,
+                                   void *ptr,
+                                   unsigned bytes,
+                                   unsigned usage)
+{
+   struct galahad_screen *glhd_screen = galahad_screen(_screen);
+   struct pipe_screen *screen = glhd_screen->screen;
+   struct pipe_resource *result;
+
+   result = screen->user_buffer_create(screen,
+                                       ptr,
+                                       bytes,
+                                       usage);
+
+   if (result)
+      return galahad_resource_create(glhd_screen, result);
+   return NULL;
+}
+
+
+
+static void
+galahad_screen_flush_frontbuffer(struct pipe_screen *_screen,
+                                  struct pipe_surface *_surface,
+                                  void *context_private)
+{
+   struct galahad_screen *glhd_screen = galahad_screen(_screen);
+   struct galahad_surface *glhd_surface = galahad_surface(_surface);
+   struct pipe_screen *screen = glhd_screen->screen;
+   struct pipe_surface *surface = glhd_surface->surface;
+
+   screen->flush_frontbuffer(screen,
+                             surface,
+                             context_private);
+}
+
+static void
+galahad_screen_fence_reference(struct pipe_screen *_screen,
+                                struct pipe_fence_handle **ptr,
+                                struct pipe_fence_handle *fence)
+{
+   struct galahad_screen *glhd_screen = galahad_screen(_screen);
+   struct pipe_screen *screen = glhd_screen->screen;
+
+   screen->fence_reference(screen,
+                           ptr,
+                           fence);
+}
+
+static int
+galahad_screen_fence_signalled(struct pipe_screen *_screen,
+                                struct pipe_fence_handle *fence,
+                                unsigned flags)
+{
+   struct galahad_screen *glhd_screen = galahad_screen(_screen);
+   struct pipe_screen *screen = glhd_screen->screen;
+
+   return screen->fence_signalled(screen,
+                                  fence,
+                                  flags);
+}
+
+static int
+galahad_screen_fence_finish(struct pipe_screen *_screen,
+                             struct pipe_fence_handle *fence,
+                             unsigned flags)
+{
+   struct galahad_screen *glhd_screen = galahad_screen(_screen);
+   struct pipe_screen *screen = glhd_screen->screen;
+
+   return screen->fence_finish(screen,
+                               fence,
+                               flags);
+}
+
+struct pipe_screen *
+galahad_screen_create(struct pipe_screen *screen)
+{
+   struct galahad_screen *glhd_screen;
+
+   if (!debug_get_option_galahad())
+      return screen;
+
+   glhd_screen = CALLOC_STRUCT(galahad_screen);
+   if (!glhd_screen) {
+      return screen;
+   }
+
+   glhd_screen->base.winsys = NULL;
+
+   glhd_screen->base.destroy = galahad_screen_destroy;
+   glhd_screen->base.get_name = galahad_screen_get_name;
+   glhd_screen->base.get_vendor = galahad_screen_get_vendor;
+   glhd_screen->base.get_param = galahad_screen_get_param;
+   glhd_screen->base.get_paramf = galahad_screen_get_paramf;
+   glhd_screen->base.is_format_supported = galahad_screen_is_format_supported;
+   glhd_screen->base.context_create = galahad_screen_context_create;
+   glhd_screen->base.resource_create = galahad_screen_resource_create;
+   glhd_screen->base.resource_from_handle = galahad_screen_resource_from_handle;
+   glhd_screen->base.resource_get_handle = galahad_screen_resource_get_handle;
+   glhd_screen->base.resource_destroy = galahad_screen_resource_destroy;
+   glhd_screen->base.get_tex_surface = galahad_screen_get_tex_surface;
+   glhd_screen->base.tex_surface_destroy = galahad_screen_tex_surface_destroy;
+   glhd_screen->base.user_buffer_create = galahad_screen_user_buffer_create;
+   glhd_screen->base.flush_frontbuffer = galahad_screen_flush_frontbuffer;
+   glhd_screen->base.fence_reference = galahad_screen_fence_reference;
+   glhd_screen->base.fence_signalled = galahad_screen_fence_signalled;
+   glhd_screen->base.fence_finish = galahad_screen_fence_finish;
+
+   glhd_screen->screen = screen;
+
+   return &glhd_screen->base;
+}
diff --git a/src/gallium/drivers/galahad/glhd_screen.h b/src/gallium/drivers/galahad/glhd_screen.h
new file mode 100644 (file)
index 0000000..7862f4a
--- /dev/null
@@ -0,0 +1,48 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE 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 GLHD_SCREEN_H
+#define GLHD_SCREEN_H
+
+#include "pipe/p_screen.h"
+#include "pipe/p_defines.h"
+
+
+struct galahad_screen {
+   struct pipe_screen base;
+
+   struct pipe_screen *screen;
+};
+
+
+static INLINE struct galahad_screen *
+galahad_screen(struct pipe_screen *screen)
+{
+   return (struct galahad_screen *)screen;
+}
+
+#endif /* GLHD_SCREEN_H */
index 2cefe708500c5756f543cbdbb30198f5654741c0..b3f387f9335774bc34401763855def9d676d7745 100644 (file)
@@ -15,7 +15,9 @@ C_SOURCES = \
        i915_state_dynamic.c \
        i915_state_derived.c \
        i915_state_emit.c \
+       i915_state_fpc.c \
        i915_state_sampler.c \
+       i915_state_static.c \
        i915_screen.c \
        i915_prim_emit.c \
        i915_prim_vbuf.c \
index d6e7a8dbd370c932059c2e44bd5a0fe82793867f..d4bf6fef13425c9eab8e0a23dda0d557904f8822 100644 (file)
@@ -24,9 +24,11 @@ i915 = env.ConvenienceLibrary(
                'i915_state.c',
                'i915_state_derived.c',
                'i915_state_dynamic.c',
+               'i915_state_fpc.c',
                'i915_state_emit.c',
                'i915_state_immediate.c',
                'i915_state_sampler.c',
+               'i915_state_static.c',
                'i915_surface.c',
                'i915_resource.c',
                'i915_resource_texture.c',
index f0086695d16f5cde235c71885f0c8d1885574d4b..c411b84ccd4756f72b5c8a0f9248d42c20f34f61 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "i915_batchbuffer.h"
 
+
 #define BEGIN_BATCH(dwords, relocs) \
    (i915_winsys_batchbuffer_check(i915->batch, dwords, relocs))
 
 #define OUT_RELOC(buf, usage, offset) \
    i915_winsys_batchbuffer_reloc(i915->batch, buf, usage, offset)
 
-#define FLUSH_BATCH(fence) do {                 \
-   i915_winsys_batchbuffer_flush(i915->batch, fence); \
-   i915->hardware_dirty = ~0;                   \
-} while (0)
+#define FLUSH_BATCH(fence) \
+   i915_flush(i915, fence)
+
+
+/************************************************************************
+ * i915_flush.c
+ */
+void i915_flush(struct i915_context *i915, struct pipe_fence_handle **fence);
+
 
 #endif
index 27ccaa6b1fa7b30ca7e2898115adf943663d5f6f..c1cd314e7b8aca94664ebd2c9b7f0166cd3ce3c8 100644 (file)
@@ -30,6 +30,8 @@
 
 #include "i915_winsys.h"
 
+struct i915_context;
+
 static INLINE boolean
 i915_winsys_batchbuffer_check(struct i915_winsys_batchbuffer *batch,
                               size_t dwords,
@@ -77,11 +79,4 @@ i915_winsys_batchbuffer_reloc(struct i915_winsys_batchbuffer *batch,
    return batch->iws->batchbuffer_reloc(batch, buffer, usage, offset);
 }
 
-static INLINE void
-i915_winsys_batchbuffer_flush(struct i915_winsys_batchbuffer *batch,
-                              struct pipe_fence_handle **fence)
-{
-   batch->iws->batchbuffer_flush(batch, fence);
-}
-
 #endif
index c5b5979bf98cbb38db3a4e1b029e5a97aebe63fd..cdf20c0055a73e124e34c746d55ea369d59350ff 100644 (file)
@@ -31,7 +31,6 @@
 #include "i915_batch.h"
 #include "i915_debug.h"
 
-#define FILE_DEBUG_FLAG DEBUG_BLIT
 
 void
 i915_fill_blit(struct i915_context *i915,
@@ -47,10 +46,8 @@ i915_fill_blit(struct i915_context *i915,
    unsigned BR13, CMD;
 
 
-   I915_DBG(i915,
-      "%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
-      __FUNCTION__,
-      dst_buffer, dst_pitch, dst_offset, x, y, w, h);
+   I915_DBG(DBG_BLIT, "%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
+            __FUNCTION__, dst_buffer, dst_pitch, dst_offset, x, y, w, h);
 
    switch (cpp) {
    case 1:
@@ -79,7 +76,6 @@ i915_fill_blit(struct i915_context *i915,
    OUT_BATCH(((y + h) << 16) | (x + w));
    OUT_RELOC(dst_buffer, I915_USAGE_2D_TARGET, dst_offset);
    OUT_BATCH(color);
-   FLUSH_BATCH(NULL);
 }
 
 void
@@ -100,11 +96,11 @@ i915_copy_blit(struct i915_context *i915,
    int dst_x2 = dst_x + w;
 
 
-   I915_DBG(i915,
-      "%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
-      __FUNCTION__,
-      src_buffer, src_pitch, src_offset, src_x, src_y,
-      dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h);
+   I915_DBG(DBG_BLIT,
+            "%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
+            __FUNCTION__,
+            src_buffer, src_pitch, src_offset, src_x, src_y,
+            dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h);
 
    switch (cpp) {
    case 1:
@@ -146,5 +142,4 @@ i915_copy_blit(struct i915_context *i915,
    OUT_BATCH((src_y << 16) | src_x);
    OUT_BATCH(((int) src_pitch & 0xffff));
    OUT_RELOC(src_buffer, I915_USAGE_2D_SOURCE, src_offset);
-   FLUSH_BATCH(NULL);
 }
index acc0ffe037fcb7873f2bc3c1a4a20f80b1d9e047..b210cb130d09088283e3a2733b1206216d509ef6 100644 (file)
@@ -237,8 +237,6 @@ struct i915_context
 
    struct i915_state current;
    unsigned hardware_dirty;
-   
-   unsigned debug;
 };
 
 /* A flag for each state_tracker state object:
@@ -318,8 +316,6 @@ struct pipe_context *i915_create_context(struct pipe_screen *screen,
                                         void *priv);
 
 
-
-
 /***********************************************************************
  * Inline conversion functions.  These are better-typed than the
  * macros used previously:
@@ -331,5 +327,4 @@ i915_context( struct pipe_context *pipe )
 }
 
 
-
 #endif
index 663fac3055cf2c100724b29f8abb216345d4e27e..57d3390dea37d3bea34ae2116487142c086ae10a 100644 (file)
 
 #include "i915_reg.h"
 #include "i915_context.h"
+#include "i915_screen.h"
 #include "i915_debug.h"
+#include "i915_debug_private.h"
 #include "i915_batch.h"
 #include "util/u_debug.h"
 
 
+
+static const struct debug_named_value debug_options[] = {
+   {"blit",      DBG_BLIT,      "Print when using the 2d blitter"},
+   {"emit",      DBG_EMIT,      "State emit information"},
+   {"atoms",     DBG_ATOMS,     "Print dirty state atoms"},
+   {"flush",     DBG_FLUSH,     "Flushing information"},
+   {"texture",   DBG_TEXTURE,   "Texture information"},
+   {"constants", DBG_CONSTANTS, "Constant buffers"},
+   DEBUG_NAMED_VALUE_END
+};
+
+unsigned i915_debug = 0;
+
+void i915_debug_init(struct i915_screen *screen)
+{
+   i915_debug = debug_get_flags_option("I915_DEBUG", debug_options, 0);
+}
+
+
+
+/***********************************************************************
+ * Batchbuffer dumping
+ */
+
 static void
 PRINTF(
    struct debug_stream  *stream,
@@ -896,3 +922,66 @@ i915_dump_batchbuffer( struct i915_winsys_batchbuffer *batch )
 }
 
 
+
+/***********************************************************************
+ * Dirty state atom dumping
+ */
+
+void
+i915_dump_dirty(struct i915_context *i915, const char *func)
+{
+   struct {
+      unsigned dirty;
+      const char *name;
+   } l[] = {
+      {I915_NEW_VIEWPORT,      "viewport"},
+      {I915_NEW_RASTERIZER,    "rasterizer"},
+      {I915_NEW_FS,            "fs"},
+      {I915_NEW_BLEND,         "blend"},
+      {I915_NEW_CLIP,          "clip"},
+      {I915_NEW_SCISSOR,       "scissor"},
+      {I915_NEW_STIPPLE,       "stipple"},
+      {I915_NEW_FRAMEBUFFER,   "framebuffer"},
+      {I915_NEW_ALPHA_TEST,    "alpha_test"},
+      {I915_NEW_DEPTH_STENCIL, "depth_stencil"},
+      {I915_NEW_SAMPLER,       "sampler"},
+      {I915_NEW_SAMPLER_VIEW,  "sampler_view"},
+      {I915_NEW_CONSTANTS,     "constants"},
+      {I915_NEW_VBO,           "vbo"},
+      {I915_NEW_VS,            "vs"},
+      {0, NULL},
+   };
+   int i;
+
+   debug_printf("%s: ", func);
+   for (i = 0; l[i].name; i++)
+      if (i915->dirty & l[i].dirty)
+         debug_printf("%s ", l[i].name);
+   debug_printf("\n");
+}
+
+void
+i915_dump_hardware_dirty(struct i915_context *i915, const char *func)
+{
+   struct {
+      unsigned dirty;
+      const char *name;
+   } l[] = {
+      {I915_HW_STATIC,    "static"},
+      {I915_HW_DYNAMIC,   "dynamic"},
+      {I915_HW_SAMPLER,   "sampler"},
+      {I915_HW_MAP,       "map"},
+      {I915_HW_PROGRAM,   "program"},
+      {I915_HW_CONSTANTS, "constants"},
+      {I915_HW_IMMEDIATE, "immediate"},
+      {I915_HW_INVARIENT, "invarient"},
+      {0, NULL},
+   };
+   int i;
+
+   debug_printf("%s: ", func);
+   for (i = 0; l[i].name; i++)
+      if (i915->hardware_dirty & l[i].dirty)
+         debug_printf("%s ", l[i].name);
+   debug_printf("\n");
+}
index 67b8d9c2f6316ff9acf2424260e789a574d32866..fa60799d0c55669253ae9ab3ae4327764a96a54a 100644 (file)
  **************************************************************************/
 
 /* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ *           Jakob Bornecrantz <wallbraker@gmail.com>
  */
 
 #ifndef I915_DEBUG_H
 #define I915_DEBUG_H
 
-#include <stdarg.h>
+#include "util/u_debug.h"
 
+struct i915_screen;
 struct i915_context;
+struct i915_winsys_batchbuffer;
 
-struct debug_stream 
-{
-   unsigned offset;            /* current gtt offset */
-   char *ptr;          /* pointer to gtt offset zero */
-   char *end;          /* pointer to gtt offset zero */
-   unsigned print_addresses;
-};
-
-
-/* Internal functions
- */
-void i915_disassemble_program(struct debug_stream *stream, 
-                             const unsigned *program, unsigned sz);
-
-void i915_print_ureg(const char *msg, unsigned ureg);
-
-
-#define DEBUG_BATCH     0x1
-#define DEBUG_BLIT       0x2
-#define DEBUG_BUFFER     0x4
-#define DEBUG_CONSTANTS  0x8
-#define DEBUG_CONTEXT    0x10
-#define DEBUG_DRAW      0x20
-#define DEBUG_DYNAMIC   0x40
-#define DEBUG_FLUSH      0x80
-#define DEBUG_MAP       0x100
-#define DEBUG_PROGRAM   0x200
-#define DEBUG_REGIONS    0x400
-#define DEBUG_SAMPLER   0x800
-#define DEBUG_STATIC    0x1000
-#define DEBUG_SURFACE    0x2000
-#define DEBUG_WINSYS     0x4000
-
-#include "pipe/p_compiler.h"
+#define DBG_BLIT      0x1
+#define DBG_EMIT      0x2
+#define DBG_ATOMS     0x4
+#define DBG_FLUSH     0x8
+#define DBG_TEXTURE   0x10
+#define DBG_CONSTANTS 0x20
 
-#if defined(DEBUG) && defined(FILE_DEBUG_FLAG)
+extern unsigned i915_debug;
 
-#include "util/u_simple_screen.h"
+#ifdef DEBUG
+static INLINE boolean
+I915_DBG_ON(unsigned flags)
+{
+   return i915_debug & flags;
+}
 
 static INLINE void
-I915_DBG(
-   struct i915_context  *i915,
-   const char           *fmt,
-                        ... )
+I915_DBG(unsigned flags, const char *fmt, ...)
 {
-   if ((i915)->debug & FILE_DEBUG_FLAG) {
+   if (I915_DBG_ON(flags)) {
       va_list  args;
 
-      va_start( args, fmt );
-      debug_vprintf( fmt, args );
-      va_end( args );
+      va_start(args, fmt);
+      debug_vprintf(fmt, args);
+      va_end(args);
    }
 }
-
 #else
-
-static INLINE void
-I915_DBG(
-   struct i915_context  *i915,
-   const char           *fmt,
-                        ... )
-{
-   (void) i915;
-   (void) fmt;
-}
-
+#define I915_DBG_ON(flags) (0)
+static INLINE void I915_DBG(unsigned flags, const char *fmt, ...) {}
 #endif
 
+void i915_debug_init(struct i915_screen *i915);
 
-struct i915_winsys_batchbuffer;
-
-void i915_dump_batchbuffer( struct i915_winsys_batchbuffer *i915 );
+void i915_dump_batchbuffer(struct i915_winsys_batchbuffer *i915);
 
-void i915_debug_init( struct i915_context *i915 );
+void i915_dump_dirty(struct i915_context *i915, const char *func);
 
+void i915_dump_hardware_dirty(struct i915_context *i915, const char *func);
 
 #endif
index f41c51f299122ae88d7d2aa3e4af344102dcc326..50f49c540fe220b1d6d4211f65c072a724872f5f 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "i915_reg.h"
 #include "i915_debug.h"
+#include "i915_debug_private.h"
 #include "util/u_debug.h"
 
 
diff --git a/src/gallium/drivers/i915/i915_debug_private.h b/src/gallium/drivers/i915/i915_debug_private.h
new file mode 100644 (file)
index 0000000..b3668d0
--- /dev/null
@@ -0,0 +1,45 @@
+/**************************************************************************
+ * 
+ * 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 I915_DEBUG_PRIVATE_H
+#define I915_DEBUG_PRIVATE_H
+
+struct debug_stream 
+{
+   unsigned offset;            /* current gtt offset */
+   char *ptr;          /* pointer to gtt offset zero */
+   char *end;          /* pointer to gtt offset zero */
+   unsigned print_addresses;
+};
+
+void i915_disassemble_program(struct debug_stream *stream, 
+                             const unsigned *program, unsigned sz);
+
+#endif
index 1582168eba576f0d832d612dd963fe430fc3c66e..a2c70b11991724e5021ee0c0e8c66592ba78c6da 100644 (file)
 #include "i915_context.h"
 #include "i915_reg.h"
 #include "i915_batch.h"
+#include "i915_debug.h"
 
 
-static void i915_flush( struct pipe_context *pipe,
-                        unsigned flags,
-                        struct pipe_fence_handle **fence )
+static void i915_flush_pipe( struct pipe_context *pipe,
+                             unsigned flags,
+                             struct pipe_fence_handle **fence )
 {
    struct i915_context *i915 = i915_context(pipe);
 
@@ -66,21 +67,31 @@ static void i915_flush( struct pipe_context *pipe,
    }
 #endif
 
-#if 0
    if (i915->batch->map == i915->batch->ptr) {
       return;
    }
-#endif
 
    /* If there are no flags, just flush pending commands to hardware:
     */
    FLUSH_BATCH(fence);
    i915->vbo_flushed = 1;
-}
-
 
+   I915_DBG(DBG_FLUSH, "%s: #####\n", __FUNCTION__);
+}
 
 void i915_init_flush_functions( struct i915_context *i915 )
 {
-   i915->base.flush = i915_flush;
+   i915->base.flush = i915_flush_pipe;
+}
+
+/**
+ * Here we handle all the notifications that needs to go out on a flush.
+ * XXX might move above function to i915_pipe_flush.c and leave this here.
+ */
+void i915_flush(struct i915_context *i915, struct pipe_fence_handle **fence)
+{
+   struct i915_winsys_batchbuffer *batch = i915->batch;
+
+   batch->iws->batchbuffer_flush(batch, fence);
+   i915->hardware_dirty = ~0;
 }
index f8665acbe18975bbd33ad7c9ca8f4eb734f777b1..bd046bd9058463ecb1d9a6356aeff344cebf0c82 100644 (file)
@@ -52,8 +52,7 @@
 #include "i915_state.h"
 
 
-#undef VBUF_USE_FIFO
-#undef VBUF_MAP_BUFFER
+#define VBUF_MAP_BUFFER
 
 /**
  * Primitive renderer for i915.
@@ -79,23 +78,18 @@ struct i915_vbuf_render {
    struct i915_winsys_buffer *vbo;
    size_t vbo_size; /**< current size of allocated buffer */
    size_t vbo_alloc_size; /**< minimum buffer size to allocate */
-   size_t vbo_offset;
+   size_t vbo_hw_offset; /**< offset that we program the hardware with */
+   size_t vbo_sw_offset; /**< offset that we work with */
+   size_t vbo_index; /**< index offset to be added to all indices */
    void *vbo_ptr;
    size_t vbo_max_used;
+   size_t vbo_max_index; /**< index offset to be added to all indices */
 
 #ifndef VBUF_MAP_BUFFER
    size_t map_used_start;
    size_t map_used_end;
    size_t map_size;
 #endif
-
-#ifdef VBUF_USE_FIFO
-   /* Stuff for the pool */
-   struct util_fifo *pool_fifo;
-   unsigned pool_used;
-   unsigned pool_buffer_size;
-   boolean pool_not_used;
-#endif
 };
 
 
@@ -109,6 +103,35 @@ i915_vbuf_render(struct vbuf_render *render)
    return (struct i915_vbuf_render *)render;
 }
 
+/**
+ * If vbo state differs between renderer and context
+ * push state to the context. This function pushes
+ * hw_offset to i915->vbo_offset and vbo to i915->vbo.
+ *
+ * Side effects:
+ *    May updates context vbo_offset and vbo fields.
+ */
+static void
+i915_vbuf_update_vbo_state(struct vbuf_render *render)
+{
+   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
+   struct i915_context *i915 = i915_render->i915;
+
+   if (i915->vbo != i915_render->vbo ||
+       i915->vbo_offset != i915_render->vbo_hw_offset) {
+      i915->vbo = i915_render->vbo;
+      i915->vbo_offset = i915_render->vbo_hw_offset;
+      i915->dirty |= I915_NEW_VBO;
+   }
+}
+
+/**
+ * Callback exported to the draw module.
+ * Returns the current vertex_info.
+ *
+ * Side effects:
+ *    If state is dirty update derived state.
+ */
 static const struct vertex_info *
 i915_vbuf_render_get_vertex_info(struct vbuf_render *render)
 {
@@ -123,12 +146,18 @@ i915_vbuf_render_get_vertex_info(struct vbuf_render *render)
    return &i915->current.vertex_info;
 }
 
+/**
+ * Reserve space in the vbo for vertices.
+ *
+ * Side effects:
+ *    None.
+ */
 static boolean
 i915_vbuf_render_reserve(struct i915_vbuf_render *i915_render, size_t size)
 {
    struct i915_context *i915 = i915_render->i915;
 
-   if (i915_render->vbo_size < size + i915_render->vbo_offset)
+   if (i915_render->vbo_size < size + i915_render->vbo_sw_offset)
       return FALSE;
 
    if (i915->vbo_flushed)
@@ -137,28 +166,28 @@ i915_vbuf_render_reserve(struct i915_vbuf_render *i915_render, size_t size)
    return TRUE;
 }
 
+/**
+ * Allocate a new vbo buffer should there not be enough space for
+ * the requested number of vertices by the draw module.
+ *
+ * Side effects:
+ *    Updates hw_offset, sw_offset, index and allocates a new buffer.
+ */
 static void
 i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size)
 {
    struct i915_context *i915 = i915_render->i915;
    struct i915_winsys *iws = i915->iws;
 
-   if (i915_render->vbo) {
-#ifdef VBUF_USE_FIFO
-      if (i915_render->pool_not_used)
-         iws->buffer_destroy(iws, i915_render->vbo);
-      else
-         u_fifo_add(i915_render->pool_fifo, i915_render->vbo);
-      i915_render->vbo = NULL;
-#else
+   if (i915_render->vbo)
       iws->buffer_destroy(iws, i915_render->vbo);
-#endif
-   }
 
    i915->vbo_flushed = 0;
 
    i915_render->vbo_size = MAX2(size, i915_render->vbo_alloc_size);
-   i915_render->vbo_offset = 0;
+   i915_render->vbo_hw_offset = 0;
+   i915_render->vbo_sw_offset = 0;
+   i915_render->vbo_index = 0;
 
 #ifndef VBUF_MAP_BUFFER
    if (i915_render->vbo_size > i915_render->map_size) {
@@ -168,52 +197,51 @@ i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size)
    }
 #endif
 
-#ifdef VBUF_USE_FIFO
-   if (i915_render->vbo_size != i915_render->pool_buffer_size) {
-      i915_render->pool_not_used = TRUE;
-      i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size, 64,
-            I915_NEW_VERTEX);
-   } else {
-      i915_render->pool_not_used = FALSE;
-
-      if (i915_render->pool_used >= 2) {
-         FLUSH_BATCH(NULL);
-         i915->vbo_flushed = 0;
-         i915_render->pool_used = 0;
-      }
-      u_fifo_pop(i915_render->pool_fifo, (void**)&i915_render->vbo);
-   }
-#else
    i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size,
                                          64, I915_NEW_VERTEX);
-#endif
 }
 
+/**
+ * Callback exported to the draw module.
+ *
+ * Side effects:
+ *    Updates hw_offset, sw_offset, index and may allocate
+ *    a new buffer. Also updates may update the vbo state
+ *    on the i915 context.
+ */
 static boolean
 i915_vbuf_render_allocate_vertices(struct vbuf_render *render,
                                    ushort vertex_size,
                                    ushort nr_vertices)
 {
    struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
-   struct i915_context *i915 = i915_render->i915;
    size_t size = (size_t)vertex_size * (size_t)nr_vertices;
+   size_t offset;
 
-   /* FIXME: handle failure */
-   assert(!i915->vbo);
+   /*
+    * Align sw_offset with first multiple of vertex size from hw_offset.
+    * Set index to be the multiples from from hw_offset to sw_offset.
+    * i915_vbuf_render_new_buf will reset index, sw_offset, hw_offset
+    * when it allocates a new buffer this is correct.
+    */
+   {
+      offset = i915_render->vbo_sw_offset - i915_render->vbo_hw_offset;
+      offset = util_align_npot(offset, vertex_size);
+      i915_render->vbo_sw_offset = i915_render->vbo_hw_offset + offset;
+      i915_render->vbo_index = offset / vertex_size;
+   }
 
-   if (!i915_vbuf_render_reserve(i915_render, size)) {
-#ifdef VBUF_USE_FIFO
-      /* incase we flushed reset the number of pool buffers used */
-      if (i915->vbo_flushed)
-         i915_render->pool_used = 0;
-#endif
+   if (!i915_vbuf_render_reserve(i915_render, size))
       i915_vbuf_render_new_buf(i915_render, size);
-   }
+
+   /*
+    * If a new buffer has been alocated sw_offset,
+    * hw_offset & index will be reset by new_buf
+    */
 
    i915_render->vertex_size = vertex_size;
-   i915->vbo = i915_render->vbo;
-   i915->vbo_offset = i915_render->vbo_offset;
-   i915->dirty |= I915_NEW_VBO;
+
+   i915_vbuf_update_vbo_state(render);
 
    if (!i915_render->vbo)
       return FALSE;
@@ -232,7 +260,7 @@ i915_vbuf_render_map_vertices(struct vbuf_render *render)
 
 #ifdef VBUF_MAP_BUFFER
    i915_render->vbo_ptr = iws->buffer_map(iws, i915_render->vbo, TRUE);
-   return (unsigned char *)i915_render->vbo_ptr + i915_render->vbo_offset;
+   return (unsigned char *)i915_render->vbo_ptr + i915_render->vbo_sw_offset;
 #else
    (void)iws;
    return (unsigned char *)i915_render->vbo_ptr;
@@ -248,6 +276,7 @@ i915_vbuf_render_unmap_vertices(struct vbuf_render *render,
    struct i915_context *i915 = i915_render->i915;
    struct i915_winsys *iws = i915->iws;
 
+   i915_render->vbo_max_index = max_index;
    i915_render->vbo_max_used = MAX2(i915_render->vbo_max_used, i915_render->vertex_size * (max_index + 1));
 #ifdef VBUF_MAP_BUFFER
    iws->buffer_unmap(iws, i915_render->vbo);
@@ -255,13 +284,36 @@ i915_vbuf_render_unmap_vertices(struct vbuf_render *render,
    i915_render->map_used_start = i915_render->vertex_size * min_index;
    i915_render->map_used_end = i915_render->vertex_size * (max_index + 1);
    iws->buffer_write(iws, i915_render->vbo,
-                     i915_render->map_used_start + i915_render->vbo_offset,
+                     i915_render->map_used_start + i915_render->vbo_sw_offset,
                      i915_render->map_used_end - i915_render->map_used_start,
                      (unsigned char *)i915_render->vbo_ptr + i915_render->map_used_start);
 
 #endif
 }
 
+/**
+ * Ensure that the given max_index given is not larger ushort max.
+ * If it is larger then ushort max it advanced the hw_offset to the
+ * same position in the vbo as sw_offset and set index to zero.
+ *
+ * Side effects:
+ *    On failure update hw_offset and index.
+ */
+static void
+i915_vbuf_ensure_index_bounds(struct vbuf_render *render,
+                              unsigned max_index)
+{
+   struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
+
+   if (max_index + i915_render->vbo_index < ((1 << 17) - 1))
+      return;
+
+   i915_render->vbo_hw_offset = i915_render->vbo_sw_offset;
+   i915_render->vbo_index = 0;
+
+   i915_vbuf_update_vbo_state(render);
+}
+
 static boolean
 i915_vbuf_render_set_primitive(struct vbuf_render *render, 
                                unsigned prim)
@@ -327,7 +379,9 @@ draw_arrays_generate_indices(struct vbuf_render *render,
    struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
    struct i915_context *i915 = i915_render->i915;
    unsigned i;
-   unsigned end = start + nr;
+   unsigned end = start + nr + i915_render->vbo_index;
+   start += i915_render->vbo_index;
+
    switch(type) {
    case 0:
       for (i = start; i+1 < end; i += 2)
@@ -391,16 +445,18 @@ draw_arrays_fallback(struct vbuf_render *render,
    struct i915_context *i915 = i915_render->i915;
    unsigned nr_indices;
 
+   nr_indices = draw_arrays_calc_nr_indices(nr, i915_render->fallback);
+   if (!nr_indices)
+      return;
+
+   i915_vbuf_ensure_index_bounds(render, start + nr_indices);
+
    if (i915->dirty)
       i915_update_derived(i915);
 
    if (i915->hardware_dirty)
       i915_emit_hardware_state(i915);
 
-   nr_indices = draw_arrays_calc_nr_indices(nr, i915_render->fallback);
-   if (!nr_indices)
-      return;
-
    if (!BEGIN_BATCH(1 + (nr_indices + 1)/2, 1)) {
       FLUSH_BATCH(NULL);
 
@@ -415,6 +471,7 @@ draw_arrays_fallback(struct vbuf_render *render,
          goto out;
       }
    }
+
    OUT_BATCH(_3DPRIMITIVE |
              PRIM_INDIRECT |
              i915_render->hwprim |
@@ -440,6 +497,9 @@ i915_vbuf_render_draw_arrays(struct vbuf_render *render,
       return;
    }
 
+   i915_vbuf_ensure_index_bounds(render, start + nr);
+   start += i915_render->vbo_index;
+
    if (i915->dirty)
       i915_update_derived(i915);
 
@@ -485,35 +545,36 @@ draw_generate_indices(struct vbuf_render *render,
    struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
    struct i915_context *i915 = i915_render->i915;
    unsigned i;
+   unsigned o = i915_render->vbo_index;
 
    switch(type) {
    case 0:
       for (i = 0; i + 1 < nr_indices; i += 2) {
-         OUT_BATCH(indices[i] | indices[i+1] << 16);
+         OUT_BATCH((o+indices[i]) | (o+indices[i+1]) << 16);
       }
       if (i < nr_indices) {
-         OUT_BATCH(indices[i]);
+         OUT_BATCH((o+indices[i]));
       }
       break;
    case PIPE_PRIM_LINE_LOOP:
       if (nr_indices >= 2) {
          for (i = 1; i < nr_indices; i++)
-            OUT_BATCH(indices[i-1] | indices[i] << 16);
-         OUT_BATCH(indices[i-1] | indices[0] << 16);
+            OUT_BATCH((o+indices[i-1]) | (o+indices[i]) << 16);
+         OUT_BATCH((o+indices[i-1]) | (o+indices[0]) << 16);
       }
       break;
    case PIPE_PRIM_QUADS:
       for (i = 0; i + 3 < nr_indices; i += 4) {
-         OUT_BATCH(indices[i+0] | indices[i+1] << 16);
-         OUT_BATCH(indices[i+3] | indices[i+1] << 16);
-         OUT_BATCH(indices[i+2] | indices[i+3] << 16);
+         OUT_BATCH((o+indices[i+0]) | (o+indices[i+1]) << 16);
+         OUT_BATCH((o+indices[i+3]) | (o+indices[i+1]) << 16);
+         OUT_BATCH((o+indices[i+2]) | (o+indices[i+3]) << 16);
       }
       break;
    case PIPE_PRIM_QUAD_STRIP:
       for (i = 0; i + 3 < nr_indices; i += 2) {
-         OUT_BATCH(indices[i+0] | indices[i+1] << 16);
-         OUT_BATCH(indices[i+3] | indices[i+2] << 16);
-         OUT_BATCH(indices[i+0] | indices[i+3] << 16);
+         OUT_BATCH((o+indices[i+0]) | (o+indices[i+1]) << 16);
+         OUT_BATCH((o+indices[i+3]) | (o+indices[i+2]) << 16);
+         OUT_BATCH((o+indices[i+0]) | (o+indices[i+3]) << 16);
       }
       break;
    default:
@@ -558,6 +619,8 @@ i915_vbuf_render_draw_elements(struct vbuf_render *render,
    if (!nr_indices)
       return;
 
+   i915_vbuf_ensure_index_bounds(render, i915_render->vbo_max_index);
+
    if (i915->dirty)
       i915_update_derived(i915);
 
@@ -597,14 +660,15 @@ static void
 i915_vbuf_render_release_vertices(struct vbuf_render *render)
 {
    struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
-   struct i915_context *i915 = i915_render->i915;
-
-   assert(i915->vbo);
 
-   i915_render->vbo_offset += i915_render->vbo_max_used;
+   i915_render->vbo_sw_offset += i915_render->vbo_max_used;
    i915_render->vbo_max_used = 0;
-   i915->vbo = NULL;
-   i915->dirty |= I915_NEW_VBO;
+
+   /*
+    * Micro optimization, by calling update here we the offset change
+    * will be picked up on the next pipe_context::draw_*.
+    */
+   i915_vbuf_update_vbo_state(render);
 }
 
 static void
@@ -652,7 +716,8 @@ i915_vbuf_render_create(struct i915_context *i915)
    i915_render->vbo = NULL;
    i915_render->vbo_ptr = NULL;
    i915_render->vbo_size = 0;
-   i915_render->vbo_offset = 0;
+   i915_render->vbo_hw_offset = 0;
+   i915_render->vbo_sw_offset = 0;
    i915_render->vbo_alloc_size = i915_render->base.max_vertex_buffer_bytes * 4;
 
 #ifdef VBUF_USE_POOL
diff --git a/src/gallium/drivers/i915/i915_public.h b/src/gallium/drivers/i915/i915_public.h
new file mode 100644 (file)
index 0000000..588654d
--- /dev/null
@@ -0,0 +1,13 @@
+
+#ifndef I915_PUBLIC_H
+#define I915_PUBLIC_H
+
+struct i915_winsys;
+struct pipe_screen;
+
+/**
+ * Create i915 pipe_screen.
+ */
+struct pipe_screen * i915_screen_create(struct i915_winsys *iws);
+
+#endif
index 17fcdee379a5df5a870563eb86134eab6cbcf6ab..752ddaae7b1571719a2e788ab238867ff7cb6548 100644 (file)
@@ -42,6 +42,7 @@
 #include "i915_resource.h"
 #include "i915_screen.h"
 #include "i915_winsys.h"
+#include "i915_debug.h"
 
 
 #define DEBUG_TEXTURES 0
@@ -800,12 +801,10 @@ i915_texture_create(struct pipe_screen *screen,
    ws->buffer_unmap(ws, tex->buffer);
 #endif
 
-#if DEBUG_TEXTURES
-   debug_printf("%s: %p size %u, stride %u, blocks (%u, %u)\n", __func__,
-                tex, (unsigned int)tex_size, tex->stride,
-                tex->stride / util_format_get_blocksize(tex->b.b.format),
-                tex->total_nblocksy);
-#endif
+   I915_DBG(DBG_TEXTURE, "%s: %p size %u, stride %u, blocks (%u, %u)\n", __func__,
+            tex, (unsigned int)tex_size, tex->stride,
+            tex->stride / util_format_get_blocksize(tex->b.b.format),
+            tex->total_nblocksy);
 
    return &tex->b.b;
 
@@ -846,12 +845,18 @@ i915_texture_from_handle(struct pipe_screen * screen,
    tex->b.b.screen = screen;
 
    tex->stride = stride;
+   tex->total_nblocksy = align_nblocksy(tex->b.b.format, tex->b.b.height0, 8);
 
    i915_texture_set_level_info(tex, 0, 1);
    i915_texture_set_image_offset(tex, 0, 0, 0, 0);
 
    tex->buffer = buffer;
 
+   I915_DBG(DBG_TEXTURE, "%s: %p stride %u, blocks (%ux%u)\n", __func__,
+            tex, tex->stride,
+            tex->stride / util_format_get_blocksize(tex->b.b.format),
+            tex->total_nblocksy);
+
    return &tex->b.b;
 }
 
index f82426520cd486eb30d10c217247e12a4c35212e..77345d5f7117fe3d369984245188bdd71aab3767 100644 (file)
 #include "util/u_string.h"
 
 #include "i915_reg.h"
+#include "i915_debug.h"
 #include "i915_context.h"
 #include "i915_screen.h"
 #include "i915_surface.h"
 #include "i915_resource.h"
 #include "i915_winsys.h"
+#include "i915_public.h"
 
 
 /*
@@ -330,5 +332,7 @@ i915_screen_create(struct i915_winsys *iws)
    i915_init_screen_resource_functions(is);
    i915_init_screen_surface_functions(is);
 
+   i915_debug_init(is);
+
    return &is->base;
 }
index 86c6b0027d5f84e3c590e3876e52f0bc171cd367..b4074dc35ba9d3964efc0487be0a89b3ae23c783 100644 (file)
@@ -35,16 +35,22 @@ struct i915_context;
 
 
 struct i915_tracked_state {
+   const char *name;
+   void (*update)(struct i915_context *);
    unsigned dirty;
-   void (*update)( struct i915_context * );
 };
 
-void i915_update_immediate( struct i915_context *i915 );
-void i915_update_dynamic( struct i915_context *i915 );
-void i915_update_derived( struct i915_context *i915 );
-void i915_update_samplers( struct i915_context *i915 );
-void i915_update_textures(struct i915_context *i915);
+extern struct i915_tracked_state i915_update_vertex_layout;
 
-void i915_emit_hardware_state( struct i915_context *i915 );
+extern struct i915_tracked_state i915_hw_samplers;
+extern struct i915_tracked_state i915_hw_sampler_views;
+extern struct i915_tracked_state i915_hw_immediate;
+extern struct i915_tracked_state i915_hw_dynamic;
+extern struct i915_tracked_state i915_hw_fs;
+extern struct i915_tracked_state i915_hw_framebuffer;
+extern struct i915_tracked_state i915_hw_constants;
+
+void i915_update_derived(struct i915_context *i915);
+void i915_emit_hardware_state(struct i915_context *i915);
 
 #endif
index 4da46772b5d8e049b806214b37e3b58c54474a97..1d4026a214e9d9e6504d3e4432052a78efe82b09 100644 (file)
 #include "draw/draw_vertex.h"
 #include "i915_context.h"
 #include "i915_state.h"
+#include "i915_debug.h"
 #include "i915_reg.h"
 
 
 
-/**
+/***********************************************************************
  * Determine the hardware vertex layout.
  * Depends on vertex/fragment shader state.
  */
-static void calculate_vertex_layout( struct i915_context *i915 )
+static void calculate_vertex_layout(struct i915_context *i915)
 {
    const struct i915_fragment_shader *fs = i915->fs;
    const enum interp_mode colorInterp = i915->rasterizer->color_interp;
@@ -146,37 +147,38 @@ static void calculate_vertex_layout( struct i915_context *i915 )
    }
 }
 
+struct i915_tracked_state i915_update_vertex_layout = {
+   "vertex_layout",
+   calculate_vertex_layout,
+   I915_NEW_RASTERIZER | I915_NEW_FS | I915_NEW_VS
+};
 
 
 
-/* Hopefully this will remain quite simple, otherwise need to pull in
- * something like the state tracker mechanism.
+/***********************************************************************
  */
-void i915_update_derived( struct i915_context *i915 )
+static struct i915_tracked_state *atoms[] = {
+   &i915_update_vertex_layout,
+   &i915_hw_samplers,
+   &i915_hw_sampler_views,
+   &i915_hw_immediate,
+   &i915_hw_dynamic,
+   &i915_hw_fs,
+   &i915_hw_framebuffer,
+   &i915_hw_constants,
+   NULL,
+};
+
+void i915_update_derived(struct i915_context *i915)
 {
-   if (i915->dirty & (I915_NEW_RASTERIZER | I915_NEW_FS | I915_NEW_VS))
-      calculate_vertex_layout( i915 );
+   int i;
 
-   if (i915->dirty & (I915_NEW_SAMPLER | I915_NEW_SAMPLER_VIEW))
-      i915_update_samplers(i915);
+   if (I915_DBG_ON(DBG_ATOMS))
+      i915_dump_dirty(i915, __FUNCTION__);
 
-   if (i915->dirty & I915_NEW_SAMPLER_VIEW)
-      i915_update_textures(i915);
-
-   if (i915->dirty)
-      i915_update_immediate( i915 );
-
-   if (i915->dirty)
-      i915_update_dynamic( i915 );
-
-   if (i915->dirty & I915_NEW_FS) {
-      i915->hardware_dirty |= I915_HW_PROGRAM; /* XXX right? */
-   }
-
-   /* HW emit currently references framebuffer state directly:
-    */
-   if (i915->dirty & I915_NEW_FRAMEBUFFER)
-      i915->hardware_dirty |= I915_HW_STATIC;
+   for (i = 0; atoms[i]; i++)
+      if (atoms[i]->dirty & i915->dirty)
+         atoms[i]->update(i915);
 
    i915->dirty = 0;
 }
index 9c6723b39167906a35eedea81c5dca625c893437..d61a8c3407f31500ffefbcee06ba0d3e5dd57b2b 100644 (file)
@@ -1,8 +1,8 @@
 /**************************************************************************
- * 
+ *
  * 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
  * distribute, sub license, and/or sell copies of the Software, and to
  * permit persons to whom the Software is furnished to do so, subject to
  * the following conditions:
- * 
+ *
  * The above copyright notice and this permission notice (including the
  * next paragraph) shall be included in all copies or substantial portions
  * of the Software.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
@@ -22,7 +22,7 @@
  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
+ *
  **************************************************************************/
 
 #include "i915_batch.h"
 #include "i915_context.h"
 #include "i915_reg.h"
 #include "i915_state.h"
-#include "util/u_math.h"
+
 #include "util/u_memory.h"
 #include "util/u_pack_color.h"
 
-#define FILE_DEBUG_FLAG DEBUG_STATE
 
 /* State that we have chosen to store in the DYNAMIC segment of the
- * i915 indirect state mechanism.  
+ * i915 indirect state mechanism.
  *
  * Can't cache these in the way we do the static state, as there is no
  * start/size in the command packet, instead an 'end' value that gets
  * (active) state every time a 4kb boundary is crossed.
  */
 
-static INLINE void set_dynamic_indirect( struct i915_context *i915,
-                                        unsigned offset,
-                                        const unsigned *src,
-                                        unsigned dwords )
+static INLINE void set_dynamic_indirect(struct i915_context *i915,
+                                        unsigned offset,
+                                        const unsigned *src,
+                                        unsigned dwords)
 {
    unsigned i;
 
+   if (!memcmp(src, &i915->current.dynamic[offset], dwords * 4))
+      return;
+
    for (i = 0; i < dwords; i++)
       i915->current.dynamic[offset + i] = src[i];
 
@@ -61,38 +63,41 @@ static INLINE void set_dynamic_indirect( struct i915_context *i915,
 }
 
 
+
 /***********************************************************************
- * Modes4: stencil masks and logicop 
+ * Modes4: stencil masks and logicop
  */
-static void upload_MODES4( struct i915_context *i915 )
+static void upload_MODES4(struct i915_context *i915)
 {
    unsigned modes4 = 0;
 
-   /* I915_NEW_STENCIL */
+   /* I915_NEW_STENCIL
+    */
    modes4 |= i915->depth_stencil->stencil_modes4;
-   /* I915_NEW_BLEND */
+
+   /* I915_NEW_BLEND
+     */
    modes4 |= i915->blend->modes4;
 
-   /* Always, so that we know when state is in-active: 
+   /* Always, so that we know when state is in-active:
     */
-   set_dynamic_indirect( i915, 
-                        I915_DYNAMIC_MODES4,
-                        &modes4,
-                        1 );
+   set_dynamic_indirect(i915,
+                        I915_DYNAMIC_MODES4,
+                        &modes4,
+                        1);
 }
 
 const struct i915_tracked_state i915_upload_MODES4 = {
-   I915_NEW_BLEND | I915_NEW_DEPTH_STENCIL,
-   upload_MODES4
+   "MODES4",
+   upload_MODES4,
+   I915_NEW_BLEND | I915_NEW_DEPTH_STENCIL
 };
 
 
 
-
 /***********************************************************************
  */
-
-static void upload_BFO( struct i915_context *i915 )
+static void upload_BFO(struct i915_context *i915)
 {
    unsigned bfo[2];
    bfo[0] = i915->depth_stencil->bfo[0];
@@ -101,88 +106,89 @@ static void upload_BFO( struct i915_context *i915 )
    if (bfo[0] & BFO_ENABLE_STENCIL_REF) {
       bfo[0] |= i915->stencil_ref.ref_value[1] << BFO_STENCIL_REF_SHIFT;
    }
-   set_dynamic_indirect( i915,
-                        I915_DYNAMIC_BFO_0,
-                        &(bfo[0]),
-                        2 );
+
+   set_dynamic_indirect(i915,
+                        I915_DYNAMIC_BFO_0,
+                        &(bfo[0]),
+                        2);
 }
 
 const struct i915_tracked_state i915_upload_BFO = {
-   I915_NEW_DEPTH_STENCIL,
-   upload_BFO
+   "BFO",
+   upload_BFO,
+   I915_NEW_DEPTH_STENCIL
 };
 
 
+
 /***********************************************************************
  */
-
-
-static void upload_BLENDCOLOR( struct i915_context *i915 )
+static void upload_BLENDCOLOR(struct i915_context *i915)
 {
    unsigned bc[2];
 
-   memset( bc, 0, sizeof(bc) );
+   memset(bc, 0, sizeof(bc));
 
-   /* I915_NEW_BLEND {_COLOR} 
+   /* I915_NEW_BLEND
     */
    {
       const float *color = i915->blend_color.color;
 
       bc[0] = _3DSTATE_CONST_BLEND_COLOR_CMD;
-      bc[1] = pack_ui32_float4( color[0],
-                               color[1],
-                               color[2], 
-                               color[3] );
+      bc[1] = pack_ui32_float4(color[0],
+                               color[1],
+                               color[2],
+                               color[3]);
    }
 
-   set_dynamic_indirect( i915, 
-                        I915_DYNAMIC_BC_0,
-                        bc,
-                        2 );
+   set_dynamic_indirect(i915,
+                        I915_DYNAMIC_BC_0,
+                        bc,
+                        2);
 }
 
 const struct i915_tracked_state i915_upload_BLENDCOLOR = {
-   I915_NEW_BLEND,
-   upload_BLENDCOLOR
+   "BLENDCOLOR",
+   upload_BLENDCOLOR,
+   I915_NEW_BLEND
 };
 
-/***********************************************************************
- */
 
 
-static void upload_IAB( struct i915_context *i915 )
+/***********************************************************************
+ */
+static void upload_IAB(struct i915_context *i915)
 {
    unsigned iab = i915->blend->iab;
 
-
-   set_dynamic_indirect( i915,
-                        I915_DYNAMIC_IAB,
-                        &iab,
-                        1 );
+   set_dynamic_indirect(i915,
+                        I915_DYNAMIC_IAB,
+                        &iab,
+                        1);
 }
 
 const struct i915_tracked_state i915_upload_IAB = {
-   I915_NEW_BLEND,
-   upload_IAB
+   "IAB",
+   upload_IAB,
+   I915_NEW_BLEND
 };
 
 
+
 /***********************************************************************
  */
-
-
-
-static void upload_DEPTHSCALE( struct i915_context *i915 )
+static void upload_DEPTHSCALE(struct i915_context *i915)
 {
-   set_dynamic_indirect( i915,
-                        I915_DYNAMIC_DEPTHSCALE_0,
-                        &(i915->rasterizer->ds[0].u),
-                        2 );
+   set_dynamic_indirect(i915,
+                        I915_DYNAMIC_DEPTHSCALE_0,
+                        &(i915->rasterizer->ds[0].u),
+                        2);
 }
 
 const struct i915_tracked_state i915_upload_DEPTHSCALE = {
-   I915_NEW_RASTERIZER,
-   upload_DEPTHSCALE
+   "DEPTHSCALE",
+   upload_DEPTHSCALE,
+   I915_NEW_RASTERIZER
 };
 
 
@@ -196,10 +202,9 @@ const struct i915_tracked_state i915_upload_DEPTHSCALE = {
  * XXX: does stipple pattern need to be adjusted according to
  * the window position?
  *
- * XXX: possibly need workaround for conform paths test. 
+ * XXX: possibly need workaround for conform paths test.
  */
-
-static void upload_STIPPLE( struct i915_context *i915 )
+static void upload_STIPPLE(struct i915_context *i915)
 {
    unsigned st[2];
 
@@ -210,7 +215,6 @@ static void upload_STIPPLE( struct i915_context *i915 )
     */
    st[1] |= i915->rasterizer->st;
 
-
    /* I915_NEW_STIPPLE
     */
    {
@@ -225,73 +229,75 @@ static void upload_STIPPLE( struct i915_context *i915 )
       /* Not sure what to do about fallbacks, so for now just dont:
        */
       st[1] |= ((p[0] << 0) |
-               (p[1] << 4) |
-               (p[2] << 8) | 
-               (p[3] << 12));
+                (p[1] << 4) |
+                (p[2] << 8) |
+                (p[3] << 12));
    }
 
-
-   set_dynamic_indirect( i915, 
-                        I915_DYNAMIC_STP_0,
-                        &st[0],
-                        2 );
+   set_dynamic_indirect(i915,
+                        I915_DYNAMIC_STP_0,
+                        &st[0],
+                        2);
 }
 
-
 const struct i915_tracked_state i915_upload_STIPPLE = {
-   I915_NEW_RASTERIZER | I915_NEW_STIPPLE,
-   upload_STIPPLE
+   "STIPPLE",
+   upload_STIPPLE,
+   I915_NEW_RASTERIZER | I915_NEW_STIPPLE
 };
 
 
 
 /***********************************************************************
- * Scissor.
+ * Scissor enable
  */
 static void upload_SCISSOR_ENABLE( struct i915_context *i915 )
 {
-   set_dynamic_indirect( i915,
-                        I915_DYNAMIC_SC_ENA_0,
-                        &(i915->rasterizer->sc[0]),
-                        1 );
+   set_dynamic_indirect(i915,
+                        I915_DYNAMIC_SC_ENA_0,
+                        &(i915->rasterizer->sc[0]),
+                        1);
 }
 
 const struct i915_tracked_state i915_upload_SCISSOR_ENABLE = {
-   I915_NEW_RASTERIZER,
-   upload_SCISSOR_ENABLE
+   "SCISSOR ENABLE",
+   upload_SCISSOR_ENABLE,
+   I915_NEW_RASTERIZER
 };
 
 
 
-static void upload_SCISSOR_RECT( struct i915_context *i915 )
+/***********************************************************************
+ * Scissor rect
+ */
+static void upload_SCISSOR_RECT(struct i915_context *i915)
 {
    unsigned x1 = i915->scissor.minx;
    unsigned y1 = i915->scissor.miny;
    unsigned x2 = i915->scissor.maxx;
    unsigned y2 = i915->scissor.maxy;
    unsigned sc[3];
+
    sc[0] = _3DSTATE_SCISSOR_RECT_0_CMD;
    sc[1] = (y1 << 16) | (x1 & 0xffff);
    sc[2] = (y2 << 16) | (x2 & 0xffff);
 
-   set_dynamic_indirect( i915, 
-                        I915_DYNAMIC_SC_RECT_0,
-                        &sc[0],
-                        3 );
+   set_dynamic_indirect(i915,
+                        I915_DYNAMIC_SC_RECT_0,
+                        &sc[0],
+                        3);
 }
 
-
 const struct i915_tracked_state i915_upload_SCISSOR_RECT = {
-   I915_NEW_SCISSOR,
-   upload_SCISSOR_RECT
+   "SCISSOR RECT",
+   upload_SCISSOR_RECT,
+   I915_NEW_SCISSOR
 };
 
 
 
-
-
-
+/***********************************************************************
+ */
 static const struct i915_tracked_state *atoms[] = {
    &i915_upload_MODES4,
    &i915_upload_BFO,
@@ -306,12 +312,17 @@ static const struct i915_tracked_state *atoms[] = {
 /* These will be dynamic indirect state commands, but for now just end
  * up on the batch buffer with everything else.
  */
-void i915_update_dynamic( struct i915_context *i915 )
+static void update_dynamic(struct i915_context *i915)
 {
    int i;
 
    for (i = 0; i < Elements(atoms); i++)
       if (i915->dirty & atoms[i]->dirty)
-        atoms[i]->update( i915 );
+         atoms[i]->update(i915);
 }
 
+struct i915_tracked_state i915_hw_dynamic = {
+   "dynamic",
+   update_dynamic,
+   ~0 /* all state atoms, becuase we do internal checking */
+};
index 22082fece82be67e6e20d826a09e7b83633e739f..7bb7893d93995279e4e17165039608c6c401b429 100644 (file)
@@ -29,6 +29,7 @@
 #include "i915_reg.h"
 #include "i915_context.h"
 #include "i915_batch.h"
+#include "i915_debug.h"
 #include "i915_reg.h"
 #include "i915_resource.h"
 
@@ -111,15 +112,20 @@ i915_emit_hardware_state(struct i915_context *i915 )
                              3
                            ) * 3/2; /* plus 50% margin */
 
-#if 0
-   debug_printf("i915_emit_hardware_state: %d dwords, %d relocs\n", dwords, relocs);
-#endif
-   
+   uintptr_t save_ptr;
+   size_t save_relocs;
+
+   if (I915_DBG_ON(DBG_ATOMS))
+      i915_dump_hardware_dirty(i915, __FUNCTION__);
+
    if(!BEGIN_BATCH(dwords, relocs)) {
       FLUSH_BATCH(NULL);
       assert(BEGIN_BATCH(dwords, relocs));
    }
 
+   save_ptr = (uintptr_t)i915->batch->ptr;
+   save_relocs = i915->batch->relocs;
+
    /* 14 dwords, 0 relocs */
    if (i915->hardware_dirty & I915_HW_INVARIENT)
    {
@@ -169,7 +175,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
       OUT_BATCH(_3DSTATE_LOAD_INDIRECT | 0);
       OUT_BATCH(0);
    }
-   
+
    /* 7 dwords, 1 relocs */
    if (i915->hardware_dirty & I915_HW_IMMEDIATE)
    {
@@ -195,7 +201,8 @@ i915_emit_hardware_state(struct i915_context *i915 )
       OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S5]);
       OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S6]);
    } 
-   
+
+#if 01
    /* I915_MAX_DYNAMIC dwords, 0 relocs */
    if (i915->hardware_dirty & I915_HW_DYNAMIC) 
    {
@@ -204,7 +211,9 @@ i915_emit_hardware_state(struct i915_context *i915 )
          OUT_BATCH(i915->current.dynamic[i]);
       }
    }
-   
+#endif
+
+#if 01
    /* 8 dwords, 2 relocs */
    if (i915->hardware_dirty & I915_HW_STATIC)
    {
@@ -253,10 +262,10 @@ i915_emit_hardware_state(struct i915_context *i915 )
                    I915_USAGE_RENDER,
                    depth_surface->offset);
       }
-   
+
       {
          unsigned cformat, zformat = 0;
-      
+
          if (cbuf_surface)
             cformat = cbuf_surface->format;
          else
@@ -275,6 +284,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
                    zformat );
       }
    }
+#endif
 
 #if 01
       /* texture images */
@@ -314,7 +324,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
    {
       if (i915->current.sampler_enable_nr) {
          int i;
-         
+
          OUT_BATCH( _3DSTATE_SAMPLER_STATE | 
                     (3 * i915->current.sampler_enable_nr) );
 
@@ -331,9 +341,10 @@ i915_emit_hardware_state(struct i915_context *i915 )
    }
 #endif
 
+#if 01
    /* constants */
    /* 2 + I915_MAX_CONSTANT*4 dwords, 0 relocs */
-   if (i915->hardware_dirty & I915_HW_PROGRAM)
+   if (i915->hardware_dirty & I915_HW_CONSTANTS)
    {
       /* Collate the user-defined constants with the fragment shader's
        * immediates according to the constant_flags[] array.
@@ -370,7 +381,9 @@ i915_emit_hardware_state(struct i915_context *i915 )
          }
       }
    }
+#endif
 
+#if 01
    /* Fragment program */
    /* i915->current.program_len dwords, 0 relocs */
    if (i915->hardware_dirty & I915_HW_PROGRAM)
@@ -382,7 +395,9 @@ i915_emit_hardware_state(struct i915_context *i915 )
          OUT_BATCH(i915->fs->program[i]);
       }
    }
+#endif
 
+#if 01
    /* drawing surface size */
    /* 6 dwords, 0 relocs */
    {
@@ -398,7 +413,11 @@ i915_emit_hardware_state(struct i915_context *i915 )
       OUT_BATCH(0);
       OUT_BATCH(0);
    }
+#endif
 
+   I915_DBG(DBG_EMIT, "%s: used %d dwords, %d relocs\n", __FUNCTION__,
+            ((uintptr_t)i915->batch->ptr - save_ptr) / 4,
+            i915->batch->relocs - save_relocs);
 
    i915->hardware_dirty = 0;
 }
diff --git a/src/gallium/drivers/i915/i915_state_fpc.c b/src/gallium/drivers/i915/i915_state_fpc.c
new file mode 100644 (file)
index 0000000..ec7cec0
--- /dev/null
@@ -0,0 +1,59 @@
+/**************************************************************************
+ *
+ * Copyright Â© 2010 Jakob Bornecrantz
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "i915_reg.h"
+#include "i915_context.h"
+#include "i915_state.h"
+
+
+
+/***********************************************************************
+ */
+static void update_hw_constants(struct i915_context *i915)
+{
+   i915->hardware_dirty |= I915_HW_CONSTANTS;
+}
+
+struct i915_tracked_state i915_hw_constants = {
+   "hw_constants",
+   update_hw_constants,
+   I915_NEW_CONSTANTS | I915_NEW_FS
+};
+
+
+
+/***********************************************************************
+ */
+static void update_fs(struct i915_context *i915)
+{
+   i915->hardware_dirty |= I915_HW_PROGRAM;
+}
+
+struct i915_tracked_state i915_hw_fs = {
+   "fs",
+   update_fs,
+   I915_NEW_FS
+};
index 8cec699285c6afe956aa5482836bcec9e94d81a3..f9ade7077f245a1a9493758168803dbee778702a 100644 (file)
@@ -1,8 +1,8 @@
 /**************************************************************************
- * 
+ *
  * 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
  * distribute, sub license, and/or sell copies of the Software, and to
  * permit persons to whom the Software is furnished to do so, subject to
  * the following conditions:
- * 
+ *
  * The above copyright notice and this permission notice (including the
  * next paragraph) shall be included in all copies or substantial portions
  * of the Software.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 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 "i915_state_inlines.h"
 #include "i915_context.h"
 #include "i915_state.h"
 
 
 /***********************************************************************
- * S0,S1: Vertex buffer state.  
+ * S0,S1: Vertex buffer state.
  */
 static void upload_S0S1(struct i915_context *i915)
 {
    unsigned LIS0, LIS1;
 
-   /* I915_NEW_VBO */
-   /* TODO: re-use vertex buffers here? */
+   /* I915_NEW_VBO
+    */
    LIS0 = i915->vbo_offset;
 
-   /* I915_NEW_VERTEX_SIZE -- do this where the vertex size is calculated! 
+   /* I915_NEW_VERTEX_SIZE
     */
+   /* XXX do this where the vertex size is calculated! */
    {
       unsigned vertex_size = i915->current.vertex_info.size;
 
       LIS1 = ((vertex_size << 24) |
-             (vertex_size << 16));
+              (vertex_size << 16));
    }
 
-   /* I915_NEW_VBO */
-   /* TODO: use a vertex generation number to track vbo changes */
+   /* I915_NEW_VBO
+    */
    if (1 ||
        i915->current.immediate[I915_IMMEDIATE_S0] != LIS0 ||
-       i915->current.immediate[I915_IMMEDIATE_S1] != LIS1) 
+       i915->current.immediate[I915_IMMEDIATE_S1] != LIS1)
    {
       i915->current.immediate[I915_IMMEDIATE_S0] = LIS0;
       i915->current.immediate[I915_IMMEDIATE_S1] = LIS1;
@@ -78,13 +79,13 @@ static void upload_S0S1(struct i915_context *i915)
 }
 
 const struct i915_tracked_state i915_upload_S0S1 = {
-   I915_NEW_VBO | I915_NEW_VERTEX_FORMAT,
-   upload_S0S1
+   "imm S0 S1",
+   upload_S0S1,
+   I915_NEW_VBO | I915_NEW_VERTEX_FORMAT
 };
 
 
 
-
 /***********************************************************************
  * S4: Vertex format, rasterization state
  */
@@ -92,7 +93,8 @@ static void upload_S2S4(struct i915_context *i915)
 {
    unsigned LIS2, LIS4;
 
-   /* I915_NEW_VERTEX_FORMAT */
+   /* I915_NEW_VERTEX_FORMAT
+    */
    {
       LIS2 = i915->current.vertex_info.hwfmt[1];
       LIS4 = i915->current.vertex_info.hwfmt[0];
@@ -113,35 +115,38 @@ static void upload_S2S4(struct i915_context *i915)
    }
 }
 
-
 const struct i915_tracked_state i915_upload_S2S4 = {
-   I915_NEW_RASTERIZER | I915_NEW_VERTEX_FORMAT,
-   upload_S2S4
+   "imm S2 S4",
+   upload_S2S4,
+   I915_NEW_RASTERIZER | I915_NEW_VERTEX_FORMAT
 };
 
 
 
 /***********************************************************************
- * 
  */
-static void upload_S5( struct i915_context *i915 )
+static void upload_S5(struct i915_context *i915)
 {
    unsigned LIS5 = 0;
 
+   /* I915_NEW_DEPTH_STENCIL
+    */
    LIS5 |= i915->depth_stencil->stencil_LIS5;
    /* hope it's safe to set stencil ref value even if stencil test is disabled? */
    LIS5 |= i915->stencil_ref.ref_value[0] << S5_STENCIL_REF_SHIFT;
 
+   /* I915_NEW_BLEND
+    */
    LIS5 |= i915->blend->LIS5;
 
 #if 0
-   /* I915_NEW_RASTERIZER */
+   /* I915_NEW_RASTERIZER
+    */
    if (i915->state.Polygon->OffsetFill) {
       LIS5 |= S5_GLOBAL_DEPTH_OFFSET_ENABLE;
    }
 #endif
 
-
    if (LIS5 != i915->current.immediate[I915_IMMEDIATE_S5]) {
       i915->current.immediate[I915_IMMEDIATE_S5] = LIS5;
       i915->hardware_dirty |= I915_HW_IMMEDIATE;
@@ -149,14 +154,16 @@ static void upload_S5( struct i915_context *i915 )
 }
 
 const struct i915_tracked_state i915_upload_S5 = {
-   (I915_NEW_DEPTH_STENCIL | I915_NEW_BLEND | I915_NEW_RASTERIZER),
-   upload_S5
+   "imm S5",
+   upload_S5,
+   I915_NEW_DEPTH_STENCIL | I915_NEW_BLEND | I915_NEW_RASTERIZER
 };
 
 
+
 /***********************************************************************
  */
-static void upload_S6( struct i915_context *i915 )
+static void upload_S6(struct i915_context *i915)
 {
    unsigned LIS6 = (2 << S6_TRISTRIP_PV_SHIFT);
 
@@ -180,14 +187,16 @@ static void upload_S6( struct i915_context *i915 )
 }
 
 const struct i915_tracked_state i915_upload_S6 = {
-   I915_NEW_BLEND | I915_NEW_DEPTH_STENCIL | I915_NEW_FRAMEBUFFER,
-   upload_S6
+   "imm s6",
+   upload_S6,
+   I915_NEW_BLEND | I915_NEW_DEPTH_STENCIL | I915_NEW_FRAMEBUFFER
 };
 
 
+
 /***********************************************************************
  */
-static void upload_S7( struct i915_context *i915 )
+static void upload_S7(struct i915_context *i915)
 {
    unsigned LIS7;
 
@@ -202,11 +211,15 @@ static void upload_S7( struct i915_context *i915 )
 }
 
 const struct i915_tracked_state i915_upload_S7 = {
-   I915_NEW_RASTERIZER,
-   upload_S7
+   "imm S7",
+   upload_S7,
+   I915_NEW_RASTERIZER
 };
 
 
+
+/***********************************************************************
+ */
 static const struct i915_tracked_state *atoms[] = {
    &i915_upload_S0S1,
    &i915_upload_S2S4,
@@ -215,13 +228,17 @@ static const struct i915_tracked_state *atoms[] = {
    &i915_upload_S7
 };
 
-/* 
- */
-void i915_update_immediate( struct i915_context *i915 )
+static void update_immediate(struct i915_context *i915)
 {
    int i;
 
    for (i = 0; i < Elements(atoms); i++)
       if (i915->dirty & atoms[i]->dirty)
-        atoms[i]->update( i915 );
+         atoms[i]->update(i915);
 }
+
+struct i915_tracked_state i915_hw_immediate = {
+   "immediate",
+   update_immediate,
+   ~0 /* all state atoms, becuase we do internal checking */
+};
index 77b9bccbb741128c94da0b878b3a4c8ece79ab5f..4667e0b78d4f362a3b86fc70c78e88afb3ea19ff 100644 (file)
  *
  * So we need to update the map state when we change samplers and
  * we need to be change the sampler state when map state is changed.
- * The first part is done by calling i915_update_texture in
- * i915_update_samplers and the second part is done else where in
- * code tracking the state changes.
+ * The first part is done by calling update_texture in update_samplers
+ * and the second part is done else where in code tracking the state
+ * changes.
+ */
+
+static void update_map(struct i915_context *i915,
+                       uint unit,
+                       const struct i915_texture *tex,
+                       const struct i915_sampler_state *sampler,
+                       uint state[2]);
+
+
+
+/***********************************************************************
+ * Samplers
  */
 
-static void
-i915_update_texture(struct i915_context *i915,
-                    uint unit,
-                    const struct i915_texture *tex,
-                    const struct i915_sampler_state *sampler,
-                    uint state[6]);
 /**
  * Compute i915 texture sampling state.
  *
@@ -74,16 +80,13 @@ i915_update_texture(struct i915_context *i915,
  */
 static void update_sampler(struct i915_context *i915,
                            uint unit,
-                          const struct i915_sampler_state *sampler,
-                          const struct i915_texture *tex,
-                          unsigned state[3] )
+                           const struct i915_sampler_state *sampler,
+                           const struct i915_texture *tex,
+                           unsigned state[3])
 {
    const struct pipe_resource *pt = &tex->b.b;
    unsigned minlod, lastlod;
 
-   /* Need to do this after updating the maps, which call the
-    * intel_finalize_mipmap_tree and hence can update firstLevel:
-    */
    state[0] = sampler->state[0];
    state[1] = sampler->state[1];
    state[2] = sampler->state[2];
@@ -118,7 +121,7 @@ static void update_sampler(struct i915_context *i915,
            wr == PIPE_TEX_WRAP_CLAMP_TO_BORDER)) {
          if (i915->conformance_mode > 0) {
             assert(0);
-            /*             sampler->fallback = true; */
+            /*             sampler->fallback = true; */
             /* TODO */
          }
       }
@@ -137,8 +140,7 @@ static void update_sampler(struct i915_context *i915,
    state[1] |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT);
 }
 
-
-void i915_update_samplers( struct i915_context *i915 )
+static void update_samplers(struct i915_context *i915)
 {
    uint unit;
 
@@ -152,29 +154,38 @@ void i915_update_samplers( struct i915_context *i915 )
       if (i915->fragment_sampler_views[unit]) {
          struct i915_texture *texture = i915_texture(i915->fragment_sampler_views[unit]->texture);
 
-        update_sampler( i915,
-                        unit,
-                        i915->sampler[unit],       /* sampler state */
-                        texture,                    /* texture */
-                        i915->current.sampler[unit] /* the result */
-                        );
-        i915_update_texture( i915,
-                             unit,
-                             texture,                      /* texture */
-                             i915->sampler[unit],          /* sampler state */
-                             i915->current.texbuffer[unit] );
-
-        i915->current.sampler_enable_nr++;
-        i915->current.sampler_enable_flags |= (1 << unit);
+         update_sampler(i915,
+                        unit,
+                        i915->sampler[unit],          /* sampler state */
+                        texture,                      /* texture */
+                        i915->current.sampler[unit]); /* the result */
+         update_map(i915,
+                    unit,
+                    texture,                        /* texture */
+                    i915->sampler[unit],            /* sampler state */
+                    i915->current.texbuffer[unit]); /* the result */
+
+         i915->current.sampler_enable_nr++;
+         i915->current.sampler_enable_flags |= (1 << unit);
       }
    }
 
    i915->hardware_dirty |= I915_HW_SAMPLER | I915_HW_MAP;
 }
 
+struct i915_tracked_state i915_hw_samplers = {
+   "samplers",
+   update_samplers,
+   I915_NEW_SAMPLER | I915_NEW_SAMPLER_VIEW
+};
 
-static uint
-translate_texture_format(enum pipe_format pipeFormat)
+
+
+/***********************************************************************
+ * Sampler views
+ */
+
+static uint translate_texture_format(enum pipe_format pipeFormat)
 {
    switch (pipeFormat) {
    case PIPE_FORMAT_L8_UNORM:
@@ -226,19 +237,17 @@ translate_texture_format(enum pipe_format pipeFormat)
       return (MAPSURF_32BIT | MT_32BIT_xI824);
    default:
       debug_printf("i915: translate_texture_format() bad image format %x\n",
-              pipeFormat);
+                   pipeFormat);
       assert(0);
       return 0;
    }
 }
 
-
-static void
-i915_update_texture(struct i915_context *i915,
-                    uint unit,
-                    const struct i915_texture *tex,
-                    const struct i915_sampler_state *sampler,
-                    uint state[6])
+static void update_map(struct i915_context *i915,
+                       uint unit,
+                       const struct i915_texture *tex,
+                       const struct i915_sampler_state *sampler,
+                       uint state[2])
 {
    const struct pipe_resource *pt = &tex->b.b;
    uint format, pitch;
@@ -287,9 +296,7 @@ i915_update_texture(struct i915_context *i915,
        | ((depth - 1) << MS4_VOLUME_DEPTH_SHIFT));
 }
 
-
-void
-i915_update_textures(struct i915_context *i915)
+static void update_maps(struct i915_context *i915)
 {
    uint unit;
 
@@ -300,13 +307,19 @@ i915_update_textures(struct i915_context *i915)
       if (i915->fragment_sampler_views[unit]) {
          struct i915_texture *texture = i915_texture(i915->fragment_sampler_views[unit]->texture);
 
-        i915_update_texture( i915,
-                             unit,
-                             texture,                      /* texture */
-                             i915->sampler[unit],          /* sampler state */
-                             i915->current.texbuffer[unit] );
+         update_map(i915,
+                    unit,
+                    texture,                      /* texture */
+                    i915->sampler[unit],          /* sampler state */
+                    i915->current.texbuffer[unit]);
       }
    }
 
    i915->hardware_dirty |= I915_HW_MAP;
 }
+
+struct i915_tracked_state i915_hw_sampler_views = {
+   "sampler_views",
+   update_maps,
+   I915_NEW_SAMPLER_VIEW
+};
diff --git a/src/gallium/drivers/i915/i915_state_static.c b/src/gallium/drivers/i915/i915_state_static.c
new file mode 100644 (file)
index 0000000..dc9a4c1
--- /dev/null
@@ -0,0 +1,47 @@
+/**************************************************************************
+ *
+ * Copyright Â© 2010 Jakob Bornecrantz
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "i915_reg.h"
+#include "i915_context.h"
+#include "i915_state.h"
+
+
+
+/***********************************************************************
+ * Update framebuffer state
+ */
+static void update_framebuffer(struct i915_context *i915)
+{
+   /* HW emit currently references framebuffer state directly:
+    */
+   i915->hardware_dirty |= I915_HW_STATIC;
+}
+
+struct i915_tracked_state i915_hw_framebuffer = {
+   "framebuffer",
+   update_framebuffer,
+   I915_NEW_FRAMEBUFFER
+};
index 3aba19fe6a3990db2a423c0e0894090d98b72e2e..5385e403d224e3715dd8116b2f0e92f049961c8f 100644 (file)
@@ -222,11 +222,4 @@ struct i915_winsys {
    void (*destroy)(struct i915_winsys *iws);
 };
 
-
-/**
- * Create i915 pipe_screen.
- */
-struct pipe_screen *i915_screen_create(struct i915_winsys *iws);
-
-
 #endif
diff --git a/src/gallium/drivers/i965/brw_public.h b/src/gallium/drivers/i965/brw_public.h
new file mode 100644 (file)
index 0000000..be2cd6b
--- /dev/null
@@ -0,0 +1,13 @@
+
+#ifndef BRW_PUBLIC_H
+#define BRW_PUBLIC_H
+
+struct brw_winsys_screen;
+struct pipe_screen;
+
+/**
+ * Create brw AKA i965 pipe_screen.
+ */
+struct pipe_screen * brw_screen_create(struct brw_winsys_screen *bws);
+
+#endif
index 50a446db917ad99cab61397e194915ae0ca4d03a..bdfead73cc87b7e39f722ea20d34886e82b7720e 100644 (file)
@@ -34,6 +34,7 @@
 #include "brw_context.h"
 #include "brw_screen.h"
 #include "brw_winsys.h"
+#include "brw_public.h"
 #include "brw_debug.h"
 #include "brw_resource.h"
 
@@ -350,7 +351,7 @@ brw_destroy_screen(struct pipe_screen *screen)
  * Create a new brw_screen object
  */
 struct pipe_screen *
-brw_create_screen(struct brw_winsys_screen *sws, uint pci_id)
+brw_screen_create(struct brw_winsys_screen *sws)
 {
    struct brw_screen *bscreen;
    struct brw_chipset chipset;
@@ -365,9 +366,9 @@ brw_create_screen(struct brw_winsys_screen *sws, uint pci_id)
 
    memset(&chipset, 0, sizeof chipset);
 
-   chipset.pci_id = pci_id;
+   chipset.pci_id = sws->pci_id;
 
-   switch (pci_id) {
+   switch (chipset.pci_id) {
    case PCI_CHIP_I965_G:
    case PCI_CHIP_I965_Q:
    case PCI_CHIP_I965_G_1:
@@ -393,7 +394,7 @@ brw_create_screen(struct brw_winsys_screen *sws, uint pci_id)
 
    default:
       debug_printf("%s: unknown pci id 0x%x, cannot create screen\n", 
-                   __FUNCTION__, pci_id);
+                   __FUNCTION__, chipset.pci_id);
       return NULL;
    }
 
index f30c7f181323fb0d5cedf364149c613f57a9ee32..a06f8bb7d6140d9e1d61111d4ea927d752355143 100644 (file)
@@ -147,6 +147,7 @@ static INLINE void make_reloc(struct brw_winsys_reloc *reloc,
 
 struct brw_winsys_screen {
 
+   unsigned pci_id;
 
    /**
     * Buffer functions.
@@ -261,12 +262,6 @@ bo_reference(struct brw_winsys_buffer **ptr, struct brw_winsys_buffer *buf)
 }
 
 
-/**
- * Create brw pipe_screen.
- */
-struct pipe_screen *brw_create_screen(struct brw_winsys_screen *iws, unsigned pci_id);
-
-
 
 /*************************************************************************
  * Cooperative dumping between winsys and driver.  TODO: make this
index 9c67759ad0bb702c0bcf80ddd0633a66898c4f48..f7ee55cc1c85b03b3a37276b0155a726fe978d2a 100644 (file)
@@ -678,7 +678,7 @@ static void precalc_tex( struct brw_wm_compile *c,
                         struct brw_fp_src src0,
                         struct brw_fp_src sampler )
 {
-   struct brw_fp_src coord = src_undef();
+   struct brw_fp_src coord;
    struct brw_fp_dst tmp = dst_undef();
 
    assert(unit < BRW_MAX_TEX_UNIT);
index e32b9102e597cddca45bc9b617a546d0a89040ff..74692d976105a7ae8e0599e32bdd7760911c5505 100644 (file)
@@ -6,7 +6,6 @@ LIBNAME = identity
 C_SOURCES = \
        id_objects.c \
        id_context.c \
-       id_screen.c \
-       id_drm.c
+       id_screen.c
 
 include ../../Makefile.template
index 2a68891c2844d9f3f4c51ee803dc54f4374981cd..b364e0acc84a4f97d95d94b3308b53021a52f271 100644 (file)
@@ -6,7 +6,6 @@ identity = env.ConvenienceLibrary(
        target = 'identity',
        source = [
                'id_context.c',
-               'id_drm.c',
                'id_objects.c',
                'id_screen.c',
        ])
diff --git a/src/gallium/drivers/identity/id_drm.c b/src/gallium/drivers/identity/id_drm.c
deleted file mode 100644 (file)
index 15d0151..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2009 VMware, 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 the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL VMWARE 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 "state_tracker/drm_api.h"
-
-#include "util/u_memory.h"
-#include "id_drm.h"
-#include "id_screen.h"
-#include "id_public.h"
-
-struct identity_drm_api
-{
-   struct drm_api base;
-
-   struct drm_api *api;
-};
-
-static INLINE struct identity_drm_api *
-identity_drm_api(struct drm_api *_api)
-{
-   return (struct identity_drm_api *)_api;
-}
-
-static struct pipe_screen *
-identity_drm_create_screen(struct drm_api *_api, int fd)
-{
-   struct identity_drm_api *id_api = identity_drm_api(_api);
-   struct drm_api *api = id_api->api;
-   struct pipe_screen *screen;
-
-   screen = api->create_screen(api, fd);
-
-   return identity_screen_create(screen);
-}
-
-static void
-identity_drm_destroy(struct drm_api *_api)
-{
-   struct identity_drm_api *id_api = identity_drm_api(_api);
-   struct drm_api *api = id_api->api;
-   api->destroy(api);
-
-   FREE(id_api);
-}
-
-struct drm_api *
-identity_drm_create(struct drm_api *api)
-{
-   struct identity_drm_api *id_api;
-
-   if (!api)
-      goto error;
-
-   id_api = CALLOC_STRUCT(identity_drm_api);
-
-   if (!id_api)
-      goto error;
-
-   id_api->base.name = api->name;
-   id_api->base.driver_name = api->driver_name;
-   id_api->base.create_screen = identity_drm_create_screen;
-   id_api->base.destroy = identity_drm_destroy;
-   id_api->api = api;
-
-   return &id_api->base;
-
-error:
-   return api;
-}
diff --git a/src/gallium/drivers/identity/id_drm.h b/src/gallium/drivers/identity/id_drm.h
deleted file mode 100644 (file)
index cf2ad2c..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2009 VMware, 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 the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL VMWARE 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 ID_DRM_H
-#define ID_DRM_H
-
-struct drm_api;
-
-struct drm_api* identity_drm_create(struct drm_api *api);
-
-#endif /* ID_DRM_H */
index ca4743f9ef725d2e33ce4ecaf60188d134b5f9fb..593928f399c7edaa7ee904169541f0426e617184 100644 (file)
@@ -120,13 +120,14 @@ identity_sampler_view_create(struct identity_context *id_context,
 
    assert(view->texture == id_resource->resource);
 
-   id_view = MALLOC(sizeof(struct identity_sampler_view));
+   id_view = CALLOC_STRUCT(identity_sampler_view);
 
    id_view->base = *view;
    id_view->base.reference.count = 1;
    id_view->base.texture = NULL;
    pipe_resource_reference(&id_view->base.texture, id_resource->resource);
    id_view->base.context = id_context->pipe;
+   id_view->sampler_view = view;
 
    return &id_view->base;
 error:
@@ -180,8 +181,8 @@ identity_transfer_destroy(struct identity_context *id_context,
                           struct identity_transfer *id_transfer)
 {
    pipe_resource_reference(&id_transfer->base.resource, NULL);
-   id_transfer->pipe->transfer_destroy(id_context->pipe,
-                                       id_transfer->transfer);
+   id_context->pipe->transfer_destroy(id_context->pipe,
+                                      id_transfer->transfer);
    FREE(id_transfer);
 }
 
index 5eea10b0b5a7d6494662cb04f048aae2cacc239b..e8deabf4fc7f3df6d59c141298b39252b656e484 100644 (file)
@@ -65,7 +65,6 @@ struct identity_transfer
 {
    struct pipe_transfer base;
 
-   struct pipe_context *pipe;
    struct pipe_transfer *transfer;
 };
 
index a1b6f56e0d2c780e9ce80abccebf24f3cd2f925c..6ebd2b8a63b858b8b2b13c01a91c1a38b1d3f3b2 100644 (file)
@@ -3,3 +3,5 @@ lp_test_blend
 lp_test_conv
 lp_test_format
 lp_test_printf
+lp_test_round
+lp_test_sincos
index ee28179c303272e18e9269352d8fbb3e0ffaba03..2892b62920e80b18c009bdce54506586f442a57e 100644 (file)
@@ -18,6 +18,7 @@ C_SOURCES = \
        lp_fence.c \
        lp_flush.c \
        lp_jit.c \
+       lp_memory.c \
        lp_perf.c \
        lp_query.c \
        lp_rast.c \
@@ -53,8 +54,12 @@ PROGS := lp_test_format      \
         lp_test_blend  \
         lp_test_conv   \
         lp_test_printf \
+        lp_test_round \
          lp_test_sincos
 
+# Need this for the lp_test_*.o files
+CLEAN_EXTRA = *.o
+
 lp_test_sincos.o : sse_mathfun.h
 
 PROGS_DEPS := ../../auxiliary/libgallium.a
index a1ef71da89d754e0594898d93f605f06bc17fe94..fd6ba1561ea771bae686452a1da324768773cb53 100644 (file)
@@ -1,3 +1,5 @@
+import distutils.version
+
 Import('*')
 
 if not env['llvm']:
@@ -23,6 +25,16 @@ env.Depends('lp_tile_soa.c', [
     '#src/gallium/auxiliary/util/u_format_pack.py', 
 ])
 
+
+# Only enable SSSE3 for lp_tile_soa_sse3.c
+ssse3_env = env.Clone()
+if env['gcc'] \
+   and distutils.version.LooseVersion(env['CCVERSION']) >= distutils.version.LooseVersion('4.3') \
+   and env['machine'] in ('x86', 'x86_64') :
+    ssse3_env.Append(CCFLAGS = ['-mssse3'])
+lp_tile_soa_os = ssse3_env.SharedObject('lp_tile_soa.c')
+
+
 llvmpipe = env.ConvenienceLibrary(
        target = 'llvmpipe',
        source = [
@@ -38,6 +50,7 @@ llvmpipe = env.ConvenienceLibrary(
                'lp_fence.c',
                'lp_flush.c',
                'lp_jit.c',
+               'lp_memory.c',
                'lp_perf.c',
                'lp_query.c',
                'lp_rast.c',
@@ -65,7 +78,7 @@ llvmpipe = env.ConvenienceLibrary(
                'lp_tex_sample.c',
                'lp_texture.c',
                'lp_tile_image.c',
-               'lp_tile_soa.c',
+        lp_tile_soa_os,
        ])
 
 
@@ -82,6 +95,9 @@ if env['platform'] != 'embedded':
        'sincos',
     ]
 
+    if not msvc:
+        tests.append('round')
+
     for test in tests:
         target = env.Program(
             target = 'lp_test_' + test,
index 70d08e71f6ecf660351cef812335eafc30acdb5c..09e983305719de4dca9f92932d2b92089d32de31 100644 (file)
@@ -190,30 +190,27 @@ lp_build_blend_swizzle(struct lp_build_blend_aos_context *bld,
                        enum lp_build_blend_swizzle rgb_swizzle,
                        unsigned alpha_swizzle)
 {
-   if(rgb == alpha) {
-      if(rgb_swizzle == LP_BUILD_BLEND_SWIZZLE_RGBA)
-         return rgb;
-      if(rgb_swizzle == LP_BUILD_BLEND_SWIZZLE_AAAA)
-         return lp_build_broadcast_aos(&bld->base, rgb, alpha_swizzle);
+   LLVMValueRef swizzled_rgb;
+
+   switch (rgb_swizzle) {
+   case LP_BUILD_BLEND_SWIZZLE_RGBA:
+      swizzled_rgb = rgb;
+      break;
+   case LP_BUILD_BLEND_SWIZZLE_AAAA:
+      swizzled_rgb = lp_build_broadcast_aos(&bld->base, rgb, alpha_swizzle);
+      break;
+   default:
+      assert(0);
+      swizzled_rgb = bld->base.undef;
    }
-   else {
-      if(rgb_swizzle == LP_BUILD_BLEND_SWIZZLE_RGBA) {
-         boolean cond[4] = {0, 0, 0, 0};
-         cond[alpha_swizzle] = 1;
-         return lp_build_select_aos(&bld->base, alpha, rgb, cond);
-      }
-      if(rgb_swizzle == LP_BUILD_BLEND_SWIZZLE_AAAA) {
-         unsigned char swizzle[4];
-         swizzle[0] = alpha_swizzle;
-         swizzle[1] = alpha_swizzle;
-         swizzle[2] = alpha_swizzle;
-         swizzle[3] = alpha_swizzle;
-         swizzle[alpha_swizzle] += 4;
-         return lp_build_swizzle2_aos(&bld->base, rgb, alpha, swizzle);
-      }
+
+   if (rgb != alpha) {
+      boolean cond[4] = {0, 0, 0, 0};
+      cond[alpha_swizzle] = 1;
+      swizzled_rgb = lp_build_select_aos(&bld->base, alpha, swizzled_rgb, cond);
    }
-   assert(0);
-   return bld->base.undef;
+
+   return swizzled_rgb;
 }
 
 
index 90d2b26f9f2fa81d549ab8e1c02c4a08a7d3776e..78744da500bc6495e61d697e5ce615b660323501 100644 (file)
@@ -261,7 +261,7 @@ attribs_update(struct lp_build_interp_soa_context *bld, int quad_index)
       const unsigned interp = bld->interp[attrib];
       for(chan = 0; chan < NUM_CHANNELS; ++chan) {
          if(mask & (1 << chan)) {
-            LLVMValueRef a = coeff_bld->undef;
+            LLVMValueRef a;
             if (interp == LP_INTERP_CONSTANT ||
                 interp == LP_INTERP_FACING) {
                a = bld->a[attrib][chan];
index 986e604ce7c167a9a5da10ecb89c3113f06af1cf..b2643ab33cd27f934221c79b370ff3ec858b2ba9 100644 (file)
@@ -83,6 +83,7 @@ struct llvmpipe_context {
       int so_count[PIPE_MAX_SO_BUFFERS];
       int num_buffers;
    } so_target;
+   struct pipe_resource *mapped_vs_tex[PIPE_MAX_VERTEX_SAMPLERS];
 
    unsigned num_samplers;
    unsigned num_fragment_sampler_views;
index 98780d7631b466e9d250219dcb1aadd7ea4e84d5..625d0c8a8c95d464ba8f98eaa4233416ef871589 100644 (file)
 
 
 /**
- * Draw vertex arrays, with optional indexing.
+ * Draw vertex arrays, with optional indexing, optional instancing.
+ * All the other drawing functions are implemented in terms of this function.
  * Basically, map the vertex buffers (and drawing surfaces), then hand off
  * the drawing to the 'draw' module.
  */
 static void
-llvmpipe_draw_range_elements(struct pipe_context *pipe,
-                             struct pipe_resource *indexBuffer,
-                             unsigned indexSize,
-                             int indexBias,
-                             unsigned min_index,
-                             unsigned max_index,
-                             unsigned mode, unsigned start, unsigned count)
+llvmpipe_draw_range_elements_instanced(struct pipe_context *pipe,
+                                       struct pipe_resource *indexBuffer,
+                                       unsigned indexSize,
+                                       int indexBias,
+                                       unsigned minIndex,
+                                       unsigned maxIndex,
+                                       unsigned mode,
+                                       unsigned start,
+                                       unsigned count,
+                                       unsigned startInstance,
+                                       unsigned instanceCount)
 {
    struct llvmpipe_context *lp = llvmpipe_context(pipe);
    struct draw_context *draw = lp->draw;
@@ -74,9 +79,11 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe,
    /* Map index buffer, if present */
    if (indexBuffer) {
       void *mapped_indexes = llvmpipe_resource_data(indexBuffer);
-      draw_set_mapped_element_buffer_range(draw, indexSize, indexBias,
-                                           min_index,
-                                           max_index,
+      draw_set_mapped_element_buffer_range(draw,
+                                           indexSize,
+                                           indexBias,
+                                           minIndex,
+                                           maxIndex,
                                            mapped_indexes);
    }
    else {
@@ -84,9 +91,13 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe,
       draw_set_mapped_element_buffer_range(draw, 0, 0, start,
                                            start + count - 1, NULL);
    }
+   llvmpipe_prepare_vertex_sampling(lp,
+                                    lp->num_vertex_sampler_views,
+                                    lp->vertex_sampler_views);
 
    /* draw! */
-   draw_arrays(draw, mode, start, count);
+   draw_arrays_instanced(draw, mode, start, count,
+                         startInstance, instanceCount);
 
    /*
     * unmap vertex/index buffers
@@ -97,6 +108,7 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe,
    if (indexBuffer) {
       draw_set_mapped_element_buffer(draw, 0, 0, NULL);
    }
+   llvmpipe_cleanup_vertex_sampling(lp);
 
    /*
     * TODO: Flush only when a user vertex/index buffer is present
@@ -107,25 +119,103 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe,
 }
 
 
+static void
+llvmpipe_draw_arrays_instanced(struct pipe_context *pipe,
+                               unsigned mode,
+                               unsigned start,
+                               unsigned count,
+                               unsigned startInstance,
+                               unsigned instanceCount)
+{
+   llvmpipe_draw_range_elements_instanced(pipe,
+                                          NULL, /* no indexBuffer */
+                                          0, 0, /* indexSize, indexBias */
+                                          0, ~0, /* minIndex, maxIndex */
+                                          mode,
+                                          start,
+                                          count,
+                                          startInstance,
+                                          instanceCount);
+}
+
+
+static void
+llvmpipe_draw_elements_instanced(struct pipe_context *pipe,
+                                 struct pipe_resource *indexBuffer,
+                                 unsigned indexSize,
+                                 int indexBias,
+                                 unsigned mode,
+                                 unsigned start,
+                                 unsigned count,
+                                 unsigned startInstance,
+                                 unsigned instanceCount)
+{
+   llvmpipe_draw_range_elements_instanced(pipe,
+                                          indexBuffer,
+                                          indexSize, indexBias,
+                                          0, ~0, /* minIndex, maxIndex */
+                                          mode,
+                                          start,
+                                          count,
+                                          startInstance,
+                                          instanceCount);
+}
+
+
 static void
 llvmpipe_draw_elements(struct pipe_context *pipe,
                        struct pipe_resource *indexBuffer,
                        unsigned indexSize,
                        int indexBias,
-                       unsigned mode, unsigned start, unsigned count)
+                       unsigned mode,
+                       unsigned start,
+                       unsigned count)
+{
+   llvmpipe_draw_range_elements_instanced(pipe,
+                                          indexBuffer,
+                                          indexSize, indexBias,
+                                          0, 0xffffffff,  /* min, maxIndex */
+                                          mode, start, count,
+                                          0,  /* startInstance */
+                                          1);  /* instanceCount */
+}
+
+
+static void
+llvmpipe_draw_range_elements(struct pipe_context *pipe,
+                             struct pipe_resource *indexBuffer,
+                             unsigned indexSize,
+                             int indexBias,
+                             unsigned min_index,
+                             unsigned max_index,
+                             unsigned mode,
+                             unsigned start,
+                             unsigned count)
 {
-   llvmpipe_draw_range_elements( pipe, indexBuffer,
-                                 indexSize, indexBias,
-                                 0, 0xffffffff,
-                                 mode, start, count );
+   llvmpipe_draw_range_elements_instanced(pipe,
+                                          indexBuffer,
+                                          indexSize, indexBias,
+                                          min_index, max_index,
+                                          mode, start, count,
+                                          0,  /* startInstance */
+                                          1);  /* instanceCount */
 }
 
 
 static void
-llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
-                     unsigned start, unsigned count)
+llvmpipe_draw_arrays(struct pipe_context *pipe,
+                     unsigned mode,
+                     unsigned start,
+                     unsigned count)
 {
-   llvmpipe_draw_elements(pipe, NULL, 0, 0, mode, start, count);
+   llvmpipe_draw_range_elements_instanced(pipe,
+                                          NULL,  /* indexBuffer */
+                                          0,  /* indexSize */
+                                          0,  /* indexBias */
+                                          0, ~0,  /* min, maxIndex */
+                                          mode, start, count,
+                                          0,  /* startInstance */
+                                          1);  /* instanceCount */
 }
 
 
@@ -135,4 +225,6 @@ llvmpipe_init_draw_funcs(struct llvmpipe_context *llvmpipe)
    llvmpipe->pipe.draw_arrays = llvmpipe_draw_arrays;
    llvmpipe->pipe.draw_elements = llvmpipe_draw_elements;
    llvmpipe->pipe.draw_range_elements = llvmpipe_draw_range_elements;
+   llvmpipe->pipe.draw_arrays_instanced = llvmpipe_draw_arrays_instanced;
+   llvmpipe->pipe.draw_elements_instanced = llvmpipe_draw_elements_instanced;
 }
index 75d8d2b8251bf5e97121a13e1008a04747d69e24..f9805e5d6881fa1ac347f59306a9be55e694f2f2 100644 (file)
@@ -28,7 +28,6 @@
 
 #include "pipe/p_screen.h"
 #include "util/u_memory.h"
-#include "util/u_inlines.h"
 #include "lp_debug.h"
 #include "lp_fence.h"
 
@@ -59,7 +58,7 @@ lp_fence_create(unsigned rank)
 
 
 /** Destroy a fence.  Called when refcount hits zero. */
-static void
+void
 lp_fence_destroy(struct lp_fence *fence)
 {
    pipe_mutex_destroy(fence->mutex);
@@ -77,12 +76,10 @@ llvmpipe_fence_reference(struct pipe_screen *screen,
                          struct pipe_fence_handle **ptr,
                          struct pipe_fence_handle *fence)
 {
-   struct lp_fence *old = (struct lp_fence *) *ptr;
+   struct lp_fence **old = (struct lp_fence **) ptr;
    struct lp_fence *f = (struct lp_fence *) fence;
 
-   if (pipe_reference(&old->reference, &f->reference)) {
-      lp_fence_destroy(old);
-   }
+   lp_fence_reference(old, f);
 }
 
 
index d9270f5784acb7ed5c5b61471d4ea52d9a7b3dca..13358fb99f2a89ddd3007706ab2fc4708691af23 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "os/os_thread.h"
 #include "pipe/p_state.h"
+#include "util/u_inlines.h"
 
 
 struct pipe_screen;
@@ -61,4 +62,21 @@ void
 llvmpipe_init_screen_fence_funcs(struct pipe_screen *screen);
 
 
+void
+lp_fence_destroy(struct lp_fence *fence);
+
+static INLINE void
+lp_fence_reference(struct lp_fence **ptr,
+                   struct lp_fence *f)
+{
+   struct lp_fence *old = *ptr;
+
+   if (pipe_reference(&old->reference, &f->reference)) {
+      lp_fence_destroy(old);
+   }
+   
+   *ptr = f;
+}
+
+
 #endif /* LP_FENCE_H */
index 0cd288bb73a7ad226343e10b15b0e3875f5638bd..845292f4ab206f4c21e290d7bba91e253cf626db 100644 (file)
 
 /**
  * \param flags  bitmask of PIPE_FLUSH_x flags
- * \param fence  if non-null, returns pointer to a fench which can be waited on
+ * \param fence  if non-null, returns pointer to a fence which can be waited on
  */
 void
 llvmpipe_flush( struct pipe_context *pipe,
-               unsigned flags,
+                unsigned flags,
                 struct pipe_fence_handle **fence )
 {
    struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
 
    draw_flush(llvmpipe->draw);
 
-   if (fence) {
-      /* if we're going to flush the setup/rasterization modules, emit
-       * a fence.
-       * XXX this (and the code below) may need fine tuning...
-       */
-      *fence = lp_setup_fence( llvmpipe->setup );
-   }
-
    /* ask the setup module to flush */
-   lp_setup_flush(llvmpipe->setup, flags);
+   lp_setup_flush(llvmpipe->setup, flags, fence);
 
    /* Enable to dump BMPs of the color/depth buffers each frame */
    if (0) {
index 23aa34ddec1c65d89aa0471816cb1ddcdd5a5346..8e6dfb293d04326b67470971648703ff8a3bb617 100644 (file)
@@ -103,10 +103,6 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
       elem_types[LP_JIT_CTX_ALPHA_REF] = LLVMFloatType();
       elem_types[LP_JIT_CTX_STENCIL_REF_FRONT] = LLVMInt32Type();
       elem_types[LP_JIT_CTX_STENCIL_REF_BACK] = LLVMInt32Type();
-      elem_types[LP_JIT_CTX_SCISSOR_XMIN] = LLVMFloatType();
-      elem_types[LP_JIT_CTX_SCISSOR_YMIN] = LLVMFloatType();
-      elem_types[LP_JIT_CTX_SCISSOR_XMAX] = LLVMFloatType();
-      elem_types[LP_JIT_CTX_SCISSOR_YMAX] = LLVMFloatType();
       elem_types[LP_JIT_CTX_BLEND_COLOR] = LLVMPointerType(LLVMInt8Type(), 0);
       elem_types[LP_JIT_CTX_TEXTURES] = LLVMArrayType(texture_type,
                                                       PIPE_MAX_SAMPLERS);
@@ -125,18 +121,6 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, stencil_ref_back,
                              screen->target, context_type,
                              LP_JIT_CTX_STENCIL_REF_BACK);
-      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_xmin,
-                             screen->target, context_type,
-                             LP_JIT_CTX_SCISSOR_XMIN);
-      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_ymin,
-                             screen->target, context_type,
-                             LP_JIT_CTX_SCISSOR_YMIN);
-      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_xmax,
-                             screen->target, context_type,
-                             LP_JIT_CTX_SCISSOR_XMAX);
-      LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, scissor_ymax,
-                             screen->target, context_type,
-                             LP_JIT_CTX_SCISSOR_YMAX);
       LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, blend_color,
                              screen->target, context_type,
                              LP_JIT_CTX_BLEND_COLOR);
index 8d06e65725f7d68e5471a38209de875e8020eb39..c94189413abde9637a5815fe59e9b7bfa021f486 100644 (file)
@@ -89,9 +89,6 @@ struct lp_jit_context
 
    uint32_t stencil_ref_front, stencil_ref_back;
 
-   /** floats, not ints */
-   float scissor_xmin, scissor_ymin, scissor_xmax, scissor_ymax;
-
    /* FIXME: store (also?) in floats */
    uint8_t *blend_color;
 
@@ -108,10 +105,6 @@ enum {
    LP_JIT_CTX_ALPHA_REF,
    LP_JIT_CTX_STENCIL_REF_FRONT,
    LP_JIT_CTX_STENCIL_REF_BACK,
-   LP_JIT_CTX_SCISSOR_XMIN,
-   LP_JIT_CTX_SCISSOR_YMIN,
-   LP_JIT_CTX_SCISSOR_XMAX,
-   LP_JIT_CTX_SCISSOR_YMAX,
    LP_JIT_CTX_BLEND_COLOR,
    LP_JIT_CTX_TEXTURES,
    LP_JIT_CTX_COUNT
@@ -130,18 +123,6 @@ enum {
 #define lp_jit_context_stencil_ref_back_value(_builder, _ptr) \
    lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_STENCIL_REF_BACK, "stencil_ref_back")
 
-#define lp_jit_context_scissor_xmin_value(_builder, _ptr) \
-   lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_SCISSOR_XMIN, "scissor_xmin")
-
-#define lp_jit_context_scissor_ymin_value(_builder, _ptr) \
-   lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_SCISSOR_YMIN, "scissor_ymin")
-
-#define lp_jit_context_scissor_xmax_value(_builder, _ptr) \
-   lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_SCISSOR_XMAX, "scissor_xmax")
-
-#define lp_jit_context_scissor_ymax_value(_builder, _ptr) \
-   lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_SCISSOR_YMAX, "scissor_ymax")
-
 #define lp_jit_context_blend_color(_builder, _ptr) \
    lp_build_struct_get(_builder, _ptr, LP_JIT_CTX_BLEND_COLOR, "blend_color")
 
@@ -160,12 +141,7 @@ typedef void
                     const void *dady,
                     uint8_t **color,
                     void *depth,
-                    const int32_t c1,
-                    const int32_t c2,
-                    const int32_t c3,
-                    const int32_t *step1,
-                    const int32_t *step2,
-                    const int32_t *step3,
+                    uint32_t mask,
                     uint32_t *counter);
 
 
diff --git a/src/gallium/drivers/llvmpipe/lp_memory.c b/src/gallium/drivers/llvmpipe/lp_memory.c
new file mode 100644 (file)
index 0000000..0f55d4a
--- /dev/null
@@ -0,0 +1,45 @@
+/**************************************************************************
+ * 
+ * Copyright 2010 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE 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 "util/u_debug.h"
+#include "lp_limits.h"
+#include "lp_memory.h"
+
+/**
+ * 32bpp RGBA swizzled tiles.  One for for each thread and each
+ * possible colorbuf.  Adds up to quite a bit 8*8*64*64*4 == 1MB.
+ * Several schemes exist to reduce this, such as scaling back the
+ * number of threads or using a smaller tilesize when multiple
+ * colorbuffers are bound.
+ */
+PIPE_ALIGN_VAR(16) uint8_t lp_swizzled_cbuf[LP_MAX_THREADS][PIPE_MAX_COLOR_BUFS][TILE_SIZE * TILE_SIZE * 4];
+
+
+/* A single dummy tile used in a couple of out-of-memory situations. 
+ */
+PIPE_ALIGN_VAR(16) uint8_t lp_dummy_tile[TILE_SIZE * TILE_SIZE * 4];
+
diff --git a/src/gallium/drivers/llvmpipe/lp_memory.h b/src/gallium/drivers/llvmpipe/lp_memory.h
new file mode 100644 (file)
index 0000000..f7418f5
--- /dev/null
@@ -0,0 +1,40 @@
+/**************************************************************************
+ * 
+ * Copyright 2010 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE 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 LP_MEMORY_H
+#define LP_MEMORY_H
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+#include "lp_limits.h"
+
+extern PIPE_ALIGN_VAR(16) uint8_t lp_swizzled_cbuf[LP_MAX_THREADS][PIPE_MAX_COLOR_BUFS][TILE_SIZE * TILE_SIZE * 4];
+
+extern PIPE_ALIGN_VAR(16) uint8_t lp_dummy_tile[TILE_SIZE * TILE_SIZE * 4];
+
+#endif /* LP_MEMORY_H */
index a316597675ce89acb724d207932e95ec42276839..083e7e30a5b27bb4e152be4e2396b3a90397a8d8 100644 (file)
@@ -46,10 +46,10 @@ lp_print_counters(void)
 {
    if (LP_DEBUG & DEBUG_COUNTERS) {
       unsigned total_64, total_16, total_4;
-      float p1, p2, p3;
+      float p1, p2, p3, p4;
 
-      debug_printf("llvmpipe: nr_triangles:               %9u\n", lp_count.nr_tris);
-      debug_printf("llvmpipe: nr_culled_triangles:        %9u\n", lp_count.nr_culled_tris);
+      debug_printf("llvmpipe: nr_triangles:                 %9u\n", lp_count.nr_tris);
+      debug_printf("llvmpipe: nr_culled_triangles:          %9u\n", lp_count.nr_culled_tris);
 
       total_64 = (lp_count.nr_empty_64 + 
                   lp_count.nr_fully_covered_64 +
@@ -58,10 +58,13 @@ lp_print_counters(void)
       p1 = 100.0 * (float) lp_count.nr_empty_64 / (float) total_64;
       p2 = 100.0 * (float) lp_count.nr_fully_covered_64 / (float) total_64;
       p3 = 100.0 * (float) lp_count.nr_partially_covered_64 / (float) total_64;
+      p4 = 100.0 * (float) lp_count.nr_shade_opaque_64 / (float) total_64;
 
-      debug_printf("llvmpipe: nr_empty_64x64:             %9u (%2.0f%% of %u)\n", lp_count.nr_empty_64, p1, total_64);
-      debug_printf("llvmpipe: nr_fully_covered_64x64:     %9u (%2.0f%% of %u)\n", lp_count.nr_fully_covered_64, p2, total_64);
-      debug_printf("llvmpipe: nr_partially_covered_64x64: %9u (%2.0f%% of %u)\n", lp_count.nr_partially_covered_64, p3, total_64);
+      debug_printf("llvmpipe: nr_64x64:                     %9u\n", total_64);
+      debug_printf("llvmpipe:   nr_fully_covered_64x64:     %9u (%3.0f%% of %u)\n", lp_count.nr_fully_covered_64, p2, total_64);
+      debug_printf("llvmpipe:     nr_shade_opaque_64x64:    %9u (%3.0f%% of %u)\n", lp_count.nr_shade_opaque_64, p4, total_64);
+      debug_printf("llvmpipe:   nr_partially_covered_64x64: %9u (%3.0f%% of %u)\n", lp_count.nr_partially_covered_64, p3, total_64);
+      debug_printf("llvmpipe:   nr_empty_64x64:             %9u (%3.0f%% of %u)\n", lp_count.nr_empty_64, p1, total_64);
 
       total_16 = (lp_count.nr_empty_16 + 
                   lp_count.nr_fully_covered_16 +
@@ -71,25 +74,27 @@ lp_print_counters(void)
       p2 = 100.0 * (float) lp_count.nr_fully_covered_16 / (float) total_16;
       p3 = 100.0 * (float) lp_count.nr_partially_covered_16 / (float) total_16;
 
-      debug_printf("llvmpipe: nr_empty_16x16:             %9u (%2.0f%% of %u)\n", lp_count.nr_empty_16, p1, total_16);
-      debug_printf("llvmpipe: nr_fully_covered_16x16:     %9u (%2.0f%% of %u)\n", lp_count.nr_fully_covered_16, p2, total_16);
-      debug_printf("llvmpipe: nr_partially_covered_16x16: %9u (%2.0f%% of %u)\n", lp_count.nr_partially_covered_16, p3, total_16);
+      debug_printf("llvmpipe: nr_16x16:                     %9u\n", total_16);
+      debug_printf("llvmpipe:   nr_fully_covered_16x16:     %9u (%3.0f%% of %u)\n", lp_count.nr_fully_covered_16, p2, total_16);
+      debug_printf("llvmpipe:   nr_partially_covered_16x16: %9u (%3.0f%% of %u)\n", lp_count.nr_partially_covered_16, p3, total_16);
+      debug_printf("llvmpipe:   nr_empty_16x16:             %9u (%3.0f%% of %u)\n", lp_count.nr_empty_16, p1, total_16);
 
       total_4 = (lp_count.nr_empty_4 + lp_count.nr_non_empty_4);
 
       p1 = 100.0 * (float) lp_count.nr_empty_4 / (float) total_4;
       p2 = 100.0 * (float) lp_count.nr_non_empty_4 / (float) total_4;
 
-      debug_printf("llvmpipe: nr_empty_4x4:               %9u (%2.0f%% of %u)\n", lp_count.nr_empty_4, p1, total_4);
-      debug_printf("llvmpipe: nr_non_empty_4x4:           %9u (%2.0f%% of %u)\n", lp_count.nr_non_empty_4, p2, total_4);
+      debug_printf("llvmpipe: nr_4x4:                       %9u\n", total_4);
+      debug_printf("llvmpipe:   nr_empty_4x4:               %9u (%3.0f%% of %u)\n", lp_count.nr_empty_4, p1, total_4);
+      debug_printf("llvmpipe:   nr_non_empty_4x4:           %9u (%3.0f%% of %u)\n", lp_count.nr_non_empty_4, p2, total_4);
 
-      debug_printf("llvmpipe: nr_color_tile_clear:        %9u\n", lp_count.nr_color_tile_clear);
-      debug_printf("llvmpipe: nr_color_tile_load:         %9u\n", lp_count.nr_color_tile_load);
-      debug_printf("llvmpipe: nr_color_tile_store:        %9u\n", lp_count.nr_color_tile_store);
+      debug_printf("llvmpipe: nr_color_tile_clear:          %9u\n", lp_count.nr_color_tile_clear);
+      debug_printf("llvmpipe: nr_color_tile_load:           %9u\n", lp_count.nr_color_tile_load);
+      debug_printf("llvmpipe: nr_color_tile_store:          %9u\n", lp_count.nr_color_tile_store);
 
-      debug_printf("llvmpipe: nr_llvm_compiles:           %u\n", lp_count.nr_llvm_compiles);
-      debug_printf("llvmpipe: total LLVM compile time:    %.2f sec\n", lp_count.llvm_compile_time / 1000000.0);
-      debug_printf("llvmpipe: average LLVM compile time:  %.2f sec\n", lp_count.llvm_compile_time / 1000000.0 / lp_count.nr_llvm_compiles);
+      debug_printf("llvmpipe: nr_llvm_compiles:             %u\n", lp_count.nr_llvm_compiles);
+      debug_printf("llvmpipe: total LLVM compile time:      %.2f sec\n", lp_count.llvm_compile_time / 1000000.0);
+      debug_printf("llvmpipe: average LLVM compile time:    %.2f sec\n", lp_count.llvm_compile_time / 1000000.0 / lp_count.nr_llvm_compiles);
 
    }
 }
index a9629dae3c7882d4c1f1c94de7b643bf34e18a3b..4774f645508742dc1d7cd6c0167481e7fa6fa6b6 100644 (file)
@@ -44,6 +44,7 @@ struct lp_counters
    unsigned nr_empty_64;
    unsigned nr_fully_covered_64;
    unsigned nr_partially_covered_64;
+   unsigned nr_shade_opaque_64;
    unsigned nr_empty_16;
    unsigned nr_fully_covered_16;
    unsigned nr_partially_covered_16;
index c902c0468457333750cc0eb98092bd4aa9293743..02eeaf64871d5344aab458785f201939654a6331 100644 (file)
@@ -48,7 +48,7 @@ static struct llvmpipe_query *llvmpipe_query( struct pipe_query *p )
 
 static struct pipe_query *
 llvmpipe_create_query(struct pipe_context *pipe, 
-                     unsigned type)
+                      unsigned type)
 {
    struct llvmpipe_query *pq;
 
@@ -67,6 +67,16 @@ static void
 llvmpipe_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
 {
    struct llvmpipe_query *pq = llvmpipe_query(q);
+   /* query might still be in process if we never waited for the result */
+   if (!pq->done) {
+     struct pipe_fence_handle *fence = NULL;
+     llvmpipe_flush(pipe, 0, &fence);
+     if (fence) {
+         pipe->screen->fence_finish(pipe->screen, fence, 0);
+         pipe->screen->fence_reference(pipe->screen, &fence, NULL);
+      }
+   }
+
    pipe_mutex_destroy(pq->mutex);
    FREE(pq);
 }
@@ -74,16 +84,26 @@ llvmpipe_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
 
 static boolean
 llvmpipe_get_query_result(struct pipe_context *pipe, 
-                         struct pipe_query *q,
-                         boolean wait,
-                         void *vresult)
+                          struct pipe_query *q,
+                          boolean wait,
+                          void *vresult)
 {
-   struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
    struct llvmpipe_query *pq = llvmpipe_query(q);
    uint64_t *result = (uint64_t *)vresult;
 
    if (!pq->done) {
-      lp_setup_flush(llvmpipe->setup, 0);
+      if (wait) {
+         struct pipe_fence_handle *fence = NULL;
+         llvmpipe_flush(pipe, 0, &fence);
+         if (fence) {
+            pipe->screen->fence_finish(pipe->screen, fence, 0);
+            pipe->screen->fence_reference(pipe->screen, &fence, NULL);
+         }
+      }
+      /* this is a bit inconsequent but should be ok */
+      else {
+         llvmpipe_flush(pipe, 0, NULL);
+      }
    }
 
    if (pq->done) {
index 50e44dcb2b3beada2e46b1c482adcf061cf4bd58..654f4ea48ebeb965e448d2d25f68379d6f89995c 100644 (file)
@@ -28,6 +28,7 @@
 #include <limits.h>
 #include "util/u_memory.h"
 #include "util/u_math.h"
+#include "util/u_rect.h"
 #include "util/u_surface.h"
 
 #include "lp_scene_queue.h"
@@ -66,7 +67,7 @@ lp_rast_begin( struct lp_rasterizer *rast,
                             cbuf->level,
                             cbuf->zslice,
                             LP_TEX_USAGE_READ_WRITE,
-                            LP_TEX_LAYOUT_NONE);
+                            LP_TEX_LAYOUT_LINEAR);
    }
 
    if (fb->zsbuf) {
@@ -81,7 +82,6 @@ lp_rast_begin( struct lp_rasterizer *rast,
                                              zsbuf->zslice,
                                              LP_TEX_USAGE_READ_WRITE,
                                              LP_TEX_LAYOUT_NONE);
-      assert(rast->zsbuf.map);
    }
 
    lp_scene_bin_iter_begin( scene );
@@ -137,7 +137,6 @@ lp_rast_tile_begin(struct lp_rasterizer_task *task,
    struct lp_rasterizer *rast = task->rast;
    struct lp_scene *scene = rast->curr_scene;
    enum lp_texture_usage usage;
-   unsigned buf;
 
    LP_DBG(DEBUG_RAST, "%s %d,%d\n", __FUNCTION__, x, y);
 
@@ -147,24 +146,8 @@ lp_rast_tile_begin(struct lp_rasterizer_task *task,
    task->x = x;
    task->y = y;
 
-   if (scene->has_color_clear)
-      usage = LP_TEX_USAGE_WRITE_ALL;
-   else
-      usage = LP_TEX_USAGE_READ_WRITE;
-
-   /* get pointers to color tile(s) */
-   for (buf = 0; buf < rast->state.nr_cbufs; buf++) {
-      struct pipe_surface *cbuf = rast->curr_scene->fb.cbufs[buf];
-      struct llvmpipe_resource *lpt;
-      assert(cbuf);
-      lpt = llvmpipe_resource(cbuf->texture);
-      task->color_tiles[buf] = llvmpipe_get_texture_tile(lpt,
-                                                         cbuf->face + cbuf->zslice,
-                                                         cbuf->level,
-                                                         usage,
-                                                         x, y);
-      assert(task->color_tiles[buf]);
-   }
+   /* reset pointers to color tile(s) */
+   memset(task->color_tiles, 0, sizeof(task->color_tiles));
 
    /* get pointer to depth/stencil tile */
    {
@@ -188,7 +171,7 @@ lp_rast_tile_begin(struct lp_rasterizer_task *task,
          /* Get actual pointer to the tile data.  Note that depth/stencil
           * data is tiled differently than color data.
           */
-         task->depth_tile = lp_rast_get_depth_block_pointer(rast, x, y);
+         task->depth_tile = lp_rast_get_depth_block_pointer(task, x, y);
 
          assert(task->depth_tile);
       }
@@ -223,7 +206,8 @@ lp_rast_clear_color(struct lp_rasterizer_task *task,
        clear_color[2] == clear_color[3]) {
       /* clear to grayscale value {x, x, x, x} */
       for (i = 0; i < rast->state.nr_cbufs; i++) {
-         uint8_t *ptr = task->color_tiles[i];
+         uint8_t *ptr =
+            lp_rast_get_color_tile_pointer(task, i, LP_TEX_USAGE_WRITE_ALL);
         memset(ptr, clear_color[0], TILE_SIZE * TILE_SIZE * 4);
       }
    }
@@ -235,7 +219,8 @@ lp_rast_clear_color(struct lp_rasterizer_task *task,
        */
       const unsigned chunk = TILE_SIZE / 4;
       for (i = 0; i < rast->state.nr_cbufs; i++) {
-         uint8_t *c = task->color_tiles[i];
+         uint8_t *c =
+            lp_rast_get_color_tile_pointer(task, i, LP_TEX_USAGE_WRITE_ALL);
          unsigned j;
 
          for (j = 0; j < 4 * TILE_SIZE; j++) {
@@ -286,8 +271,6 @@ lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
 
    dst = task->depth_tile;
 
-   assert(dst == lp_rast_get_depth_block_pointer(rast, task->x, task->y));
-
    switch (block_size) {
    case 1:
       memset(dst, (uint8_t) clear_value, height * width);
@@ -376,8 +359,8 @@ lp_rast_load_color(struct lp_rasterizer_task *task,
  * This is a bin command which is stored in all bins.
  */
 void
-lp_rast_store_color( struct lp_rasterizer_task *task,
-                     const union lp_rast_cmd_arg arg)
+lp_rast_store_linear_color( struct lp_rasterizer_task *task,
+                            const union lp_rast_cmd_arg arg)
 {
    struct lp_rasterizer *rast = task->rast;
    struct lp_scene *scene = rast->curr_scene;
@@ -387,30 +370,20 @@ lp_rast_store_color( struct lp_rasterizer_task *task,
       struct pipe_surface *cbuf = scene->fb.cbufs[buf];
       const unsigned face = cbuf->face, level = cbuf->level;
       struct llvmpipe_resource *lpt = llvmpipe_resource(cbuf->texture);
-      /* this will convert the tiled data to linear if needed */
-      (void) llvmpipe_get_texture_tile_linear(lpt, face, level,
-                                              LP_TEX_USAGE_READ,
-                                              task->x, task->y);
-   }
-}
-
 
-/**
- * This is a bin command called during bin processing.
- */
-void
-lp_rast_set_state(struct lp_rasterizer_task *task,
-                  const union lp_rast_cmd_arg arg)
-{
-   const struct lp_rast_state *state = arg.set_state;
+      if (!task->color_tiles[buf])
+         continue;
 
-   LP_DBG(DEBUG_RAST, "%s %p\n", __FUNCTION__, (void *) state);
-
-   /* just set the current state pointer for this rasterizer */
-   task->current_state = state;
+      llvmpipe_unswizzle_cbuf_tile(lpt,
+                                   face,
+                                   level,
+                                   task->x, task->y,
+                                   task->color_tiles[buf]);
+   }
 }
 
 
+
 /**
  * Run the shader on all blocks in a tile.  This is used when a tile is
  * completely contained inside a triangle.
@@ -421,8 +394,8 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task,
                    const union lp_rast_cmd_arg arg)
 {
    struct lp_rasterizer *rast = task->rast;
-   const struct lp_rast_state *state = task->current_state;
    const struct lp_rast_shader_inputs *inputs = arg.shade_tile;
+   const struct lp_rast_state *state = inputs->state;
    struct lp_fragment_shader_variant *variant = state->variant;
    const unsigned tile_x = task->x, tile_y = task->y;
    unsigned x, y;
@@ -442,36 +415,60 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task,
                                                        tile_x + x, tile_y + y);
 
          /* depth buffer */
-         depth = lp_rast_get_depth_block_pointer(rast, tile_x + x, tile_y + y);
+         depth = lp_rast_get_depth_block_pointer(task, tile_x + x, tile_y + y);
 
          /* run shader on 4x4 block */
          variant->jit_function[RAST_WHOLE]( &state->jit_context,
-                                          tile_x + x, tile_y + y,
-                                          inputs->facing,
-                                          inputs->a0,
-                                          inputs->dadx,
-                                          inputs->dady,
-                                          color,
-                                          depth,
-                                          INT_MIN, INT_MIN, INT_MIN,
-                                          NULL, NULL, NULL, &task->vis_counter);
+                                            tile_x + x, tile_y + y,
+                                            inputs->facing,
+                                            inputs->a0,
+                                            inputs->dadx,
+                                            inputs->dady,
+                                            color,
+                                            depth,
+                                            0xffff,
+                                            &task->vis_counter);
       }
    }
 }
 
 
 /**
- * Compute shading for a 4x4 block of pixels.
+ * Run the shader on all blocks in a tile.  This is used when a tile is
+ * completely contained inside a triangle, and the shader is opaque.
+ * This is a bin command called during bin processing.
+ */
+void
+lp_rast_shade_tile_opaque(struct lp_rasterizer_task *task,
+                          const union lp_rast_cmd_arg arg)
+{
+   struct lp_rasterizer *rast = task->rast;
+   unsigned i;
+
+   LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
+
+   /* this will prevent converting the layout from tiled to linear */
+   for (i = 0; i < rast->state.nr_cbufs; i++) {
+      (void)lp_rast_get_color_tile_pointer(task, i, LP_TEX_USAGE_WRITE_ALL);
+   }
+
+   lp_rast_shade_tile(task, arg);
+}
+
+
+/**
+ * Compute shading for a 4x4 block of pixels inside a triangle.
  * This is a bin command called during bin processing.
  * \param x  X position of quad in window coords
  * \param y  Y position of quad in window coords
  */
-void lp_rast_shade_quads( struct lp_rasterizer_task *task,
-                          const struct lp_rast_shader_inputs *inputs,
-                          unsigned x, unsigned y,
-                          int32_t c1, int32_t c2, int32_t c3)
+void
+lp_rast_shade_quads_mask(struct lp_rasterizer_task *task,
+                         const struct lp_rast_shader_inputs *inputs,
+                         unsigned x, unsigned y,
+                         unsigned mask)
 {
-   const struct lp_rast_state *state = task->current_state;
+   const struct lp_rast_state *state = inputs->state;
    struct lp_fragment_shader_variant *variant = state->variant;
    struct lp_rasterizer *rast = task->rast;
    uint8_t *color[PIPE_MAX_COLOR_BUFS];
@@ -494,32 +491,26 @@ void lp_rast_shade_quads( struct lp_rasterizer_task *task,
    }
 
    /* depth buffer */
-   depth = lp_rast_get_depth_block_pointer(rast, x, y);
+   depth = lp_rast_get_depth_block_pointer(task, x, y);
 
 
    assert(lp_check_alignment(state->jit_context.blend_color, 16));
 
-   assert(lp_check_alignment(inputs->step[0], 16));
-   assert(lp_check_alignment(inputs->step[1], 16));
-   assert(lp_check_alignment(inputs->step[2], 16));
-
    /* run shader on 4x4 block */
-   variant->jit_function[RAST_EDGE_TEST]( &state->jit_context,
-                                        x, y,
-                                        inputs->facing,
-                                        inputs->a0,
-                                        inputs->dadx,
-                                        inputs->dady,
-                                        color,
-                                        depth,
-                                        c1, c2, c3,
-                                        inputs->step[0],
-                                        inputs->step[1],
-                                        inputs->step[2],
-                                       &task->vis_counter);
+   variant->jit_function[RAST_EDGE_TEST](&state->jit_context,
+                                         x, y,
+                                         inputs->facing,
+                                         inputs->a0,
+                                         inputs->dadx,
+                                         inputs->dady,
+                                         color,
+                                         depth,
+                                         mask,
+                                         &task->vis_counter);
 }
 
 
+
 /**
  * Set top row and left column of the tile's pixels to white.  For debugging.
  */
@@ -598,6 +589,11 @@ lp_rast_tile_end(struct lp_rasterizer_task *task)
    (void) outline_subtiles;
 #endif
 
+   {
+      union lp_rast_cmd_arg dummy = {0};
+      lp_rast_store_linear_color(task, dummy);
+   }
+
    /* debug */
    memset(task->color_tiles, 0, sizeof(task->color_tiles));
    task->depth_tile = NULL;
@@ -627,7 +623,7 @@ void
 lp_rast_begin_query(struct lp_rasterizer_task *task,
                     const union lp_rast_cmd_arg arg)
 {
-   /* Reset the the per-task counter */
+   /* Reset the per-task counter */
    task->vis_counter = 0;
 }
  
@@ -715,10 +711,16 @@ static struct {
 {
    RAST(clear_color),
    RAST(clear_zstencil),
-   RAST(triangle),
+   RAST(triangle_1),
+   RAST(triangle_2),
+   RAST(triangle_3),
+   RAST(triangle_4),
+   RAST(triangle_5),
+   RAST(triangle_6),
+   RAST(triangle_7),
    RAST(shade_tile),
-   RAST(set_state),
-   RAST(store_color),
+   RAST(shade_tile_opaque),
+   RAST(store_linear_color),
    RAST(fence),
    RAST(begin_query),
    RAST(end_query),
@@ -754,30 +756,8 @@ debug_bin( const struct cmd_bin *bin )
 static boolean
 is_empty_bin( const struct cmd_bin *bin )
 {
-   const struct cmd_block *head = bin->commands.head;
-   int i;
-   
-   if (0)
-      debug_bin(bin);
-   
-   /* We emit at most two load-tile commands at the start of the first
-    * command block.  In addition we seem to emit a couple of
-    * set-state commands even in empty bins.
-    *
-    * As a heuristic, if a bin has more than 4 commands, consider it
-    * non-empty.
-    */
-   if (head->next != NULL ||
-       head->count > 4) {
-      return FALSE;
-   }
-
-   for (i = 0; i < head->count; i++)
-      if (head->cmd[i] != lp_rast_set_state) {
-         return FALSE;
-      }
-
-   return TRUE;
+   if (0) debug_bin(bin);
+   return bin->commands.head->count == 0;
 }
 
 
@@ -813,6 +793,10 @@ rasterize_scene(struct lp_rasterizer_task *task,
       }
    }
 #endif
+
+   if (scene->fence) {
+      lp_rast_fence(task, lp_rast_arg_fence(scene->fence));
+   }
 }
 
 
@@ -983,6 +967,10 @@ lp_rast_create( unsigned num_threads )
    /* for synchronizing rasterization threads */
    pipe_barrier_init( &rast->barrier, rast->num_threads );
 
+   memset(lp_swizzled_cbuf, 0, sizeof lp_swizzled_cbuf);
+
+   memset(lp_dummy_tile, 0, sizeof lp_dummy_tile);
+
    return rast;
 }
 
index 80ca68f5a2f5161cfe38d676fbf7d75900c5efd1..eaf2a6f33450b752148735ec0fb67d4c5ada2fe6 100644 (file)
@@ -84,8 +84,7 @@ struct lp_rast_shader_inputs {
    float (*dadx)[4];
    float (*dady)[4];
 
-   /* edge/step info for 3 edges and 4x4 block of pixels */
-   PIPE_ALIGN_VAR(16) int step[3][16];
+   const struct lp_rast_state *state;
 };
 
 struct lp_rast_clearzs {
@@ -93,6 +92,22 @@ struct lp_rast_clearzs {
    unsigned clearzs_mask;
 };
 
+struct lp_rast_plane {
+   /* one-pixel sized trivial accept offsets for each plane */
+   int ei;
+
+   /* one-pixel sized trivial reject offsets for each plane */
+   int eo;
+
+   /* edge function values at minx,miny ?? */
+   int c;
+
+   int dcdx;
+   int dcdy;
+   
+   /* edge/step info for 3 edges and 4x4 block of pixels */
+   const int *step;
+};
 
 /**
  * Rasterization information for a triangle known to be in this bin,
@@ -101,35 +116,16 @@ struct lp_rast_clearzs {
  * Objects of this type are put into the lp_setup_context::data buffer.
  */
 struct lp_rast_triangle {
+   /* inputs for the shader */
+   struct lp_rast_shader_inputs inputs;
+
+   int step[3][16];
+
 #ifdef DEBUG
    float v[3][2];
 #endif
 
-   /* one-pixel sized trivial accept offsets for each plane */
-   int ei1;                   
-   int ei2;
-   int ei3;
-
-   /* one-pixel sized trivial reject offsets for each plane */
-   int eo1;                   
-   int eo2;
-   int eo3;
-
-   /* y deltas for vertex pairs (in fixed pt) */
-   int dy12;
-   int dy23;
-   int dy31;
-
-   /* x deltas for vertex pairs (in fixed pt) */
-   int dx12;
-   int dx23;
-   int dx31;
-
-   /* edge function values at minx,miny ?? */
-   int c1, c2, c3;
-
-   /* inputs for the shader */
-   PIPE_ALIGN_VAR(16) struct lp_rast_shader_inputs inputs;
+   struct lp_rast_plane plane[7]; /* NOTE: may allocate fewer planes */
 };
 
 
@@ -153,7 +149,10 @@ lp_rast_finish( struct lp_rasterizer *rast );
 
 union lp_rast_cmd_arg {
    const struct lp_rast_shader_inputs *shade_tile;
-   const struct lp_rast_triangle *triangle;
+   struct {
+      const struct lp_rast_triangle *tri;
+      unsigned plane_mask;
+   } triangle;
    const struct lp_rast_state *set_state;
    uint8_t clear_color[4];
    const struct lp_rast_clearzs *clear_zstencil;
@@ -173,10 +172,12 @@ lp_rast_arg_inputs( const struct lp_rast_shader_inputs *shade_tile )
 }
 
 static INLINE union lp_rast_cmd_arg
-lp_rast_arg_triangle( const struct lp_rast_triangle *triangle )
+lp_rast_arg_triangle( const struct lp_rast_triangle *triangle,
+                      unsigned plane_mask)
 {
    union lp_rast_cmd_arg arg;
-   arg.triangle = triangle;
+   arg.triangle.tri = triangle;
+   arg.triangle.plane_mask = plane_mask;
    return arg;
 }
 
@@ -226,19 +227,31 @@ void lp_rast_clear_color( struct lp_rasterizer_task *,
 void lp_rast_clear_zstencil( struct lp_rasterizer_task *, 
                              const union lp_rast_cmd_arg );
 
-void lp_rast_set_state( struct lp_rasterizer_task *, 
-                        const union lp_rast_cmd_arg );
-
-void lp_rast_triangle( struct lp_rasterizer_task *, 
-                       const union lp_rast_cmd_arg );
+void lp_rast_triangle_1( struct lp_rasterizer_task *, 
+                         const union lp_rast_cmd_arg );
+void lp_rast_triangle_2( struct lp_rasterizer_task *, 
+                         const union lp_rast_cmd_arg );
+void lp_rast_triangle_3( struct lp_rasterizer_task *, 
+                         const union lp_rast_cmd_arg );
+void lp_rast_triangle_4( struct lp_rasterizer_task *, 
+                         const union lp_rast_cmd_arg );
+void lp_rast_triangle_5( struct lp_rasterizer_task *, 
+                         const union lp_rast_cmd_arg );
+void lp_rast_triangle_6( struct lp_rasterizer_task *, 
+                         const union lp_rast_cmd_arg );
+void lp_rast_triangle_7( struct lp_rasterizer_task *, 
+                         const union lp_rast_cmd_arg );
 
 void lp_rast_shade_tile( struct lp_rasterizer_task *,
                          const union lp_rast_cmd_arg );
 
+void lp_rast_shade_tile_opaque( struct lp_rasterizer_task *,
+                                const union lp_rast_cmd_arg );
+
 void lp_rast_fence( struct lp_rasterizer_task *,
                     const union lp_rast_cmd_arg );
 
-void lp_rast_store_color( struct lp_rasterizer_task *,
+void lp_rast_store_linear_color( struct lp_rasterizer_task *,
                           const union lp_rast_cmd_arg );
 
 
index d33dd49f3a7dba7d4bf13bc7afdafaea80301b21..b4a48cfd024470c4a7aaee89ba98a8f6ea30b9c5 100644 (file)
@@ -31,6 +31,7 @@
 #include "os/os_thread.h"
 #include "util/u_format.h"
 #include "gallivm/lp_bld_debug.h"
+#include "lp_memory.h"
 #include "lp_rast.h"
 #include "lp_scene.h"
 #include "lp_state.h"
@@ -52,8 +53,6 @@ struct lp_rasterizer_task
    uint8_t *color_tiles[PIPE_MAX_COLOR_BUFS];
    uint8_t *depth_tile;
 
-   const struct lp_rast_state *current_state;
-
    /** "back" pointer */
    struct lp_rasterizer *rast;
 
@@ -118,10 +117,12 @@ struct lp_rasterizer
 };
 
 
-void lp_rast_shade_quads( struct lp_rasterizer_task *task,
-                          const struct lp_rast_shader_inputs *inputs,
-                          unsigned x, unsigned y,
-                          int32_t c1, int32_t c2, int32_t c3);
+void
+lp_rast_shade_quads_mask(struct lp_rasterizer_task *task,
+                         const struct lp_rast_shader_inputs *inputs,
+                         unsigned x, unsigned y,
+                         unsigned mask);
+
 
 
 /**
@@ -132,18 +133,23 @@ void lp_rast_shade_quads( struct lp_rasterizer_task *task,
  * \param x, y location of 4x4 block in window coords
  */
 static INLINE void *
-lp_rast_get_depth_block_pointer(const struct lp_rasterizer *rast,
+lp_rast_get_depth_block_pointer(struct lp_rasterizer_task *task,
                                 unsigned x, unsigned y)
 {
+   const struct lp_rasterizer *rast = task->rast;
    void *depth;
 
    assert((x % TILE_VECTOR_WIDTH) == 0);
    assert((y % TILE_VECTOR_HEIGHT) == 0);
 
-   assert(rast->zsbuf.map || !rast->curr_scene->fb.zsbuf);
-
-   if (!rast->zsbuf.map)
-      return NULL;
+   if (!rast->zsbuf.map) {
+      /* Either out of memory or no zsbuf.  Can't tell without access
+       * to the state.  Just use dummy tile memory, but don't print
+       * the oom warning as this most likely because there is no
+       * zsbuf.
+       */
+      return lp_dummy_tile;
+   }
 
    depth = (rast->zsbuf.map +
             rast->zsbuf.stride * y +
@@ -154,6 +160,39 @@ lp_rast_get_depth_block_pointer(const struct lp_rasterizer *rast,
 }
 
 
+/**
+ * Get pointer to the swizzled color tile
+ */
+static INLINE uint8_t *
+lp_rast_get_color_tile_pointer(struct lp_rasterizer_task *task,
+                               unsigned buf, enum lp_texture_usage usage)
+{
+   struct lp_rasterizer *rast = task->rast;
+
+   assert(task->x % TILE_SIZE == 0);
+   assert(task->y % TILE_SIZE == 0);
+   assert(buf < rast->state.nr_cbufs);
+
+   if (!task->color_tiles[buf]) {
+      struct pipe_surface *cbuf = rast->curr_scene->fb.cbufs[buf];
+      struct llvmpipe_resource *lpt;
+      assert(cbuf);
+      lpt = llvmpipe_resource(cbuf->texture);
+      task->color_tiles[buf] = lp_swizzled_cbuf[task->thread_index][buf];
+
+      if (usage != LP_TEX_USAGE_WRITE_ALL) {
+         llvmpipe_swizzle_cbuf_tile(lpt,
+                                    cbuf->face + cbuf->zslice,
+                                    cbuf->level,
+                                    task->x, task->y,
+                                    task->color_tiles[buf]);
+      }
+   }
+
+   return task->color_tiles[buf];
+}
+
+
 /**
  * Get the pointer to a 4x4 color block (within a 64x64 tile).
  * We'll map the color buffer on demand here.
@@ -171,7 +210,7 @@ lp_rast_get_color_block_pointer(struct lp_rasterizer_task *task,
    assert((x % TILE_VECTOR_WIDTH) == 0);
    assert((y % TILE_VECTOR_HEIGHT) == 0);
 
-   color = task->color_tiles[buf];
+   color = lp_rast_get_color_tile_pointer(task, buf, LP_TEX_USAGE_READ_WRITE);
    assert(color);
 
    px = x % TILE_SIZE;
@@ -196,8 +235,8 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
                          const struct lp_rast_shader_inputs *inputs,
                          unsigned x, unsigned y )
 {
-   struct lp_rasterizer *rast = task->rast;
-   const struct lp_rast_state *state = task->current_state;
+   const struct lp_rasterizer *rast = task->rast;
+   const struct lp_rast_state *state = inputs->state;
    struct lp_fragment_shader_variant *variant = state->variant;
    uint8_t *color[PIPE_MAX_COLOR_BUFS];
    void *depth;
@@ -207,19 +246,19 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
    for (i = 0; i < rast->state.nr_cbufs; i++)
       color[i] = lp_rast_get_color_block_pointer(task, i, x, y);
 
-   depth = lp_rast_get_depth_block_pointer(rast, x, y);
+   depth = lp_rast_get_depth_block_pointer(task, x, y);
 
    /* run shader on 4x4 block */
    variant->jit_function[RAST_WHOLE]( &state->jit_context,
-                                    x, y,
-                                    inputs->facing,
-                                    inputs->a0,
-                                    inputs->dadx,
-                                    inputs->dady,
-                                    color,
-                                    depth,
-                                    INT_MIN, INT_MIN, INT_MIN,
-                                    NULL, NULL, NULL, &task->vis_counter );
+                                      x, y,
+                                      inputs->facing,
+                                      inputs->a0,
+                                      inputs->dadx,
+                                      inputs->dady,
+                                      color,
+                                      depth,
+                                      0xffff,
+                                      &task->vis_counter );
 }
 
 
index a5f0d14c95dfd22f9f3a836ec8353501c166497f..ebe9a8e92b481a9eea33591326f3e76a166fd924 100644 (file)
@@ -113,168 +113,31 @@ block_full_16(struct lp_rasterizer_task *task,
         block_full_4(task, tri, x + ix, y + iy);
 }
 
+#define TAG(x) x##_1
+#define NR_PLANES 1
+#include "lp_rast_tri_tmp.h"
 
-/**
- * Pass the 4x4 pixel block to the shader function.
- * Determination of which of the 16 pixels lies inside the triangle
- * will be done as part of the fragment shader.
- */
-static void
-do_block_4(struct lp_rasterizer_task *task,
-           const struct lp_rast_triangle *tri,
-           int x, int y,
-           int c1, int c2, int c3)
-{
-   assert(x >= 0);
-   assert(y >= 0);
-
-   lp_rast_shade_quads(task, &tri->inputs, x, y, -c1, -c2, -c3);
-}
-
-
-/**
- * Evaluate a 16x16 block of pixels to determine which 4x4 subblocks are in/out
- * of the triangle's bounds.
- */
-static void
-do_block_16(struct lp_rasterizer_task *task,
-            const struct lp_rast_triangle *tri,
-            int x, int y,
-            int c0, int c1, int c2)
-{
-   unsigned mask = 0;
-   int eo[3];
-   int c[3];
-   int i, j;
-
-   assert(x >= 0);
-   assert(y >= 0);
-   assert(x % 16 == 0);
-   assert(y % 16 == 0);
-
-   eo[0] = tri->eo1 * 4;
-   eo[1] = tri->eo2 * 4;
-   eo[2] = tri->eo3 * 4;
-
-   c[0] = c0;
-   c[1] = c1;
-   c[2] = c2;
-
-   for (j = 0; j < 3; j++) {
-      const int *step = tri->inputs.step[j];
-      const int cx = c[j] + eo[j];
-
-      /* Mask has bits set whenever we are outside any of the edges.
-       */
-      for (i = 0; i < 16; i++) {
-         int out = cx + step[i] * 4;
-         mask |= (out >> 31) & (1 << i);
-      }
-   }
+#define TAG(x) x##_2
+#define NR_PLANES 2
+#include "lp_rast_tri_tmp.h"
 
-   mask = ~mask & 0xffff;
-   while (mask) {
-      int i = ffs(mask) - 1;
-      int px = x + pos_table4[i][0];
-      int py = y + pos_table4[i][1];
-      int cx1 = c0 + tri->inputs.step[0][i] * 4;
-      int cx2 = c1 + tri->inputs.step[1][i] * 4;
-      int cx3 = c2 + tri->inputs.step[2][i] * 4;
+#define TAG(x) x##_3
+#define NR_PLANES 3
+#include "lp_rast_tri_tmp.h"
 
-      mask &= ~(1 << i);
+#define TAG(x) x##_4
+#define NR_PLANES 4
+#include "lp_rast_tri_tmp.h"
 
-      /* Don't bother testing if the 4x4 block is entirely in/out of
-       * the triangle.  It's a little faster to do it in the jit code.
-       */
-      LP_COUNT(nr_non_empty_4);
-      do_block_4(task, tri, px, py, cx1, cx2, cx3);
-   }
-}
-
-
-/**
- * Scan the tile in chunks and figure out which pixels to rasterize
- * for this triangle.
- */
-void
-lp_rast_triangle(struct lp_rasterizer_task *task,
-                 const union lp_rast_cmd_arg arg)
-{
-   const struct lp_rast_triangle *tri = arg.triangle;
-   const int x = task->x, y = task->y;
-   int ei[3], eo[3], c[3];
-   unsigned outmask, inmask, partial_mask;
-   unsigned i, j;
-
-   c[0] = tri->c1 + tri->dx12 * y - tri->dy12 * x;
-   c[1] = tri->c2 + tri->dx23 * y - tri->dy23 * x;
-   c[2] = tri->c3 + tri->dx31 * y - tri->dy31 * x;
-
-   eo[0] = tri->eo1 * 16;
-   eo[1] = tri->eo2 * 16;
-   eo[2] = tri->eo3 * 16;
-
-   ei[0] = tri->ei1 * 16;
-   ei[1] = tri->ei2 * 16;
-   ei[2] = tri->ei3 * 16;
-
-   outmask = 0;
-   inmask = 0xffff;
+#define TAG(x) x##_5
+#define NR_PLANES 5
+#include "lp_rast_tri_tmp.h"
 
-   for (j = 0; j < 3; j++) {
-      const int *step = tri->inputs.step[j];
-      const int cox = c[j] + eo[j];
-      const int cio = ei[j]- eo[j];
+#define TAG(x) x##_6
+#define NR_PLANES 6
+#include "lp_rast_tri_tmp.h"
 
-      /* Outmask has bits set whenever we are outside any of the
-       * edges.
-       */
-      /* Inmask has bits set whenever we are inside all of the edges.
-       */
-      for (i = 0; i < 16; i++) {
-         int out = cox + step[i] * 16;
-         int in = out + cio;
-         outmask |= (out >> 31) & (1 << i);
-         inmask &= ~((in >> 31) & (1 << i));
-      }
-   }
+#define TAG(x) x##_7
+#define NR_PLANES 7
+#include "lp_rast_tri_tmp.h"
 
-   assert((outmask & inmask) == 0);
-
-   if (outmask == 0xffff)
-      return;
-
-   /* Invert mask, so that bits are set whenever we are at least
-    * partially inside all of the edges:
-    */
-   partial_mask = ~inmask & ~outmask & 0xffff;
-
-   /* Iterate over partials:
-    */
-   while (partial_mask) {
-      int i = ffs(partial_mask) - 1;
-      int px = x + pos_table16[i][0];
-      int py = y + pos_table16[i][1];
-      int cx1 = c[0] + tri->inputs.step[0][i] * 16;
-      int cx2 = c[1] + tri->inputs.step[1][i] * 16;
-      int cx3 = c[2] + tri->inputs.step[2][i] * 16;
-
-      partial_mask &= ~(1 << i);
-
-      LP_COUNT(nr_partially_covered_16);
-      do_block_16(task, tri, px, py, cx1, cx2, cx3);
-   }
-
-   /* Iterate over fulls: 
-    */
-   while (inmask) {
-      int i = ffs(inmask) - 1;
-      int px = x + pos_table16[i][0];
-      int py = y + pos_table16[i][1];
-
-      inmask &= ~(1 << i);
-
-      LP_COUNT(nr_fully_covered_16);
-      block_full_16(task, tri, px, py);
-   }
-}
diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri_tmp.h b/src/gallium/drivers/llvmpipe/lp_rast_tri_tmp.h
new file mode 100644 (file)
index 0000000..a410c61
--- /dev/null
@@ -0,0 +1,238 @@
+/**************************************************************************
+ *
+ * Copyright 2007-2010 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE 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.
+ *
+ **************************************************************************/
+
+/*
+ * Rasterization for binned triangles within a tile
+ */
+
+
+
+/**
+ * Prototype for a 7 plane rasterizer function.  Will codegenerate
+ * several of these.
+ *
+ * XXX: Varients for more/fewer planes.
+ * XXX: Need ways of dropping planes as we descend.
+ * XXX: SIMD
+ */
+static void
+TAG(do_block_4)(struct lp_rasterizer_task *task,
+                const struct lp_rast_triangle *tri,
+                const struct lp_rast_plane *plane,
+                int x, int y,
+                const int *c)
+{
+   unsigned mask = 0;
+   int i;
+
+   for (i = 0; i < 16; i++) {
+      int any_negative = 0;
+      int j;
+
+      for (j = 0; j < NR_PLANES; j++) 
+         any_negative |= (c[j] - 1 + plane[j].step[i]);
+         
+      any_negative >>= 31;
+
+      mask |= (~any_negative) & (1 << i);
+   }
+
+   /* Now pass to the shader:
+    */
+   if (mask)
+      lp_rast_shade_quads_mask(task, &tri->inputs, x, y, mask);
+}
+
+/**
+ * Evaluate a 16x16 block of pixels to determine which 4x4 subblocks are in/out
+ * of the triangle's bounds.
+ */
+static void
+TAG(do_block_16)(struct lp_rasterizer_task *task,
+                 const struct lp_rast_triangle *tri,
+                 const struct lp_rast_plane *plane,
+                 int x, int y,
+                 const int *c)
+{
+   unsigned outmask, inmask, partmask, partial_mask;
+   unsigned i, j;
+
+   outmask = 0;                 /* outside one or more trivial reject planes */
+   partmask = 0;                /* outside one or more trivial accept planes */
+
+   for (j = 0; j < NR_PLANES; j++) {
+      const int *step = plane[j].step;
+      const int eo = plane[j].eo * 4;
+      const int ei = plane[j].ei * 4;
+      const int cox = c[j] + eo;
+      const int cio = ei - 1 - eo;
+
+      for (i = 0; i < 16; i++) {
+         int out = cox + step[i] * 4;
+         int part = out + cio;
+         outmask  |= (out >> 31) & (1 << i);
+         partmask |= (part >> 31) & (1 << i);
+      }
+   }
+
+   if (outmask == 0xffff)
+      return;
+
+   /* Mask of sub-blocks which are inside all trivial accept planes:
+    */
+   inmask = ~partmask & 0xffff;
+
+   /* Mask of sub-blocks which are inside all trivial reject planes,
+    * but outside at least one trivial accept plane:
+    */
+   partial_mask = partmask & ~outmask;
+
+   assert((partial_mask & inmask) == 0);
+
+   /* Iterate over partials:
+    */
+   while (partial_mask) {
+      int i = ffs(partial_mask) - 1;
+      int px = x + pos_table4[i][0];
+      int py = y + pos_table4[i][1];
+      int cx[NR_PLANES];
+
+      for (j = 0; j < NR_PLANES; j++)
+         cx[j] = c[j] + plane[j].step[i] * 4;
+
+      partial_mask &= ~(1 << i);
+
+      TAG(do_block_4)(task, tri, plane, px, py, cx);
+   }
+
+   /* Iterate over fulls: 
+    */
+   while (inmask) {
+      int i = ffs(inmask) - 1;
+      int px = x + pos_table4[i][0];
+      int py = y + pos_table4[i][1];
+
+      inmask &= ~(1 << i);
+
+      block_full_4(task, tri, px, py);
+   }
+}
+
+
+/**
+ * Scan the tile in chunks and figure out which pixels to rasterize
+ * for this triangle.
+ */
+void
+TAG(lp_rast_triangle)(struct lp_rasterizer_task *task,
+                      const union lp_rast_cmd_arg arg)
+{
+   const struct lp_rast_triangle *tri = arg.triangle.tri;
+   unsigned plane_mask = arg.triangle.plane_mask;
+   const int x = task->x, y = task->y;
+   struct lp_rast_plane plane[NR_PLANES];
+   int c[NR_PLANES];
+   unsigned outmask, inmask, partmask, partial_mask;
+   unsigned i, j, nr_planes = 0;
+
+   while (plane_mask) {
+      int i = ffs(plane_mask) - 1;
+      plane[nr_planes] = tri->plane[i];
+      plane_mask &= ~(1 << i);
+      nr_planes++;
+   };
+
+   assert(nr_planes == NR_PLANES);
+   outmask = 0;                 /* outside one or more trivial reject planes */
+   partmask = 0;                /* outside one or more trivial accept planes */
+
+   for (j = 0; j < NR_PLANES; j++) {
+      const int *step = plane[j].step;
+      const int eo = plane[j].eo * 16;
+      const int ei = plane[j].ei * 16;
+      int cox, cio;
+
+      c[j] = plane[j].c + plane[j].dcdy * y - plane[j].dcdx * x;
+      cox = c[j] + eo;
+      cio = ei - 1 - eo;
+
+      for (i = 0; i < 16; i++) {
+         int out = cox + step[i] * 16;
+         int part = out + cio;
+         outmask  |= (out >> 31) & (1 << i);
+         partmask |= (part >> 31) & (1 << i);
+      }
+   }
+
+   if (outmask == 0xffff)
+      return;
+
+   /* Mask of sub-blocks which are inside all trivial accept planes:
+    */
+   inmask = ~partmask & 0xffff;
+
+   /* Mask of sub-blocks which are inside all trivial reject planes,
+    * but outside at least one trivial accept plane:
+    */
+   partial_mask = partmask & ~outmask;
+
+   assert((partial_mask & inmask) == 0);
+
+   /* Iterate over partials:
+    */
+   while (partial_mask) {
+      int i = ffs(partial_mask) - 1;
+      int px = x + pos_table16[i][0];
+      int py = y + pos_table16[i][1];
+      int cx[NR_PLANES];
+
+      for (j = 0; j < NR_PLANES; j++)
+         cx[j] = c[j] + plane[j].step[i] * 16;
+
+      partial_mask &= ~(1 << i);
+
+      LP_COUNT(nr_partially_covered_16);
+      TAG(do_block_16)(task, tri, plane, px, py, cx);
+   }
+
+   /* Iterate over fulls: 
+    */
+   while (inmask) {
+      int i = ffs(inmask) - 1;
+      int px = x + pos_table16[i][0];
+      int py = y + pos_table16[i][1];
+
+      inmask &= ~(1 << i);
+
+      LP_COUNT(nr_fully_covered_16);
+      block_full_16(task, tri, px, py);
+   }
+}
+
+#undef TAG
+#undef NR_PLANES
+
index 845c175cf2ecc0780e508339d4b3c2b93c40afe8..f88a759fe703bf03bb4eafe21eac4c52f4869dff 100644 (file)
@@ -32,6 +32,7 @@
 #include "util/u_simple_list.h"
 #include "lp_scene.h"
 #include "lp_scene_queue.h"
+#include "lp_fence.h"
 
 
 /** List of texture references */
@@ -162,8 +163,8 @@ lp_scene_reset(struct lp_scene *scene )
 
    /* Free all but last binner command lists:
     */
-   for (i = 0; i < scene->tiles_x; i++) {
-      for (j = 0; j < scene->tiles_y; j++) {
+   for (i = 0; i < TILES_X; i++) {
+      for (j = 0; j < TILES_Y; j++) {
          lp_scene_bin_reset(scene, i, j);
       }
    }
@@ -198,6 +199,8 @@ lp_scene_reset(struct lp_scene *scene )
       make_empty_list(ref_list);
    }
 
+   lp_fence_reference(&scene->fence, NULL);
+
    scene->scene_size = 0;
 
    scene->has_color_clear = FALSE;
@@ -303,60 +306,6 @@ lp_scene_is_resource_referenced(const struct lp_scene *scene,
 }
 
 
-/**
- * Return last command in the bin
- */
-static lp_rast_cmd
-lp_get_last_command( const struct cmd_bin *bin )
-{
-   const struct cmd_block *tail = bin->commands.tail;
-   const unsigned i = tail->count;
-   if (i > 0)
-      return tail->cmd[i - 1];
-   else
-      return NULL;
-}
-
-
-/**
- * Replace the arg of the last command in the bin.
- */
-static void
-lp_replace_last_command_arg( struct cmd_bin *bin,
-                             const union lp_rast_cmd_arg arg )
-{
-   struct cmd_block *tail = bin->commands.tail;
-   const unsigned i = tail->count;
-   assert(i > 0);
-   tail->arg[i - 1] = arg;
-}
-
-
-
-/**
- * Put a state-change command into all bins.
- * If we find that the last command in a bin was also a state-change
- * command, we can simply replace that one with the new one.
- */
-void
-lp_scene_bin_state_command( struct lp_scene *scene,
-                            lp_rast_cmd cmd,
-                            const union lp_rast_cmd_arg arg )
-{
-   unsigned i, j;
-   for (i = 0; i < scene->tiles_x; i++) {
-      for (j = 0; j < scene->tiles_y; j++) {
-         struct cmd_bin *bin = lp_scene_get_bin(scene, i, j);
-         lp_rast_cmd last_cmd = lp_get_last_command(bin);
-         if (last_cmd == cmd) {
-            lp_replace_last_command_arg(bin, arg);
-         }
-         else {
-            lp_scene_bin_command( scene, i, j, cmd, arg );
-         }
-      }
-   }
-}
 
 
 /** advance curr_x,y to the next bin */
index 4e55d43174697a1bae42823c17de096b8d4b0ce9..fa1b311fa1762d40badcbda4f8a5d602940d50aa 100644 (file)
@@ -112,6 +112,7 @@ struct resource_ref {
  */
 struct lp_scene {
    struct pipe_context *pipe;
+   struct lp_fence *fence;
 
    /** the framebuffer to render the scene into */
    struct pipe_framebuffer_state fb;
index 6432cea862d58e6983b8345cc55793d83e9a40da..167cb2ee2e05cde6710f0754582715038f7e90fb 100644 (file)
@@ -43,6 +43,7 @@
 #include "lp_debug.h"
 #include "lp_public.h"
 #include "lp_limits.h"
+#include "lp_rast.h"
 
 #include "state_tracker/sw_winsys.h"
 
@@ -86,7 +87,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
       return PIPE_MAX_SAMPLERS;
    case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
-      return 0;
+      return PIPE_MAX_VERTEX_SAMPLERS;
    case PIPE_CAP_MAX_COMBINED_SAMPLERS:
       return PIPE_MAX_SAMPLERS + PIPE_MAX_VERTEX_SAMPLERS;
    case PIPE_CAP_NPOT_TEXTURES:
@@ -166,6 +167,10 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return LP_MAX_TGSI_PREDS;
    case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
       return 1;
+   case PIPE_CAP_GEOMETRY_SHADER4:
+      return 1;
+   case PIPE_CAP_DEPTH_CLAMP:
+      return 0;
    default:
       assert(0);
       return 0;
@@ -294,11 +299,16 @@ llvmpipe_destroy_screen( struct pipe_screen *_screen )
    struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
    struct sw_winsys *winsys = screen->winsys;
 
+   if (screen->rast)
+      lp_rast_destroy(screen->rast);
+
    lp_jit_screen_cleanup(screen);
 
    if(winsys->destroy)
       winsys->destroy(winsys);
 
+   pipe_mutex_destroy(screen->rast_mutex);
+
    FREE(screen);
 }
 
@@ -347,11 +357,6 @@ llvmpipe_create_screen(struct sw_winsys *winsys)
 
    lp_jit_screen_init(screen);
 
-#ifdef PIPE_OS_WINDOWS
-   /* Multithreading not supported on windows until conditions and barriers are
-    * properly implemented. */
-   screen->num_threads = 0;
-#else
 #ifdef PIPE_OS_EMBEDDED
    screen->num_threads = 0;
 #else
@@ -359,7 +364,14 @@ llvmpipe_create_screen(struct sw_winsys *winsys)
 #endif
    screen->num_threads = debug_get_num_option("LP_NUM_THREADS", screen->num_threads);
    screen->num_threads = MIN2(screen->num_threads, LP_MAX_THREADS);
-#endif
+
+   screen->rast = lp_rast_create(screen->num_threads);
+   if (!screen->rast) {
+      lp_jit_screen_cleanup(screen);
+      FREE(screen);
+      return NULL;
+   }
+   pipe_mutex_init(screen->rast_mutex);
 
    util_format_s3tc_init();
 
index eb40f6823f5f946be6fa686022f27a96abf7a304..731526dfabebc72e28d8ddb5a0a0a30a08d29e4f 100644 (file)
@@ -37,6 +37,7 @@
 #include "gallivm/lp_bld.h"
 #include <llvm-c/ExecutionEngine.h>
 
+#include "os/os_thread.h"
 #include "pipe/p_screen.h"
 #include "pipe/p_defines.h"
 
@@ -63,6 +64,9 @@ struct llvmpipe_screen
    /* Increments whenever textures are modified.  Contexts can track this.
     */
    unsigned timestamp;
+
+   struct lp_rasterizer *rast;
+   pipe_mutex rast_mutex;
 };
 
 
index e8aafee33ff06b296422fabff015bb8747d79bc1..556e571585dc948268415dccf01fea6a5d95c6e4 100644 (file)
@@ -40,6 +40,7 @@
 #include "util/u_memory.h"
 #include "util/u_pack_color.h"
 #include "lp_context.h"
+#include "lp_memory.h"
 #include "lp_scene.h"
 #include "lp_scene_queue.h"
 #include "lp_texture.h"
@@ -63,15 +64,7 @@ struct lp_scene *
 lp_setup_get_current_scene(struct lp_setup_context *setup)
 {
    if (!setup->scene) {
-
-      /* wait for a free/empty scene
-       */
-      setup->scene = lp_scene_dequeue(setup->empty_scenes, TRUE);
-
-      assert(lp_scene_is_empty(setup->scene));
-
-      lp_scene_begin_binning(setup->scene,
-                             &setup->fb );
+      set_scene_state( setup, SETUP_EMPTY );
    }
    return setup->scene;
 }
@@ -159,8 +152,11 @@ static void
 lp_setup_rasterize_scene( struct lp_setup_context *setup )
 {
    struct lp_scene *scene = lp_setup_get_current_scene(setup);
+   struct llvmpipe_screen *screen = llvmpipe_screen(scene->pipe->screen);
 
-   lp_scene_rasterize(scene, setup->rast);
+   pipe_mutex_lock(screen->rast_mutex);
+   lp_scene_rasterize(scene, screen->rast);
+   pipe_mutex_unlock(screen->rast_mutex);
 
    reset_context( setup );
 
@@ -233,22 +229,36 @@ set_scene_state( struct lp_setup_context *setup,
    LP_DBG(DEBUG_SETUP, "%s old %d new %d\n", __FUNCTION__, old_state, new_state);
 
    switch (new_state) {
-   case SETUP_ACTIVE:
-      begin_binning( setup );
+   case SETUP_EMPTY:
+      assert(old_state == SETUP_FLUSHED);
+      assert(setup->scene == NULL);
+
+      /* wait for a free/empty scene
+       */
+      setup->scene = lp_scene_dequeue(setup->empty_scenes, TRUE);
+      assert(lp_scene_is_empty(setup->scene));
+      lp_scene_begin_binning(setup->scene,
+                             &setup->fb );
       break;
 
    case SETUP_CLEARED:
-      if (old_state == SETUP_ACTIVE) {
-         assert(0);
-         return;
-      }
+      assert(old_state == SETUP_EMPTY);
+      assert(setup->scene != NULL);
       break;
-      
+
+   case SETUP_ACTIVE:
+      assert(old_state == SETUP_EMPTY ||
+             old_state == SETUP_CLEARED);
+      assert(setup->scene != NULL);
+      begin_binning( setup );
+      break;
+
    case SETUP_FLUSHED:
       if (old_state == SETUP_CLEARED)
          execute_clears( setup );
       else
          lp_setup_rasterize_scene( setup );
+      assert(setup->scene == NULL);
       break;
 
    default:
@@ -264,23 +274,19 @@ set_scene_state( struct lp_setup_context *setup,
  */
 void
 lp_setup_flush( struct lp_setup_context *setup,
-                unsigned flags )
+                unsigned flags,
+                struct pipe_fence_handle **fence)
 {
    LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
 
    if (setup->scene) {
-      struct lp_scene *scene = lp_setup_get_current_scene(setup);
-      union lp_rast_cmd_arg dummy = {0};
-
-      if (flags & (PIPE_FLUSH_SWAPBUFFERS |
-                   PIPE_FLUSH_FRAME)) {
-         /* Store colors in the linear color buffer(s).
-          * If we don't do this here, we'll end up converting the tiled
-          * data to linear in the texture_unmap() function, which will
-          * not be a parallel/threaded operation as here.
+      if (fence) {
+         /* if we're going to flush the setup/rasterization modules, emit
+          * a fence.
           */
-         lp_scene_bin_everywhere(scene, lp_rast_store_color, dummy);
+         *fence = lp_setup_fence( setup );
       }
+
    }
 
    set_scene_state( setup, SETUP_FLUSHED );
@@ -297,6 +303,11 @@ lp_setup_bind_framebuffer( struct lp_setup_context *setup,
     */
    set_scene_state( setup, SETUP_FLUSHED );
 
+   /*
+    * Ensure the old scene is not reused.
+    */
+   assert(!setup->scene);
+
    /* Set new state.  This will be picked up later when we next need a
     * scene.
     */
@@ -421,24 +432,27 @@ lp_setup_clear( struct lp_setup_context *setup,
 struct pipe_fence_handle *
 lp_setup_fence( struct lp_setup_context *setup )
 {
-   if (setup->num_threads == 0) {
+   if (setup->scene == NULL)
       return NULL;
-   }
-   else {
+   else if (setup->num_threads == 0)
+      return NULL;
+   else
+   {
       struct lp_scene *scene = lp_setup_get_current_scene(setup);
-      const unsigned rank = lp_scene_get_num_bins( scene ); /* xxx */
-      struct lp_fence *fence = lp_fence_create(rank);
-
-      LP_DBG(DEBUG_SETUP, "%s rank %u\n", __FUNCTION__, rank);
+      const unsigned rank = setup->num_threads;
 
       set_scene_state( setup, SETUP_ACTIVE );
+      
+      assert(scene->fence == NULL);
+
+      /* The caller gets a reference, we keep a copy too, so need to
+       * bump the refcount:
+       */
+      lp_fence_reference(&scene->fence, lp_fence_create(rank));
 
-      /* insert the fence into all command bins */
-      lp_scene_bin_everywhere( scene,
-                               lp_rast_fence,
-                               lp_rast_arg_fence(fence) );
+      LP_DBG(DEBUG_SETUP, "%s rank %u\n", __FUNCTION__, rank);
 
-      return (struct pipe_fence_handle *) fence;
+      return (struct pipe_fence_handle *) scene->fence;
    }
 }
 
@@ -611,6 +625,17 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
                                                  LP_TEX_LAYOUT_LINEAR);
                jit_tex->row_stride[j] = lp_tex->row_stride[j];
                jit_tex->img_stride[j] = lp_tex->img_stride[j];
+
+               if (!jit_tex->data[j]) {
+                  /* out of memory - use dummy tile memory */
+                  jit_tex->data[j] = lp_dummy_tile;
+                  jit_tex->width = TILE_SIZE;
+                  jit_tex->height = TILE_SIZE;
+                  jit_tex->depth = 1;
+                  jit_tex->last_level = 0;
+                  jit_tex->row_stride[j] = 0;
+                  jit_tex->img_stride[j] = 0;
+               }
             }
          }
          else {
@@ -618,7 +643,6 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup,
             /*
              * XXX: Where should this be unmapped?
              */
-
             struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
             struct sw_winsys *winsys = screen->winsys;
             jit_tex->data[0] = winsys->displaytarget_map(winsys, lp_tex->dt,
@@ -717,28 +741,6 @@ lp_setup_update_state( struct lp_setup_context *setup )
       setup->dirty |= LP_SETUP_NEW_FS;
    }
 
-   if (setup->dirty & LP_SETUP_NEW_SCISSOR) {
-      float *stored;
-
-      stored = lp_scene_alloc_aligned(scene, 4 * sizeof(int32_t), 16);
-
-      if (stored) {
-         stored[0] = (float) setup->scissor.current.minx;
-         stored[1] = (float) setup->scissor.current.miny;
-         stored[2] = (float) setup->scissor.current.maxx;
-         stored[3] = (float) setup->scissor.current.maxy;
-
-         setup->scissor.stored = stored;
-
-         setup->fs.current.jit_context.scissor_xmin = stored[0];
-         setup->fs.current.jit_context.scissor_ymin = stored[1];
-         setup->fs.current.jit_context.scissor_xmax = stored[2];
-         setup->fs.current.jit_context.scissor_ymax = stored[3];
-      }
-
-      setup->dirty |= LP_SETUP_NEW_FS;
-   }
-
    if(setup->dirty & LP_SETUP_NEW_CONSTANTS) {
       struct pipe_resource *buffer = setup->constants.current;
 
@@ -792,11 +794,6 @@ lp_setup_update_state( struct lp_setup_context *setup )
                    &setup->fs.current,
                    sizeof setup->fs.current);
             setup->fs.stored = stored;
-
-            /* put the state-set command into all bins */
-            lp_scene_bin_state_command( scene,
-                                       lp_rast_set_state, 
-                                       lp_rast_arg_state(setup->fs.stored) );
          }
 
          /* The scene now references the textures in the rasterization
@@ -843,8 +840,6 @@ lp_setup_destroy( struct lp_setup_context *setup )
 
    lp_scene_queue_destroy(setup->empty_scenes);
 
-   lp_rast_destroy( setup->rast );
-
    FREE( setup );
 }
 
@@ -871,13 +866,7 @@ lp_setup_create( struct pipe_context *pipe,
    if (!setup->empty_scenes)
       goto fail;
 
-   /* XXX: move this to the screen and share between contexts:
-    */
    setup->num_threads = screen->num_threads;
-   setup->rast = lp_rast_create(screen->num_threads);
-   if (!setup->rast) 
-      goto fail;
-
    setup->vbuf = draw_vbuf_stage(draw, &setup->base);
    if (!setup->vbuf)
       goto fail;
@@ -901,9 +890,6 @@ lp_setup_create( struct pipe_context *pipe,
    return setup;
 
 fail:
-   if (setup->rast)
-      lp_rast_destroy( setup->rast );
-   
    if (setup->vbuf)
       ;
 
@@ -933,6 +919,8 @@ lp_setup_begin_query(struct lp_setup_context *setup,
 
    memset(pq->count, 0, sizeof(pq->count));  /* reset all counters */
 
+   set_scene_state( setup, SETUP_ACTIVE );
+
    cmd_arg.query_obj = pq;
    lp_scene_bin_everywhere(scene, lp_rast_begin_query, cmd_arg);
    pq->binned = TRUE;
@@ -948,6 +936,8 @@ lp_setup_end_query(struct lp_setup_context *setup, struct llvmpipe_query *pq)
    struct lp_scene * scene = lp_setup_get_current_scene(setup);
    union lp_rast_cmd_arg cmd_arg;
 
+   set_scene_state( setup, SETUP_ACTIVE );
+
    cmd_arg.query_obj = pq;
    lp_scene_bin_everywhere(scene, lp_rast_end_query, cmd_arg);
 }
index 6a0dc551290ffb4800da7a17850fcc3790a62b55..73b1c85325a4ec5eb883f84dfe8daf094827b683 100644 (file)
@@ -84,7 +84,8 @@ lp_setup_fence( struct lp_setup_context *setup );
 
 void
 lp_setup_flush( struct lp_setup_context *setup,
-                unsigned flags );
+                unsigned flags,
+                struct pipe_fence_handle **fence);
 
 
 void
index c8b8a2480b0e9221baf8c11c4be600964f496748..a0606f503408e882db84b176b457f1c450cb5825 100644 (file)
@@ -81,7 +81,6 @@ struct lp_setup_context
     */
    struct draw_stage *vbuf;
    unsigned num_threads;
-   struct lp_rasterizer *rast;
    struct lp_scene *scenes[MAX_SCENES];  /**< all the scenes */
    struct lp_scene *scene;               /**< current scene being built */
    struct lp_scene_queue *empty_scenes;  /**< queue of empty scenes */
@@ -101,9 +100,10 @@ struct lp_setup_context
    } clear;
 
    enum setup_state {
-      SETUP_FLUSHED,
-      SETUP_CLEARED,
-      SETUP_ACTIVE
+      SETUP_FLUSHED,    /**< scene is null */
+      SETUP_EMPTY,      /**< scene exists but has only state changes */
+      SETUP_CLEARED,    /**< scene exists but has only clears */
+      SETUP_ACTIVE      /**< scene exists and has at least one draw/query */
    } state;
    
    struct {
@@ -129,7 +129,6 @@ struct lp_setup_context
 
    struct {
       struct pipe_scissor_state current;
-      const void *stored;
    } scissor;
 
    unsigned dirty;   /**< bitmask of LP_SETUP_NEW_x bits */
index 0557d35f8b152879f65f68365889a615d7f4d275..7e432503c126028d33c8034c59d3fbdf06dab686 100644 (file)
 
 #define NUM_CHANNELS 4
 
+struct tri_info {
+
+   float pixel_offset;
+
+   /* fixed point vertex coordinates */
+   int x[3];
+   int y[3];
+
+   /* float x,y deltas - all from the original coordinates
+    */
+   float dy01, dy20;
+   float dx01, dx20;
+   float oneoverarea;
+
+   const float (*v0)[4];
+   const float (*v1)[4];
+   const float (*v2)[4];
+
+   boolean frontfacing;
+};
+
+
+
+static const int step_scissor_minx[16] = {
+   0, 1, 0, 1,
+   2, 3, 2, 3,
+   0, 1, 0, 1,
+   2, 3, 2, 3
+};
+
+static const int step_scissor_maxx[16] = {
+    0, -1,  0, -1,
+   -2, -3, -2, -3,
+    0, -1,  0, -1,
+   -2, -3, -2, -3
+};
+
+static const int step_scissor_miny[16] = {
+   0, 0, 1, 1,
+   0, 0, 1, 1,
+   2, 2, 3, 3,
+   2, 2, 3, 3
+};
+
+static const int step_scissor_maxy[16] = {
+    0,  0, -1, -1,
+    0,  0, -1, -1,
+   -2, -2, -3, -3,
+   -2, -2, -3, -3
+};
+
+
+
+   
+static INLINE int
+subpixel_snap(float a)
+{
+   return util_iround(FIXED_ONE * a);
+}
+
+static INLINE float
+fixed_to_float(int a)
+{
+   return a * (1.0 / FIXED_ONE);
+}
+
+
 
 /**
  * Compute a0 for a constant-valued coefficient (GL_FLAT shading).
  */
-static void constant_coef( struct lp_setup_context *setup,
-                           struct lp_rast_triangle *tri,
+static void constant_coef( struct lp_rast_triangle *tri,
                            unsigned slot,
                           const float value,
                            unsigned i )
@@ -54,28 +120,21 @@ static void constant_coef( struct lp_setup_context *setup,
 }
 
 
-/**
- * Compute a0, dadx and dady for a linearly interpolated coefficient,
- * for a triangle.
- */
-static void linear_coef( struct lp_setup_context *setup,
-                         struct lp_rast_triangle *tri,
-                         float oneoverarea,
+
+static void linear_coef( struct lp_rast_triangle *tri,
+                         const struct tri_info *info,
                          unsigned slot,
-                         const float (*v1)[4],
-                         const float (*v2)[4],
-                         const float (*v3)[4],
                          unsigned vert_attr,
                          unsigned i)
 {
-   float a1 = v1[vert_attr][i];
-   float a2 = v2[vert_attr][i];
-   float a3 = v3[vert_attr][i];
+   float a0 = info->v0[vert_attr][i];
+   float a1 = info->v1[vert_attr][i];
+   float a2 = info->v2[vert_attr][i];
 
-   float da12 = a1 - a2;
-   float da31 = a3 - a1;
-   float dadx = (da12 * tri->dy31 - tri->dy12 * da31) * oneoverarea;
-   float dady = (da31 * tri->dx12 - tri->dx31 * da12) * oneoverarea;
+   float da01 = a0 - a1;
+   float da20 = a2 - a0;
+   float dadx = (da01 * info->dy20 - info->dy01 * da20) * info->oneoverarea;
+   float dady = (da20 * info->dx01 - info->dx20 * da01) * info->oneoverarea;
 
    tri->inputs.dadx[slot][i] = dadx;
    tri->inputs.dady[slot][i] = dady;
@@ -92,9 +151,9 @@ static void linear_coef( struct lp_setup_context *setup,
     * to define a0 as the sample at a pixel center somewhere near vmin
     * instead - i'll switch to this later.
     */
-   tri->inputs.a0[slot][i] = (a1 -
-                              (dadx * (v1[0][0] - setup->pixel_offset) +
-                               dady * (v1[0][1] - setup->pixel_offset)));
+   tri->inputs.a0[slot][i] = (a0 -
+                              (dadx * (info->v0[0][0] - info->pixel_offset) +
+                               dady * (info->v0[0][1] - info->pixel_offset)));
 }
 
 
@@ -106,31 +165,27 @@ static void linear_coef( struct lp_setup_context *setup,
  * Later, when we compute the value at a particular fragment position we'll
  * divide the interpolated value by the interpolated W at that fragment.
  */
-static void perspective_coef( struct lp_setup_context *setup,
-                              struct lp_rast_triangle *tri,
-                              float oneoverarea,
+static void perspective_coef( struct lp_rast_triangle *tri,
+                              const struct tri_info *info,
                               unsigned slot,
-                             const float (*v1)[4],
-                             const float (*v2)[4],
-                             const float (*v3)[4],
                              unsigned vert_attr,
                               unsigned i)
 {
    /* premultiply by 1/w  (v[0][3] is always 1/w):
     */
-   float a1 = v1[vert_attr][i] * v1[0][3];
-   float a2 = v2[vert_attr][i] * v2[0][3];
-   float a3 = v3[vert_attr][i] * v3[0][3];
-   float da12 = a1 - a2;
-   float da31 = a3 - a1;
-   float dadx = (da12 * tri->dy31 - tri->dy12 * da31) * oneoverarea;
-   float dady = (da31 * tri->dx12 - tri->dx31 * da12) * oneoverarea;
+   float a0 = info->v0[vert_attr][i] * info->v0[0][3];
+   float a1 = info->v1[vert_attr][i] * info->v1[0][3];
+   float a2 = info->v2[vert_attr][i] * info->v2[0][3];
+   float da01 = a0 - a1;
+   float da20 = a2 - a0;
+   float dadx = (da01 * info->dy20 - info->dy01 * da20) * info->oneoverarea;
+   float dady = (da20 * info->dx01 - info->dx20 * da01) * info->oneoverarea;
 
    tri->inputs.dadx[slot][i] = dadx;
    tri->inputs.dady[slot][i] = dady;
-   tri->inputs.a0[slot][i] = (a1 -
-                              (dadx * (v1[0][0] - setup->pixel_offset) +
-                               dady * (v1[0][1] - setup->pixel_offset)));
+   tri->inputs.a0[slot][i] = (a0 -
+                              (dadx * (info->v0[0][0] - info->pixel_offset) +
+                               dady * (info->v0[0][1] - info->pixel_offset)));
 }
 
 
@@ -141,13 +196,9 @@ static void perspective_coef( struct lp_setup_context *setup,
  * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask.
  */
 static void
-setup_fragcoord_coef(struct lp_setup_context *setup,
-                     struct lp_rast_triangle *tri,
-                     float oneoverarea,
+setup_fragcoord_coef(struct lp_rast_triangle *tri,
+                     const struct tri_info *info,
                      unsigned slot,
-                     const float (*v1)[4],
-                     const float (*v2)[4],
-                     const float (*v3)[4],
                      unsigned usage_mask)
 {
    /*X*/
@@ -166,12 +217,12 @@ setup_fragcoord_coef(struct lp_setup_context *setup,
 
    /*Z*/
    if (usage_mask & TGSI_WRITEMASK_Z) {
-      linear_coef(setup, tri, oneoverarea, slot, v1, v2, v3, 0, 2);
+      linear_coef(tri, info, slot, 0, 2);
    }
 
    /*W*/
    if (usage_mask & TGSI_WRITEMASK_W) {
-      linear_coef(setup, tri, oneoverarea, slot, v1, v2, v3, 0, 3);
+      linear_coef(tri, info, slot, 0, 3);
    }
 }
 
@@ -180,24 +231,23 @@ setup_fragcoord_coef(struct lp_setup_context *setup,
  * Setup the fragment input attribute with the front-facing value.
  * \param frontface  is the triangle front facing?
  */
-static void setup_facing_coef( struct lp_setup_context *setup,
-                               struct lp_rast_triangle *tri,
+static void setup_facing_coef( struct lp_rast_triangle *tri,
                                unsigned slot,
                                boolean frontface,
                                unsigned usage_mask)
 {
    /* convert TRUE to 1.0 and FALSE to -1.0 */
    if (usage_mask & TGSI_WRITEMASK_X)
-      constant_coef( setup, tri, slot, 2.0f * frontface - 1.0f, 0 );
+      constant_coef( tri, slot, 2.0f * frontface - 1.0f, 0 );
 
    if (usage_mask & TGSI_WRITEMASK_Y)
-      constant_coef( setup, tri, slot, 0.0f, 1 ); /* wasted */
+      constant_coef( tri, slot, 0.0f, 1 ); /* wasted */
 
    if (usage_mask & TGSI_WRITEMASK_Z)
-      constant_coef( setup, tri, slot, 0.0f, 2 ); /* wasted */
+      constant_coef( tri, slot, 0.0f, 2 ); /* wasted */
 
    if (usage_mask & TGSI_WRITEMASK_W)
-      constant_coef( setup, tri, slot, 0.0f, 3 ); /* wasted */
+      constant_coef( tri, slot, 0.0f, 3 ); /* wasted */
 }
 
 
@@ -206,11 +256,7 @@ static void setup_facing_coef( struct lp_setup_context *setup,
  */
 static void setup_tri_coefficients( struct lp_setup_context *setup,
                                    struct lp_rast_triangle *tri,
-                                    float oneoverarea,
-                                   const float (*v1)[4],
-                                   const float (*v2)[4],
-                                   const float (*v3)[4],
-                                   boolean frontface)
+                                    const struct tri_info *info)
 {
    unsigned fragcoord_usage_mask = TGSI_WRITEMASK_XYZ;
    unsigned slot;
@@ -227,25 +273,25 @@ static void setup_tri_coefficients( struct lp_setup_context *setup,
          if (setup->flatshade_first) {
             for (i = 0; i < NUM_CHANNELS; i++)
                if (usage_mask & (1 << i))
-                  constant_coef(setup, tri, slot+1, v1[vert_attr][i], i);
+                  constant_coef(tri, slot+1, info->v0[vert_attr][i], i);
          }
          else {
             for (i = 0; i < NUM_CHANNELS; i++)
                if (usage_mask & (1 << i))
-                  constant_coef(setup, tri, slot+1, v3[vert_attr][i], i);
+                  constant_coef(tri, slot+1, info->v2[vert_attr][i], i);
          }
          break;
 
       case LP_INTERP_LINEAR:
          for (i = 0; i < NUM_CHANNELS; i++)
             if (usage_mask & (1 << i))
-               linear_coef(setup, tri, oneoverarea, slot+1, v1, v2, v3, vert_attr, i);
+               linear_coef(tri, info, slot+1, vert_attr, i);
          break;
 
       case LP_INTERP_PERSPECTIVE:
          for (i = 0; i < NUM_CHANNELS; i++)
             if (usage_mask & (1 << i))
-               perspective_coef(setup, tri, oneoverarea, slot+1, v1, v2, v3, vert_attr, i);
+               perspective_coef(tri, info, slot+1, vert_attr, i);
          fragcoord_usage_mask |= TGSI_WRITEMASK_W;
          break;
 
@@ -259,7 +305,7 @@ static void setup_tri_coefficients( struct lp_setup_context *setup,
          break;
 
       case LP_INTERP_FACING:
-         setup_facing_coef(setup, tri, slot+1, frontface, usage_mask);
+         setup_facing_coef(tri, slot+1, info->frontfacing, usage_mask);
          break;
 
       default:
@@ -269,16 +315,11 @@ static void setup_tri_coefficients( struct lp_setup_context *setup,
 
    /* The internal position input is in slot zero:
     */
-   setup_fragcoord_coef(setup, tri, oneoverarea, 0, v1, v2, v3,
-                        fragcoord_usage_mask);
+   setup_fragcoord_coef(tri, info, 0, fragcoord_usage_mask);
 }
 
 
 
-static INLINE int subpixel_snap( float a )
-{
-   return util_iround(FIXED_ONE * a - (FIXED_ONE / 2));
-}
 
 
 
@@ -291,21 +332,23 @@ static INLINE int subpixel_snap( float a )
  * \return pointer to triangle space
  */
 static INLINE struct lp_rast_triangle *
-alloc_triangle(struct lp_scene *scene, unsigned nr_inputs, unsigned *tri_size)
+alloc_triangle(struct lp_scene *scene,
+               unsigned nr_inputs,
+               unsigned nr_planes,
+               unsigned *tri_size)
 {
    unsigned input_array_sz = NUM_CHANNELS * (nr_inputs + 1) * sizeof(float);
    struct lp_rast_triangle *tri;
-   unsigned bytes;
+   unsigned tri_bytes, bytes;
    char *inputs;
 
-   assert(sizeof(*tri) % 16 == 0);
-
-   bytes = sizeof(*tri) + (3 * input_array_sz);
+   tri_bytes = align(Offset(struct lp_rast_triangle, plane[nr_planes]), 16);
+   bytes = tri_bytes + (3 * input_array_sz);
 
    tri = lp_scene_alloc_aligned( scene, bytes, 16 );
 
    if (tri) {
-      inputs = (char *) (tri + 1);
+      inputs = ((char *)tri) + tri_bytes;
       tri->inputs.a0   = (float (*)[4]) inputs;
       tri->inputs.dadx = (float (*)[4]) (inputs + input_array_sz);
       tri->inputs.dady = (float (*)[4]) (inputs + 2 * input_array_sz);
@@ -329,52 +372,71 @@ print_triangle(struct lp_setup_context *setup,
    uint i;
 
    debug_printf("llvmpipe triangle\n");
-   for (i = 0; i < setup->fs.nr_inputs; i++) {
+   for (i = 0; i < 1 + setup->fs.nr_inputs; i++) {
       debug_printf("  v1[%d]:  %f %f %f %f\n", i,
                    v1[i][0], v1[i][1], v1[i][2], v1[i][3]);
    }
-   for (i = 0; i < setup->fs.nr_inputs; i++) {
+   for (i = 0; i < 1 + setup->fs.nr_inputs; i++) {
       debug_printf("  v2[%d]:  %f %f %f %f\n", i,
                    v2[i][0], v2[i][1], v2[i][2], v2[i][3]);
    }
-   for (i = 0; i < setup->fs.nr_inputs; i++) {
+   for (i = 0; i < 1 + setup->fs.nr_inputs; i++) {
       debug_printf("  v3[%d]:  %f %f %f %f\n", i,
                    v3[i][0], v3[i][1], v3[i][2], v3[i][3]);
    }
 }
 
 
+lp_rast_cmd lp_rast_tri_tab[8] = {
+   NULL,               /* should be impossible */
+   lp_rast_triangle_1,
+   lp_rast_triangle_2,
+   lp_rast_triangle_3,
+   lp_rast_triangle_4,
+   lp_rast_triangle_5,
+   lp_rast_triangle_6,
+   lp_rast_triangle_7
+};
+
 /**
  * Do basic setup for triangle rasterization and determine which
  * framebuffer tiles are touched.  Put the triangle in the scene's
  * bins for the tiles which we overlap.
  */
-static void 
+static void
 do_triangle_ccw(struct lp_setup_context *setup,
                const float (*v1)[4],
                const float (*v2)[4],
                const float (*v3)[4],
                boolean frontfacing )
 {
-   /* x/y positions in fixed point */
-   const int x1 = subpixel_snap(v1[0][0] + 0.5 - setup->pixel_offset);
-   const int x2 = subpixel_snap(v2[0][0] + 0.5 - setup->pixel_offset);
-   const int x3 = subpixel_snap(v3[0][0] + 0.5 - setup->pixel_offset);
-   const int y1 = subpixel_snap(v1[0][1] + 0.5 - setup->pixel_offset);
-   const int y2 = subpixel_snap(v2[0][1] + 0.5 - setup->pixel_offset);
-   const int y3 = subpixel_snap(v3[0][1] + 0.5 - setup->pixel_offset);
 
    struct lp_scene *scene = lp_setup_get_current_scene(setup);
+   struct lp_fragment_shader_variant *variant = setup->fs.current.variant;
    struct lp_rast_triangle *tri;
+   struct tri_info info;
    int area;
-   float oneoverarea;
    int minx, maxx, miny, maxy;
+   int ix0, ix1, iy0, iy1;
    unsigned tri_bytes;
-
+   int i;
+   int nr_planes = 3;
+      
    if (0)
       print_triangle(setup, v1, v2, v3);
 
-   tri = alloc_triangle(scene, setup->fs.nr_inputs, &tri_bytes);
+   if (setup->scissor_test) {
+      nr_planes = 7;
+   }
+   else {
+      nr_planes = 3;
+   }
+
+
+   tri = alloc_triangle(scene,
+                        setup->fs.nr_inputs,
+                        nr_planes,
+                        &tri_bytes);
    if (!tri)
       return;
 
@@ -387,15 +449,24 @@ do_triangle_ccw(struct lp_setup_context *setup,
    tri->v[2][1] = v3[0][1];
 #endif
 
-   tri->dx12 = x1 - x2;
-   tri->dx23 = x2 - x3;
-   tri->dx31 = x3 - x1;
+   /* x/y positions in fixed point */
+   info.x[0] = subpixel_snap(v1[0][0] - setup->pixel_offset);
+   info.x[1] = subpixel_snap(v2[0][0] - setup->pixel_offset);
+   info.x[2] = subpixel_snap(v3[0][0] - setup->pixel_offset);
+   info.y[0] = subpixel_snap(v1[0][1] - setup->pixel_offset);
+   info.y[1] = subpixel_snap(v2[0][1] - setup->pixel_offset);
+   info.y[2] = subpixel_snap(v3[0][1] - setup->pixel_offset);
+
+   tri->plane[0].dcdy = info.x[0] - info.x[1];
+   tri->plane[1].dcdy = info.x[1] - info.x[2];
+   tri->plane[2].dcdy = info.x[2] - info.x[0];
 
-   tri->dy12 = y1 - y2;
-   tri->dy23 = y2 - y3;
-   tri->dy31 = y3 - y1;
+   tri->plane[0].dcdx = info.y[0] - info.y[1];
+   tri->plane[1].dcdx = info.y[1] - info.y[2];
+   tri->plane[2].dcdx = info.y[2] - info.y[0];
 
-   area = (tri->dx12 * tri->dy31 - tri->dx31 * tri->dy12);
+   area = (tri->plane[0].dcdy * tri->plane[2].dcdx -
+           tri->plane[2].dcdy * tri->plane[0].dcdx);
 
    LP_COUNT(nr_tris);
 
@@ -410,20 +481,35 @@ do_triangle_ccw(struct lp_setup_context *setup,
    }
 
    /* Bounding rectangle (in pixels) */
-   minx = (MIN3(x1, x2, x3) + (FIXED_ONE-1)) >> FIXED_ORDER;
-   maxx = (MAX3(x1, x2, x3) + (FIXED_ONE-1)) >> FIXED_ORDER;
-   miny = (MIN3(y1, y2, y3) + (FIXED_ONE-1)) >> FIXED_ORDER;
-   maxy = (MAX3(y1, y2, y3) + (FIXED_ONE-1)) >> FIXED_ORDER;
-   
+   {
+      /* Yes this is necessary to accurately calculate bounding boxes
+       * with the two fill-conventions we support.  GL (normally) ends
+       * up needing a bottom-left fill convention, which requires
+       * slightly different rounding.
+       */
+      int adj = (setup->pixel_offset != 0) ? 1 : 0;
+
+      minx = (MIN3(info.x[0], info.x[1], info.x[2]) + (FIXED_ONE-1)) >> FIXED_ORDER;
+      maxx = (MAX3(info.x[0], info.x[1], info.x[2]) + (FIXED_ONE-1)) >> FIXED_ORDER;
+      miny = (MIN3(info.y[0], info.y[1], info.y[2]) + (FIXED_ONE-1) + adj) >> FIXED_ORDER;
+      maxy = (MAX3(info.y[0], info.y[1], info.y[2]) + (FIXED_ONE-1) + adj) >> FIXED_ORDER;
+   }
+
    if (setup->scissor_test) {
       minx = MAX2(minx, setup->scissor.current.minx);
       maxx = MIN2(maxx, setup->scissor.current.maxx);
       miny = MAX2(miny, setup->scissor.current.miny);
       maxy = MIN2(maxy, setup->scissor.current.maxy);
    }
+   else {
+      minx = MAX2(minx, 0);
+      miny = MAX2(miny, 0);
+      maxx = MIN2(maxx, scene->fb.width);
+      maxy = MIN2(maxy, scene->fb.height);
+   }
+
 
-   if (miny == maxy || 
-       minx == maxx) {
+   if (miny >= maxy || minx >= maxx) {
       lp_scene_putback_data( scene, tri_bytes );
       LP_COUNT(nr_culled_tris);
       return;
@@ -431,75 +517,88 @@ do_triangle_ccw(struct lp_setup_context *setup,
 
    /* 
     */
-   oneoverarea = ((float)FIXED_ONE) / (float)area;
+   info.pixel_offset = setup->pixel_offset;
+   info.v0 = v1;
+   info.v1 = v2;
+   info.v2 = v3;
+   info.dx01 = info.v0[0][0] - info.v1[0][0];
+   info.dx20 = info.v2[0][0] - info.v0[0][0];
+   info.dy01 = info.v0[0][1] - info.v1[0][1];
+   info.dy20 = info.v2[0][1] - info.v0[0][1];
+   info.oneoverarea = 1.0 / (info.dx01 * info.dy20 - info.dx20 * info.dy01);
+   info.frontfacing = frontfacing;
 
    /* Setup parameter interpolants:
     */
-   setup_tri_coefficients( setup, tri, oneoverarea, v1, v2, v3, frontfacing );
+   setup_tri_coefficients( setup, tri, &info );
 
    tri->inputs.facing = frontfacing ? 1.0F : -1.0F;
+   tri->inputs.state = setup->fs.stored;
 
-   /* half-edge constants, will be interated over the whole render target.
-    */
-   tri->c1 = tri->dy12 * x1 - tri->dx12 * y1;
-   tri->c2 = tri->dy23 * x2 - tri->dx23 * y2;
-   tri->c3 = tri->dy31 * x3 - tri->dx31 * y3;
 
-   /* correct for top-left fill convention:
-    */
-   if (tri->dy12 < 0 || (tri->dy12 == 0 && tri->dx12 > 0)) tri->c1++;
-   if (tri->dy23 < 0 || (tri->dy23 == 0 && tri->dx23 > 0)) tri->c2++;
-   if (tri->dy31 < 0 || (tri->dy31 == 0 && tri->dx31 > 0)) tri->c3++;
-
-   tri->dy12 *= FIXED_ONE;
-   tri->dy23 *= FIXED_ONE;
-   tri->dy31 *= FIXED_ONE;
-
-   tri->dx12 *= FIXED_ONE;
-   tri->dx23 *= FIXED_ONE;
-   tri->dx31 *= FIXED_ONE;
-
-   /* find trivial reject offsets for each edge for a single-pixel
-    * sized block.  These will be scaled up at each recursive level to
-    * match the active blocksize.  Scaling in this way works best if
-    * the blocks are square.
-    */
-   tri->eo1 = 0;
-   if (tri->dy12 < 0) tri->eo1 -= tri->dy12;
-   if (tri->dx12 > 0) tri->eo1 += tri->dx12;
+  
+   for (i = 0; i < 3; i++) {
+      struct lp_rast_plane *plane = &tri->plane[i];
 
-   tri->eo2 = 0;
-   if (tri->dy23 < 0) tri->eo2 -= tri->dy23;
-   if (tri->dx23 > 0) tri->eo2 += tri->dx23;
+      /* half-edge constants, will be interated over the whole render
+       * target.
+       */
+      plane->c = plane->dcdx * info.x[i] - plane->dcdy * info.y[i];
+
+      /* correct for top-left vs. bottom-left fill convention.  
+       *
+       * note that we're overloading gl_rasterization_rules to mean
+       * both (0.5,0.5) pixel centers *and* bottom-left filling
+       * convention.
+       *
+       * GL actually has a top-left filling convention, but GL's
+       * notion of "top" differs from gallium's...
+       *
+       * Also, sometimes (in FBO cases) GL will render upside down
+       * to its usual method, in which case it will probably want
+       * to use the opposite, top-left convention.
+       */         
+      if (plane->dcdx < 0) {
+         /* both fill conventions want this - adjust for left edges */
+         plane->c++;            
+      }
+      else if (plane->dcdx == 0) {
+         if (setup->pixel_offset == 0) {
+            /* correct for top-left fill convention:
+             */
+            if (plane->dcdy > 0) plane->c++;
+         }
+         else {
+            /* correct for bottom-left fill convention:
+             */
+            if (plane->dcdy < 0) plane->c++;
+         }
+      }
 
-   tri->eo3 = 0;
-   if (tri->dy31 < 0) tri->eo3 -= tri->dy31;
-   if (tri->dx31 > 0) tri->eo3 += tri->dx31;
+      plane->dcdx *= FIXED_ONE;
+      plane->dcdy *= FIXED_ONE;
 
-   /* Calculate trivial accept offsets from the above.
-    */
-   tri->ei1 = tri->dx12 - tri->dy12 - tri->eo1;
-   tri->ei2 = tri->dx23 - tri->dy23 - tri->eo2;
-   tri->ei3 = tri->dx31 - tri->dy31 - tri->eo3;
+      /* find trivial reject offsets for each edge for a single-pixel
+       * sized block.  These will be scaled up at each recursive level to
+       * match the active blocksize.  Scaling in this way works best if
+       * the blocks are square.
+       */
+      plane->eo = 0;
+      if (plane->dcdx < 0) plane->eo -= plane->dcdx;
+      if (plane->dcdy > 0) plane->eo += plane->dcdy;
 
-   /* Fill in the inputs.step[][] arrays.
-    * We've manually unrolled some loops here.
-    */
-   {
-      const int xstep1 = -tri->dy12;
-      const int xstep2 = -tri->dy23;
-      const int xstep3 = -tri->dy31;
-      const int ystep1 = tri->dx12;
-      const int ystep2 = tri->dx23;
-      const int ystep3 = tri->dx31;
-
-#define SETUP_STEP(i, x, y)                                \
-      do {                                                 \
-         tri->inputs.step[0][i] = x * xstep1 + y * ystep1; \
-         tri->inputs.step[1][i] = x * xstep2 + y * ystep2; \
-         tri->inputs.step[2][i] = x * xstep3 + y * ystep3; \
-      } while (0)
+      /* Calculate trivial accept offsets from the above.
+       */
+      plane->ei = plane->dcdy - plane->dcdx - plane->eo;
 
+      plane->step = tri->step[i];
+
+      /* Fill in the inputs.step[][] arrays.
+       * We've manually unrolled some loops here.
+       */
+#define SETUP_STEP(j, x, y) \
+      tri->step[i][j] = y * plane->dcdy - x * plane->dcdx
+      
       SETUP_STEP(0, 0, 0);
       SETUP_STEP(1, 1, 0);
       SETUP_STEP(2, 0, 1);
@@ -522,63 +621,106 @@ do_triangle_ccw(struct lp_setup_context *setup,
 #undef STEP
    }
 
+
+   /* 
+    * When rasterizing scissored tris, use the intersection of the
+    * triangle bounding box and the scissor rect to generate the
+    * scissor planes.
+    *
+    * This permits us to cut off the triangle "tails" that are present
+    * in the intermediate recursive levels caused when two of the
+    * triangles edges don't diverge quickly enough to trivially reject
+    * exterior blocks from the triangle.
+    *
+    * It's not really clear if it's worth worrying about these tails,
+    * but since we generate the planes for each scissored tri, it's
+    * free to trim them in this case.
+    * 
+    * Note that otherwise, the scissor planes only vary in 'C' value,
+    * and even then only on state-changes.  Could alternatively store
+    * these planes elsewhere.
+    */
+   if (nr_planes == 7) {
+      tri->plane[3].step = step_scissor_minx;
+      tri->plane[3].dcdx = -1;
+      tri->plane[3].dcdy = 0;
+      tri->plane[3].c = 1-minx;
+      tri->plane[3].ei = 0;
+      tri->plane[3].eo = 1;
+
+      tri->plane[4].step = step_scissor_maxx;
+      tri->plane[4].dcdx = 1;
+      tri->plane[4].dcdy = 0;
+      tri->plane[4].c = maxx;
+      tri->plane[4].ei = -1;
+      tri->plane[4].eo = 0;
+
+      tri->plane[5].step = step_scissor_miny;
+      tri->plane[5].dcdx = 0;
+      tri->plane[5].dcdy = 1;
+      tri->plane[5].c = 1-miny;
+      tri->plane[5].ei = 0;
+      tri->plane[5].eo = 1;
+
+      tri->plane[6].step = step_scissor_maxy;
+      tri->plane[6].dcdx = 0;
+      tri->plane[6].dcdy = -1;
+      tri->plane[6].c = maxy;
+      tri->plane[6].ei = -1;
+      tri->plane[6].eo = 0;
+   }
+
+
    /*
     * All fields of 'tri' are now set.  The remaining code here is
     * concerned with binning.
     */
 
-   /* Convert to tile coordinates:
+   /* Convert to tile coordinates, and inclusive ranges:
     */
-   minx = minx / TILE_SIZE;
-   miny = miny / TILE_SIZE;
-   maxx = maxx / TILE_SIZE;
-   maxy = maxy / TILE_SIZE;
+   ix0 = minx / TILE_SIZE;
+   iy0 = miny / TILE_SIZE;
+   ix1 = (maxx-1) / TILE_SIZE;
+   iy1 = (maxy-1) / TILE_SIZE;
 
    /*
     * Clamp to framebuffer size
     */
-   minx = MAX2(minx, 0);
-   miny = MAX2(miny, 0);
-   maxx = MIN2(maxx, scene->tiles_x - 1);
-   maxy = MIN2(maxy, scene->tiles_y - 1);
+   assert(ix0 == MAX2(ix0, 0));
+   assert(iy0 == MAX2(iy0, 0));
+   assert(ix1 == MIN2(ix1, scene->tiles_x - 1));
+   assert(iy1 == MIN2(iy1, scene->tiles_y - 1));
 
    /* Determine which tile(s) intersect the triangle's bounding box
     */
-   if (miny == maxy && minx == maxx)
+   if (iy0 == iy1 && ix0 == ix1)
    {
       /* Triangle is contained in a single tile:
        */
-      lp_scene_bin_command( scene, minx, miny, lp_rast_triangle, 
-                           lp_rast_arg_triangle(tri) );
+      lp_scene_bin_command( scene, ix0, iy0,
+                            lp_rast_tri_tab[nr_planes], 
+                           lp_rast_arg_triangle(tri, (1<<nr_planes)-1) );
    }
-   else 
+   else
    {
-      int c1 = (tri->c1 + 
-                tri->dx12 * miny * TILE_SIZE - 
-                tri->dy12 * minx * TILE_SIZE);
-      int c2 = (tri->c2 + 
-                tri->dx23 * miny * TILE_SIZE -
-                tri->dy23 * minx * TILE_SIZE);
-      int c3 = (tri->c3 +
-                tri->dx31 * miny * TILE_SIZE -
-                tri->dy31 * minx * TILE_SIZE);
-
-      int ei1 = tri->ei1 << TILE_ORDER;
-      int ei2 = tri->ei2 << TILE_ORDER;
-      int ei3 = tri->ei3 << TILE_ORDER;
-
-      int eo1 = tri->eo1 << TILE_ORDER;
-      int eo2 = tri->eo2 << TILE_ORDER;
-      int eo3 = tri->eo3 << TILE_ORDER;
-
-      int xstep1 = -(tri->dy12 << TILE_ORDER);
-      int xstep2 = -(tri->dy23 << TILE_ORDER);
-      int xstep3 = -(tri->dy31 << TILE_ORDER);
-
-      int ystep1 = tri->dx12 << TILE_ORDER;
-      int ystep2 = tri->dx23 << TILE_ORDER;
-      int ystep3 = tri->dx31 << TILE_ORDER;
+      int c[7];
+      int ei[7];
+      int eo[7];
+      int xstep[7];
+      int ystep[7];
       int x, y;
+      
+      for (i = 0; i < nr_planes; i++) {
+         c[i] = (tri->plane[i].c + 
+                 tri->plane[i].dcdy * iy0 * TILE_SIZE - 
+                 tri->plane[i].dcdx * ix0 * TILE_SIZE);
+
+         ei[i] = tri->plane[i].ei << TILE_ORDER;
+         eo[i] = tri->plane[i].eo << TILE_ORDER;
+         xstep[i] = -(tri->plane[i].dcdx << TILE_ORDER);
+         ystep[i] = tri->plane[i].dcdy << TILE_ORDER;
+      }
+
 
 
       /* Test tile-sized blocks against the triangle.
@@ -586,63 +728,67 @@ do_triangle_ccw(struct lp_setup_context *setup,
        * contained inside the tri, bin an lp_rast_shade_tile command.
        * Else, bin a lp_rast_triangle command.
        */
-      for (y = miny; y <= maxy; y++)
+      for (y = iy0; y <= iy1; y++)
       {
-        int cx1 = c1;
-        int cx2 = c2;
-        int cx3 = c3;
         boolean in = FALSE;  /* are we inside the triangle? */
+        int cx[7];
+
+         for (i = 0; i < nr_planes; i++)
+            cx[i] = c[i];
 
-        for (x = minx; x <= maxx; x++)
+        for (x = ix0; x <= ix1; x++)
         {
-           if (cx1 + eo1 < 0 || 
-               cx2 + eo2 < 0 ||
-               cx3 + eo3 < 0) 
-           {
-              /* do nothing */
+            int out = 0;
+            int partial = 0;
+
+            for (i = 0; i < nr_planes; i++) {
+               int planeout = cx[i] + eo[i];
+               int planepartial = cx[i] + ei[i] - 1;
+               out |= (planeout >> 31);
+               partial |= (planepartial >> 31) & (1<<i);
+            }
+
+            if (out) {
+               /* do nothing */
+               if (in)
+                  break;  /* exiting triangle, all done with this row */
                LP_COUNT(nr_empty_64);
-              if (in)
-                 break;  /* exiting triangle, all done with this row */
-           }
-           else if (cx1 + ei1 > 0 &&
-                    cx2 + ei2 > 0 &&
-                    cx3 + ei3 > 0) 
-           {
+            }
+            else if (partial) {
+               /* Not trivially accepted by at least one plane - 
+                * rasterize/shade partial tile
+                */
+               int count = util_bitcount(partial);
+               in = TRUE;
+               lp_scene_bin_command( scene, x, y,
+                                     lp_rast_tri_tab[count], 
+                                     lp_rast_arg_triangle(tri, partial) );
+
+               LP_COUNT(nr_partially_covered_64);
+            }
+            else {
                /* triangle covers the whole tile- shade whole tile */
                LP_COUNT(nr_fully_covered_64);
-              in = TRUE;
-              if (setup->fs.current.variant->opaque) {
+               in = TRUE;
+              if (variant->opaque &&
+                  !setup->fb.zsbuf) {
                  lp_scene_bin_reset( scene, x, y );
-                 lp_scene_bin_command( scene, x, y,
-                                       lp_rast_set_state,
-                                       lp_rast_arg_state(setup->fs.stored) );
               }
                lp_scene_bin_command( scene, x, y,
                                     lp_rast_shade_tile,
                                     lp_rast_arg_inputs(&tri->inputs) );
-           }
-           else 
-           { 
-               /* rasterizer/shade partial tile */
-               LP_COUNT(nr_partially_covered_64);
-              in = TRUE;
-               lp_scene_bin_command( scene, x, y,
-                                    lp_rast_triangle, 
-                                    lp_rast_arg_triangle(tri) );
-           }
+            }
 
            /* Iterate cx values across the region:
             */
-           cx1 += xstep1;
-           cx2 += xstep2;
-           cx3 += xstep3;
+            for (i = 0; i < nr_planes; i++)
+               cx[i] += xstep[i];
         }
       
         /* Iterate c values down the region:
          */
-        c1 += ystep1;
-        c2 += ystep2;
-        c3 += ystep3;    
+         for (i = 0; i < nr_planes; i++)
+            c[i] += ystep[i];
       }
    }
 }
index f6a424f25a833575480baac47fcecef618fe8d77..51948f5bf295482ac83a441f2e3e695bc6226cb4 100644 (file)
@@ -61,7 +61,9 @@ lp_setup_get_vertex_info(struct vbuf_render *vbr)
 {
    struct lp_setup_context *setup = lp_setup_context(vbr);
 
-   /* vertex size/info depends on the latest state */
+   /* Vertex size/info depends on the latest state.
+    * The draw module may have issued additional state-change commands.
+    */
    lp_setup_update_state(setup);
 
    return setup->vertex_info;
index 05d1b9379449cae2211425e079283835d9db9b7e..86313e1c48469e5efbf7aed40ca238afe5553970 100644 (file)
@@ -130,6 +130,12 @@ llvmpipe_init_rasterizer_funcs(struct llvmpipe_context *llvmpipe);
 void
 llvmpipe_init_so_funcs(struct llvmpipe_context *llvmpipe);
 
+void
+llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *ctx,
+                                 unsigned num,
+                                 struct pipe_sampler_view **views);
+void
+llvmpipe_cleanup_vertex_sampling(struct llvmpipe_context *ctx);
 
 
 #endif
index d20a5218d41f70157db6a04b2ede8331c07993e6..77bec4640bb5517b4e83465df84119e0daf633b3 100644 (file)
@@ -189,7 +189,7 @@ void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
                                 llvmpipe->constants[PIPE_SHADER_FRAGMENT][0]);
 
    if (llvmpipe->dirty & LP_NEW_SAMPLER_VIEW)
-      lp_setup_set_fragment_sampler_views(llvmpipe->setup, 
+      lp_setup_set_fragment_sampler_views(llvmpipe->setup,
                                           llvmpipe->num_fragment_sampler_views,
                                           llvmpipe->fragment_sampler_views);
 
index 65115052cdd50a2adc1489ae6433cd09880ef287..5953d690a41c7f3951a42814952b58bb93821d16 100644 (file)
@@ -31,9 +31,6 @@
  * Code generate the whole fragment pipeline.
  *
  * The fragment pipeline consists of the following stages:
- * - triangle edge in/out testing
- * - scissor test
- * - stipple (TBI)
  * - early depth test
  * - fragment shader
  * - alpha test
@@ -97,6 +94,7 @@
 #include "lp_state.h"
 #include "lp_tex_sample.h"
 #include "lp_flush.h"
+#include "lp_state_fs.h"
 
 
 #include <llvm-c/Analysis.h>
@@ -170,177 +168,63 @@ generate_depth_stencil(LLVMBuilderRef builder,
 
 
 /**
- * Generate the code to do inside/outside triangle testing for the
+ * Expand the relevent bits of mask_input to a 4-dword mask for the 
  * four pixels in a 2x2 quad.  This will set the four elements of the
  * quad mask vector to 0 or ~0.
- * \param i  which quad of the quad group to test, in [0,3]
+ *
+ * \param quad  which quad of the quad group to test, in [0,3]
+ * \param mask_input  bitwise mask for the whole 4x4 stamp
  */
-static void
-generate_tri_edge_mask(LLVMBuilderRef builder,
-                       unsigned i,
-                       LLVMValueRef *mask,      /* ivec4, out */
-                       LLVMValueRef c0,         /* int32 */
-                       LLVMValueRef c1,         /* int32 */
-                       LLVMValueRef c2,         /* int32 */
-                       LLVMValueRef step0_ptr,  /* ivec4 */
-                       LLVMValueRef step1_ptr,  /* ivec4 */
-                       LLVMValueRef step2_ptr)  /* ivec4 */
+static LLVMValueRef
+generate_quad_mask(LLVMBuilderRef builder,
+                   struct lp_type fs_type,
+                   unsigned quad,
+                   LLVMValueRef mask_input) /* int32 */
 {
-#define OPTIMIZE_IN_OUT_TEST 0
-#if OPTIMIZE_IN_OUT_TEST
-   struct lp_build_if_state ifctx;
-   LLVMValueRef not_draw_all;
-#endif
-   struct lp_build_flow_context *flow;
-   struct lp_type i32_type;
-   LLVMTypeRef i32vec4_type;
-   LLVMValueRef c0_vec, c1_vec, c2_vec;
-   LLVMValueRef in_out_mask;
-
-   assert(i < 4);
-   
-   /* int32 vector type */
-   memset(&i32_type, 0, sizeof i32_type);
-   i32_type.floating = FALSE; /* values are integers */
-   i32_type.sign = TRUE;      /* values are signed */
-   i32_type.norm = FALSE;     /* values are not normalized */
-   i32_type.width = 32;       /* 32-bit int values */
-   i32_type.length = 4;       /* 4 elements per vector */
-
-   i32vec4_type = lp_build_int32_vec4_type();
+   struct lp_type mask_type;
+   LLVMTypeRef i32t = LLVMInt32Type();
+   LLVMValueRef bits[4];
+   LLVMValueRef mask;
 
    /*
-    * Use a conditional here to do detailed pixel in/out testing.
-    * We only have to do this if c0 != INT_MIN.
+    * XXX: We'll need a different path for 16 x u8
     */
-   flow = lp_build_flow_create(builder);
-   lp_build_flow_scope_begin(flow);
-
-   {
-#if OPTIMIZE_IN_OUT_TEST
-      /* not_draw_all = (c0 != INT_MIN) */
-      not_draw_all = LLVMBuildICmp(builder,
-                                   LLVMIntNE,
-                                   c0,
-                                   LLVMConstInt(LLVMInt32Type(), INT_MIN, 0),
-                                   "");
-
-      in_out_mask = lp_build_const_int_vec(i32_type, ~0);
-
-
-      lp_build_flow_scope_declare(flow, &in_out_mask);
-
-      /* if (not_draw_all) {... */
-      lp_build_if(&ifctx, flow, builder, not_draw_all);
-#endif
-      {
-         LLVMValueRef step0_vec, step1_vec, step2_vec;
-         LLVMValueRef m0_vec, m1_vec, m2_vec;
-         LLVMValueRef index, m;
-
-         /* c0_vec = {c0, c0, c0, c0}
-          * Note that we emit this code four times but LLVM optimizes away
-          * three instances of it.
-          */
-         c0_vec = lp_build_broadcast(builder, i32vec4_type, c0);
-         c1_vec = lp_build_broadcast(builder, i32vec4_type, c1);
-         c2_vec = lp_build_broadcast(builder, i32vec4_type, c2);
-         lp_build_name(c0_vec, "edgeconst0vec");
-         lp_build_name(c1_vec, "edgeconst1vec");
-         lp_build_name(c2_vec, "edgeconst2vec");
-
-         /* load step0vec, step1, step2 vec from memory */
-         index = LLVMConstInt(LLVMInt32Type(), i, 0);
-         step0_vec = LLVMBuildLoad(builder, LLVMBuildGEP(builder, step0_ptr, &index, 1, ""), "");
-         step1_vec = LLVMBuildLoad(builder, LLVMBuildGEP(builder, step1_ptr, &index, 1, ""), "");
-         step2_vec = LLVMBuildLoad(builder, LLVMBuildGEP(builder, step2_ptr, &index, 1, ""), "");
-         lp_build_name(step0_vec, "step0vec");
-         lp_build_name(step1_vec, "step1vec");
-         lp_build_name(step2_vec, "step2vec");
-
-         /* m0_vec = step0_ptr[i] > c0_vec */
-         m0_vec = lp_build_compare(builder, i32_type, PIPE_FUNC_GREATER, step0_vec, c0_vec);
-         m1_vec = lp_build_compare(builder, i32_type, PIPE_FUNC_GREATER, step1_vec, c1_vec);
-         m2_vec = lp_build_compare(builder, i32_type, PIPE_FUNC_GREATER, step2_vec, c2_vec);
-
-         /* in_out_mask = m0_vec & m1_vec & m2_vec */
-         m = LLVMBuildAnd(builder, m0_vec, m1_vec, "");
-         in_out_mask = LLVMBuildAnd(builder, m, m2_vec, "");
-         lp_build_name(in_out_mask, "inoutmaskvec");
-      }
-#if OPTIMIZE_IN_OUT_TEST
-      lp_build_endif(&ifctx);
-#endif
-
-   }
-   lp_build_flow_scope_end(flow);
-   lp_build_flow_destroy(flow);
+   assert(fs_type.width == 32);
+   assert(fs_type.length == 4);
+   mask_type = lp_int_type(fs_type);
 
-   /* This is the initial alive/dead pixel mask for a quad of four pixels.
-    * It's an int[4] vector with each word set to 0 or ~0.
-    * Words will get cleared when pixels faile the Z test, etc.
+   /*
+    * mask_input >>= (quad * 4)
     */
-   *mask = in_out_mask;
-}
-
-
-static LLVMValueRef
-generate_scissor_test(LLVMBuilderRef builder,
-                      LLVMValueRef context_ptr,
-                      const struct lp_build_interp_soa_context *interp,
-                      struct lp_type type)
-{
-   LLVMTypeRef vec_type = lp_build_vec_type(type);
-   LLVMValueRef xpos = interp->pos[0], ypos = interp->pos[1];
-   LLVMValueRef xmin, ymin, xmax, ymax;
-   LLVMValueRef m0, m1, m2, m3, m;
-
-   /* xpos, ypos contain the window coords for the four pixels in the quad */
-   assert(xpos);
-   assert(ypos);
-
-   /* get the current scissor bounds, convert to vectors */
-   xmin = lp_jit_context_scissor_xmin_value(builder, context_ptr);
-   xmin = lp_build_broadcast(builder, vec_type, xmin);
-
-   ymin = lp_jit_context_scissor_ymin_value(builder, context_ptr);
-   ymin = lp_build_broadcast(builder, vec_type, ymin);
 
-   xmax = lp_jit_context_scissor_xmax_value(builder, context_ptr);
-   xmax = lp_build_broadcast(builder, vec_type, xmax);
+   mask_input = LLVMBuildLShr(builder,
+                              mask_input,
+                              LLVMConstInt(i32t, quad * 4, 0),
+                              "");
 
-   ymax = lp_jit_context_scissor_ymax_value(builder, context_ptr);
-   ymax = lp_build_broadcast(builder, vec_type, ymax);
+   /*
+    * mask = { mask_input & (1 << i), for i in [0,3] }
+    */
 
-   /* compare the fragment's position coordinates against the scissor bounds */
-   m0 = lp_build_compare(builder, type, PIPE_FUNC_GEQUAL, xpos, xmin);
-   m1 = lp_build_compare(builder, type, PIPE_FUNC_GEQUAL, ypos, ymin);
-   m2 = lp_build_compare(builder, type, PIPE_FUNC_LESS, xpos, xmax);
-   m3 = lp_build_compare(builder, type, PIPE_FUNC_LESS, ypos, ymax);
+   mask = lp_build_broadcast(builder, lp_build_vec_type(mask_type), mask_input);
 
-   /* AND all the masks together */
-   m = LLVMBuildAnd(builder, m0, m1, "");
-   m = LLVMBuildAnd(builder, m, m2, "");
-   m = LLVMBuildAnd(builder, m, m3, "");
+   bits[0] = LLVMConstInt(i32t, 1 << 0, 0);
+   bits[1] = LLVMConstInt(i32t, 1 << 1, 0);
+   bits[2] = LLVMConstInt(i32t, 1 << 2, 0);
+   bits[3] = LLVMConstInt(i32t, 1 << 3, 0);
 
-   lp_build_name(m, "scissormask");
+   mask = LLVMBuildAnd(builder, mask, LLVMConstVector(bits, 4), "");
 
-   return m;
-}
+   /*
+    * mask = mask != 0 ? ~0 : 0
+    */
 
+   mask = lp_build_compare(builder,
+                           mask_type, PIPE_FUNC_NOTEQUAL,
+                           mask,
+                           lp_build_const_int_vec(mask_type, 0));
 
-static LLVMValueRef
-build_int32_vec_const(int value)
-{
-   struct lp_type i32_type;
-
-   memset(&i32_type, 0, sizeof i32_type);
-   i32_type.floating = FALSE; /* values are integers */
-   i32_type.sign = TRUE;      /* values are signed */
-   i32_type.norm = FALSE;     /* values are not normalized */
-   i32_type.width = 32;       /* 32-bit int values */
-   i32_type.length = 4;       /* 4 elements per vector */
-   return lp_build_const_int_vec(i32_type, value);
+   return mask;
 }
 
 
@@ -348,7 +232,7 @@ build_int32_vec_const(int value)
 /**
  * Generate the fragment shader, depth/stencil test, and alpha tests.
  * \param i  which quad in the tile, in range [0,3]
- * \param do_tri_test  if 1, do triangle edge in/out testing
+ * \param partial_mask  if 1, do mask_input testing
  */
 static void
 generate_fs(struct llvmpipe_context *lp,
@@ -364,13 +248,8 @@ generate_fs(struct llvmpipe_context *lp,
             LLVMValueRef (*color)[4],
             LLVMValueRef depth_ptr,
             LLVMValueRef facing,
-            unsigned do_tri_test,
-            LLVMValueRef c0,
-            LLVMValueRef c1,
-            LLVMValueRef c2,
-            LLVMValueRef step0_ptr,
-            LLVMValueRef step1_ptr,
-            LLVMValueRef step2_ptr,
+            unsigned partial_mask,
+            LLVMValueRef mask_input,
             LLVMValueRef counter)
 {
    const struct tgsi_token *tokens = shader->base.tokens;
@@ -411,23 +290,17 @@ generate_fs(struct llvmpipe_context *lp,
    lp_build_flow_scope_declare(flow, &z);
 
    /* do triangle edge testing */
-   if (do_tri_test) {
-      generate_tri_edge_mask(builder, i, pmask,
-                             c0, c1, c2, step0_ptr, step1_ptr, step2_ptr);
+   if (partial_mask) {
+      *pmask = generate_quad_mask(builder, type,
+                                  i, mask_input);
    }
    else {
-      *pmask = build_int32_vec_const(~0);
+      *pmask = lp_build_const_int_vec(type, ~0);
    }
 
    /* 'mask' will control execution based on quad's pixel alive/killed state */
    lp_build_mask_begin(&mask, flow, type, *pmask);
 
-   if (key->scissor) {
-      LLVMValueRef smask =
-         generate_scissor_test(builder, context_ptr, interp, type);
-      lp_build_mask_update(&mask, smask);
-   }
-
    early_depth_stencil_test =
       (key->depth.enabled || key->stencil[0].enabled) &&
       !key->alpha.enabled &&
@@ -579,7 +452,7 @@ static void
 generate_fragment(struct llvmpipe_context *lp,
                   struct lp_fragment_shader *shader,
                   struct lp_fragment_shader_variant *variant,
-                  unsigned do_tri_test)
+                  unsigned partial_mask)
 {
    struct llvmpipe_screen *screen = llvmpipe_screen(lp->pipe.screen);
    const struct lp_fragment_shader_variant_key *key = &variant->key;
@@ -589,9 +462,8 @@ generate_fragment(struct llvmpipe_context *lp,
    LLVMTypeRef fs_elem_type;
    LLVMTypeRef fs_int_vec_type;
    LLVMTypeRef blend_vec_type;
-   LLVMTypeRef arg_types[16];
+   LLVMTypeRef arg_types[11];
    LLVMTypeRef func_type;
-   LLVMTypeRef int32_vec4_type = lp_build_int32_vec4_type();
    LLVMValueRef context_ptr;
    LLVMValueRef x;
    LLVMValueRef y;
@@ -600,7 +472,8 @@ generate_fragment(struct llvmpipe_context *lp,
    LLVMValueRef dady_ptr;
    LLVMValueRef color_ptr_ptr;
    LLVMValueRef depth_ptr;
-   LLVMValueRef c0, c1, c2, step0_ptr, step1_ptr, step2_ptr, counter = NULL;
+   LLVMValueRef mask_input;
+   LLVMValueRef counter = NULL;
    LLVMBasicBlockRef block;
    LLVMBuilderRef builder;
    struct lp_build_sampler_soa *sampler;
@@ -645,7 +518,7 @@ generate_fragment(struct llvmpipe_context *lp,
    blend_vec_type = lp_build_vec_type(blend_type);
 
    util_snprintf(func_name, sizeof(func_name), "fs%u_variant%u_%s", 
-                shader->no, variant->no, do_tri_test ? "edge" : "whole");
+                shader->no, variant->no, partial_mask ? "partial" : "whole");
 
    arg_types[0] = screen->context_ptr_type;            /* context */
    arg_types[1] = LLVMInt32Type();                     /* x */
@@ -656,23 +529,15 @@ generate_fragment(struct llvmpipe_context *lp,
    arg_types[6] = LLVMPointerType(fs_elem_type, 0);    /* dady */
    arg_types[7] = LLVMPointerType(LLVMPointerType(blend_vec_type, 0), 0);  /* color */
    arg_types[8] = LLVMPointerType(fs_int_vec_type, 0); /* depth */
-   arg_types[9] = LLVMInt32Type();                     /* c0 */
-   arg_types[10] = LLVMInt32Type();                    /* c1 */
-   arg_types[11] = LLVMInt32Type();                    /* c2 */
-   /* Note: the step arrays are built as int32[16] but we interpret
-    * them here as int32_vec4[4].
-    */
-   arg_types[12] = LLVMPointerType(int32_vec4_type, 0);/* step0 */
-   arg_types[13] = LLVMPointerType(int32_vec4_type, 0);/* step1 */
-   arg_types[14] = LLVMPointerType(int32_vec4_type, 0);/* step2 */
-   arg_types[15] = LLVMPointerType(LLVMInt32Type(), 0);/* counter */
+   arg_types[9] = LLVMInt32Type();                     /* mask_input */
+   arg_types[10] = LLVMPointerType(LLVMInt32Type(), 0);/* counter */
 
    func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0);
 
    function = LLVMAddFunction(screen->module, func_name, func_type);
    LLVMSetFunctionCallConv(function, LLVMCCallConv);
 
-   variant->function[do_tri_test] = function;
+   variant->function[partial_mask] = function;
 
 
    /* XXX: need to propagate noalias down into color param now we are
@@ -691,12 +556,7 @@ generate_fragment(struct llvmpipe_context *lp,
    dady_ptr     = LLVMGetParam(function, 6);
    color_ptr_ptr = LLVMGetParam(function, 7);
    depth_ptr    = LLVMGetParam(function, 8);
-   c0           = LLVMGetParam(function, 9);
-   c1           = LLVMGetParam(function, 10);
-   c2           = LLVMGetParam(function, 11);
-   step0_ptr    = LLVMGetParam(function, 12);
-   step1_ptr    = LLVMGetParam(function, 13);
-   step2_ptr    = LLVMGetParam(function, 14);
+   mask_input   = LLVMGetParam(function, 9);
 
    lp_build_name(context_ptr, "context");
    lp_build_name(x, "x");
@@ -706,15 +566,10 @@ generate_fragment(struct llvmpipe_context *lp,
    lp_build_name(dady_ptr, "dady");
    lp_build_name(color_ptr_ptr, "color_ptr_ptr");
    lp_build_name(depth_ptr, "depth");
-   lp_build_name(c0, "c0");
-   lp_build_name(c1, "c1");
-   lp_build_name(c2, "c2");
-   lp_build_name(step0_ptr, "step0");
-   lp_build_name(step1_ptr, "step1");
-   lp_build_name(step2_ptr, "step2");
+   lp_build_name(mask_input, "mask_input");
 
    if (key->occlusion_count) {
-      counter = LLVMGetParam(function, 15);
+      counter = LLVMGetParam(function, 10);
       lp_build_name(counter, "counter");
    }
 
@@ -763,9 +618,9 @@ generate_fragment(struct llvmpipe_context *lp,
                   out_color,
                   depth_ptr_i,
                   facing,
-                  do_tri_test,
-                  c0, c1, c2,
-                  step0_ptr, step1_ptr, step2_ptr, counter);
+                  partial_mask,
+                  mask_input,
+                  counter);
 
       for(cbuf = 0; cbuf < key->nr_cbufs; cbuf++)
         for(chan = 0; chan < NUM_CHANNELS; ++chan)
@@ -792,9 +647,13 @@ generate_fragment(struct llvmpipe_context *lp,
         lp_build_name(blend_in_color[chan], "color%d.%c", cbuf, "rgba"[chan]);
       }
 
-      lp_build_conv_mask(builder, fs_type, blend_type,
-                        fs_mask, num_fs,
-                        &blend_mask, 1);
+      if (partial_mask || !variant->opaque) {
+         lp_build_conv_mask(builder, fs_type, blend_type,
+                            fs_mask, num_fs,
+                            &blend_mask, 1);
+      } else {
+         blend_mask = lp_build_const_int_vec(blend_type, ~0);
+      }
 
       color_ptr = LLVMBuildLoad(builder, 
                                LLVMBuildGEP(builder, color_ptr_ptr, &index, 1, ""),
@@ -832,8 +691,7 @@ generate_fragment(struct llvmpipe_context *lp,
 #endif
 
    /* Apply optimizations to LLVM IR */
-   if (1)
-      LLVMRunFunctionPassManager(screen->pass, function);
+   LLVMRunFunctionPassManager(screen->pass, function);
 
    if (gallivm_debug & GALLIVM_DEBUG_IR) {
       /* Print the LLVM IR to stderr */
@@ -847,7 +705,7 @@ generate_fragment(struct llvmpipe_context *lp,
    {
       void *f = LLVMGetPointerToGlobal(screen->engine, function);
 
-      variant->jit_function[do_tri_test] = (lp_jit_frag_func)pointer_to_func(f);
+      variant->jit_function[partial_mask] = (lp_jit_frag_func)pointer_to_func(f);
 
       if (gallivm_debug & GALLIVM_DEBUG_ASM) {
          lp_disassemble(f);
@@ -963,7 +821,6 @@ generate_variant(struct llvmpipe_context *lp,
          !key->stencil[0].enabled &&
          !key->alpha.enabled &&
          !key->depth.enabled &&
-         !key->scissor &&
          !shader->info.uses_kill
          ? TRUE : FALSE;
 
@@ -1182,7 +1039,6 @@ make_variant_key(struct llvmpipe_context *lp,
    /* alpha.ref_value is passed in jit_context */
 
    key->flatshade = lp->rasterizer->flatshade;
-   key->scissor = lp->rasterizer->scissor;
    if (lp->active_query_count) {
       key->occlusion_count = TRUE;
    }
index 593cd4de6beefa5fdf2a1e82e600fc55578fe21a..37900fc54432297487c2848e3d7335c0439263a7 100644 (file)
@@ -54,7 +54,6 @@ struct lp_fragment_shader_variant_key
    enum pipe_format zsbuf_format;
    unsigned nr_cbufs:8;
    unsigned flatshade:1;
-   unsigned scissor:1;
    unsigned occlusion_count:1;
 
    struct {
index e94065fb6ab571b465e0b3e4fb8276e40449173b..715ce2f02e4e8dd4909ccb2f63a99a0657f6ba35 100644 (file)
 #include "draw/draw_context.h"
 
 #include "lp_context.h"
-#include "lp_context.h"
+#include "lp_screen.h"
 #include "lp_state.h"
-#include "draw/draw_context.h"
-
+#include "state_tracker/sw_winsys.h"
 
 
 static void *
@@ -100,6 +99,10 @@ llvmpipe_bind_vertex_sampler_states(struct pipe_context *pipe,
 
    llvmpipe->num_vertex_samplers = num_samplers;
 
+   draw_set_samplers(llvmpipe->draw,
+                     llvmpipe->vertex_samplers,
+                     llvmpipe->num_vertex_samplers);
+
    llvmpipe->dirty |= LP_NEW_SAMPLER;
 }
 
@@ -166,6 +169,10 @@ llvmpipe_set_vertex_sampler_views(struct pipe_context *pipe,
 
    llvmpipe->num_vertex_sampler_views = num;
 
+   draw_set_sampler_views(llvmpipe->draw,
+                          llvmpipe->vertex_sampler_views,
+                          llvmpipe->num_vertex_sampler_views);
+
    llvmpipe->dirty |= LP_NEW_SAMPLER_VIEW;
 }
 
@@ -214,6 +221,77 @@ llvmpipe_delete_sampler_state(struct pipe_context *pipe,
 }
 
 
+/**
+ * Called during state validation when LP_NEW_SAMPLER_VIEW is set.
+ */
+void
+llvmpipe_prepare_vertex_sampling(struct llvmpipe_context *lp,
+                                 unsigned num,
+                                 struct pipe_sampler_view **views)
+{
+   unsigned i;
+   uint32_t row_stride[DRAW_MAX_TEXTURE_LEVELS];
+   uint32_t img_stride[DRAW_MAX_TEXTURE_LEVELS];
+   const void *data[DRAW_MAX_TEXTURE_LEVELS];
+
+   assert(num <= PIPE_MAX_VERTEX_SAMPLERS);
+   if (!num)
+      return;
+
+   for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
+      struct pipe_sampler_view *view = i < num ? views[i] : NULL;
+
+      if (view) {
+         struct pipe_resource *tex = view->texture;
+         struct llvmpipe_resource *lp_tex = llvmpipe_resource(tex);
+
+         /* We're referencing the texture's internal data, so save a
+          * reference to it.
+          */
+         pipe_resource_reference(&lp->mapped_vs_tex[i], tex);
+
+         if (!lp_tex->dt) {
+            /* regular texture - setup array of mipmap level pointers */
+            int j;
+            for (j = 0; j <= tex->last_level; j++) {
+               data[j] =
+                  llvmpipe_get_texture_image_all(lp_tex, j, LP_TEX_USAGE_READ,
+                                                 LP_TEX_LAYOUT_LINEAR);
+               row_stride[j] = lp_tex->row_stride[j];
+               img_stride[j] = lp_tex->img_stride[j];
+            }
+         }
+         else {
+            /* display target texture/surface */
+            /*
+             * XXX: Where should this be unmapped?
+             */
+            struct llvmpipe_screen *screen = llvmpipe_screen(tex->screen);
+            struct sw_winsys *winsys = screen->winsys;
+            data[0] = winsys->displaytarget_map(winsys, lp_tex->dt,
+                                                PIPE_TRANSFER_READ);
+            row_stride[0] = lp_tex->row_stride[0];
+            img_stride[0] = lp_tex->img_stride[0];
+            assert(data[0]);
+         }
+         draw_set_mapped_texture(lp->draw,
+                                 i,
+                                 tex->width0, tex->height0, tex->depth0,
+                                 tex->last_level,
+                                 row_stride, img_stride, data);
+      }
+   }
+}
+
+void
+llvmpipe_cleanup_vertex_sampling(struct llvmpipe_context *ctx)
+{
+   unsigned i;
+   for (i = 0; i < Elements(ctx->mapped_vs_tex); i++) {
+      pipe_resource_reference(&ctx->mapped_vs_tex[i], NULL);
+   }
+}
+
 void
 llvmpipe_init_sampler_funcs(struct llvmpipe_context *llvmpipe)
 {
index 4c64a5b142c9d8ca5ba91374854abc3fa58231b0..30b17c98816d2b0f6f8ce56ee5853169f8a50c23 100644 (file)
@@ -29,7 +29,6 @@
 #include "lp_state.h"
 #include "lp_texture.h"
 
-#include "util/u_format.h"
 #include "util/u_memory.h"
 #include "draw/draw_context.h"
 
index 76b3fce1fa992336adf976fdb9b6eb187fd97d29..f761e8285000b2adea39f26bdfe5b658791ef4ab 100644 (file)
@@ -67,14 +67,14 @@ lp_resource_copy(struct pipe_context *pipe,
                            dst, subdst.face, subdst.level,
                            0, /* flush_flags */
                            FALSE, /* read_only */
-                           FALSE, /* cpu_access */
+                           TRUE, /* cpu_access */
                            FALSE); /* do_not_block */
 
    llvmpipe_flush_resource(pipe,
                            src, subsrc.face, subsrc.level,
                            0, /* flush_flags */
                            TRUE, /* read_only */
-                           FALSE, /* cpu_access */
+                           TRUE, /* cpu_access */
                            FALSE); /* do_not_block */
 
    /*
@@ -106,19 +106,27 @@ lp_resource_copy(struct pipe_context *pipe,
       unsigned x, y;
       enum lp_texture_usage usage;
 
-      /* XXX for the tiles which are completely contained by the
-       * dest rectangle, we could set the usage mode to WRITE_ALL.
-       * Just test for the case of replacing the whole dest region for now.
-       */
-      if (width == dst_tex->base.width0 && height == dst_tex->base.height0)
-         usage = LP_TEX_USAGE_WRITE_ALL;
-      else
-         usage = LP_TEX_USAGE_READ_WRITE;
-
       adjust_to_tile_bounds(dstx, dsty, width, height, &tx, &ty, &tw, &th);
 
       for (y = 0; y < th; y += TILE_SIZE) {
+         boolean contained_y = ty + y >= dsty &&
+                               ty + y + TILE_SIZE <= dsty + height ?
+                               TRUE : FALSE;
+
          for (x = 0; x < tw; x += TILE_SIZE) {
+            boolean contained_x = tx + x >= dstx &&
+                                  tx + x + TILE_SIZE <= dstx + width ?
+                                  TRUE : FALSE;
+
+            /*
+             * Set the usage mode to WRITE_ALL for the tiles which are
+             * completely contained by the dest rectangle.
+             */
+            if (contained_y && contained_x)
+               usage = LP_TEX_USAGE_WRITE_ALL;
+            else
+               usage = LP_TEX_USAGE_READ_WRITE;
+
             (void) llvmpipe_get_texture_tile_linear(dst_tex,
                                                     subdst.face, subdst.level,
                                                     usage,
@@ -138,13 +146,15 @@ lp_resource_copy(struct pipe_context *pipe,
                                               subdst.level,
                                               LP_TEX_LAYOUT_LINEAR);
 
-      util_copy_rect(dst_linear_ptr, format,
-                     llvmpipe_resource_stride(&dst_tex->base, subdst.level),
-                     dstx, dsty,
-                     width, height,
-                     src_linear_ptr,
-                     llvmpipe_resource_stride(&src_tex->base, subsrc.level),
-                     srcx, srcy);
+      if (dst_linear_ptr && src_linear_ptr) {
+         util_copy_rect(dst_linear_ptr, format,
+                        llvmpipe_resource_stride(&dst_tex->base, subdst.level),
+                        dstx, dsty,
+                        width, height,
+                        src_linear_ptr,
+                        llvmpipe_resource_stride(&src_tex->base, subsrc.level),
+                        srcx, srcy);
+      }
    }
 }
 
index 9b02f436c5b2e2946d9c87d293662b22cf346086..cf41b40581f3857bf651e1bda699b238f45fec8e 100644 (file)
@@ -167,19 +167,26 @@ test_one(unsigned verbose,
    unsigned i, j;
    void *code;
 
+   if (src_type.width * src_type.length != dst_type.width * dst_type.length &&
+       src_type.length != dst_type.length) {
+      return TRUE;
+   }
+
    if(verbose >= 1)
       dump_conv_types(stdout, src_type, dst_type);
 
-   if(src_type.length > dst_type.length) {
+   if (src_type.length > dst_type.length) {
       num_srcs = 1;
       num_dsts = src_type.length/dst_type.length;
    }
-   else  {
+   else if (src_type.length < dst_type.length) {
       num_dsts = 1;
       num_srcs = dst_type.length/src_type.length;
    }
-
-   assert(src_type.width * src_type.length == dst_type.width * dst_type.length);
+   else  {
+      num_dsts = 1;
+      num_srcs = 1;
+   }
 
    /* We must not loose or gain channels. Only precision */
    assert(src_type.length * num_srcs == dst_type.length * num_dsts);
@@ -381,6 +388,11 @@ const struct lp_type conv_types[] = {
    {  FALSE, FALSE,  TRUE, FALSE,     8,  16 },
    {  FALSE, FALSE, FALSE,  TRUE,     8,  16 },
    {  FALSE, FALSE, FALSE, FALSE,     8,  16 },
+
+   {  FALSE, FALSE,  TRUE,  TRUE,     8,   4 },
+   {  FALSE, FALSE,  TRUE, FALSE,     8,   4 },
+   {  FALSE, FALSE, FALSE,  TRUE,     8,   4 },
+   {  FALSE, FALSE, FALSE, FALSE,     8,   4 },
 };
 
 
index 8b6dc1c7f5dc64dc2773f0842323fe8c3c81f877..2855d7cea4fb5980b30185a58f7409f2edde1348 100644 (file)
@@ -31,6 +31,7 @@
 #include <float.h>
 
 #include "gallivm/lp_bld.h"
+#include "gallivm/lp_bld_debug.h"
 #include "gallivm/lp_bld_init.h"
 #include <llvm-c/Analysis.h>
 #include <llvm-c/Target.h>
@@ -38,6 +39,7 @@
 
 #include "util/u_memory.h"
 #include "util/u_pointer.h"
+#include "util/u_string.h"
 #include "util/u_format.h"
 #include "util/u_format_tests.h"
 #include "util/u_format_s3tc.h"
@@ -71,17 +73,20 @@ write_tsv_row(FILE *fp,
 
 
 typedef void
-(*fetch_ptr_t)(float *, const void *packed,
+(*fetch_ptr_t)(void *unpacked, const void *packed,
                unsigned i, unsigned j);
 
 
 static LLVMValueRef
-add_fetch_rgba_test(LLVMModuleRef lp_build_module,
-                    const struct util_format_description *desc)
+add_fetch_rgba_test(unsigned verbose,
+                    const struct util_format_description *desc,
+                    struct lp_type type)
 {
+   char name[256];
    LLVMTypeRef args[4];
    LLVMValueRef func;
    LLVMValueRef packed_ptr;
+   LLVMValueRef offset = LLVMConstNull(LLVMInt32Type());
    LLVMValueRef rgba_ptr;
    LLVMValueRef i;
    LLVMValueRef j;
@@ -89,11 +94,15 @@ add_fetch_rgba_test(LLVMModuleRef lp_build_module,
    LLVMBuilderRef builder;
    LLVMValueRef rgba;
 
-   args[0] = LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0);
+   util_snprintf(name, sizeof name, "fetch_%s_%s", desc->short_name,
+                 type.floating ? "float" : "unorm8");
+
+   args[0] = LLVMPointerType(lp_build_vec_type(type), 0);
    args[1] = LLVMPointerType(LLVMInt8Type(), 0);
    args[3] = args[2] = LLVMInt32Type();
 
-   func = LLVMAddFunction(lp_build_module, "fetch", LLVMFunctionType(LLVMVoidType(), args, Elements(args), 0));
+   func = LLVMAddFunction(lp_build_module, name,
+                          LLVMFunctionType(LLVMVoidType(), args, Elements(args), 0));
    LLVMSetFunctionCallConv(func, LLVMCCallConv);
    rgba_ptr = LLVMGetParam(func, 0);
    packed_ptr = LLVMGetParam(func, 1);
@@ -104,91 +113,104 @@ add_fetch_rgba_test(LLVMModuleRef lp_build_module,
    builder = LLVMCreateBuilder();
    LLVMPositionBuilderAtEnd(builder, block);
 
-   rgba = lp_build_fetch_rgba_aos(builder, desc, packed_ptr, i, j);
+   rgba = lp_build_fetch_rgba_aos(builder, desc, type,
+                                  packed_ptr, offset, i, j);
 
    LLVMBuildStore(builder, rgba, rgba_ptr);
 
    LLVMBuildRetVoid(builder);
 
    LLVMDisposeBuilder(builder);
+
+   if (LLVMVerifyFunction(func, LLVMPrintMessageAction)) {
+      LLVMDumpValue(func);
+      abort();
+   }
+
+   LLVMRunFunctionPassManager(lp_build_pass, func);
+
+   if (verbose >= 1) {
+      LLVMDumpValue(func);
+   }
+
    return func;
 }
 
 
 PIPE_ALIGN_STACK
 static boolean
-test_format(unsigned verbose, FILE *fp,
-            const struct util_format_description *desc,
-            const struct util_format_test_case *test)
+test_format_float(unsigned verbose, FILE *fp,
+                  const struct util_format_description *desc)
 {
    LLVMValueRef fetch = NULL;
-   LLVMPassManagerRef pass = NULL;
    fetch_ptr_t fetch_ptr;
    PIPE_ALIGN_VAR(16) float unpacked[4];
-   boolean success;
-   unsigned i, j, k;
+   boolean first = TRUE;
+   boolean success = TRUE;
+   unsigned i, j, k, l;
+   void *f;
 
-   fetch = add_fetch_rgba_test(lp_build_module, desc);
+   fetch = add_fetch_rgba_test(verbose, desc, lp_float32_vec4_type());
 
-   if (LLVMVerifyFunction(fetch, LLVMPrintMessageAction)) {
-      LLVMDumpValue(fetch);
-      abort();
+   f = LLVMGetPointerToGlobal(lp_build_engine, fetch);
+   fetch_ptr = (fetch_ptr_t) pointer_to_func(f);
+
+   if (verbose >= 2) {
+      lp_disassemble(f);
    }
 
-#if 0
-   pass = LLVMCreatePassManager();
-   LLVMAddTargetData(LLVMGetExecutionEngineTargetData(lp_build_engine), pass);
-   /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
-    * but there are more on SVN. */
-   LLVMAddConstantPropagationPass(pass);
-   LLVMAddInstructionCombiningPass(pass);
-   LLVMAddPromoteMemoryToRegisterPass(pass);
-   LLVMAddGVNPass(pass);
-   LLVMAddCFGSimplificationPass(pass);
-   LLVMRunPassManager(pass, lp_build_module);
-#else
-   (void)pass;
-#endif
-
-   fetch_ptr = (fetch_ptr_t)pointer_to_func(LLVMGetPointerToGlobal(lp_build_engine, fetch));
-
-   for (i = 0; i < desc->block.height; ++i) {
-      for (j = 0; j < desc->block.width; ++j) {
-
-         memset(unpacked, 0, sizeof unpacked);
-
-         fetch_ptr(unpacked, test->packed, j, i);
-
-         success = TRUE;
-         for(k = 0; k < 4; ++k)
-            if (fabs((float)test->unpacked[i][j][k] - unpacked[k]) > FLT_EPSILON)
-               success = FALSE;
-
-         if (!success) {
-            printf("FAILED\n");
-            printf("  Packed: %02x %02x %02x %02x\n",
-                   test->packed[0], test->packed[1], test->packed[2], test->packed[3]);
-            printf("  Unpacked (%u,%u): %f %f %f %f obtained\n",
-                   j, i,
-                   unpacked[0], unpacked[1], unpacked[2], unpacked[3]);
-            printf("                  %f %f %f %f expected\n",
-                   test->unpacked[i][j][0],
-                   test->unpacked[i][j][1],
-                   test->unpacked[i][j][2],
-                   test->unpacked[i][j][3]);
+   for (l = 0; l < util_format_nr_test_cases; ++l) {
+      const struct util_format_test_case *test = &util_format_test_cases[l];
+
+      if (test->format == desc->format) {
+
+         if (first) {
+            printf("Testing %s (float) ...\n",
+                   desc->name);
+            first = FALSE;
+         }
+
+         for (i = 0; i < desc->block.height; ++i) {
+            for (j = 0; j < desc->block.width; ++j) {
+               boolean match;
+
+               memset(unpacked, 0, sizeof unpacked);
+
+               fetch_ptr(unpacked, test->packed, j, i);
+
+               match = TRUE;
+               for(k = 0; k < 4; ++k)
+                  if (fabs((float)test->unpacked[i][j][k] - unpacked[k]) > FLT_EPSILON)
+                     match = FALSE;
+
+               if (!match) {
+                  printf("FAILED\n");
+                  printf("  Packed: %02x %02x %02x %02x\n",
+                         test->packed[0], test->packed[1], test->packed[2], test->packed[3]);
+                  printf("  Unpacked (%u,%u): %f %f %f %f obtained\n",
+                         j, i,
+                         unpacked[0], unpacked[1], unpacked[2], unpacked[3]);
+                  printf("                  %f %f %f %f expected\n",
+                         test->unpacked[i][j][0],
+                         test->unpacked[i][j][1],
+                         test->unpacked[i][j][2],
+                         test->unpacked[i][j][3]);
+                  success = FALSE;
+               }
+            }
          }
       }
    }
 
-   if (!success)
-      LLVMDumpValue(fetch);
+   if (!success) {
+      if (verbose < 1) {
+         LLVMDumpValue(fetch);
+      }
+   }
 
    LLVMFreeMachineCodeForFunction(lp_build_engine, fetch);
    LLVMDeleteFunction(fetch);
 
-   if(pass)
-      LLVMDisposePassManager(pass);
-
    if(fp)
       write_tsv_row(fp, desc, success);
 
@@ -196,32 +218,104 @@ test_format(unsigned verbose, FILE *fp,
 }
 
 
-
+PIPE_ALIGN_STACK
 static boolean
-test_one(unsigned verbose, FILE *fp,
-         const struct util_format_description *format_desc)
+test_format_unorm8(unsigned verbose, FILE *fp,
+                   const struct util_format_description *desc)
 {
-   unsigned i;
+   LLVMValueRef fetch = NULL;
+   fetch_ptr_t fetch_ptr;
+   uint8_t unpacked[4];
    boolean first = TRUE;
    boolean success = TRUE;
+   unsigned i, j, k, l;
+   void *f;
 
-   for (i = 0; i < util_format_nr_test_cases; ++i) {
-      const struct util_format_test_case *test = &util_format_test_cases[i];
+   fetch = add_fetch_rgba_test(verbose, desc, lp_unorm8_vec4_type());
 
-      if (test->format == format_desc->format) {
+   f = LLVMGetPointerToGlobal(lp_build_engine, fetch);
+   fetch_ptr = (fetch_ptr_t) pointer_to_func(f);
+
+   if (verbose >= 2) {
+      lp_disassemble(f);
+   }
+
+   for (l = 0; l < util_format_nr_test_cases; ++l) {
+      const struct util_format_test_case *test = &util_format_test_cases[l];
+
+      if (test->format == desc->format) {
 
          if (first) {
-            printf("Testing %s ...\n",
-                   format_desc->name);
+            printf("Testing %s (unorm8) ...\n",
+                   desc->name);
             first = FALSE;
          }
 
-         if (!test_format(verbose, fp, format_desc, test)) {
-           success = FALSE;
+         for (i = 0; i < desc->block.height; ++i) {
+            for (j = 0; j < desc->block.width; ++j) {
+               boolean match;
+
+               memset(unpacked, 0, sizeof unpacked);
+
+               fetch_ptr(unpacked, test->packed, j, i);
+
+               match = TRUE;
+               for(k = 0; k < 4; ++k) {
+                  int error = float_to_ubyte(test->unpacked[i][j][k]) - unpacked[k];
+                  if (error < 0)
+                     error = -error;
+                  if (error > 1)
+                     match = FALSE;
+               }
+
+               if (!match) {
+                  printf("FAILED\n");
+                  printf("  Packed: %02x %02x %02x %02x\n",
+                         test->packed[0], test->packed[1], test->packed[2], test->packed[3]);
+                  printf("  Unpacked (%u,%u): %02x %02x %02x %02x obtained\n",
+                         j, i,
+                         unpacked[0], unpacked[1], unpacked[2], unpacked[3]);
+                  printf("                  %02x %02x %02x %02x expected\n",
+                         float_to_ubyte(test->unpacked[i][j][0]),
+                         float_to_ubyte(test->unpacked[i][j][1]),
+                         float_to_ubyte(test->unpacked[i][j][2]),
+                         float_to_ubyte(test->unpacked[i][j][3]));
+                  success = FALSE;
+               }
+            }
          }
       }
    }
 
+   if (!success)
+      LLVMDumpValue(fetch);
+
+   LLVMFreeMachineCodeForFunction(lp_build_engine, fetch);
+   LLVMDeleteFunction(fetch);
+
+   if(fp)
+      write_tsv_row(fp, desc, success);
+
+   return success;
+}
+
+
+
+
+static boolean
+test_one(unsigned verbose, FILE *fp,
+         const struct util_format_description *format_desc)
+{
+   boolean success = TRUE;
+
+   if (!test_format_float(verbose, fp, format_desc)) {
+     success = FALSE;
+   }
+
+   if (!test_format_unorm8(verbose, fp, format_desc)) {
+     success = FALSE;
+   }
+
    return success;
 }
 
diff --git a/src/gallium/drivers/llvmpipe/lp_test_round.c b/src/gallium/drivers/llvmpipe/lp_test_round.c
new file mode 100644 (file)
index 0000000..f571a81
--- /dev/null
@@ -0,0 +1,277 @@
+/**************************************************************************
+ *
+ * Copyright 2010 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "util/u_pointer.h"
+#include "gallivm/lp_bld.h"
+#include "gallivm/lp_bld_printf.h"
+#include "gallivm/lp_bld_arit.h"
+
+#include <llvm-c/Analysis.h>
+#include <llvm-c/ExecutionEngine.h>
+#include <llvm-c/Target.h>
+#include <llvm-c/Transforms/Scalar.h>
+
+#include "lp_test.h"
+
+
+void
+write_tsv_header(FILE *fp)
+{
+   fprintf(fp,
+           "result\t"
+           "format\n");
+
+   fflush(fp);
+}
+
+
+#ifdef PIPE_ARCH_SSE
+
+#define USE_SSE2
+#include "sse_mathfun.h"
+
+typedef __m128 (*test_round_t)(__m128);
+
+typedef LLVMValueRef (*lp_func_t)(struct lp_build_context *, LLVMValueRef);
+
+
+static LLVMValueRef
+add_test(LLVMModuleRef module, const char *name, lp_func_t lp_func)
+{
+   LLVMTypeRef v4sf = LLVMVectorType(LLVMFloatType(), 4);
+   LLVMTypeRef args[1] = { v4sf };
+   LLVMValueRef func = LLVMAddFunction(module, name, LLVMFunctionType(v4sf, args, 1, 0));
+   LLVMValueRef arg1 = LLVMGetParam(func, 0);
+   LLVMBuilderRef builder = LLVMCreateBuilder();
+   LLVMBasicBlockRef block = LLVMAppendBasicBlock(func, "entry");
+   LLVMValueRef ret;
+   struct lp_build_context bld;
+
+   bld.builder = builder;
+   bld.type.floating = 1;
+   bld.type.width = 32;
+   bld.type.length = 4;
+
+   LLVMSetFunctionCallConv(func, LLVMCCallConv);
+
+   LLVMPositionBuilderAtEnd(builder, block);
+
+   ret = lp_func(&bld, arg1);
+
+   LLVMBuildRet(builder, ret);
+   LLVMDisposeBuilder(builder);
+   return func;
+}
+
+static void
+printv(char* string, v4sf value)
+{
+   v4sf v = value;
+   float *f = (float *)&v;
+   printf("%s: %10f %10f %10f %10f\n", string,
+           f[0], f[1], f[2], f[3]);
+}
+
+static void
+compare(v4sf x, v4sf y)
+{
+   float *xp = (float *) &x;
+   float *yp = (float *) &y;
+   if (xp[0] != yp[0] ||
+       xp[1] != yp[1] ||
+       xp[2] != yp[2] ||
+       xp[3] != yp[3]) {
+      printf(" Incorrect result! ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ \n");
+   }
+}
+
+
+
+PIPE_ALIGN_STACK
+static boolean
+test_round(unsigned verbose, FILE *fp)
+{
+   LLVMModuleRef module = NULL;
+   LLVMValueRef test_round = NULL, test_trunc, test_floor, test_ceil;
+   LLVMExecutionEngineRef engine = NULL;
+   LLVMModuleProviderRef provider = NULL;
+   LLVMPassManagerRef pass = NULL;
+   char *error = NULL;
+   test_round_t round_func, trunc_func, floor_func, ceil_func;
+   float unpacked[4];
+   unsigned packed;
+   boolean success = TRUE;
+   int i;
+
+   module = LLVMModuleCreateWithName("test");
+
+   test_round = add_test(module, "round", lp_build_round);
+   test_trunc = add_test(module, "trunc", lp_build_trunc);
+   test_floor = add_test(module, "floor", lp_build_floor);
+   test_ceil = add_test(module, "ceil", lp_build_ceil);
+
+   if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) {
+      printf("LLVMVerifyModule: %s\n", error);
+      LLVMDumpModule(module);
+      abort();
+   }
+   LLVMDisposeMessage(error);
+
+   provider = LLVMCreateModuleProviderForExistingModule(module);
+   if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) {
+      fprintf(stderr, "%s\n", error);
+      LLVMDisposeMessage(error);
+      abort();
+   }
+
+#if 0
+   pass = LLVMCreatePassManager();
+   LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
+   /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
+    * but there are more on SVN. */
+   LLVMAddConstantPropagationPass(pass);
+   LLVMAddInstructionCombiningPass(pass);
+   LLVMAddPromoteMemoryToRegisterPass(pass);
+   LLVMAddGVNPass(pass);
+   LLVMAddCFGSimplificationPass(pass);
+   LLVMRunPassManager(pass, module);
+#else
+   (void)pass;
+#endif
+
+   round_func = (test_round_t) pointer_to_func(LLVMGetPointerToGlobal(engine, test_round));
+   trunc_func = (test_round_t) pointer_to_func(LLVMGetPointerToGlobal(engine, test_trunc));
+   floor_func = (test_round_t) pointer_to_func(LLVMGetPointerToGlobal(engine, test_floor));
+   ceil_func = (test_round_t) pointer_to_func(LLVMGetPointerToGlobal(engine, test_ceil));
+
+   memset(unpacked, 0, sizeof unpacked);
+   packed = 0;
+
+   if (0)
+      LLVMDumpModule(module);
+
+   for (i = 0; i < 3; i++) {
+      v4sf xvals[3] = {
+         {-10.0, -1, 0, 12.0},
+         {-1.5, -0.25, 1.25, 2.5},
+         {-0.99, -0.01, 0.01, 0.99}
+      };
+      v4sf x = xvals[i];
+      v4sf y, ref;
+      float *xp = (float *) &x;
+      float *refp = (float *) &ref;
+
+      printf("\n");
+      printv("x            ", x);
+
+      refp[0] = round(xp[0]);
+      refp[1] = round(xp[1]);
+      refp[2] = round(xp[2]);
+      refp[3] = round(xp[3]);
+      y = round_func(x);
+      printv("C round(x)   ", ref);
+      printv("LLVM round(x)", y);
+      compare(ref, y);
+
+      refp[0] = trunc(xp[0]);
+      refp[1] = trunc(xp[1]);
+      refp[2] = trunc(xp[2]);
+      refp[3] = trunc(xp[3]);
+      y = trunc_func(x);
+      printv("C trunc(x)   ", ref);
+      printv("LLVM trunc(x)", y);
+      compare(ref, y);
+
+      refp[0] = floor(xp[0]);
+      refp[1] = floor(xp[1]);
+      refp[2] = floor(xp[2]);
+      refp[3] = floor(xp[3]);
+      y = floor_func(x);
+      printv("C floor(x)   ", ref);
+      printv("LLVM floor(x)", y);
+      compare(ref, y);
+
+      refp[0] = ceil(xp[0]);
+      refp[1] = ceil(xp[1]);
+      refp[2] = ceil(xp[2]);
+      refp[3] = ceil(xp[3]);
+      y = ceil_func(x);
+      printv("C ceil(x)    ", ref);
+      printv("LLVM ceil(x) ", y);
+      compare(ref, y);
+   }
+
+   LLVMFreeMachineCodeForFunction(engine, test_round);
+   LLVMFreeMachineCodeForFunction(engine, test_trunc);
+   LLVMFreeMachineCodeForFunction(engine, test_floor);
+   LLVMFreeMachineCodeForFunction(engine, test_ceil);
+
+   LLVMDisposeExecutionEngine(engine);
+   if(pass)
+      LLVMDisposePassManager(pass);
+
+   return success;
+}
+
+#else /* !PIPE_ARCH_SSE */
+
+static boolean
+test_round(unsigned verbose, FILE *fp)
+{
+   return TRUE;
+}
+
+#endif /* !PIPE_ARCH_SSE */
+
+
+boolean
+test_all(unsigned verbose, FILE *fp)
+{
+   boolean success = TRUE;
+
+   test_round(verbose, fp);
+
+   return success;
+}
+
+
+boolean
+test_some(unsigned verbose, FILE *fp, unsigned long n)
+{
+   return test_all(verbose, fp);
+}
+
+boolean
+test_single(unsigned verbose, FILE *fp)
+{
+   printf("no test_single()");
+   return TRUE;
+}
index c7a903a0256abc10a64ba7b5c19db2125b9d6307..1366ecddcbc2448dfe9d8cc3e696a5af07110531 100644 (file)
@@ -108,7 +108,6 @@ test_sincos(unsigned verbose, FILE *fp)
    test_sincos_t sin_func;
    test_sincos_t cos_func;
    float unpacked[4];
-   unsigned packed;
    boolean success = TRUE;
 
    module = LLVMModuleCreateWithName("test");
@@ -149,7 +148,6 @@ test_sincos(unsigned verbose, FILE *fp)
    cos_func = (test_sincos_t)LLVMGetPointerToGlobal(engine, test_cos);
 
    memset(unpacked, 0, sizeof unpacked);
-   packed = 0;
 
 
    // LLVMDumpModule(module);
index 0d526ead89d229abb81ca70df4c47da139d98da1..25112c10a662868c8393275a1ee798e3fda04f1d 100644 (file)
@@ -36,6 +36,7 @@
 #include "pipe/p_defines.h"
 
 #include "util/u_inlines.h"
+#include "util/u_cpu_detect.h"
 #include "util/u_format.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
@@ -55,6 +56,7 @@
 #ifdef DEBUG
 static struct llvmpipe_resource resource_list;
 #endif
+static unsigned id_counter = 0;
 
 
 static INLINE boolean
@@ -183,8 +185,8 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
     */
    const unsigned width = align(lpr->base.width0, TILE_SIZE);
    const unsigned height = align(lpr->base.height0, TILE_SIZE);
-   const unsigned width_t = align(width, TILE_SIZE) / TILE_SIZE;
-   const unsigned height_t = align(height, TILE_SIZE) / TILE_SIZE;
+   const unsigned width_t = width / TILE_SIZE;
+   const unsigned height_t = height / TILE_SIZE;
 
    lpr->tiles_per_row[0] = width_t;
    lpr->tiles_per_image[0] = width_t * height_t;
@@ -209,7 +211,6 @@ static struct pipe_resource *
 llvmpipe_resource_create(struct pipe_screen *_screen,
                          const struct pipe_resource *templat)
 {
-   static unsigned id_counter = 0;
    struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
    struct llvmpipe_resource *lpr = CALLOC_STRUCT(llvmpipe_resource);
    if (!lpr)
@@ -389,7 +390,6 @@ llvmpipe_resource_map(struct pipe_resource *resource,
 
       map = llvmpipe_get_texture_image(lpr, face + zslice, level,
                                        tex_usage, layout);
-      assert(map);
       return map;
    }
    else {
@@ -446,6 +446,10 @@ llvmpipe_resource_from_handle(struct pipe_screen *screen,
 {
    struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys;
    struct llvmpipe_resource *lpr = CALLOC_STRUCT(llvmpipe_resource);
+   unsigned width, height, width_t, height_t;
+
+   /* XXX Seems like from_handled depth textures doesn't work that well */
+
    if (!lpr)
       return NULL;
 
@@ -453,6 +457,25 @@ llvmpipe_resource_from_handle(struct pipe_screen *screen,
    pipe_reference_init(&lpr->base.reference, 1);
    lpr->base.screen = screen;
 
+   width = align(lpr->base.width0, TILE_SIZE);
+   height = align(lpr->base.height0, TILE_SIZE);
+   width_t = width / TILE_SIZE;
+   height_t = height / TILE_SIZE;
+
+   /*
+    * Looks like unaligned displaytargets work just fine,
+    * at least sampler/render ones.
+    */
+#if 0
+   assert(lpr->base.width0 == width);
+   assert(lpr->base.height0 == height);
+#endif
+
+   lpr->tiles_per_row[0] = width_t;
+   lpr->tiles_per_image[0] = width_t * height_t;
+   lpr->num_slices_faces[0] = 1;
+   lpr->img_stride[0] = 0;
+
    lpr->dt = winsys->displaytarget_from_handle(winsys,
                                                template,
                                                whandle,
@@ -460,6 +483,17 @@ llvmpipe_resource_from_handle(struct pipe_screen *screen,
    if (!lpr->dt)
       goto fail;
 
+   lpr->layout[0] = alloc_layout_array(1, lpr->base.width0, lpr->base.height0);
+
+   assert(lpr->layout[0]);
+   assert(lpr->layout[0][0] == LP_TEX_LAYOUT_NONE);
+
+   lpr->id = id_counter++;
+
+#ifdef DEBUG
+   insert_at_tail(&resource_list, lpr);
+#endif
+
    return &lpr->base;
 
  fail:
@@ -899,13 +933,15 @@ static void
 alloc_image_data(struct llvmpipe_resource *lpr, unsigned level,
                  enum lp_texture_layout layout)
 {
+   uint alignment = MAX2(16, util_cpu_caps.cacheline);
+
    if (lpr->dt)
       assert(level == 0);
 
    if (layout == LP_TEX_LAYOUT_TILED) {
       /* tiled data is stored in regular memory */
       uint buffer_size = tex_image_size(lpr, level, layout);
-      lpr->tiled[level].data = align_malloc(buffer_size, 16);
+      lpr->tiled[level].data = align_malloc(buffer_size, alignment);
    }
    else {
       assert(layout == LP_TEX_LAYOUT_LINEAR);
@@ -921,7 +957,7 @@ alloc_image_data(struct llvmpipe_resource *lpr, unsigned level,
       else {
          /* not a display target - allocate regular memory */
          uint buffer_size = tex_image_size(lpr, level, LP_TEX_LAYOUT_LINEAR);
-         lpr->linear[level].data = align_malloc(buffer_size, 16);
+         lpr->linear[level].data = align_malloc(buffer_size, alignment);
       }
    }
 }
@@ -1035,7 +1071,7 @@ llvmpipe_get_texture_image(struct llvmpipe_resource *lpr,
 
             layout_logic(cur_layout, layout, usage, &new_layout, &convert);
 
-            if (convert) {
+            if (convert && other_data && target_data) {
                if (layout == LP_TEX_LAYOUT_TILED) {
                   lp_linear_to_tiled(other_data, target_data,
                                      x * TILE_SIZE, y * TILE_SIZE,
@@ -1067,8 +1103,6 @@ llvmpipe_get_texture_image(struct llvmpipe_resource *lpr,
                                         width_t, height_t, layout);
    }
 
-   assert(target_data);
-
    return target_data;
 }
 
@@ -1138,7 +1172,7 @@ llvmpipe_get_texture_tile_linear(struct llvmpipe_resource *lpr,
    layout_logic(cur_layout, LP_TEX_LAYOUT_LINEAR, usage,
                 &new_layout, &convert);
 
-   if (convert) {
+   if (convert && tiled_image && linear_image) {
       lp_tiled_to_linear(tiled_image, linear_image,
                          x, y, TILE_SIZE, TILE_SIZE, lpr->base.format,
                          lpr->row_stride[level],
@@ -1187,13 +1221,16 @@ llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr,
    cur_layout = llvmpipe_get_texture_tile_layout(lpr, face_slice, level, tx, ty);
 
    layout_logic(cur_layout, LP_TEX_LAYOUT_TILED, usage, &new_layout, &convert);
-   if (convert) {
+   if (convert && linear_image && tiled_image) {
       lp_linear_to_tiled(linear_image, tiled_image,
                          x, y, TILE_SIZE, TILE_SIZE, lpr->base.format,
                          lpr->row_stride[level],
                          lpr->tiles_per_row[level]);
    }
 
+   if (!tiled_image)
+      return NULL;
+
    if (new_layout != cur_layout)
       llvmpipe_set_texture_tile_layout(lpr, face_slice, level, tx, ty, new_layout);
 
@@ -1205,6 +1242,94 @@ llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr,
 }
 
 
+/**
+ * Get pointer to tiled data for rendering.
+ * \return pointer to the tiled data at the given tile position
+ */
+void
+llvmpipe_unswizzle_cbuf_tile(struct llvmpipe_resource *lpr,
+                             unsigned face_slice, unsigned level,
+                             unsigned x, unsigned y,
+                             uint8_t *tile)
+{
+   struct llvmpipe_texture_image *linear_img = &lpr->linear[level];
+   const unsigned tx = x / TILE_SIZE, ty = y / TILE_SIZE;
+   uint8_t *linear_image;
+
+   assert(x % TILE_SIZE == 0);
+   assert(y % TILE_SIZE == 0);
+
+   if (!linear_img->data) {
+      /* allocate memory for the linear image now */
+      alloc_image_data(lpr, level, LP_TEX_LAYOUT_LINEAR);
+   }
+
+   /* compute address of the slice/face of the image that contains the tile */
+   linear_image = llvmpipe_get_texture_image_address(lpr, face_slice, level,
+                                                     LP_TEX_LAYOUT_LINEAR);
+
+   {
+      uint ii = x, jj = y;
+      uint tile_offset = jj / TILE_SIZE + ii / TILE_SIZE;
+      uint byte_offset = tile_offset * TILE_SIZE * TILE_SIZE * 4;
+      
+      /* Note that lp_tiled_to_linear expects the tile parameter to
+       * point at the first tile in a whole-image sized array.  In
+       * this code, we have only a single tile and have to do some
+       * pointer arithmetic to figure out where the "image" would have
+       * started.
+       */
+      lp_tiled_to_linear(tile - byte_offset, linear_image,
+                         x, y, TILE_SIZE, TILE_SIZE,
+                         lpr->base.format,
+                         lpr->row_stride[level],
+                         1);       /* tiles per row */
+   }
+
+   llvmpipe_set_texture_tile_layout(lpr, face_slice, level, tx, ty,
+                                    LP_TEX_LAYOUT_LINEAR);
+}
+
+
+/**
+ * Get pointer to tiled data for rendering.
+ * \return pointer to the tiled data at the given tile position
+ */
+void
+llvmpipe_swizzle_cbuf_tile(struct llvmpipe_resource *lpr,
+                           unsigned face_slice, unsigned level,
+                           unsigned x, unsigned y,
+                           uint8_t *tile)
+{
+   uint8_t *linear_image;
+
+   assert(x % TILE_SIZE == 0);
+   assert(y % TILE_SIZE == 0);
+
+   /* compute address of the slice/face of the image that contains the tile */
+   linear_image = llvmpipe_get_texture_image_address(lpr, face_slice, level,
+                                                     LP_TEX_LAYOUT_LINEAR);
+
+   if (linear_image) {
+      uint ii = x, jj = y;
+      uint tile_offset = jj / TILE_SIZE + ii / TILE_SIZE;
+      uint byte_offset = tile_offset * TILE_SIZE * TILE_SIZE * 4;
+
+      /* Note that lp_linear_to_tiled expects the tile parameter to
+       * point at the first tile in a whole-image sized array.  In
+       * this code, we have only a single tile and have to do some
+       * pointer arithmetic to figure out where the "image" would have
+       * started.
+       */
+      lp_linear_to_tiled(linear_image, tile - byte_offset,
+                         x, y, TILE_SIZE, TILE_SIZE,
+                         lpr->base.format,
+                         lpr->row_stride[level],
+                         1);       /* tiles per row */
+   }
+}
+
+
 /**
  * Return size of resource in bytes
  */
index 503b6a19a8d57aeb86577f49ce4bd76ffe4c3a69..4e4a65dcb401d1e260b79655ab301a45e6e8c2f1 100644 (file)
@@ -223,6 +223,17 @@ llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr,
                            unsigned x, unsigned y);
 
 
+void
+llvmpipe_unswizzle_cbuf_tile(struct llvmpipe_resource *lpr,
+                             unsigned face_slice, unsigned level,
+                             unsigned x, unsigned y,
+                             uint8_t *tile);
+
+void
+llvmpipe_swizzle_cbuf_tile(struct llvmpipe_resource *lpr,
+                           unsigned face_slice, unsigned level,
+                           unsigned x, unsigned y,
+                           uint8_t *tile);
 
 extern void
 llvmpipe_print_resources(void);
index 2b63992dd7008271f4bb5916c98f01a6a679fca7..0938f7aea7e0d39c8f80affe03b965f0c12cb6ee 100644 (file)
@@ -204,7 +204,7 @@ lp_tiled_to_linear(const void *src, void *dst,
             lp_tile_unswizzle_4ub(format,
                               src_tile,
                               dst, dst_stride,
-                              ii, jj, tile_w, tile_h);
+                              ii, jj);
          }
       }
    }
@@ -293,7 +293,7 @@ lp_linear_to_tiled(const void *src, void *dst,
             lp_tile_swizzle_4ub(format,
                              dst_tile,
                              src, src_stride,
-                             ii, jj, tile_w, tile_h);
+                             ii, jj);
          }
       }
    }
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_shuffle_mask.py b/src/gallium/drivers/llvmpipe/lp_tile_shuffle_mask.py
new file mode 100644 (file)
index 0000000..ea2fc0f
--- /dev/null
@@ -0,0 +1,32 @@
+
+tile =  [[0,1,4,5],
+        [2,3,6,7],
+        [8,9,12,13],
+        [10,11,14,15]]
+shift = 0
+align = 1
+value = 0L
+holder = []
+
+import sys
+
+basemask = [0x
+fd = sys.stdout
+indent = " "*9
+for c in range(4):
+   fd.write(indent + "*pdst++ = \n");
+   for l,line in enumerate(tile):
+       fd.write(indent + "   %s_mm_shuffle_epi8(line%d, (__m128i){"%(l and '+' or ' ',l))
+       for i,pos in enumerate(line):
+           mask = 0x00ffffffff & (~(0xffL << shift))
+           value = mask | ((pos) << shift)
+           holder.append(value)
+            if holder and (i + 1) %2 == 0:
+               fd.write("0x%8.0x"%(holder[0] + (holder[1] << 32)))
+               holder = []
+               if (i) %4 == 1:
+                       fd.write( ',')
+               
+        fd.write("})%s\n"%((l == 3) and ';' or ''))
+   print
+   shift += 8
index 07f71b8411abcba596458637900a8d44322ca9ec..12dac1da6ca89cc597748e15591d89cca1047630 100644 (file)
@@ -79,14 +79,14 @@ void
 lp_tile_swizzle_4ub(enum pipe_format format,
                  uint8_t *dst,
                  const void *src, unsigned src_stride,
-                 unsigned x, unsigned y, unsigned w, unsigned h);
+                 unsigned x, unsigned y);
 
 
 void
 lp_tile_unswizzle_4ub(enum pipe_format format,
                   const uint8_t *src,
                   void *dst, unsigned dst_stride,
-                  unsigned x, unsigned y, unsigned w, unsigned h);
+                  unsigned x, unsigned y);
 
 
 
index 5ab63cbac67fdc190150292e42e9967f14f349e8..c71ec8066c72875f9af7289d7f04c00bc4df9620 100644 (file)
@@ -75,13 +75,13 @@ def generate_format_read(format, dst_channel, dst_native_type, dst_suffix):
     src_native_type = native_type(format)
 
     print 'static void'
-    print 'lp_tile_%s_swizzle_%s(%s *dst, const uint8_t *src, unsigned src_stride, unsigned x0, unsigned y0, unsigned w, unsigned h)' % (name, dst_suffix, dst_native_type)
+    print 'lp_tile_%s_swizzle_%s(%s *dst, const uint8_t *src, unsigned src_stride, unsigned x0, unsigned y0)' % (name, dst_suffix, dst_native_type)
     print '{'
     print '   unsigned x, y;'
     print '   const uint8_t *src_row = src + y0*src_stride;'
-    print '   for (y = 0; y < h; ++y) {'
+    print '   for (y = 0; y < TILE_SIZE; ++y) {'
     print '      const %s *src_pixel = (const %s *)(src_row + x0*%u);' % (src_native_type, src_native_type, format.stride())
-    print '      for (x = 0; x < w; ++x) {'
+    print '      for (x = 0; x < TILE_SIZE; ++x) {'
 
     names = ['']*4
     if format.colorspace in ('rgb', 'srgb'):
@@ -202,9 +202,9 @@ def emit_unrolled_unswizzle_code(format, src_channel):
     print '   %s *dstpix = (%s *) dst;' % (dst_native_type, dst_native_type)
     print '   unsigned int qx, qy, i;'
     print
-    print '   for (qy = 0; qy < h; qy += TILE_VECTOR_HEIGHT) {'
+    print '   for (qy = 0; qy < TILE_SIZE; qy += TILE_VECTOR_HEIGHT) {'
     print '      const unsigned py = y0 + qy;'
-    print '      for (qx = 0; qx < w; qx += TILE_VECTOR_WIDTH) {'
+    print '      for (qx = 0; qx < TILE_SIZE; qx += TILE_VECTOR_WIDTH) {'
     print '         const unsigned px = x0 + qx;'
     print '         const uint8_t *r = src + 0 * TILE_C_STRIDE;'
     print '         const uint8_t *g = src + 1 * TILE_C_STRIDE;'
@@ -231,9 +231,9 @@ def emit_tile_pixel_unswizzle_code(format, src_channel):
 
     print '   unsigned x, y;'
     print '   uint8_t *dst_row = dst + y0*dst_stride;'
-    print '   for (y = 0; y < h; ++y) {'
+    print '   for (y = 0; y < TILE_SIZE; ++y) {'
     print '      %s *dst_pixel = (%s *)(dst_row + x0*%u);' % (dst_native_type, dst_native_type, format.stride())
-    print '      for (x = 0; x < w; ++x) {'
+    print '      for (x = 0; x < TILE_SIZE; ++x) {'
 
     if format.layout == PLAIN:
         if not format.is_array():
@@ -273,7 +273,7 @@ def generate_format_write(format, src_channel, src_native_type, src_suffix):
     name = format.short_name()
 
     print 'static void'
-    print 'lp_tile_%s_unswizzle_%s(const %s *src, uint8_t *dst, unsigned dst_stride, unsigned x0, unsigned y0, unsigned w, unsigned h)' % (name, src_suffix, src_native_type)
+    print 'lp_tile_%s_unswizzle_%s(const %s *src, uint8_t *dst, unsigned dst_stride, unsigned x0, unsigned y0)' % (name, src_suffix, src_native_type)
     print '{'
     if format.layout == PLAIN \
         and format.colorspace == 'rgb' \
@@ -289,6 +289,202 @@ def generate_format_write(format, src_channel, src_native_type, src_suffix):
     print
     
 
+def generate_ssse3():
+    print '''
+#if defined(PIPE_ARCH_SSE)
+
+
+#if defined(PIPE_ARCH_SSSE3)
+
+#include <tmmintrin.h>
+
+#else
+
+#include <emmintrin.h>
+
+/**
+ * Describe _mm_shuffle_epi8() with gcc extended inline assembly, for cases
+ * where -mssse3 is not supported/enabled.
+ *
+ * MSVC will never get in here as its intrinsics support do not rely on
+ * compiler command line options.
+ */
+static __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_shuffle_epi8(__m128i a, __m128i mask)
+{
+    __m128i result;
+    __asm__("pshufb %1, %0"
+            : "=x" (result)
+            : "xm" (mask), "0" (a));
+    return result;
+}
+
+#endif
+
+
+static void
+lp_tile_b8g8r8a8_unorm_swizzle_4ub_ssse3(uint8_t *dst,
+                                         const uint8_t *src, unsigned src_stride,
+                                         unsigned x0, unsigned y0)
+{
+
+   unsigned x, y;
+   __m128i *pdst = (__m128i*) dst;
+   const uint8_t *ysrc0 = src + y0*src_stride + x0*sizeof(uint32_t);
+   unsigned int tile_stridex = src_stride*(TILE_VECTOR_HEIGHT - 1) - sizeof(uint32_t)*TILE_VECTOR_WIDTH;
+   unsigned int tile_stridey = src_stride*TILE_VECTOR_HEIGHT;
+
+   const __m128i shuffle00 = _mm_setr_epi8(0x02,0x06,0xff,0xff,0x0a,0x0e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff);
+   const __m128i shuffle01 = _mm_setr_epi8(0x01,0x05,0xff,0xff,0x09,0x0d,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff);
+   const __m128i shuffle02 = _mm_setr_epi8(0x00,0x04,0xff,0xff,0x08,0x0c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff);
+   const __m128i shuffle03 = _mm_setr_epi8(0x03,0x07,0xff,0xff,0x0b,0x0f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff);
+
+   const __m128i shuffle10 = _mm_setr_epi8(0xff,0xff,0x02,0x06,0xff,0xff,0x0a,0x0e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff);
+   const __m128i shuffle11 = _mm_setr_epi8(0xff,0xff,0x01,0x05,0xff,0xff,0x09,0x0d,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff);
+   const __m128i shuffle12 = _mm_setr_epi8(0xff,0xff,0x00,0x04,0xff,0xff,0x08,0x0c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff);
+   const __m128i shuffle13 = _mm_setr_epi8(0xff,0xff,0x03,0x07,0xff,0xff,0x0b,0x0f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff);
+
+   const __m128i shuffle20 = _mm_setr_epi8(0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x02,0x06,0xff,0xff,0x0a,0x0e,0xff,0xff);
+   const __m128i shuffle21 = _mm_setr_epi8(0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x05,0xff,0xff,0x09,0x0d,0xff,0xff);
+   const __m128i shuffle22 = _mm_setr_epi8(0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x04,0xff,0xff,0x08,0x0c,0xff,0xff);
+   const __m128i shuffle23 = _mm_setr_epi8(0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x07,0xff,0xff,0x0b,0x0f,0xff,0xff);
+
+   const __m128i shuffle30 = _mm_setr_epi8(0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x02,0x06,0xff,0xff,0x0a,0x0e);
+   const __m128i shuffle31 = _mm_setr_epi8(0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x05,0xff,0xff,0x09,0x0d);
+   const __m128i shuffle32 = _mm_setr_epi8(0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x04,0xff,0xff,0x08,0x0c);
+   const __m128i shuffle33 = _mm_setr_epi8(0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x07,0xff,0xff,0x0b,0x0f);
+
+   for (y = 0; y < TILE_SIZE; y += TILE_VECTOR_HEIGHT) {
+      __m128i line0 = *(__m128i*)ysrc0;
+      const uint8_t *ysrc = ysrc0 + src_stride;
+      ysrc0 += tile_stridey;
+
+      for (x = 0; x < TILE_SIZE; x += TILE_VECTOR_WIDTH) {
+         __m128i r, g, b, a, line1;
+         line1 = *(__m128i*)ysrc;
+         PIPE_READ_WRITE_BARRIER();
+         ysrc += src_stride;
+         r = _mm_shuffle_epi8(line0, shuffle00);
+         g = _mm_shuffle_epi8(line0, shuffle01);
+         b = _mm_shuffle_epi8(line0, shuffle02);
+         a = _mm_shuffle_epi8(line0, shuffle03);
+
+         line0 = *(__m128i*)ysrc;
+         PIPE_READ_WRITE_BARRIER();
+         ysrc += src_stride;
+         r = _mm_or_si128(r, _mm_shuffle_epi8(line1, shuffle10));
+         g = _mm_or_si128(g, _mm_shuffle_epi8(line1, shuffle11));
+         b = _mm_or_si128(b, _mm_shuffle_epi8(line1, shuffle12));
+         a = _mm_or_si128(a, _mm_shuffle_epi8(line1, shuffle13));
+
+         line1 = *(__m128i*)ysrc;
+         PIPE_READ_WRITE_BARRIER();
+         ysrc -= tile_stridex;
+         r = _mm_or_si128(r, _mm_shuffle_epi8(line0, shuffle20));
+         g = _mm_or_si128(g, _mm_shuffle_epi8(line0, shuffle21));
+         b = _mm_or_si128(b, _mm_shuffle_epi8(line0, shuffle22));
+         a = _mm_or_si128(a, _mm_shuffle_epi8(line0, shuffle23));
+
+         if (x + 1 < TILE_SIZE) {
+            line0 = *(__m128i*)ysrc;
+            ysrc += src_stride;
+         }
+
+         PIPE_READ_WRITE_BARRIER();
+         r = _mm_or_si128(r, _mm_shuffle_epi8(line1, shuffle30));
+         g = _mm_or_si128(g, _mm_shuffle_epi8(line1, shuffle31));
+         b = _mm_or_si128(b, _mm_shuffle_epi8(line1, shuffle32));
+         a = _mm_or_si128(a, _mm_shuffle_epi8(line1, shuffle33));
+
+         *pdst++ = r;
+         *pdst++ = g;
+         *pdst++ = b;
+         *pdst++ = a;
+      }
+   }
+
+}
+
+static void
+lp_tile_b8g8r8a8_unorm_unswizzle_4ub_ssse3(const uint8_t *src,
+                                          uint8_t *dst, unsigned dst_stride,
+                                          unsigned x0, unsigned y0)
+{
+   unsigned int x, y;
+   const __m128i *psrc = (__m128i*) src;
+   const __m128i *end = (__m128i*) (src + (y0 + TILE_SIZE - 1)*dst_stride + (x0 + TILE_SIZE - 1)*sizeof(uint32_t));
+   uint8_t *pdst = dst + y0 * dst_stride + x0 * sizeof(uint32_t);
+   __m128i c0 = *psrc++;
+   __m128i c1;
+
+   const __m128i shuffle00 = _mm_setr_epi8(0xff,0xff,0x00,0xff,0xff,0xff,0x01,0xff,0xff,0xff,0x04,0xff,0xff,0xff,0x05,0xff);
+   const __m128i shuffle01 = _mm_setr_epi8(0xff,0xff,0x02,0xff,0xff,0xff,0x03,0xff,0xff,0xff,0x06,0xff,0xff,0xff,0x07,0xff);
+   const __m128i shuffle02 = _mm_setr_epi8(0xff,0xff,0x08,0xff,0xff,0xff,0x09,0xff,0xff,0xff,0x0c,0xff,0xff,0xff,0x0d,0xff);
+   const __m128i shuffle03 = _mm_setr_epi8(0xff,0xff,0x0a,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff);
+
+   const __m128i shuffle10 = _mm_setr_epi8(0xff,0x00,0xff,0xff,0xff,0x01,0xff,0xff,0xff,0x04,0xff,0xff,0xff,0x05,0xff,0xff);
+   const __m128i shuffle11 = _mm_setr_epi8(0xff,0x02,0xff,0xff,0xff,0x03,0xff,0xff,0xff,0x06,0xff,0xff,0xff,0x07,0xff,0xff);
+   const __m128i shuffle12 = _mm_setr_epi8(0xff,0x08,0xff,0xff,0xff,0x09,0xff,0xff,0xff,0x0c,0xff,0xff,0xff,0x0d,0xff,0xff);
+   const __m128i shuffle13 = _mm_setr_epi8(0xff,0x0a,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,0xff);
+
+   const __m128i shuffle20 = _mm_setr_epi8(0x00,0xff,0xff,0xff,0x01,0xff,0xff,0xff,0x04,0xff,0xff,0xff,0x05,0xff,0xff,0xff);
+   const __m128i shuffle21 = _mm_setr_epi8(0x02,0xff,0xff,0xff,0x03,0xff,0xff,0xff,0x06,0xff,0xff,0xff,0x07,0xff,0xff,0xff);
+   const __m128i shuffle22 = _mm_setr_epi8(0x08,0xff,0xff,0xff,0x09,0xff,0xff,0xff,0x0c,0xff,0xff,0xff,0x0d,0xff,0xff,0xff);
+   const __m128i shuffle23 = _mm_setr_epi8(0x0a,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0x0e,0xff,0xff,0xff,0x0f,0xff,0xff,0xff);
+
+   const __m128i shuffle30 = _mm_setr_epi8(0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x01,0xff,0xff,0xff,0x04,0xff,0xff,0xff,0x05);
+   const __m128i shuffle31 = _mm_setr_epi8(0xff,0xff,0xff,0x02,0xff,0xff,0xff,0x03,0xff,0xff,0xff,0x06,0xff,0xff,0xff,0x07);
+   const __m128i shuffle32 = _mm_setr_epi8(0xff,0xff,0xff,0x08,0xff,0xff,0xff,0x09,0xff,0xff,0xff,0x0c,0xff,0xff,0xff,0x0d);
+   const __m128i shuffle33 = _mm_setr_epi8(0xff,0xff,0xff,0x0a,0xff,0xff,0xff,0x0b,0xff,0xff,0xff,0x0e,0xff,0xff,0xff,0x0f);
+
+   for (y = 0; y < TILE_SIZE; y += TILE_VECTOR_HEIGHT) {
+      __m128i *tile = (__m128i*) pdst;
+      pdst += dst_stride * TILE_VECTOR_HEIGHT;
+      for (x = 0; x < TILE_SIZE; x += TILE_VECTOR_WIDTH) {
+         uint8_t *linep = (uint8_t*) (tile++);
+         __m128i line0, line1, line2, line3;
+
+         c1 = *psrc++; /* r */
+         PIPE_READ_WRITE_BARRIER();
+         line0 = _mm_shuffle_epi8(c0, shuffle00);
+         line1 = _mm_shuffle_epi8(c0, shuffle01);
+         line2 = _mm_shuffle_epi8(c0, shuffle02);
+         line3 = _mm_shuffle_epi8(c0, shuffle03);
+
+         c0 = *psrc++; /* g */
+         PIPE_READ_WRITE_BARRIER();
+         line0 = _mm_or_si128(line0, _mm_shuffle_epi8(c1, shuffle10));
+         line1 = _mm_or_si128(line1, _mm_shuffle_epi8(c1, shuffle11));
+         line2 = _mm_or_si128(line2, _mm_shuffle_epi8(c1, shuffle12));
+         line3 = _mm_or_si128(line3, _mm_shuffle_epi8(c1, shuffle13));
+
+         c1 = *psrc++; /* b */
+         PIPE_READ_WRITE_BARRIER();
+         line0 = _mm_or_si128(line0, _mm_shuffle_epi8(c0, shuffle20));
+         line1 = _mm_or_si128(line1, _mm_shuffle_epi8(c0, shuffle21));
+         line2 = _mm_or_si128(line2, _mm_shuffle_epi8(c0, shuffle22));
+         line3 = _mm_or_si128(line3, _mm_shuffle_epi8(c0, shuffle23));
+
+         if (psrc != end)
+                 c0 = *psrc++; /* a */
+         PIPE_READ_WRITE_BARRIER();
+         line0 = _mm_or_si128(line0, _mm_shuffle_epi8(c1, shuffle30));
+         line1 = _mm_or_si128(line1, _mm_shuffle_epi8(c1, shuffle31));
+         line2 = _mm_or_si128(line2, _mm_shuffle_epi8(c1, shuffle32));
+         line3 = _mm_or_si128(line3, _mm_shuffle_epi8(c1, shuffle33));
+
+         *(__m128i*) (linep) = line0;
+         *(__m128i*) (((char*)linep) + dst_stride) = line1;
+         *(__m128i*) (((char*)linep) + 2 * dst_stride) = line2;
+         *(__m128i*) (((char*)linep) + 3 * dst_stride) = line3;
+      }
+   }
+}
+
+#endif /* PIPE_ARCH_SSSE3 */
+'''
+
+
 def generate_swizzle(formats, dst_channel, dst_native_type, dst_suffix):
     '''Generate the dispatch function to read pixels from any format'''
 
@@ -297,9 +493,9 @@ def generate_swizzle(formats, dst_channel, dst_native_type, dst_suffix):
             generate_format_read(format, dst_channel, dst_native_type, dst_suffix)
 
     print 'void'
-    print 'lp_tile_swizzle_%s(enum pipe_format format, %s *dst, const void *src, unsigned src_stride, unsigned x, unsigned y, unsigned w, unsigned h)' % (dst_suffix, dst_native_type)
+    print 'lp_tile_swizzle_%s(enum pipe_format format, %s *dst, const void *src, unsigned src_stride, unsigned x, unsigned y)' % (dst_suffix, dst_native_type)
     print '{'
-    print '   void (*func)(%s *dst, const uint8_t *src, unsigned src_stride, unsigned x0, unsigned y0, unsigned w, unsigned h);' % dst_native_type
+    print '   void (*func)(%s *dst, const uint8_t *src, unsigned src_stride, unsigned x0, unsigned y0);' % dst_native_type
     print '#ifdef DEBUG'
     print '   lp_tile_swizzle_count += 1;'
     print '#endif'
@@ -307,13 +503,21 @@ def generate_swizzle(formats, dst_channel, dst_native_type, dst_suffix):
     for format in formats:
         if is_format_supported(format):
             print '   case %s:' % format.name
-            print '      func = &lp_tile_%s_swizzle_%s;' % (format.short_name(), dst_suffix)
+            func_name = 'lp_tile_%s_swizzle_%s' % (format.short_name(), dst_suffix)
+            if format.name == 'PIPE_FORMAT_B8G8R8A8_UNORM':
+                print '#ifdef PIPE_ARCH_SSE'
+                print '      func = util_cpu_caps.has_ssse3 ? %s_ssse3 : %s;' % (func_name, func_name)
+                print '#else'
+                print '      func = %s;' % (func_name,)
+                print '#endif'
+            else:
+                print '      func = %s;' % (func_name,)
             print '      break;'
     print '   default:'
     print '      debug_printf("%s: unsupported format %s\\n", __FUNCTION__, util_format_name(format));'
     print '      return;'
     print '   }'
-    print '   func(dst, (const uint8_t *)src, src_stride, x, y, w, h);'
+    print '   func(dst, (const uint8_t *)src, src_stride, x, y);'
     print '}'
     print
 
@@ -326,10 +530,10 @@ def generate_unswizzle(formats, src_channel, src_native_type, src_suffix):
             generate_format_write(format, src_channel, src_native_type, src_suffix)
 
     print 'void'
-    print 'lp_tile_unswizzle_%s(enum pipe_format format, const %s *src, void *dst, unsigned dst_stride, unsigned x, unsigned y, unsigned w, unsigned h)' % (src_suffix, src_native_type)
+    print 'lp_tile_unswizzle_%s(enum pipe_format format, const %s *src, void *dst, unsigned dst_stride, unsigned x, unsigned y)' % (src_suffix, src_native_type)
     
     print '{'
-    print '   void (*func)(const %s *src, uint8_t *dst, unsigned dst_stride, unsigned x0, unsigned y0, unsigned w, unsigned h);' % src_native_type
+    print '   void (*func)(const %s *src, uint8_t *dst, unsigned dst_stride, unsigned x0, unsigned y0);' % src_native_type
     print '#ifdef DEBUG'
     print '   lp_tile_unswizzle_count += 1;'
     print '#endif'
@@ -337,13 +541,21 @@ def generate_unswizzle(formats, src_channel, src_native_type, src_suffix):
     for format in formats:
         if is_format_supported(format):
             print '   case %s:' % format.name
-            print '      func = &lp_tile_%s_unswizzle_%s;' % (format.short_name(), src_suffix)
+            func_name = 'lp_tile_%s_unswizzle_%s' % (format.short_name(), src_suffix)
+            if format.name == 'PIPE_FORMAT_B8G8R8A8_UNORM':
+                print '#ifdef PIPE_ARCH_SSE'
+                print '      func = util_cpu_caps.has_ssse3 ? %s_ssse3 : %s;' % (func_name, func_name)
+                print '#else'
+                print '      func = %s;' % (func_name,)
+                print '#endif'
+            else:
+                print '      func = %s;' % (func_name,)
             print '      break;'
     print '   default:'
     print '      debug_printf("%s: unsupported format %s\\n", __FUNCTION__, util_format_name(format));'
     print '      return;'
     print '   }'
-    print '   func(src, (uint8_t *)dst, dst_stride, x, y, w, h);'
+    print '   func(src, (uint8_t *)dst, dst_stride, x, y);'
     print '}'
     print
 
@@ -362,6 +574,7 @@ def main():
     print '#include "util/u_format.h"'
     print '#include "util/u_math.h"'
     print '#include "util/u_half.h"'
+    print '#include "util/u_cpu_detect.h"'
     print '#include "lp_tile_soa.h"'
     print
     print '#ifdef DEBUG'
@@ -391,6 +604,8 @@ def main():
     print '};'
     print
 
+    generate_ssse3()
+
     channel = Channel(UNSIGNED, True, 8)
     native_type = 'uint8_t'
     suffix = '4ub'
index 60bdd7276aa5b9b65126314f581473b8d514cd7e..513e5e02bc05ab834b0f0c48d05532d978b752b0 100644 (file)
@@ -6,6 +6,7 @@
 #include "util/u_inlines.h"
 #include "util/u_format.h"
 #include "util/u_format_s3tc.h"
+#include "util/u_string.h"
 
 #include <stdio.h>
 #include <errno.h>
@@ -15,7 +16,7 @@
 #include "nouveau_screen.h"
 
 /* XXX this should go away */
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drm_driver.h"
 #include "util/u_simple_screen.h"
 
 static const char *
@@ -24,7 +25,7 @@ nouveau_screen_get_name(struct pipe_screen *pscreen)
        struct nouveau_device *dev = nouveau_screen(pscreen)->device;
        static char buffer[128];
 
-       snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset);
+       util_snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset);
        return buffer;
 }
 
@@ -181,7 +182,7 @@ nouveau_screen_bo_from_handle(struct pipe_screen *pscreen,
        ret = nouveau_bo_handle_ref(dev, whandle->handle, &bo);
        if (ret) {
                debug_printf("%s: ref name 0x%08x failed with %d\n",
-                            __func__, whandle->handle, ret);
+                            __FUNCTION__, whandle->handle, ret);
                return NULL;
        }
 
index 8eacdff035815b64ebafcb7afe8521f86c9782be..8c290273fb4597537cefb0940378af01083b4b47 100644 (file)
@@ -14,7 +14,7 @@ struct nouveau_screen {
        unsigned index_buffer_flags;
 };
 
-static inline struct nouveau_screen *
+static INLINE struct nouveau_screen *
 nouveau_screen(struct pipe_screen *pscreen)
 {
        return (struct nouveau_screen *)pscreen;
@@ -67,13 +67,13 @@ void nouveau_screen_fini(struct nouveau_screen *);
 
 
 
-static __inline__ unsigned
+static INLINE unsigned
 RING_3D(unsigned mthd, unsigned size)
 {
        return (7 << 13) | (size << 18) | mthd;
 }
 
-static __inline__ unsigned
+static INLINE unsigned
 RING_3D_NI(unsigned mthd, unsigned size)
 {
        return 0x40000000 | (7 << 13) | (size << 18) | mthd;
index ed6e643785db8ae6c9a61fd83040fd04feea07e1..a5e8537533e7d97e18ef5be296a3df0a41814a34 100644 (file)
@@ -103,7 +103,7 @@ struct u_split_prim {
    uint edgeflag_off:1;
 };
 
-static inline void
+static INLINE void
 u_split_prim_init(struct u_split_prim *s,
                   unsigned mode, unsigned start, unsigned count)
 {
index cd7da9977d8e0eaea6b56688272f0848df181518..df79ca89ca1dad29fcad3f8ef2efba5bd2d9ccce 100644 (file)
@@ -13,7 +13,7 @@
 #include "nouveau/nouveau_resource.h"
 #include "nouveau/nouveau_pushbuf.h"
 
-static inline uint32_t
+static INLINE uint32_t
 nouveau_screen_transfer_flags(unsigned pipe)
 {
        uint32_t flags = 0;
index 61807dd999be49a0d04a92115d01f8ed99d79ed1..12c4a93a9bd4ed2ba1574dfc3c45cc21ec915df2 100644 (file)
@@ -21,7 +21,7 @@
 #include "nv50_program.h"
 
 #define NOUVEAU_ERR(fmt, args...) \
-       fprintf(stderr, "%s:%d -  "fmt, __func__, __LINE__, ##args);
+       fprintf(stderr, "%s:%d -  "fmt, __FUNCTION__, __LINE__, ##args);
 #define NOUVEAU_MSG(fmt, args...) \
        fprintf(stderr, "nouveau: "fmt, ##args);
 
@@ -50,6 +50,7 @@
 #define NV50_NEW_SAMPLER       (1 << 15)
 #define NV50_NEW_TEXTURE       (1 << 16)
 #define NV50_NEW_STENCIL_REF   (1 << 17)
+#define NV50_NEW_CLIP          (1 << 18)
 
 struct nv50_blend_stateobj {
        struct pipe_blend_state pipe;
@@ -140,6 +141,7 @@ struct nv50_context {
        struct pipe_scissor_state scissor;
        struct pipe_viewport_state viewport;
        struct pipe_framebuffer_state framebuffer;
+       struct pipe_clip_state clip;
        struct nv50_program *vertprog;
        struct nv50_program *fragprog;
        struct nv50_program *geomprog;
index 21908bcd3c22da289482ce28373ad488d8411676..ca4b01b12b3fc54b8370b6d983af65a0b718ba2a 100644 (file)
@@ -186,6 +186,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
        case PIPE_CAP_MAX_VS_TEMPS:
        case PIPE_CAP_MAX_FS_TEMPS: /* no spilling atm */
                return 128 / 4;
+       case PIPE_CAP_DEPTH_CLAMP:
+               return 1;
        default:
                NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
                return 0;
@@ -525,6 +527,9 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
        OUT_RINGf (chan, 0.0f);
        OUT_RINGf (chan, 1.0f);
 
+       BEGIN_RING(chan, screen->tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
+       OUT_RING  (chan, 1);
+
        /* no dynamic combination of TIC & TSC entries => only BIND_TIC used */
        BEGIN_RING(chan, screen->tesla, NV50TCL_LINKED_TSC, 1);
        OUT_RING  (chan, 1);
index f8bff764f27ab2ac626b5c5ff9a5e93fc8cc2d81..42c5a5831893a8769617defbd3f6380a0b6ac88d 100644 (file)
@@ -658,6 +658,10 @@ static void
 nv50_set_clip_state(struct pipe_context *pipe,
                    const struct pipe_clip_state *clip)
 {
+       struct nv50_context *nv50 = nv50_context(pipe);
+
+       nv50->clip.depth_clamp = clip->depth_clamp;
+       nv50->dirty |= NV50_NEW_CLIP;
 }
 
 static void
index 14c3490599dc75d800a5819642f0976862a8b9f0..524696f35d16be45858819a864ac812df68891b9 100644 (file)
@@ -277,7 +277,7 @@ static struct nouveau_stateobj *
 validate_viewport(struct nv50_context *nv50)
 {
        struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct nouveau_stateobj *so = so_new(5, 9, 0);
+       struct nouveau_stateobj *so = so_new(3, 7, 0);
 
        so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE_X(0), 3);
        so_data  (so, fui(nv50->viewport.translate[0]));
@@ -288,15 +288,6 @@ validate_viewport(struct nv50_context *nv50)
        so_data  (so, fui(nv50->viewport.scale[1]));
        so_data  (so, fui(nv50->viewport.scale[2]));
 
-       so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
-       so_data  (so, 1);
-       /* 0x0000 = remove whole primitive only (xyz)
-        * 0x1018 = remove whole primitive only (xy), clamp z
-        * 0x1080 = clip primitive (xyz)
-        * 0x1098 = clip primitive (xy), clamp z
-        */
-       so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
-       so_data  (so, 0x1080);
        /* no idea what 0f90 does */
        so_method(so, tesla, 0x0f90, 1);
        so_data  (so, 0);
@@ -341,6 +332,26 @@ validate_vtxattr(struct nv50_context *nv50)
        return so;
 }
 
+static struct nouveau_stateobj *
+validate_clip(struct nv50_context *nv50)
+{
+       struct nouveau_grobj *tesla = nv50->screen->tesla;
+       struct nouveau_stateobj *so = so_new(1, 1, 0);
+       uint32_t vvcc;
+
+       /* 0x0000 = remove whole primitive only (xyz)
+        * 0x1018 = remove whole primitive only (xy), clamp z
+        * 0x1080 = clip primitive (xyz)
+        * 0x1098 = clip primitive (xy), clamp z
+        */
+       vvcc = nv50->clip.depth_clamp ? 0x1098 : 0x1080;
+
+       so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
+       so_data  (so, vvcc);
+
+       return so;
+}
+
 struct state_validate {
        struct nouveau_stateobj *(*func)(struct nv50_context *nv50);
        unsigned states;
@@ -365,6 +376,7 @@ struct state_validate {
        { nv50_vbo_validate       , NV50_NEW_ARRAYS                           },
        { validate_vtxbuf         , NV50_NEW_ARRAYS                           },
        { validate_vtxattr        , NV50_NEW_ARRAYS                           },
+       { validate_clip           , NV50_NEW_CLIP                             },
        {}
 };
 #define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
index 6772d9bd5160a28ded16642feb4ed0eb8c8cfc2f..ee41f03b9b8fd7064f64ff75efeb63f266c427c5 100644 (file)
@@ -842,7 +842,6 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx)
        struct nouveau_channel* chan = nvfx->screen->base.channel;
        struct nvfx_fragment_program *fp = nvfx->fragprog;
        int update = 0;
-       int i;
 
        if (!fp->translated)
        {
@@ -895,6 +894,7 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx)
                        {
                                struct nvfx_fragment_program_bo* fpbo = os_malloc_aligned(sizeof(struct nvfx_fragment_program) + fp->prog_size * fp->progs_per_bo, 16);
                                char *map, *buf;
+                               int i;
 
                                if(fp->fpbo)
                                {
@@ -910,7 +910,7 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx)
 
                                map = fpbo->bo->map;
                                buf = fpbo->insn;
-                               for(int i = 0; i < fp->progs_per_bo; ++i)
+                               for(i = 0; i < fp->progs_per_bo; ++i)
                                {
                                        memcpy(buf, fp->insn, fp->insn_len * 4);
                                        nvfx_fp_memcpy(map, fp->insn, fp->insn_len * 4);
@@ -931,6 +931,7 @@ nvfx_fragprog_validate(struct nvfx_context *nvfx)
                        uint32_t* map = pipe_buffer_map(&nvfx->pipe, constbuf, PIPE_TRANSFER_READ, &transfer);
                        uint32_t* fpmap = (uint32_t*)((char*)fp->fpbo->bo->map + offset);
                        uint32_t* buf = (uint32_t*)((char*)fp->fpbo->insn + offset);
+                       int i;
                        for (i = 0; i < fp->nr_consts; ++i) {
                                unsigned off = fp->consts[i].offset;
                                unsigned idx = fp->consts[i].index * 4;
index a78d2411a05994d0cfc4d98350bebee3a9ee8ad5..80db28a07cb27dbfc6de21c32f2833b35371e1ce 100644 (file)
@@ -56,6 +56,8 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
                return 0;
        case PIPE_CAP_TEXTURE_SHADOW_MAP:
                return 1;
+       case PIPE_CAP_TEXTURE_SWIZZLE:
+               return 1;
        case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
                return 13;
        case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
@@ -127,6 +129,8 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
                return 2;
        case PIPE_CAP_MAX_VS_PREDS:
                return screen->is_nv4x ? 1 : 0;
+       case PIPE_CAP_GEOMETRY_SHADER4:
+               return 0;
        default:
                NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
                return 0;
index dd897f6072fb646912685af14d252bb70a74068c..728bc40a5bb269647a6e85e7296f9b55718d86e5 100644 (file)
@@ -21,10 +21,10 @@ C_SOURCES = \
        r300_screen_buffer.c \
        r300_state.c \
        r300_state_derived.c \
-       r300_state_invariant.c \
        r300_vs.c \
        r300_vs_draw.c \
        r300_texture.c \
+       r300_texture_desc.c \
        r300_tgsi_to_rc.c \
        r300_transfer.c
 
index ee19e9d27837179f9bbab0d2150d04ec161c23a2..bf023daaa56c9687d1ac73cbf000a00f38987945 100644 (file)
@@ -31,10 +31,10 @@ r300 = env.ConvenienceLibrary(
         'r300_screen_buffer.c',
         'r300_state.c',
         'r300_state_derived.c',
-        'r300_state_invariant.c',
         'r300_vs.c',
         'r300_vs_draw.c',
         'r300_texture.c',
+        'r300_texture_desc.c',
         'r300_tgsi_to_rc.c',
         'r300_transfer.c',
     ] + r300compiler) + r300compiler
index 2a4770129124ed6aa3c419142f81b893404bdbfd..d125196b6dc9e869bf3bb003d13cdcfbe8dd77c3 100644 (file)
 #include "r300_texture.h"
 
 #include "util/u_format.h"
+#include "util/u_pack_color.h"
 
-enum r300_blitter_op
+enum r300_blitter_op /* bitmask */
 {
-    R300_CLEAR,
-    R300_CLEAR_SURFACE,
-    R300_COPY
+    R300_CLEAR         = 1,
+    R300_CLEAR_SURFACE = 2,
+    R300_COPY          = 4
 };
 
 static void r300_blitter_begin(struct r300_context* r300, enum r300_blitter_op op)
@@ -79,6 +80,31 @@ static void r300_blitter_end(struct r300_context *r300)
     }
 }
 
+static uint32_t r300_depth_clear_cb_value(enum pipe_format format,
+                                         const float* rgba)
+{
+    union util_color uc;
+    util_pack_color(rgba, format, &uc);
+
+    if (util_format_get_blocksizebits(format) == 32)
+        return uc.ui;
+    else
+        return uc.us | (uc.us << 16);
+}
+
+static boolean r300_cbzb_clear_allowed(struct r300_context *r300,
+                                       unsigned clear_buffers)
+{
+    struct pipe_framebuffer_state *fb =
+        (struct pipe_framebuffer_state*)r300->fb_state.state;
+
+    /* Only color clear allowed, and only one colorbuffer. */
+    if (clear_buffers != PIPE_CLEAR_COLOR || fb->nr_cbufs != 1)
+        return FALSE;
+
+    return r300_surface(fb->cbufs[0])->cbzb_allowed;
+}
+
 /* Clear currently bound buffers. */
 static void r300_clear(struct pipe_context* pipe,
                        unsigned buffers,
@@ -86,39 +112,81 @@ static void r300_clear(struct pipe_context* pipe,
                        double depth,
                        unsigned stencil)
 {
-    /* XXX Implement fastfill.
+    /* My notes about fastfill:
+     *
+     * 1) Only the zbuffer is cleared.
+     *
+     * 2) The zbuffer must be micro-tiled and whole microtiles must be
+     *    written. If microtiling is disabled, it locks up.
      *
-     * If fastfill is enabled, a few facts should be considered:
+     * 3) There is Z Mask RAM which contains a compressed zbuffer and
+     *    it interacts with fastfill. We should figure out how to use it
+     *    to get more performance.
+     *    This is what we know about the Z Mask:
      *
-     * 1) Zbuffer must be micro-tiled and whole microtiles must be
-     *    written.
+     *       Each dword of the Z Mask contains compression information
+     *       for 16 4x4 pixel blocks, that is 2 bits for each block.
+     *       On chips with 2 Z pipes, every other dword maps to a different
+     *       pipe.
      *
-     * 2) ZB_DEPTHCLEARVALUE is used to clear a zbuffer and Z Mask must be
-     *    equal to 0.
+     * 4) ZB_DEPTHCLEARVALUE is used to clear the zbuffer and the Z Mask must
+     *    be equal to 0. (clear the Z Mask RAM with zeros)
      *
-     * 3) For 16-bit integer buffering, compression causes a hung with one or
+     * 5) For 16-bit zbuffer, compression causes a hung with one or
      *    two samples and should not be used.
      *
-     * 4) Fastfill must not be used if reading of compressed Z data is disabled
+     * 6) FORCE_COMPRESSED_STENCIL_VALUE should be enabled for stencil clears
+     *    to avoid needless decompression.
+     *
+     * 7) Fastfill must not be used if reading of compressed Z data is disabled
      *    and writing of compressed Z data is enabled (RD/WR_COMP_ENABLE),
      *    i.e. it cannot be used to compress the zbuffer.
-     *    (what the hell does that mean and how does it fit in clearing
-     *    the buffers?)
+     *
+     * 8) ZB_CB_CLEAR does not interact with fastfill in any way.
      *
      * - Marek
      */
 
     struct r300_context* r300 = r300_context(pipe);
-    struct pipe_framebuffer_statefb =
+    struct pipe_framebuffer_state *fb =
         (struct pipe_framebuffer_state*)r300->fb_state.state;
+    struct r300_hyperz_state *hyperz =
+        (struct r300_hyperz_state*)r300->hyperz_state.state;
+    uint32_t width = fb->width;
+    uint32_t height = fb->height;
+
+    /* Enable CBZB clear. */
+    if (r300_cbzb_clear_allowed(r300, buffers)) {
+        struct r300_surface *surf = r300_surface(fb->cbufs[0]);
+
+        hyperz->zb_depthclearvalue =
+                r300_depth_clear_cb_value(surf->base.format, rgba);
+
+        width = surf->cbzb_width;
+        height = surf->cbzb_height;
+
+        r300->cbzb_clear = TRUE;
+        r300_mark_fb_state_dirty(r300, R300_CHANGED_CBZB_FLAG);
+    }
 
+    /* Clear. */
     r300_blitter_begin(r300, R300_CLEAR);
     util_blitter_clear(r300->blitter,
-                       fb->width,
-                       fb->height,
+                       width,
+                       height,
                        fb->nr_cbufs,
                        buffers, rgba, depth, stencil);
     r300_blitter_end(r300);
+
+    /* Disable CBZB clear. */
+    if (r300->cbzb_clear) {
+        r300->cbzb_clear = FALSE;
+        r300_mark_fb_state_dirty(r300, R300_CHANGED_CBZB_FLAG);
+    }
+
+    /* XXX this flush "fixes" a hardlock in the cubestorm xscreensaver */
+    if (r300->flush_counter == 0)
+        pipe->flush(pipe, 0, NULL);
 }
 
 /* Clear a region of a color surface to a constant value. */
@@ -185,14 +253,6 @@ static void r300_resource_copy_region(struct pipe_context *pipe,
     enum pipe_format old_format = dst->format;
     enum pipe_format new_format = old_format;
 
-    if (dst->format != src->format) {
-        debug_printf("r300: Implementation error: Format mismatch in %s\n"
-            "    : src: %s dst: %s\n", __FUNCTION__,
-            util_format_short_name(src->format),
-            util_format_short_name(dst->format));
-        debug_assert(0);
-    }
-
     if (!pipe->screen->is_format_supported(pipe->screen,
                                            old_format, src->target,
                                            src->nr_samples,
index 69874712442401f5ff914369b00da7c979c8c6b7..9d3d4fc1b19843a2028d404f1d3843a66d439cd0 100644 (file)
@@ -89,9 +89,6 @@
     CB_DEBUG(cs_count = size;) \
 } while (0)
 
-#define BEGIN_CS_AS_CB(r300, size) \
-    BEGIN_CB(r300->rws->get_cs_pointer(r300->rws, dwords), dwords)
-
 #define END_CB do { \
     CB_DEBUG(if (cs_count != 0) \
         debug_printf("r300: Warning: cs_count off by %d at (%s, %s:%i)\n", \
index e6dca66d4a0ed6179770944c86d9f0776a7bb815..21f3b9d2610eec4800ed2a798d039bf44dc0ccfc 100644 (file)
@@ -36,6 +36,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)
     caps->num_vert_fpus = 2;
     caps->num_tex_units = 16;
     caps->has_tcl = debug_get_bool_option("RADEON_NO_TCL", FALSE) ? FALSE : TRUE;
+    caps->has_hiz = TRUE;
     caps->is_r400 = FALSE;
     caps->is_r500 = FALSE;
     caps->high_second_pipe = FALSE;
@@ -76,6 +77,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)
         case 0x4E54:
         case 0x4E56:
             caps->family = CHIP_FAMILY_RV350;
+            caps->has_hiz = FALSE;
             caps->high_second_pipe = TRUE;
             break;
 
@@ -106,6 +108,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)
         case 0x5B64:
         case 0x5B65:
             caps->family = CHIP_FAMILY_RV370;
+            caps->has_hiz = FALSE;
             caps->high_second_pipe = TRUE;
             break;
 
@@ -201,24 +204,28 @@ void r300_parse_chipset(struct r300_capabilities* caps)
         case 0x5954:
         case 0x5955:
             caps->family = CHIP_FAMILY_RS480;
+            caps->has_hiz = FALSE;
             caps->has_tcl = FALSE;
             break;
 
         case 0x5974:
         case 0x5975:
             caps->family = CHIP_FAMILY_RS482;
+            caps->has_hiz = FALSE;
             caps->has_tcl = FALSE;
             break;
 
         case 0x5A41:
         case 0x5A42:
             caps->family = CHIP_FAMILY_RS400;
+            caps->has_hiz = FALSE;
             caps->has_tcl = FALSE;
             break;
 
         case 0x5A61:
         case 0x5A62:
             caps->family = CHIP_FAMILY_RC410;
+            caps->has_hiz = FALSE;
             caps->has_tcl = FALSE;
             break;
 
index ab649c385730b14eb403a8488a09b87e44d26cf0..65750f54e718cd98474326016aaac717dceaf419 100644 (file)
@@ -42,6 +42,8 @@ struct r300_capabilities {
     unsigned num_tex_units;
     /* Whether or not TCL is physically present */
     boolean has_tcl;
+    /* Some chipsets do not have HiZ RAM. */
+    boolean has_hiz;
     /* Whether or not this is RV350 or newer, including all r400 and r500
      * chipsets. The differences compared to the oldest r300 chips are:
      * - Blend LTE/GTE thresholds
index 16a75aa612b9b859c3119dc18f07e7f36d2245d4..df903590583d120b317cfaa315f618968f8800c4 100644 (file)
 #include "r300_emit.h"
 #include "r300_screen.h"
 #include "r300_screen_buffer.h"
-#include "r300_state_invariant.h"
 #include "r300_winsys.h"
 
 #include <inttypes.h>
 
-static void r300_destroy_context(struct pipe_context* context)
+static void r300_update_num_contexts(struct r300_screen *r300screen,
+                                     int diff)
 {
-    struct r300_context* r300 = r300_context(context);
+    if (diff > 0) {
+        p_atomic_inc(&r300screen->num_contexts);
+
+        if (r300screen->num_contexts > 1)
+            util_mempool_set_thread_safety(&r300screen->pool_buffers,
+                                           UTIL_MEMPOOL_MULTITHREADED);
+    } else {
+        p_atomic_dec(&r300screen->num_contexts);
+
+        if (r300screen->num_contexts <= 1)
+            util_mempool_set_thread_safety(&r300screen->pool_buffers,
+                                           UTIL_MEMPOOL_SINGLETHREADED);
+    }
+}
+
+static void r300_release_referenced_objects(struct r300_context *r300)
+{
+    struct pipe_framebuffer_state *fb =
+            (struct pipe_framebuffer_state*)r300->fb_state.state;
+    struct r300_textures_state *textures =
+            (struct r300_textures_state*)r300->textures_state.state;
     struct r300_query *query, *temp;
-    struct r300_atom *atom;
+    unsigned i;
 
+    /* Framebuffer state. */
+    util_assign_framebuffer_state(fb, NULL);
+
+    /* Textures. */
+    for (i = 0; i < textures->sampler_view_count; i++)
+        pipe_sampler_view_reference(
+                (struct pipe_sampler_view**)&textures->sampler_views[i], NULL);
+
+    /* The special dummy texture for texkill. */
     if (r300->texkill_sampler) {
         pipe_sampler_view_reference(
                 (struct pipe_sampler_view**)&r300->texkill_sampler,
                 NULL);
     }
 
+    /* The SWTCL VBO. */
+    pipe_resource_reference(&r300->vbo, NULL);
+
+    /* Vertex buffers. */
+    for (i = 0; i < r300->vertex_buffer_count; i++) {
+        pipe_resource_reference(&r300->vertex_buffer[i].buffer, NULL);
+    }
+
+    /* If there are any queries pending or not destroyed, remove them now. */
+    foreach_s(query, temp, &r300->query_list) {
+        remove_from_list(query);
+        FREE(query);
+    }
+}
+
+static void r300_destroy_context(struct pipe_context* context)
+{
+    struct r300_context* r300 = r300_context(context);
+    struct r300_atom *atom;
+
     util_blitter_destroy(r300->blitter);
     draw_destroy(r300->draw);
 
@@ -62,23 +111,30 @@ static void r300_destroy_context(struct pipe_context* context)
         }
     }
 
-    /* If there are any queries pending or not destroyed, remove them now. */
-    foreach_s(query, temp, &r300->query_list) {
-        remove_from_list(query);
-        FREE(query);
-    }
-
     u_upload_destroy(r300->upload_vb);
     u_upload_destroy(r300->upload_ib);
 
     translate_cache_destroy(r300->tran.translate_cache);
 
+    r300_release_referenced_objects(r300);
+
+    r300->rws->cs_destroy(r300->cs);
+
+    util_mempool_destroy(&r300->pool_transfers);
+
+    r300_update_num_contexts(r300->screen, -1);
+
+    FREE(r300->aa_state.state);
     FREE(r300->blend_color_state.state);
     FREE(r300->clip_state.state);
     FREE(r300->fb_state.state);
+    FREE(r300->gpu_flush.state);
+    FREE(r300->hyperz_state.state);
+    FREE(r300->invariant_state.state);
     FREE(r300->rs_block_state.state);
     FREE(r300->scissor_state.state);
     FREE(r300->textures_state.state);
+    FREE(r300->vap_invariant_state.state);
     FREE(r300->viewport_state.state);
     FREE(r300->ztop_state.state);
     FREE(r300->fs_constants.state);
@@ -89,7 +145,7 @@ static void r300_destroy_context(struct pipe_context* context)
     FREE(r300);
 }
 
-static void r300_flush_cb(void *data)
+void r300_flush_cb(void *data)
 {
     struct r300_context* const cs_context_copy = data;
 
@@ -106,8 +162,10 @@ static void r300_flush_cb(void *data)
 
 static void r300_setup_atoms(struct r300_context* r300)
 {
+    boolean is_rv350 = r300->screen->caps.is_rv350;
     boolean is_r500 = r300->screen->caps.is_r500;
     boolean has_tcl = r300->screen->caps.has_tcl;
+    boolean drm_2_3_0 = r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0);
 
     /* Create the actual atom list.
      *
@@ -115,44 +173,75 @@ static void r300_setup_atoms(struct r300_context* r300)
      * can affect performance and conformance if not handled with care.
      *
      * Some atoms never change size, others change every emit - those have
-     * the size of 0 here. */
+     * the size of 0 here.
+     *
+     * NOTE: The framebuffer state is split into these atoms:
+     * - gpu_flush          (unpipelined regs)
+     * - aa_state           (unpipelined regs)
+     * - fb_state           (unpipelined regs)
+     * - hyperz_state       (unpipelined regs followed by pipelined ones)
+     * - fb_state_pipelined (pipelined regs)
+     * The motivation behind this is to be able to emit a strict
+     * subset of the regs, and to have reasonable register ordering. */
     make_empty_list(&r300->atom_list);
-    R300_INIT_ATOM(invariant_state, 71);
+    /* SC, GB (unpipelined), RB3D (unpipelined), ZB (unpipelined). */
+    R300_INIT_ATOM(gpu_flush, 9);
+    R300_INIT_ATOM(aa_state, 4);
+    R300_INIT_ATOM(fb_state, 0);
+    /* ZB (unpipelined), SC. */
+    R300_INIT_ATOM(hyperz_state, 6);
     R300_INIT_ATOM(ztop_state, 2);
-    R300_INIT_ATOM(query_start, 4);
+    /* ZB, FG. */
+    R300_INIT_ATOM(dsa_state, is_r500 ? 8 : 6);
+    /* RB3D. */
     R300_INIT_ATOM(blend_state, 8);
     R300_INIT_ATOM(blend_color_state, is_r500 ? 3 : 2);
-    R300_INIT_ATOM(clip_state, has_tcl ? 5 + (6 * 4) : 2);
-    R300_INIT_ATOM(dsa_state, is_r500 ? 8 : 6);
-    R300_INIT_ATOM(fb_state, 0);
-    R300_INIT_ATOM(rs_state, 0);
+    /* SC. */
     R300_INIT_ATOM(scissor_state, 3);
+    /* GB, FG, GA, SU, SC, RB3D. */
+    R300_INIT_ATOM(invariant_state, 16 + (is_rv350 ? 4 : 0));
+    /* VAP. */
     R300_INIT_ATOM(viewport_state, 9);
-    R300_INIT_ATOM(rs_block_state, 0);
-    R300_INIT_ATOM(vertex_stream_state, 0);
     R300_INIT_ATOM(pvs_flush, 2);
+    R300_INIT_ATOM(vap_invariant_state, 9);
+    R300_INIT_ATOM(vertex_stream_state, 0);
     R300_INIT_ATOM(vs_state, 0);
     R300_INIT_ATOM(vs_constants, 0);
-    R300_INIT_ATOM(texture_cache_inval, 2);
-    R300_INIT_ATOM(textures_state, 0);
+    R300_INIT_ATOM(clip_state, has_tcl ? 5 + (6 * 4) : 2);
+    /* VAP, RS, GA, GB, SU, SC. */
+    R300_INIT_ATOM(rs_block_state, 0);
+    R300_INIT_ATOM(rs_state, 0);
+    /* SC, US. */
+    R300_INIT_ATOM(fb_state_pipelined, 5 + (drm_2_3_0 ? 3 : 0));
+    /* US. */
     R300_INIT_ATOM(fs, 0);
     R300_INIT_ATOM(fs_rc_constant_state, 0);
     R300_INIT_ATOM(fs_constants, 0);
+    /* TX. */
+    R300_INIT_ATOM(texture_cache_inval, 2);
+    R300_INIT_ATOM(textures_state, 0);
+    /* ZB (unpipelined), SU. */
+    R300_INIT_ATOM(query_start, 4);
 
     /* Replace emission functions for r500. */
-    if (r300->screen->caps.is_r500) {
+    if (is_r500) {
         r300->fs.emit = r500_emit_fs;
         r300->fs_rc_constant_state.emit = r500_emit_fs_rc_constant_state;
         r300->fs_constants.emit = r500_emit_fs_constants;
     }
 
     /* Some non-CSO atoms need explicit space to store the state locally. */
+    r300->aa_state.state = CALLOC_STRUCT(r300_aa_state);
     r300->blend_color_state.state = CALLOC_STRUCT(r300_blend_color_state);
     r300->clip_state.state = CALLOC_STRUCT(r300_clip_state);
     r300->fb_state.state = CALLOC_STRUCT(pipe_framebuffer_state);
+    r300->gpu_flush.state = CALLOC_STRUCT(pipe_framebuffer_state);
+    r300->hyperz_state.state = CALLOC_STRUCT(r300_hyperz_state);
+    r300->invariant_state.state = CALLOC_STRUCT(r300_invariant_state);
     r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block);
     r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state);
     r300->textures_state.state = CALLOC_STRUCT(r300_textures_state);
+    r300->vap_invariant_state.state = CALLOC_STRUCT(r300_vap_invariant_state);
     r300->viewport_state.state = CALLOC_STRUCT(r300_viewport_state);
     r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state);
     r300->fs_constants.state = CALLOC_STRUCT(r300_constant_buffer);
@@ -162,27 +251,45 @@ static void r300_setup_atoms(struct r300_context* r300)
     }
 
     /* Some non-CSO atoms don't use the state pointer. */
-    r300->invariant_state.allow_null_state = TRUE;
+    r300->fb_state_pipelined.allow_null_state = TRUE;
     r300->fs_rc_constant_state.allow_null_state = TRUE;
     r300->pvs_flush.allow_null_state = TRUE;
     r300->query_start.allow_null_state = TRUE;
     r300->texture_cache_inval.allow_null_state = TRUE;
+
+    /* Some states must be marked as dirty here to properly set up
+     * hardware in the first command stream. */
+    r300->invariant_state.dirty = TRUE;
+    r300->pvs_flush.dirty = TRUE;
+    r300->vap_invariant_state.dirty = TRUE;
+    r300->texture_cache_inval.dirty = TRUE;
+    r300->textures_state.dirty = TRUE;
 }
 
 /* Not every state tracker calls every driver function before the first draw
  * call and we must initialize the command buffers somehow. */
 static void r300_init_states(struct pipe_context *pipe)
 {
+    struct r300_context *r300 = r300_context(pipe);
     struct pipe_blend_color bc = {{0}};
     struct pipe_clip_state cs = {{{0}}};
     struct pipe_scissor_state ss = {0};
     struct r300_clip_state *clip =
-            (struct r300_clip_state*)r300_context(pipe)->clip_state.state;
+            (struct r300_clip_state*)r300->clip_state.state;
+    struct r300_gpu_flush *gpuflush =
+            (struct r300_gpu_flush*)r300->gpu_flush.state;
+    struct r300_vap_invariant_state *vap_invariant =
+            (struct r300_vap_invariant_state*)r300->vap_invariant_state.state;
+    struct r300_invariant_state *invariant =
+            (struct r300_invariant_state*)r300->invariant_state.state;
+    struct r300_hyperz_state *hyperz =
+            (struct r300_hyperz_state*)r300->hyperz_state.state;
     CB_LOCALS;
 
     pipe->set_blend_color(pipe, &bc);
     pipe->set_scissor_state(pipe, &ss);
 
+    /* Initialize the clip state. */
     if (r300_context(pipe)->screen->caps.has_tcl) {
         pipe->set_clip_state(pipe, &cs);
     } else {
@@ -190,6 +297,66 @@ static void r300_init_states(struct pipe_context *pipe)
         OUT_CB_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
         END_CB;
     }
+
+    /* Initialize the GPU flush. */
+    {
+        BEGIN_CB(gpuflush->cb_flush_clean, 6);
+
+        /* Flush and free renderbuffer caches. */
+        OUT_CB_REG(R300_RB3D_DSTCACHE_CTLSTAT,
+            R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS |
+            R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D);
+        OUT_CB_REG(R300_ZB_ZCACHE_CTLSTAT,
+            R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE |
+            R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
+
+        /* Wait until the GPU is idle.
+         * This fixes random pixels sometimes appearing probably caused
+         * by incomplete rendering. */
+        OUT_CB_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN);
+        END_CB;
+    }
+
+    /* Initialize the VAP invariant state. */
+    {
+        BEGIN_CB(vap_invariant->cb, 9);
+        OUT_CB_REG(VAP_PVS_VTX_TIMEOUT_REG, 0xffff);
+        OUT_CB_REG_SEQ(R300_VAP_GB_VERT_CLIP_ADJ, 4);
+        OUT_CB_32F(1.0);
+        OUT_CB_32F(1.0);
+        OUT_CB_32F(1.0);
+        OUT_CB_32F(1.0);
+        OUT_CB_REG(R300_VAP_PSC_SGN_NORM_CNTL, R300_SGN_NORM_NO_ZERO);
+        END_CB;
+    }
+
+    /* Initialize the invariant state. */
+    {
+        BEGIN_CB(invariant->cb, r300->invariant_state.size);
+        OUT_CB_REG(R300_GB_SELECT, 0);
+        OUT_CB_REG(R300_FG_FOG_BLEND, 0);
+        OUT_CB_REG(R300_GA_ROUND_MODE, 1);
+        OUT_CB_REG(R300_GA_OFFSET, 0);
+        OUT_CB_REG(R300_SU_TEX_WRAP, 0);
+        OUT_CB_REG(R300_SU_DEPTH_SCALE, 0x4B7FFFFF);
+        OUT_CB_REG(R300_SU_DEPTH_OFFSET, 0);
+        OUT_CB_REG(R300_SC_EDGERULE, 0x2DA49525);
+
+        if (r300->screen->caps.is_rv350) {
+            OUT_CB_REG(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 0x01010101);
+            OUT_CB_REG(R500_RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD, 0xFEFEFEFE);
+        }
+        END_CB;
+    }
+
+    /* Initialize the hyperz state. */
+    {
+        BEGIN_CB(&hyperz->cb_begin, r300->hyperz_state.size);
+        OUT_CB_REG(R300_ZB_BW_CNTL, 0);
+        OUT_CB_REG(R300_ZB_DEPTHCLEARVALUE, 0);
+        OUT_CB_REG(R300_SC_HYPERZ, R300_SC_HYPERZ_ADJ_2);
+        END_CB;
+    }
 }
 
 struct pipe_context* r300_create_context(struct pipe_screen* screen,
@@ -202,6 +369,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
     if (!r300)
         return NULL;
 
+    r300_update_num_contexts(r300screen, 1);
+
     r300->rws = rws;
     r300->screen = r300screen;
 
@@ -211,6 +380,12 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
 
     r300->context.destroy = r300_destroy_context;
 
+    r300->cs = rws->cs_create(rws);
+
+    util_mempool_create(&r300->pool_transfers,
+                        sizeof(struct pipe_transfer), 64,
+                        UTIL_MEMPOOL_SINGLETHREADED);
+
     if (!r300screen->caps.has_tcl) {
         /* Create a Draw. This is used for SW TCL. */
         r300->draw = draw_create(&r300->context);
@@ -230,16 +405,15 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
     r300_init_blit_functions(r300);
     r300_init_flush_functions(r300);
     r300_init_query_functions(r300);
-    r300_init_render_functions(r300);
     r300_init_state_functions(r300);
     r300_init_resource_functions(r300);
 
-    r300->invariant_state.dirty = TRUE;
+    r300->blitter = util_blitter_create(&r300->context);
 
-    rws->set_flush_cb(r300->rws, r300_flush_cb, r300);
-    r300->dirty_hw++;
+    /* Render functions must be initialized after blitter. */
+    r300_init_render_functions(r300);
 
-    r300->blitter = util_blitter_create(&r300->context);
+    rws->cs_set_flush(r300->cs, r300_flush_cb, r300);
 
     r300->upload_ib = u_upload_create(&r300->context,
                                      32 * 1024, 16,
@@ -280,11 +454,6 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
             r300->context.create_sampler_view(&r300->context, tex, &vtempl);
 
         pipe_resource_reference(&tex, NULL);
-
-        /* This will make sure that the dummy texture is set up
-         * from the beginning even if an application does not use
-         * textures. */
-        r300->textures_state.dirty = TRUE;
     }
 
     return &r300->context;
@@ -296,11 +465,6 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
     return NULL;
 }
 
-boolean r300_check_cs(struct r300_context *r300, unsigned size)
-{
-    return size <= r300->rws->get_cs_free_dwords(r300->rws);
-}
-
 void r300_finish(struct r300_context *r300)
 {
     struct pipe_framebuffer_state *fb;
index 8d0b4bb3d376d98ba92c98ac1e67ff75b8f39128..b4256c62786e47ab6f493742cd1a9de95fbda17b 100644 (file)
@@ -61,6 +61,13 @@ struct r300_atom {
     boolean allow_null_state;
 };
 
+struct r300_aa_state {
+    struct r300_surface *dest;
+
+    uint32_t aa_config;
+    uint32_t aaresolve_ctl;
+};
+
 struct r300_blend_state {
     uint32_t cb[8];
     uint32_t cb_no_readwrite[8];
@@ -98,40 +105,39 @@ struct r300_dsa_state {
     boolean two_sided_stencil_ref;
 };
 
+struct r300_hyperz_state {
+    /* This is actually a command buffer with named dwords. */
+    uint32_t cb_begin;
+    uint32_t zb_bw_cntl;            /* R300_ZB_BW_CNTL */
+    uint32_t cb_reg1;
+    uint32_t zb_depthclearvalue;    /* R300_ZB_DEPTHCLEARVALUE */
+    uint32_t cb_reg2;
+    uint32_t sc_hyperz;             /* R300_SC_HYPERZ */
+};
+
+struct r300_gpu_flush {
+    uint32_t cb_flush_clean[6];
+};
+
 struct r300_rs_state {
     /* Original rasterizer state. */
     struct pipe_rasterizer_state rs;
     /* Draw-specific rasterizer state. */
     struct pipe_rasterizer_state rs_draw;
 
-    uint32_t vap_control_status;    /* R300_VAP_CNTL_STATUS: 0x2140 */
-    uint32_t multisample_position_0;/* R300_GB_MSPOS0: 0x4010 */
-    uint32_t multisample_position_1;/* R300_GB_MSPOS1: 0x4014 */
-    uint32_t antialiasing_config;   /* R300_GB_AA_CONFIG: 0x4020 */
-    uint32_t point_size;            /* R300_GA_POINT_SIZE: 0x421c */
-    uint32_t point_minmax;          /* R300_GA_POINT_MINMAX: 0x4230 */
-    uint32_t line_control;          /* R300_GA_LINE_CNTL: 0x4234 */
-    float depth_scale;            /* R300_SU_POLY_OFFSET_FRONT_SCALE: 0x42a4 */
-                                  /* R300_SU_POLY_OFFSET_BACK_SCALE: 0x42ac */
-    float depth_offset;           /* R300_SU_POLY_OFFSET_FRONT_OFFSET: 0x42a8 */
-                                  /* R300_SU_POLY_OFFSET_BACK_OFFSET: 0x42b0 */
-    uint32_t polygon_offset_enable; /* R300_SU_POLY_OFFSET_ENABLE: 0x42b4 */
-    uint32_t cull_mode;             /* R300_SU_CULL_MODE: 0x42b8 */
-    uint32_t line_stipple_config;   /* R300_GA_LINE_STIPPLE_CONFIG: 0x4328 */
-    uint32_t line_stipple_value;    /* R300_GA_LINE_STIPPLE_VALUE: 0x4260 */
+    /* Command buffers. */
+    uint32_t cb_main[25];
+    uint32_t cb_poly_offset_zb16[5];
+    uint32_t cb_poly_offset_zb24[5];
+
+    /* The index to cb_main where the cull_mode register value resides. */
+    unsigned cull_mode_index;
+
+    /* Whether polygon offset is enabled. */
+    boolean polygon_offset_enable;
+
+    /* This is emitted in the draw function. */
     uint32_t color_control;         /* R300_GA_COLOR_CONTROL: 0x4278 */
-    uint32_t polygon_mode;          /* R300_GA_POLY_MODE: 0x4288 */
-    uint32_t clip_rule;             /* R300_SC_CLIP_RULE: 0x43D0 */
-
-    /* Specifies top of Raster pipe specific enable controls,
-     * i.e. texture coordinates stuffing for points, lines, triangles */
-    uint32_t stuffing_enable;       /* R300_GB_ENABLE: 0x4008 */
-
-    /* Point sprites texture coordinates, 0: lower left, 1: upper right */
-    float point_texcoord_left;      /* R300_GA_POINT_S0: 0x4200 */
-    float point_texcoord_bottom;    /* R300_GA_POINT_T0: 0x4204 */
-    float point_texcoord_right;     /* R300_GA_POINT_S1: 0x4208 */
-    float point_texcoord_top;       /* R300_GA_POINT_T1: 0x420c */
 };
 
 struct r300_rs_block {
@@ -214,6 +220,14 @@ struct r300_vertex_stream_state {
     unsigned count;
 };
 
+struct r300_invariant_state {
+    uint32_t cb[20];
+};
+
+struct r300_vap_invariant_state {
+    uint32_t cb[9];
+};
+
 struct r300_viewport_state {
     float xscale;         /* R300_VAP_VPORT_XSCALE:  0x2098 */
     float xoffset;        /* R300_VAP_VPORT_XOFFSET: 0x209c */
@@ -233,8 +247,8 @@ struct r300_ztop_state {
 
 struct r300_constant_buffer {
     /* Buffer of constants */
-    uint32_t constants[256][4];
-    /* Total number of constants */
+    uint32_t *ptr;
+    /* Total number of vec4s */
     unsigned count;
 };
 
@@ -294,32 +308,48 @@ struct r300_surface {
 
     enum r300_buffer_domain domain;
 
-    uint32_t offset;
+    uint32_t offset;    /* COLOROFFSET or DEPTHOFFSET. */
     uint32_t pitch;     /* COLORPITCH or DEPTHPITCH. */
-    uint32_t format;    /* US_OUT_FMT or R300_ZB_FORMAT. */
+    uint32_t format;    /* US_OUT_FMT or ZB_FORMAT. */
+
+    /* Parameters dedicated to the CBZB clear. */
+    uint32_t cbzb_width;            /* Aligned width. */
+    uint32_t cbzb_height;           /* Half of the height. */
+    uint32_t cbzb_midpoint_offset;  /* DEPTHOFFSET. */
+    uint32_t cbzb_pitch;            /* DEPTHPITCH. */
+    uint32_t cbzb_format;           /* ZB_FORMAT. */
+
+    /* Whether the CBZB clear is allowed on the surface. */
+    boolean cbzb_allowed;
 };
 
-struct r300_texture {
-    /* Parent class */
+struct r300_texture_desc {
+    /* Parent class. */
     struct u_resource b;
 
-    enum r300_buffer_domain domain;
+    /* Buffer tiling.
+     * Macrotiling is specified per-level because small mipmaps cannot
+     * be macrotiled. */
+    enum r300_buffer_tiling microtile;
+    enum r300_buffer_tiling macrotile[R300_MAX_TEXTURE_LEVELS];
 
     /* Offsets into the buffer. */
-    unsigned offset[R300_MAX_TEXTURE_LEVELS];
+    unsigned offset_in_bytes[R300_MAX_TEXTURE_LEVELS];
 
-    /* A pitch for each mip-level */
-    unsigned pitch[R300_MAX_TEXTURE_LEVELS];
+    /* Strides for each mip-level. */
+    unsigned stride_in_pixels[R300_MAX_TEXTURE_LEVELS];
+    unsigned stride_in_bytes[R300_MAX_TEXTURE_LEVELS];
 
-    /* A pitch multiplied by blockwidth as hardware wants
-     * the number of pixels instead of the number of blocks. */
-    unsigned hwpitch[R300_MAX_TEXTURE_LEVELS];
+    /* Size of one zslice or face or 2D image based on the texture target. */
+    unsigned layer_size_in_bytes[R300_MAX_TEXTURE_LEVELS];
 
-    /* Size of one zslice or face based on the texture target */
-    unsigned layer_size[R300_MAX_TEXTURE_LEVELS];
+    /* Total size of this texture, in bytes,
+     * derived from the texture properties. */
+    unsigned size_in_bytes;
 
-    /* Whether the mipmap level is macrotiled. */
-    enum r300_buffer_tiling mip_macrotile[R300_MAX_TEXTURE_LEVELS];
+    /* Total size of the buffer backing this texture, in bytes.
+     * It must be >= size. */
+    unsigned buffer_size_in_bytes;
 
     /**
      * If non-zero, override the natural texture layout with
@@ -329,16 +359,24 @@ struct r300_texture {
      *
      * \sa r300_texture_get_stride
      */
-    unsigned stride_override;
+    unsigned stride_in_bytes_override;
 
-    /* Total size of this texture, in bytes. */
-    unsigned size;
+    /* Whether this texture has non-power-of-two dimensions.
+     * It can be either a regular texture or a rectangle one. */
+    boolean is_npot;
 
-    /* Whether this texture has non-power-of-two dimensions
-     * or a user-specified pitch.
-     * It can be either a regular texture or a rectangle one.
-     */
-    boolean uses_pitch;
+    /* This flag says that hardware must use the stride for addressing
+     * instead of the width. */
+    boolean uses_stride_addressing;
+
+    /* Whether CBZB fast color clear is allowed on the miplevel. */
+    boolean cbzb_allowed[R300_MAX_TEXTURE_LEVELS];
+};
+
+struct r300_texture {
+    struct r300_texture_desc desc;
+
+    enum r300_buffer_domain domain;
 
     /* Pipe buffer backing this texture. */
     struct r300_winsys_buffer *buffer;
@@ -349,8 +387,9 @@ struct r300_texture {
     /* All bits should be filled in. */
     struct r300_texture_fb_state fb_state;
 
-    /* Buffer tiling */
-    enum r300_buffer_tiling microtile, macrotile;
+    /* This is the level tiling flags were last time set for.
+     * It's used to prevent redundant tiling-flags changes from happening.*/
+    unsigned surface_level;
 };
 
 struct r300_vertex_element_state {
@@ -391,6 +430,8 @@ struct r300_context {
 
     /* The interface to the windowing system, etc. */
     struct r300_winsys_screen *rws;
+    /* The command stream. */
+    struct r300_winsys_cs *cs;
     /* Screen. */
     struct r300_screen *screen;
     /* Draw module. Used mostly for SW TCL. */
@@ -421,6 +462,8 @@ struct r300_context {
     /* Various CSO state objects. */
     /* Beginning of atom list. */
     struct r300_atom atom_list;
+    /* Anti-aliasing (MSAA) state. */
+    struct r300_atom aa_state;
     /* Blend state. */
     struct r300_atom blend_state;
     /* Blend color state. */
@@ -437,6 +480,10 @@ struct r300_context {
     struct r300_atom fs_constants;
     /* Framebuffer state. */
     struct r300_atom fb_state;
+    /* Framebuffer state (pipelined regs). */
+    struct r300_atom fb_state_pipelined;
+    /* HyperZ state (various SC/ZB bits). */
+    struct r300_atom hyperz_state;
     /* Occlusion query. */
     struct r300_atom query_start;
     /* Rasterizer state. */
@@ -459,8 +506,12 @@ struct r300_context {
     struct r300_atom ztop_state;
     /* PVS flush. */
     struct r300_atom pvs_flush;
+    /* VAP invariant state. */
+    struct r300_atom vap_invariant_state;
     /* Texture cache invalidate. */
     struct r300_atom texture_cache_inval;
+    /* GPU flush. */
+    struct r300_atom gpu_flush;
 
     /* Invariant state. This must be emitted to get the engine started. */
     struct r300_atom invariant_state;
@@ -497,10 +548,13 @@ struct r300_context {
     /* Incompatible vertex buffer layout? (misaligned stride or buffer_offset) */
     boolean incompatible_vb_layout;
 
+    boolean cbzb_clear;
     /* upload managers */
     struct u_upload_mgr *upload_vb;
     struct u_upload_mgr *upload_ib;
 
+    struct util_mempool pool_transfers;
+
     /* Stat counter. */
     uint64_t flush_counter;
 };
@@ -534,8 +588,8 @@ static INLINE struct r300_fragment_shader *r300_fs(struct r300_context *r300)
 struct pipe_context* r300_create_context(struct pipe_screen* screen,
                                          void *priv);
 
-boolean r300_check_cs(struct r300_context *r300, unsigned size);
 void r300_finish(struct r300_context *r300);
+void r300_flush_cb(void *data);
 
 /* Context initialization. */
 struct draw_stage* r300_draw_stage(struct r300_context* r300);
@@ -563,6 +617,13 @@ void r300_translate_index_buffer(struct r300_context *r300,
 void r300_plug_in_stencil_ref_fallback(struct r300_context *r300);
 
 /* r300_state.c */
+enum r300_fb_state_change {
+    R300_CHANGED_FB_STATE = 0,
+    R300_CHANGED_CBZB_FLAG
+};
+
+void r300_mark_fb_state_dirty(struct r300_context *r300,
+                              enum r300_fb_state_change change);
 void r300_mark_fs_code_dirty(struct r300_context *r300);
 
 /* r300_debug.c */
index 1db7da642bd89af4027acf30766f8a44b1c06b36..c194d6a1b08c3ebff2c61b5e8d78efe58f2f7c8d 100644 (file)
  */
 
 #define CS_LOCALS(context) \
-    struct r300_context* const cs_context_copy = (context); \
-    struct r300_winsys_screen *cs_winsys = cs_context_copy->rws; \
-    CS_DEBUG(int cs_count = 0; (void) cs_count;)
+    struct r300_winsys_cs *cs_copy = (context)->cs; \
+    struct r300_winsys_screen *cs_winsys = (context)->rws; \
+    int cs_count = 0; (void) cs_count; (void) cs_winsys;
 
 #define BEGIN_CS(size) do { \
-    assert(r300_check_cs(cs_context_copy, (size))); \
+    assert(size <= (cs_copy->ndw - cs_copy->cdw)); \
     CS_DEBUG(cs_count = size;) \
 } while (0)
 
 #define END_CS
 #endif
 
+
 /**
  * Writing pure DWORDs.
  */
 
 #define OUT_CS(value) do { \
-    cs_winsys->write_cs_dword(cs_winsys, (value)); \
+    cs_copy->ptr[cs_copy->cdw++] = (value); \
     CS_DEBUG(cs_count--;) \
 } while (0)
 
-#define OUT_CS_32F(value) do { \
-    cs_winsys->write_cs_dword(cs_winsys, fui(value)); \
-    CS_DEBUG(cs_count--;) \
-} while (0)
+#define OUT_CS_32F(value) \
+    OUT_CS(fui(value))
 
 #define OUT_CS_REG(register, value) do { \
-    assert(register); \
-    cs_winsys->write_cs_dword(cs_winsys, CP_PACKET0(register, 0)); \
-    cs_winsys->write_cs_dword(cs_winsys, value); \
-    CS_DEBUG(cs_count -= 2;) \
+    OUT_CS(CP_PACKET0(register, 0)); \
+    OUT_CS(value); \
 } while (0)
 
 /* Note: This expects count to be the number of registers,
  * not the actual packet0 count! */
-#define OUT_CS_REG_SEQ(register, count) do { \
-    assert(register); \
-    cs_winsys->write_cs_dword(cs_winsys, CP_PACKET0((register), ((count) - 1))); \
-    CS_DEBUG(cs_count--;) \
-} while (0)
+#define OUT_CS_REG_SEQ(register, count) \
+    OUT_CS(CP_PACKET0((register), ((count) - 1)))
 
-#define OUT_CS_TABLE(values, count) do { \
-    cs_winsys->write_cs_table(cs_winsys, values, count); \
-    CS_DEBUG(cs_count -= count;) \
-} while (0)
+#define OUT_CS_ONE_REG(register, count) \
+    OUT_CS(CP_PACKET0((register), ((count) - 1)) | RADEON_ONE_REG_WR)
 
-#define OUT_CS_ONE_REG(register, count) do { \
-    assert(register); \
-    cs_winsys->write_cs_dword(cs_winsys, CP_PACKET0((register), ((count) - 1)) | RADEON_ONE_REG_WR); \
-    CS_DEBUG(cs_count--;) \
-} while (0)
+#define OUT_CS_PKT3(op, count) \
+    OUT_CS(CP_PACKET3(op, count))
 
-#define OUT_CS_PKT3(op, count) do { \
-    cs_winsys->write_cs_dword(cs_winsys, CP_PACKET3(op, count)); \
-    CS_DEBUG(cs_count--;) \
+#define OUT_CS_TABLE(values, count) do { \
+    memcpy(cs_copy->ptr + cs_copy->cdw, values, count * 4); \
+    cs_copy->cdw += count; \
+    CS_DEBUG(cs_count -= count;) \
 } while (0)
 
 
  * Writing relocations.
  */
 
-#define OUT_CS_RELOC(bo, offset, rd, wd, flags) do { \
+#define OUT_CS_RELOC(bo, offset, rd, wd) do { \
     assert(bo); \
-    cs_winsys->write_cs_dword(cs_winsys, offset); \
-    cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \
-    CS_DEBUG(cs_count -= 3;) \
+    OUT_CS(offset); \
+    cs_winsys->cs_write_reloc(cs_copy, bo, rd, wd); \
+    CS_DEBUG(cs_count -= 2;) \
 } while (0)
 
-#define OUT_CS_BUF_RELOC(bo, offset, rd, wd, flags) do { \
+#define OUT_CS_BUF_RELOC(bo, offset, rd, wd) do { \
     assert(bo); \
-    OUT_CS_RELOC(r300_buffer(bo)->buf, offset, rd, wd, flags); \
+    OUT_CS_RELOC(r300_buffer(bo)->buf, offset, rd, wd); \
 } while (0)
 
-#define OUT_CS_TEX_RELOC(tex, offset, rd, wd, flags) do { \
+#define OUT_CS_TEX_RELOC(tex, offset, rd, wd) do { \
     assert(tex); \
-    OUT_CS_RELOC(tex->buffer, offset, rd, wd, flags); \
+    OUT_CS_RELOC(tex->buffer, offset, rd, wd); \
 } while (0)
 
-#define OUT_CS_BUF_RELOC_NO_OFFSET(bo, rd, wd, flags) do { \
+#define OUT_CS_BUF_RELOC_NO_OFFSET(bo, rd, wd) do { \
     assert(bo); \
-    cs_winsys->write_cs_reloc(cs_winsys, r300_buffer(bo)->buf, rd, wd, flags); \
+    cs_winsys->cs_write_reloc(cs_copy, r300_buffer(bo)->buf, rd, wd); \
     CS_DEBUG(cs_count -= 2;) \
 } while (0)
 
 
 #define WRITE_CS_TABLE(values, count) do { \
     CS_DEBUG(assert(cs_count == 0);) \
-    cs_winsys->write_cs_table(cs_winsys, values, count); \
+    memcpy(cs_copy->ptr + cs_copy->cdw, (values), (count) * 4); \
+    cs_copy->cdw += (count); \
 } while (0)
 
 #endif /* R300_CS_H */
index a6cd86e39208662116a72116f14f8e7ade170301..053a64ea6d7f8f999492aadad5b74cbc65d330a9 100644 (file)
 static const struct debug_named_value debug_options[] = {
     { "fp", DBG_FP, "Fragment program handling (for debugging)" },
     { "vp", DBG_VP, "Vertex program handling (for debugging)" },
-    { "draw", DBG_DRAW, "Draw and emit (for debugging)" },
+    { "draw", DBG_DRAW, "Draw calls (for debugging)" },
+    { "swtcl", DBG_SWTCL, "SWTCL-specific info (for debugging)" },
+    { "rsblock", DBG_RS_BLOCK, "Rasterizer registers (for debugging)" },
+    { "psc", DBG_PSC, "Vertex stream registers (for debugging)" },
     { "tex", DBG_TEX, "Textures (for debugging)" },
     { "texalloc", DBG_TEXALLOC, "Texture allocation (for debugging)" },
     { "fall", DBG_FALL, "Fallbacks (for debugging)" },
     { "rs", DBG_RS, "Rasterizer (for debugging)" },
     { "fb", DBG_FB, "Framebuffer (for debugging)" },
+    { "cbzb", DBG_CBZB, "Fast color clear info (for debugging)" },
+    { "fakeocc", DBG_FAKE_OCC, "Use fake occlusion queries (for debugging)" },
     { "anisohq", DBG_ANISOHQ, "High quality anisotropic filtering (for benchmarking)" },
     { "notiling", DBG_NO_TILING, "Disable tiling (for benchmarking)" },
     { "noimmd", DBG_NO_IMMD, "Disable immediate mode (for benchmarking)" },
-    { "fakeocc", DBG_FAKE_OCC, "Use fake occlusion queries (for lulz)" },
-    { "stats", DBG_STATS, "Gather statistics (for lulz)" },
+    { "stats", DBG_STATS, "Gather statistics" },
 
     /* must be last */
     DEBUG_NAMED_VALUE_END
index d510d80a7bb293e807f40746e2ba8994a6148b83..896aeef395d7544c0b443d531958fe24e5aa7aa6 100644 (file)
 enum r300_buffer_tiling {
     R300_BUFFER_LINEAR = 0,
     R300_BUFFER_TILED,
-    R300_BUFFER_SQUARETILED
+    R300_BUFFER_SQUARETILED,
+
+    R300_BUFFER_UNKNOWN,
+    R300_BUFFER_SELECT_LAYOUT = R300_BUFFER_UNKNOWN
 };
 
 enum r300_buffer_domain { /* bitfield */
index e2c40d823d423fea9bf6f7fdb2036a1234aa8eb2..36a26a78717a37e5ca0651082c3a1234ea667f93 100644 (file)
@@ -170,15 +170,18 @@ void r300_emit_fs_constants(struct r300_context* r300, unsigned size, void *stat
 {
     struct r300_fragment_shader *fs = r300_fs(r300);
     struct r300_constant_buffer *buf = (struct r300_constant_buffer*)state;
-    unsigned count = fs->shader->externals_count * 4;
+    unsigned count = fs->shader->externals_count;
+    unsigned i, j;
     CS_LOCALS(r300);
 
     if (count == 0)
         return;
 
     BEGIN_CS(size);
-    OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X, count);
-    OUT_CS_TABLE(buf->constants, count);
+    OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X, count * 4);
+    for (i = 0; i < count; i++)
+        for (j = 0; j < 4; j++)
+            OUT_CS(pack_float24(*(float*)&buf->ptr[i*4+j]));
     END_CS;
 }
 
@@ -190,7 +193,6 @@ void r300_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, vo
     unsigned count = fs->shader->rc_state_count;
     unsigned first = fs->shader->externals_count;
     unsigned end = constants->Count;
-    uint32_t cdata[4];
     unsigned j;
     CS_LOCALS(r300);
 
@@ -203,11 +205,9 @@ void r300_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, vo
             const float *data =
                     get_rc_constant_state(r300, &constants->Constants[i]);
 
-            for (j = 0; j < 4; j++)
-                cdata[j] = pack_float24(data[j]);
-
             OUT_CS_REG_SEQ(R300_PFS_PARAM_0_X + i * 16, 4);
-            OUT_CS_TABLE(cdata, 4);
+            for (j = 0; j < 4; j++)
+                OUT_CS(pack_float24(data[j]));
         }
     }
     END_CS;
@@ -234,7 +234,7 @@ void r500_emit_fs_constants(struct r300_context* r300, unsigned size, void *stat
     BEGIN_CS(size);
     OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_CONST);
     OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, count);
-    OUT_CS_TABLE(buf->constants, count);
+    OUT_CS_TABLE(buf->ptr, count);
     END_CS;
 }
 
@@ -267,13 +267,22 @@ void r500_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, vo
     END_CS;
 }
 
-void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
+void r300_emit_gpu_flush(struct r300_context *r300, unsigned size, void *state)
 {
-    struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state;
-    struct r300_surface* surf;
-    unsigned i;
+    struct r300_gpu_flush *gpuflush = (struct r300_gpu_flush*)state;
+    struct pipe_framebuffer_state* fb =
+            (struct pipe_framebuffer_state*)r300->fb_state.state;
+    uint32_t height = fb->height;
+    uint32_t width = fb->width;
     CS_LOCALS(r300);
 
+    if (r300->cbzb_clear) {
+        struct r300_surface *surf = r300_surface(fb->cbufs[0]);
+
+        height = surf->cbzb_height;
+        width = surf->cbzb_width;
+    }
+
     BEGIN_CS(size);
 
     /* Set up scissors.
@@ -281,27 +290,48 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
     OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2);
     if (r300->screen->caps.is_r500) {
         OUT_CS(0);
-        OUT_CS(((fb->width  - 1) << R300_SCISSORS_X_SHIFT) |
-               ((fb->height - 1) << R300_SCISSORS_Y_SHIFT));
+        OUT_CS(((width  - 1) << R300_SCISSORS_X_SHIFT) |
+               ((height - 1) << R300_SCISSORS_Y_SHIFT));
     } else {
         OUT_CS((1440 << R300_SCISSORS_X_SHIFT) |
                (1440 << R300_SCISSORS_Y_SHIFT));
-        OUT_CS(((fb->width  + 1440-1) << R300_SCISSORS_X_SHIFT) |
-               ((fb->height + 1440-1) << R300_SCISSORS_Y_SHIFT));
+        OUT_CS(((width  + 1440-1) << R300_SCISSORS_X_SHIFT) |
+               ((height + 1440-1) << R300_SCISSORS_Y_SHIFT));
+    }
+
+    /* Flush CB & ZB caches and wait until the 3D engine is idle and clean. */
+    OUT_CS_TABLE(gpuflush->cb_flush_clean, 6);
+    END_CS;
+}
+
+void r300_emit_aa_state(struct r300_context *r300, unsigned size, void *state)
+{
+    struct r300_aa_state *aa = (struct r300_aa_state*)state;
+    CS_LOCALS(r300);
+
+    BEGIN_CS(size);
+    OUT_CS_REG(R300_GB_AA_CONFIG, aa->aa_config);
+
+    if (aa->dest) {
+        OUT_CS_REG_SEQ(R300_RB3D_AARESOLVE_OFFSET, 1);
+        OUT_CS_RELOC(aa->dest->buffer, aa->dest->offset, 0, aa->dest->domain);
+
+        OUT_CS_REG_SEQ(R300_RB3D_AARESOLVE_PITCH, 1);
+        OUT_CS_RELOC(aa->dest->buffer, aa->dest->pitch, 0, aa->dest->domain);
     }
 
-    /* Flush and free renderbuffer caches. */
-    OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT,
-        R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS |
-        R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D);
-    OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT,
-        R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE |
-        R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
+    OUT_CS_REG(R300_RB3D_AARESOLVE_CTL, aa->aaresolve_ctl);
+    END_CS;
+}
 
-    /* Wait until the GPU is idle.
-     * This fixes random pixels sometimes appearing probably caused
-     * by incomplete rendering. */
-    OUT_CS_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN);
+void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
+{
+    struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state;
+    struct r300_surface* surf;
+    unsigned i;
+    CS_LOCALS(r300);
+
+    BEGIN_CS(size);
 
     /* NUM_MULTIWRITES replicates COLOR[0] to all colorbuffers, which is not
      * what we usually want. */
@@ -317,28 +347,123 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
         surf = r300_surface(fb->cbufs[i]);
 
         OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1);
-        OUT_CS_RELOC(surf->buffer, surf->offset, 0, surf->domain, 0);
+        OUT_CS_RELOC(surf->buffer, surf->offset, 0, surf->domain);
 
         OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1);
-        OUT_CS_RELOC(surf->buffer, surf->pitch, 0, surf->domain, 0);
-
-        OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i), surf->format);
-    }
-    for (; i < 4; i++) {
-        OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i), R300_US_OUT_FMT_UNUSED);
+        OUT_CS_RELOC(surf->buffer, surf->pitch, 0, surf->domain);
     }
 
-    /* Set up a zbuffer. */
-    if (fb->zsbuf) {
-        surf = r300_surface(fb->zsbuf);
+    /* Set up the ZB part of the CBZB clear. */
+    if (r300->cbzb_clear) {
+        surf = r300_surface(fb->cbufs[0]);
+
+        OUT_CS_REG(R300_ZB_FORMAT, surf->cbzb_format);
 
         OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1);
-        OUT_CS_RELOC(surf->buffer, surf->offset, 0, surf->domain, 0);
+        OUT_CS_RELOC(surf->buffer, surf->cbzb_midpoint_offset, 0, surf->domain);
+
+        OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1);
+        OUT_CS_RELOC(surf->buffer, surf->cbzb_pitch, 0, surf->domain);
+    }
+    /* Set up a zbuffer. */
+    else if (fb->zsbuf) {
+        surf = r300_surface(fb->zsbuf);
 
         OUT_CS_REG(R300_ZB_FORMAT, surf->format);
 
+        OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1);
+        OUT_CS_RELOC(surf->buffer, surf->offset, 0, surf->domain);
+
         OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1);
-        OUT_CS_RELOC(surf->buffer, surf->pitch, 0, surf->domain, 0);
+        OUT_CS_RELOC(surf->buffer, surf->pitch, 0, surf->domain);
+
+        /* HiZ RAM. */
+        if (r300->screen->caps.has_hiz) {
+            OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0);
+            OUT_CS_REG(R300_ZB_HIZ_PITCH, 0);
+        }
+
+        /* Z Mask RAM. (compressed zbuffer) */
+        OUT_CS_REG(R300_ZB_ZMASK_OFFSET, 0);
+        OUT_CS_REG(R300_ZB_ZMASK_PITCH, 0);
+    }
+
+    END_CS;
+}
+
+void r300_emit_hyperz_state(struct r300_context *r300,
+                            unsigned size, void *state)
+{
+    CS_LOCALS(r300);
+    WRITE_CS_TABLE(state, size);
+}
+
+void r300_emit_hyperz_end(struct r300_context *r300)
+{
+    struct r300_hyperz_state z =
+            *(struct r300_hyperz_state*)r300->hyperz_state.state;
+
+    z.zb_bw_cntl = 0;
+    z.zb_depthclearvalue = 0;
+    z.sc_hyperz = R300_SC_HYPERZ_ADJ_2;
+
+    r300_emit_hyperz_state(r300, r300->hyperz_state.size, &z);
+}
+
+void r300_emit_fb_state_pipelined(struct r300_context *r300,
+                                  unsigned size, void *state)
+{
+    struct pipe_framebuffer_state* fb =
+            (struct pipe_framebuffer_state*)r300->fb_state.state;
+    unsigned i;
+    CS_LOCALS(r300);
+
+    BEGIN_CS(size);
+
+    /* Colorbuffer format in the US block.
+     * (must be written after unpipelined regs) */
+    OUT_CS_REG_SEQ(R300_US_OUT_FMT_0, 4);
+    for (i = 0; i < fb->nr_cbufs; i++) {
+        OUT_CS(r300_surface(fb->cbufs[i])->format);
+    }
+    for (; i < 4; i++) {
+        OUT_CS(R300_US_OUT_FMT_UNUSED);
+    }
+
+    /* Multisampling. Depends on framebuffer sample count.
+     * These are pipelined regs and as such cannot be moved
+     * to the AA state. */
+    if (r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0)) {
+        unsigned mspos0 = 0x66666666;
+        unsigned mspos1 = 0x6666666;
+
+        if (fb->nr_cbufs && fb->cbufs[0]->texture->nr_samples > 1) {
+            /* Subsample placement. These may not be optimal. */
+            switch (fb->cbufs[0]->texture->nr_samples) {
+                case 2:
+                    mspos0 = 0x33996633;
+                    mspos1 = 0x6666663;
+                    break;
+                case 3:
+                    mspos0 = 0x33936933;
+                    mspos1 = 0x6666663;
+                    break;
+                case 4:
+                    mspos0 = 0x33939933;
+                    mspos1 = 0x3966663;
+                    break;
+                case 6:
+                    mspos0 = 0x22a2aa22;
+                    mspos1 = 0x2a65672;
+                    break;
+                default:
+                    debug_printf("r300: Bad number of multisamples!\n");
+            }
+        }
+
+        OUT_CS_REG_SEQ(R300_GB_MSPOS0, 2);
+        OUT_CS(mspos0);
+        OUT_CS(mspos1);
     }
     END_CS;
 }
@@ -387,13 +512,13 @@ static void r300_emit_query_end_frag_pipes(struct r300_context *r300,
             OUT_CS_REG(R300_SU_REG_DEST, 1 << 3);
             OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
             OUT_CS_RELOC(buf, (query->num_results + 3) * 4,
-                    0, query->domain, 0);
+                    0, query->domain);
         case 3:
             /* pipe 2 only */
             OUT_CS_REG(R300_SU_REG_DEST, 1 << 2);
             OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
             OUT_CS_RELOC(buf, (query->num_results + 2) * 4,
-                    0, query->domain, 0);
+                    0, query->domain);
         case 2:
             /* pipe 1 only */
             /* As mentioned above, accomodate RV380 and older. */
@@ -401,13 +526,13 @@ static void r300_emit_query_end_frag_pipes(struct r300_context *r300,
                     1 << (caps->high_second_pipe ? 3 : 1));
             OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
             OUT_CS_RELOC(buf, (query->num_results + 1) * 4,
-                    0, query->domain, 0);
+                    0, query->domain);
         case 1:
             /* pipe 0 only */
             OUT_CS_REG(R300_SU_REG_DEST, 1 << 0);
             OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
             OUT_CS_RELOC(buf, (query->num_results + 0) * 4,
-                    0, query->domain, 0);
+                    0, query->domain);
             break;
         default:
             fprintf(stderr, "r300: Implementation error: Chipset reports %d"
@@ -429,7 +554,7 @@ static void rv530_emit_query_end_single_z(struct r300_context *r300,
     BEGIN_CS(8);
     OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
     OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
-    OUT_CS_RELOC(buf, query->num_results * 4, 0, query->domain, 0);
+    OUT_CS_RELOC(buf, query->num_results * 4, 0, query->domain);
     OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
     END_CS;
 }
@@ -443,10 +568,10 @@ static void rv530_emit_query_end_double_z(struct r300_context *r300,
     BEGIN_CS(14);
     OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
     OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
-    OUT_CS_RELOC(buf, (query->num_results + 0) * 4, 0, query->domain, 0);
+    OUT_CS_RELOC(buf, (query->num_results + 0) * 4, 0, query->domain);
     OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_1);
     OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
-    OUT_CS_RELOC(buf, (query->num_results + 1) * 4, 0, query->domain, 0);
+    OUT_CS_RELOC(buf, (query->num_results + 1) * 4, 0, query->domain);
     OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
     END_CS;
 }
@@ -480,102 +605,27 @@ void r300_emit_query_end(struct r300_context* r300)
     }
 }
 
+void r300_emit_invariant_state(struct r300_context *r300,
+                               unsigned size, void *state)
+{
+    CS_LOCALS(r300);
+    WRITE_CS_TABLE(state, size);
+}
+
 void r300_emit_rs_state(struct r300_context* r300, unsigned size, void* state)
 {
     struct r300_rs_state* rs = state;
-    struct pipe_framebuffer_state* fb = r300->fb_state.state;
-    float scale, offset;
-    unsigned mspos0, mspos1, aa_config;
     CS_LOCALS(r300);
 
     BEGIN_CS(size);
-    OUT_CS_REG(R300_VAP_CNTL_STATUS, rs->vap_control_status);
-
-    /* Multisampling. Depends on framebuffer sample count. */
-    if (r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0)) {
-        if (fb->nr_cbufs && fb->cbufs[0]->texture->nr_samples > 1) {
-            aa_config = R300_GB_AA_CONFIG_AA_ENABLE;
-            /* Subsample placement. These may not be optimal. */
-            switch (fb->cbufs[0]->texture->nr_samples) {
-                case 2:
-                    aa_config |= R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_2;
-                    mspos0 = 0x33996633;
-                    mspos1 = 0x6666663;
-                    break;
-                case 3:
-                    aa_config |= R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_3;
-                    mspos0 = 0x33936933;
-                    mspos1 = 0x6666663;
-                    break;
-                case 4:
-                    aa_config |= R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_4;
-                    mspos0 = 0x33939933;
-                    mspos1 = 0x3966663;
-                    break;
-                case 6:
-                    aa_config |= R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_6;
-                    mspos0 = 0x22a2aa22;
-                    mspos1 = 0x2a65672;
-                    break;
-                default:
-                    debug_printf("r300: Bad number of multisamples!\n");
-                    mspos0 = rs->multisample_position_0;
-                    mspos1 = rs->multisample_position_1;
-                    break;
-            }
-
-            OUT_CS_REG_SEQ(R300_GB_MSPOS0, 2);
-            OUT_CS(mspos0);
-            OUT_CS(mspos1);
-
-            OUT_CS_REG(R300_GB_AA_CONFIG, aa_config);
-        } else {
-            OUT_CS_REG_SEQ(R300_GB_MSPOS0, 2);
-            OUT_CS(rs->multisample_position_0);
-            OUT_CS(rs->multisample_position_1);
-
-            OUT_CS_REG(R300_GB_AA_CONFIG, rs->antialiasing_config);
-        }
-    }
-
-    OUT_CS_REG(R300_GA_POINT_SIZE, rs->point_size);
-    OUT_CS_REG_SEQ(R300_GA_POINT_MINMAX, 2);
-    OUT_CS(rs->point_minmax);
-    OUT_CS(rs->line_control);
-
+    OUT_CS_TABLE(rs->cb_main, 25);
     if (rs->polygon_offset_enable) {
-        scale = rs->depth_scale * 12;
-        offset = rs->depth_offset;
-
-        switch (r300->zbuffer_bpp) {
-            case 16:
-                offset *= 4;
-                break;
-            case 24:
-                offset *= 2;
-                break;
+        if (r300->zbuffer_bpp == 16) {
+            OUT_CS_TABLE(rs->cb_poly_offset_zb16, 5);
+        } else {
+            OUT_CS_TABLE(rs->cb_poly_offset_zb24, 5);
         }
-
-        OUT_CS_REG_SEQ(R300_SU_POLY_OFFSET_FRONT_SCALE, 4);
-        OUT_CS_32F(scale);
-        OUT_CS_32F(offset);
-        OUT_CS_32F(scale);
-        OUT_CS_32F(offset);
     }
-
-    OUT_CS_REG_SEQ(R300_SU_POLY_OFFSET_ENABLE, 2);
-    OUT_CS(rs->polygon_offset_enable);
-    OUT_CS(rs->cull_mode);
-    OUT_CS_REG(R300_GA_LINE_STIPPLE_CONFIG, rs->line_stipple_config);
-    OUT_CS_REG(R300_GA_LINE_STIPPLE_VALUE, rs->line_stipple_value);
-    OUT_CS_REG(R300_GA_POLY_MODE, rs->polygon_mode);
-    OUT_CS_REG(R300_SC_CLIP_RULE, rs->clip_rule);
-    OUT_CS_REG(R300_GB_ENABLE, rs->stuffing_enable);
-    OUT_CS_REG_SEQ(R300_GA_POINT_S0, 4);
-    OUT_CS_32F(rs->point_texcoord_left);
-    OUT_CS_32F(rs->point_texcoord_bottom);
-    OUT_CS_32F(rs->point_texcoord_right);
-    OUT_CS_32F(rs->point_texcoord_top);
     END_CS;
 }
 
@@ -588,11 +638,20 @@ void r300_emit_rs_block_state(struct r300_context* r300,
     unsigned count = (rs->inst_count & R300_RS_INST_COUNT_MASK) + 1;
     CS_LOCALS(r300);
 
-    if (SCREEN_DBG_ON(r300->screen, DBG_DRAW)) {
+    if (DBG_ON(r300, DBG_RS_BLOCK)) {
         r500_dump_rs_block(rs);
-    }
 
-    DBG(r300, DBG_DRAW, "r300: RS emit:\n");
+        fprintf(stderr, "r300: RS emit:\n");
+
+        for (i = 0; i < count; i++)
+            fprintf(stderr, "    : ip %d: 0x%08x\n", i, rs->ip[i]);
+
+        for (i = 0; i < count; i++)
+            fprintf(stderr, "    : inst %d: 0x%08x\n", i, rs->inst[i]);
+
+        fprintf(stderr, "    : count: 0x%08x inst_count: 0x%08x\n",
+            rs->count, rs->inst_count);
+    }
 
     BEGIN_CS(size);
     OUT_CS_REG_SEQ(R300_VAP_VTX_STATE_CNTL, 2);
@@ -608,9 +667,6 @@ void r300_emit_rs_block_state(struct r300_context* r300,
         OUT_CS_REG_SEQ(R300_RS_IP_0, count);
     }
     OUT_CS_TABLE(rs->ip, count);
-    for (i = 0; i < count; i++) {
-        DBG(r300, DBG_DRAW, "    : ip %d: 0x%08x\n", i, rs->ip[i]);
-    }
 
     OUT_CS_REG_SEQ(R300_RS_COUNT, 2);
     OUT_CS(rs->count);
@@ -622,13 +678,6 @@ void r300_emit_rs_block_state(struct r300_context* r300,
         OUT_CS_REG_SEQ(R300_RS_INST_0, count);
     }
     OUT_CS_TABLE(rs->inst, count);
-    for (i = 0; i < count; i++) {
-        DBG(r300, DBG_DRAW, "    : inst %d: 0x%08x\n", i, rs->inst[i]);
-    }
-
-    DBG(r300, DBG_DRAW, "    : count: 0x%08x inst_count: 0x%08x\n",
-        rs->count, rs->inst_count);
-
     END_CS;
 }
 
@@ -682,7 +731,7 @@ void r300_emit_textures_state(struct r300_context *r300,
 
             OUT_CS_REG_SEQ(R300_TX_OFFSET_0 + (i * 4), 1);
             OUT_CS_TEX_RELOC(tex, texstate->format.tile_config, tex->domain,
-                             0, 0);
+                             0);
         }
     }
     END_CS;
@@ -725,7 +774,7 @@ void r300_emit_aos(struct r300_context* r300, int offset, boolean indexed)
 
     for (i = 0; i < aos_count; i++) {
         buf = r300_buffer(vbuf[velem[i].vertex_buffer_index].buffer);
-        OUT_CS_BUF_RELOC_NO_OFFSET(&buf->b.b, buf->domain, 0, 0);
+        OUT_CS_BUF_RELOC_NO_OFFSET(&buf->b.b, buf->domain, 0);
     }
     END_CS;
 }
@@ -734,7 +783,7 @@ void r300_emit_aos_swtcl(struct r300_context *r300, boolean indexed)
 {
     CS_LOCALS(r300);
 
-    DBG(r300, DBG_DRAW, "r300: Preparing vertex buffer %p for render, "
+    DBG(r300, DBG_SWTCL, "r300: Preparing vertex buffer %p for render, "
             "vertex size %d\n", r300->vbo,
             r300->vertex_info.size);
     /* Set the pointer to our vertex buffer. The emitted values are this:
@@ -750,7 +799,7 @@ void r300_emit_aos_swtcl(struct r300_context *r300, boolean indexed)
     OUT_CS(r300->vertex_info.size |
             (r300->vertex_info.size << 8));
     OUT_CS(r300->vbo_offset);
-    OUT_CS_BUF_RELOC(r300->vbo, 0, r300_buffer(r300->vbo)->domain, 0, 0);
+    OUT_CS_BUF_RELOC(r300->vbo, 0, r300_buffer(r300->vbo)->domain, 0);
     END_CS;
 }
 
@@ -762,21 +811,25 @@ void r300_emit_vertex_stream_state(struct r300_context* r300,
     unsigned i;
     CS_LOCALS(r300);
 
-    DBG(r300, DBG_DRAW, "r300: PSC emit:\n");
+    if (DBG_ON(r300, DBG_PSC)) {
+        fprintf(stderr, "r300: PSC emit:\n");
+
+        for (i = 0; i < streams->count; i++) {
+            fprintf(stderr, "    : prog_stream_cntl%d: 0x%08x\n", i,
+                   streams->vap_prog_stream_cntl[i]);
+        }
+
+        for (i = 0; i < streams->count; i++) {
+            fprintf(stderr, "    : prog_stream_cntl_ext%d: 0x%08x\n", i,
+                   streams->vap_prog_stream_cntl_ext[i]);
+        }
+    }
 
     BEGIN_CS(size);
     OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, streams->count);
     OUT_CS_TABLE(streams->vap_prog_stream_cntl, streams->count);
-    for (i = 0; i < streams->count; i++) {
-        DBG(r300, DBG_DRAW, "    : prog_stream_cntl%d: 0x%08x\n", i,
-               streams->vap_prog_stream_cntl[i]);
-    }
     OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_EXT_0, streams->count);
     OUT_CS_TABLE(streams->vap_prog_stream_cntl_ext, streams->count);
-    for (i = 0; i < streams->count; i++) {
-        DBG(r300, DBG_DRAW, "    : prog_stream_cntl_ext%d: 0x%08x\n", i,
-               streams->vap_prog_stream_cntl_ext[i]);
-    }
     END_CS;
 }
 
@@ -789,6 +842,13 @@ void r300_emit_pvs_flush(struct r300_context* r300, unsigned size, void* state)
     END_CS;
 }
 
+void r300_emit_vap_invariant_state(struct r300_context *r300,
+                                   unsigned size, void *state)
+{
+    CS_LOCALS(r300);
+    WRITE_CS_TABLE(state, size);
+}
+
 void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state)
 {
     struct r300_vertex_shader* vs = (struct r300_vertex_shader*)state;
@@ -813,6 +873,7 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state)
     CS_LOCALS(r300);
 
     BEGIN_CS(size);
+
     /* R300_VAP_PVS_CODE_CNTL_0
      * R300_VAP_PVS_CONST_CNTL
      * R300_VAP_PVS_CODE_CNTL_1
@@ -865,7 +926,7 @@ void r300_emit_vs_constants(struct r300_context* r300,
                (r300->screen->caps.is_r500 ?
                R500_PVS_CONST_START : R300_PVS_CONST_START));
     OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, count * 4);
-    OUT_CS_TABLE(buf->constants, count * 4);
+    OUT_CS_TABLE(buf->ptr, count * 4);
     END_CS;
 }
 
@@ -924,27 +985,22 @@ void r300_emit_buffer_validate(struct r300_context *r300,
     }
 
     /* Clean out BOs. */
-    r300->rws->reset_bos(r300->rws);
+    r300->rws->cs_reset_buffers(r300->cs);
 
 validate:
     /* Color buffers... */
     for (i = 0; i < fb->nr_cbufs; i++) {
         tex = r300_texture(fb->cbufs[i]->texture);
         assert(tex && tex->buffer && "cbuf is marked, but NULL!");
-        if (!r300_add_texture(r300->rws, tex, 0, tex->domain)) {
-            r300->context.flush(&r300->context, 0, NULL);
-            goto validate;
-        }
+        r300->rws->cs_add_buffer(r300->cs, tex->buffer, 0,
+                                 r300_surface(fb->cbufs[i])->domain);
     }
     /* ...depth buffer... */
     if (fb->zsbuf) {
         tex = r300_texture(fb->zsbuf->texture);
         assert(tex && tex->buffer && "zsbuf is marked, but NULL!");
-        if (!r300_add_texture(r300->rws, tex,
-                             0, tex->domain)) {
-            r300->context.flush(&r300->context, 0, NULL);
-            goto validate;
-        }
+        r300->rws->cs_add_buffer(r300->cs, tex->buffer, 0,
+                                 r300_surface(fb->zsbuf)->domain);
     }
     /* ...textures... */
     for (i = 0; i < texstate->count; i++) {
@@ -953,48 +1009,31 @@ validate:
         }
 
         tex = r300_texture(texstate->sampler_views[i]->base.texture);
-        if (!r300_add_texture(r300->rws, tex, tex->domain, 0)) {
-            r300->context.flush(&r300->context, 0, NULL);
-            goto validate;
-        }
+        r300->rws->cs_add_buffer(r300->cs, tex->buffer, tex->domain, 0);
     }
     /* ...occlusion query buffer... */
-    if (r300->query_current) {
-        if (!r300->rws->add_buffer(r300->rws, r300->query_current->buffer,
-                                   0, r300->query_current->domain)) {
-            r300->context.flush(&r300->context, 0, NULL);
-            goto validate;
-        }
-    }
+    if (r300->query_current)
+        r300->rws->cs_add_buffer(r300->cs, r300->query_current->buffer,
+                                 0, r300->query_current->domain);
     /* ...vertex buffer for SWTCL path... */
-    if (r300->vbo) {
-        if (!r300_add_buffer(r300->rws, r300->vbo,
-                            r300_buffer(r300->vbo)->domain, 0)) {
-            r300->context.flush(&r300->context, 0, NULL);
-            goto validate;
-        }
-    }
+    if (r300->vbo)
+        r300->rws->cs_add_buffer(r300->cs, r300_buffer(r300->vbo)->buf,
+                                 r300_buffer(r300->vbo)->domain, 0);
     /* ...vertex buffers for HWTCL path... */
     if (do_validate_vertex_buffers) {
         for (i = 0; i < r300->velems->count; i++) {
             pbuf = vbuf[velem[i].vertex_buffer_index].buffer;
 
-            if (!r300_add_buffer(r300->rws, pbuf,
-                                r300_buffer(pbuf)->domain, 0)) {
-               r300->context.flush(&r300->context, 0, NULL);
-                goto validate;
-            }
+            r300->rws->cs_add_buffer(r300->cs, r300_buffer(pbuf)->buf,
+                                     r300_buffer(pbuf)->domain, 0);
         }
     }
     /* ...and index buffer for HWTCL path. */
-    if (index_buffer) {
-        if (!r300_add_buffer(r300->rws, index_buffer,
-                            r300_buffer(index_buffer)->domain, 0)) {
-            r300->context.flush(&r300->context, 0, NULL);
-            goto validate;
-        }
-    }
-    if (!r300->rws->validate(r300->rws)) {
+    if (index_buffer)
+        r300->rws->cs_add_buffer(r300->cs, r300_buffer(index_buffer)->buf,
+                                 r300_buffer(index_buffer)->domain, 0);
+
+    if (!r300->rws->cs_validate(r300->cs)) {
         r300->context.flush(&r300->context, 0, NULL);
         if (invalid) {
             /* Well, hell. */
index 36a29894d01dc2aead60312997231451f2bade06..5d05039669ffad85bab221c7574ec9859489aa86 100644 (file)
@@ -45,6 +45,11 @@ void r300_emit_clip_state(struct r300_context* r300,
 void r300_emit_dsa_state(struct r300_context* r300,
                          unsigned size, void* state);
 
+void r300_emit_hyperz_state(struct r300_context *r300,
+                            unsigned size, void *state);
+
+void r300_emit_hyperz_end(struct r300_context *r300);
+
 void r300_emit_fs(struct r300_context* r300, unsigned size, void *state);
 
 void r300_emit_fs_constants(struct r300_context* r300, unsigned size, void *state);
@@ -59,6 +64,13 @@ void r500_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, vo
 
 void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state);
 
+void r300_emit_fb_state_pipelined(struct r300_context *r300,
+                                  unsigned size, void *state);
+
+void r300_emit_gpu_flush(struct r300_context *r300, unsigned size, void *state);
+
+void r300_emit_aa_state(struct r300_context *r300, unsigned size, void *state);
+
 void r300_emit_query_start(struct r300_context *r300, unsigned size, void *state);
 
 void r300_emit_query_end(struct r300_context* r300);
@@ -76,6 +88,9 @@ void r300_emit_textures_state(struct r300_context *r300,
 
 void r300_emit_aos_swtcl(struct r300_context *r300, boolean indexed);
 
+void r300_emit_vap_invariant_state(struct r300_context *r300,
+                                   unsigned size, void *state);
+
 void r300_emit_vertex_stream_state(struct r300_context* r300,
                                    unsigned size, void* state);
 
@@ -94,6 +109,9 @@ void r300_emit_pvs_flush(struct r300_context* r300, unsigned size, void* state);
 
 void r300_emit_texture_cache_inval(struct r300_context* r300, unsigned size, void* state);
 
+void r300_emit_invariant_state(struct r300_context *r300,
+                               unsigned size, void *state);
+
 unsigned r300_get_num_dirty_dwords(struct r300_context *r300);
 
 /* Emit all dirty state. */
index ba840bfff81b8b68da3f4aa3d22a7dfb9d70bb6e..ae7b5759e78bbd9b27d8b443257561864afff133 100644 (file)
@@ -25,6 +25,7 @@
 #include "draw/draw_private.h"
 
 #include "util/u_simple_list.h"
+#include "util/u_upload_mgr.h"
 
 #include "r300_context.h"
 #include "r300_cs.h"
@@ -39,6 +40,9 @@ static void r300_flush(struct pipe_context* pipe,
     struct r300_atom *atom;
     struct r300_fence **rfence = (struct r300_fence**)fence;
 
+    u_upload_flush(r300->upload_vb);
+    u_upload_flush(r300->upload_ib);
+
     /* We probably need to flush Draw, but we may have been called from
      * within Draw. This feels kludgy, but it might be the best thing.
      *
@@ -48,12 +52,11 @@ static void r300_flush(struct pipe_context* pipe,
     }
 
     if (r300->dirty_hw) {
+        r300_emit_hyperz_end(r300);
         r300_emit_query_end(r300);
 
-        if (SCREEN_DBG_ON(r300->screen, DBG_STATS)) {
-            r300->flush_counter++;
-        }
-        r300->rws->flush_cs(r300->rws);
+        r300->flush_counter++;
+        r300->rws->cs_flush(r300->cs);
         r300->dirty_hw = 0;
 
         /* New kitchen sink, baby. */
index e585394304eaaeda1ecd8a3877afe1107e5b0932..db5269912e2d1e6db5f648ca6e5c15b92181fd67 100644 (file)
@@ -173,7 +173,7 @@ static void get_external_state(
             t = (struct r300_texture*)texstate->sampler_views[i]->base.texture;
 
             /* XXX this should probably take into account STR, not just S. */
-            if (t->uses_pitch) {
+            if (t->desc.is_npot) {
                 switch (s->state.wrap_s) {
                     case PIPE_TEX_WRAP_REPEAT:
                         state->unit[i].wrap_mode = RC_WRAP_REPEAT;
@@ -246,13 +246,14 @@ static void r300_emit_fs_code_to_buffer(
     if (r300->screen->caps.is_r500) {
         struct r500_fragment_program_code *code = &generic_code->code.r500;
 
-        shader->cb_code_size = 17 +
+        shader->cb_code_size = 19 +
                                ((code->inst_end + 1) * 6) +
                                imm_count * 7;
 
         NEW_CB(shader->cb_code, shader->cb_code_size);
         OUT_CB_REG(R500_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
         OUT_CB_REG(R500_US_PIXSIZE, code->max_temp_idx);
+        OUT_CB_REG(R500_US_FC_CTRL, code->us_fc_ctrl);
         OUT_CB_REG(R500_US_CODE_RANGE,
                    R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(code->inst_end));
         OUT_CB_REG(R500_US_CODE_OFFSET, 0);
@@ -288,11 +289,16 @@ static void r300_emit_fs_code_to_buffer(
         struct r300_fragment_program_code *code = &generic_code->code.r300;
 
         shader->cb_code_size = 19 +
+                               (r300->screen->caps.is_r400 ? 2 : 0) +
                                code->alu.length * 4 +
                                (code->tex.length ? (1 + code->tex.length) : 0) +
                                imm_count * 5;
 
         NEW_CB(shader->cb_code, shader->cb_code_size);
+
+        if (r300->screen->caps.is_r400)
+            OUT_CB_REG(R400_US_CODE_BANK, 0);
+
         OUT_CB_REG(R300_US_CONFIG, code->config);
         OUT_CB_REG(R300_US_PIXSIZE, code->pixsize);
         OUT_CB_REG(R300_US_CODE_OFFSET, code->code_offset);
index e5c76589528ace95aab54e55a1a4dc37e2be1445..e9528956019fada19635d65acae1fea681d07d79 100644 (file)
  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
 
-
-#include "r300_hyperz.h"
 #include "r300_context.h"
+#include "r300_hyperz.h"
 #include "r300_reg.h"
 #include "r300_fs.h"
 
+/*****************************************************************************/
+/* The HyperZ setup                                                          */
+/*****************************************************************************/
+
+static void r300_update_hyperz(struct r300_context* r300)
+{
+    struct r300_hyperz_state *z =
+        (struct r300_hyperz_state*)r300->hyperz_state.state;
+
+    z->zb_bw_cntl = 0;
+    z->sc_hyperz = R300_SC_HYPERZ_ADJ_2;
+
+    if (r300->cbzb_clear)
+        z->zb_bw_cntl |= R300_ZB_CB_CLEAR_CACHE_LINE_WRITE_ONLY;
+}
+
 /*****************************************************************************/
 /* The ZTOP state                                                            */
 /*****************************************************************************/
@@ -119,4 +134,7 @@ static void r300_update_ztop(struct r300_context* r300)
 void r300_update_hyperz_state(struct r300_context* r300)
 {
     r300_update_ztop(r300);
+    if (r300->hyperz_state.dirty) {
+        r300_update_hyperz(r300);
+    }
 }
diff --git a/src/gallium/drivers/r300/r300_public.h b/src/gallium/drivers/r300/r300_public.h
new file mode 100644 (file)
index 0000000..8e7a963
--- /dev/null
@@ -0,0 +1,9 @@
+
+#ifndef R300_PUBLIC_H
+#define R300_PUBLIC_H
+
+struct r300_winsys_screen;
+
+struct pipe_screen* r300_screen_create(struct r300_winsys_screen *rws);
+
+#endif
index 10cb468dfcce429a5fed9a26d4fcf593a4813b43..5b0121ce9e19459f38641a5e1425f35d0acb1bde 100644 (file)
@@ -37,7 +37,9 @@ static struct pipe_query *r300_create_query(struct pipe_context *pipe,
     struct r300_screen *r300screen = r300->screen;
     struct r300_query *q;
 
-    assert(query_type == PIPE_QUERY_OCCLUSION_COUNTER);
+    if (query_type != PIPE_QUERY_OCCLUSION_COUNTER) {
+        return NULL;
+    }
 
     q = CALLOC_STRUCT(r300_query);
     if (!q)
@@ -55,7 +57,9 @@ static struct pipe_query *r300_create_query(struct pipe_context *pipe,
     insert_at_tail(&r300->query_list, q);
 
     /* Open up the occlusion query buffer. */
-    q->buffer = r300->rws->buffer_create(r300->rws, 4096, 0, q->domain, q->buffer_size);
+    q->buffer = r300->rws->buffer_create(r300->rws, q->buffer_size, 4096,
+                                         PIPE_BIND_CUSTOM, PIPE_USAGE_STREAM,
+                                         q->domain);
 
     return (struct pipe_query*)q;
 }
@@ -132,7 +136,7 @@ static boolean r300_get_query_result(struct pipe_context* pipe,
 
     flags = PIPE_TRANSFER_READ | (!wait ? PIPE_TRANSFER_DONTBLOCK : 0);
 
-    map = r300->rws->buffer_map(r300->rws, q->buffer, flags);
+    map = r300->rws->buffer_map(r300->rws, q->buffer, r300->cs, flags);
     if (!map)
         return FALSE;
 
index c783998c78dc447eca73c86028a50d9625692cbf..2acc1a903e8a839b8bc2605b49d3881b24682b7a 100644 (file)
@@ -2617,7 +2617,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #      define R300_WR_COMP_DISABLE                          (0 << 4)
 #      define R300_WR_COMP_ENABLE                           (1 << 4)
 #      define R300_ZB_CB_CLEAR_RMW                          (0 << 5)
-#      define R300_ZB_CB_CLEAR_CACHE_LINEAR                 (1 << 5)
+#      define R300_ZB_CB_CLEAR_CACHE_LINE_WRITE_ONLY        (1 << 5)
 #      define R300_FORCE_COMPRESSED_STENCIL_VALUE_DISABLE   (0 << 6)
 #      define R300_FORCE_COMPRESSED_STENCIL_VALUE_ENABLE    (1 << 6)
 
@@ -2673,6 +2673,24 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 /* Z Buffer Clear Value */
 #define R300_ZB_DEPTHCLEARVALUE                  0x4f28
 
+/* Z Mask RAM is a Z compression buffer.
+ * Each dword of the Z Mask contains compression info for 16 4x4 pixel blocks,
+ * that is 2 bits for each block.
+ * On chips with 2 Z pipes, every other dword maps to a different pipe.
+ */
+
+/* The dword offset into Z mask RAM (bits 18:4) */
+#define R300_ZB_ZMASK_OFFSET                     0x4f30
+
+/* Z Mask Pitch. */
+#define R300_ZB_ZMASK_PITCH                      0x4f34
+
+/* Access to Z Mask RAM in a manner similar to HiZ RAM.
+ * The indices are autoincrementing. */
+#define R300_ZB_ZMASK_WRINDEX                    0x4f38
+#define R300_ZB_ZMASK_DWORD                      0x4f3c
+#define R300_ZB_ZMASK_RDINDEX                    0x4f40
+
 /* Hierarchical Z Memory Offset */
 #define R300_ZB_HIZ_OFFSET                       0x4f44
 
@@ -3264,8 +3282,8 @@ enum {
 #   define R500_FC_B_OP0_NONE                          (0 << 24)
 #   define R500_FC_B_OP0_DECR                          (1 << 24)
 #   define R500_FC_B_OP0_INCR                          (2 << 24)
-#   define R500_FC_B_OP1_DECR                          (0 << 26)
-#   define R500_FC_B_OP1_NONE                          (1 << 26)
+#   define R500_FC_B_OP1_NONE                          (0 << 26)
+#   define R500_FC_B_OP1_DECR                          (1 << 26)
 #   define R500_FC_B_OP1_INCR                          (2 << 26)
 #   define R500_FC_IGNORE_UNCOVERED                    (1 << 28)
 #define R500_US_FC_INT_CONST_0                         0x4c00
index 4afd124c0eb1fb72d4e67b5af1592a386f66d8a0..bae02135da9d18550502cbd5408e552097473443 100644 (file)
@@ -35,7 +35,6 @@
 #include "util/u_prim.h"
 
 #include "r300_cs.h"
-#include "r300_cb.h"
 #include "r300_context.h"
 #include "r300_screen_buffer.h"
 #include "r300_emit.h"
@@ -224,11 +223,12 @@ static void r300_prepare_for_rendering(struct r300_context *r300,
 
     /* Emitted in flush. */
     end_dwords += 26; /* emit_query_end */
+    end_dwords += r300->hyperz_state.size; /* emit_hyperz_end */
 
     cs_dwords += end_dwords;
 
     /* Reserve requested CS space. */
-    if (!r300_check_cs(r300, cs_dwords)) {
+    if (cs_dwords > (r300->cs->ndw - r300->cs->cdw)) {
         r300->context.flush(&r300->context, 0, NULL);
         flushed = TRUE;
     }
@@ -278,7 +278,6 @@ static boolean immd_is_good_idea(struct r300_context *r300,
 
     /* We shouldn't map buffers referenced by CS, busy buffers,
      * and ones placed in VRAM. */
-    /* XXX Check for VRAM buffers. */
     for (i = 0; i < vertex_element_count; i++) {
         velem = &r300->velems->velem[i];
         vbi = velem->vertex_buffer_index;
@@ -286,6 +285,10 @@ static boolean immd_is_good_idea(struct r300_context *r300,
         if (!checked[vbi]) {
             vbuf = &r300->vertex_buffer[vbi];
 
+            if (!(r300_buffer(vbuf->buffer)->domain & R300_DOMAIN_GTT)) {
+                return FALSE;
+            }
+
             if (r300_buffer_is_referenced(&r300->context,
                                           vbuf->buffer,
                                           R300_REF_CS | R300_REF_HW)) {
@@ -299,8 +302,7 @@ static boolean immd_is_good_idea(struct r300_context *r300,
 }
 
 /*****************************************************************************
- * The emission of draw packets for r500. Older GPUs may use these functions *
- * after resolving fallback issues (e.g. stencil ref two-sided).             *
+ * The HWTCL draw functions.                                                 *
  ****************************************************************************/
 
 static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
@@ -316,74 +318,70 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
     /* Size of the vertex, in dwords. */
     unsigned vertex_size = r300->velems->vertex_size_dwords;
 
-    /* Offsets of the attribute, in dwords, from the start of the vertex. */
-    unsigned offset[PIPE_MAX_ATTRIBS];
-
     /* Size of the vertex element, in dwords. */
     unsigned size[PIPE_MAX_ATTRIBS];
 
     /* Stride to the same attrib in the next vertex in the vertex buffer,
      * in dwords. */
-    unsigned stride[PIPE_MAX_ATTRIBS] = {0};
+    unsigned stride[PIPE_MAX_ATTRIBS];
 
     /* Mapped vertex buffers. */
-    uint32_t* map[PIPE_MAX_ATTRIBS] = {0};
-    struct pipe_transfer* transfer[PIPE_MAX_ATTRIBS] = {NULL};
+    uint32_t* map[PIPE_MAX_ATTRIBS];
+    uint32_t* mapelem[PIPE_MAX_ATTRIBS];
+    struct pipe_transfer* transfer[PIPE_MAX_ATTRIBS] = {0};
 
-    CB_LOCALS;
+    CS_LOCALS(r300);
 
     /* Calculate the vertex size, offsets, strides etc. and map the buffers. */
     for (i = 0; i < vertex_element_count; i++) {
         velem = &r300->velems->velem[i];
-        offset[i] = velem->src_offset / 4;
         size[i] = r300->velems->hw_format_size[i] / 4;
         vbi = velem->vertex_buffer_index;
+        vbuf = &r300->vertex_buffer[vbi];
+        stride[i] = vbuf->stride / 4;
 
         /* Map the buffer. */
-        if (!map[vbi]) {
-            vbuf = &r300->vertex_buffer[vbi];
+        if (!transfer[vbi]) {
             map[vbi] = (uint32_t*)pipe_buffer_map(&r300->context,
                                                   vbuf->buffer,
                                                   PIPE_TRANSFER_READ,
                                                  &transfer[vbi]);
-            stride[vbi] = vbuf->stride / 4;
-            map[vbi] += vbuf->buffer_offset / 4 + stride[vbi] * start;
+            map[vbi] += (vbuf->buffer_offset / 4) + stride[i] * start;
         }
+        mapelem[i] = map[vbi] + (velem->src_offset / 4);
     }
 
     dwords = 9 + count * vertex_size;
 
     r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0, NULL);
 
-    BEGIN_CS_AS_CB(r300, dwords);
-    OUT_CB_REG(R300_GA_COLOR_CONTROL,
+    BEGIN_CS(dwords);
+    OUT_CS_REG(R300_GA_COLOR_CONTROL,
             r300_provoking_vertex_fixes(r300, mode));
-    OUT_CB_REG(R300_VAP_VTX_SIZE, vertex_size);
-    OUT_CB_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
-    OUT_CB(count - 1);
-    OUT_CB(0);
-    OUT_CB_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, count * vertex_size);
-    OUT_CB(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (count << 16) |
+    OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size);
+    OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
+    OUT_CS(count - 1);
+    OUT_CS(0);
+    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, count * vertex_size);
+    OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (count << 16) |
             r300_translate_primitive(mode));
 
     /* Emit vertices. */
     for (v = 0; v < count; v++) {
         for (i = 0; i < vertex_element_count; i++) {
-            vbi = r300->velems->velem[i].vertex_buffer_index;
-
-            OUT_CB_TABLE(&map[vbi][offset[i] + stride[vbi] * v], size[i]);
+            OUT_CS_TABLE(&mapelem[i][stride[i] * v], size[i]);
         }
     }
-    END_CB;
+    END_CS;
 
     /* Unmap buffers. */
     for (i = 0; i < vertex_element_count; i++) {
         vbi = r300->velems->velem[i].vertex_buffer_index;
 
-        if (map[vbi]) {
+        if (transfer[vbi]) {
             vbuf = &r300->vertex_buffer[vbi];
             pipe_buffer_unmap(&r300->context, vbuf->buffer, transfer[vbi]);
-            map[vbi] = NULL;
+            transfer[vbi] = NULL;
         }
     }
 }
@@ -475,7 +473,7 @@ static void r300_emit_draw_elements(struct r300_context *r300,
            (0 << R300_INDX_BUFFER_SKIP_SHIFT));
     OUT_CS(offset_dwords << 2);
     OUT_CS_BUF_RELOC(indexBuffer, count_dwords,
-                    r300_buffer(indexBuffer)->domain, 0, 0);
+                     r300_buffer(indexBuffer)->domain, 0);
 
     END_CS;
 }
@@ -499,6 +497,7 @@ static void r300_draw_range_elements(struct pipe_context* pipe,
     unsigned short_count;
     int buffer_offset = 0, index_offset = 0; /* for index bias emulation */
     boolean translate = FALSE;
+    unsigned new_offset;
 
     if (r300->skip_rendering) {
         return;
@@ -508,6 +507,12 @@ static void r300_draw_range_elements(struct pipe_context* pipe,
         return;
     }
 
+    /* Index buffer range checking. */
+    if ((start + count) * indexSize > indexBuffer->width0) {
+        fprintf(stderr, "r300: Invalid index buffer range. Skipping rendering.\n");
+        return;
+    }
+
     /* Set up fallback for incompatible vertex layout if needed. */
     if (r300->incompatible_vb_layout || r300->velems->incompatible_layout) {
         r300_begin_vertex_translate(r300);
@@ -522,18 +527,17 @@ static void r300_draw_range_elements(struct pipe_context* pipe,
                                 &start, count);
 
     r300_update_derived_state(r300);
-    r300_upload_index_buffer(r300, &indexBuffer, indexSize, start, count);
+    r300_upload_index_buffer(r300, &indexBuffer, indexSize, start, count, &new_offset);
 
+    start = new_offset;
     /* 15 dwords for emit_draw_elements */
     r300_prepare_for_rendering(r300,
         PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED,
         indexBuffer, 15, buffer_offset, indexBias, NULL);
 
-    u_upload_flush(r300->upload_vb);
-    u_upload_flush(r300->upload_ib);
     if (alt_num_verts || count <= 65535) {
         r300_emit_draw_elements(r300, indexBuffer, indexSize,
-                                 minIndex, maxIndex, mode, start, count);
+                               minIndex, maxIndex, mode, start, count);
     } else {
         do {
             short_count = MIN2(count, 65534);
@@ -865,13 +869,12 @@ static void r300_render_draw_arrays(struct vbuf_render* render,
     unsigned dwords = 6;
 
     CS_LOCALS(r300);
-
     (void) i; (void) ptr;
 
     r300_prepare_for_rendering(r300, PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL,
                                NULL, dwords, 0, 0, NULL);
 
-    DBG(r300, DBG_DRAW, "r300: Doing vbuf render, count %d\n", count);
+    DBG(r300, DBG_DRAW, "r300: render_draw_arrays (count: %d)\n", count);
 
     /* Uncomment to dump all VBOs rendered through this interface.
      * Slow and noisy!
@@ -914,6 +917,7 @@ static void r300_render_draw_elements(struct vbuf_render* render,
     unsigned free_dwords;
 
     CS_LOCALS(r300);
+    DBG(r300, DBG_DRAW, "r300: render_draw_elements (count: %d)\n", count);
 
     /* Reserve at least 256 dwords.
      *
@@ -924,7 +928,7 @@ static void r300_render_draw_elements(struct vbuf_render* render,
         NULL, 256, 0, 0, &end_cs_dwords);
 
     while (count) {
-        free_dwords = r300->rws->get_cs_free_dwords(r300->rws);
+        free_dwords = r300->cs->ndw - r300->cs->cdw;
 
         short_count = MIN2(count, (free_dwords - end_cs_dwords - 6) * 2);
 
@@ -1015,6 +1019,88 @@ struct draw_stage* r300_draw_stage(struct r300_context* r300)
  *                         End of SW TCL functions                          *
  ***************************************************************************/
 
+/* If we used a quad to draw a rectangle, the pixels on the main diagonal
+ * would be computed and stored twice, which makes the clear/copy codepaths
+ * somewhat inefficient. Instead we use a rectangular point sprite. */
+static void r300_blitter_draw_rectangle(struct blitter_context *blitter,
+                                        unsigned x1, unsigned y1,
+                                        unsigned x2, unsigned y2,
+                                        float depth,
+                                        enum blitter_attrib_type type,
+                                        const float attrib[4])
+{
+    struct r300_context *r300 = r300_context(util_blitter_get_pipe(blitter));
+    unsigned last_sprite_coord_enable = r300->sprite_coord_enable;
+    unsigned width = x2 - x1;
+    unsigned height = y2 - y1;
+    unsigned vertex_size =
+            type == UTIL_BLITTER_ATTRIB_COLOR || !r300->draw ? 8 : 4;
+    unsigned dwords = 13 + vertex_size +
+                      (type == UTIL_BLITTER_ATTRIB_TEXCOORD ? 7 : 0);
+    const float zeros[4] = {0, 0, 0, 0};
+    CS_LOCALS(r300);
+
+    if (type == UTIL_BLITTER_ATTRIB_TEXCOORD)
+        r300->sprite_coord_enable = 1;
+
+    r300_update_derived_state(r300);
+
+    /* Mark some states we don't care about as non-dirty. */
+    r300->clip_state.dirty = FALSE;
+    r300->viewport_state.dirty = FALSE;
+
+    r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0, NULL);
+
+    DBG(r300, DBG_DRAW, "r300: draw_rectangle\n");
+
+    BEGIN_CS(dwords);
+    /* Set up GA. */
+    OUT_CS_REG(R300_GA_POINT_SIZE, (height * 6) | ((width * 6) << 16));
+
+    if (type == UTIL_BLITTER_ATTRIB_TEXCOORD) {
+        /* Set up the GA to generate texcoords. */
+        OUT_CS_REG(R300_GB_ENABLE, R300_GB_POINT_STUFF_ENABLE |
+                   (R300_GB_TEX_STR << R300_GB_TEX0_SOURCE_SHIFT));
+        OUT_CS_REG_SEQ(R300_GA_POINT_S0, 4);
+        OUT_CS_32F(attrib[0]);
+        OUT_CS_32F(attrib[3]);
+        OUT_CS_32F(attrib[2]);
+        OUT_CS_32F(attrib[1]);
+    }
+
+    /* Set up VAP controls. */
+    OUT_CS_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
+    OUT_CS_REG(R300_VAP_VTE_CNTL, R300_VTX_XY_FMT | R300_VTX_Z_FMT);
+    OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size);
+    OUT_CS_REG_SEQ(R300_VAP_VF_MAX_VTX_INDX, 2);
+    OUT_CS(1);
+    OUT_CS(0);
+
+    /* Draw. */
+    OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, vertex_size);
+    OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (1 << 16) |
+           R300_VAP_VF_CNTL__PRIM_POINTS);
+
+    OUT_CS_32F(x1 + width * 0.5f);
+    OUT_CS_32F(y1 + height * 0.5f);
+    OUT_CS_32F(depth);
+    OUT_CS_32F(1);
+
+    if (vertex_size == 8) {
+        if (!attrib)
+            attrib = zeros;
+        OUT_CS_TABLE(attrib, 4);
+    }
+    END_CS;
+
+    /* Restore the state. */
+    r300->clip_state.dirty = TRUE;
+    r300->rs_state.dirty = TRUE;
+    r300->viewport_state.dirty = TRUE;
+
+    r300->sprite_coord_enable = last_sprite_coord_enable;
+}
+
 static void r300_resource_resolve(struct pipe_context* pipe,
                                   struct pipe_resource* dest,
                                   struct pipe_subresource subdest,
@@ -1022,33 +1108,35 @@ static void r300_resource_resolve(struct pipe_context* pipe,
                                   struct pipe_subresource subsrc)
 {
     struct r300_context* r300 = r300_context(pipe);
-    struct r300_surface* destsurf = r300_surface(
-        dest->screen->get_tex_surface(dest->screen,
-            dest, subdest.face, subdest.level, 0, 0));
+    struct r300_aa_state *aa = (struct r300_aa_state*)r300->aa_state.state;
     struct pipe_surface* srcsurf = src->screen->get_tex_surface(src->screen,
             src, subsrc.face, subsrc.level, 0, 0);
     float color[] = {0, 0, 0, 0};
-    CS_LOCALS(r300);
 
     DBG(r300, DBG_DRAW, "r300: Resolving resource...\n");
 
-    OUT_CS_REG_SEQ(R300_RB3D_AARESOLVE_OFFSET, 1);
-    OUT_CS_RELOC(destsurf->buffer, destsurf->offset, 0, destsurf->domain, 0);
-
-    OUT_CS_REG_SEQ(R300_RB3D_AARESOLVE_PITCH, 1);
-    OUT_CS_RELOC(destsurf->buffer, destsurf->pitch, 0, destsurf->domain, 0);
+    /* Enable AA resolve. */
+    aa->dest = r300_surface(
+            dest->screen->get_tex_surface(dest->screen, dest, subdest.face,
+                                          subdest.level, 0, 0));
 
-    OUT_CS_REG(R300_RB3D_AARESOLVE_CTL,
+    aa->aaresolve_ctl =
         R300_RB3D_AARESOLVE_CTL_AARESOLVE_MODE_RESOLVE |
-        R300_RB3D_AARESOLVE_CTL_AARESOLVE_ALPHA_AVERAGE);
+        R300_RB3D_AARESOLVE_CTL_AARESOLVE_ALPHA_AVERAGE;
+    r300->aa_state.size = 12;
+    r300->aa_state.dirty = TRUE;
 
+    /* Resolve the surface. */
     r300->context.clear_render_target(pipe,
         srcsurf, color, 0, 0, src->width0, src->height0);
 
-    OUT_CS_REG(R300_RB3D_AARESOLVE_CTL, 0x0);
+    /* Disable AA resolve. */
+    aa->aaresolve_ctl = 0;
+    r300->aa_state.size = 4;
+    r300->aa_state.dirty = TRUE;
 
     pipe_surface_reference((struct pipe_surface**)&srcsurf, NULL);
-    pipe_surface_reference((struct pipe_surface**)&destsurf, NULL);
+    pipe_surface_reference((struct pipe_surface**)&aa->dest, NULL);
 }
 
 void r300_init_render_functions(struct r300_context *r300)
@@ -1066,6 +1154,7 @@ void r300_init_render_functions(struct r300_context *r300)
     }
 
     r300->context.resource_resolve = r300_resource_resolve;
+    r300->blitter->draw_rectangle = r300_blitter_draw_rectangle;
 
     /* Plug in the two-sided stencil reference value fallback if needed. */
     if (!r300->screen->caps.is_r500)
index d509ded3ec8a4c06ad053a10e11121e606b2f705..9a6b4e12ff1ed0c135c91d8b8a23ef5cc4e20cc7 100644 (file)
@@ -64,12 +64,12 @@ static void r300_stencilref_begin(struct r300_context *r300)
     struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state;
 
     /* Save state. */
-    sr->rs_cull_mode = rs->cull_mode;
+    sr->rs_cull_mode = rs->cb_main[rs->cull_mode_index];
     sr->zb_stencilrefmask = dsa->stencil_ref_mask;
     sr->ref_value_front = r300->stencil_ref.ref_value[0];
 
     /* We *cull* pixels, therefore no need to mask out the bits. */
-    rs->cull_mode |= R300_CULL_BACK;
+    rs->cb_main[rs->cull_mode_index] |= R300_CULL_BACK;
 
     r300->rs_state.dirty = TRUE;
 }
@@ -81,7 +81,7 @@ static void r300_stencilref_switch_side(struct r300_context *r300)
     struct r300_rs_state *rs = (struct r300_rs_state*)r300->rs_state.state;
     struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state;
 
-    rs->cull_mode = sr->rs_cull_mode | R300_CULL_FRONT;
+    rs->cb_main[rs->cull_mode_index] = sr->rs_cull_mode | R300_CULL_FRONT;
     dsa->stencil_ref_mask = dsa->stencil_ref_bf;
     r300->stencil_ref.ref_value[0] = r300->stencil_ref.ref_value[1];
 
@@ -97,7 +97,7 @@ static void r300_stencilref_end(struct r300_context *r300)
     struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state;
 
     /* Restore state. */
-    rs->cull_mode = sr->rs_cull_mode;
+    rs->cb_main[rs->cull_mode_index] = sr->rs_cull_mode;
     dsa->stencil_ref_mask = sr->zb_stencilrefmask;
     r300->stencil_ref.ref_value[0] = sr->ref_value_front;
 
index 8f7c96b829c967ac96f4503e024fd2e0423bd3c9..676430f5fee61e24e11df23b5b7cc17ec54618f9 100644 (file)
@@ -30,6 +30,7 @@
 #include "r300_screen_buffer.h"
 #include "r300_state_inlines.h"
 #include "r300_winsys.h"
+#include "r300_public.h"
 
 /* Return the identifier behind whom the brave coders responsible for this
  * amalgamation of code, sweat, and duct tape, routinely obscure their names.
@@ -114,6 +115,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
         case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
         case PIPE_CAP_BLEND_EQUATION_SEPARATE:
         case PIPE_CAP_TEXTURE_SWIZZLE:
+        case PIPE_CAP_DEPTH_CLAMP:
             return 1;
 
         /* Unsupported features (boolean caps). */
@@ -206,6 +208,8 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
             return 1; /* XXX guessed */
         case PIPE_CAP_MAX_VS_PREDS:
             return is_r500 ? 4 : 0; /* XXX guessed. */
+        case PIPE_CAP_GEOMETRY_SHADER4:
+            return 0;
 
         default:
             fprintf(stderr, "r300: Implementation error: Bad param %d\n",
@@ -253,9 +257,6 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
     uint32_t retval = 0;
     boolean is_r500 = r300_screen(screen)->caps.is_r500;
     boolean is_r400 = r300_screen(screen)->caps.is_r400;
-    boolean is_rv350 = r300_screen(screen)->caps.is_rv350;
-    boolean is_z24 = format == PIPE_FORMAT_X8Z24_UNORM ||
-                     format == PIPE_FORMAT_S8_USCALED_Z24_UNORM;
     boolean is_color2101010 = format == PIPE_FORMAT_R10G10B10A2_UNORM ||
                               format == PIPE_FORMAT_R10G10B10X2_SNORM ||
                               format == PIPE_FORMAT_B10G10R10A2_UNORM ||
@@ -269,12 +270,7 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
                             format == PIPE_FORMAT_R16G16B16_FLOAT ||
                             format == PIPE_FORMAT_R16G16B16A16_FLOAT;
 
-    if (target >= PIPE_MAX_TEXTURE_TYPES) {
-        fprintf(stderr, "r300: Implementation error: Received bogus texture "
-            "target %d in %s\n", target, __FUNCTION__);
-        return FALSE;
-    }
-
+    /* Check multisampling support. */
     switch (sample_count) {
         case 0:
         case 1:
@@ -295,8 +291,6 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
 
     /* Check sampler format support. */
     if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
-        /* Z24 cannot be sampled from on non-r5xx. */
-        (is_r500 || !is_z24) &&
         /* ATI1N is r5xx-only. */
         (is_r500 || !is_ati1n) &&
         /* ATI2N is supported on r4xx-r5xx. */
@@ -329,7 +323,7 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
     /* Check vertex buffer format support. */
     if (usage & PIPE_BIND_VERTEX_BUFFER &&
         /* Half float is supported on >= RV350. */
-        (is_rv350 || !is_half_float) &&
+        (is_r400 || is_r500 || !is_half_float) &&
         r300_translate_vertex_data_type(format) != R300_INVALID_FORMAT) {
         retval |= PIPE_BIND_VERTEX_BUFFER;
     }
@@ -348,6 +342,8 @@ static void r300_destroy_screen(struct pipe_screen* pscreen)
     struct r300_screen* r300screen = r300_screen(pscreen);
     struct r300_winsys_screen *rws = r300_winsys_screen(pscreen);
 
+    util_mempool_destroy(&r300screen->pool_buffers);
+
     if (rws)
       rws->destroy(rws);
 
@@ -387,7 +383,7 @@ static int r300_fence_finish(struct pipe_screen *screen,
     return 0; /* 0 == success */
 }
 
-struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws)
+struct pipe_screen* r300_screen_create(struct r300_winsys_screen *rws)
 {
     struct r300_screen *r300screen = CALLOC_STRUCT(r300_screen);
 
@@ -403,6 +399,10 @@ struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws)
     r300_init_debug(r300screen);
     r300_parse_chipset(&r300screen->caps);
 
+    util_mempool_create(&r300screen->pool_buffers,
+                        sizeof(struct r300_buffer), 64,
+                        UTIL_MEMPOOL_SINGLETHREADED);
+
     r300screen->rws = rws;
     r300screen->screen.winsys = (struct pipe_winsys*)rws;
     r300screen->screen.destroy = r300_destroy_screen;
@@ -423,9 +423,3 @@ struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws)
 
     return &r300screen->screen;
 }
-
-struct r300_winsys_screen *
-r300_winsys_screen(struct pipe_screen *screen)
-{
-    return r300_screen(screen)->rws;
-}
index 29cd5dbe26792ce555707b67a45292507515eec0..18745b83a09c541506d9885558c90bc0223c3bc9 100644 (file)
 
 #include "r300_chipset.h"
 
+#include "util/u_mempool.h"
+
 #include <stdio.h>
 
+struct r300_winsys_screen;
+
 struct r300_screen {
     /* Parent class */
     struct pipe_screen screen;
@@ -39,16 +43,28 @@ struct r300_screen {
     /* Chipset capabilities */
     struct r300_capabilities caps;
 
+    /* Memory pools. */
+    struct util_mempool pool_buffers;
+
     /** Combination of DBG_xxx flags */
     unsigned debug;
+
+    /* The number of created contexts to know whether we have multiple
+     * contexts or not. */
+    int num_contexts;
 };
 
 
-/* Convenience cast wrapper. */
+/* Convenience cast wrappers. */
 static INLINE struct r300_screen* r300_screen(struct pipe_screen* screen) {
     return (struct r300_screen*)screen;
 }
 
+static INLINE struct r300_winsys_screen *
+r300_winsys_screen(struct pipe_screen *screen) {
+    return r300_screen(screen)->rws;
+}
+
 /* Debug functionality. */
 
 /**
@@ -61,17 +77,20 @@ static INLINE struct r300_screen* r300_screen(struct pipe_screen* screen) {
  * those changes.
  */
 /*@{*/
-#define DBG_HELP        (1 << 0)
+
 /* Logging. */
+#define DBG_PSC         (1 << 0)
 #define DBG_FP          (1 << 1)
 #define DBG_VP          (1 << 2)
-/* The bit (1 << 3) is unused. */
+#define DBG_SWTCL       (1 << 3)
 #define DBG_DRAW        (1 << 4)
 #define DBG_TEX         (1 << 5)
 #define DBG_TEXALLOC    (1 << 6)
 #define DBG_RS          (1 << 7)
 #define DBG_FALL        (1 << 8)
 #define DBG_FB          (1 << 9)
+#define DBG_RS_BLOCK    (1 << 10)
+#define DBG_CBZB        (1 << 11)
 /* Features. */
 #define DBG_ANISOHQ     (1 << 16)
 #define DBG_NO_TILING   (1 << 17)
index 7959e6a2f9eaa82a9c701b974ce9d3377c7d8956..37a080ba48b940bf5850d0a8967c51349d63d9c3 100644 (file)
@@ -43,7 +43,7 @@ unsigned r300_buffer_is_referenced(struct pipe_context *context,
     if (r300_buffer_is_user_buffer(buf))
        return PIPE_UNREFERENCED;
 
-    if (r300->rws->is_buffer_referenced(r300->rws, rbuf->buf, domain))
+    if (r300->rws->cs_is_buffer_referenced(r300->cs, rbuf->buf, domain))
         return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
 
     return PIPE_UNREFERENCED;
@@ -62,7 +62,8 @@ int r300_upload_index_buffer(struct r300_context *r300,
                             struct pipe_resource **index_buffer,
                             unsigned index_size,
                             unsigned start,
-                            unsigned count)
+                            unsigned count,
+                            unsigned *out_offset)
 {
    struct pipe_resource *upload_buffer = NULL;
    unsigned index_offset = start * index_size;
@@ -79,7 +80,10 @@ int r300_upload_index_buffer(struct r300_context *r300,
            goto done;
        }
        *index_buffer = upload_buffer;
-    }
+       *out_offset = index_offset / index_size;
+    } else
+        *out_offset = start;
+
  done:
     //    if (upload_buffer)
     // pipe_resource_reference(&upload_buffer, NULL);
@@ -119,31 +123,59 @@ int r300_upload_user_buffers(struct r300_context *r300)
     return ret;
 }
 
-static void r300_winsys_buffer_destroy(struct r300_screen *r300screen,
-                                      struct r300_buffer *rbuf)
+static void r300_buffer_destroy(struct pipe_screen *screen,
+                               struct pipe_resource *buf)
 {
+    struct r300_screen *r300screen = r300_screen(screen);
+    struct r300_buffer *rbuf = r300_buffer(buf);
     struct r300_winsys_screen *rws = r300screen->rws;
 
-    if (rbuf->buf) {
-       rws->buffer_reference(rws, &rbuf->buf, NULL);
-       rbuf->buf = NULL;
-    }
+    if (rbuf->constant_buffer)
+        FREE(rbuf->constant_buffer);
+
+    if (rbuf->buf)
+        rws->buffer_reference(rws, &rbuf->buf, NULL);
+
+    util_mempool_free(&r300screen->pool_buffers, rbuf);
 }
 
-static void r300_buffer_destroy(struct pipe_screen *screen,
-                               struct pipe_resource *buf)
+static struct pipe_transfer*
+r300_default_get_transfer(struct pipe_context *context,
+                          struct pipe_resource *resource,
+                          struct pipe_subresource sr,
+                          unsigned usage,
+                          const struct pipe_box *box)
 {
-    struct r300_screen *r300screen = r300_screen(screen);
-    struct r300_buffer *rbuf = r300_buffer(buf);
+   struct r300_context *r300 = r300_context(context);
+   struct pipe_transfer *transfer =
+         util_mempool_malloc(&r300->pool_transfers);
+
+   transfer->resource = resource;
+   transfer->sr = sr;
+   transfer->usage = usage;
+   transfer->box = *box;
+   transfer->stride = 0;
+   transfer->slice_stride = 0;
+   transfer->data = NULL;
+
+   /* Note strides are zero, this is ok for buffers, but not for
+    * textures 2d & higher at least.
+    */
+   return transfer;
+}
 
-    r300_winsys_buffer_destroy(r300screen, rbuf);
-    FREE(rbuf);
+static void r300_default_transfer_destroy(struct pipe_context *pipe,
+                                          struct pipe_transfer *transfer)
+{
+   struct r300_context *r300 = r300_context(pipe);
+   util_mempool_free(&r300->pool_transfers, transfer);
 }
 
 static void *
 r300_buffer_transfer_map( struct pipe_context *pipe,
                          struct pipe_transfer *transfer )
 {
+    struct r300_context *r300 = r300_context(pipe);
     struct r300_screen *r300screen = r300_screen(pipe->screen);
     struct r300_winsys_screen *rws = r300screen->rws;
     struct r300_buffer *rbuf = r300_buffer(transfer->resource);
@@ -153,10 +185,8 @@ r300_buffer_transfer_map( struct pipe_context *pipe,
 
     if (rbuf->user_buffer)
         return (uint8_t *) rbuf->user_buffer + transfer->box.x;
-
-    if (rbuf->b.b.bind & PIPE_BIND_CONSTANT_BUFFER) {
-       goto just_map;
-    }
+    if (rbuf->constant_buffer)
+        return (uint8_t *) rbuf->constant_buffer + transfer->box.x;
 
     /* check if the mapping is to a range we already flushed */
     if (transfer->usage & PIPE_TRANSFER_DISCARD) {
@@ -170,16 +200,18 @@ r300_buffer_transfer_map( struct pipe_context *pipe,
                rws->buffer_reference(rws, &rbuf->buf, NULL);
 
                rbuf->num_ranges = 0;
-               rbuf->buf = r300screen->rws->buffer_create(r300screen->rws, 16,
-                                                     rbuf->b.b.bind,
-                                                      rbuf->domain,
-                                                     rbuf->b.b.width0);
+                rbuf->buf =
+                    r300screen->rws->buffer_create(r300screen->rws,
+                                                   rbuf->b.b.width0, 16,
+                                                   rbuf->b.b.bind,
+                                                   rbuf->b.b.usage,
+                                                   rbuf->domain);
                break;
            }
        }
     }
-just_map:
-    map = rws->buffer_map(rws, rbuf->buf, transfer->usage);
+
+    map = rws->buffer_map(rws, rbuf->buf, r300->cs, transfer->usage);
 
     if (map == NULL)
         return NULL;
@@ -204,9 +236,8 @@ static void r300_buffer_transfer_flush_region( struct pipe_context *pipe,
 
     if (rbuf->user_buffer)
        return;
-
-    if (rbuf->b.b.bind & PIPE_BIND_CONSTANT_BUFFER)
-       return;
+    if (rbuf->constant_buffer)
+        return;
 
     /* mark the range as used */
     for(i = 0; i < rbuf->num_ranges; ++i) {
@@ -237,14 +268,14 @@ static void r300_buffer_transfer_unmap( struct pipe_context *pipe,
 struct u_resource_vtbl r300_buffer_vtbl = 
 {
    u_default_resource_get_handle,      /* get_handle */
-   r300_buffer_destroy,                     /* resource_destroy */
-   r300_buffer_is_referenced_by_cs,  /* is_buffer_referenced */
-   u_default_get_transfer,          /* get_transfer */
-   u_default_transfer_destroy,      /* transfer_destroy */
-   r300_buffer_transfer_map,        /* transfer_map */
+   r300_buffer_destroy,                /* resource_destroy */
+   r300_buffer_is_referenced_by_cs,    /* is_buffer_referenced */
+   r300_default_get_transfer,          /* get_transfer */
+   r300_default_transfer_destroy,      /* transfer_destroy */
+   r300_buffer_transfer_map,           /* transfer_map */
    r300_buffer_transfer_flush_region,  /* transfer_flush_region */
-   r300_buffer_transfer_unmap,      /* transfer_unmap */
-   u_default_transfer_inline_write   /* transfer_inline_write */
+   r300_buffer_transfer_unmap,         /* transfer_unmap */
+   u_default_transfer_inline_write     /* transfer_inline_write */
 };
 
 struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
@@ -254,9 +285,7 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
     struct r300_buffer *rbuf;
     unsigned alignment = 16;
 
-    rbuf = CALLOC_STRUCT(r300_buffer);
-    if (!rbuf)
-       goto error1;
+    rbuf = util_mempool_malloc(&r300screen->pool_buffers);
 
     rbuf->magic = R300_BUFFER_MAGIC;
 
@@ -265,21 +294,29 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
     pipe_reference_init(&rbuf->b.b.reference, 1);
     rbuf->b.b.screen = screen;
     rbuf->domain = R300_DOMAIN_GTT;
+    rbuf->num_ranges = 0;
+    rbuf->buf = NULL;
+    rbuf->constant_buffer = NULL;
+    rbuf->user_buffer = NULL;
+
+    /* Alloc constant buffers in RAM. */
+    if (templ->bind & PIPE_BIND_CONSTANT_BUFFER) {
+        rbuf->constant_buffer = MALLOC(templ->width0);
+        return &rbuf->b.b;
+    }
 
-    rbuf->buf = r300screen->rws->buffer_create(r300screen->rws,
-                                         alignment,
-                                         rbuf->b.b.bind,
-                                          rbuf->domain,
-                                         rbuf->b.b.width0);
+    rbuf->buf =
+        r300screen->rws->buffer_create(r300screen->rws,
+                                       rbuf->b.b.width0, alignment,
+                                       rbuf->b.b.bind, rbuf->b.b.usage,
+                                       rbuf->domain);
 
-    if (!rbuf->buf)
-       goto error2;
+    if (!rbuf->buf) {
+        util_mempool_free(&r300screen->pool_buffers, rbuf);
+        return NULL;
+    }
 
     return &rbuf->b.b;
-error2:
-    FREE(rbuf);
-error1:
-    return NULL;
 }
 
 struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
@@ -287,28 +324,28 @@ struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
                                              unsigned bytes,
                                              unsigned bind)
 {
+    struct r300_screen *r300screen = r300_screen(screen);
     struct r300_buffer *rbuf;
 
-    rbuf = CALLOC_STRUCT(r300_buffer);
-    if (!rbuf)
-       goto no_rbuf;
+    rbuf = util_mempool_malloc(&r300screen->pool_buffers);
 
     rbuf->magic = R300_BUFFER_MAGIC;
 
     pipe_reference_init(&rbuf->b.b.reference, 1);
     rbuf->b.vtbl = &r300_buffer_vtbl;
     rbuf->b.b.screen = screen;
+    rbuf->b.b.target = PIPE_BUFFER;
     rbuf->b.b.format = PIPE_FORMAT_R8_UNORM;
     rbuf->b.b.usage = PIPE_USAGE_IMMUTABLE;
     rbuf->b.b.bind = bind;
     rbuf->b.b.width0 = bytes;
     rbuf->b.b.height0 = 1;
     rbuf->b.b.depth0 = 1;
+    rbuf->b.b.flags = 0;
     rbuf->domain = R300_DOMAIN_GTT;
-
+    rbuf->num_ranges = 0;
+    rbuf->buf = NULL;
+    rbuf->constant_buffer = NULL;
     rbuf->user_buffer = ptr;
     return &rbuf->b.b;
-
-no_rbuf:
-    return NULL;
 }
index ff355858704c5bf8da95abbc6454ea602ded1507..cafa9f96f20f957e5f8874541b6baca8b93c1708 100644 (file)
@@ -55,6 +55,7 @@ struct r300_buffer
     enum r300_buffer_domain domain;
 
     void *user_buffer;
+    void *constant_buffer;
     struct r300_buffer_range ranges[R300_BUFFER_MAX_RANGES];
     unsigned num_ranges;
 };
@@ -67,7 +68,7 @@ int r300_upload_index_buffer(struct r300_context *r300,
                             struct pipe_resource **index_buffer,
                             unsigned index_size,
                             unsigned start,
-                            unsigned count);
+                            unsigned count, unsigned *out_offset);
 
 struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
                                         const struct pipe_resource *templ);
@@ -97,23 +98,4 @@ static INLINE boolean r300_buffer_is_user_buffer(struct pipe_resource *buffer)
     return r300_buffer(buffer)->user_buffer ? true : false;
 }
 
-static INLINE boolean r300_add_buffer(struct r300_winsys_screen *rws,
-                                     struct pipe_resource *buffer,
-                                     int rd, int wr)
-{
-    struct r300_buffer *buf = r300_buffer(buffer);
-
-    if (!buf->buf)
-       return true;
-
-    return rws->add_buffer(rws, buf->buf, rd, wr);
-}
-
-static INLINE boolean r300_add_texture(struct r300_winsys_screen *rws,
-                                      struct r300_texture *tex,
-                                      int rd, int wr)
-{
-    return rws->add_buffer(rws, tex->buffer, rd, wr);
-}
-
 #endif
index bc2b62ba54177041c3815ca6f29d5690244f5c20..3e221f2e02de0d781fff819abf1c1dbf6200e724 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "draw/draw_context.h"
 
+#include "util/u_blitter.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 #include "util/u_pack_color.h"
@@ -428,14 +429,19 @@ static void r300_set_clip_state(struct pipe_context* pipe,
     clip->clip = *state;
 
     if (r300->screen->caps.has_tcl) {
-        BEGIN_CB(clip->cb, 29);
-        OUT_CB_REG(R300_VAP_PVS_VECTOR_INDX_REG,
-                (r300->screen->caps.is_r500 ?
-                 R500_PVS_UCP_START : R300_PVS_UCP_START));
-        OUT_CB_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, 6 * 4);
-        OUT_CB_TABLE(state->ucp, 6 * 4);
+        r300->clip_state.size = 2 + !!state->nr * 3 + state->nr * 4;
+
+        BEGIN_CB(clip->cb, r300->clip_state.size);
+        if (state->nr) {
+           OUT_CB_REG(R300_VAP_PVS_VECTOR_INDX_REG,
+                   (r300->screen->caps.is_r500 ?
+                    R500_PVS_UCP_START : R300_PVS_UCP_START));
+           OUT_CB_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, state->nr * 4);
+           OUT_CB_TABLE(state->ucp, state->nr * 4);
+        }
         OUT_CB_REG(R300_VAP_CLIP_CNTL, ((1 << state->nr) - 1) |
-                R300_PS_UCP_MODE_CLIP_AS_TRIFAN);
+                R300_PS_UCP_MODE_CLIP_AS_TRIFAN |
+                (state->depth_clamp ? R300_CLIP_DISABLE : 0));
         END_CB;
 
         r300->clip_state.dirty = TRUE;
@@ -608,32 +614,43 @@ static void r300_set_stencil_ref(struct pipe_context* pipe,
     r300->dsa_state.dirty = TRUE;
 }
 
+static void r300_tex_set_tiling_flags(struct r300_context *r300,
+                                      struct r300_texture *tex, unsigned level)
+{
+    /* Check if the macrotile flag needs to be changed.
+     * Skip changing the flags otherwise. */
+    if (tex->desc.macrotile[tex->surface_level] !=
+        tex->desc.macrotile[level]) {
+        /* Tiling determines how DRM treats the buffer data.
+         * We must flush CS when changing it if the buffer is referenced. */
+        if (r300->rws->cs_is_buffer_referenced(r300->cs,
+                                               tex->buffer, R300_REF_CS))
+            r300->context.flush(&r300->context, 0, NULL);
+
+        r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
+                tex->desc.microtile, tex->desc.macrotile[level],
+                tex->desc.stride_in_bytes[0]);
+
+        tex->surface_level = level;
+    }
+}
+
 /* This switcheroo is needed just because of goddamned MACRO_SWITCH. */
 static void r300_fb_set_tiling_flags(struct r300_context *r300,
-                               const struct pipe_framebuffer_state *old_state,
-                               const struct pipe_framebuffer_state *new_state)
+                               const struct pipe_framebuffer_state *state)
 {
-    struct r300_texture *tex;
-    unsigned i, level;
+    unsigned i;
 
     /* Set tiling flags for new surfaces. */
-    for (i = 0; i < new_state->nr_cbufs; i++) {
-        tex = r300_texture(new_state->cbufs[i]->texture);
-        level = new_state->cbufs[i]->level;
-
-        r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
-                tex->pitch[0] * util_format_get_blocksize(tex->b.b.format),
-                tex->microtile,
-                tex->mip_macrotile[level]);
+    for (i = 0; i < state->nr_cbufs; i++) {
+        r300_tex_set_tiling_flags(r300,
+                                  r300_texture(state->cbufs[i]->texture),
+                                  state->cbufs[i]->level);
     }
-    if (new_state->zsbuf) {
-        tex = r300_texture(new_state->zsbuf->texture);
-        level = new_state->zsbuf->level;
-
-        r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
-                tex->pitch[0] * util_format_get_blocksize(tex->b.b.format),
-                tex->microtile,
-                tex->mip_macrotile[level]);
+    if (state->zsbuf) {
+        r300_tex_set_tiling_flags(r300,
+                                  r300_texture(state->zsbuf->texture),
+                                  state->zsbuf->level);
     }
 }
 
@@ -654,26 +671,49 @@ static void r300_print_fb_surf_info(struct pipe_surface *surf, unsigned index,
             surf->zslice, surf->face, surf->level,
             util_format_short_name(surf->format),
 
-            rtex->macrotile ? "YES" : " NO", rtex->microtile ? "YES" : " NO",
-            rtex->hwpitch[0], tex->width0, tex->height0, tex->depth0,
+            rtex->desc.macrotile[0] ? "YES" : " NO",
+            rtex->desc.microtile ? "YES" : " NO",
+            rtex->desc.stride_in_pixels[0],
+            tex->width0, tex->height0, tex->depth0,
             tex->last_level, util_format_short_name(tex->format));
 }
 
+void r300_mark_fb_state_dirty(struct r300_context *r300,
+                              enum r300_fb_state_change change)
+{
+    struct pipe_framebuffer_state *state = r300->fb_state.state;
+
+    /* What is marked as dirty depends on the enum r300_fb_state_change. */
+    r300->gpu_flush.dirty = TRUE;
+    r300->fb_state.dirty = TRUE;
+    r300->hyperz_state.dirty = TRUE;
+
+    if (change == R300_CHANGED_FB_STATE) {
+        r300->aa_state.dirty = TRUE;
+        r300->fb_state_pipelined.dirty = TRUE;
+    }
+
+    /* Now compute the fb_state atom size. */
+    r300->fb_state.size = 2 + (8 * state->nr_cbufs);
+
+    if (r300->cbzb_clear)
+        r300->fb_state.size += 10;
+    else if (state->zsbuf)
+        r300->fb_state.size += r300->screen->caps.has_hiz ? 18 : 14;
+
+    /* The size of the rest of atoms stays the same. */
+}
+
 static void
     r300_set_framebuffer_state(struct pipe_context* pipe,
                                const struct pipe_framebuffer_state* state)
 {
     struct r300_context* r300 = r300_context(pipe);
+    struct r300_aa_state *aa = (struct r300_aa_state*)r300->aa_state.state;
     struct pipe_framebuffer_state *old_state = r300->fb_state.state;
     unsigned max_width, max_height, i;
     uint32_t zbuffer_bpp = 0;
 
-    if (state->nr_cbufs > 4) {
-        fprintf(stderr, "r300: Implementation error: Too many MRTs in %s, "
-            "refusing to bind framebuffer state!\n", __FUNCTION__);
-        return;
-    }
-
     if (r300->screen->caps.is_r500) {
         max_width = max_height = 4096;
     } else if (r300->screen->caps.is_r400) {
@@ -692,8 +732,6 @@ static void
         draw_flush(r300->draw);
     }
 
-    r300->fb_state.dirty = TRUE;
-
     /* If nr_cbufs is changed from zero to non-zero or vice versa... */
     if (!!old_state->nr_cbufs != !!state->nr_cbufs) {
         r300->blend_state.dirty = TRUE;
@@ -704,12 +742,11 @@ static void
     }
 
     /* The tiling flags are dependent on the surface miplevel, unfortunately. */
-    r300_fb_set_tiling_flags(r300, r300->fb_state.state, state);
+    r300_fb_set_tiling_flags(r300, state);
 
-    memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state));
+    util_assign_framebuffer_state(r300->fb_state.state, state);
 
-    r300->fb_state.size = (10 * state->nr_cbufs) + (2 * (4 - state->nr_cbufs)) +
-                          (state->zsbuf ? 10 : 0) + 11;
+    r300_mark_fb_state_dirty(r300, R300_CHANGED_FB_STATE);
 
     /* Polygon offset depends on the zbuffer bit depth. */
     if (state->zsbuf && r300->polygon_offset_enabled) {
@@ -728,6 +765,30 @@ static void
         }
     }
 
+    /* Set up AA config. */
+    if (r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0)) {
+        if (state->nr_cbufs && state->cbufs[0]->texture->nr_samples > 1) {
+            aa->aa_config = R300_GB_AA_CONFIG_AA_ENABLE;
+
+            switch (state->cbufs[0]->texture->nr_samples) {
+                case 2:
+                    aa->aa_config |= R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_2;
+                    break;
+                case 3:
+                    aa->aa_config |= R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_3;
+                    break;
+                case 4:
+                    aa->aa_config |= R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_4;
+                    break;
+                case 6:
+                    aa->aa_config |= R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_6;
+                    break;
+            }
+        } else {
+            aa->aa_config = 0;
+        }
+    }
+
     if (DBG_ON(r300, DBG_FB)) {
         fprintf(stderr, "r300: set_framebuffer_state:\n");
         for (i = 0; i < state->nr_cbufs; i++) {
@@ -826,6 +887,27 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
     struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state);
     int i;
     float psiz;
+    uint32_t vap_control_status;    /* R300_VAP_CNTL_STATUS: 0x2140 */
+    uint32_t point_size;            /* R300_GA_POINT_SIZE: 0x421c */
+    uint32_t point_minmax;          /* R300_GA_POINT_MINMAX: 0x4230 */
+    uint32_t line_control;          /* R300_GA_LINE_CNTL: 0x4234 */
+    uint32_t polygon_offset_enable; /* R300_SU_POLY_OFFSET_ENABLE: 0x42b4 */
+    uint32_t cull_mode;             /* R300_SU_CULL_MODE: 0x42b8 */
+    uint32_t line_stipple_config;   /* R300_GA_LINE_STIPPLE_CONFIG: 0x4328 */
+    uint32_t line_stipple_value;    /* R300_GA_LINE_STIPPLE_VALUE: 0x4260 */
+    uint32_t polygon_mode;          /* R300_GA_POLY_MODE: 0x4288 */
+    uint32_t clip_rule;             /* R300_SC_CLIP_RULE: 0x43D0 */
+
+    /* Specifies top of Raster pipe specific enable controls,
+     * i.e. texture coordinates stuffing for points, lines, triangles */
+    uint32_t stuffing_enable;       /* R300_GB_ENABLE: 0x4008 */
+
+    /* Point sprites texture coordinates, 0: lower left, 1: upper right */
+    float point_texcoord_left;      /* R300_GA_POINT_S0: 0x4200 */
+    float point_texcoord_bottom = 0;/* R300_GA_POINT_T0: 0x4204 */
+    float point_texcoord_right;     /* R300_GA_POINT_S1: 0x4208 */
+    float point_texcoord_top = 0;   /* R300_GA_POINT_T1: 0x420c */
+    CB_LOCALS;
 
     /* Copy rasterizer state. */
     rs->rs = *state;
@@ -835,18 +917,18 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
     rs->rs_draw.sprite_coord_enable = 0; /* We can do this in HW. */
 
 #ifdef PIPE_ARCH_LITTLE_ENDIAN
-    rs->vap_control_status = R300_VC_NO_SWAP;
+    vap_control_status = R300_VC_NO_SWAP;
 #else
-    rs->vap_control_status = R300_VC_32BIT_SWAP;
+    vap_control_status = R300_VC_32BIT_SWAP;
 #endif
 
     /* If no TCL engine is present, turn off the HW TCL. */
     if (!r300_screen(pipe->screen)->caps.has_tcl) {
-        rs->vap_control_status |= R300_VAP_TCL_BYPASS;
+        vap_control_status |= R300_VAP_TCL_BYPASS;
     }
 
     /* Point size width and height. */
-    rs->point_size =
+    point_size =
         pack_float_16_6x(state->point_size) |
         (pack_float_16_6x(state->point_size) << R300_POINTSIZE_X_SHIFT);
 
@@ -856,68 +938,70 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
          * Clamp to [0, max FB size] */
         psiz = pipe->screen->get_paramf(pipe->screen,
                                         PIPE_CAP_MAX_POINT_WIDTH);
-        rs->point_minmax =
+        point_minmax =
             pack_float_16_6x(psiz) << R300_GA_POINT_MINMAX_MAX_SHIFT;
     } else {
         /* We cannot disable the point-size vertex output,
          * so clamp it. */
         psiz = state->point_size;
-        rs->point_minmax =
+        point_minmax =
             (pack_float_16_6x(psiz) << R300_GA_POINT_MINMAX_MIN_SHIFT) |
             (pack_float_16_6x(psiz) << R300_GA_POINT_MINMAX_MAX_SHIFT);
     }
 
     /* Line control. */
-    rs->line_control = pack_float_16_6x(state->line_width) |
+    line_control = pack_float_16_6x(state->line_width) |
         R300_GA_LINE_CNTL_END_TYPE_COMP;
 
     /* Enable polygon mode */
+    polygon_mode = 0;
     if (state->fill_front != PIPE_POLYGON_MODE_FILL ||
         state->fill_back != PIPE_POLYGON_MODE_FILL) {
-        rs->polygon_mode = R300_GA_POLY_MODE_DUAL;
+        polygon_mode = R300_GA_POLY_MODE_DUAL;
     }
 
     /* Front face */
     if (state->front_ccw) 
-        rs->cull_mode = R300_FRONT_FACE_CCW;
+        cull_mode = R300_FRONT_FACE_CCW;
     else
-        rs->cull_mode = R300_FRONT_FACE_CW;
+        cull_mode = R300_FRONT_FACE_CW;
 
     /* Polygon offset */
+    polygon_offset_enable = 0;
     if (util_get_offset(state, state->fill_front)) {
-       rs->polygon_offset_enable |= R300_FRONT_ENABLE;
+       polygon_offset_enable |= R300_FRONT_ENABLE;
     }
     if (util_get_offset(state, state->fill_back)) {
-       rs->polygon_offset_enable |= R300_BACK_ENABLE;
+       polygon_offset_enable |= R300_BACK_ENABLE;
     }
 
+    rs->polygon_offset_enable = polygon_offset_enable != 0;
+
     /* Polygon mode */
-    if (rs->polygon_mode) {
-       rs->polygon_mode |=
+    if (polygon_mode) {
+       polygon_mode |=
           r300_translate_polygon_mode_front(state->fill_front);
-       rs->polygon_mode |=
+       polygon_mode |=
           r300_translate_polygon_mode_back(state->fill_back);
     }
 
     if (state->cull_face & PIPE_FACE_FRONT) {
-        rs->cull_mode |= R300_CULL_FRONT;
+        cull_mode |= R300_CULL_FRONT;
     }
     if (state->cull_face & PIPE_FACE_BACK) {
-        rs->cull_mode |= R300_CULL_BACK;
-    }
-
-    if (rs->polygon_offset_enable) {
-        rs->depth_offset = state->offset_units;
-        rs->depth_scale = state->offset_scale;
+        cull_mode |= R300_CULL_BACK;
     }
 
     if (state->line_stipple_enable) {
-        rs->line_stipple_config =
+        line_stipple_config =
             R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_LINE |
             (fui((float)state->line_stipple_factor) &
                 R300_GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_MASK);
         /* XXX this might need to be scaled up */
-        rs->line_stipple_value = state->line_stipple_pattern;
+        line_stipple_value = state->line_stipple_pattern;
+    } else {
+        line_stipple_config = 0;
+        line_stipple_value = 0;
     }
 
     if (state->flatshade) {
@@ -926,35 +1010,78 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
         rs->color_control = R300_SHADE_MODEL_SMOOTH;
     }
 
-    rs->clip_rule = state->scissor ? 0xAAAA : 0xFFFF;
+    clip_rule = state->scissor ? 0xAAAA : 0xFFFF;
 
     /* Point sprites */
+    stuffing_enable = 0;
     if (state->sprite_coord_enable) {
-        rs->stuffing_enable = R300_GB_POINT_STUFF_ENABLE;
+        stuffing_enable = R300_GB_POINT_STUFF_ENABLE;
        for (i = 0; i < 8; i++) {
            if (state->sprite_coord_enable & (1 << i))
-               rs->stuffing_enable |=
+                stuffing_enable |=
                    R300_GB_TEX_STR << (R300_GB_TEX0_SOURCE_SHIFT + (i*2));
        }
 
-        rs->point_texcoord_left = 0.0f;
-        rs->point_texcoord_right = 1.0f;
+        point_texcoord_left = 0.0f;
+        point_texcoord_right = 1.0f;
 
         switch (state->sprite_coord_mode) {
             case PIPE_SPRITE_COORD_UPPER_LEFT:
-                rs->point_texcoord_top = 0.0f;
-                rs->point_texcoord_bottom = 1.0f;
+                point_texcoord_top = 0.0f;
+                point_texcoord_bottom = 1.0f;
                 break;
             case PIPE_SPRITE_COORD_LOWER_LEFT:
-                rs->point_texcoord_top = 1.0f;
-                rs->point_texcoord_bottom = 0.0f;
+                point_texcoord_top = 1.0f;
+                point_texcoord_bottom = 0.0f;
                 break;
         }
     }
 
-    if (state->gl_rasterization_rules) {
-        rs->multisample_position_0 = 0x66666666;
-        rs->multisample_position_1 = 0x6666666;
+    /* Build the main command buffer. */
+    BEGIN_CB(rs->cb_main, 25);
+    OUT_CB_REG(R300_VAP_CNTL_STATUS, vap_control_status);
+    OUT_CB_REG(R300_GA_POINT_SIZE, point_size);
+    OUT_CB_REG_SEQ(R300_GA_POINT_MINMAX, 2);
+    OUT_CB(point_minmax);
+    OUT_CB(line_control);
+    OUT_CB_REG_SEQ(R300_SU_POLY_OFFSET_ENABLE, 2);
+    OUT_CB(polygon_offset_enable);
+    rs->cull_mode_index = 9;
+    OUT_CB(cull_mode);
+    OUT_CB_REG(R300_GA_LINE_STIPPLE_CONFIG, line_stipple_config);
+    OUT_CB_REG(R300_GA_LINE_STIPPLE_VALUE, line_stipple_value);
+    OUT_CB_REG(R300_GA_POLY_MODE, polygon_mode);
+    OUT_CB_REG(R300_SC_CLIP_RULE, clip_rule);
+    OUT_CB_REG(R300_GB_ENABLE, stuffing_enable);
+    OUT_CB_REG_SEQ(R300_GA_POINT_S0, 4);
+    OUT_CB_32F(point_texcoord_left);
+    OUT_CB_32F(point_texcoord_bottom);
+    OUT_CB_32F(point_texcoord_right);
+    OUT_CB_32F(point_texcoord_top);
+    END_CB;
+
+    /* Build the two command buffers for polygon offset setup. */
+    if (polygon_offset_enable) {
+        float scale = state->offset_scale * 12;
+        float offset = state->offset_units * 4;
+
+        BEGIN_CB(rs->cb_poly_offset_zb16, 5);
+        OUT_CB_REG_SEQ(R300_SU_POLY_OFFSET_FRONT_SCALE, 4);
+        OUT_CB_32F(scale);
+        OUT_CB_32F(offset);
+        OUT_CB_32F(scale);
+        OUT_CB_32F(offset);
+        END_CB;
+
+        offset = state->offset_units * 2;
+
+        BEGIN_CB(rs->cb_poly_offset_zb24, 5);
+        OUT_CB_REG_SEQ(R300_SU_POLY_OFFSET_FRONT_SCALE, 4);
+        OUT_CB_32F(scale);
+        OUT_CB_32F(offset);
+        OUT_CB_32F(scale);
+        OUT_CB_32F(offset);
+        END_CB;
     }
 
     return (void*)rs;
@@ -986,8 +1113,7 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
     }
 
     UPDATE_STATE(state, r300->rs_state);
-    r300->rs_state.size = 25 + (r300->polygon_offset_enabled ? 5 : 0) +
-        (r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0) ? 5 : 0);
+    r300->rs_state.size = 25 + (r300->polygon_offset_enabled ? 5 : 0);
 
     if (last_sprite_coord_enable != r300->sprite_coord_enable ||
         last_two_sided_color != r300->two_sided_color) {
@@ -1056,7 +1182,7 @@ static void*
 
     lod_bias = CLAMP((int)(state->lod_bias * 32 + 1), -(1 << 9), (1 << 9) - 1);
 
-    sampler->filter1 |= lod_bias << R300_LOD_BIAS_SHIFT;
+    sampler->filter1 |= (lod_bias << R300_LOD_BIAS_SHIFT) & R300_LOD_BIAS_MASK;
 
     /* This is very high quality anisotropic filtering for R5xx.
      * It's good for benchmarking the performance of texturing but
@@ -1170,7 +1296,7 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
             /* Set the texrect factor in the fragment shader.
              * Needed for RECT and NPOT fallback. */
             texture = r300_texture(views[i]->texture);
-            if (texture->uses_pitch) {
+            if (texture->desc.is_npot) {
                 r300->fs_rc_constant_state.dirty = TRUE;
             }
 
@@ -1204,6 +1330,7 @@ r300_create_sampler_view(struct pipe_context *pipe,
 {
     struct r300_sampler_view *view = CALLOC_STRUCT(r300_sampler_view);
     struct r300_texture *tex = r300_texture(texture);
+    boolean is_r500 = r300_screen(pipe->screen)->caps.is_r500;
 
     if (view) {
         view->base = *templ;
@@ -1219,8 +1346,9 @@ r300_create_sampler_view(struct pipe_context *pipe,
 
         view->format = tex->tx_format;
         view->format.format1 |= r300_translate_texformat(templ->format,
-                                                         view->swizzle);
-        if (r300_screen(pipe->screen)->caps.is_r500) {
+                                                         view->swizzle,
+                                                         is_r500);
+        if (is_r500) {
             view->format.format2 |= r500_tx_format_msb_bit(templ->format);
         }
     }
@@ -1544,7 +1672,6 @@ static void* r300_create_vs_state(struct pipe_context* pipe,
                                   const struct pipe_shader_state* shader)
 {
     struct r300_context* r300 = r300_context(pipe);
-
     struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader);
 
     /* Copy state directly into shader. */
@@ -1621,8 +1748,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
 {
     struct r300_context* r300 = r300_context(pipe);
     struct r300_constant_buffer *cbuf;
-    struct pipe_transfer *tr;
-    float *mapped;
+    uint32_t *mapped = r300_buffer(buf)->user_buffer;
     int max_size = 0, max_size_bytes = 0, clamped_size = 0;
 
     switch (shader) {
@@ -1645,8 +1771,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
     max_size_bytes = max_size * 4 * sizeof(float);
 
     if (buf == NULL || buf->width0 == 0 ||
-        (mapped = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &tr)) == NULL)
-    {
+        (mapped = r300_buffer(buf)->constant_buffer) == NULL) {
         cbuf->count = 0;
         return;
     }
@@ -1664,17 +1789,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
 
         clamped_size = MIN2(buf->width0, max_size_bytes);
         cbuf->count = clamped_size / (4 * sizeof(float));
-
-        if (shader == PIPE_SHADER_FRAGMENT && !r300->screen->caps.is_r500) {
-            unsigned i,j;
-
-            /* Convert constants to float24. */
-            for (i = 0; i < cbuf->count; i++)
-                for (j = 0; j < 4; j++)
-                    cbuf->constants[i][j] = pack_float24(mapped[i*4+j]);
-        } else {
-            memcpy(cbuf->constants, mapped, clamped_size);
-        }
+        cbuf->ptr = mapped;
     }
 
     if (shader == PIPE_SHADER_VERTEX) {
@@ -1690,8 +1805,6 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
     } else if (shader == PIPE_SHADER_FRAGMENT) {
         r300->fs_constants.dirty = TRUE;
     }
-
-    pipe_buffer_unmap(pipe, buf, tr);
 }
 
 void r300_init_state_functions(struct r300_context* r300)
index 3aa8deb63c88fb0f4e31bbd517679c63c8aa09ab..a85db27064cea647406d69c879a4e8909efd4515 100644 (file)
@@ -102,7 +102,8 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300)
      * they won't be rasterized. */
     gen_count = 0;
     for (i = 0; i < ATTR_GENERIC_COUNT && gen_count < 8; i++) {
-        if (vs_outputs->generic[i] != ATTR_UNUSED) {
+        if (vs_outputs->generic[i] != ATTR_UNUSED &&
+            !(r300->sprite_coord_enable & (1 << i))) {
             r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
                                   vs_outputs->generic[i]);
             gen_count++;
@@ -118,7 +119,7 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300)
 
     /* WPOS. */
     if (r300_fs(r300)->shader->inputs.wpos != ATTR_UNUSED && gen_count < 8) {
-        DBG(r300, DBG_DRAW, "draw_emit_attrib: WPOS, index: %i\n",
+        DBG(r300, DBG_SWTCL, "draw_emit_attrib: WPOS, index: %i\n",
             vs_outputs->wpos);
         r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
                               vs_outputs->wpos);
@@ -140,18 +141,19 @@ static void r300_swtcl_vertex_psc(struct r300_context *r300)
     /* For each Draw attribute, route it to the fragment shader according
      * to the vs_output_tab. */
     attrib_count = vinfo->num_attribs;
-    DBG(r300, DBG_DRAW, "r300: attrib count: %d\n", attrib_count);
+    DBG(r300, DBG_SWTCL, "r300: attrib count: %d\n", attrib_count);
     for (i = 0; i < attrib_count; i++) {
-        DBG(r300, DBG_DRAW, "r300: attrib: index %d, interp %d, emit %d,"
-               " vs_output_tab %d\n", vinfo->attrib[i].src_index,
-               vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit,
-               vs_output_tab[i]);
-
-        /* Make sure we have a proper destination for our attribute. */
-        assert(vs_output_tab[i] != -1);
+        if (vs_output_tab[i] == -1) {
+            assert(0);
+            abort();
+        }
 
         format = draw_translate_vinfo_format(vinfo->attrib[i].emit);
 
+        DBG(r300, DBG_SWTCL,
+            "r300: swtcl_vertex_psc [%i] <- %s\n",
+            vs_output_tab[i], util_format_short_name(format));
+
         /* Obtain the type of data in this attribute. */
         type = r300_translate_vertex_data_type(format);
         if (type == R300_INVALID_FORMAT) {
@@ -526,15 +528,9 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
     struct r300_sampler_state *sampler;
     struct r300_sampler_view *view;
     struct r300_texture *tex;
-    unsigned min_level, max_level, i, size;
+    unsigned min_level, max_level, i, j, size;
     unsigned count = MIN2(state->sampler_view_count,
                           state->sampler_state_count);
-    unsigned char depth_swizzle[4] = {
-        UTIL_FORMAT_SWIZZLE_X,
-        UTIL_FORMAT_SWIZZLE_X,
-        UTIL_FORMAT_SWIZZLE_X,
-        UTIL_FORMAT_SWIZZLE_X
-    };
 
     /* The KIL opcode fix, see below. */
     if (!count && !r300->screen->caps.is_r500)
@@ -561,14 +557,29 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
             /* Assign a texture cache region. */
             texstate->format.format1 |= view->texcache_region;
 
-            /* If compare mode is disabled, the sampler view swizzles
-             * are stored in the format.
-             * Otherwise, swizzles must be applied after the compare mode
-             * in the fragment shader. */
-            if (util_format_is_depth_or_stencil(tex->b.b.format)) {
+            /* Depth textures are kinda special. */
+            if (util_format_is_depth_or_stencil(tex->desc.b.b.format)) {
+                unsigned char depth_swizzle[4];
+
+                if (!r300->screen->caps.is_r500 &&
+                    util_format_get_blocksizebits(tex->desc.b.b.format) == 32) {
+                    /* X24x8 is sampled as Y16X16 on r3xx-r4xx.
+                     * The depth here is at the Y component. */
+                    for (j = 0; j < 4; j++)
+                        depth_swizzle[j] = UTIL_FORMAT_SWIZZLE_Y;
+                } else {
+                    for (j = 0; j < 4; j++)
+                        depth_swizzle[j] = UTIL_FORMAT_SWIZZLE_X;
+                }
+
+                /* If compare mode is disabled, sampler view swizzles
+                 * are stored in the format.
+                 * Otherwise, the swizzles must be applied after the compare
+                 * mode in the fragment shader. */
                 if (sampler->state.compare_mode == PIPE_TEX_COMPARE_NONE) {
                     texstate->format.format1 |=
-                        r300_get_swizzle_combined(depth_swizzle, view->swizzle);
+                        r300_get_swizzle_combined(depth_swizzle,
+                                                  view->swizzle);
                 } else {
                     texstate->format.format1 |=
                         r300_get_swizzle_combined(depth_swizzle, 0);
@@ -576,12 +587,12 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
             }
 
             /* to emulate 1D textures through 2D ones correctly */
-            if (tex->b.b.target == PIPE_TEXTURE_1D) {
+            if (tex->desc.b.b.target == PIPE_TEXTURE_1D) {
                 texstate->filter0 &= ~R300_TX_WRAP_T_MASK;
                 texstate->filter0 |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE);
             }
 
-            if (tex->uses_pitch) {
+            if (tex->desc.is_npot) {
                 /* NPOT textures don't support mip filter, unfortunately.
                  * This prevents incorrect rendering. */
                 texstate->filter0 &= ~R300_TX_MIN_FILTER_MIP_MASK;
@@ -608,7 +619,7 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
                 /* determine min/max levels */
                 /* the MAX_MIP level is the largest (finest) one */
                 max_level = MIN3(sampler->max_lod + view->base.first_level,
-                                 tex->b.b.last_level, view->base.last_level);
+                                 tex->desc.b.b.last_level, view->base.last_level);
                 min_level = MIN2(sampler->min_lod + view->base.first_level,
                                  max_level);
                 texstate->format.format0 |= R300_TX_NUM_LEVELS(max_level);
diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c
deleted file mode 100644 (file)
index e67a0ae..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright 2009 Joakim Sindholt <opensource@zhasha.com>
- *                Corbin Simpson <MostAwesomeDude@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-#include "r300_context.h"
-#include "r300_cs.h"
-#include "r300_reg.h"
-#include "r300_screen.h"
-#include "r300_state_invariant.h"
-
-/* Calculate and emit invariant state. This is data that the 3D engine
- * will probably want at the beginning of every CS, but it's not currently
- * handled by any CSO setup, and in addition it doesn't really change much.
- *
- * Note that eventually this should be empty, but it's useful for development
- * and general unduplication of code. */
-void r300_emit_invariant_state(struct r300_context* r300,
-                               unsigned size, void* state)
-{
-    CS_LOCALS(r300);
-
-    BEGIN_CS(12 + (r300->screen->caps.has_tcl ? 2 : 0));
-
-    /*** Graphics Backend (GB) ***/
-    /* Source of fog depth */
-    OUT_CS_REG(R300_GB_SELECT, R300_GB_FOG_SELECT_1_1_W);
-
-    /*** Fog (FG) ***/
-    OUT_CS_REG(R300_FG_FOG_BLEND, 0x0);
-    OUT_CS_REG(R300_FG_FOG_COLOR_R, 0x0);
-    OUT_CS_REG(R300_FG_FOG_COLOR_G, 0x0);
-    OUT_CS_REG(R300_FG_FOG_COLOR_B, 0x0);
-
-    /*** VAP ***/
-    /* Sign/normalize control */
-    OUT_CS_REG(R300_VAP_PSC_SGN_NORM_CNTL, R300_SGN_NORM_NO_ZERO);
-    /* TCL-only stuff */
-    if (r300->screen->caps.has_tcl) {
-        /* Amount of time to wait for vertex fetches in PVS */
-        OUT_CS_REG(VAP_PVS_VTX_TIMEOUT_REG, 0xffff);
-    }
-
-    END_CS;
-
-    /* XXX unsorted stuff from surface_fill */
-    BEGIN_CS(38 + (r300->screen->caps.has_tcl ? 7 : 0) +
-             (r300->screen->caps.is_rv350 ? 4 : 0) +
-             (r300->screen->caps.is_r400 ? 2 : 0));
-
-    if (r300->screen->caps.has_tcl) {
-        /*Flushing PVS is required before the VAP_GB registers can be changed*/
-        OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0);
-        OUT_CS_REG_SEQ(R300_VAP_GB_VERT_CLIP_ADJ, 4);
-        OUT_CS_32F(1.0);
-        OUT_CS_32F(1.0);
-        OUT_CS_32F(1.0);
-        OUT_CS_32F(1.0);
-    }
-    /* XXX line tex stuffing */
-    OUT_CS_REG_SEQ(R300_GA_LINE_S0, 1);
-    OUT_CS_32F(0.0);
-    OUT_CS_REG_SEQ(R300_GA_LINE_S1, 1);
-    OUT_CS_32F(1.0);
-    OUT_CS_REG(R300_GA_TRIANGLE_STIPPLE, 0x5 |
-        (0x5 << R300_GA_TRIANGLE_STIPPLE_Y_SHIFT_SHIFT));
-    /* XXX this big chunk should be refactored into rs_state */
-    OUT_CS_REG(R300_GA_SOLID_RG, 0x00000000);
-    OUT_CS_REG(R300_GA_SOLID_BA, 0x00000000);
-    OUT_CS_REG(R300_GA_ROUND_MODE, 0x00000001);
-    OUT_CS_REG(R300_GA_OFFSET, 0x00000000);
-    OUT_CS_REG(R300_GA_FOG_SCALE, 0x3DBF1412);
-    OUT_CS_REG(R300_GA_FOG_OFFSET, 0x00000000);
-    OUT_CS_REG(R300_SU_TEX_WRAP, 0x00000000);
-    OUT_CS_REG(R300_SU_DEPTH_SCALE, 0x4B7FFFFF);
-    OUT_CS_REG(R300_SU_DEPTH_OFFSET, 0x00000000);
-    OUT_CS_REG(R300_SC_HYPERZ, 0x0000001C);
-    OUT_CS_REG(R300_SC_EDGERULE, 0x2DA49525);
-    OUT_CS_REG(R300_RB3D_AARESOLVE_CTL, 0x00000000);
-
-    if (r300->screen->caps.is_rv350) {
-        OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 0x01010101);
-        OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD, 0xFEFEFEFE);
-    }
-
-    OUT_CS_REG(R300_ZB_BW_CNTL, 0x00000000);
-    OUT_CS_REG(R300_ZB_DEPTHCLEARVALUE, 0x00000000);
-    OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0x00000000);
-    OUT_CS_REG(R300_ZB_HIZ_PITCH, 0x00000000);
-    if (r300->screen->caps.is_r400)
-        OUT_CS_REG(R400_US_CODE_BANK, 0);
-    END_CS;
-}
diff --git a/src/gallium/drivers/r300/r300_state_invariant.h b/src/gallium/drivers/r300/r300_state_invariant.h
deleted file mode 100644 (file)
index 83d031c..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) 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. */
-
-#ifndef R300_STATE_INVARIANT_H
-#define R300_STATE_INVARIANT_H
-
-struct r300_context;
-
-void r300_emit_invariant_state(struct r300_context* r300,
-                               unsigned size, void* state);
-
-#endif /* R300_STATE_INVARIANT_H */
index ddb66000561314e4f65e7c03fcdfcffeb021fd52..fcdca5605e934cd569227bbb0c9d8d285802f15d 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "r300_context.h"
 #include "r300_reg.h"
+#include "r300_texture_desc.h"
 #include "r300_transfer.h"
 #include "r300_screen.h"
 #include "r300_winsys.h"
 #include "util/u_memory.h"
 
 #include "pipe/p_screen.h"
-#include "state_tracker/drm_api.h"
-
-enum r300_dim {
-    DIM_WIDTH  = 0,
-    DIM_HEIGHT = 1
-};
 
 unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
                                    const unsigned char *swizzle_view)
@@ -110,7 +105,8 @@ unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
  * The FORMAT specifies how the texture sampler will treat the texture, and
  * makes available X, Y, Z, W, ZERO, and ONE for swizzling. */
 uint32_t r300_translate_texformat(enum pipe_format format,
-                                  const unsigned char *swizzle_view)
+                                  const unsigned char *swizzle_view,
+                                  boolean is_r500)
 {
     uint32_t result = 0;
     const struct util_format_description *desc;
@@ -135,7 +131,10 @@ uint32_t r300_translate_texformat(enum pipe_format format,
                     return R300_TX_FORMAT_X16;
                 case PIPE_FORMAT_X8Z24_UNORM:
                 case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
-                    return R500_TX_FORMAT_Y8X24;
+                    if (is_r500)
+                        return R500_TX_FORMAT_Y8X24;
+                    else
+                        return R300_TX_FORMAT_Y16X16;
                 default:
                     return ~0; /* Unsupported. */
             }
@@ -538,26 +537,27 @@ boolean r300_is_zs_format_supported(enum pipe_format format)
 
 boolean r300_is_sampler_format_supported(enum pipe_format format)
 {
-    return r300_translate_texformat(format, 0) != ~0;
+    return r300_translate_texformat(format, 0, TRUE) != ~0;
 }
 
 static void r300_texture_setup_immutable_state(struct r300_screen* screen,
                                                struct r300_texture* tex)
 {
     struct r300_texture_format_state* f = &tex->tx_format;
-    struct pipe_resource *pt = &tex->b.b;
+    struct pipe_resource *pt = &tex->desc.b.b;
     boolean is_r500 = screen->caps.is_r500;
 
     /* Set sampler state. */
     f->format0 = R300_TX_WIDTH((pt->width0 - 1) & 0x7ff) |
                  R300_TX_HEIGHT((pt->height0 - 1) & 0x7ff);
 
-    if (tex->uses_pitch) {
+    if (tex->desc.uses_stride_addressing) {
         /* rectangles love this */
         f->format0 |= R300_TX_PITCH_EN;
-        f->format2 = (tex->hwpitch[0] - 1) & 0x1fff;
+        f->format2 = (tex->desc.stride_in_pixels[0] - 1) & 0x1fff;
     } else {
-        /* power of two textures (3D, mipmaps, and no pitch) */
+        /* Power of two textures (3D, mipmaps, and no pitch),
+         * also NPOT textures with a width being POT. */
         f->format0 |= R300_TX_DEPTH(util_logbase2(pt->depth0) & 0xf);
     }
 
@@ -580,8 +580,8 @@ static void r300_texture_setup_immutable_state(struct r300_screen* screen,
         }
     }
 
-    f->tile_config = R300_TXO_MACRO_TILE(tex->macrotile) |
-                     R300_TXO_MICRO_TILE(tex->microtile);
+    f->tile_config = R300_TXO_MACRO_TILE(tex->desc.macrotile[0]) |
+                     R300_TXO_MICRO_TILE(tex->desc.microtile);
 }
 
 static void r300_texture_setup_fb_state(struct r300_screen* screen,
@@ -590,23 +590,23 @@ static void r300_texture_setup_fb_state(struct r300_screen* screen,
     unsigned i;
 
     /* Set framebuffer state. */
-    if (util_format_is_depth_or_stencil(tex->b.b.format)) {
-        for (i = 0; i <= tex->b.b.last_level; i++) {
+    if (util_format_is_depth_or_stencil(tex->desc.b.b.format)) {
+        for (i = 0; i <= tex->desc.b.b.last_level; i++) {
             tex->fb_state.pitch[i] =
-                tex->hwpitch[i] |
-                R300_DEPTHMACROTILE(tex->mip_macrotile[i]) |
-                R300_DEPTHMICROTILE(tex->microtile);
+                tex->desc.stride_in_pixels[i] |
+                R300_DEPTHMACROTILE(tex->desc.macrotile[i]) |
+                R300_DEPTHMICROTILE(tex->desc.microtile);
         }
-        tex->fb_state.format = r300_translate_zsformat(tex->b.b.format);
+        tex->fb_state.format = r300_translate_zsformat(tex->desc.b.b.format);
     } else {
-        for (i = 0; i <= tex->b.b.last_level; i++) {
+        for (i = 0; i <= tex->desc.b.b.last_level; i++) {
             tex->fb_state.pitch[i] =
-                tex->hwpitch[i] |
-                r300_translate_colorformat(tex->b.b.format) |
-                R300_COLOR_TILE(tex->mip_macrotile[i]) |
-                R300_COLOR_MICROTILE(tex->microtile);
+                tex->desc.stride_in_pixels[i] |
+                r300_translate_colorformat(tex->desc.b.b.format) |
+                R300_COLOR_TILE(tex->desc.macrotile[i]) |
+                R300_COLOR_MICROTILE(tex->desc.microtile);
         }
-        tex->fb_state.format = r300_translate_out_fmt(tex->b.b.format);
+        tex->fb_state.format = r300_translate_out_fmt(tex->desc.b.b.format);
     }
 }
 
@@ -626,282 +626,6 @@ void r300_texture_reinterpret_format(struct pipe_screen *screen,
     r300_texture_setup_fb_state(r300_screen(screen), r300_texture(tex));
 }
 
-unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level,
-                                 unsigned zslice, unsigned face)
-{
-    unsigned offset = tex->offset[level];
-
-    switch (tex->b.b.target) {
-        case PIPE_TEXTURE_3D:
-            assert(face == 0);
-            return offset + zslice * tex->layer_size[level];
-
-        case PIPE_TEXTURE_CUBE:
-            assert(zslice == 0);
-            return offset + face * tex->layer_size[level];
-
-        default:
-            assert(zslice == 0 && face == 0);
-            return offset;
-    }
-}
-
-/* Returns the number of pixels that the texture should be aligned to
- * in the given dimension. */
-static unsigned r300_get_pixel_alignment(struct r300_texture *tex,
-                                         enum r300_buffer_tiling macrotile,
-                                         enum r300_dim dim)
-{
-    static const unsigned table[2][5][3][2] =
-    {
-        {
-    /* Macro: linear    linear    linear
-       Micro: linear    tiled  square-tiled */
-            {{ 32, 1}, { 8,  4}, { 0,  0}}, /*   8 bits per pixel */
-            {{ 16, 1}, { 8,  2}, { 4,  4}}, /*  16 bits per pixel */
-            {{  8, 1}, { 4,  2}, { 0,  0}}, /*  32 bits per pixel */
-            {{  4, 1}, { 0,  0}, { 2,  2}}, /*  64 bits per pixel */
-            {{  2, 1}, { 0,  0}, { 0,  0}}  /* 128 bits per pixel */
-        },
-        {
-    /* Macro: tiled     tiled     tiled
-       Micro: linear    tiled  square-tiled */
-            {{256, 8}, {64, 32}, { 0,  0}}, /*   8 bits per pixel */
-            {{128, 8}, {64, 16}, {32, 32}}, /*  16 bits per pixel */
-            {{ 64, 8}, {32, 16}, { 0,  0}}, /*  32 bits per pixel */
-            {{ 32, 8}, { 0,  0}, {16, 16}}, /*  64 bits per pixel */
-            {{ 16, 8}, { 0,  0}, { 0,  0}}  /* 128 bits per pixel */
-        }
-    };
-    static const unsigned aa_block[2] = {4, 8};
-    unsigned res = 0;
-    unsigned pixsize = util_format_get_blocksize(tex->b.b.format);
-
-    assert(macrotile <= R300_BUFFER_TILED);
-    assert(tex->microtile <= R300_BUFFER_SQUARETILED);
-    assert(pixsize <= 16);
-    assert(dim <= DIM_HEIGHT);
-
-    if (tex->b.b.nr_samples > 1) {
-        /* Multisampled textures have their own alignment scheme. */
-        if (pixsize == 4)
-            res = aa_block[dim];
-    } else {
-        /* Standard alignment. */
-        res = table[macrotile][util_logbase2(pixsize)][tex->microtile][dim];
-    }
-
-    assert(res);
-    return res;
-}
-
-/* Return true if macrotiling should be enabled on the miplevel. */
-static boolean r300_texture_macro_switch(struct r300_texture *tex,
-                                         unsigned level,
-                                         boolean rv350_mode,
-                                         enum r300_dim dim)
-{
-    unsigned tile, texdim;
-
-    tile = r300_get_pixel_alignment(tex, R300_BUFFER_TILED, dim);
-    if (dim == DIM_WIDTH) {
-        texdim = u_minify(tex->b.b.width0, level);
-    } else {
-        texdim = u_minify(tex->b.b.height0, level);
-    }
-
-    /* See TX_FILTER1_n.MACRO_SWITCH. */
-    if (rv350_mode) {
-        return texdim >= tile;
-    } else {
-        return texdim > tile;
-    }
-}
-
-/**
- * Return the stride, in bytes, of the texture images of the given texture
- * at the given level.
- */
-unsigned r300_texture_get_stride(struct r300_screen* screen,
-                                 struct r300_texture* tex, unsigned level)
-{
-    unsigned tile_width, width, stride;
-
-    if (tex->stride_override)
-        return tex->stride_override;
-
-    /* Check the level. */
-    if (level > tex->b.b.last_level) {
-        SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n",
-                   __FUNCTION__, level, tex->b.b.last_level);
-        return 0;
-    }
-
-    width = u_minify(tex->b.b.width0, level);
-
-    if (util_format_is_plain(tex->b.b.format)) {
-        tile_width = r300_get_pixel_alignment(tex, tex->mip_macrotile[level],
-                                              DIM_WIDTH);
-        width = align(width, tile_width);
-
-        stride = util_format_get_stride(tex->b.b.format, width);
-
-        /* Some IGPs need a minimum stride of 64 bytes, hmm...
-         * This doesn't seem to apply to tiled textures, according to r300c. */
-        if (!tex->microtile && !tex->mip_macrotile[level] &&
-            (screen->caps.family == CHIP_FAMILY_RS600 ||
-             screen->caps.family == CHIP_FAMILY_RS690 ||
-             screen->caps.family == CHIP_FAMILY_RS740)) {
-            return stride < 64 ? 64 : stride;
-        }
-
-        /* The alignment to 32 bytes is sort of implied by the layout... */
-        return stride;
-    } else {
-        return align(util_format_get_stride(tex->b.b.format, width), 32);
-    }
-}
-
-static unsigned r300_texture_get_nblocksy(struct r300_texture* tex,
-                                          unsigned level)
-{
-    unsigned height, tile_height;
-
-    height = u_minify(tex->b.b.height0, level);
-
-    if (util_format_is_plain(tex->b.b.format)) {
-        tile_height = r300_get_pixel_alignment(tex, tex->mip_macrotile[level],
-                                               DIM_HEIGHT);
-        height = align(height, tile_height);
-
-        /* This is needed for the kernel checker, unfortunately. */
-        height = util_next_power_of_two(height);
-    }
-
-    return util_format_get_nblocksy(tex->b.b.format, height);
-}
-
-static void r300_texture_3d_fix_mipmapping(struct r300_screen *screen,
-                                           struct r300_texture *tex)
-{
-    /* The kernels <= 2.6.34-rc4 compute the size of mipmapped 3D textures
-     * incorrectly. This is a workaround to prevent CS from being rejected. */
-
-    unsigned i, size;
-
-    if (!screen->rws->get_value(screen->rws, R300_VID_DRM_2_3_0) &&
-        tex->b.b.target == PIPE_TEXTURE_3D &&
-        tex->b.b.last_level > 0) {
-        size = 0;
-
-        for (i = 0; i <= tex->b.b.last_level; i++) {
-            size += r300_texture_get_stride(screen, tex, i) *
-                    r300_texture_get_nblocksy(tex, i);
-        }
-
-        size *= tex->b.b.depth0;
-        tex->size = size;
-    }
-}
-
-static void r300_setup_miptree(struct r300_screen* screen,
-                               struct r300_texture* tex)
-{
-    struct pipe_resource* base = &tex->b.b;
-    unsigned stride, size, layer_size, nblocksy, i;
-    boolean rv350_mode = screen->caps.is_rv350;
-
-    SCREEN_DBG(screen, DBG_TEXALLOC,
-        "r300: Making miptree for texture, format %s\n",
-        util_format_short_name(base->format));
-
-    for (i = 0; i <= base->last_level; i++) {
-        /* Let's see if this miplevel can be macrotiled. */
-        tex->mip_macrotile[i] =
-            (tex->macrotile == R300_BUFFER_TILED &&
-             r300_texture_macro_switch(tex, i, rv350_mode, DIM_WIDTH) &&
-             r300_texture_macro_switch(tex, i, rv350_mode, DIM_HEIGHT)) ?
-             R300_BUFFER_TILED : R300_BUFFER_LINEAR;
-
-        stride = r300_texture_get_stride(screen, tex, i);
-        nblocksy = r300_texture_get_nblocksy(tex, i);
-        layer_size = stride * nblocksy;
-
-        if (base->nr_samples) {
-            layer_size *= base->nr_samples;
-        }
-
-        if (base->target == PIPE_TEXTURE_CUBE)
-            size = layer_size * 6;
-        else
-            size = layer_size * u_minify(base->depth0, i);
-
-        tex->offset[i] = tex->size;
-        tex->size = tex->offset[i] + size;
-        tex->layer_size[i] = layer_size;
-        tex->pitch[i] = stride / util_format_get_blocksize(base->format);
-        tex->hwpitch[i] =
-                tex->pitch[i] * util_format_get_blockwidth(base->format);
-
-        SCREEN_DBG(screen, DBG_TEXALLOC, "r300: Texture miptree: Level %d "
-                "(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n",
-                i, u_minify(base->width0, i), u_minify(base->height0, i),
-                u_minify(base->depth0, i), stride, tex->size,
-                tex->mip_macrotile[i] ? "TRUE" : "FALSE");
-    }
-}
-
-static void r300_setup_flags(struct r300_texture* tex)
-{
-    tex->uses_pitch = !util_is_power_of_two(tex->b.b.width0) ||
-                      !util_is_power_of_two(tex->b.b.height0) ||
-                      tex->stride_override;
-}
-
-static void r300_setup_tiling(struct pipe_screen *screen,
-                              struct r300_texture *tex)
-{
-    struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
-    enum pipe_format format = tex->b.b.format;
-    boolean rv350_mode = r300_screen(screen)->caps.is_rv350;
-    boolean is_zb = util_format_is_depth_or_stencil(format);
-    boolean dbg_no_tiling = SCREEN_DBG_ON(r300_screen(screen), DBG_NO_TILING);
-
-    if (!util_format_is_plain(format)) {
-        return;
-    }
-
-    /* If height == 1, disable microtiling except for zbuffer. */
-    if (!is_zb && (tex->b.b.height0 == 1 || dbg_no_tiling)) {
-        return;
-    }
-
-    /* Set microtiling. */
-    switch (util_format_get_blocksize(format)) {
-        case 1:
-        case 4:
-            tex->microtile = R300_BUFFER_TILED;
-            break;
-
-        case 2:
-        case 8:
-            if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT)) {
-                tex->microtile = R300_BUFFER_SQUARETILED;
-            }
-            break;
-    }
-
-    if (dbg_no_tiling) {
-        return;
-    }
-
-    /* Set macrotiling. */
-    if (r300_texture_macro_switch(tex, 0, rv350_mode, DIM_WIDTH) &&
-        r300_texture_macro_switch(tex, 0, rv350_mode, DIM_HEIGHT)) {
-        tex->macrotile = R300_BUFFER_TILED;
-    }
-}
-
 static unsigned r300_texture_is_referenced(struct pipe_context *context,
                                         struct pipe_resource *texture,
                                         unsigned face, unsigned level)
@@ -909,7 +633,8 @@ static unsigned r300_texture_is_referenced(struct pipe_context *context,
     struct r300_context *r300 = r300_context(context);
     struct r300_texture *rtex = (struct r300_texture *)texture;
 
-    if (r300->rws->is_buffer_referenced(r300->rws, rtex->buffer, R300_REF_CS))
+    if (r300->rws->cs_is_buffer_referenced(r300->cs,
+                                           rtex->buffer, R300_REF_CS))
         return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
 
     return PIPE_UNREFERENCED;
@@ -936,12 +661,11 @@ static boolean r300_texture_get_handle(struct pipe_screen* screen,
         return FALSE;
     }
 
-    whandle->stride = r300_texture_get_stride(r300_screen(screen), tex, 0);
-
-    return rws->buffer_get_handle(rws, tex->buffer, whandle);
+    return rws->buffer_get_handle(rws, tex->buffer,
+                                  tex->desc.stride_in_bytes[0], whandle);
 }
 
-struct u_resource_vtbl r300_texture_vtbl = 
+struct u_resource_vtbl r300_texture_vtbl =
 {
    r300_texture_get_handle,          /* get_handle */
    r300_texture_destroy,             /* resource_destroy */
@@ -954,17 +678,69 @@ struct u_resource_vtbl r300_texture_vtbl =
    u_default_transfer_inline_write    /* transfer_inline_write */
 };
 
-/* Create a new texture. */
-struct pipe_resource* r300_texture_create(struct pipe_screen* screen,
-                                          const struct pipe_resource* base)
+/* The common texture constructor. */
+static struct r300_texture*
+r300_texture_create_object(struct r300_screen *rscreen,
+                           const struct pipe_resource *base,
+                           enum r300_buffer_tiling microtile,
+                           enum r300_buffer_tiling macrotile,
+                           unsigned stride_in_bytes_override,
+                           unsigned max_buffer_size,
+                           struct r300_winsys_buffer *buffer)
 {
-    struct r300_texture* tex = CALLOC_STRUCT(r300_texture);
-    struct r300_screen* rscreen = r300_screen(screen);
-    struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
-
+    struct r300_winsys_screen *rws = rscreen->rws;
+    struct r300_texture *tex = CALLOC_STRUCT(r300_texture);
     if (!tex) {
+        if (buffer)
+            rws->buffer_reference(rws, &buffer, NULL);
+        return NULL;
+    }
+
+    /* Initialize the descriptor. */
+    if (!r300_texture_desc_init(rscreen, &tex->desc, base,
+                                microtile, macrotile,
+                                stride_in_bytes_override,
+                                max_buffer_size)) {
+        if (buffer)
+            rws->buffer_reference(rws, &buffer, NULL);
+        FREE(tex);
         return NULL;
     }
+    /* Initialize the hardware state. */
+    r300_texture_setup_immutable_state(rscreen, tex);
+    r300_texture_setup_fb_state(rscreen, tex);
+
+    tex->desc.b.vtbl = &r300_texture_vtbl;
+    pipe_reference_init(&tex->desc.b.b.reference, 1);
+    tex->domain = base->flags & R300_RESOURCE_FLAG_TRANSFER ?
+                  R300_DOMAIN_GTT :
+                  R300_DOMAIN_VRAM | R300_DOMAIN_GTT;
+    tex->buffer = buffer;
+
+    /* Create the backing buffer if needed. */
+    if (!tex->buffer) {
+        tex->buffer = rws->buffer_create(rws, tex->desc.size_in_bytes, 2048,
+                                         base->bind, base->usage, tex->domain);
+
+        if (!tex->buffer) {
+            FREE(tex);
+            return NULL;
+        }
+    }
+
+    rws->buffer_set_tiling(rws, tex->buffer,
+            tex->desc.microtile, tex->desc.macrotile[0],
+            tex->desc.stride_in_bytes[0]);
+
+    return tex;
+}
+
+/* Create a new texture. */
+struct pipe_resource *r300_texture_create(struct pipe_screen *screen,
+                                          const struct pipe_resource *base)
+{
+    struct r300_screen *rscreen = r300_screen(screen);
+    enum r300_buffer_tiling microtile, macrotile;
 
     /* Refuse to create a texture with size 0. */
     if (!base->width0 ||
@@ -974,58 +750,70 @@ struct pipe_resource* r300_texture_create(struct pipe_screen* screen,
         fprintf(stderr, "r300: texture_create: "
                 "Got invalid texture dimensions: %ix%ix%i\n",
                 base->width0, base->height0, base->depth0);
-        FREE(tex);
         return NULL;
     }
 
-    tex->b.b = *base;
-    tex->b.vtbl = &r300_texture_vtbl;
-    pipe_reference_init(&tex->b.b.reference, 1);
-    tex->b.b.screen = screen;
+    if ((base->flags & R300_RESOURCE_FLAG_TRANSFER) ||
+        (base->bind & PIPE_BIND_SCANOUT)) {
+        microtile = R300_BUFFER_LINEAR;
+        macrotile = R300_BUFFER_LINEAR;
+    } else {
+        microtile = R300_BUFFER_SELECT_LAYOUT;
+        macrotile = R300_BUFFER_SELECT_LAYOUT;
+    }
+
+    return (struct pipe_resource*)
+           r300_texture_create_object(rscreen, base, microtile, macrotile,
+                                      0, 0, NULL);
+}
+
+struct pipe_resource *r300_texture_from_handle(struct pipe_screen *screen,
+                                               const struct pipe_resource *base,
+                                               struct winsys_handle *whandle)
+{
+    struct r300_winsys_screen *rws = (struct r300_winsys_screen*)screen->winsys;
+    struct r300_screen *rscreen = r300_screen(screen);
+    struct r300_winsys_buffer *buffer;
+    enum r300_buffer_tiling microtile, macrotile;
+    unsigned stride, size;
 
-    r300_setup_flags(tex);
-    if (!(base->flags & R300_RESOURCE_FLAG_TRANSFER) &&
-        !(base->bind & PIPE_BIND_SCANOUT)) {
-        r300_setup_tiling(screen, tex);
+    /* Support only 2D textures without mipmaps */
+    if (base->target != PIPE_TEXTURE_2D ||
+        base->depth0 != 1 ||
+        base->last_level != 0) {
+        return NULL;
     }
-    r300_setup_miptree(rscreen, tex);
-    r300_texture_3d_fix_mipmapping(rscreen, tex);
-    r300_texture_setup_immutable_state(rscreen, tex);
-    r300_texture_setup_fb_state(rscreen, tex);
 
-    SCREEN_DBG(rscreen, DBG_TEX,
-               "r300: texture_create: Macro: %s, Micro: %s, Pitch: %i, "
-               "Dim: %ix%ix%i, LastLevel: %i, Size: %i, Format: %s\n",
-               tex->macrotile ? "YES" : " NO",
-               tex->microtile ? "YES" : " NO",
-               tex->hwpitch[0],
-               base->width0, base->height0, base->depth0, base->last_level,
-               tex->size,
-               util_format_short_name(base->format));
+    buffer = rws->buffer_from_handle(rws, whandle, &stride, &size);
+    if (!buffer)
+        return NULL;
 
-    tex->domain = base->flags & R300_RESOURCE_FLAG_TRANSFER ? R300_DOMAIN_GTT :
-                                                              R300_DOMAIN_VRAM;
+    rws->buffer_get_tiling(rws, buffer, &microtile, &macrotile);
 
-    tex->buffer = rws->buffer_create(rws, 2048, base->bind, tex->domain,
-                                     tex->size);
+    /* Enforce a microtiled zbuffer. */
+    if (util_format_is_depth_or_stencil(base->format) &&
+        microtile == R300_BUFFER_LINEAR) {
+        switch (util_format_get_blocksize(base->format)) {
+            case 4:
+                microtile = R300_BUFFER_TILED;
+                break;
 
-    if (!tex->buffer) {
-       FREE(tex);
-       return NULL;
+            case 2:
+                if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT))
+                    microtile = R300_BUFFER_SQUARETILED;
+                break;
+        }
     }
 
-    rws->buffer_set_tiling(rws, tex->buffer,
-            tex->pitch[0] * util_format_get_blocksize(tex->b.b.format),
-            tex->microtile,
-            tex->macrotile);
-
-    return (struct pipe_resource*)tex;
+    return (struct pipe_resource*)
+           r300_texture_create_object(rscreen, base, microtile, macrotile,
+                                      stride, size, buffer);
 }
 
 /* Not required to implement u_resource_vtbl, consider moving to another file:
  */
 struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen,
-                                         struct pipe_resource* texture,
+                                          struct pipe_resource* texture,
                                          unsigned face,
                                          unsigned level,
                                          unsigned zslice,
@@ -1035,6 +823,8 @@ struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen,
     struct r300_surface* surface = CALLOC_STRUCT(r300_surface);
 
     if (surface) {
+        uint32_t offset, tile_height;
+
         pipe_reference_init(&surface->base.reference, 1);
         pipe_resource_reference(&surface->base.texture, texture);
         surface->base.format = texture->format;
@@ -1046,10 +836,49 @@ struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen,
         surface->base.level = level;
 
         surface->buffer = tex->buffer;
+
+        /* Prefer VRAM if there are multiple domains to choose from. */
         surface->domain = tex->domain;
-        surface->offset = r300_texture_get_offset(tex, level, zslice, face);
+        if (surface->domain & R300_DOMAIN_VRAM)
+            surface->domain &= ~R300_DOMAIN_GTT;
+
+        surface->offset = r300_texture_get_offset(&tex->desc,
+                                                  level, zslice, face);
         surface->pitch = tex->fb_state.pitch[level];
         surface->format = tex->fb_state.format;
+
+        /* Parameters for the CBZB clear. */
+        surface->cbzb_allowed = tex->desc.cbzb_allowed[level];
+        surface->cbzb_width = align(surface->base.width, 64);
+
+        /* Height must be aligned to the size of a tile. */
+        tile_height = r300_get_pixel_alignment(tex->desc.b.b.format,
+                                               tex->desc.b.b.nr_samples,
+                                               tex->desc.microtile,
+                                               tex->desc.macrotile[level],
+                                               DIM_HEIGHT);
+
+        surface->cbzb_height = align((surface->base.height + 1) / 2,
+                                     tile_height);
+
+        /* Offset must be aligned to 2K and must point at the beginning
+         * of a scanline. */
+        offset = surface->offset +
+                 tex->desc.stride_in_bytes[level] * surface->cbzb_height;
+        surface->cbzb_midpoint_offset = offset & ~2047;
+
+        surface->cbzb_pitch = surface->pitch & 0x1ffffc;
+
+        if (util_format_get_blocksizebits(surface->base.format) == 32)
+            surface->cbzb_format = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
+        else
+            surface->cbzb_format = R300_DEPTHFORMAT_16BIT_INT_Z;
+
+        SCREEN_DBG(r300_screen(screen), DBG_CBZB,
+                   "CBZB Dim: %ix%i, Misalignment: %i, Macro: %s\n",
+                   surface->cbzb_width, surface->cbzb_height,
+                   offset & 2047,
+                   tex->desc.macrotile[level] ? "YES" : " NO");
     }
 
     return &surface->base;
@@ -1062,88 +891,3 @@ void r300_tex_surface_destroy(struct pipe_surface* s)
     pipe_resource_reference(&s->texture, NULL);
     FREE(s);
 }
-
-struct pipe_resource*
-r300_texture_from_handle(struct pipe_screen* screen,
-                         const struct pipe_resource* base,
-                         struct winsys_handle *whandle)
-{
-    struct r300_winsys_screen *rws = (struct r300_winsys_screen*)screen->winsys;
-    struct r300_screen* rscreen = r300_screen(screen);
-    struct r300_winsys_buffer *buffer;
-    struct r300_texture* tex;
-    boolean override_zb_flags;
-
-    /* Support only 2D textures without mipmaps */
-    if (base->target != PIPE_TEXTURE_2D ||
-        base->depth0 != 1 ||
-        base->last_level != 0) {
-        return NULL;
-    }
-
-    buffer = rws->buffer_from_handle(rws, whandle->handle);
-    if (!buffer) {
-        return NULL;
-    }
-
-    tex = CALLOC_STRUCT(r300_texture);
-    if (!tex) {
-        return NULL;
-    }
-
-    tex->b.b = *base;
-    tex->b.vtbl = &r300_texture_vtbl;
-    pipe_reference_init(&tex->b.b.reference, 1);
-    tex->b.b.screen = screen;
-    tex->domain = R300_DOMAIN_VRAM;
-
-    tex->stride_override = whandle->stride;
-
-    /* one ref already taken */
-    tex->buffer = buffer;
-
-    rws->buffer_get_tiling(rws, buffer, &tex->microtile, &tex->macrotile);
-    r300_setup_flags(tex);
-    SCREEN_DBG(rscreen, DBG_TEX,
-               "r300: texture_from_handle: Macro: %s, Micro: %s, "
-               "Pitch: % 4i, Dim: %ix%i, Format: %s\n",
-               tex->macrotile ? "YES" : " NO",
-               tex->microtile ? "YES" : " NO",
-               whandle->stride / util_format_get_blocksize(base->format),
-               base->width0, base->height0,
-               util_format_short_name(base->format));
-
-    /* Enforce microtiled zbuffer. */
-    override_zb_flags = util_format_is_depth_or_stencil(base->format) &&
-                        tex->microtile == R300_BUFFER_LINEAR;
-
-    if (override_zb_flags) {
-        switch (util_format_get_blocksize(base->format)) {
-            case 4:
-                tex->microtile = R300_BUFFER_TILED;
-                break;
-
-            case 2:
-                if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT)) {
-                    tex->microtile = R300_BUFFER_SQUARETILED;
-                    break;
-                }
-                /* Pass through. */
-
-            default:
-                override_zb_flags = FALSE;
-        }
-    }
-
-    r300_setup_miptree(rscreen, tex);
-    r300_texture_setup_immutable_state(rscreen, tex);
-    r300_texture_setup_fb_state(rscreen, tex);
-
-    if (override_zb_flags) {
-        rws->buffer_set_tiling(rws, tex->buffer,
-                tex->pitch[0] * util_format_get_blocksize(tex->b.b.format),
-                tex->microtile,
-                tex->macrotile);
-    }
-    return (struct pipe_resource*)tex;
-}
index 99e7694254e071d5daac13e92545c1a33711e6e4..a4524320fdac7cdb6e9b445abaa842be6ad7a254 100644 (file)
@@ -35,16 +35,11 @@ unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
                                    const unsigned char *swizzle_view);
 
 uint32_t r300_translate_texformat(enum pipe_format format,
-                                  const unsigned char *swizzle_view);
+                                  const unsigned char *swizzle_view,
+                                  boolean is_r500);
 
 uint32_t r500_tx_format_msb_bit(enum pipe_format format);
 
-unsigned r300_texture_get_stride(struct r300_screen* screen,
-                                 struct r300_texture* tex, unsigned level);
-
-unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level,
-                                 unsigned zslice, unsigned face);
-
 void r300_texture_reinterpret_format(struct pipe_screen *screen,
                                      struct pipe_resource *tex,
                                      enum pipe_format new_format);
diff --git a/src/gallium/drivers/r300/r300_texture_desc.c b/src/gallium/drivers/r300/r300_texture_desc.c
new file mode 100644 (file)
index 0000000..343089b
--- /dev/null
@@ -0,0 +1,465 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2010 Marek Olšák <maraeo@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "r300_texture_desc.h"
+
+#include "r300_context.h"
+#include "r300_winsys.h"
+
+#include "util/u_format.h"
+
+/* Returns the number of pixels that the texture should be aligned to
+ * in the given dimension. */
+unsigned r300_get_pixel_alignment(enum pipe_format format,
+                                  unsigned num_samples,
+                                  enum r300_buffer_tiling microtile,
+                                  enum r300_buffer_tiling macrotile,
+                                  enum r300_dim dim)
+{
+    static const unsigned table[2][5][3][2] =
+    {
+        {
+    /* Macro: linear    linear    linear
+       Micro: linear    tiled  square-tiled */
+            {{ 32, 1}, { 8,  4}, { 0,  0}}, /*   8 bits per pixel */
+            {{ 16, 1}, { 8,  2}, { 4,  4}}, /*  16 bits per pixel */
+            {{  8, 1}, { 4,  2}, { 0,  0}}, /*  32 bits per pixel */
+            {{  4, 1}, { 0,  0}, { 2,  2}}, /*  64 bits per pixel */
+            {{  2, 1}, { 0,  0}, { 0,  0}}  /* 128 bits per pixel */
+        },
+        {
+    /* Macro: tiled     tiled     tiled
+       Micro: linear    tiled  square-tiled */
+            {{256, 8}, {64, 32}, { 0,  0}}, /*   8 bits per pixel */
+            {{128, 8}, {64, 16}, {32, 32}}, /*  16 bits per pixel */
+            {{ 64, 8}, {32, 16}, { 0,  0}}, /*  32 bits per pixel */
+            {{ 32, 8}, { 0,  0}, {16, 16}}, /*  64 bits per pixel */
+            {{ 16, 8}, { 0,  0}, { 0,  0}}  /* 128 bits per pixel */
+        }
+    };
+    static const unsigned aa_block[2] = {4, 8};
+    unsigned tile = 0;
+    unsigned pixsize = util_format_get_blocksize(format);
+
+    assert(macrotile <= R300_BUFFER_TILED);
+    assert(microtile <= R300_BUFFER_SQUARETILED);
+    assert(pixsize <= 16);
+    assert(dim <= DIM_HEIGHT);
+
+    if (num_samples > 1) {
+        /* Multisampled textures have their own alignment scheme. */
+        if (pixsize == 4)
+            tile = aa_block[dim];
+        /* XXX FP16 AA. */
+    } else {
+        /* Standard alignment. */
+        tile = table[macrotile][util_logbase2(pixsize)][microtile][dim];
+    }
+
+    assert(tile);
+    return tile;
+}
+
+/* Return true if macrotiling should be enabled on the miplevel. */
+static boolean r300_texture_macro_switch(struct r300_texture_desc *desc,
+                                         unsigned level,
+                                         boolean rv350_mode,
+                                         enum r300_dim dim)
+{
+    unsigned tile, texdim;
+
+    tile = r300_get_pixel_alignment(desc->b.b.format, desc->b.b.nr_samples,
+                                    desc->microtile, R300_BUFFER_TILED, dim);
+    if (dim == DIM_WIDTH) {
+        texdim = u_minify(desc->b.b.width0, level);
+    } else {
+        texdim = u_minify(desc->b.b.height0, level);
+    }
+
+    /* See TX_FILTER1_n.MACRO_SWITCH. */
+    if (rv350_mode) {
+        return texdim >= tile;
+    } else {
+        return texdim > tile;
+    }
+}
+
+/**
+ * Return the stride, in bytes, of the texture image of the given texture
+ * at the given level.
+ */
+static unsigned r300_texture_get_stride(struct r300_screen *screen,
+                                        struct r300_texture_desc *desc,
+                                        unsigned level)
+{
+    unsigned tile_width, width, stride;
+
+    if (desc->stride_in_bytes_override)
+        return desc->stride_in_bytes_override;
+
+    /* Check the level. */
+    if (level > desc->b.b.last_level) {
+        SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n",
+                   __FUNCTION__, level, desc->b.b.last_level);
+        return 0;
+    }
+
+    width = u_minify(desc->b.b.width0, level);
+
+    if (util_format_is_plain(desc->b.b.format)) {
+        tile_width = r300_get_pixel_alignment(desc->b.b.format,
+                                              desc->b.b.nr_samples,
+                                              desc->microtile,
+                                              desc->macrotile[level],
+                                              DIM_WIDTH);
+        width = align(width, tile_width);
+
+        stride = util_format_get_stride(desc->b.b.format, width);
+
+        /* Some IGPs need a minimum stride of 64 bytes, hmm...
+         * This doesn't seem to apply to tiled textures, according to r300c. */
+        if (!desc->microtile && !desc->macrotile[level] &&
+            (screen->caps.family == CHIP_FAMILY_RS600 ||
+             screen->caps.family == CHIP_FAMILY_RS690 ||
+             screen->caps.family == CHIP_FAMILY_RS740)) {
+            return stride < 64 ? 64 : stride;
+        }
+
+        /* The alignment to 32 bytes is sort of implied by the layout... */
+        return stride;
+    } else {
+        return align(util_format_get_stride(desc->b.b.format, width), 32);
+    }
+}
+
+static unsigned r300_texture_get_nblocksy(struct r300_texture_desc *desc,
+                                          unsigned level,
+                                          boolean *out_aligned_for_cbzb)
+{
+    unsigned height, tile_height;
+
+    height = u_minify(desc->b.b.height0, level);
+
+    if (util_format_is_plain(desc->b.b.format)) {
+        tile_height = r300_get_pixel_alignment(desc->b.b.format,
+                                               desc->b.b.nr_samples,
+                                               desc->microtile,
+                                               desc->macrotile[level],
+                                               DIM_HEIGHT);
+        height = align(height, tile_height);
+
+        /* This is needed for the kernel checker, unfortunately. */
+        if ((desc->b.b.target != PIPE_TEXTURE_1D &&
+             desc->b.b.target != PIPE_TEXTURE_2D) ||
+            desc->b.b.last_level != 0) {
+            height = util_next_power_of_two(height);
+        }
+
+        /* See if the CBZB clear can be used on the buffer,
+         * taking the texture size into account. */
+        if (out_aligned_for_cbzb) {
+            if (desc->macrotile[level]) {
+                /* When clearing, the layer (width*height) is horizontally split
+                 * into two, and the upper and lower halves are cleared by the CB
+                 * and ZB units, respectively. Therefore, the number of macrotiles
+                 * in the Y direction must be even. */
+
+                /* Align the height so that there is an even number of macrotiles.
+                 * Do so for 3 or more macrotiles in the Y direction. */
+                if (level == 0 && desc->b.b.last_level == 0 &&
+                    (desc->b.b.target == PIPE_TEXTURE_1D ||
+                     desc->b.b.target == PIPE_TEXTURE_2D) &&
+                    height >= tile_height * 3) {
+                    height = align(height, tile_height * 2);
+                }
+
+                *out_aligned_for_cbzb = height % (tile_height * 2) == 0;
+            } else {
+                *out_aligned_for_cbzb = FALSE;
+            }
+        }
+    }
+
+    return util_format_get_nblocksy(desc->b.b.format, height);
+}
+
+static void r300_texture_3d_fix_mipmapping(struct r300_screen *screen,
+                                           struct r300_texture_desc *desc)
+{
+    /* The kernels <= 2.6.34-rc4 compute the size of mipmapped 3D textures
+     * incorrectly. This is a workaround to prevent CS from being rejected. */
+
+    unsigned i, size;
+
+    if (!screen->rws->get_value(screen->rws, R300_VID_DRM_2_3_0) &&
+        desc->b.b.target == PIPE_TEXTURE_3D &&
+        desc->b.b.last_level > 0) {
+        size = 0;
+
+        for (i = 0; i <= desc->b.b.last_level; i++) {
+            size += desc->stride_in_bytes[i] *
+                    r300_texture_get_nblocksy(desc, i, FALSE);
+        }
+
+        size *= desc->b.b.depth0;
+        desc->size_in_bytes = size;
+    }
+}
+
+/* Get a width in pixels from a stride in bytes. */
+static unsigned stride_to_width(enum pipe_format format,
+                                unsigned stride_in_bytes)
+{
+    return (stride_in_bytes / util_format_get_blocksize(format)) *
+            util_format_get_blockwidth(format);
+}
+
+static void r300_setup_miptree(struct r300_screen *screen,
+                               struct r300_texture_desc *desc,
+                               boolean align_for_cbzb)
+{
+    struct pipe_resource *base = &desc->b.b;
+    unsigned stride, size, layer_size, nblocksy, i;
+    boolean rv350_mode = screen->caps.is_rv350;
+    boolean aligned_for_cbzb;
+
+    desc->size_in_bytes = 0;
+
+    SCREEN_DBG(screen, DBG_TEXALLOC,
+        "r300: Making miptree for texture, format %s\n",
+        util_format_short_name(base->format));
+
+    for (i = 0; i <= base->last_level; i++) {
+        /* Let's see if this miplevel can be macrotiled. */
+        desc->macrotile[i] =
+            (desc->macrotile[0] == R300_BUFFER_TILED &&
+             r300_texture_macro_switch(desc, i, rv350_mode, DIM_WIDTH) &&
+             r300_texture_macro_switch(desc, i, rv350_mode, DIM_HEIGHT)) ?
+             R300_BUFFER_TILED : R300_BUFFER_LINEAR;
+
+        stride = r300_texture_get_stride(screen, desc, i);
+
+        /* Compute the number of blocks in Y, see if the CBZB clear can be
+         * used on the texture. */
+        aligned_for_cbzb = FALSE;
+        if (align_for_cbzb && desc->cbzb_allowed[i])
+            nblocksy = r300_texture_get_nblocksy(desc, i, &aligned_for_cbzb);
+        else
+            nblocksy = r300_texture_get_nblocksy(desc, i, NULL);
+
+        layer_size = stride * nblocksy;
+
+        if (base->nr_samples) {
+            layer_size *= base->nr_samples;
+        }
+
+        if (base->target == PIPE_TEXTURE_CUBE)
+            size = layer_size * 6;
+        else
+            size = layer_size * u_minify(base->depth0, i);
+
+        desc->offset_in_bytes[i] = desc->size_in_bytes;
+        desc->size_in_bytes = desc->offset_in_bytes[i] + size;
+        desc->layer_size_in_bytes[i] = layer_size;
+        desc->stride_in_bytes[i] = stride;
+        desc->stride_in_pixels[i] = stride_to_width(desc->b.b.format, stride);
+        desc->cbzb_allowed[i] = desc->cbzb_allowed[i] && aligned_for_cbzb;
+
+        SCREEN_DBG(screen, DBG_TEXALLOC, "r300: Texture miptree: Level %d "
+                "(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n",
+                i, u_minify(base->width0, i), u_minify(base->height0, i),
+                u_minify(base->depth0, i), stride, desc->size_in_bytes,
+                desc->macrotile[i] ? "TRUE" : "FALSE");
+    }
+}
+
+static void r300_setup_flags(struct r300_texture_desc *desc)
+{
+    desc->uses_stride_addressing =
+        !util_is_power_of_two(desc->b.b.width0) ||
+        !util_is_power_of_two(desc->b.b.height0) ||
+        (desc->stride_in_bytes_override &&
+         stride_to_width(desc->b.b.format,
+                         desc->stride_in_bytes_override) != desc->b.b.width0);
+
+    desc->is_npot =
+        desc->uses_stride_addressing ||
+        !util_is_power_of_two(desc->b.b.height0);
+}
+
+static void r300_setup_cbzb_flags(struct r300_screen *rscreen,
+                                  struct r300_texture_desc *desc)
+{
+    unsigned i, bpp;
+    boolean first_level_valid;
+
+    bpp = util_format_get_blocksizebits(desc->b.b.format);
+
+    /* 1) The texture must be point-sampled,
+     * 2) The depth must be 16 or 32 bits.
+     * 3) If the midpoint ZB offset is not aligned to 2048, it returns garbage
+     *    with certain texture sizes. Macrotiling ensures the alignment. */
+    first_level_valid = desc->b.b.nr_samples <= 1 &&
+                       (bpp == 16 || bpp == 32) &&
+                       desc->macrotile[0];
+
+    for (i = 0; i <= desc->b.b.last_level; i++)
+        desc->cbzb_allowed[i] = first_level_valid && desc->macrotile[i];
+}
+
+static void r300_setup_tiling(struct r300_screen *screen,
+                              struct r300_texture_desc *desc)
+{
+    struct r300_winsys_screen *rws = screen->rws;
+    enum pipe_format format = desc->b.b.format;
+    boolean rv350_mode = screen->caps.is_rv350;
+    boolean is_zb = util_format_is_depth_or_stencil(format);
+    boolean dbg_no_tiling = SCREEN_DBG_ON(screen, DBG_NO_TILING);
+
+    if (!util_format_is_plain(format)) {
+        return;
+    }
+
+    /* If height == 1, disable microtiling except for zbuffer. */
+    if (!is_zb && (desc->b.b.height0 == 1 || dbg_no_tiling)) {
+        return;
+    }
+
+    /* Set microtiling. */
+    switch (util_format_get_blocksize(format)) {
+        case 1:
+        case 4:
+            desc->microtile = R300_BUFFER_TILED;
+            break;
+
+        case 2:
+        case 8:
+            if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT)) {
+                desc->microtile = R300_BUFFER_SQUARETILED;
+            }
+            break;
+    }
+
+    if (dbg_no_tiling) {
+        return;
+    }
+
+    /* Set macrotiling. */
+    if (r300_texture_macro_switch(desc, 0, rv350_mode, DIM_WIDTH) &&
+        r300_texture_macro_switch(desc, 0, rv350_mode, DIM_HEIGHT)) {
+        desc->macrotile[0] = R300_BUFFER_TILED;
+    }
+}
+
+static void r300_tex_print_info(struct r300_screen *rscreen,
+                                struct r300_texture_desc *desc,
+                                const char *func)
+{
+    fprintf(stderr,
+            "r300: %s: Macro: %s, Micro: %s, Pitch: %i, Dim: %ix%ix%i, "
+            "LastLevel: %i, Size: %i, Format: %s\n",
+            func,
+            desc->macrotile[0] ? "YES" : " NO",
+            desc->microtile ? "YES" : " NO",
+            desc->stride_in_pixels[0],
+            desc->b.b.width0, desc->b.b.height0, desc->b.b.depth0,
+            desc->b.b.last_level, desc->size_in_bytes,
+            util_format_short_name(desc->b.b.format));
+}
+
+boolean r300_texture_desc_init(struct r300_screen *rscreen,
+                               struct r300_texture_desc *desc,
+                               const struct pipe_resource *base,
+                               enum r300_buffer_tiling microtile,
+                               enum r300_buffer_tiling macrotile,
+                               unsigned stride_in_bytes_override,
+                               unsigned max_buffer_size)
+{
+    desc->b.b = *base;
+    desc->b.b.screen = &rscreen->screen;
+
+    desc->stride_in_bytes_override = stride_in_bytes_override;
+
+    if (microtile == R300_BUFFER_SELECT_LAYOUT ||
+        macrotile == R300_BUFFER_SELECT_LAYOUT) {
+        r300_setup_tiling(rscreen, desc);
+    } else {
+        desc->microtile = microtile;
+        desc->macrotile[0] = macrotile;
+        assert(desc->b.b.last_level == 0);
+    }
+
+    r300_setup_flags(desc);
+    r300_setup_cbzb_flags(rscreen, desc);
+
+    /* Setup the miptree description. */
+    r300_setup_miptree(rscreen, desc, TRUE);
+    /* If the required buffer size is larger the given max size,
+     * try again without the alignment for the CBZB clear. */
+    if (max_buffer_size && desc->size_in_bytes > max_buffer_size) {
+        r300_setup_miptree(rscreen, desc, FALSE);
+    }
+
+    r300_texture_3d_fix_mipmapping(rscreen, desc);
+
+    if (max_buffer_size) {
+        /* Make sure the buffer we got is large enough. */
+        if (desc->size_in_bytes > max_buffer_size) {
+            fprintf(stderr, "r300: texture_from_handle: The buffer is not "
+                            "large enough. Got: %i, Need: %i, Info:\n",
+                            max_buffer_size, desc->size_in_bytes);
+            r300_tex_print_info(rscreen, desc, "texture_from_handle");
+            return FALSE;
+        }
+
+        desc->buffer_size_in_bytes = max_buffer_size;
+    } else {
+        desc->buffer_size_in_bytes = desc->size_in_bytes;
+    }
+
+    if (SCREEN_DBG_ON(rscreen, DBG_TEX))
+        r300_tex_print_info(rscreen, desc, "texture_from_handle");
+
+    return TRUE;
+}
+
+unsigned r300_texture_get_offset(struct r300_texture_desc *desc,
+                                 unsigned level, unsigned zslice,
+                                 unsigned face)
+{
+    unsigned offset = desc->offset_in_bytes[level];
+
+    switch (desc->b.b.target) {
+        case PIPE_TEXTURE_3D:
+            assert(face == 0);
+            return offset + zslice * desc->layer_size_in_bytes[level];
+
+        case PIPE_TEXTURE_CUBE:
+            assert(zslice == 0);
+            return offset + face * desc->layer_size_in_bytes[level];
+
+        default:
+            assert(zslice == 0 && face == 0);
+            return offset;
+    }
+}
diff --git a/src/gallium/drivers/r300/r300_texture_desc.h b/src/gallium/drivers/r300/r300_texture_desc.h
new file mode 100644 (file)
index 0000000..95de66f
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2010 Marek Olšák <maraeo@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) 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. */
+
+#ifndef R300_TEXTURE_DESC_H
+#define R300_TEXTURE_DESC_H
+
+#include "r300_defines.h"
+
+struct pipe_resource;
+struct r300_screen;
+struct r300_texture_desc;
+struct r300_texture;
+
+enum r300_dim {
+    DIM_WIDTH  = 0,
+    DIM_HEIGHT = 1
+};
+
+unsigned r300_get_pixel_alignment(enum pipe_format format,
+                                  unsigned num_samples,
+                                  enum r300_buffer_tiling microtile,
+                                  enum r300_buffer_tiling macrotile,
+                                  enum r300_dim dim);
+
+boolean r300_texture_desc_init(struct r300_screen *rscreen,
+                               struct r300_texture_desc *desc,
+                               const struct pipe_resource *base,
+                               enum r300_buffer_tiling microtile,
+                               enum r300_buffer_tiling macrotile,
+                               unsigned stride_in_bytes_override,
+                               unsigned max_buffer_size);
+
+unsigned r300_texture_get_offset(struct r300_texture_desc *desc,
+                                 unsigned level, unsigned zslice,
+                                 unsigned face);
+
+#endif
index 5394e04f727c4d8610bf0d5583992ccc63bd5c72..51b2c5555024de54919a8860a9acd3fba1c2a695 100644 (file)
@@ -71,7 +71,7 @@ static unsigned translate_opcode(unsigned opcode)
         case TGSI_OPCODE_COS: return RC_OPCODE_COS;
         case TGSI_OPCODE_DDX: return RC_OPCODE_DDX;
         case TGSI_OPCODE_DDY: return RC_OPCODE_DDY;
-     /* case TGSI_OPCODE_KILP: return RC_OPCODE_KILP; */
+        case TGSI_OPCODE_KILP: return RC_OPCODE_KILP;
      /* case TGSI_OPCODE_PK2H: return RC_OPCODE_PK2H; */
      /* case TGSI_OPCODE_PK2US: return RC_OPCODE_PK2US; */
      /* case TGSI_OPCODE_PK4B: return RC_OPCODE_PK4B; */
index d41f2588369d87a5fd93b38ab99e28c424f79503..e9333b35ef53be62420294be95fcc8859f0903b3 100644 (file)
@@ -22,7 +22,7 @@
  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
 
 #include "r300_transfer.h"
-#include "r300_texture.h"
+#include "r300_texture_desc.h"
 #include "r300_screen_buffer.h"
 
 #include "util/u_memory.h"
@@ -35,8 +35,8 @@ struct r300_transfer {
     /* Offset from start of buffer. */
     unsigned offset;
 
-    /* Detiled texture. */
-    struct r300_texture *detiled_texture;
+    /* Linear texture. */
+    struct r300_texture *linear_texture;
 };
 
 /* Convenience cast wrapper. */
@@ -57,7 +57,7 @@ static void r300_copy_from_tiled_texture(struct pipe_context *ctx,
     subdst.face = 0;
     subdst.level = 0;
 
-    ctx->resource_copy_region(ctx, &r300transfer->detiled_texture->b.b, subdst,
+    ctx->resource_copy_region(ctx, &r300transfer->linear_texture->desc.b.b, subdst,
                              0, 0, 0,
                              tex, transfer->sr,
                              transfer->box.x, transfer->box.y, transfer->box.z,
@@ -77,9 +77,11 @@ static void r300_copy_into_tiled_texture(struct pipe_context *ctx,
 
     ctx->resource_copy_region(ctx, tex, transfer->sr,
                              transfer->box.x, transfer->box.y, transfer->box.z,
-                             &r300transfer->detiled_texture->b.b, subsrc,
+                              &r300transfer->linear_texture->desc.b.b, subsrc,
                              0, 0, 0,
                              transfer->box.width, transfer->box.height);
+
+    ctx->flush(ctx, 0, NULL);
 }
 
 struct pipe_transfer*
@@ -89,19 +91,21 @@ r300_texture_get_transfer(struct pipe_context *ctx,
                          unsigned usage,
                          const struct pipe_box *box)
 {
+    struct r300_context *r300 = r300_context(ctx);
     struct r300_texture *tex = r300_texture(texture);
-    struct r300_screen *r300screen = r300_screen(ctx->screen);
     struct r300_transfer *trans;
     struct pipe_resource base;
     boolean referenced_cs, referenced_hw, blittable;
 
-    referenced_cs = r300screen->rws->is_buffer_referenced(
-                                r300screen->rws, tex->buffer, R300_REF_CS);
+    referenced_cs =
+        r300->rws->cs_is_buffer_referenced(r300->cs,
+                                           tex->buffer, R300_REF_CS);
     if (referenced_cs) {
         referenced_hw = TRUE;
     } else {
-        referenced_hw = r300screen->rws->is_buffer_referenced(
-                                r300screen->rws, tex->buffer, R300_REF_HW);
+        referenced_hw =
+            r300->rws->cs_is_buffer_referenced(r300->cs,
+                                               tex->buffer, R300_REF_HW);
     }
 
     blittable = ctx->screen->is_format_supported(
@@ -119,7 +123,7 @@ r300_texture_get_transfer(struct pipe_context *ctx,
         /* If the texture is tiled, we must create a temporary detiled texture
          * for this transfer.
          * Also make write transfers pipelined. */
-        if (tex->microtile || tex->macrotile ||
+        if (tex->desc.microtile || tex->desc.macrotile[sr.level] ||
             ((referenced_hw & !(usage & PIPE_TRANSFER_READ)) && blittable)) {
             base.target = PIPE_TEXTURE_2D;
             base.format = texture->format;
@@ -144,23 +148,23 @@ r300_texture_get_transfer(struct pipe_context *ctx,
             }
 
             /* Create the temporary texture. */
-            trans->detiled_texture = r300_texture(
+            trans->linear_texture = r300_texture(
                ctx->screen->resource_create(ctx->screen,
                                             &base));
 
-            if (!trans->detiled_texture) {
+            if (!trans->linear_texture) {
                 /* Oh crap, the thing can't create the texture.
                  * Let's flush and try again. */
                 ctx->flush(ctx, 0, NULL);
 
-                trans->detiled_texture = r300_texture(
+                trans->linear_texture = r300_texture(
                    ctx->screen->resource_create(ctx->screen,
                                                 &base));
 
-                if (!trans->detiled_texture) {
+                if (!trans->linear_texture) {
                     /* For linear textures, it's safe to fallback to
                      * an unpipelined transfer. */
-                    if (!tex->microtile && !tex->macrotile) {
+                    if (!tex->desc.microtile && !tex->desc.macrotile[sr.level]) {
                         goto unpipelined;
                     }
 
@@ -172,8 +176,8 @@ r300_texture_get_transfer(struct pipe_context *ctx,
                 }
             }
 
-            assert(!trans->detiled_texture->microtile &&
-                   !trans->detiled_texture->macrotile);
+            assert(!trans->linear_texture->desc.microtile &&
+                   !trans->linear_texture->desc.macrotile[0]);
 
             /* Set the stride.
             *
@@ -183,7 +187,7 @@ r300_texture_get_transfer(struct pipe_context *ctx,
             * right thing internally.
             */
             trans->transfer.stride =
-                r300_texture_get_stride(r300screen, trans->detiled_texture, 0);
+                    trans->linear_texture->desc.stride_in_bytes[0];
 
             if (usage & PIPE_TRANSFER_READ) {
                 /* We cannot map a tiled texture directly because the data is
@@ -198,11 +202,11 @@ r300_texture_get_transfer(struct pipe_context *ctx,
 
     unpipelined:
         /* Unpipelined transfer. */
-        trans->transfer.stride =
-                r300_texture_get_stride(r300screen, tex, sr.level);
-        trans->offset = r300_texture_get_offset(tex, sr.level, box->z, sr.face);
+        trans->transfer.stride = tex->desc.stride_in_bytes[sr.level];
+        trans->offset = r300_texture_get_offset(&tex->desc,
+                                                sr.level, box->z, sr.face);
 
-        if (referenced_cs && (usage & PIPE_TRANSFER_READ))
+        if (referenced_cs)
             ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
         return &trans->transfer;
     }
@@ -214,13 +218,13 @@ void r300_texture_transfer_destroy(struct pipe_context *ctx,
 {
     struct r300_transfer *r300transfer = r300_transfer(trans);
 
-    if (r300transfer->detiled_texture) {
+    if (r300transfer->linear_texture) {
         if (trans->usage & PIPE_TRANSFER_WRITE) {
             r300_copy_into_tiled_texture(ctx, r300transfer);
         }
 
         pipe_resource_reference(
-            (struct pipe_resource**)&r300transfer->detiled_texture, NULL);
+            (struct pipe_resource**)&r300transfer->linear_texture, NULL);
     }
     pipe_resource_reference(&trans->resource, NULL);
     FREE(trans);
@@ -229,21 +233,23 @@ void r300_texture_transfer_destroy(struct pipe_context *ctx,
 void* r300_texture_transfer_map(struct pipe_context *ctx,
                                struct pipe_transfer *transfer)
 {
+    struct r300_context *r300 = r300_context(ctx);
     struct r300_winsys_screen *rws = (struct r300_winsys_screen *)ctx->winsys;
     struct r300_transfer *r300transfer = r300_transfer(transfer);
     struct r300_texture *tex = r300_texture(transfer->resource);
     char *map;
-    enum pipe_format format = tex->b.b.format;
+    enum pipe_format format = tex->desc.b.b.format;
 
-    if (r300transfer->detiled_texture) {
+    if (r300transfer->linear_texture) {
         /* The detiled texture is of the same size as the region being mapped
          * (no offset needed). */
         return rws->buffer_map(rws,
-                               r300transfer->detiled_texture->buffer,
+                               r300transfer->linear_texture->buffer,
+                               r300->cs,
                                transfer->usage);
     } else {
         /* Tiling is disabled. */
-        map = rws->buffer_map(rws, tex->buffer,
+        map = rws->buffer_map(rws, tex->buffer, r300->cs,
                               transfer->usage);
 
         if (!map) {
@@ -263,8 +269,8 @@ void r300_texture_transfer_unmap(struct pipe_context *ctx,
     struct r300_transfer *r300transfer = r300_transfer(transfer);
     struct r300_texture *tex = r300_texture(transfer->resource);
 
-    if (r300transfer->detiled_texture) {
-       rws->buffer_unmap(rws, r300transfer->detiled_texture->buffer);
+    if (r300transfer->linear_texture) {
+        rws->buffer_unmap(rws, r300transfer->linear_texture->buffer);
     } else {
         rws->buffer_unmap(rws, tex->buffer);
     }
index d64040b8911ae37bc2b74ed32453f514ba33ed16..2939963c3550dc2c8facb17af2cbcb2a170ec5bc 100644 (file)
@@ -185,7 +185,7 @@ static void transform_decl(struct tgsi_transform_context *ctx,
                 if (decl->Semantic.Index == 1 && !vsctx->bcolor_used[0]) {
                     insert_output(ctx, decl, TGSI_SEMANTIC_BCOLOR, 0,
                                   TGSI_INTERPOLATE_LINEAR);
-                    vsctx->color_used[2] = TRUE;
+                    vsctx->bcolor_used[0] = TRUE;
                 }
                 /* One more case is handled in insert_trailing_bcolor. */
                 break;
index 77c1c13ef9ae55419828033e2e60e2c492c53763..ff11546a647b9bbacf3d94eef1bb1633298062e4 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2010 Marek Olšák <maraeo@gmail.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
 #ifndef R300_WINSYS_H
 #define R300_WINSYS_H
 
-/* The public interface header for the r300 pipe driver.
- * Any winsys hosting this pipe needs to implement r300_winsys and then
- * call r300_create_screen to start things. */
+/* The public winsys interface header for the r300 pipe driver.
+ * Any winsys hosting this pipe needs to implement r300_winsys_screen and then
+ * call r300_screen_create to start things. */
 
 #include "pipe/p_defines.h"
 #include "pipe/p_state.h"
 
 #include "r300_defines.h"
 
+struct r300_winsys_screen;
+
 struct r300_winsys_buffer;
 
+struct r300_winsys_cs {
+    uint32_t *ptr;      /* Pointer to the beginning of the CS. */
+    unsigned cdw;       /* Number of used dwords. */
+    unsigned ndw;       /* Size of the CS in dwords. */
+};
+
 enum r300_value_id {
     R300_VID_PCI_ID,
     R300_VID_GB_PIPES,
@@ -48,121 +57,251 @@ enum r300_reference_domain { /* bitfield */
 };
 
 struct r300_winsys_screen {
+    /**
+     * Destroy this winsys.
+     *
+     * \param ws        The winsys this function is called from.
+     */
     void (*destroy)(struct r300_winsys_screen *ws);
-    
+
     /**
+     * Query a system value from a winsys.
+     *
+     * \param ws        The winsys this function is called from.
+     * \param vid       One of the R300_VID_* enums.
+     */
+    uint32_t (*get_value)(struct r300_winsys_screen *ws,
+                          enum r300_value_id vid);
+
+    /**************************************************************************
      * Buffer management. Buffer attributes are mostly fixed over its lifetime.
      *
      * Remember that gallium gets to choose the interface it needs, and the
      * window systems must then implement that interface (rather than the
      * other way around...).
+     *************************************************************************/
+
+    /**
+     * Create a buffer object.
      *
-     * usage is a bitmask of R300_WINSYS_BUFFER_USAGE_PIXEL/VERTEX/INDEX/CONSTANT. This
-     * usage argument is only an optimization hint, not a guarantee, therefore
-     * proper behavior must be observed in all circumstances.
-     *
-     * alignment indicates the client's alignment requirements, eg for
-     * SSE instructions.
+     * \param ws        The winsys this function is called from.
+     * \param size      The size to allocate.
+     * \param alignment An alignment of the buffer in memory.
+     * \param bind      A bitmask of the PIPE_BIND_* flags.
+     * \param usage     A bitmask of the PIPE_USAGE_* flags.
+     * \param domain    A bitmask of the R300_DOMAIN_* flags.
+     * \return          The created buffer object.
      */
     struct r300_winsys_buffer *(*buffer_create)(struct r300_winsys_screen *ws,
-                                               unsigned alignment,
-                                               unsigned usage,
-                                                enum r300_buffer_domain domain,
-                                               unsigned size);
+                                                unsigned size,
+                                                unsigned alignment,
+                                                unsigned bind,
+                                                unsigned usage,
+                                                enum r300_buffer_domain domain);
 
     /**
-     * Map the entire data store of a buffer object into the client's address.
-     * flags is bitmask of R300_WINSYS_BUFFER_USAGE_CPU_READ/WRITE flags.
+     * Reference a buffer object (assign with reference counting).
+     *
+     * \param ws        The winsys this function is called from.
+     * \param pdst      A destination pointer to set the source buffer to.
+     * \param src       A source buffer object.
      */
-    void *(*buffer_map)( struct r300_winsys_screen *ws,
-                        struct r300_winsys_buffer *buf,
-                        unsigned usage);
+    void (*buffer_reference)(struct r300_winsys_screen *ws,
+                             struct r300_winsys_buffer **pdst,
+                             struct r300_winsys_buffer *src);
 
-    void (*buffer_unmap)( struct r300_winsys_screen *ws,
-                         struct r300_winsys_buffer *buf );
+    /**
+     * Map the entire data store of a buffer object into the client's address
+     * space.
+     *
+     * \param ws        The winsys this function is called from.
+     * \param buf       A winsys buffer object to map.
+     * \param cs        A command stream to flush if the buffer is referenced by it.
+     * \param usage     A bitmask of the PIPE_TRANSFER_* flags.
+     * \return          The pointer at the beginning of the buffer.
+     */
+    void *(*buffer_map)(struct r300_winsys_screen *ws,
+                        struct r300_winsys_buffer *buf,
+                        struct r300_winsys_cs *cs,
+                        enum pipe_transfer_usage usage);
 
-    void (*buffer_destroy)( struct r300_winsys_buffer *buf );
+    /**
+     * Unmap a buffer object from the client's address space.
+     *
+     * \param ws        The winsys this function is called from.
+     * \param buf       A winsys buffer object to unmap.
+     */
+    void (*buffer_unmap)(struct r300_winsys_screen *ws,
+                         struct r300_winsys_buffer *buf);
 
+    /**
+     * Wait for a buffer object until it is not used by a GPU. This is
+     * equivalent to a fence placed after the last command using the buffer,
+     * and synchronizing to the fence.
+     *
+     * \param ws        The winsys this function is called from.
+     * \param buf       A winsys buffer object to wait for.
+     */
+    void (*buffer_wait)(struct r300_winsys_screen *ws,
+                        struct r300_winsys_buffer *buf);
 
-    void (*buffer_reference)(struct r300_winsys_screen *rws,
-                            struct r300_winsys_buffer **pdst,
-                            struct r300_winsys_buffer *src);
+    /**
+     * Return tiling flags describing a memory layout of a buffer object.
+     *
+     * \param ws        The winsys this function is called from.
+     * \param buf       A winsys buffer object to get the flags from.
+     * \param macrotile A pointer to the return value of the microtile flag.
+     * \param microtile A pointer to the return value of the macrotile flag.
+     *
+     * \note microtile and macrotile are not bitmasks!
+     */
+    void (*buffer_get_tiling)(struct r300_winsys_screen *ws,
+                              struct r300_winsys_buffer *buf,
+                              enum r300_buffer_tiling *microtile,
+                              enum r300_buffer_tiling *macrotile);
 
-    void (*buffer_wait)(struct r300_winsys_screen *rws,
-                        struct r300_winsys_buffer *buf);
+    /**
+     * Set tiling flags describing a memory layout of a buffer object.
+     *
+     * \param ws        The winsys this function is called from.
+     * \param buf       A winsys buffer object to set the flags for.
+     * \param macrotile A macrotile flag.
+     * \param microtile A microtile flag.
+     * \param stride    A stride of the buffer in bytes, for texturing.
+     *
+     * \note microtile and macrotile are not bitmasks!
+     */
+    void (*buffer_set_tiling)(struct r300_winsys_screen *ws,
+                              struct r300_winsys_buffer *buf,
+                              enum r300_buffer_tiling microtile,
+                              enum r300_buffer_tiling macrotile,
+                              unsigned stride);
 
-    /* Add a pipe_resource to the list of buffer objects to validate. */
-    boolean (*add_buffer)(struct r300_winsys_screen *winsys,
-                          struct r300_winsys_buffer *buf,
-                          enum r300_buffer_domain rd,
-                          enum r300_buffer_domain wd);
+    /**
+     * Get a winsys buffer from a winsys handle. The internal structure
+     * of the handle is platform-specific and only a winsys should access it.
+     *
+     * \param ws        The winsys this function is called from.
+     * \param whandle   A winsys handle pointer as was received from a state
+     *                  tracker.
+     * \param stride    The returned buffer stride in bytes.
+     * \param size      The returned buffer size.
+     */
+    struct r300_winsys_buffer *(*buffer_from_handle)(struct r300_winsys_screen *ws,
+                                                     struct winsys_handle *whandle,
+                                                     unsigned *stride,
+                                                     unsigned *size);
 
+    /**
+     * Get a winsys handle from a winsys buffer. The internal structure
+     * of the handle is platform-specific and only a winsys should access it.
+     *
+     * \param ws        The winsys this function is called from.
+     * \param buf       A winsys buffer object to get the handle from.
+     * \param whandle   A winsys handle pointer.
+     * \param stride    A stride of the buffer in bytes, for texturing.
+     * \return          TRUE on success.
+     */
+    boolean (*buffer_get_handle)(struct r300_winsys_screen *ws,
+                                 struct r300_winsys_buffer *buf,
+                                 unsigned stride,
+                                 struct winsys_handle *whandle);
 
-    /* Revalidate all currently setup pipe_buffers.
-     * Returns TRUE if a flush is required. */
-    boolean (*validate)(struct r300_winsys_screen* winsys);
+    /**************************************************************************
+     * Command submission.
+     *
+     * Each pipe context should create its own command stream and submit
+     * commands independently of other contexts.
+     *************************************************************************/
 
-    /* Return the number of free dwords in CS. */
-    unsigned (*get_cs_free_dwords)(struct r300_winsys_screen *winsys);
+    /**
+     * Create a command stream.
+     *
+     * \param ws        The winsys this function is called from.
+     */
+    struct r300_winsys_cs *(*cs_create)(struct r300_winsys_screen *ws);
 
-    /* Return the pointer to the first free dword in CS and assume a pipe
-     * driver wants to fill "count" dwords. */
-    uint32_t *(*get_cs_pointer)(struct r300_winsys_screen *winsys,
-                                unsigned count);
+    /**
+     * Destroy a command stream.
+     *
+     * \param cs        A command stream to destroy.
+     */
+    void (*cs_destroy)(struct r300_winsys_cs *cs);
 
-    /* Write a dword to the command buffer. */
-    void (*write_cs_dword)(struct r300_winsys_screen* winsys, uint32_t dword);
+    /**
+     * Add a buffer object to the list of buffers to validate.
+     *
+     * \param cs        A command stream to add buffer for validation against.
+     * \param buf       A winsys buffer to validate.
+     * \param rd        A read domain containing a bitmask
+     *                  of the R300_DOMAIN_* flags.
+     * \param wd        A write domain containing a bitmask
+     *                  of the R300_DOMAIN_* flags.
+     */
+    void (*cs_add_buffer)(struct r300_winsys_cs *cs,
+                          struct r300_winsys_buffer *buf,
+                          enum r300_buffer_domain rd,
+                          enum r300_buffer_domain wd);
 
-    /* Write a table of dwords to the command buffer. */
-    void (*write_cs_table)(struct r300_winsys_screen* winsys,
-                           const void *dwords, unsigned count);
+    /**
+     * Revalidate all currently set up winsys buffers.
+     * Returns TRUE if a flush is required.
+     *
+     * \param cs        A command stream to validate.
+     */
+    boolean (*cs_validate)(struct r300_winsys_cs *cs);
 
-    /* Write a relocated dword to the command buffer. */
-    void (*write_cs_reloc)(struct r300_winsys_screen *winsys,
+    /**
+     * Write a relocated dword to a command buffer.
+     *
+     * \param cs        A command stream the relocation is written to.
+     * \param buf       A winsys buffer to write the relocation for.
+     * \param rd        A read domain containing a bitmask of the R300_DOMAIN_* flags.
+     * \param wd        A write domain containing a bitmask of the R300_DOMAIN_* flags.
+     */
+    void (*cs_write_reloc)(struct r300_winsys_cs *cs,
                            struct r300_winsys_buffer *buf,
                            enum r300_buffer_domain rd,
-                           enum r300_buffer_domain wd,
-                           uint32_t flags);
-
-    /* Flush the CS. */
-    void (*flush_cs)(struct r300_winsys_screen* winsys);
-
-    /* winsys flush - callback from winsys when flush required */
-    void (*set_flush_cb)(struct r300_winsys_screen *winsys,
-                        void (*flush_cb)(void *), void *data);
-
-    void (*reset_bos)(struct r300_winsys_screen *winsys);
-
-    void (*buffer_get_tiling)(struct r300_winsys_screen *winsys,
-                              struct r300_winsys_buffer *buffer,
-                              enum r300_buffer_tiling *microtiled,
-                              enum r300_buffer_tiling *macrotiled);
+                           enum r300_buffer_domain wd);
 
-    void (*buffer_set_tiling)(struct r300_winsys_screen *winsys,
-                              struct r300_winsys_buffer *buffer,
-                              uint32_t pitch,
-                              enum r300_buffer_tiling microtiled,
-                              enum r300_buffer_tiling macrotiled);
-
-    uint32_t (*get_value)(struct r300_winsys_screen *winsys,
-                         enum r300_value_id vid);
+    /**
+     * Flush a command stream.
+     *
+     * \param cs        A command stream to flush.
+     */
+    void (*cs_flush)(struct r300_winsys_cs *cs);
 
-    struct r300_winsys_buffer *(*buffer_from_handle)(struct r300_winsys_screen *winsys,
-                                                     unsigned handle);
+    /**
+     * Set a flush callback which is called from winsys when flush is
+     * required.
+     *
+     * \param cs        A command stream to set the callback for.
+     * \param flush     A flush callback function associated with the command stream.
+     * \param user      A user pointer that will be passed to the flush callback.
+     */
+    void (*cs_set_flush)(struct r300_winsys_cs *cs,
+                         void (*flush)(void *),
+                         void *user);
 
-    boolean (*buffer_get_handle)(struct r300_winsys_screen *winsys,
-                                struct r300_winsys_buffer *buffer,
-                                struct winsys_handle *whandle);
+    /**
+     * Reset the list of buffer objects to validate, usually called
+     * prior to adding buffer objects for validation.
+     *
+     * \param cs        A command stream to reset buffers for.
+     */
+    void (*cs_reset_buffers)(struct r300_winsys_cs *cs);
 
-    boolean (*is_buffer_referenced)(struct r300_winsys_screen *winsys,
-                                    struct r300_winsys_buffer *buffer,
-                                    enum r300_reference_domain domain);
+    /**
+     * Return TRUE if a buffer is referenced by a command stream or by hardware
+     * (i.e. is busy), based on the domain parameter.
+     *
+     * \param cs        A command stream.
+     * \param buf       A winsys buffer.
+     * \param domain    A bitmask of the R300_REF_* enums.
+     */
+    boolean (*cs_is_buffer_referenced)(struct r300_winsys_cs *cs,
+                                       struct r300_winsys_buffer *buf,
+                                       enum r300_reference_domain domain);
 };
 
-struct r300_winsys_screen *
-r300_winsys_screen(struct pipe_screen *screen);
-
-/* Creates a new r300 screen. */
-struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws);
-
 #endif /* R300_WINSYS_H */
index aae31a6a6eb5871718e31e6229d8ba5910ad0956..8f1e1366b5017800c9c4bdd69ecfcca10da5dcfc 100644 (file)
@@ -18,10 +18,7 @@ C_SOURCES = \
        r600_state.c \
        r600_texture.c \
        r600_shader.c \
-       r600_compiler.c \
-       r600_compiler_tgsi.c \
-       r600_compiler_dump.c \
-       r600_compiler_r600.c \
-       r600_compiler_r700.c
+       r600_asm.c \
+       r700_asm.c
 
 include ../../Makefile.template
index 26e2f1941cc91e7fc4ce91b9be2cc912a072f2ba..99c8644e0267dfb5d9fd41e8b8368f6547b4ab2d 100644 (file)
@@ -27,11 +27,8 @@ r600 = env.ConvenienceLibrary(
         'r600_state.c',
         'r600_texture.c',
         'r600_shader.c',
-        'r600_compiler.c',
-        'r600_compiler_tgsi.c',
-        'r600_compiler_dump.c',
-        'r600_compiler_r600.c',
-        'r600_compiler_r700.c'
+        'r600_asm.c',
+        'r700_asm.c',
     ])
 
 Export('r600')
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
new file mode 100644 (file)
index 0000000..e678a2f
--- /dev/null
@@ -0,0 +1,468 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "r600_asm.h"
+#include "r600_context.h"
+#include "util/u_memory.h"
+#include "r600_sq.h"
+#include <stdio.h>
+#include <errno.h>
+
+int r700_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id);
+
+static struct r600_bc_cf *r600_bc_cf(void)
+{
+       struct r600_bc_cf *cf = CALLOC_STRUCT(r600_bc_cf);
+
+       if (cf == NULL)
+               return NULL;
+       LIST_INITHEAD(&cf->list);
+       LIST_INITHEAD(&cf->alu);
+       LIST_INITHEAD(&cf->vtx);
+       LIST_INITHEAD(&cf->tex);
+       return cf;
+}
+
+static struct r600_bc_alu *r600_bc_alu(void)
+{
+       struct r600_bc_alu *alu = CALLOC_STRUCT(r600_bc_alu);
+
+       if (alu == NULL)
+               return NULL;
+       LIST_INITHEAD(&alu->list);
+       return alu;
+}
+
+static struct r600_bc_vtx *r600_bc_vtx(void)
+{
+       struct r600_bc_vtx *vtx = CALLOC_STRUCT(r600_bc_vtx);
+
+       if (vtx == NULL)
+               return NULL;
+       LIST_INITHEAD(&vtx->list);
+       return vtx;
+}
+
+static struct r600_bc_tex *r600_bc_tex(void)
+{
+       struct r600_bc_tex *tex = CALLOC_STRUCT(r600_bc_tex);
+
+       if (tex == NULL)
+               return NULL;
+       LIST_INITHEAD(&tex->list);
+       return tex;
+}
+
+int r600_bc_init(struct r600_bc *bc, enum radeon_family family)
+{
+       LIST_INITHEAD(&bc->cf);
+       bc->family = family;
+       return 0;
+}
+
+static int r600_bc_add_cf(struct r600_bc *bc)
+{
+       struct r600_bc_cf *cf = r600_bc_cf();
+
+       if (cf == NULL)
+               return -ENOMEM;
+       LIST_ADDTAIL(&cf->list, &bc->cf);
+       if (bc->cf_last)
+               cf->id = bc->cf_last->id + 2;
+       bc->cf_last = cf;
+       bc->ncf++;
+       bc->ndw += 2;
+       return 0;
+}
+
+int r600_bc_add_output(struct r600_bc *bc, const struct r600_bc_output *output)
+{
+       int r;
+
+       r = r600_bc_add_cf(bc);
+       if (r)
+               return r;
+       bc->cf_last->inst = output->inst;
+       memcpy(&bc->cf_last->output, output, sizeof(struct r600_bc_output));
+       return 0;
+}
+
+int r600_bc_add_alu(struct r600_bc *bc, const struct r600_bc_alu *alu)
+{
+       struct r600_bc_alu *nalu = r600_bc_alu();
+       struct r600_bc_alu *lalu;
+       int i, r;
+
+       if (nalu == NULL)
+               return -ENOMEM;
+       memcpy(nalu, alu, sizeof(struct r600_bc_alu));
+       nalu->nliteral = 0;
+
+       /* cf can contains only alu or only vtx or only tex */
+       if (bc->cf_last == NULL || bc->cf_last->inst != (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3)) {
+               r = r600_bc_add_cf(bc);
+               if (r) {
+                       free(nalu);
+                       return r;
+               }
+               bc->cf_last->inst = V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3;
+       }
+       /* number of gpr == the last gpr used in any alu */
+       for (i = 0; i < 3; i++) {
+               if (alu->src[i].sel >= bc->ngpr && alu->src[i].sel < 128) {
+                       bc->ngpr = alu->src[i].sel + 1;
+               }
+               /* compute how many literal are needed
+                * either 2 or 4 literals
+                */
+               if (alu->src[i].sel == 253) {
+                       if (((alu->src[i].chan + 2) & 0x6) > nalu->nliteral) {
+                               nalu->nliteral = (alu->src[i].chan + 2) & 0x6;
+                       }
+               }
+       }
+       if (!LIST_IS_EMPTY(&bc->cf_last->alu)) {
+               lalu = LIST_ENTRY(struct r600_bc_alu, bc->cf_last->alu.prev, list);
+               if (!lalu->last && lalu->nliteral > nalu->nliteral) {
+                       nalu->nliteral = lalu->nliteral;
+               }
+       }
+       if (alu->dst.sel >= bc->ngpr) {
+               bc->ngpr = alu->dst.sel + 1;
+       }
+       LIST_ADDTAIL(&nalu->list, &bc->cf_last->alu);
+       /* each alu use 2 dwords */
+       bc->cf_last->ndw += 2;
+       bc->ndw += 2;
+       return 0;
+}
+
+int r600_bc_add_literal(struct r600_bc *bc, const u32 *value)
+{
+       struct r600_bc_alu *alu;
+
+       if (bc->cf_last == NULL) {
+               R600_ERR("no last CF\n");
+               return -EINVAL;
+       }
+       if (bc->cf_last->inst == V_SQ_CF_WORD1_SQ_CF_INST_TEX) {
+               return 0;
+       }
+       if (bc->cf_last->inst != (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3) ||
+               LIST_IS_EMPTY(&bc->cf_last->alu)) {
+               R600_ERR("last CF is not ALU (%p)\n", bc->cf_last);
+               return -EINVAL;
+       }
+       alu = LIST_ENTRY(struct r600_bc_alu, bc->cf_last->alu.prev, list);
+       if (!alu->last || !alu->nliteral) {
+               return 0;
+       }
+       memcpy(alu->value, value, 4 * 4);
+       bc->cf_last->ndw += alu->nliteral;
+       bc->ndw += alu->nliteral;
+       return 0;
+}
+
+int r600_bc_add_vtx(struct r600_bc *bc, const struct r600_bc_vtx *vtx)
+{
+       struct r600_bc_vtx *nvtx = r600_bc_vtx();
+       int r;
+
+       if (nvtx == NULL)
+               return -ENOMEM;
+       memcpy(nvtx, vtx, sizeof(struct r600_bc_vtx));
+
+       /* cf can contains only alu or only vtx or only tex */
+       if (bc->cf_last == NULL ||
+               (bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_VTX &&
+                bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC)) {
+               r = r600_bc_add_cf(bc);
+               if (r) {
+                       free(nvtx);
+                       return r;
+               }
+               bc->cf_last->inst = V_SQ_CF_WORD1_SQ_CF_INST_VTX;
+       }
+       LIST_ADDTAIL(&nvtx->list, &bc->cf_last->vtx);
+       /* each fetch use 4 dwords */
+       bc->cf_last->ndw += 4;
+       bc->ndw += 4;
+       return 0;
+}
+
+int r600_bc_add_tex(struct r600_bc *bc, const struct r600_bc_tex *tex)
+{
+       struct r600_bc_tex *ntex = r600_bc_tex();
+       int r;
+
+       if (ntex == NULL)
+               return -ENOMEM;
+       memcpy(ntex, tex, sizeof(struct r600_bc_tex));
+
+       /* cf can contains only alu or only vtx or only tex */
+       if (bc->cf_last == NULL ||
+               bc->cf_last->inst != V_SQ_CF_WORD1_SQ_CF_INST_TEX) {
+               r = r600_bc_add_cf(bc);
+               if (r) {
+                       free(ntex);
+                       return r;
+               }
+               bc->cf_last->inst = V_SQ_CF_WORD1_SQ_CF_INST_TEX;
+       }
+       LIST_ADDTAIL(&ntex->list, &bc->cf_last->tex);
+       /* each texture fetch use 4 dwords */
+       bc->cf_last->ndw += 4;
+       bc->ndw += 4;
+       return 0;
+}
+
+static int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsigned id)
+{
+       bc->bytecode[id++] = S_SQ_VTX_WORD0_BUFFER_ID(vtx->buffer_id) |
+                               S_SQ_VTX_WORD0_SRC_GPR(vtx->src_gpr) |
+                               S_SQ_VTX_WORD0_SRC_SEL_X(vtx->src_sel_x) |
+                               S_SQ_VTX_WORD0_MEGA_FETCH_COUNT(vtx->mega_fetch_count);
+       bc->bytecode[id++] = S_SQ_VTX_WORD1_DST_SEL_X(vtx->dst_sel_x) |
+                               S_SQ_VTX_WORD1_DST_SEL_Y(vtx->dst_sel_y) |
+                               S_SQ_VTX_WORD1_DST_SEL_Z(vtx->dst_sel_z) |
+                               S_SQ_VTX_WORD1_DST_SEL_W(vtx->dst_sel_w) |
+                               S_SQ_VTX_WORD1_USE_CONST_FIELDS(1) |
+                               S_SQ_VTX_WORD1_GPR_DST_GPR(vtx->dst_gpr);
+       bc->bytecode[id++] = S_SQ_VTX_WORD2_MEGA_FETCH(1);
+       bc->bytecode[id++] = 0;
+       return 0;
+}
+
+static int r600_bc_tex_build(struct r600_bc *bc, struct r600_bc_tex *tex, unsigned id)
+{
+       bc->bytecode[id++] = S_SQ_TEX_WORD0_TEX_INST(tex->inst) |
+                               S_SQ_TEX_WORD0_RESOURCE_ID(tex->resource_id) |
+                               S_SQ_TEX_WORD0_SRC_GPR(tex->src_gpr) |
+                               S_SQ_TEX_WORD0_SRC_REL(tex->src_rel);
+       bc->bytecode[id++] = S_SQ_TEX_WORD1_DST_GPR(tex->dst_gpr) |
+                               S_SQ_TEX_WORD1_DST_REL(tex->dst_rel) |
+                               S_SQ_TEX_WORD1_DST_SEL_X(tex->dst_sel_x) |
+                               S_SQ_TEX_WORD1_DST_SEL_Y(tex->dst_sel_y) |
+                               S_SQ_TEX_WORD1_DST_SEL_Z(tex->dst_sel_z) |
+                               S_SQ_TEX_WORD1_DST_SEL_W(tex->dst_sel_w) |
+                               S_SQ_TEX_WORD1_LOD_BIAS(tex->lod_bias) |
+                               S_SQ_TEX_WORD1_COORD_TYPE_X(tex->coord_type_x) |
+                               S_SQ_TEX_WORD1_COORD_TYPE_Y(tex->coord_type_y) |
+                               S_SQ_TEX_WORD1_COORD_TYPE_Z(tex->coord_type_z) |
+                               S_SQ_TEX_WORD1_COORD_TYPE_W(tex->coord_type_w);
+       bc->bytecode[id++] = S_SQ_TEX_WORD2_OFFSET_X(tex->offset_x) |
+                               S_SQ_TEX_WORD2_OFFSET_Y(tex->offset_y) |
+                               S_SQ_TEX_WORD2_OFFSET_Z(tex->offset_z) |
+                               S_SQ_TEX_WORD2_SAMPLER_ID(tex->sampler_id) |
+                               S_SQ_TEX_WORD2_SRC_SEL_X(tex->src_sel_x) |
+                               S_SQ_TEX_WORD2_SRC_SEL_Y(tex->src_sel_y) |
+                               S_SQ_TEX_WORD2_SRC_SEL_Z(tex->src_sel_z) |
+                               S_SQ_TEX_WORD2_SRC_SEL_W(tex->src_sel_w);
+       bc->bytecode[id++] = 0;
+       return 0;
+}
+
+int r600_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id)
+{
+       unsigned i;
+
+       /* don't replace gpr by pv or ps for destination register */
+       if (alu->is_op3) {
+               bc->bytecode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |
+                                       S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |
+                                       S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |
+                                       S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |
+                                       S_SQ_ALU_WORD0_LAST(alu->last);
+               bc->bytecode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
+                                       S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
+                                       S_SQ_ALU_WORD1_OP3_SRC2_SEL(alu->src[2].sel) |
+                                       S_SQ_ALU_WORD1_OP3_SRC2_CHAN(alu->src[2].chan) |
+                                       S_SQ_ALU_WORD1_OP3_SRC2_NEG(alu->src[2].neg) |
+                                       S_SQ_ALU_WORD1_OP3_ALU_INST(alu->inst) |
+                                       S_SQ_ALU_WORD1_BANK_SWIZZLE(0);
+       } else {
+               bc->bytecode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |
+                                       S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |
+                                       S_SQ_ALU_WORD0_SRC0_NEG(alu->src[0].neg) |
+                                       S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |
+                                       S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |
+                                       S_SQ_ALU_WORD0_SRC1_NEG(alu->src[1].neg) |
+                                       S_SQ_ALU_WORD0_LAST(alu->last);
+               bc->bytecode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
+                                       S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
+                                       S_SQ_ALU_WORD1_OP2_SRC0_ABS(alu->src[0].abs) |
+                                       S_SQ_ALU_WORD1_OP2_SRC1_ABS(alu->src[1].abs) |
+                                       S_SQ_ALU_WORD1_OP2_WRITE_MASK(alu->dst.write) |
+                                       S_SQ_ALU_WORD1_OP2_ALU_INST(alu->inst) |
+                                       S_SQ_ALU_WORD1_BANK_SWIZZLE(0);
+       }
+       if (alu->last) {
+               for (i = 0; i < alu->nliteral; i++) {
+                       bc->bytecode[id++] = alu->value[i];
+               }
+       }
+       return 0;
+}
+
+int r600_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
+{
+       unsigned id = cf->id;
+
+       switch (cf->inst) {
+       case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
+               bc->bytecode[id++] = S_SQ_CF_ALU_WORD0_ADDR(cf->addr >> 1);
+               bc->bytecode[id++] = S_SQ_CF_ALU_WORD1_CF_INST(cf->inst >> 3) |
+                                       S_SQ_CF_ALU_WORD1_BARRIER(1) |
+                                       S_SQ_CF_ALU_WORD1_COUNT((cf->ndw / 2) - 1);
+               break;
+       case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
+       case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
+       case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
+               bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);
+               bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(cf->inst) |
+                                       S_SQ_CF_WORD1_BARRIER(1) |
+                                       S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1);
+               break;
+       case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
+       case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
+               bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) |
+                       S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(cf->output.elem_size) |
+                       S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(cf->output.array_base) |
+                       S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(cf->output.type);
+               bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X(cf->output.swizzle_x) |
+                       S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(cf->output.swizzle_y) |
+                       S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(cf->output.swizzle_z) |
+                       S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(cf->output.swizzle_w) |
+                       S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->output.barrier) |
+                       S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(cf->output.inst) |
+                       S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->output.end_of_program);
+               break;
+       default:
+               R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+int r600_bc_build(struct r600_bc *bc)
+{
+       struct r600_bc_cf *cf;
+       struct r600_bc_alu *alu;
+       struct r600_bc_vtx *vtx;
+       struct r600_bc_tex *tex;
+       unsigned addr;
+       int r;
+
+
+       /* first path compute addr of each CF block */
+       /* addr start after all the CF instructions */
+       addr = bc->cf_last->id + 2;
+       LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) {
+               switch (cf->inst) {
+               case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
+                       break;
+               case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
+               case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
+               case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
+                       /* fetch node need to be 16 bytes aligned*/
+                       addr += 3;
+                       addr &= 0xFFFFFFFCUL;
+                       break;
+               case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
+               case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
+                       break;
+               default:
+                       R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst);
+                       return -EINVAL;
+               }
+               cf->addr = addr;
+               addr += cf->ndw;
+               bc->ndw = cf->addr + cf->ndw;
+       }
+       free(bc->bytecode);
+       bc->bytecode = calloc(1, bc->ndw * 4);
+       if (bc->bytecode == NULL)
+               return -ENOMEM;
+       LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) {
+               addr = cf->addr;
+               r = r600_bc_cf_build(bc, cf);
+               if (r)
+                       return r;
+               switch (cf->inst) {
+               case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
+                       LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) {
+                               switch (bc->family) {
+                               case CHIP_R600:
+                               case CHIP_RV610:
+                               case CHIP_RV630:
+                               case CHIP_RV670:
+                               case CHIP_RV620:
+                               case CHIP_RV635:
+                               case CHIP_RS780:
+                               case CHIP_RS880:
+                                       r = r600_bc_alu_build(bc, alu, addr);
+                                       break;
+                               case CHIP_RV770:
+                               case CHIP_RV730:
+                               case CHIP_RV710:
+                               case CHIP_RV740:
+                                       r = r700_bc_alu_build(bc, alu, addr);
+                                       break;
+                               default:
+                                       R600_ERR("unknown family %d\n", bc->family);
+                                       return -EINVAL;
+                               }
+                               if (r)
+                                       return r;
+                               addr += 2;
+                               if (alu->last) {
+                                       addr += alu->nliteral;
+                               }
+                       }
+                       break;
+               case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
+               case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
+                       LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) {
+                               r = r600_bc_vtx_build(bc, vtx, addr);
+                               if (r)
+                                       return r;
+                               addr += 4;
+                       }
+                       break;
+               case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
+                       LIST_FOR_EACH_ENTRY(tex, &cf->tex, list) {
+                               r = r600_bc_tex_build(bc, tex, addr);
+                               if (r)
+                                       return r;
+                               addr += 4;
+                       }
+                       break;
+               case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
+               case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
+                       break;
+               default:
+                       R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst);
+                       return -EINVAL;
+               }
+       }
+       return 0;
+}
diff --git a/src/gallium/drivers/r600/r600_asm.h b/src/gallium/drivers/r600/r600_asm.h
new file mode 100644 (file)
index 0000000..88fb957
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) 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.
+ */
+#ifndef R600_ASM_H
+#define R600_ASM_H
+
+#include "radeon.h"
+#include "util/u_double_list.h"
+
+struct r600_bc_alu_src {
+       unsigned                        sel;
+       unsigned                        chan;
+       unsigned                        neg;
+       unsigned                        abs;
+};
+
+struct r600_bc_alu_dst {
+       unsigned                        sel;
+       unsigned                        chan;
+       unsigned                        clamp;
+       unsigned                        write;
+};
+
+struct r600_bc_alu {
+       struct list_head                list;
+       struct r600_bc_alu_src          src[3];
+       struct r600_bc_alu_dst          dst;
+       unsigned                        inst;
+       unsigned                        last;
+       unsigned                        is_op3;
+       unsigned                        nliteral;
+       u32                             value[4];
+};
+
+struct r600_bc_tex {
+       struct list_head                list;
+       unsigned                        inst;
+       unsigned                        resource_id;
+       unsigned                        src_gpr;
+       unsigned                        src_rel;
+       unsigned                        dst_gpr;
+       unsigned                        dst_rel;
+       unsigned                        dst_sel_x;
+       unsigned                        dst_sel_y;
+       unsigned                        dst_sel_z;
+       unsigned                        dst_sel_w;
+       unsigned                        lod_bias;
+       unsigned                        coord_type_x;
+       unsigned                        coord_type_y;
+       unsigned                        coord_type_z;
+       unsigned                        coord_type_w;
+       unsigned                        offset_x;
+       unsigned                        offset_y;
+       unsigned                        offset_z;
+       unsigned                        sampler_id;
+       unsigned                        src_sel_x;
+       unsigned                        src_sel_y;
+       unsigned                        src_sel_z;
+       unsigned                        src_sel_w;
+};
+
+struct r600_bc_vtx {
+       struct list_head                list;
+       unsigned                        inst;
+       unsigned                        fetch_type;
+       unsigned                        buffer_id;
+       unsigned                        src_gpr;
+       unsigned                        src_sel_x;
+       unsigned                        mega_fetch_count;
+       unsigned                        dst_gpr;
+       unsigned                        dst_sel_x;
+       unsigned                        dst_sel_y;
+       unsigned                        dst_sel_z;
+       unsigned                        dst_sel_w;
+};
+
+struct r600_bc_output {
+       unsigned                        array_base;
+       unsigned                        type;
+       unsigned                        end_of_program;
+       unsigned                        inst;
+       unsigned                        elem_size;
+       unsigned                        gpr;
+       unsigned                        swizzle_x;
+       unsigned                        swizzle_y;
+       unsigned                        swizzle_z;
+       unsigned                        swizzle_w;
+       unsigned                        barrier;
+};
+
+struct r600_bc_cf {
+       struct list_head                list;
+       unsigned                        inst;
+       unsigned                        addr;
+       unsigned                        ndw;
+       unsigned                        id;
+       struct list_head                alu;
+       struct list_head                tex;
+       struct list_head                vtx;
+       struct r600_bc_output           output;
+};
+
+struct r600_bc {
+       enum radeon_family              family;
+       struct list_head                cf;
+       struct r600_bc_cf               *cf_last;
+       unsigned                        ndw;
+       unsigned                        ncf;
+       unsigned                        ngpr;
+       unsigned                        nresource;
+       u32                             *bytecode;
+};
+
+int r600_bc_init(struct r600_bc *bc, enum radeon_family family);
+int r600_bc_add_alu(struct r600_bc *bc, const struct r600_bc_alu *alu);
+int r600_bc_add_literal(struct r600_bc *bc, const u32 *value);
+int r600_bc_add_vtx(struct r600_bc *bc, const struct r600_bc_vtx *vtx);
+int r600_bc_add_tex(struct r600_bc *bc, const struct r600_bc_tex *tex);
+int r600_bc_add_output(struct r600_bc *bc, const struct r600_bc_output *output);
+int r600_bc_build(struct r600_bc *bc);
+
+#endif
index 272f4dd6730503a8f20f5098b28f46c5db1f1943..bc6e336ba7b016e69f8b2e52ca42d8d2d9b4f8a2 100644 (file)
@@ -29,7 +29,7 @@
 #include <util/u_math.h>
 #include <util/u_inlines.h>
 #include <util/u_memory.h>
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drm_driver.h"
 #include "r600_screen.h"
 #include "r600_context.h"
 
diff --git a/src/gallium/drivers/r600/r600_compiler.c b/src/gallium/drivers/r600/r600_compiler.c
deleted file mode 100644 (file)
index f1be2bb..0000000
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <errno.h>
-#include "r600_compiler.h"
-
-struct c_vector *c_vector_new(void)
-{
-       struct c_vector *v = calloc(1, sizeof(struct c_vector));
-
-       if (v == NULL) {
-               return NULL;
-       }
-       c_list_init(v);
-       return v;
-}
-
-static unsigned c_opcode_is_alu(unsigned opcode)
-{
-       switch (opcode) {
-       case C_OPCODE_MOV:
-       case C_OPCODE_MUL:
-       case C_OPCODE_MAD:
-       case C_OPCODE_ARL:
-       case C_OPCODE_LIT:
-       case C_OPCODE_RCP:
-       case C_OPCODE_RSQ:
-       case C_OPCODE_EXP:
-       case C_OPCODE_LOG:
-       case C_OPCODE_ADD:
-       case C_OPCODE_DP3:
-       case C_OPCODE_DP4:
-       case C_OPCODE_DST:
-       case C_OPCODE_MIN:
-       case C_OPCODE_MAX:
-       case C_OPCODE_SLT:
-       case C_OPCODE_SGE:
-       case C_OPCODE_SUB:
-       case C_OPCODE_LRP:
-       case C_OPCODE_CND:
-       case C_OPCODE_DP2A:
-       case C_OPCODE_FRC:
-       case C_OPCODE_CLAMP:
-       case C_OPCODE_FLR:
-       case C_OPCODE_ROUND:
-       case C_OPCODE_EX2:
-       case C_OPCODE_LG2:
-       case C_OPCODE_POW:
-       case C_OPCODE_XPD:
-       case C_OPCODE_ABS:
-       case C_OPCODE_RCC:
-       case C_OPCODE_DPH:
-       case C_OPCODE_COS:
-       case C_OPCODE_DDX:
-       case C_OPCODE_DDY:
-       case C_OPCODE_PK2H:
-       case C_OPCODE_PK2US:
-       case C_OPCODE_PK4B:
-       case C_OPCODE_PK4UB:
-       case C_OPCODE_RFL:
-       case C_OPCODE_SEQ:
-       case C_OPCODE_SFL:
-       case C_OPCODE_SGT:
-       case C_OPCODE_SIN:
-       case C_OPCODE_SLE:
-       case C_OPCODE_SNE:
-       case C_OPCODE_STR:
-       case C_OPCODE_UP2H:
-       case C_OPCODE_UP2US:
-       case C_OPCODE_UP4B:
-       case C_OPCODE_UP4UB:
-       case C_OPCODE_X2D:
-       case C_OPCODE_ARA:
-       case C_OPCODE_ARR:
-       case C_OPCODE_BRA:
-       case C_OPCODE_SSG:
-       case C_OPCODE_CMP:
-       case C_OPCODE_SCS:
-       case C_OPCODE_NRM:
-       case C_OPCODE_DIV:
-       case C_OPCODE_DP2:
-       case C_OPCODE_CEIL:
-       case C_OPCODE_I2F:
-       case C_OPCODE_NOT:
-       case C_OPCODE_TRUNC:
-       case C_OPCODE_SHL:
-       case C_OPCODE_AND:
-       case C_OPCODE_OR:
-       case C_OPCODE_MOD:
-       case C_OPCODE_XOR:
-       case C_OPCODE_SAD:
-       case C_OPCODE_NRM4:
-       case C_OPCODE_F2I:
-       case C_OPCODE_IDIV:
-       case C_OPCODE_IMAX:
-       case C_OPCODE_IMIN:
-       case C_OPCODE_INEG:
-       case C_OPCODE_ISGE:
-       case C_OPCODE_ISHR:
-       case C_OPCODE_ISLT:
-       case C_OPCODE_F2U:
-       case C_OPCODE_U2F:
-       case C_OPCODE_UADD:
-       case C_OPCODE_UDIV:
-       case C_OPCODE_UMAD:
-       case C_OPCODE_UMAX:
-       case C_OPCODE_UMIN:
-       case C_OPCODE_UMOD:
-       case C_OPCODE_UMUL:
-       case C_OPCODE_USEQ:
-       case C_OPCODE_USGE:
-       case C_OPCODE_USHR:
-       case C_OPCODE_USLT:
-       case C_OPCODE_USNE:
-               return 1;
-       case C_OPCODE_END:
-       case C_OPCODE_VFETCH:
-       case C_OPCODE_KILP:
-       case C_OPCODE_CAL:
-       case C_OPCODE_RET:
-       case C_OPCODE_TXB:
-       case C_OPCODE_TXL:
-       case C_OPCODE_BRK:
-       case C_OPCODE_IF:
-       case C_OPCODE_BGNFOR:
-       case C_OPCODE_REP:
-       case C_OPCODE_ELSE:
-       case C_OPCODE_ENDIF:
-       case C_OPCODE_ENDFOR:
-       case C_OPCODE_ENDREP:
-       case C_OPCODE_PUSHA:
-       case C_OPCODE_POPA:
-       case C_OPCODE_TXF:
-       case C_OPCODE_TXQ:
-       case C_OPCODE_CONT:
-       case C_OPCODE_EMIT:
-       case C_OPCODE_ENDPRIM:
-       case C_OPCODE_BGNLOOP:
-       case C_OPCODE_BGNSUB:
-       case C_OPCODE_ENDLOOP:
-       case C_OPCODE_ENDSUB:
-       case C_OPCODE_NOP:
-       case C_OPCODE_CALLNZ:
-       case C_OPCODE_IFC:
-       case C_OPCODE_BREAKC:
-       case C_OPCODE_KIL:
-       case C_OPCODE_TEX:
-       case C_OPCODE_TXD:
-       case C_OPCODE_TXP:
-       case C_OPCODE_SWITCH:
-       case C_OPCODE_CASE:
-       case C_OPCODE_DEFAULT:
-       case C_OPCODE_ENDSWITCH:
-       default:
-               return 0;
-       }
-}
-
-
-/* NEW */
-void c_node_init(struct c_node *node)
-{
-       memset(node, 0, sizeof(struct c_node));
-       c_list_init(&node->predecessors);
-       c_list_init(&node->successors);
-       c_list_init(&node->childs);
-       c_list_init(&node->insts);
-       node->parent = NULL;
-}
-
-static struct c_node_link *c_node_link_new(struct c_node *node)
-{
-       struct c_node_link *link;
-
-       link = calloc(1, sizeof(struct c_node_link));
-       if (link == NULL)
-               return NULL;
-       c_list_init(link);
-       link->node = node;
-       return link;
-}
-
-int c_node_cfg_link(struct c_node *predecessor, struct c_node *successor)
-{
-       struct c_node_link *pedge, *sedge;
-
-       pedge = c_node_link_new(successor);
-       sedge = c_node_link_new(predecessor);
-       if (sedge == NULL || pedge == NULL) {
-               free(sedge);
-               free(pedge);
-               return -ENOMEM;
-       }
-       c_list_add_tail(pedge, &predecessor->successors);
-       c_list_add_tail(sedge, &successor->predecessors);
-       return 0;
-}
-
-int c_node_add_new_instruction_head(struct c_node *node, struct c_instruction *instruction)
-{
-       struct c_instruction *inst = calloc(1, sizeof(struct c_instruction));
-
-       if (inst == NULL)
-               return -ENOMEM;
-       memcpy(inst, instruction, sizeof(struct c_instruction));
-       c_list_add(inst, &node->insts);
-       return 0;
-}
-
-int c_node_add_new_instruction(struct c_node *node, struct c_instruction *instruction)
-{
-       struct c_instruction *inst = calloc(1, sizeof(struct c_instruction));
-
-       if (inst == NULL)
-               return -ENOMEM;
-       memcpy(inst, instruction, sizeof(struct c_instruction));
-       c_list_add_tail(inst, &node->insts);
-       return 0;
-}
-
-struct c_node *c_shader_cfg_new_node_after(struct c_shader *shader, struct c_node *predecessor)
-{
-       struct c_node *node = calloc(1, sizeof(struct c_node));
-
-       if (node == NULL)
-               return NULL;
-       c_node_init(node);
-       if (c_node_cfg_link(predecessor, node)) {
-               free(node);
-               return NULL;
-       }
-       c_list_add_tail(node, &shader->nodes);
-       return node;
-}
-
-int c_shader_init(struct c_shader *shader, unsigned type)
-{
-       unsigned i;
-       int r;
-
-       shader->type = type;
-       for (i = 0; i < C_FILE_COUNT; i++) {
-               shader->files[i].nvectors = 0;
-               c_list_init(&shader->files[i].vectors);
-       }
-       c_list_init(&shader->nodes);
-       c_node_init(&shader->entry);
-       c_node_init(&shader->end);
-       shader->entry.opcode = C_OPCODE_ENTRY;
-       shader->end.opcode = C_OPCODE_END;
-       r = c_node_cfg_link(&shader->entry, &shader->end);
-       if (r)
-               return r;
-       return 0;
-}
-
-struct c_vector *c_shader_vector_new(struct c_shader *shader, unsigned file, unsigned name, int sid)
-{
-       struct c_vector *v = calloc(1, sizeof(struct c_vector));
-       int i;
-
-       if (v == NULL) {
-               return NULL;
-       }
-       for (i = 0; i < 4; i++) {
-               v->channel[i] = calloc(1, sizeof(struct c_channel));
-               if (v->channel[i] == NULL)
-                       goto out_err;
-               v->channel[i]->vindex = i;
-               v->channel[i]->vector = v;
-       }
-       v->file = file;
-       v->name = name;
-       v->sid = sid;
-       shader->files[v->file].nvectors++;
-       v->id = shader->nvectors++;
-       c_list_add_tail(v, &shader->files[v->file].vectors);
-       return v;
-out_err:
-       for (i = 0; i < 4; i++) {
-               free(v->channel[i]);
-       }
-       free(v);
-       return NULL;
-}
-
-static void c_node_remove_link(struct c_node_link *head, struct c_node *node)
-{
-       struct c_node_link *link, *tmp;
-
-       c_list_for_each_safe(link, tmp, head) {
-               if (link->node == node) {
-                       c_list_del(link);
-                       free(link);
-               }
-       }
-}
-
-static void c_node_destroy(struct c_node *node)
-{
-       struct c_instruction *i, *ni;
-       struct c_node_link *link, *tmp;
-
-       c_list_for_each_safe(i, ni, &node->insts) {
-               c_list_del(i);
-               free(i);
-       }
-       if (node->parent)
-               c_node_remove_link(&node->parent->childs, node);
-       node->parent = NULL;
-       c_list_for_each_safe(link, tmp, &node->predecessors) {
-               c_node_remove_link(&link->node->successors, node);
-               c_list_del(link);
-               free(link);
-       }
-       c_list_for_each_safe(link, tmp, &node->successors) {
-               c_node_remove_link(&link->node->predecessors, node);
-               c_list_del(link);
-               free(link);
-       }
-       c_list_for_each_safe(link, tmp, &node->childs) {
-               link->node->parent = NULL;
-               c_list_del(link);
-               free(link);
-       }
-}
-
-void c_shader_destroy(struct c_shader *shader)
-{
-       struct c_node *n, *nn;
-       struct c_vector *v, *nv;
-       unsigned i;
-
-       for (i = 0; i < C_FILE_COUNT; i++) {
-               shader->files[i].nvectors = 0;
-               c_list_for_each_safe(v, nv, &shader->files[i].vectors) {
-                       c_list_del(v);
-                       free(v->channel[0]);
-                       free(v->channel[1]);
-                       free(v->channel[2]);
-                       free(v->channel[3]);
-                       free(v);
-               }
-       }
-       c_list_for_each_safe(n, nn, &shader->nodes) {
-               c_list_del(n);
-               c_node_destroy(n);
-       }
-       memset(shader, 0, sizeof(struct c_shader));
-}
-
-static void c_shader_dfs_without_rec(struct c_node *entry, struct c_node *node)
-{
-       struct c_node_link *link;
-
-       if (entry == node || entry->visited)
-               return;
-       entry->visited = 1;
-       c_list_for_each(link, &entry->successors) {
-               c_shader_dfs_without_rec(link->node, node);
-       }
-}
-
-static void c_shader_dfs_without(struct c_shader *shader, struct c_node *node)
-{
-       struct c_node *n;
-
-       shader->entry.visited = 0;
-       shader->end.visited = 0;
-       c_list_for_each(n, &shader->nodes) {
-               n->visited = 0;
-       }
-       c_shader_dfs_without_rec(&shader->entry, node);
-}
-
-static int c_shader_build_dominator_tree_rec(struct c_shader *shader, struct c_node *node)
-{
-       struct c_node_link *link, *nlink;
-       unsigned found = 0;
-       int r;
-
-       if (node->done)
-               return 0;
-       node->done = 1;
-       c_list_for_each(link, &node->predecessors) {
-               /* if we remove this predecessor can we reach the current node ? */
-               c_shader_dfs_without(shader, link->node);
-               if (node->visited == 0) {
-                       /* we were unable to visit current node thus current
-                        * predecessor  is the immediate dominator of node, as
-                        * their can be only one immediate dominator we break
-                        */
-                       node->parent = link->node;
-                       nlink = c_node_link_new(node);
-                       if (nlink == NULL)
-                               return -ENOMEM;
-                       c_list_add_tail(nlink, &link->node->childs);
-                       found = 1;
-                       break;
-               }
-       }
-       /* this shouldn't happen there should at least be 1 denominator for each node */
-       if (!found && node->opcode != C_OPCODE_ENTRY) {
-               fprintf(stderr, "invalid flow control graph node %p (%d) has no immediate dominator\n",
-                       node, node->opcode);
-               return -EINVAL;
-       }
-       c_list_for_each(link, &node->predecessors) {
-               r = c_shader_build_dominator_tree_rec(shader, link->node);
-               if (r)
-                       return r;
-       }
-       return 0;
-}
-
-int c_shader_build_dominator_tree(struct c_shader *shader)
-{
-       struct c_node *node;
-       c_list_for_each(node, &shader->nodes) {
-               node->done = 0;
-       }
-       return c_shader_build_dominator_tree_rec(shader, &shader->end);
-}
diff --git a/src/gallium/drivers/r600/r600_compiler.h b/src/gallium/drivers/r600/r600_compiler.h
deleted file mode 100644 (file)
index 3de1997..0000000
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) 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.
- */
-#ifndef R600_COMPILER_H
-#define R600_COMPILER_H
-
-struct c_vector;
-
-/* operand are the basic source/destination of each operation */
-struct c_channel {
-       struct c_channel        *next;
-       struct c_channel        *prev;
-       unsigned                vindex;         /**< index in vector X,Y,Z,W (0,1,2,3) */
-       unsigned                value;          /**< immediate value 32bits */
-       struct c_vector         *vector;        /**< vector to which it belongs */
-};
-
-/* in GPU world most of the time operand are grouped into vector
- * of 4 component this structure is mostly and handler to group
- * operand into a same vector
- */
-struct c_vector {
-       struct c_vector         *next;
-       struct c_vector         *prev;
-       unsigned                id;             /**< vector uniq id */
-       unsigned                name;           /**< semantic name */
-       unsigned                file;           /**< operand file C_FILE_* */
-       int                     sid;            /**< semantic id */
-       struct c_channel        *channel[4];    /**< operands */
-};
-
-#define c_list_init(e) do { (e)->next = e; (e)->prev = e; } while(0)
-#define c_list_add(e, h) do { (e)->next = (h)->next; (e)->prev = h;  (h)->next = e; (e)->next->prev = e; } while(0)
-#define c_list_add_tail(e, h) do { (e)->next = h; (e)->prev = (h)->prev;  (h)->prev = e; (e)->prev->next = e; } while(0)
-#define c_list_del(e) do { (e)->next->prev = (e)->prev; (e)->prev->next = (e)->next; c_list_init(e); } while(0)
-#define c_list_for_each(p, h) for (p = (h)->next; p != (h); p = p->next)
-#define c_list_for_each_from(p, s, h) for (p = s; p != (h); p = p->next)
-#define c_list_for_each_safe(p, n, h) for (p = (h)->next, n = p->next; p != (h); p = n, n = p->next)
-#define c_list_empty(h) ((h)->next == h)
-
-
-#define C_PROGRAM_TYPE_VS      0
-#define C_PROGRAM_TYPE_FS      1
-#define C_PROGRAM_TYPE_COUNT   2
-
-#define C_NODE_FLAG_ALU                1
-#define C_NODE_FLAG_FETCH      2
-
-#define C_SWIZZLE_X            0
-#define C_SWIZZLE_Y            1
-#define C_SWIZZLE_Z            2
-#define C_SWIZZLE_W            3
-#define C_SWIZZLE_0            4
-#define C_SWIZZLE_1            5
-#define C_SWIZZLE_D            6
-
-#define C_FILE_NULL            0
-#define C_FILE_CONSTANT                1
-#define C_FILE_INPUT           2
-#define C_FILE_OUTPUT          3
-#define C_FILE_TEMPORARY       4
-#define C_FILE_SAMPLER         5
-#define C_FILE_ADDRESS         6
-#define C_FILE_IMMEDIATE       7
-#define C_FILE_LOOP            8
-#define C_FILE_PREDICATE       9
-#define C_FILE_SYSTEM_VALUE    10
-#define C_FILE_RESOURCE                11
-#define C_FILE_COUNT           12
-
-#define C_SEMANTIC_POSITION    0
-#define C_SEMANTIC_COLOR       1
-#define C_SEMANTIC_BCOLOR      2  /**< back-face color */
-#define C_SEMANTIC_FOG         3
-#define C_SEMANTIC_PSIZE       4
-#define C_SEMANTIC_GENERIC     5
-#define C_SEMANTIC_NORMAL      6
-#define C_SEMANTIC_FACE                7
-#define C_SEMANTIC_EDGEFLAG    8
-#define C_SEMANTIC_PRIMID      9
-#define C_SEMANTIC_INSTANCEID  10
-#define C_SEMANTIC_VERTEXID    11
-#define C_SEMANTIC_COUNT       12 /**< number of semantic values */
-
-#define C_OPCODE_NOP           0
-#define C_OPCODE_MOV           1
-#define C_OPCODE_LIT           2
-#define C_OPCODE_RCP           3
-#define C_OPCODE_RSQ           4
-#define C_OPCODE_EXP           5
-#define C_OPCODE_LOG           6
-#define C_OPCODE_MUL           7
-#define C_OPCODE_ADD           8
-#define C_OPCODE_DP3           9
-#define C_OPCODE_DP4           10
-#define C_OPCODE_DST           11
-#define C_OPCODE_MIN           12
-#define C_OPCODE_MAX           13
-#define C_OPCODE_SLT           14
-#define C_OPCODE_SGE           15
-#define C_OPCODE_MAD           16
-#define C_OPCODE_SUB           17
-#define C_OPCODE_LRP           18
-#define C_OPCODE_CND           19
-/* gap */
-#define C_OPCODE_DP2A          21
-/* gap */
-#define C_OPCODE_FRC           24
-#define C_OPCODE_CLAMP         25
-#define C_OPCODE_FLR           26
-#define C_OPCODE_ROUND         27
-#define C_OPCODE_EX2           28
-#define C_OPCODE_LG2           29
-#define C_OPCODE_POW           30
-#define C_OPCODE_XPD           31
-/* gap */
-#define C_OPCODE_ABS           33
-#define C_OPCODE_RCC           34
-#define C_OPCODE_DPH           35
-#define C_OPCODE_COS           36
-#define C_OPCODE_DDX           37
-#define C_OPCODE_DDY           38
-#define C_OPCODE_KILP          39              /* predicated kill */
-#define C_OPCODE_PK2H          40
-#define C_OPCODE_PK2US         41
-#define C_OPCODE_PK4B          42
-#define C_OPCODE_PK4UB         43
-#define C_OPCODE_RFL           44
-#define C_OPCODE_SEQ           45
-#define C_OPCODE_SFL           46
-#define C_OPCODE_SGT           47
-#define C_OPCODE_SIN           48
-#define C_OPCODE_SLE           49
-#define C_OPCODE_SNE           50
-#define C_OPCODE_STR           51
-#define C_OPCODE_TEX           52
-#define C_OPCODE_TXD           53
-#define C_OPCODE_TXP           54
-#define C_OPCODE_UP2H          55
-#define C_OPCODE_UP2US         56
-#define C_OPCODE_UP4B          57
-#define C_OPCODE_UP4UB         58
-#define C_OPCODE_X2D           59
-#define C_OPCODE_ARA           60
-#define C_OPCODE_ARR           61
-#define C_OPCODE_BRA           62
-#define C_OPCODE_CAL           63
-#define C_OPCODE_RET           64
-#define C_OPCODE_SSG           65              /* SGN */
-#define C_OPCODE_CMP           66
-#define C_OPCODE_SCS           67
-#define C_OPCODE_TXB           68
-#define C_OPCODE_NRM           69
-#define C_OPCODE_DIV           70
-#define C_OPCODE_DP2           71
-#define C_OPCODE_TXL           72
-#define C_OPCODE_BRK           73
-#define C_OPCODE_IF            74
-#define C_OPCODE_BGNFOR                75
-#define C_OPCODE_REP           76
-#define C_OPCODE_ELSE          77
-#define C_OPCODE_ENDIF         78
-#define C_OPCODE_ENDFOR                79
-#define C_OPCODE_ENDREP                80
-#define C_OPCODE_PUSHA         81
-#define C_OPCODE_POPA          82
-#define C_OPCODE_CEIL          83
-#define C_OPCODE_I2F           84
-#define C_OPCODE_NOT           85
-#define C_OPCODE_TRUNC         86
-#define C_OPCODE_SHL           87
-/* gap */
-#define C_OPCODE_AND           89
-#define C_OPCODE_OR            90
-#define C_OPCODE_MOD           91
-#define C_OPCODE_XOR           92
-#define C_OPCODE_SAD           93
-#define C_OPCODE_TXF           94
-#define C_OPCODE_TXQ           95
-#define C_OPCODE_CONT          96
-#define C_OPCODE_EMIT          97
-#define C_OPCODE_ENDPRIM       98
-#define C_OPCODE_BGNLOOP       99
-#define C_OPCODE_BGNSUB                100
-#define C_OPCODE_ENDLOOP       101
-#define C_OPCODE_ENDSUB                102
-/* gap */
-#define C_OPCODE_NRM4          112
-#define C_OPCODE_CALLNZ                113
-#define C_OPCODE_IFC           114
-#define C_OPCODE_BREAKC                115
-#define C_OPCODE_KIL           116     /* conditional kill */
-#define C_OPCODE_END           117     /* aka HALT */
-/* gap */
-#define C_OPCODE_F2I           119
-#define C_OPCODE_IDIV          120
-#define C_OPCODE_IMAX          121
-#define C_OPCODE_IMIN          122
-#define C_OPCODE_INEG          123
-#define C_OPCODE_ISGE          124
-#define C_OPCODE_ISHR          125
-#define C_OPCODE_ISLT          126
-#define C_OPCODE_F2U           127
-#define C_OPCODE_U2F           128
-#define C_OPCODE_UADD          129
-#define C_OPCODE_UDIV          130
-#define C_OPCODE_UMAD          131
-#define C_OPCODE_UMAX          132
-#define C_OPCODE_UMIN          133
-#define C_OPCODE_UMOD          134
-#define C_OPCODE_UMUL          135
-#define C_OPCODE_USEQ          136
-#define C_OPCODE_USGE          137
-#define C_OPCODE_USHR          138
-#define C_OPCODE_USLT          139
-#define C_OPCODE_USNE          140
-#define C_OPCODE_SWITCH                141
-#define C_OPCODE_CASE          142
-#define C_OPCODE_DEFAULT       143
-#define C_OPCODE_ENDSWITCH     144
-#define C_OPCODE_VFETCH                145
-#define C_OPCODE_ENTRY         146
-#define C_OPCODE_ARL           147
-#define C_OPCODE_LAST          148
-
-#define C_OPERAND_FLAG_ABS             (1 << 0)
-#define C_OPERAND_FLAG_NEG             (1 << 1)
-
-struct c_operand {
-       struct c_vector         *vector;
-       unsigned                swizzle;
-       unsigned                flag;
-};
-
-struct c_op {
-       unsigned                ninput;
-       struct c_operand        input[3];
-       struct c_operand        output;
-       unsigned                opcode;
-};
-
-struct c_instruction {
-       struct c_instruction    *next, *prev;
-       unsigned                nop;
-       struct c_op             op[5];
-};
-
-struct c_node;
-
-struct c_node_link {
-       struct c_node_link      *next;
-       struct c_node_link      *prev;
-       struct c_node           *node;
-};
-
-/**
- * struct c_node
- *
- * @next:              all node are in a double linked list, this point to
- *                     next node
- * @next:              all node are in a double linked list, this point to
- *                     previous node
- * @predecessors:      list of all predecessor nodes in the flow graph
- * @successors:                list of all sucessor nodes in the flow graph
- * @parent:            parent node in the depth first walk tree
- * @childs:            child nodes in the depth first walk tree
- */
-struct c_node {
-       struct c_node           *next, *prev;
-       struct c_node_link      predecessors;
-       struct c_node_link      successors;
-       struct c_node           *parent;
-       struct c_node_link      childs;
-       struct c_instruction    insts;
-       unsigned                opcode;
-       unsigned                visited;
-       unsigned                done;
-       void                    *backend;
-};
-
-struct c_file {
-       unsigned                nvectors;
-       struct c_vector         vectors;
-};
-
-struct c_shader {
-       unsigned                        nvectors;
-       struct c_file                   files[C_FILE_COUNT];
-       struct c_node                   nodes;
-       struct c_node                   entry;
-       struct c_node                   end;
-       unsigned                        type;
-};
-
-int c_shader_init(struct c_shader *shader, unsigned type);
-void c_shader_destroy(struct c_shader *shader);
-struct c_vector *c_shader_vector_new(struct c_shader *shader, unsigned file, unsigned name, int sid);
-int c_shader_build_dominator_tree(struct c_shader *shader);
-void c_shader_dump(struct c_shader *shader);
-
-void c_node_init(struct c_node *node);
-int c_node_add_new_instruction(struct c_node *node, struct c_instruction *instruction);
-int c_node_add_new_instruction_head(struct c_node *node, struct c_instruction *instruction);
-
-/* control flow graph functions */
-int c_node_cfg_link(struct c_node *predecessor, struct c_node *successor);
-struct c_node *c_node_cfg_new_after(struct c_node *predecessor);
-struct c_node *c_shader_cfg_new_node_after(struct c_shader *shader, struct c_node *predecessor);
-
-struct c_vector *c_vector_new(void);
-
-#endif
diff --git a/src/gallium/drivers/r600/r600_compiler_dump.c b/src/gallium/drivers/r600/r600_compiler_dump.c
deleted file mode 100644 (file)
index 4850320..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdio.h>
-#include "r600_compiler.h"
-
-static const char *c_file_swz[] = {
-       "x",
-       "y",
-       "z",
-       "w",
-       "0",
-       "1",
-       ".",
-};
-
-static const char *c_file_str[] = {
-       "NULL",
-       "CONSTANT",
-       "INPUT",
-       "OUTPUT",
-       "TEMPORARY",
-       "SAMPLER",
-       "ADDRESS",
-       "IMMEDIATE",
-       "LOOP",
-       "PREDICATE",
-       "SYSTEM_VALUE",
-};
-
-static const char *c_semantic_str[] = {
-       "POSITION",
-       "COLOR",
-       "BCOLOR",
-       "FOG",
-       "PSIZE",
-       "GENERIC",
-       "NORMAL",
-       "FACE",
-       "EDGEFLAG",
-       "PRIMID",
-       "INSTANCEID",
-};
-
-static const char *c_opcode_str[] = {
-       "ARL",
-       "MOV",
-       "LIT",
-       "RCP",
-       "RSQ",
-       "EXP",
-       "LOG",
-       "MUL",
-       "ADD",
-       "DP3",
-       "DP4",
-       "DST",
-       "MIN",
-       "MAX",
-       "SLT",
-       "SGE",
-       "MAD",
-       "SUB",
-       "LRP",
-       "CND",
-       "(INVALID)",
-       "DP2A",
-       "(INVALID)",
-       "(INVALID)",
-       "FRC",
-       "CLAMP",
-       "FLR",
-       "ROUND",
-       "EX2",
-       "LG2",
-       "POW",
-       "XPD",
-       "(INVALID)",
-       "ABS",
-       "RCC",
-       "DPH",
-       "COS",
-       "DDX",
-       "DDY",
-       "KILP",
-       "PK2H",
-       "PK2US",
-       "PK4B",
-       "PK4UB",
-       "RFL",
-       "SEQ",
-       "SFL",
-       "SGT",
-       "SIN",
-       "SLE",
-       "SNE",
-       "STR",
-       "TEX",
-       "TXD",
-       "TXP",
-       "UP2H",
-       "UP2US",
-       "UP4B",
-       "UP4UB",
-       "X2D",
-       "ARA",
-       "ARR",
-       "BRA",
-       "CAL",
-       "RET",
-       "SSG",
-       "CMP",
-       "SCS",
-       "TXB",
-       "NRM",
-       "DIV",
-       "DP2",
-       "TXL",
-       "BRK",
-       "IF",
-       "BGNFOR",
-       "REP",
-       "ELSE",
-       "ENDIF",
-       "ENDFOR",
-       "ENDREP",
-       "PUSHA",
-       "POPA",
-       "CEIL",
-       "I2F",
-       "NOT",
-       "TRUNC",
-       "SHL",
-       "(INVALID)",
-       "AND",
-       "OR",
-       "MOD",
-       "XOR",
-       "SAD",
-       "TXF",
-       "TXQ",
-       "CONT",
-       "EMIT",
-       "ENDPRIM",
-       "BGNLOOP",
-       "BGNSUB",
-       "ENDLOOP",
-       "ENDSUB",
-       "(INVALID)",
-       "(INVALID)",
-       "(INVALID)",
-       "(INVALID)",
-       "NOP",
-       "(INVALID)",
-       "(INVALID)",
-       "(INVALID)",
-       "(INVALID)",
-       "NRM4",
-       "CALLNZ",
-       "IFC",
-       "BREAKC",
-       "KIL",
-       "END",
-       "(INVALID)",
-       "F2I",
-       "IDIV",
-       "IMAX",
-       "IMIN",
-       "INEG",
-       "ISGE",
-       "ISHR",
-       "ISLT",
-       "F2U",
-       "U2F",
-       "UADD",
-       "UDIV",
-       "UMAD",
-       "UMAX",
-       "UMIN",
-       "UMOD",
-       "UMUL",
-       "USEQ",
-       "USGE",
-       "USHR",
-       "USLT",
-       "USNE",
-       "SWITCH",
-       "CASE",
-       "DEFAULT",
-       "ENDSWITCH",
-       "VFETCH",
-       "ENTRY",
-};
-
-static inline const char *c_get_name(const char *name[], unsigned i)
-{
-       return name[i];
-}
-
-static void pindent(unsigned indent)
-{
-       unsigned i;
-       for (i = 0; i < indent; i++)
-               fprintf(stderr, " ");
-}
-
-static void c_node_dump(struct c_node *node, unsigned indent)
-{
-       struct c_instruction *i;
-       unsigned j, k;
-
-       pindent(indent); fprintf(stderr, "# node %s\n", c_get_name(c_opcode_str, node->opcode));
-       c_list_for_each(i, &node->insts) {
-               for (k = 0; k < i->nop; k++) {
-                       pindent(indent);
-                       fprintf(stderr, "%s", c_get_name(c_opcode_str, i->op[k].opcode));
-                       fprintf(stderr, " %s[%d][%s]",
-                               c_get_name(c_file_str, i->op[k].output.vector->file),
-                               i->op[k].output.vector->id,
-                               c_get_name(c_file_swz, i->op[k].output.swizzle));
-                       for (j = 0; j < i->op[k].ninput; j++) {
-                               fprintf(stderr, " %s[%d][%s]",
-                                               c_get_name(c_file_str, i->op[k].input[j].vector->file),
-                                               i->op[k].input[j].vector->id,
-                                               c_get_name(c_file_swz, i->op[k].input[j].swizzle));
-                       }
-                       fprintf(stderr, ";\n");
-               }
-       }
-}
-
-static void c_shader_dump_rec(struct c_shader *shader, struct c_node *node, unsigned indent)
-{
-       struct c_node_link *link;
-
-       c_node_dump(node, indent);
-       c_list_for_each(link, &node->childs) {
-               c_shader_dump_rec(shader, link->node, indent + 1);
-       }
-}
-
-void c_shader_dump(struct c_shader *shader)
-{
-       c_shader_dump_rec(shader, &shader->entry, 0);
-}
diff --git a/src/gallium/drivers/r600/r600_compiler_r600.c b/src/gallium/drivers/r600/r600_compiler_r600.c
deleted file mode 100644 (file)
index 14ea8ab..0000000
+++ /dev/null
@@ -1,891 +0,0 @@
-/*
- * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <errno.h>
-#include <util/u_format.h>
-#include "r600_screen.h"
-#include "r600_context.h"
-#include "r600_sq.h"
-
-
-struct r600_alu_instruction {
-       unsigned                        copcode;
-       enum r600_instruction           instruction;
-};
-
-static int r600_shader_alu_translate(struct r600_shader *rshader,
-                                       struct r600_shader_node *node,
-                                       struct c_instruction *instruction);
-struct r600_alu_instruction r600_alu_instruction[C_OPCODE_LAST];
-struct r600_instruction_info r600_instruction_info[];
-
-int r600_shader_insert_fetch(struct c_shader *shader)
-{
-       struct c_vector *vi, *vr, *v, *nv;
-       struct c_instruction instruction;
-       int r;
-
-       if (shader->type != C_PROGRAM_TYPE_VS)
-               return 0;
-       vi = c_shader_vector_new(shader, C_FILE_INPUT, C_SEMANTIC_VERTEXID, -1);
-       if (vi == NULL)
-               return -ENOMEM;
-       c_list_for_each_safe(v, nv, &shader->files[C_FILE_INPUT].vectors) {
-               if (v == vi)
-                       continue;
-               vr = c_shader_vector_new(shader, C_FILE_RESOURCE, C_SEMANTIC_GENERIC, -1);
-               if (vr == NULL)
-                       return -ENOMEM;
-               memset(&instruction, 0, sizeof(struct c_instruction));
-               instruction.nop = 4;
-               instruction.op[0].opcode = C_OPCODE_VFETCH;
-               instruction.op[1].opcode = C_OPCODE_VFETCH;
-               instruction.op[2].opcode = C_OPCODE_VFETCH;
-               instruction.op[3].opcode = C_OPCODE_VFETCH;
-               instruction.op[0].ninput = 2;
-               instruction.op[1].ninput = 2;
-               instruction.op[2].ninput = 2;
-               instruction.op[3].ninput = 2;
-               instruction.op[0].output.vector = v;
-               instruction.op[1].output.vector = v;
-               instruction.op[2].output.vector = v;
-               instruction.op[3].output.vector = v;
-               instruction.op[0].input[0].vector = vi;
-               instruction.op[0].input[1].vector = vr;
-               instruction.op[1].input[0].vector = vi;
-               instruction.op[1].input[1].vector = vr;
-               instruction.op[2].input[0].vector = vi;
-               instruction.op[2].input[1].vector = vr;
-               instruction.op[3].input[0].vector = vi;
-               instruction.op[3].input[1].vector = vr;
-               instruction.op[0].output.swizzle = C_SWIZZLE_X;
-               instruction.op[1].output.swizzle = C_SWIZZLE_Y;
-               instruction.op[2].output.swizzle = C_SWIZZLE_Z;
-               instruction.op[3].output.swizzle = C_SWIZZLE_W;
-               r = c_node_add_new_instruction_head(&shader->entry, &instruction);
-               if (r)
-                       return r;
-               c_list_del(v);
-               shader->files[C_FILE_INPUT].nvectors--;
-               c_list_add_tail(v, &shader->files[C_FILE_TEMPORARY].vectors);
-               shader->files[C_FILE_TEMPORARY].nvectors++;
-               v->file = C_FILE_TEMPORARY;
-       }
-       return 0;
-}
-
-void r600_shader_cleanup(struct r600_shader *rshader)
-{
-       struct r600_shader_node *n, *nn;
-       struct r600_shader_vfetch *vf, *nvf;
-       struct r600_shader_alu *alu, *nalu;
-       int i;
-
-       if (rshader == NULL)
-               return;
-       if (rshader->gpr) {
-               for (i = 0; i < rshader->nvector; i++) {
-                       free(rshader->gpr[i]);
-               }
-               free(rshader->gpr);
-               rshader->gpr = NULL;
-       }
-       c_list_for_each_safe(n, nn, &rshader->nodes) {
-               c_list_del(n);
-               c_list_for_each_safe(vf, nvf, &n->vfetch) {
-                       c_list_del(vf);
-                       free(vf);
-               }
-               c_list_for_each_safe(alu, nalu, &n->alu) {
-                       c_list_del(alu);
-                       free(alu);
-               }
-               free(n);
-       }
-       free(rshader->bcode);
-       return;
-}
-
-int r600_shader_vfetch_bytecode(struct r600_shader *rshader,
-                               struct r600_shader_node *rnode,
-                               struct r600_shader_vfetch *vfetch,
-                               unsigned *cid)
-{
-       unsigned id = *cid;
-
-       vfetch->cf_addr = id;
-       rshader->bcode[id++] = S_SQ_VTX_WORD0_BUFFER_ID(vfetch->src[1].sel) |
-                               S_SQ_VTX_WORD0_SRC_GPR(vfetch->src[0].sel) |
-                               S_SQ_VTX_WORD0_SRC_SEL_X(vfetch->src[0].sel) |
-                               S_SQ_VTX_WORD0_MEGA_FETCH_COUNT(0x1F);
-       rshader->bcode[id++] = S_SQ_VTX_WORD1_DST_SEL_X(vfetch->dst[0].chan) |
-                               S_SQ_VTX_WORD1_DST_SEL_Y(vfetch->dst[1].chan) |
-                               S_SQ_VTX_WORD1_DST_SEL_Z(vfetch->dst[2].chan) |
-                               S_SQ_VTX_WORD1_DST_SEL_W(vfetch->dst[3].chan) |
-                               S_SQ_VTX_WORD1_USE_CONST_FIELDS(1) |
-                               S_SQ_VTX_WORD1_GPR_DST_GPR(vfetch->dst[0].sel);
-       rshader->bcode[id++] = S_SQ_VTX_WORD2_MEGA_FETCH(1);
-       rshader->bcode[id++] = 0;
-       *cid = id;
-       return 0;
-}
-
-int r600_shader_update(struct r600_shader *rshader, enum pipe_format *resource_format)
-{
-       struct r600_shader_node *rnode;
-       struct r600_shader_vfetch *vfetch;
-       unsigned i;
-
-       memcpy(rshader->resource_format, resource_format,
-               rshader->nresource * sizeof(enum pipe_format));
-       c_list_for_each(rnode, &rshader->nodes) {
-               c_list_for_each(vfetch, &rnode->vfetch) {
-                       const struct util_format_description *desc;
-                       i = vfetch->cf_addr + 1;
-                       rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_X;
-                       rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_Y;
-                       rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_Z;
-                       rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_W;
-                       desc = util_format_description(resource_format[vfetch->src[1].sel]);
-                       if (desc == NULL) {
-                               fprintf(stderr, "%s unknown format %d\n", __func__, resource_format[vfetch->src[1].sel]);
-                               continue;
-                       }
-                       /* WARNING so far TGSI swizzle match R600 ones */
-                       rshader->bcode[i] |= S_SQ_VTX_WORD1_DST_SEL_X(desc->swizzle[0]);
-                       rshader->bcode[i] |= S_SQ_VTX_WORD1_DST_SEL_Y(desc->swizzle[1]);
-                       rshader->bcode[i] |= S_SQ_VTX_WORD1_DST_SEL_Z(desc->swizzle[2]);
-                       rshader->bcode[i] |= S_SQ_VTX_WORD1_DST_SEL_W(desc->swizzle[3]);
-               }
-       }
-       return 0;
-}
-
-int r600_shader_register(struct r600_shader *rshader)
-{
-       struct c_vector *v, *nv;
-       unsigned tid, cid, rid, i;
-
-       rshader->nvector = rshader->cshader.nvectors;
-       rshader->gpr = calloc(rshader->nvector, sizeof(void*));
-       if (rshader->gpr == NULL)
-               return -ENOMEM;
-       tid = 0;
-       cid = 0;
-       rid = 0;
-       /* alloc input first */
-       c_list_for_each(v, &rshader->cshader.files[C_FILE_INPUT].vectors) {
-               nv = c_vector_new();
-               if (nv == NULL) {
-                       return -ENOMEM;
-               }
-               memcpy(nv, v, sizeof(struct c_vector));
-               nv->id = tid++;
-               rshader->gpr[v->id] = nv;
-       }
-       for (i = 0; i < C_FILE_COUNT; i++) {
-               if (i == C_FILE_INPUT || i == C_FILE_IMMEDIATE)
-                       continue;
-               c_list_for_each(v, &rshader->cshader.files[i].vectors) {
-                       switch (v->file) {
-                       case C_FILE_OUTPUT:
-                       case C_FILE_TEMPORARY:
-                               nv = c_vector_new();
-                               if (nv == NULL) {
-                                       return -ENOMEM;
-                               }
-                               memcpy(nv, v, sizeof(struct c_vector));
-                               nv->id = tid++;
-                               rshader->gpr[v->id] = nv;
-                               break;
-                       case C_FILE_CONSTANT:
-                               nv = c_vector_new();
-                               if (nv == NULL) {
-                                       return -ENOMEM;
-                               }
-                               memcpy(nv, v, sizeof(struct c_vector));
-                               nv->id = (cid++) + 256;
-                               rshader->gpr[v->id] = nv;
-                               break;
-                       case C_FILE_RESOURCE:
-                               nv = c_vector_new();
-                               if (nv == NULL) {
-                                       return -ENOMEM;
-                               }
-                               memcpy(nv, v, sizeof(struct c_vector));
-                               nv->id = (rid++);
-                               rshader->gpr[v->id] = nv;
-                               break;
-                       default:
-                               fprintf(stderr, "%s:%d unsupported file %d\n", __func__, __LINE__, v->file);
-                               return -EINVAL;
-                       }
-               }
-       }
-       rshader->ngpr = tid;
-       rshader->nconstant = cid;
-       rshader->nresource = rid;
-       return 0;
-}
-
-int r600_shader_find_gpr(struct r600_shader *rshader, struct c_vector *v, unsigned swizzle,
-                       struct r600_shader_operand *operand)
-{
-       struct c_vector *tmp;
-
-       /* Values [0,127] correspond to GPR[0..127]. 
-        * Values [256,511] correspond to cfile constants c[0..255]. 
-        * Other special values are shown in the list below.
-        * 248  SQ_ALU_SRC_0: special constant 0.0.
-        * 249  SQ_ALU_SRC_1: special constant 1.0 float.
-        * 250  SQ_ALU_SRC_1_INT: special constant 1 integer.
-        * 251  SQ_ALU_SRC_M_1_INT: special constant -1 integer.
-        * 252  SQ_ALU_SRC_0_5: special constant 0.5 float.
-        * 253  SQ_ALU_SRC_LITERAL: literal constant.
-        * 254  SQ_ALU_SRC_PV: previous vector result.
-        * 255  SQ_ALU_SRC_PS: previous scalar result.
-        */
-       operand->vector = v;
-       operand->sel = 248;
-       operand->chan = 0;
-       operand->neg = 0;
-       operand->abs = 0;
-       if (v == NULL)
-               return 0;
-       if (v->file == C_FILE_IMMEDIATE) {
-               operand->sel = 253;
-       } else {
-               tmp = rshader->gpr[v->id];
-               if (tmp == NULL) {
-                       fprintf(stderr, "%s %d unknown register\n", __FILE__, __LINE__);
-                       return -EINVAL;
-               }
-               operand->sel = tmp->id;
-       }
-       operand->chan = swizzle;
-       switch (swizzle) {
-       case C_SWIZZLE_X:
-       case C_SWIZZLE_Y:
-       case C_SWIZZLE_Z:
-       case C_SWIZZLE_W:
-               break;
-       case C_SWIZZLE_0:
-               operand->sel = 248;
-               operand->chan = 0;
-               break;
-       case C_SWIZZLE_1:
-               operand->sel = 249;
-               operand->chan = 0;
-               break;
-       default:
-               fprintf(stderr, "%s %d invalid swizzle %d\n", __FILE__, __LINE__, swizzle);
-               return -EINVAL;
-       }
-       return 0;
-}
-
-static struct r600_shader_node *r600_shader_new_node(struct r600_shader *rshader, struct c_node *node)
-{
-       struct r600_shader_node *rnode;
-
-       rnode = CALLOC_STRUCT(r600_shader_node);
-       if (rnode == NULL)
-               return NULL;
-       rnode->node = node;
-       c_list_init(&rnode->vfetch);
-       c_list_init(&rnode->alu);
-       c_list_add_tail(rnode, &rshader->nodes);
-       return rnode;
-}
-
-static int r600_shader_add_vfetch(struct r600_shader *rshader,
-                               struct r600_shader_node *node,
-                               struct c_instruction *instruction)
-{
-       struct r600_shader_vfetch *vfetch;
-       struct r600_shader_node *rnode;
-       int r;
-
-       if (instruction == NULL)
-               return 0;
-       if (instruction->op[0].opcode != C_OPCODE_VFETCH)
-               return 0;
-       if (!c_list_empty(&node->alu)) {
-               rnode = r600_shader_new_node(rshader, node->node);
-               if (rnode == NULL)
-                       return -ENOMEM;
-               node = rnode;
-       }
-       vfetch = calloc(1, sizeof(struct r600_shader_vfetch));
-       if (vfetch == NULL)
-               return -ENOMEM;
-       r = r600_shader_find_gpr(rshader, instruction->op[0].output.vector, 0, &vfetch->dst[0]);
-       if (r)
-               return r;
-       r = r600_shader_find_gpr(rshader, instruction->op[0].input[0].vector, 0, &vfetch->src[0]);
-       if (r)
-               return r;
-       r = r600_shader_find_gpr(rshader, instruction->op[0].input[1].vector, 0, &vfetch->src[1]);
-       if (r)
-               return r;
-       vfetch->dst[0].chan = C_SWIZZLE_X;
-       vfetch->dst[1].chan = C_SWIZZLE_Y;
-       vfetch->dst[2].chan = C_SWIZZLE_Z;
-       vfetch->dst[3].chan = C_SWIZZLE_W;
-       c_list_add_tail(vfetch, &node->vfetch);
-       node->nslot += 2;
-       return 0;
-}
-
-static int r600_node_translate(struct r600_shader *rshader, struct c_node *node)
-{
-       struct c_instruction *instruction;
-       struct r600_shader_node *rnode;
-       int r;
-
-       rnode = r600_shader_new_node(rshader, node);
-       if (rnode == NULL)
-               return -ENOMEM;
-       c_list_for_each(instruction, &node->insts) {
-               switch (instruction->op[0].opcode) {
-               case C_OPCODE_VFETCH:
-                       r = r600_shader_add_vfetch(rshader, rnode, instruction);
-                       if (r) {
-                               fprintf(stderr, "%s %d vfetch failed\n", __func__, __LINE__);
-                               return r;
-                       }
-                       break;
-               default:
-                       r = r600_shader_alu_translate(rshader, rnode, instruction);
-                       if (r) {
-                               fprintf(stderr, "%s %d alu failed\n", __func__, __LINE__);
-                               return r;
-                       }
-                       break;
-               }
-       }
-       return 0;
-}
-
-int r600_shader_translate_rec(struct r600_shader *rshader, struct c_node *node)
-{
-       struct c_node_link *link;
-       int r;
-
-       if (node->opcode == C_OPCODE_END)
-               return 0;
-       r = r600_node_translate(rshader, node);
-       if (r)
-               return r;
-       c_list_for_each(link, &node->childs) {
-               r = r600_shader_translate_rec(rshader, link->node);
-               if (r)
-                       return r;
-       }
-       return 0;
-}
-
-static struct r600_shader_alu *r600_shader_insert_alu(struct r600_shader *rshader, struct r600_shader_node *node)
-{
-       struct r600_shader_alu *alu;
-
-       alu = CALLOC_STRUCT(r600_shader_alu);
-       if (alu == NULL)
-               return NULL;
-       alu->alu[0].inst = INST_NOP;
-       alu->alu[1].inst = INST_NOP;
-       alu->alu[2].inst = INST_NOP;
-       alu->alu[3].inst = INST_NOP;
-       alu->alu[4].inst = INST_NOP;
-       alu->alu[0].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
-       alu->alu[1].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
-       alu->alu[2].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
-       alu->alu[3].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
-       alu->alu[4].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
-       c_list_add_tail(alu, &node->alu);
-       return alu;
-}
-
-static int r600_shader_alu_translate(struct r600_shader *rshader,
-                                       struct r600_shader_node *node,
-                                       struct c_instruction *instruction)
-{
-       struct r600_shader_node *rnode;
-       struct r600_shader_alu *alu;
-       int i, j, r, comp, litteral_lastcomp = -1;
-
-       if (!c_list_empty(&node->vfetch)) {
-               rnode = r600_shader_new_node(rshader, node->node);
-               if (rnode == NULL) {
-                       fprintf(stderr, "%s %d new node failed\n", __func__, __LINE__);
-                       return -ENOMEM;
-               }
-               node = rnode;
-       }
-
-       /* initialize alu */
-       alu = r600_shader_insert_alu(rshader, node);
-
-       /* check special operation like lit */
-
-       /* go through operation */
-       for (i = 0; i < instruction->nop; i++) {
-               struct r600_alu_instruction *ainfo = &r600_alu_instruction[instruction->op[i].opcode];
-               struct r600_instruction_info *iinfo = &r600_instruction_info[ainfo->instruction];
-               unsigned comp;
-
-               /* check that output is a valid component */
-               comp = instruction->op[i].output.swizzle;
-               switch (comp) {
-               case C_SWIZZLE_X:
-               case C_SWIZZLE_Y:
-               case C_SWIZZLE_Z:
-               case C_SWIZZLE_W:
-                       break;
-               case C_SWIZZLE_0:
-               case C_SWIZZLE_1:
-               default:
-                       fprintf(stderr, "%s %d invalid output\n", __func__, __LINE__);
-                       return -EINVAL;
-               }
-               alu->alu[comp].inst = ainfo->instruction;
-               alu->alu[comp].opcode = iinfo->opcode;
-               alu->alu[comp].is_op3 = iinfo->is_op3;
-               for (j = 0; j < instruction->op[i].ninput; j++) {
-                       r = r600_shader_find_gpr(rshader, instruction->op[i].input[j].vector,
-                                       instruction->op[i].input[j].swizzle, &alu->alu[comp].src[j]);
-                       if (r) {
-                               fprintf(stderr, "%s %d register failed\n", __FILE__, __LINE__);
-                               return r;
-                       }
-                       if (instruction->op[i].input[j].vector->file == C_FILE_IMMEDIATE) {
-                               r = instruction->op[i].input[j].swizzle;
-                               switch (r) {
-                               case C_SWIZZLE_X:
-                               case C_SWIZZLE_Y:
-                               case C_SWIZZLE_Z:
-                               case C_SWIZZLE_W:
-                                       break;
-                               case C_SWIZZLE_0:
-                               case C_SWIZZLE_1:
-                               default:
-                                       fprintf(stderr, "%s %d invalid input\n", __func__, __LINE__);
-                                       return -EINVAL;
-                               }
-                               alu->literal[r] = instruction->op[i].input[j].vector->channel[r]->value;
-                               if (r > litteral_lastcomp) {
-                                       litteral_lastcomp = r;
-                               }
-                       }
-               }
-               r = r600_shader_find_gpr(rshader, instruction->op[i].output.vector,
-                               instruction->op[i].output.swizzle, &alu->alu[comp].dst);
-               if (r) {
-                       fprintf(stderr, "%s %d register failed\n", __FILE__, __LINE__);
-                       return r;
-               }
-       }
-       switch (litteral_lastcomp) {
-       case 0:
-       case 1:
-               alu->nliteral = 2;
-               break;
-       case 2:
-       case 3:
-               alu->nliteral = 4;
-               break;
-       case -1:
-       default:
-               break;
-       }
-printf("nliteral: %d\n", alu->nliteral);
-       for (i = instruction->nop; i >= 0; i--) {
-               if (alu->alu[i].inst != INST_NOP) {
-                       alu->alu[i].last = 1;
-                       alu->nalu = i + 1;
-                       break;
-               }
-       }
-       return 0;
-}
-
-void r600_shader_node_place(struct r600_shader *rshader)
-{
-       struct r600_shader_node *node, *nnode;
-       struct r600_shader_alu *alu, *nalu;
-       struct r600_shader_vfetch *vfetch, *nvfetch;
-       unsigned cf_id = 0, cf_addr = 0;
-
-       rshader->ncf = 0;
-       rshader->nslot = 0;
-       c_list_for_each_safe(node, nnode, &rshader->nodes) {
-               c_list_for_each_safe(alu, nalu, &node->alu) {
-                       node->nslot += alu->nalu;
-                       node->nslot += alu->nliteral >> 1;
-               }
-               node->nfetch = 0;
-               c_list_for_each_safe(vfetch, nvfetch, &node->vfetch) {
-                       node->nslot += 2;
-                       node->nfetch += 1;
-               }
-               if (!c_list_empty(&node->vfetch)) {
-                       /* fetch node need to be 16 bytes aligned*/
-                       cf_addr += 1;
-                       cf_addr &= 0xFFFFFFFEUL;
-               }
-               node->cf_id = cf_id;
-               node->cf_addr = cf_addr;
-               cf_id += 2;
-               cf_addr += node->nslot * 2;
-               rshader->ncf++;
-       }
-       rshader->nslot = cf_addr;
-       c_list_for_each_safe(node, nnode, &rshader->nodes) {
-               node->cf_addr += cf_id * 2;
-       }
-       rshader->ncf += rshader->cshader.files[C_FILE_OUTPUT].nvectors;
-       rshader->ndw = rshader->ncf * 2 + rshader->nslot * 2;
-}
-
-int r600_shader_legalize(struct r600_shader *rshader)
-{
-       return 0;
-}
-
-
-static int r600_cshader_legalize_rec(struct c_shader *shader, struct c_node *node)
-{
-       struct c_node_link *link;
-       struct c_instruction *i;
-       struct c_operand operand;
-       unsigned k;
-       int r;
-
-       c_list_for_each(i, &node->insts) {
-               for (k = 0; k < i->nop; k++) {
-                       switch (i->op[k].opcode) {
-                       case C_OPCODE_SLT:
-                               i->op[k].opcode = C_OPCODE_SGT;
-                               memcpy(&operand, &i->op[k].input[0], sizeof(struct c_operand));
-                               memcpy(&i->op[k].input[0], &i->op[k].input[1], sizeof(struct c_operand));
-                               memcpy(&i->op[k].input[1], &operand, sizeof(struct c_operand));
-                               break;
-                       default:
-                               break;
-                       }
-               }
-       }
-       c_list_for_each(link, &node->childs) {
-               r = r600_cshader_legalize_rec(shader, link->node);
-               if (r) {
-                       return r;
-               }
-       }
-       return 0;
-}
-
-int r600_cshader_legalize(struct c_shader *shader)
-{
-       return r600_cshader_legalize_rec(shader, &shader->entry);
-}
-
-
-struct r600_instruction_info r600_instruction_info[] = {
-       {INST_ADD,                      V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD,                     0, 0},
-       {INST_MUL,                      V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL,                     0, 0},
-       {INST_MUL_IEEE,                 V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL_IEEE,                0, 0},
-       {INST_MAX,                      V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX,                     0, 0},
-       {INST_MIN,                      V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN,                     0, 0},
-       {INST_MAX_DX10,                 V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_DX10,                0, 0},
-       {INST_MIN_DX10,                 V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_DX10,                0, 0},
-       {INST_SETE,                     V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE,                    0, 0},
-       {INST_SETGT,                    V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT,                   0, 0},
-       {INST_SETGE,                    V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE,                   0, 0},
-       {INST_SETNE,                    V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE,                   0, 0},
-       {INST_SETE_DX10,                V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE_DX10,               0, 0},
-       {INST_SETGT_DX10,               V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_DX10,              0, 0},
-       {INST_SETGE_DX10,               V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_DX10,              0, 0},
-       {INST_SETNE_DX10,               V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE_DX10,              0, 0},
-       {INST_FRACT,                    V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FRACT,                   0, 0},
-       {INST_TRUNC,                    V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_TRUNC,                   0, 0},
-       {INST_CEIL,                     V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CEIL,                    0, 0},
-       {INST_RNDNE,                    V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RNDNE,                   0, 0},
-       {INST_FLOOR,                    V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLOOR,                   0, 0},
-       {INST_MOVA,                     V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA,                    0, 0},
-       {INST_MOVA_FLOOR,               V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR,              0, 0},
-       {INST_MOVA_INT,                 V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT,                0, 0},
-       {INST_MOV,                      V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV,                     0, 0},
-       {INST_NOP,                      V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP,                     0, 0},
-       {INST_PRED_SETGT_UINT,          V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_UINT,         0, 0},
-       {INST_PRED_SETGE_UINT,          V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_UINT,         0, 0},
-       {INST_PRED_SETE,                V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE,               0, 0},
-       {INST_PRED_SETGT,               V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT,              0, 0},
-       {INST_PRED_SETGE,               V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE,              0, 0},
-       {INST_PRED_SETNE,               V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE,              0, 0},
-       {INST_PRED_SET_INV,             V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_INV,            0, 0},
-       {INST_PRED_SET_POP,             V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_POP,            0, 0},
-       {INST_PRED_SET_CLR,             V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_CLR,            0, 0},
-       {INST_PRED_SET_RESTORE,         V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_RESTORE,        0, 0},
-       {INST_PRED_SETE_PUSH,           V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH,          0, 0},
-       {INST_PRED_SETGT_PUSH,          V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH,         0, 0},
-       {INST_PRED_SETGE_PUSH,          V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH,         0, 0},
-       {INST_PRED_SETNE_PUSH,          V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH,         0, 0},
-       {INST_KILLE,                    V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE,                   0, 0},
-       {INST_KILLGT,                   V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT,                  0, 0},
-       {INST_KILLGE,                   V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE,                  0, 0},
-       {INST_KILLNE,                   V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE,                  0, 0},
-       {INST_AND_INT,                  V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_AND_INT,                 0, 0},
-       {INST_OR_INT,                   V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_OR_INT,                  0, 0},
-       {INST_XOR_INT,                  V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_XOR_INT,                 0, 0},
-       {INST_NOT_INT,                  V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOT_INT,                 0, 0},
-       {INST_ADD_INT,                  V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD_INT,                 0, 0},
-       {INST_SUB_INT,                  V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SUB_INT,                 0, 0},
-       {INST_MAX_INT,                  V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_INT,                 0, 0},
-       {INST_MIN_INT,                  V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_INT,                 0, 0},
-       {INST_MAX_UINT,                 V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_UINT,                0, 0},
-       {INST_MIN_UINT,                 V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_UINT,                0, 0},
-       {INST_SETE_INT,                 V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE_INT,                0, 0},
-       {INST_SETGT_INT,                V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_INT,               0, 0},
-       {INST_SETGE_INT,                V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_INT,               0, 0},
-       {INST_SETNE_INT,                V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE_INT,               0, 0},
-       {INST_SETGT_UINT,               V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_UINT,              0, 0},
-       {INST_SETGE_UINT,               V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_UINT,              0, 0},
-       {INST_KILLGT_UINT,              V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_UINT,             0, 0},
-       {INST_KILLGE_UINT,              V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_UINT,             0, 0},
-       {INST_PRED_SETE_INT,            V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_INT,           0, 0},
-       {INST_PRED_SETGT_INT,           V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_INT,          0, 0},
-       {INST_PRED_SETGE_INT,           V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_INT,          0, 0},
-       {INST_PRED_SETNE_INT,           V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_INT,          0, 0},
-       {INST_KILLE_INT,                V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE_INT,               0, 0},
-       {INST_KILLGT_INT,               V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_INT,              0, 0},
-       {INST_KILLGE_INT,               V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_INT,              0, 0},
-       {INST_KILLNE_INT,               V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE_INT,              0, 0},
-       {INST_PRED_SETE_PUSH_INT,       V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH_INT,      0, 0},
-       {INST_PRED_SETGT_PUSH_INT,      V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH_INT,     0, 0},
-       {INST_PRED_SETGE_PUSH_INT,      V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH_INT,     0, 0},
-       {INST_PRED_SETNE_PUSH_INT,      V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH_INT,     0, 0},
-       {INST_PRED_SETLT_PUSH_INT,      V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLT_PUSH_INT,     0, 0},
-       {INST_PRED_SETLE_PUSH_INT,      V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLE_PUSH_INT,     0, 0},
-       {INST_DOT4,                     V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4,                    0, 0},
-       {INST_DOT4_IEEE,                V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE,               0, 0},
-       {INST_CUBE,                     V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE,                    0, 0},
-       {INST_MAX4,                     V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX4,                    0, 0},
-       {INST_MOVA_GPR_INT,             V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_GPR_INT,            0, 0},
-       {INST_EXP_IEEE,                 V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE,                1, 0},
-       {INST_LOG_CLAMPED,              V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED,             1, 0},
-       {INST_LOG_IEEE,                 V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE,                1, 0},
-       {INST_RECIP_CLAMPED,            V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_CLAMPED,           1, 0},
-       {INST_RECIP_FF,                 V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_FF,                1, 0},
-       {INST_RECIP_IEEE,               V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE,              1, 0},
-       {INST_RECIPSQRT_CLAMPED,        V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED,       1, 0},
-       {INST_RECIPSQRT_FF,             V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_FF,            1, 0},
-       {INST_RECIPSQRT_IEEE,           V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE,          1, 0},
-       {INST_SQRT_IEEE,                V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SQRT_IEEE,               1, 0},
-       {INST_FLT_TO_INT,               V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT,              1, 0},
-       {INST_INT_TO_FLT,               V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_INT_TO_FLT,              1, 0},
-       {INST_UINT_TO_FLT,              V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_UINT_TO_FLT,             1, 0},
-       {INST_SIN,                      V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN,                     1, 0},
-       {INST_COS,                      V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS,                     1, 0},
-       {INST_ASHR_INT,                 V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ASHR_INT,                1, 0},
-       {INST_LSHR_INT,                 V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHR_INT,                1, 0},
-       {INST_LSHL_INT,                 V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHL_INT,                1, 0},
-       {INST_MULLO_INT,                V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_INT,               1, 0},
-       {INST_MULHI_INT,                V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_INT,               1, 0},
-       {INST_MULLO_UINT,               V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_UINT,              1, 0},
-       {INST_MULHI_UINT,               V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_UINT,              1, 0},
-       {INST_RECIP_INT,                V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_INT,               1, 0},
-       {INST_RECIP_UINT,               V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_UINT,              1, 0},
-       {INST_FLT_TO_UINT,              V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_UINT,             1, 0},
-       {INST_MUL_LIT,                  V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT,                 1, 1},
-       {INST_MUL_LIT_M2,               V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M2,              1, 1},
-       {INST_MUL_LIT_M4,               V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M4,              1, 1},
-       {INST_MUL_LIT_D2,               V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_D2,              1, 1},
-       {INST_MULADD,                   V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD,                  0, 1},
-       {INST_MULADD_M2,                V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_M2,               0, 1},
-       {INST_MULADD_M4,                V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_M4,               0, 1},
-       {INST_MULADD_D2,                V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_D2,               0, 1},
-       {INST_MULADD_IEEE,              V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE,             0, 1},
-       {INST_MULADD_IEEE_M2,           V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_M2,          0, 1},
-       {INST_MULADD_IEEE_M4,           V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_M4,          0, 1},
-       {INST_MULADD_IEEE_D2,           V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_D2,          0, 1},
-       {INST_CNDE,                     V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDE,                    0, 1},
-       {INST_CNDGT,                    V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGT,                   0, 1},
-       {INST_CNDGE,                    V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGE,                   0, 1},
-       {INST_CNDE_INT,                 V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDE_INT,                0, 1},
-       {INST_CNDGT_INT,                V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGT_INT,               0, 1},
-       {INST_CNDGE_INT,                V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGE_INT,               0, 1},
-};
-
-struct r600_alu_instruction r600_alu_instruction[C_OPCODE_LAST] = {
-       {C_OPCODE_NOP,          INST_NOP},
-       {C_OPCODE_MOV,          INST_MOV},
-       {C_OPCODE_LIT,          INST_NOP},
-       {C_OPCODE_RCP,          INST_RECIP_IEEE},
-       {C_OPCODE_RSQ,          INST_RECIPSQRT_IEEE},
-       {C_OPCODE_EXP,          INST_EXP_IEEE},
-       {C_OPCODE_LOG,          INST_LOG_IEEE},
-       {C_OPCODE_MUL,          INST_MUL},
-       {C_OPCODE_ADD,          INST_ADD},
-       {C_OPCODE_DP3,          INST_DOT4},
-       {C_OPCODE_DP4,          INST_DOT4},
-       {C_OPCODE_DST,          INST_NOP},
-       {C_OPCODE_MIN,          INST_MIN},
-       {C_OPCODE_MAX,          INST_MAX},
-       {C_OPCODE_SLT,          INST_NOP},
-       {C_OPCODE_SGE,          INST_NOP},
-       {C_OPCODE_MAD,          INST_MULADD},
-       {C_OPCODE_SUB,          INST_COUNT},
-       {C_OPCODE_LRP,          INST_NOP},
-       {C_OPCODE_CND,          INST_NOP},
-       {20,                    INST_NOP},
-       {C_OPCODE_DP2A,         INST_NOP},
-       {22,                    INST_NOP},
-       {23,                    INST_NOP},
-       {C_OPCODE_FRC,          INST_NOP},
-       {C_OPCODE_CLAMP,        INST_NOP},
-       {C_OPCODE_FLR,          INST_NOP},
-       {C_OPCODE_ROUND,        INST_NOP},
-       {C_OPCODE_EX2,          INST_NOP},
-       {C_OPCODE_LG2,          INST_NOP},
-       {C_OPCODE_POW,          INST_NOP},
-       {C_OPCODE_XPD,          INST_NOP},
-       {32,                    INST_NOP},
-       {C_OPCODE_ABS,          INST_COUNT},
-       {C_OPCODE_RCC,          INST_NOP},
-       {C_OPCODE_DPH,          INST_NOP},
-       {C_OPCODE_COS,          INST_COS},
-       {C_OPCODE_DDX,          INST_NOP},
-       {C_OPCODE_DDY,          INST_NOP},
-       {C_OPCODE_KILP,         INST_NOP},
-       {C_OPCODE_PK2H,         INST_NOP},
-       {C_OPCODE_PK2US,        INST_NOP},
-       {C_OPCODE_PK4B,         INST_NOP},
-       {C_OPCODE_PK4UB,        INST_NOP},
-       {C_OPCODE_RFL,          INST_NOP},
-       {C_OPCODE_SEQ,          INST_NOP},
-       {C_OPCODE_SFL,          INST_NOP},
-       {C_OPCODE_SGT,          INST_SETGT},
-       {C_OPCODE_SIN,          INST_SIN},
-       {C_OPCODE_SLE,          INST_NOP},
-       {C_OPCODE_SNE,          INST_NOP},
-       {C_OPCODE_STR,          INST_NOP},
-       {C_OPCODE_TEX,          INST_NOP},
-       {C_OPCODE_TXD,          INST_NOP},
-       {C_OPCODE_TXP,          INST_NOP},
-       {C_OPCODE_UP2H,         INST_NOP},
-       {C_OPCODE_UP2US,        INST_NOP},
-       {C_OPCODE_UP4B,         INST_NOP},
-       {C_OPCODE_UP4UB,        INST_NOP},
-       {C_OPCODE_X2D,          INST_NOP},
-       {C_OPCODE_ARA,          INST_NOP},
-       {C_OPCODE_ARR,          INST_NOP},
-       {C_OPCODE_BRA,          INST_NOP},
-       {C_OPCODE_CAL,          INST_NOP},
-       {C_OPCODE_RET,          INST_NOP},
-       {C_OPCODE_SSG,          INST_NOP},
-       {C_OPCODE_CMP,          INST_NOP},
-       {C_OPCODE_SCS,          INST_NOP},
-       {C_OPCODE_TXB,          INST_NOP},
-       {C_OPCODE_NRM,          INST_NOP},
-       {C_OPCODE_DIV,          INST_NOP},
-       {C_OPCODE_DP2,          INST_NOP},
-       {C_OPCODE_TXL,          INST_NOP},
-       {C_OPCODE_BRK,          INST_NOP},
-       {C_OPCODE_IF,           INST_NOP},
-       {C_OPCODE_BGNFOR,       INST_NOP},
-       {C_OPCODE_REP,          INST_NOP},
-       {C_OPCODE_ELSE,         INST_NOP},
-       {C_OPCODE_ENDIF,        INST_NOP},
-       {C_OPCODE_ENDFOR,       INST_NOP},
-       {C_OPCODE_ENDREP,       INST_NOP},
-       {C_OPCODE_PUSHA,        INST_NOP},
-       {C_OPCODE_POPA,         INST_NOP},
-       {C_OPCODE_CEIL,         INST_NOP},
-       {C_OPCODE_I2F,          INST_NOP},
-       {C_OPCODE_NOT,          INST_NOP},
-       {C_OPCODE_TRUNC,        INST_NOP},
-       {C_OPCODE_SHL,          INST_NOP},
-       {88,                    INST_NOP},
-       {C_OPCODE_AND,          INST_NOP},
-       {C_OPCODE_OR,           INST_NOP},
-       {C_OPCODE_MOD,          INST_NOP},
-       {C_OPCODE_XOR,          INST_NOP},
-       {C_OPCODE_SAD,          INST_NOP},
-       {C_OPCODE_TXF,          INST_NOP},
-       {C_OPCODE_TXQ,          INST_NOP},
-       {C_OPCODE_CONT,         INST_NOP},
-       {C_OPCODE_EMIT,         INST_NOP},
-       {C_OPCODE_ENDPRIM,      INST_NOP},
-       {C_OPCODE_BGNLOOP,      INST_NOP},
-       {C_OPCODE_BGNSUB,       INST_NOP},
-       {C_OPCODE_ENDLOOP,      INST_NOP},
-       {C_OPCODE_ENDSUB,       INST_NOP},
-       {103,                   INST_NOP},
-       {104,                   INST_NOP},
-       {105,                   INST_NOP},
-       {106,                   INST_NOP},
-       {107,                   INST_NOP},
-       {108,                   INST_NOP},
-       {109,                   INST_NOP},
-       {110,                   INST_NOP},
-       {111,                   INST_NOP},
-       {C_OPCODE_NRM4,         INST_NOP},
-       {C_OPCODE_CALLNZ,       INST_NOP},
-       {C_OPCODE_IFC,          INST_NOP},
-       {C_OPCODE_BREAKC,       INST_NOP},
-       {C_OPCODE_KIL,          INST_NOP},
-       {C_OPCODE_END,          INST_NOP},
-       {118,                   INST_NOP},
-       {C_OPCODE_F2I,          INST_NOP},
-       {C_OPCODE_IDIV,         INST_NOP},
-       {C_OPCODE_IMAX,         INST_NOP},
-       {C_OPCODE_IMIN,         INST_NOP},
-       {C_OPCODE_INEG,         INST_NOP},
-       {C_OPCODE_ISGE,         INST_NOP},
-       {C_OPCODE_ISHR,         INST_NOP},
-       {C_OPCODE_ISLT,         INST_NOP},
-       {C_OPCODE_F2U,          INST_NOP},
-       {C_OPCODE_U2F,          INST_NOP},
-       {C_OPCODE_UADD,         INST_NOP},
-       {C_OPCODE_UDIV,         INST_NOP},
-       {C_OPCODE_UMAD,         INST_NOP},
-       {C_OPCODE_UMAX,         INST_NOP},
-       {C_OPCODE_UMIN,         INST_NOP},
-       {C_OPCODE_UMOD,         INST_NOP},
-       {C_OPCODE_UMUL,         INST_NOP},
-       {C_OPCODE_USEQ,         INST_NOP},
-       {C_OPCODE_USGE,         INST_NOP},
-       {C_OPCODE_USHR,         INST_NOP},
-       {C_OPCODE_USLT,         INST_NOP},
-       {C_OPCODE_USNE,         INST_NOP},
-       {C_OPCODE_SWITCH,       INST_NOP},
-       {C_OPCODE_CASE,         INST_NOP},
-       {C_OPCODE_DEFAULT,      INST_NOP},
-       {C_OPCODE_ENDSWITCH,    INST_NOP},
-       {C_OPCODE_VFETCH,       INST_NOP},
-       {C_OPCODE_ENTRY,        INST_NOP},
-       {C_OPCODE_ARL,          INST_NOP},
-};
diff --git a/src/gallium/drivers/r600/r600_compiler_r700.c b/src/gallium/drivers/r600/r600_compiler_r700.c
deleted file mode 100644 (file)
index 809a57a..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <errno.h>
-#include "r600_context.h"
-#include "r700_sq.h"
-
-static int r700_shader_cf_node_bytecode(struct r600_shader *rshader,
-                                       struct r600_shader_node *rnode,
-                                       unsigned *cid)
-{
-       unsigned id = *cid;
-
-       if (rnode->nfetch) {
-               rshader->bcode[id++] = S_SQ_CF_WORD0_ADDR(rnode->cf_addr >> 1);
-               rshader->bcode[id++] = S_SQ_CF_WORD1_CF_INST(V_SQ_CF_WORD1_SQ_CF_INST_VTX) |
-                                       S_SQ_CF_WORD1_BARRIER(1) |
-                                       S_SQ_CF_WORD1_COUNT(rnode->nfetch - 1);
-       } else {
-               rshader->bcode[id++] = S_SQ_CF_ALU_WORD0_ADDR(rnode->cf_addr >> 1);
-               rshader->bcode[id++] = S_SQ_CF_ALU_WORD1_CF_INST(V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU) |
-                                       S_SQ_CF_ALU_WORD1_BARRIER(1) |
-                                       S_SQ_CF_ALU_WORD1_COUNT(rnode->nslot - 1);
-       }
-       *cid = id;
-       return 0;
-}
-
-static int r700_shader_cf_output_bytecode(struct r600_shader *rshader,
-                                               struct c_vector *v,
-                                               unsigned *cid,
-                                               unsigned end)
-{
-       struct r600_shader_operand out;
-       unsigned id = *cid;
-       int r;
-
-       r = r600_shader_find_gpr(rshader, v, 0, &out);
-       if (r)
-               return r;
-       rshader->bcode[id + 0] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(out.sel) |
-                               S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(3);
-       rshader->bcode[id + 1] = S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X(0) |
-               S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(1) |
-               S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(2) |
-               S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(3) |
-               S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(1) |
-               S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE) |
-               S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(end);
-       switch (v->name) {
-       case C_SEMANTIC_POSITION:
-               rshader->bcode[id + 0] |= S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(60) |
-                       S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS);
-               break;
-       case C_SEMANTIC_COLOR:
-               if (rshader->cshader.type == C_PROGRAM_TYPE_VS) {
-                       rshader->output[rshader->noutput].gpr = out.sel;
-                       rshader->output[rshader->noutput].sid = v->sid;
-                       rshader->output[rshader->noutput].name = v->name;
-                       rshader->bcode[id + 0] |= S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(rshader->noutput++) |
-                               S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM);
-               } else {
-                       rshader->bcode[id + 0] |= S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(0) |
-                               S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL);
-               }
-               break;
-       case C_SEMANTIC_GENERIC:
-               rshader->output[rshader->noutput].gpr = out.sel;
-               rshader->output[rshader->noutput].sid = v->sid;
-               rshader->output[rshader->noutput].name = v->name;
-               rshader->bcode[id + 0] |= S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(rshader->noutput++) |
-                       S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM);
-               break;
-       default:
-               fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
-               return -EINVAL;
-       }
-       *cid = id + 2;
-       return 0;
-}
-
-static int r700_shader_alu_bytecode(struct r600_shader *rshader,
-                                       struct r600_shader_node *rnode,
-                                       struct r600_shader_inst *alu,
-                                       unsigned *cid)
-{
-       unsigned id = *cid;
-
-       /* don't replace gpr by pv or ps for destination register */
-       if (alu->is_op3) {
-               rshader->bcode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |
-                                       S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |
-                                       S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |
-                                       S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |
-                                       S_SQ_ALU_WORD0_LAST(alu->last);
-               rshader->bcode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
-                                       S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
-                                       S_SQ_ALU_WORD1_OP3_SRC2_SEL(alu->src[2].sel) |
-                                       S_SQ_ALU_WORD1_OP3_SRC2_CHAN(alu->src[2].chan) |
-                                       S_SQ_ALU_WORD1_OP3_SRC2_NEG(alu->src[2].neg) |
-                                       S_SQ_ALU_WORD1_OP3_ALU_INST(alu->opcode) |
-                                       S_SQ_ALU_WORD1_BANK_SWIZZLE(0);
-       } else {
-               rshader->bcode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |
-                                       S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |
-                                       S_SQ_ALU_WORD0_SRC0_NEG(alu->src[0].neg) |
-                                       S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |
-                                       S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |
-                                       S_SQ_ALU_WORD0_SRC1_NEG(alu->src[1].neg) |
-                                       S_SQ_ALU_WORD0_LAST(alu->last);
-               rshader->bcode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
-                                       S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
-                                       S_SQ_ALU_WORD1_OP2_SRC0_ABS(alu->src[0].abs) |
-                                       S_SQ_ALU_WORD1_OP2_SRC1_ABS(alu->src[1].abs) |
-                                       S_SQ_ALU_WORD1_OP2_WRITE_MASK(1) |
-                                       S_SQ_ALU_WORD1_OP2_ALU_INST(alu->opcode) |
-                                       S_SQ_ALU_WORD1_BANK_SWIZZLE(0);
-       }
-       *cid = id;
-       return 0;
-}
-
-int r700_shader_translate(struct r600_shader *rshader)
-{
-       struct c_shader *shader = &rshader->cshader;
-       struct r600_shader_node *rnode;
-       struct r600_shader_vfetch *vfetch;
-       struct r600_shader_alu *alu;
-       struct c_vector *v;
-       unsigned id, i, end;
-       int r;
-
-       r = r600_shader_register(rshader);
-       if (r) {
-               fprintf(stderr, "%s %d register allocation failed\n", __FILE__, __LINE__);
-               return r;
-       }
-       r = r600_shader_translate_rec(rshader, &shader->entry);
-       if (r) {
-               fprintf(stderr, "%s %d translation failed\n", __FILE__, __LINE__);
-               return r;
-       }
-       r = r600_shader_legalize(rshader);
-       if (r) {
-               fprintf(stderr, "%s %d legalize failed\n", __FILE__, __LINE__);
-               return r;
-       }
-       r600_shader_node_place(rshader);
-       rshader->bcode = malloc(rshader->ndw * 4);
-       if (rshader->bcode == NULL)
-               return -ENOMEM;
-       c_list_for_each(rnode, &rshader->nodes) {
-               id = rnode->cf_addr;
-               c_list_for_each(vfetch, &rnode->vfetch) {
-                       r = r600_shader_vfetch_bytecode(rshader, rnode, vfetch, &id);
-                       if (r)
-                               return r;
-               }
-               c_list_for_each(alu, &rnode->alu) {
-                       for (i = 0; i < alu->nalu; i++) {
-                               r = r700_shader_alu_bytecode(rshader, rnode, &alu->alu[i], &id);
-                               if (r)
-                                       return r;
-                       }
-                       for (i = 0; i < alu->nliteral; i++) {
-                               rshader->bcode[id++] = alu->literal[i];
-                       }
-               }
-       }
-       id = 0;
-       c_list_for_each(rnode, &rshader->nodes) {
-               r = r700_shader_cf_node_bytecode(rshader, rnode, &id);
-               if (r)
-                       return r;
-       }
-       c_list_for_each(v, &rshader->cshader.files[C_FILE_OUTPUT].vectors) {
-               end = 0;
-               if (v->next == &rshader->cshader.files[C_FILE_OUTPUT].vectors)
-                       end = 1;
-               r = r700_shader_cf_output_bytecode(rshader, v, &id, end);
-               if (r)
-                       return r;
-       }
-       c_list_for_each(v, &rshader->cshader.files[C_FILE_INPUT].vectors) {
-               rshader->input[rshader->ninput].gpr = rshader->ninput;
-               rshader->input[rshader->ninput].sid = v->sid;
-               rshader->input[rshader->ninput].name = v->name;
-               rshader->ninput++;
-       }
-       return 0;
-}
diff --git a/src/gallium/drivers/r600/r600_compiler_tgsi.c b/src/gallium/drivers/r600/r600_compiler_tgsi.c
deleted file mode 100644 (file)
index 172cf15..0000000
+++ /dev/null
@@ -1,730 +0,0 @@
-/*
- * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <errno.h>
-#include <tgsi/tgsi_parse.h>
-#include <tgsi/tgsi_scan.h>
-#include "r600_shader.h"
-#include "r600_context.h"
-
-struct tgsi_shader {
-       struct c_vector                         **v[TGSI_FILE_COUNT];
-       struct tgsi_shader_info                 info;
-       struct tgsi_parse_context               parser;
-       const struct tgsi_token                 *tokens;
-       struct c_shader                         *shader;
-       struct c_node                           *node;
-};
-
-static unsigned tgsi_file_to_c_file(unsigned file);
-static unsigned tgsi_sname_to_c_sname(unsigned sname);
-static int tgsi_opcode_to_c_opcode(unsigned opcode, unsigned *copcode);
-
-static int tgsi_shader_init(struct tgsi_shader *ts,
-                               const struct tgsi_token *tokens,
-                               struct c_shader *shader)
-{
-       int i;
-
-       ts->shader = shader;
-       ts->tokens = tokens;
-       tgsi_scan_shader(ts->tokens, &ts->info);
-       tgsi_parse_init(&ts->parser, ts->tokens);
-       /* initialize to NULL in case of error */
-       for (i = 0; i < C_FILE_COUNT; i++) {
-               ts->v[i] = NULL;
-       }
-       for (i = 0; i < TGSI_FILE_COUNT; i++) {
-               if (ts->info.file_count[i] > 0) {
-                       ts->v[i] = calloc(ts->info.file_count[i], sizeof(void*));
-                       if (ts->v[i] == NULL) {
-                               fprintf(stderr, "%s:%d unsupported %d %d\n", __func__, __LINE__, i, ts->info.file_count[i]);
-                               return -ENOMEM;
-                       }
-               }
-       }
-       return 0;
-}
-
-static void tgsi_shader_destroy(struct tgsi_shader *ts)
-{
-       int i;
-
-       for (i = 0; i < TGSI_FILE_COUNT; i++) {
-               free(ts->v[i]);
-       }
-       tgsi_parse_free(&ts->parser);
-}
-
-static int ntransform_declaration(struct tgsi_shader *ts)
-{
-       struct tgsi_full_declaration *fd = &ts->parser.FullToken.FullDeclaration;
-       struct c_vector *v;
-       unsigned file;
-       unsigned name;
-       int sid;
-       int i;
-
-       if (fd->Declaration.Dimension) {
-               fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
-               return -EINVAL;
-       }
-       for (i = fd->Range.First ; i <= fd->Range.Last; i++) {
-               sid = i;
-               name = C_SEMANTIC_GENERIC;
-               file = tgsi_file_to_c_file(fd->Declaration.File);
-               if (file == TGSI_FILE_NULL) {
-                       fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
-                       return -EINVAL;
-               }
-               if (fd->Declaration.Semantic) {
-                       name = tgsi_sname_to_c_sname(fd->Semantic.Name);
-                       sid = fd->Semantic.Index;
-               }
-               v = c_shader_vector_new(ts->shader, file, name, sid);
-               if (v == NULL) {
-                       fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
-                       return -ENOMEM;
-               }
-               ts->v[fd->Declaration.File][i] = v;
-       }
-       return 0;
-}
-
-static int ntransform_immediate(struct tgsi_shader *ts)
-{
-       struct tgsi_full_immediate *fd = &ts->parser.FullToken.FullImmediate;
-       struct c_vector *v;
-       unsigned file;
-       unsigned name;
-
-       if (fd->Immediate.DataType != TGSI_IMM_FLOAT32) {
-               fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
-               return -EINVAL;
-       }
-       name = C_SEMANTIC_GENERIC;
-       file = C_FILE_IMMEDIATE;
-       v = c_shader_vector_new(ts->shader, file, name, 0);
-       if (v == NULL) {
-               fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
-                       return -ENOMEM;
-       }
-       v->channel[0]->value = fd->u[0].Uint;
-       v->channel[1]->value = fd->u[1].Uint;
-       v->channel[2]->value = fd->u[2].Uint;
-       v->channel[3]->value = fd->u[3].Uint;
-       ts->v[TGSI_FILE_IMMEDIATE][0] = v;
-       return 0;
-}
-
-static int ntransform_instruction(struct tgsi_shader *ts)
-{
-       struct tgsi_full_instruction *fi = &ts->parser.FullToken.FullInstruction;
-       struct c_shader *shader = ts->shader;
-       struct c_instruction instruction;
-       unsigned opcode;
-       int i, j, r;
-
-       if (fi->Instruction.NumDstRegs > 1) {
-               fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
-               return -EINVAL;
-       }
-       if (fi->Instruction.Saturate) {
-               fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
-               return -EINVAL;
-       }
-       if (fi->Instruction.Predicate) {
-               fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
-               return -EINVAL;
-       }
-       if (fi->Instruction.Label) {
-               fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
-               return -EINVAL;
-       }
-       if (fi->Instruction.Texture) {
-               fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
-               return -EINVAL;
-       }
-       for (i = 0; i < fi->Instruction.NumSrcRegs; i++) {
-               if (fi->Src[i].Register.Indirect ||
-                       fi->Src[i].Register.Dimension ||
-                       fi->Src[i].Register.Absolute) {
-                       fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
-                       return -EINVAL;
-               }
-       }
-       for (i = 0; i < fi->Instruction.NumDstRegs; i++) {
-               if (fi->Dst[i].Register.Indirect || fi->Dst[i].Register.Dimension) {
-                       fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
-                       return -EINVAL;
-               }
-       }
-       r = tgsi_opcode_to_c_opcode(fi->Instruction.Opcode, &opcode);
-       if (r) {
-               fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
-               return r;
-       }
-       if (opcode == C_OPCODE_END) {
-               return c_node_cfg_link(ts->node, &shader->end);
-       }
-       /* FIXME add flow instruction handling */
-       memset(&instruction, 0, sizeof(struct c_instruction));
-       instruction.nop = 0;
-       for (j = 0; j < 4; j++) {
-               instruction.op[instruction.nop].opcode = opcode;
-               instruction.op[instruction.nop].ninput = fi->Instruction.NumSrcRegs;
-               for (i = 0; i < fi->Instruction.NumSrcRegs; i++) {
-                       instruction.op[instruction.nop].input[i].vector = ts->v[fi->Src[i].Register.File][fi->Src[i].Register.Index];
-                       switch (j) {
-                       case 0:
-                               instruction.op[instruction.nop].input[i].swizzle = fi->Src[i].Register.SwizzleX;
-                               break;
-                       case 1:
-                               instruction.op[instruction.nop].input[i].swizzle = fi->Src[i].Register.SwizzleY;
-                               break;
-                       case 2:
-                               instruction.op[instruction.nop].input[i].swizzle = fi->Src[i].Register.SwizzleZ;
-                               break;
-                       case 3:
-                               instruction.op[instruction.nop].input[i].swizzle = fi->Src[i].Register.SwizzleW;
-                               break;
-                       default:
-                               return -EINVAL;
-                       }
-               }
-               instruction.op[instruction.nop].output.vector = ts->v[fi->Dst[0].Register.File][fi->Dst[0].Register.Index];
-               switch (j) {
-               case 0:
-                       instruction.op[instruction.nop].output.swizzle = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_X : C_SWIZZLE_D;
-                       break;
-               case 1:
-                       instruction.op[instruction.nop].output.swizzle = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_Y : C_SWIZZLE_D;
-                       break;
-               case 2:
-                       instruction.op[instruction.nop].output.swizzle = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_Z : C_SWIZZLE_D;
-                       break;
-               case 3:
-                       instruction.op[instruction.nop].output.swizzle = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_W : C_SWIZZLE_D;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-               instruction.nop++;
-       }
-       return c_node_add_new_instruction(ts->node, &instruction);
-}
-
-int c_shader_from_tgsi(struct c_shader *shader, unsigned type,
-                       const struct tgsi_token *tokens)
-{
-       struct tgsi_shader ts;
-       int r = 0;
-
-       c_shader_init(shader, type);
-       r = tgsi_shader_init(&ts, tokens, shader);
-       if (r)
-               goto out_err;
-       ts.shader = shader;
-       ts.node = &shader->entry;
-       while (!tgsi_parse_end_of_tokens(&ts.parser)) {
-               tgsi_parse_token(&ts.parser);
-               switch (ts.parser.FullToken.Token.Type) {
-               case TGSI_TOKEN_TYPE_IMMEDIATE:
-                       r = ntransform_immediate(&ts);
-                       if (r)
-                               goto out_err;
-                       break;
-               case TGSI_TOKEN_TYPE_DECLARATION:
-                       r = ntransform_declaration(&ts);
-                       if (r)
-                               goto out_err;
-                       break;
-               case TGSI_TOKEN_TYPE_INSTRUCTION:
-                       r = ntransform_instruction(&ts);
-                       if (r)
-                               goto out_err;
-                       break;
-               default:
-                       r = -EINVAL;
-                       goto out_err;
-               }
-       }
-       tgsi_shader_destroy(&ts);
-       return 0;
-out_err:
-       c_shader_destroy(shader);
-       tgsi_shader_destroy(&ts);
-       return r;
-}
-
-static unsigned tgsi_file_to_c_file(unsigned file)
-{
-       switch (file) {
-       case TGSI_FILE_CONSTANT:
-               return C_FILE_CONSTANT;
-       case TGSI_FILE_INPUT:
-               return C_FILE_INPUT;
-       case TGSI_FILE_OUTPUT:
-               return C_FILE_OUTPUT;
-       case TGSI_FILE_TEMPORARY:
-               return C_FILE_TEMPORARY;
-       case TGSI_FILE_SAMPLER:
-               return C_FILE_SAMPLER;
-       case TGSI_FILE_ADDRESS:
-               return C_FILE_ADDRESS;
-       case TGSI_FILE_IMMEDIATE:
-               return C_FILE_IMMEDIATE;
-       case TGSI_FILE_PREDICATE:
-               return C_FILE_PREDICATE;
-       case TGSI_FILE_SYSTEM_VALUE:
-               return C_FILE_SYSTEM_VALUE;
-       case TGSI_FILE_NULL:
-               return C_FILE_NULL;
-       default:
-               fprintf(stderr, "%s:%d unsupported file %d\n", __func__, __LINE__, file);
-               return C_FILE_NULL;
-       }
-}
-
-static unsigned tgsi_sname_to_c_sname(unsigned sname)
-{
-       switch (sname) {
-       case TGSI_SEMANTIC_POSITION:
-               return C_SEMANTIC_POSITION;
-       case TGSI_SEMANTIC_COLOR:
-               return C_SEMANTIC_COLOR;
-       case TGSI_SEMANTIC_BCOLOR:
-               return C_SEMANTIC_BCOLOR;
-       case TGSI_SEMANTIC_FOG:
-               return C_SEMANTIC_FOG;
-       case TGSI_SEMANTIC_PSIZE:
-               return C_SEMANTIC_PSIZE;
-       case TGSI_SEMANTIC_GENERIC:
-               return C_SEMANTIC_GENERIC;
-       case TGSI_SEMANTIC_NORMAL:
-               return C_SEMANTIC_NORMAL;
-       case TGSI_SEMANTIC_FACE:
-               return C_SEMANTIC_FACE;
-       case TGSI_SEMANTIC_EDGEFLAG:
-               return C_SEMANTIC_EDGEFLAG;
-       case TGSI_SEMANTIC_PRIMID:
-               return C_SEMANTIC_PRIMID;
-       case TGSI_SEMANTIC_INSTANCEID:
-               return C_SEMANTIC_INSTANCEID;
-       default:
-               return C_SEMANTIC_GENERIC;
-       }
-}
-
-static int tgsi_opcode_to_c_opcode(unsigned opcode, unsigned *copcode)
-{
-       switch (opcode) {
-       case TGSI_OPCODE_MOV:
-               *copcode = C_OPCODE_MOV;
-               return 0;
-       case TGSI_OPCODE_MUL:
-               *copcode = C_OPCODE_MUL;
-               return 0;
-       case TGSI_OPCODE_MAD:
-               *copcode = C_OPCODE_MAD;
-               return 0;
-       case TGSI_OPCODE_END:
-               *copcode = C_OPCODE_END;
-               return 0;
-       case TGSI_OPCODE_ARL:
-               *copcode = C_OPCODE_ARL;
-               return 0;
-       case TGSI_OPCODE_LIT:
-               *copcode = C_OPCODE_LIT;
-               return 0;
-       case TGSI_OPCODE_RCP:
-               *copcode = C_OPCODE_RCP;
-               return 0;
-       case TGSI_OPCODE_RSQ:
-               *copcode = C_OPCODE_RSQ;
-               return 0;
-       case TGSI_OPCODE_EXP:
-               *copcode = C_OPCODE_EXP;
-               return 0;
-       case TGSI_OPCODE_LOG:
-               *copcode = C_OPCODE_LOG;
-               return 0;
-       case TGSI_OPCODE_ADD:
-               *copcode = C_OPCODE_ADD;
-               return 0;
-       case TGSI_OPCODE_DP3:
-               *copcode = C_OPCODE_DP3;
-               return 0;
-       case TGSI_OPCODE_DP4:
-               *copcode = C_OPCODE_DP4;
-               return 0;
-       case TGSI_OPCODE_DST:
-               *copcode = C_OPCODE_DST;
-               return 0;
-       case TGSI_OPCODE_MIN:
-               *copcode = C_OPCODE_MIN;
-               return 0;
-       case TGSI_OPCODE_MAX:
-               *copcode = C_OPCODE_MAX;
-               return 0;
-       case TGSI_OPCODE_SLT:
-               *copcode = C_OPCODE_SLT;
-               return 0;
-       case TGSI_OPCODE_SGE:
-               *copcode = C_OPCODE_SGE;
-               return 0;
-       case TGSI_OPCODE_SUB:
-               *copcode = C_OPCODE_SUB;
-               return 0;
-       case TGSI_OPCODE_LRP:
-               *copcode = C_OPCODE_LRP;
-               return 0;
-       case TGSI_OPCODE_CND:
-               *copcode = C_OPCODE_CND;
-               return 0;
-       case TGSI_OPCODE_DP2A:
-               *copcode = C_OPCODE_DP2A;
-               return 0;
-       case TGSI_OPCODE_FRC:
-               *copcode = C_OPCODE_FRC;
-               return 0;
-       case TGSI_OPCODE_CLAMP:
-               *copcode = C_OPCODE_CLAMP;
-               return 0;
-       case TGSI_OPCODE_FLR:
-               *copcode = C_OPCODE_FLR;
-               return 0;
-       case TGSI_OPCODE_ROUND:
-               *copcode = C_OPCODE_ROUND;
-               return 0;
-       case TGSI_OPCODE_EX2:
-               *copcode = C_OPCODE_EX2;
-               return 0;
-       case TGSI_OPCODE_LG2:
-               *copcode = C_OPCODE_LG2;
-               return 0;
-       case TGSI_OPCODE_POW:
-               *copcode = C_OPCODE_POW;
-               return 0;
-       case TGSI_OPCODE_XPD:
-               *copcode = C_OPCODE_XPD;
-               return 0;
-       case TGSI_OPCODE_ABS:
-               *copcode = C_OPCODE_ABS;
-               return 0;
-       case TGSI_OPCODE_RCC:
-               *copcode = C_OPCODE_RCC;
-               return 0;
-       case TGSI_OPCODE_DPH:
-               *copcode = C_OPCODE_DPH;
-               return 0;
-       case TGSI_OPCODE_COS:
-               *copcode = C_OPCODE_COS;
-               return 0;
-       case TGSI_OPCODE_DDX:
-               *copcode = C_OPCODE_DDX;
-               return 0;
-       case TGSI_OPCODE_DDY:
-               *copcode = C_OPCODE_DDY;
-               return 0;
-       case TGSI_OPCODE_KILP:
-               *copcode = C_OPCODE_KILP;
-               return 0;
-       case TGSI_OPCODE_PK2H:
-               *copcode = C_OPCODE_PK2H;
-               return 0;
-       case TGSI_OPCODE_PK2US:
-               *copcode = C_OPCODE_PK2US;
-               return 0;
-       case TGSI_OPCODE_PK4B:
-               *copcode = C_OPCODE_PK4B;
-               return 0;
-       case TGSI_OPCODE_PK4UB:
-               *copcode = C_OPCODE_PK4UB;
-               return 0;
-       case TGSI_OPCODE_RFL:
-               *copcode = C_OPCODE_RFL;
-               return 0;
-       case TGSI_OPCODE_SEQ:
-               *copcode = C_OPCODE_SEQ;
-               return 0;
-       case TGSI_OPCODE_SFL:
-               *copcode = C_OPCODE_SFL;
-               return 0;
-       case TGSI_OPCODE_SGT:
-               *copcode = C_OPCODE_SGT;
-               return 0;
-       case TGSI_OPCODE_SIN:
-               *copcode = C_OPCODE_SIN;
-               return 0;
-       case TGSI_OPCODE_SLE:
-               *copcode = C_OPCODE_SLE;
-               return 0;
-       case TGSI_OPCODE_SNE:
-               *copcode = C_OPCODE_SNE;
-               return 0;
-       case TGSI_OPCODE_STR:
-               *copcode = C_OPCODE_STR;
-               return 0;
-       case TGSI_OPCODE_TEX:
-               *copcode = C_OPCODE_TEX;
-               return 0;
-       case TGSI_OPCODE_TXD:
-               *copcode = C_OPCODE_TXD;
-               return 0;
-       case TGSI_OPCODE_TXP:
-               *copcode = C_OPCODE_TXP;
-               return 0;
-       case TGSI_OPCODE_UP2H:
-               *copcode = C_OPCODE_UP2H;
-               return 0;
-       case TGSI_OPCODE_UP2US:
-               *copcode = C_OPCODE_UP2US;
-               return 0;
-       case TGSI_OPCODE_UP4B:
-               *copcode = C_OPCODE_UP4B;
-               return 0;
-       case TGSI_OPCODE_UP4UB:
-               *copcode = C_OPCODE_UP4UB;
-               return 0;
-       case TGSI_OPCODE_X2D:
-               *copcode = C_OPCODE_X2D;
-               return 0;
-       case TGSI_OPCODE_ARA:
-               *copcode = C_OPCODE_ARA;
-               return 0;
-       case TGSI_OPCODE_ARR:
-               *copcode = C_OPCODE_ARR;
-               return 0;
-       case TGSI_OPCODE_BRA:
-               *copcode = C_OPCODE_BRA;
-               return 0;
-       case TGSI_OPCODE_CAL:
-               *copcode = C_OPCODE_CAL;
-               return 0;
-       case TGSI_OPCODE_RET:
-               *copcode = C_OPCODE_RET;
-               return 0;
-       case TGSI_OPCODE_SSG:
-               *copcode = C_OPCODE_SSG;
-               return 0;
-       case TGSI_OPCODE_CMP:
-               *copcode = C_OPCODE_CMP;
-               return 0;
-       case TGSI_OPCODE_SCS:
-               *copcode = C_OPCODE_SCS;
-               return 0;
-       case TGSI_OPCODE_TXB:
-               *copcode = C_OPCODE_TXB;
-               return 0;
-       case TGSI_OPCODE_NRM:
-               *copcode = C_OPCODE_NRM;
-               return 0;
-       case TGSI_OPCODE_DIV:
-               *copcode = C_OPCODE_DIV;
-               return 0;
-       case TGSI_OPCODE_DP2:
-               *copcode = C_OPCODE_DP2;
-               return 0;
-       case TGSI_OPCODE_TXL:
-               *copcode = C_OPCODE_TXL;
-               return 0;
-       case TGSI_OPCODE_BRK:
-               *copcode = C_OPCODE_BRK;
-               return 0;
-       case TGSI_OPCODE_IF:
-               *copcode = C_OPCODE_IF;
-               return 0;
-       case TGSI_OPCODE_ELSE:
-               *copcode = C_OPCODE_ELSE;
-               return 0;
-       case TGSI_OPCODE_ENDIF:
-               *copcode = C_OPCODE_ENDIF;
-               return 0;
-       case TGSI_OPCODE_PUSHA:
-               *copcode = C_OPCODE_PUSHA;
-               return 0;
-       case TGSI_OPCODE_POPA:
-               *copcode = C_OPCODE_POPA;
-               return 0;
-       case TGSI_OPCODE_CEIL:
-               *copcode = C_OPCODE_CEIL;
-               return 0;
-       case TGSI_OPCODE_I2F:
-               *copcode = C_OPCODE_I2F;
-               return 0;
-       case TGSI_OPCODE_NOT:
-               *copcode = C_OPCODE_NOT;
-               return 0;
-       case TGSI_OPCODE_TRUNC:
-               *copcode = C_OPCODE_TRUNC;
-               return 0;
-       case TGSI_OPCODE_SHL:
-               *copcode = C_OPCODE_SHL;
-               return 0;
-       case TGSI_OPCODE_AND:
-               *copcode = C_OPCODE_AND;
-               return 0;
-       case TGSI_OPCODE_OR:
-               *copcode = C_OPCODE_OR;
-               return 0;
-       case TGSI_OPCODE_MOD:
-               *copcode = C_OPCODE_MOD;
-               return 0;
-       case TGSI_OPCODE_XOR:
-               *copcode = C_OPCODE_XOR;
-               return 0;
-       case TGSI_OPCODE_SAD:
-               *copcode = C_OPCODE_SAD;
-               return 0;
-       case TGSI_OPCODE_TXF:
-               *copcode = C_OPCODE_TXF;
-               return 0;
-       case TGSI_OPCODE_TXQ:
-               *copcode = C_OPCODE_TXQ;
-               return 0;
-       case TGSI_OPCODE_CONT:
-               *copcode = C_OPCODE_CONT;
-               return 0;
-       case TGSI_OPCODE_EMIT:
-               *copcode = C_OPCODE_EMIT;
-               return 0;
-       case TGSI_OPCODE_ENDPRIM:
-               *copcode = C_OPCODE_ENDPRIM;
-               return 0;
-       case TGSI_OPCODE_BGNLOOP:
-               *copcode = C_OPCODE_BGNLOOP;
-               return 0;
-       case TGSI_OPCODE_BGNSUB:
-               *copcode = C_OPCODE_BGNSUB;
-               return 0;
-       case TGSI_OPCODE_ENDLOOP:
-               *copcode = C_OPCODE_ENDLOOP;
-               return 0;
-       case TGSI_OPCODE_ENDSUB:
-               *copcode = C_OPCODE_ENDSUB;
-               return 0;
-       case TGSI_OPCODE_NOP:
-               *copcode = C_OPCODE_NOP;
-               return 0;
-       case TGSI_OPCODE_NRM4:
-               *copcode = C_OPCODE_NRM4;
-               return 0;
-       case TGSI_OPCODE_CALLNZ:
-               *copcode = C_OPCODE_CALLNZ;
-               return 0;
-       case TGSI_OPCODE_IFC:
-               *copcode = C_OPCODE_IFC;
-               return 0;
-       case TGSI_OPCODE_BREAKC:
-               *copcode = C_OPCODE_BREAKC;
-               return 0;
-       case TGSI_OPCODE_KIL:
-               *copcode = C_OPCODE_KIL;
-               return 0;
-       case TGSI_OPCODE_F2I:
-               *copcode = C_OPCODE_F2I;
-               return 0;
-       case TGSI_OPCODE_IDIV:
-               *copcode = C_OPCODE_IDIV;
-               return 0;
-       case TGSI_OPCODE_IMAX:
-               *copcode = C_OPCODE_IMAX;
-               return 0;
-       case TGSI_OPCODE_IMIN:
-               *copcode = C_OPCODE_IMIN;
-               return 0;
-       case TGSI_OPCODE_INEG:
-               *copcode = C_OPCODE_INEG;
-               return 0;
-       case TGSI_OPCODE_ISGE:
-               *copcode = C_OPCODE_ISGE;
-               return 0;
-       case TGSI_OPCODE_ISHR:
-               *copcode = C_OPCODE_ISHR;
-               return 0;
-       case TGSI_OPCODE_ISLT:
-               *copcode = C_OPCODE_ISLT;
-               return 0;
-       case TGSI_OPCODE_F2U:
-               *copcode = C_OPCODE_F2U;
-               return 0;
-       case TGSI_OPCODE_U2F:
-               *copcode = C_OPCODE_U2F;
-               return 0;
-       case TGSI_OPCODE_UADD:
-               *copcode = C_OPCODE_UADD;
-               return 0;
-       case TGSI_OPCODE_UDIV:
-               *copcode = C_OPCODE_UDIV;
-               return 0;
-       case TGSI_OPCODE_UMAD:
-               *copcode = C_OPCODE_UMAD;
-               return 0;
-       case TGSI_OPCODE_UMAX:
-               *copcode = C_OPCODE_UMAX;
-               return 0;
-       case TGSI_OPCODE_UMIN:
-               *copcode = C_OPCODE_UMIN;
-               return 0;
-       case TGSI_OPCODE_UMOD:
-               *copcode = C_OPCODE_UMOD;
-               return 0;
-       case TGSI_OPCODE_UMUL:
-               *copcode = C_OPCODE_UMUL;
-               return 0;
-       case TGSI_OPCODE_USEQ:
-               *copcode = C_OPCODE_USEQ;
-               return 0;
-       case TGSI_OPCODE_USGE:
-               *copcode = C_OPCODE_USGE;
-               return 0;
-       case TGSI_OPCODE_USHR:
-               *copcode = C_OPCODE_USHR;
-               return 0;
-       case TGSI_OPCODE_USLT:
-               *copcode = C_OPCODE_USLT;
-               return 0;
-       case TGSI_OPCODE_USNE:
-               *copcode = C_OPCODE_USNE;
-               return 0;
-       case TGSI_OPCODE_SWITCH:
-               *copcode = C_OPCODE_SWITCH;
-               return 0;
-       case TGSI_OPCODE_CASE:
-               *copcode = C_OPCODE_CASE;
-               return 0;
-       case TGSI_OPCODE_DEFAULT:
-               *copcode = C_OPCODE_DEFAULT;
-               return 0;
-       case TGSI_OPCODE_ENDSWITCH:
-               *copcode = C_OPCODE_ENDSWITCH;
-               return 0;
-       default:
-               fprintf(stderr, "%s:%d unsupported opcode %d\n", __func__, __LINE__, opcode);
-               return -EINVAL;
-       }
-}
index 0a7efe3bfb9463df6a0a46c1b1870e7df139026d..05575b576763a939d3e3efa18f685ce6c4e08b52 100644 (file)
@@ -32,6 +32,7 @@
 #include "r600_resource.h"
 #include "r600_screen.h"
 #include "r600_context.h"
+#include "r600d.h"
 
 static void r600_destroy_context(struct pipe_context *context)
 {
@@ -62,6 +63,245 @@ static void r600_flush(struct pipe_context *ctx, unsigned flags,
        dc++;
 }
 
+static void r600_init_config(struct r600_context *rctx)
+{
+       int ps_prio;
+       int vs_prio;
+       int gs_prio;
+       int es_prio;
+       int num_ps_gprs;
+       int num_vs_gprs;
+       int num_gs_gprs;
+       int num_es_gprs;
+       int num_temp_gprs;
+       int num_ps_threads;
+       int num_vs_threads;
+       int num_gs_threads;
+       int num_es_threads;
+       int num_ps_stack_entries;
+       int num_vs_stack_entries;
+       int num_gs_stack_entries;
+       int num_es_stack_entries;
+       enum radeon_family family;
+
+       family = radeon_get_family(rctx->rw);
+       ps_prio = 0;
+       vs_prio = 1;
+       gs_prio = 2;
+       es_prio = 3;
+       switch (family) {
+       case CHIP_R600:
+               num_ps_gprs = 192;
+               num_vs_gprs = 56;
+               num_temp_gprs = 4;
+               num_gs_gprs = 0;
+               num_es_gprs = 0;
+               num_ps_threads = 136;
+               num_vs_threads = 48;
+               num_gs_threads = 4;
+               num_es_threads = 4;
+               num_ps_stack_entries = 128;
+               num_vs_stack_entries = 128;
+               num_gs_stack_entries = 0;
+               num_es_stack_entries = 0;
+               break;
+       case CHIP_RV630:
+       case CHIP_RV635:
+               num_ps_gprs = 84;
+               num_vs_gprs = 36;
+               num_temp_gprs = 4;
+               num_gs_gprs = 0;
+               num_es_gprs = 0;
+               num_ps_threads = 144;
+               num_vs_threads = 40;
+               num_gs_threads = 4;
+               num_es_threads = 4;
+               num_ps_stack_entries = 40;
+               num_vs_stack_entries = 40;
+               num_gs_stack_entries = 32;
+               num_es_stack_entries = 16;
+               break;
+       case CHIP_RV610:
+       case CHIP_RV620:
+       case CHIP_RS780:
+       case CHIP_RS880:
+       default:
+               num_ps_gprs = 84;
+               num_vs_gprs = 36;
+               num_temp_gprs = 4;
+               num_gs_gprs = 0;
+               num_es_gprs = 0;
+               num_ps_threads = 136;
+               num_vs_threads = 48;
+               num_gs_threads = 4;
+               num_es_threads = 4;
+               num_ps_stack_entries = 40;
+               num_vs_stack_entries = 40;
+               num_gs_stack_entries = 32;
+               num_es_stack_entries = 16;
+               break;
+       case CHIP_RV670:
+               num_ps_gprs = 144;
+               num_vs_gprs = 40;
+               num_temp_gprs = 4;
+               num_gs_gprs = 0;
+               num_es_gprs = 0;
+               num_ps_threads = 136;
+               num_vs_threads = 48;
+               num_gs_threads = 4;
+               num_es_threads = 4;
+               num_ps_stack_entries = 40;
+               num_vs_stack_entries = 40;
+               num_gs_stack_entries = 32;
+               num_es_stack_entries = 16;
+               break;
+       case CHIP_RV770:
+               num_ps_gprs = 192;
+               num_vs_gprs = 56;
+               num_temp_gprs = 4;
+               num_gs_gprs = 0;
+               num_es_gprs = 0;
+               num_ps_threads = 188;
+               num_vs_threads = 60;
+               num_gs_threads = 0;
+               num_es_threads = 0;
+               num_ps_stack_entries = 256;
+               num_vs_stack_entries = 256;
+               num_gs_stack_entries = 0;
+               num_es_stack_entries = 0;
+               break;
+       case CHIP_RV730:
+       case CHIP_RV740:
+               num_ps_gprs = 84;
+               num_vs_gprs = 36;
+               num_temp_gprs = 4;
+               num_gs_gprs = 0;
+               num_es_gprs = 0;
+               num_ps_threads = 188;
+               num_vs_threads = 60;
+               num_gs_threads = 0;
+               num_es_threads = 0;
+               num_ps_stack_entries = 128;
+               num_vs_stack_entries = 128;
+               num_gs_stack_entries = 0;
+               num_es_stack_entries = 0;
+               break;
+       case CHIP_RV710:
+               num_ps_gprs = 192;
+               num_vs_gprs = 56;
+               num_temp_gprs = 4;
+               num_gs_gprs = 0;
+               num_es_gprs = 0;
+               num_ps_threads = 144;
+               num_vs_threads = 48;
+               num_gs_threads = 0;
+               num_es_threads = 0;
+               num_ps_stack_entries = 128;
+               num_vs_stack_entries = 128;
+               num_gs_stack_entries = 0;
+               num_es_stack_entries = 0;
+               break;
+       }
+       printf("ps_prio : %d\n", ps_prio);
+       printf("vs_prio : %d\n", vs_prio);
+       printf("gs_prio : %d\n", gs_prio);
+       printf("es_prio : %d\n", es_prio);
+       printf("num_ps_gprs : %d\n", num_ps_gprs);
+       printf("num_vs_gprs : %d\n", num_vs_gprs);
+       printf("num_gs_gprs : %d\n", num_gs_gprs);
+       printf("num_es_gprs : %d\n", num_es_gprs);
+       printf("num_temp_gprs : %d\n", num_temp_gprs);
+       printf("num_ps_threads : %d\n", num_ps_threads);
+       printf("num_vs_threads : %d\n", num_vs_threads);
+       printf("num_gs_threads : %d\n", num_gs_threads);
+       printf("num_es_threads : %d\n", num_es_threads);
+       printf("num_ps_stack_entries : %d\n", num_ps_stack_entries);
+       printf("num_vs_stack_entries : %d\n", num_vs_stack_entries);
+       printf("num_gs_stack_entries : %d\n", num_gs_stack_entries);
+       printf("num_es_stack_entries : %d\n", num_es_stack_entries);
+
+       rctx->config = radeon_state(rctx->rw, R600_CONFIG_TYPE, R600_CONFIG);
+
+       rctx->config->states[R600_CONFIG__SQ_CONFIG] = 0x00000000;
+       switch (family) {
+       case CHIP_RV610:
+       case CHIP_RV620:
+       case CHIP_RS780:
+       case CHIP_RS880:
+       case CHIP_RV710:
+               break;
+       default:
+               rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VC_ENABLE(1);
+               break;
+       }
+       rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_DX9_CONSTS(1);
+       rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ALU_INST_PREFER_VECTOR(1);
+       rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_PS_PRIO(ps_prio);
+       rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_VS_PRIO(vs_prio);
+       rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_GS_PRIO(gs_prio);
+       rctx->config->states[R600_CONFIG__SQ_CONFIG] |= S_008C00_ES_PRIO(es_prio);
+
+       rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] = 0;
+       rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_PS_GPRS(num_ps_gprs);
+       rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_VS_GPRS(num_vs_gprs);
+       rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] |= S_008C04_NUM_CLAUSE_TEMP_GPRS(num_temp_gprs);
+
+       rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] = 0;
+       rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_gs_gprs);
+       rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] |= S_008C08_NUM_GS_GPRS(num_es_gprs);
+
+       rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] = 0;
+       rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_PS_THREADS(num_ps_threads);
+       rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_VS_THREADS(num_vs_threads);
+       rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_GS_THREADS(num_gs_threads);
+       rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] |= S_008C0C_NUM_ES_THREADS(num_es_threads);
+
+       rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] = 0;
+       rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_PS_STACK_ENTRIES(num_ps_stack_entries);
+       rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] |= S_008C10_NUM_VS_STACK_ENTRIES(num_vs_stack_entries);
+
+       rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] = 0;
+       rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_GS_STACK_ENTRIES(num_gs_stack_entries);
+       rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] |= S_008C14_NUM_ES_STACK_ENTRIES(num_es_stack_entries);
+
+       rctx->config->states[R600_CONFIG__SQ_DYN_GPR_CNTL_PS_FLUSH_REQ] = 0x00004000;
+       rctx->config->states[R600_CONFIG__TA_CNTL_AUX] = 0x07000002;
+       rctx->config->states[R600_CONFIG__VC_ENHANCE] = 0x00000000;
+       rctx->config->states[R600_CONFIG__DB_DEBUG] = 0x00000000;
+       rctx->config->states[R600_CONFIG__DB_WATERMARKS] = 0x00420204;
+       rctx->config->states[R600_CONFIG__SX_MISC] = 0x00000000;
+       rctx->config->states[R600_CONFIG__SPI_THREAD_GROUPING] = 0x00000001;
+       rctx->config->states[R600_CONFIG__CB_SHADER_CONTROL] = 0x00000003;
+       rctx->config->states[R600_CONFIG__SQ_ESGS_RING_ITEMSIZE] = 0x00000000;
+       rctx->config->states[R600_CONFIG__SQ_GSVS_RING_ITEMSIZE] = 0x00000000;
+       rctx->config->states[R600_CONFIG__SQ_ESTMP_RING_ITEMSIZE] = 0x00000000;
+       rctx->config->states[R600_CONFIG__SQ_GSTMP_RING_ITEMSIZE] = 0x00000000;
+       rctx->config->states[R600_CONFIG__SQ_VSTMP_RING_ITEMSIZE] = 0x00000000;
+       rctx->config->states[R600_CONFIG__SQ_PSTMP_RING_ITEMSIZE] = 0x00000000;
+       rctx->config->states[R600_CONFIG__SQ_FBUF_RING_ITEMSIZE] = 0x00000000;
+       rctx->config->states[R600_CONFIG__SQ_REDUC_RING_ITEMSIZE] = 0x00000000;
+       rctx->config->states[R600_CONFIG__SQ_GS_VERT_ITEMSIZE] = 0x00000000;
+       rctx->config->states[R600_CONFIG__VGT_OUTPUT_PATH_CNTL] = 0x00000000;
+       rctx->config->states[R600_CONFIG__VGT_HOS_CNTL] = 0x00000000;
+       rctx->config->states[R600_CONFIG__VGT_HOS_MAX_TESS_LEVEL] = 0x00000000;
+       rctx->config->states[R600_CONFIG__VGT_HOS_MIN_TESS_LEVEL] = 0x00000000;
+       rctx->config->states[R600_CONFIG__VGT_HOS_REUSE_DEPTH] = 0x00000000;
+       rctx->config->states[R600_CONFIG__VGT_GROUP_PRIM_TYPE] = 0x00000000;
+       rctx->config->states[R600_CONFIG__VGT_GROUP_FIRST_DECR] = 0x00000000;
+       rctx->config->states[R600_CONFIG__VGT_GROUP_DECR] = 0x00000000;
+       rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_0_CNTL] = 0x00000000;
+       rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_1_CNTL] = 0x00000000;
+       rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_0_FMT_CNTL] = 0x00000000;
+       rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_1_FMT_CNTL] = 0x00000000;
+       rctx->config->states[R600_CONFIG__VGT_GS_MODE] = 0x00000000;
+       rctx->config->states[R600_CONFIG__PA_SC_MODE_CNTL] = 0x00514000;
+       rctx->config->states[R600_CONFIG__VGT_STRMOUT_EN] = 0x00000000;
+       rctx->config->states[R600_CONFIG__VGT_REUSE_OFF] = 0x00000001;
+       rctx->config->states[R600_CONFIG__VGT_VTX_CNT_EN] = 0x00000000;
+       rctx->config->states[R600_CONFIG__VGT_STRMOUT_BUFFER_EN] = 0x00000000;
+       radeon_state_pm4(rctx->config);
+}
+
 struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv)
 {
        struct r600_context *rctx = CALLOC_STRUCT(r600_context);
@@ -107,49 +347,7 @@ struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv)
        rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_MASK] = 0xFFFFFFFF;
        radeon_state_pm4(rctx->cb_cntl);
 
-       rctx->config = radeon_state(rscreen->rw, R600_CONFIG_TYPE, R600_CONFIG);
-       rctx->config->states[R600_CONFIG__SQ_CONFIG] = 0xE400000C;
-       rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] = 0x403800C0;
-       rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] = 0x00000000;
-       rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] = 0x00003090;
-       rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] = 0x00800080;
-       rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] = 0x00000000;
-       rctx->config->states[R600_CONFIG__SQ_DYN_GPR_CNTL_PS_FLUSH_REQ] = 0x00004000;
-       rctx->config->states[R600_CONFIG__TA_CNTL_AUX] = 0x07000002;
-       rctx->config->states[R600_CONFIG__VC_ENHANCE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__DB_DEBUG] = 0x00000000;
-       rctx->config->states[R600_CONFIG__DB_WATERMARKS] = 0x00420204;
-       rctx->config->states[R600_CONFIG__SX_MISC] = 0x00000000;
-       rctx->config->states[R600_CONFIG__SPI_THREAD_GROUPING] = 0x00000001;
-       rctx->config->states[R600_CONFIG__CB_SHADER_CONTROL] = 0x00000003;
-       rctx->config->states[R600_CONFIG__SQ_ESGS_RING_ITEMSIZE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__SQ_GSVS_RING_ITEMSIZE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__SQ_ESTMP_RING_ITEMSIZE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__SQ_GSTMP_RING_ITEMSIZE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__SQ_VSTMP_RING_ITEMSIZE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__SQ_PSTMP_RING_ITEMSIZE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__SQ_FBUF_RING_ITEMSIZE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__SQ_REDUC_RING_ITEMSIZE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__SQ_GS_VERT_ITEMSIZE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_OUTPUT_PATH_CNTL] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_HOS_CNTL] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_HOS_MAX_TESS_LEVEL] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_HOS_MIN_TESS_LEVEL] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_HOS_REUSE_DEPTH] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_GROUP_PRIM_TYPE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_GROUP_FIRST_DECR] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_GROUP_DECR] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_0_CNTL] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_1_CNTL] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_0_FMT_CNTL] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_1_FMT_CNTL] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_GS_MODE] = 0x00000000;
-       rctx->config->states[R600_CONFIG__PA_SC_MODE_CNTL] = 0x00514000;
-       rctx->config->states[R600_CONFIG__VGT_STRMOUT_EN] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_REUSE_OFF] = 0x00000001;
-       rctx->config->states[R600_CONFIG__VGT_VTX_CNT_EN] = 0x00000000;
-       rctx->config->states[R600_CONFIG__VGT_STRMOUT_BUFFER_EN] = 0x00000000;
-       radeon_state_pm4(rctx->config);
+       r600_init_config(rctx);
 
        rctx->ctx = radeon_ctx(rscreen->rw);
        rctx->draw = radeon_draw(rscreen->rw);
index f27ff58ed46352fd2a77096a049fc4eeeaf44abe..669aaec0b24ddb7a58b176869e312d621afd1d2c 100644 (file)
@@ -40,7 +40,6 @@ struct r600_vertex_elements_state
 };
 
 struct r600_pipe_shader {
-       unsigned                                type;
        struct r600_shader                      shader;
        struct radeon_bo                        *bo;
        struct radeon_state                     *state;
@@ -92,8 +91,10 @@ struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv)
 
 void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *rpshader);
 struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx,
-                                               unsigned type,
                                                const struct tgsi_token *tokens);
 int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader);
 
+#define R600_ERR(fmt, args...) \
+       fprintf(stderr, "EE %s/%s:%d - "fmt, __FILE__, __func__, __LINE__, ##args)
+
 #endif
index e3175b627aa4d9c5bece134fbaee9da7d11e0f9b..7241ab1c175d4ca33c4416ddaf38e4f1bfad8144 100644 (file)
@@ -27,6 +27,7 @@
 #include <errno.h>
 #include <util/u_inlines.h>
 #include "r600_screen.h"
+#include "r600_context.h"
 #include "r600d.h"
 
 int r600_conv_pipe_format(unsigned pformat, unsigned *format)
@@ -49,6 +50,12 @@ int r600_conv_pipe_format(unsigned pformat, unsigned *format)
        case PIPE_FORMAT_R8G8B8A8_SSCALED:
                *format = V_0280A0_COLOR_8_8_8_8;
                return 0;
+       case PIPE_FORMAT_R32_FLOAT:
+               *format = V_0280A0_COLOR_32_FLOAT;
+               return 0;
+       case PIPE_FORMAT_R32G32_FLOAT:
+               *format = V_0280A0_COLOR_32_32_FLOAT;
+               return 0;
        case PIPE_FORMAT_L8_UNORM:
        case PIPE_FORMAT_A8_UNORM:
        case PIPE_FORMAT_I8_UNORM:
@@ -60,8 +67,6 @@ int r600_conv_pipe_format(unsigned pformat, unsigned *format)
        case PIPE_FORMAT_R64G64_FLOAT:
        case PIPE_FORMAT_R64G64B64_FLOAT:
        case PIPE_FORMAT_R64G64B64A64_FLOAT:
-       case PIPE_FORMAT_R32_FLOAT:
-       case PIPE_FORMAT_R32G32_FLOAT:
        case PIPE_FORMAT_R32_UNORM:
        case PIPE_FORMAT_R32G32_UNORM:
        case PIPE_FORMAT_R32G32B32_UNORM:
@@ -111,7 +116,7 @@ int r600_conv_pipe_format(unsigned pformat, unsigned *format)
        case PIPE_FORMAT_R32G32B32_FIXED:
        case PIPE_FORMAT_R32G32B32A32_FIXED:
        default:
-               fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pformat);
+               R600_ERR("unsupported %d\n", pformat);
                return -EINVAL;
        }
 }
diff --git a/src/gallium/drivers/r600/r600_public.h b/src/gallium/drivers/r600/r600_public.h
new file mode 100644 (file)
index 0000000..1d89c9f
--- /dev/null
@@ -0,0 +1,9 @@
+
+#ifndef R600_PUBLIC_H
+#define R600_PUBLIC_H
+
+struct radeon;
+
+struct pipe_screen* r600_screen_create(struct radeon *rw);
+
+#endif
index 1d83383fd95d79a17d3f6704804e65cb91afb533..dec6fa8d272ecf5d0593c4795bd74787da8f9e42 100644 (file)
@@ -31,6 +31,7 @@
 #include "r600_screen.h"
 #include "r600_texture.h"
 #include "r600_context.h"
+#include "r600_public.h"
 #include <stdio.h>
 
 static const char* r600_get_vendor(struct pipe_screen* pscreen)
@@ -40,7 +41,13 @@ static const char* r600_get_vendor(struct pipe_screen* pscreen)
 
 static const char* r600_get_name(struct pipe_screen* pscreen)
 {
-       return "R600/R700 (HD2XXX,HD3XXX,HD4XXX)";
+       struct r600_screen *screen = r600_screen(pscreen);
+       enum radeon_family family = radeon_get_family(screen->rw);
+
+       if (family >= CHIP_R600 && family < CHIP_RV770)
+               return "R600 (HD2XXX,HD3XXX)";
+       else
+               return "R700 (HD4XXX)";
 }
 
 static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
@@ -240,7 +247,7 @@ static void r600_destroy_screen(struct pipe_screen* pscreen)
        FREE(rscreen);
 }
 
-struct pipe_screen *radeon_create_screen(struct radeon *rw)
+struct pipe_screen *r600_screen_create(struct radeon *rw)
 {
        struct r600_screen* rscreen;
 
index 6b29d3337989df7567995aaea10b8470cde493d2..e5e6786fd04ec85bb6954ea3c9de5b64799d55c8 100644 (file)
  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 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:
- *      Jerome Glisse
  */
-#include <stdio.h>
-#include <errno.h>
-#include <util/u_inlines.h>
-#include <util/u_format.h>
-#include <util/u_memory.h>
-#include <tgsi/tgsi_dump.h>
+#include "pipe/p_shader_tokens.h"
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_scan.h"
+#include "tgsi/tgsi_dump.h"
+#include "util/u_format.h"
 #include "r600_screen.h"
 #include "r600_context.h"
+#include "r600_shader.h"
+#include "r600_asm.h"
+#include "r600_sq.h"
 #include "r600d.h"
+#include <stdio.h>
+#include <errno.h>
+
+static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader);
+
+static int r600_shader_update(struct pipe_context *ctx, struct r600_shader *shader)
+{
+       struct r600_context *rctx = r600_context(ctx);
+       const struct util_format_description *desc;
+       enum pipe_format resource_format[160];
+       unsigned i, nresources = 0;
+       struct r600_bc *bc = &shader->bc;
+       struct r600_bc_cf *cf;
+       struct r600_bc_vtx *vtx;
+
+       if (shader->processor_type != TGSI_PROCESSOR_VERTEX)
+               return 0;
+       for (i = 0; i < rctx->vertex_elements->count; i++) {
+               resource_format[nresources++] = rctx->vertex_elements->elements[i].src_format;
+       }
+       LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) {
+               switch (cf->inst) {
+               case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
+               case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
+                       LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) {
+                               desc = util_format_description(resource_format[vtx->buffer_id]);
+                               if (desc == NULL) {
+                                       R600_ERR("unknown format %d\n", resource_format[vtx->buffer_id]);
+                                       return -EINVAL;
+                               }
+                               vtx->dst_sel_x = desc->swizzle[0];
+                               vtx->dst_sel_y = desc->swizzle[1];
+                               vtx->dst_sel_z = desc->swizzle[2];
+                               vtx->dst_sel_w = desc->swizzle[3];
+                       }
+                       break;
+               default:
+                       break;
+               }
+       }
+       return r600_bc_build(&shader->bc);
+}
+
+struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx,
+                                               const struct tgsi_token *tokens)
+{
+       struct r600_screen *rscreen = r600_screen(ctx->screen);
+       struct r600_pipe_shader *rpshader = CALLOC_STRUCT(r600_pipe_shader);
+       int r;
+
+fprintf(stderr, "--------------------------------------------------------------\n");
+tgsi_dump(tokens, 0);
+       if (rpshader == NULL)
+               return NULL;
+       rpshader->shader.family = radeon_get_family(rscreen->rw);
+       r = r600_shader_from_tgsi(tokens, &rpshader->shader);
+       if (r) {
+               R600_ERR("translation from TGSI failed !\n");
+               goto out_err;
+       }
+       r = r600_bc_build(&rpshader->shader.bc);
+       if (r) {
+               R600_ERR("building bytecode failed !\n");
+               goto out_err;
+       }
+fprintf(stderr, "______________________________________________________________\n");
+       return rpshader;
+out_err:
+       free(rpshader);
+       return NULL;
+}
 
 static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
 {
        struct r600_screen *rscreen = r600_screen(ctx->screen);
        struct r600_shader *rshader = &rpshader->shader;
        struct radeon_state *state;
-       unsigned i, tmp;
+       unsigned i, j, tmp;
 
        rpshader->state = radeon_state_decref(rpshader->state);
        state = radeon_state(rscreen->rw, R600_VS_SHADER_TYPE, R600_VS_SHADER);
        if (state == NULL)
                return -ENOMEM;
-       for (i = 0; i < rshader->noutput; i += 4) {
-               tmp = rshader->output[i].sid;
-               tmp |= rshader->output[i + 1].sid << 8;
-               tmp |= rshader->output[i + 2].sid << 16;
-               tmp |= rshader->output[i + 3].sid << 24;
-               state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + i / 4] = tmp;
-       }
-       state->states[R600_VS_SHADER__SPI_VS_OUT_CONFIG] = S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 1);
-       state->states[R600_VS_SHADER__SQ_PGM_RESOURCES_VS] = S_028868_NUM_GPRS(rshader->ngpr);
+       for (i = 0; i < 10; i++) {
+               state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + i] = 0;
+       }
+       for (i = 0, j = 0; i < rshader->noutput; i++) {
+               if (rshader->output[i].name != TGSI_SEMANTIC_POSITION) {
+                       tmp = rshader->output[i].sid << ((j & 3) * 8);
+                       state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + j / 4] |= tmp;
+                       j++;
+               }
+       }
+       state->states[R600_VS_SHADER__SPI_VS_OUT_CONFIG] = S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 2);
+       state->states[R600_VS_SHADER__SQ_PGM_RESOURCES_VS] = S_028868_NUM_GPRS(rshader->bc.ngpr);
        rpshader->state = state;
        rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);
        rpshader->state->bo[1] = radeon_bo_incref(rscreen->rw, rpshader->bo);
@@ -81,7 +154,7 @@ static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader
        state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_0] = S_0286CC_NUM_INTERP(rshader->ninput) |
                                                        S_0286CC_PERSP_GRADIENT_ENA(1);
        state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_1] = 0x00000000;
-       state->states[R600_PS_SHADER__SQ_PGM_RESOURCES_PS] = S_028868_NUM_GPRS(rshader->ngpr);
+       state->states[R600_PS_SHADER__SQ_PGM_RESOURCES_PS] = S_028868_NUM_GPRS(rshader->bc.ngpr);
        state->states[R600_PS_SHADER__SQ_PGM_EXPORTS_PS] = 0x00000002;
        rpshader->state = state;
        rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);
@@ -100,21 +173,21 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *r
        /* copy new shader */
        radeon_bo_decref(rscreen->rw, rpshader->bo);
        rpshader->bo = NULL;
-       rpshader->bo = radeon_bo(rscreen->rw, 0, rshader->ndw * 4,
+       rpshader->bo = radeon_bo(rscreen->rw, 0, rshader->bc.ndw * 4,
                                4096, NULL);
        if (rpshader->bo == NULL) {
                return -ENOMEM;
        }
        radeon_bo_map(rscreen->rw, rpshader->bo);
-       memcpy(rpshader->bo->data, rshader->bcode, rshader->ndw * 4);
+       memcpy(rpshader->bo->data, rshader->bc.bytecode, rshader->bc.ndw * 4);
        radeon_bo_unmap(rscreen->rw, rpshader->bo);
        /* build state */
        rshader->flat_shade = rctx->flat_shade;
-       switch (rpshader->type) {
-       case C_PROGRAM_TYPE_VS:
+       switch (rshader->processor_type) {
+       case TGSI_PROCESSOR_VERTEX:
                r = r600_pipe_shader_vs(ctx, rpshader);
                break;
-       case C_PROGRAM_TYPE_FS:
+       case TGSI_PROCESSOR_FRAGMENT:
                r = r600_pipe_shader_ps(ctx, rpshader);
                break;
        default:
@@ -124,100 +197,813 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *r
        return r;
 }
 
-struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx, unsigned type, const struct tgsi_token *tokens)
+int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
 {
-       struct r600_pipe_shader *rpshader = CALLOC_STRUCT(r600_pipe_shader);
-       struct r600_shader *rshader = &rpshader->shader;
+       struct r600_context *rctx = r600_context(ctx);
        int r;
 
        if (rpshader == NULL)
-               return NULL;
-       rpshader->type = type;
-       c_list_init(&rshader->nodes);
-       fprintf(stderr, "<<\n");
-       tgsi_dump(tokens, 0);
-       fprintf(stderr, "--------------------------------------------------------------\n");
-       r = c_shader_from_tgsi(&rshader->cshader, type, tokens);
-       if (r) {
-               r600_pipe_shader_destroy(ctx, rpshader);
-               fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
-               return NULL;
+               return -EINVAL;
+       /* there should be enough input */
+       if (rctx->vertex_elements->count < rpshader->shader.bc.nresource) {
+               R600_ERR("%d resources provided, expecting %d\n",
+                       rctx->vertex_elements->count, rpshader->shader.bc.nresource);
+               return -EINVAL;
        }
-       r = r600_shader_insert_fetch(&rshader->cshader);
-       if (r) {
-               r600_pipe_shader_destroy(ctx, rpshader);
-               fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
-               return NULL;
+       r = r600_shader_update(ctx, &rpshader->shader);
+       if (r)
+               return r;
+       return r600_pipe_shader(ctx, rpshader);
+}
+
+struct r600_shader_tgsi_instruction;
+
+struct r600_shader_ctx {
+       struct tgsi_shader_info                 info;
+       struct tgsi_parse_context               parse;
+       const struct tgsi_token                 *tokens;
+       unsigned                                type;
+       unsigned                                file_offset[TGSI_FILE_COUNT];
+       unsigned                                temp_reg;
+       struct r600_shader_tgsi_instruction     *inst_info;
+       struct r600_bc                          *bc;
+       struct r600_shader                      *shader;
+};
+
+struct r600_shader_tgsi_instruction {
+       unsigned        tgsi_opcode;
+       unsigned        is_op3;
+       unsigned        r600_opcode;
+       int (*process)(struct r600_shader_ctx *ctx);
+};
+
+static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[];
+
+static int tgsi_is_supported(struct r600_shader_ctx *ctx)
+{
+       struct tgsi_full_instruction *i = &ctx->parse.FullToken.FullInstruction;
+       int j;
+
+       if (i->Instruction.NumDstRegs > 1) {
+               R600_ERR("too many dst (%d)\n", i->Instruction.NumDstRegs);
+               return -EINVAL;
        }
-       r = c_shader_build_dominator_tree(&rshader->cshader);
-       if (r) {
-               r600_pipe_shader_destroy(ctx, rpshader);
-               fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
-               return NULL;
+       if (i->Instruction.Saturate) {
+               R600_ERR("staturate unsupported\n");
+               return -EINVAL;
        }
-       c_shader_dump(&rshader->cshader);
-       r = r600_cshader_legalize(&rshader->cshader);
-       if (r) {
-               r600_pipe_shader_destroy(ctx, rpshader);
-               fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
-               return NULL;
+       if (i->Instruction.Predicate) {
+               R600_ERR("predicate unsupported\n");
+               return -EINVAL;
        }
-       r = r700_shader_translate(rshader);
-       if (r) {
-               r600_pipe_shader_destroy(ctx, rpshader);
-               fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
-               return NULL;
+       if (i->Instruction.Label) {
+               R600_ERR("label unsupported\n");
+               return -EINVAL;
        }
-#if 1
-#if 0
-       fprintf(stderr, "--------------------------------------------------------------\n");
-       for (int i = 0; i < rshader->ndw; i++) {
-               fprintf(stderr, "0x%08X\n", rshader->bcode[i]);
+       for (j = 0; j < i->Instruction.NumSrcRegs; j++) {
+               if (i->Src[j].Register.Indirect ||
+                       i->Src[j].Register.Dimension ||
+                       i->Src[j].Register.Absolute) {
+                       R600_ERR("unsupported src (indirect|dimension|absolute)\n");
+                       return -EINVAL;
+               }
        }
-#endif
-       fprintf(stderr, ">>\n\n");
-#endif
-       return rpshader;
+       for (j = 0; j < i->Instruction.NumDstRegs; j++) {
+               if (i->Dst[j].Register.Indirect || i->Dst[j].Register.Dimension) {
+                       R600_ERR("unsupported dst (indirect|dimension)\n");
+                       return -EINVAL;
+               }
+       }
+       return 0;
 }
 
-void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
+static int tgsi_declaration(struct r600_shader_ctx *ctx)
 {
-       struct r600_screen *rscreen = r600_screen(ctx->screen);
+       struct tgsi_full_declaration *d = &ctx->parse.FullToken.FullDeclaration;
+       struct r600_bc_vtx vtx;
+       unsigned i;
+       int r;
 
-       if (rpshader == NULL)
-               return;
-       radeon_bo_decref(rscreen->rw, rpshader->bo);
-       rpshader->bo = NULL;
-       r600_shader_cleanup(&rpshader->shader);
-       FREE(rpshader);
+       switch (d->Declaration.File) {
+       case TGSI_FILE_INPUT:
+               i = ctx->shader->ninput++;
+               ctx->shader->input[i].name = d->Semantic.Name;
+               ctx->shader->input[i].sid = d->Semantic.Index;
+               ctx->shader->input[i].gpr = ctx->file_offset[TGSI_FILE_INPUT] + i;
+               if (ctx->type == TGSI_PROCESSOR_VERTEX) {
+                       /* turn input into fetch */
+                       memset(&vtx, 0, sizeof(struct r600_bc_vtx));
+                       vtx.inst = 0;
+                       vtx.fetch_type = 0;
+                       vtx.buffer_id = i;
+                       /* register containing the index into the buffer */
+                       vtx.src_gpr = 0;
+                       vtx.src_sel_x = 0;
+                       vtx.mega_fetch_count = 0x1F;
+                       vtx.dst_gpr = ctx->shader->input[i].gpr;
+                       vtx.dst_sel_x = 0;
+                       vtx.dst_sel_y = 1;
+                       vtx.dst_sel_z = 2;
+                       vtx.dst_sel_w = 3;
+                       r = r600_bc_add_vtx(ctx->bc, &vtx);
+                       if (r)
+                               return r;
+               }
+               break;
+       case TGSI_FILE_OUTPUT:
+               i = ctx->shader->noutput++;
+               ctx->shader->output[i].name = d->Semantic.Name;
+               ctx->shader->output[i].sid = d->Semantic.Index;
+               ctx->shader->output[i].gpr = ctx->file_offset[TGSI_FILE_OUTPUT] + i;
+               break;
+       case TGSI_FILE_CONSTANT:
+       case TGSI_FILE_TEMPORARY:
+       case TGSI_FILE_SAMPLER:
+               break;
+       default:
+               R600_ERR("unsupported file %d declaration\n", d->Declaration.File);
+               return -EINVAL;
+       }
+       return 0;
 }
 
-int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
+int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader)
 {
-       struct r600_context *rctx = r600_context(ctx);
-       struct r600_shader *rshader;
-       enum pipe_format resource_format[160];
-       unsigned i, nresources = 0;
-       int r;
+       struct tgsi_full_immediate *immediate;
+       struct r600_shader_ctx ctx;
+       struct r600_bc_output output;
+       unsigned opcode;
+       int i, r = 0, pos0;
+       u32 value[4];
 
-       if (rpshader == NULL)
-               return -EINVAL;
-       rshader = &rpshader->shader;
-       switch (rpshader->type) {
-       case C_PROGRAM_TYPE_VS:
-               for (i = 0; i < rctx->vertex_elements->count; i++) {
-                       resource_format[nresources++] = rctx->vertex_elements->elements[i].src_format;
+       ctx.bc = &shader->bc;
+       ctx.shader = shader;
+       r = r600_bc_init(ctx.bc, shader->family);
+       if (r)
+               return r;
+       ctx.tokens = tokens;
+       tgsi_scan_shader(tokens, &ctx.info);
+       tgsi_parse_init(&ctx.parse, tokens);
+       ctx.type = ctx.parse.FullHeader.Processor.Processor;
+       shader->processor_type = ctx.type;
+
+       /* register allocations */
+       /* Values [0,127] correspond to GPR[0..127]. 
+        * Values [256,511] correspond to cfile constants c[0..255]. 
+        * Other special values are shown in the list below.
+        * 248  SQ_ALU_SRC_0: special constant 0.0.
+        * 249  SQ_ALU_SRC_1: special constant 1.0 float.
+        * 250  SQ_ALU_SRC_1_INT: special constant 1 integer.
+        * 251  SQ_ALU_SRC_M_1_INT: special constant -1 integer.
+        * 252  SQ_ALU_SRC_0_5: special constant 0.5 float.
+        * 253  SQ_ALU_SRC_LITERAL: literal constant.
+        * 254  SQ_ALU_SRC_PV: previous vector result.
+        * 255  SQ_ALU_SRC_PS: previous scalar result.
+        */
+       for (i = 0; i < TGSI_FILE_COUNT; i++) {
+               ctx.file_offset[i] = 0;
+       }
+       if (ctx.type == TGSI_PROCESSOR_VERTEX) {
+               ctx.file_offset[TGSI_FILE_INPUT] = 1;
+       }
+       ctx.file_offset[TGSI_FILE_OUTPUT] = ctx.file_offset[TGSI_FILE_INPUT] +
+                                               ctx.info.file_count[TGSI_FILE_INPUT];
+       ctx.file_offset[TGSI_FILE_TEMPORARY] = ctx.file_offset[TGSI_FILE_OUTPUT] +
+                                               ctx.info.file_count[TGSI_FILE_OUTPUT];
+       ctx.file_offset[TGSI_FILE_CONSTANT] = 256;
+       ctx.file_offset[TGSI_FILE_IMMEDIATE] = 253;
+       ctx.temp_reg = ctx.file_offset[TGSI_FILE_TEMPORARY] +
+                       ctx.info.file_count[TGSI_FILE_TEMPORARY];
+
+       while (!tgsi_parse_end_of_tokens(&ctx.parse)) {
+               tgsi_parse_token(&ctx.parse);
+               switch (ctx.parse.FullToken.Token.Type) {
+               case TGSI_TOKEN_TYPE_IMMEDIATE:
+                       immediate = &ctx.parse.FullToken.FullImmediate;
+                       value[0] = immediate->u[0].Uint;
+                       value[1] = immediate->u[1].Uint;
+                       value[2] = immediate->u[2].Uint;
+                       value[3] = immediate->u[3].Uint;
+                       break;
+               case TGSI_TOKEN_TYPE_DECLARATION:
+                       r = tgsi_declaration(&ctx);
+                       if (r)
+                               goto out_err;
+                       break;
+               case TGSI_TOKEN_TYPE_INSTRUCTION:
+                       r = tgsi_is_supported(&ctx);
+                       if (r)
+                               goto out_err;
+                       opcode = ctx.parse.FullToken.FullInstruction.Instruction.Opcode;
+                       ctx.inst_info = &r600_shader_tgsi_instruction[opcode];
+                       r = ctx.inst_info->process(&ctx);
+                       if (r)
+                               goto out_err;
+                       r = r600_bc_add_literal(ctx.bc, value);
+                       if (r)
+                               goto out_err;
+                       break;
+               default:
+                       R600_ERR("unsupported token type %d\n", ctx.parse.FullToken.Token.Type);
+                       r = -EINVAL;
+                       goto out_err;
+               }
+       }
+       /* export output */
+       for (i = 0, pos0 = 0; i < shader->noutput; i++) {
+               memset(&output, 0, sizeof(struct r600_bc_output));
+               output.gpr = shader->output[i].gpr;
+               output.elem_size = 3;
+               output.swizzle_x = 0;
+               output.swizzle_y = 1;
+               output.swizzle_z = 2;
+               output.swizzle_w = 3;
+               output.barrier = 1;
+               output.type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM;
+               output.array_base = i - pos0;
+               output.inst = V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE;
+               switch (ctx.type == TGSI_PROCESSOR_VERTEX) {
+               case TGSI_PROCESSOR_VERTEX:
+                       if (shader->output[i].name == TGSI_SEMANTIC_POSITION) {
+                               output.array_base = 60;
+                               output.type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS;
+                               /* position doesn't count in array_base */
+                               pos0 = 1;
+                       }
+                       break;
+               case TGSI_PROCESSOR_FRAGMENT:
+                       if (shader->output[i].name == TGSI_SEMANTIC_COLOR) {
+                               output.array_base = 0;
+                               output.type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
+                       } else {
+                               R600_ERR("unsupported fragment output name %d\n", shader->output[i].name);
+                               r = -EINVAL;
+                               goto out_err;
+                       }
+                       break;
+               default:
+                       R600_ERR("unsupported processor type %d\n", ctx.type);
+                       r = -EINVAL;
+                       goto out_err;
                }
+               if (i == (shader->noutput - 1)) {
+                       output.end_of_program = 1;
+               }
+               r = r600_bc_add_output(ctx.bc, &output);
+               if (r)
+                       goto out_err;
+       }
+       tgsi_parse_free(&ctx.parse);
+       return 0;
+out_err:
+       tgsi_parse_free(&ctx.parse);
+       return r;
+}
+
+static int tgsi_unsupported(struct r600_shader_ctx *ctx)
+{
+       R600_ERR("%d tgsi opcode unsupported\n", ctx->inst_info->tgsi_opcode);
+       return -EINVAL;
+}
+
+static int tgsi_end(struct r600_shader_ctx *ctx)
+{
+       return 0;
+}
+
+static int tgsi_src(struct r600_shader_ctx *ctx,
+                       const struct tgsi_full_src_register *tgsi_src,
+                       unsigned swizzle,
+                       struct r600_bc_alu_src *r600_src)
+{
+       r600_src->sel = tgsi_src->Register.Index;
+       if (tgsi_src->Register.File == TGSI_FILE_IMMEDIATE) {
+               r600_src->sel = 0;
+       }
+       r600_src->sel += ctx->file_offset[tgsi_src->Register.File];
+       switch (swizzle) {
+       case 0:
+               r600_src->chan = tgsi_src->Register.SwizzleX;
                break;
-       default:
+       case 1:
+               r600_src->chan = tgsi_src->Register.SwizzleY;
                break;
-       }
-       /* there should be enough input */
-       if (nresources < rshader->nresource)
+       case 2:
+               r600_src->chan = tgsi_src->Register.SwizzleZ;
+               break;
+       case 3:
+               r600_src->chan = tgsi_src->Register.SwizzleW;
+               break;
+       default:
                return -EINVAL;
-       /* FIXME compare resources */
-       r = r600_shader_update(rshader, resource_format);
-       if (r)
+       }
+       return 0;
+}
+
+static int tgsi_dst(struct r600_shader_ctx *ctx,
+                       const struct tgsi_full_dst_register *tgsi_dst,
+                       unsigned swizzle,
+                       struct r600_bc_alu_dst *r600_dst)
+{
+       r600_dst->sel = tgsi_dst->Register.Index;
+       r600_dst->sel += ctx->file_offset[tgsi_dst->Register.File];
+       r600_dst->chan = swizzle;
+       r600_dst->write = 1;
+       return 0;
+}
+
+static int tgsi_op2(struct r600_shader_ctx *ctx)
+{
+       struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+       struct r600_bc_alu alu;
+       int i, j, r;
+
+       for (i = 0; i < 4; i++) {
+               memset(&alu, 0, sizeof(struct r600_bc_alu));
+               if (!(inst->Dst[0].Register.WriteMask & (1 << i))) {
+                       alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
+               } else {
+                       alu.inst = ctx->inst_info->r600_opcode;
+                       for (j = 0; j < inst->Instruction.NumSrcRegs; j++) {
+                               r = tgsi_src(ctx, &inst->Src[j], i, &alu.src[j]);
+                               if (r)
+                                       return r;
+                       }
+                       r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst);
+                       if (r)
+                               return r;
+               }
+               /* handle some special cases */
+               switch (ctx->inst_info->tgsi_opcode) {
+               case TGSI_OPCODE_SUB:
+                       alu.src[1].neg = 1;
+                       break;
+               default:
+                       break;
+               }
+               if (i == 3) {
+                       alu.last = 1;
+               }
+               r = r600_bc_add_alu(ctx->bc, &alu);
+               if (r)
+                       return r;
+       }
+       return 0;
+}
+
+static int tgsi_slt(struct r600_shader_ctx *ctx)
+{
+       struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+       struct r600_bc_alu alu;
+       int i, r;
+
+       for (i = 0; i < 4; i++) {
+               memset(&alu, 0, sizeof(struct r600_bc_alu));
+               if (!(inst->Dst[0].Register.WriteMask & (1 << i))) {
+                       alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
+               } else {
+                       alu.inst = ctx->inst_info->r600_opcode;
+                       r = tgsi_src(ctx, &inst->Src[0], i, &alu.src[1]);
+                       if (r)
+                               return r;
+                       r = tgsi_src(ctx, &inst->Src[1], i, &alu.src[0]);
+                       if (r)
+                               return r;
+                       r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst);
+                       if (r)
+                               return r;
+               }
+               if (i == 3) {
+                       alu.last = 1;
+               }
+               r = r600_bc_add_alu(ctx->bc, &alu);
+               if (r)
+                       return r;
+       }
+       return 0;
+}
+
+static int tgsi_lit(struct r600_shader_ctx *ctx)
+{
+       struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+       struct r600_bc_alu alu;
+
+       int r;
+
+
+       if (inst->Dst[0].Register.WriteMask & (1 << 0))
+       {
+               /* dst.x, <- 1.0  */
+               memset(&alu, 0, sizeof(struct r600_bc_alu));
+               alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV;
+               alu.src[0].sel  = 249; /*1.0*/
+               alu.src[0].chan = 0;
+               r = tgsi_dst(ctx, &inst->Dst[0], 0, &alu.dst);
+               if (r)
+                       return r;
+               if ((inst->Dst[0].Register.WriteMask & 0xe) == 0)
+                       alu.last = 1;
+               r = r600_bc_add_alu(ctx->bc, &alu);
+               if (r)
+                       return r;
+       }
+
+
+       if (inst->Dst[0].Register.WriteMask & (1 << 1))
+       {
+               /* dst.y = max(src.x, 0.0) */
+               memset(&alu, 0, sizeof(struct r600_bc_alu));
+               alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX;
+               r = tgsi_src(ctx, &inst->Src[0], 0, &alu.src[0]);
+               if (r)
+                       return r;
+               alu.src[1].sel  = 248; /*0.0*/
+               alu.src[1].chan = 0;
+               r = tgsi_dst(ctx, &inst->Dst[0], 1, &alu.dst);
+               if (r)
+                       return r;
+               if ((inst->Dst[0].Register.WriteMask & 0xa) == 0)
+                       alu.last = 1;
+               r = r600_bc_add_alu(ctx->bc, &alu);
+               if (r)
+                       return r;
+       }
+
+       if (inst->Dst[0].Register.WriteMask & (1 << 3))
+       {
+               /* dst.w, <- 1.0  */
+               memset(&alu, 0, sizeof(struct r600_bc_alu));
+               alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV;
+               alu.src[0].sel  = 249;
+               alu.src[0].chan = 0;
+               r = tgsi_dst(ctx, &inst->Dst[0], 3, &alu.dst);
+               if (r)
+                       return r;
+               if ((inst->Dst[0].Register.WriteMask & 0x4) == 0)
+                       alu.last = 1;
+               r = r600_bc_add_alu(ctx->bc, &alu);
+               if (r)
+                       return r;
+       }
+
+       if (inst->Dst[0].Register.WriteMask & (1 << 2))
+       {
+               /* dst.z = log(src.y) */
+               memset(&alu, 0, sizeof(struct r600_bc_alu));
+               alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED;
+               r = tgsi_src(ctx, &inst->Src[0], 1, &alu.src[0]);
+               if (r)
+                       return r;
+               r = tgsi_dst(ctx, &inst->Dst[0], 2, &alu.dst);
+               if (r)
+                       return r;
+               alu.last = 1;
+               r = r600_bc_add_alu(ctx->bc, &alu);
+               if (r)
+                       return r;
+
+               int chan = alu.dst.chan;
+               int sel = alu.dst.sel;
+
+               /* tmp.x = amd MUL_LIT(src.w, dst.z, src.x ) */
+               memset(&alu, 0, sizeof(struct r600_bc_alu));
+               alu.inst = V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT;
+               r = tgsi_src(ctx, &inst->Src[0], 3, &alu.src[0]);
+               if (r)
                return r;
-       return r600_pipe_shader(ctx, rpshader);
+               alu.src[1].sel  = sel;
+               alu.src[1].chan = chan;
+               r = tgsi_src(ctx, &inst->Src[0], 0, &alu.src[2]);
+               if (r)
+                       return r;
+               alu.dst.sel = ctx->temp_reg;
+               alu.dst.chan = 0;
+               alu.dst.write = 1;
+               alu.is_op3 = 1;
+               alu.last = 1;
+               r = r600_bc_add_alu(ctx->bc, &alu);
+               if (r)
+                       return r;
+
+               /* dst.z = exp(tmp.x) */
+               memset(&alu, 0, sizeof(struct r600_bc_alu));
+               alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE;
+               alu.src[0].sel = ctx->temp_reg;
+               alu.src[0].chan = 0;
+               r = tgsi_dst(ctx, &inst->Dst[0], 2, &alu.dst);
+               if (r)
+                       return r;
+               alu.last = 1;
+               r = r600_bc_add_alu(ctx->bc, &alu);
+               if (r)
+                       return r;
+       }
+       return 0;
+}
+
+static int tgsi_trans(struct r600_shader_ctx *ctx)
+{
+       struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+       struct r600_bc_alu alu;
+       int i, j, r;
+
+       for (i = 0; i < 4; i++) {
+               memset(&alu, 0, sizeof(struct r600_bc_alu));
+               if (inst->Dst[0].Register.WriteMask & (1 << i)) {
+                       alu.inst = ctx->inst_info->r600_opcode;
+                       for (j = 0; j < inst->Instruction.NumSrcRegs; j++) {
+                               r = tgsi_src(ctx, &inst->Src[j], i, &alu.src[j]);
+                               if (r)
+                                       return r;
+                       }
+                       r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst);
+                       if (r)
+                               return r;
+                       alu.last = 1;
+                       r = r600_bc_add_alu(ctx->bc, &alu);
+                       if (r)
+                               return r;
+               }
+       }
+       return 0;
 }
+
+static int tgsi_helper_copy(struct r600_shader_ctx *ctx, struct tgsi_full_instruction *inst)
+{
+       struct r600_bc_alu alu;
+       int i, r;
+
+       for (i = 0; i < 4; i++) {
+               memset(&alu, 0, sizeof(struct r600_bc_alu));
+               if (!(inst->Dst[0].Register.WriteMask & (1 << i))) {
+                       alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
+               } else {
+                       alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV;
+                       r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst);
+                       if (r)
+                               return r;
+                       alu.src[0].sel = ctx->temp_reg;
+                       alu.src[0].chan = i;
+               }
+               if (i == 3) {
+                       alu.last = 1;
+               }
+               r = r600_bc_add_alu(ctx->bc, &alu);
+               if (r)
+                       return r;
+       }
+       return 0;
+}
+
+static int tgsi_op3(struct r600_shader_ctx *ctx)
+{
+       struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+       struct r600_bc_alu alu;
+       int i, j, r;
+
+       /* do it in 2 step as op3 doesn't support writemask */
+       for (i = 0; i < 4; i++) {
+               memset(&alu, 0, sizeof(struct r600_bc_alu));
+               alu.inst = ctx->inst_info->r600_opcode;
+               for (j = 0; j < inst->Instruction.NumSrcRegs; j++) {
+                       r = tgsi_src(ctx, &inst->Src[j], i, &alu.src[j]);
+                       if (r)
+                               return r;
+               }
+               alu.dst.sel = ctx->temp_reg;
+               alu.dst.chan = i;
+               alu.dst.write = 1;
+               alu.is_op3 = 1;
+               if (i == 3) {
+                       alu.last = 1;
+               }
+               r = r600_bc_add_alu(ctx->bc, &alu);
+               if (r)
+                       return r;
+       }
+       return tgsi_helper_copy(ctx, inst);
+}
+
+static int tgsi_dp(struct r600_shader_ctx *ctx)
+{
+       struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+       struct r600_bc_alu alu;
+       int i, j, r;
+
+       for (i = 0; i < 4; i++) {
+               memset(&alu, 0, sizeof(struct r600_bc_alu));
+               alu.inst = ctx->inst_info->r600_opcode;
+               for (j = 0; j < inst->Instruction.NumSrcRegs; j++) {
+                       r = tgsi_src(ctx, &inst->Src[j], i, &alu.src[j]);
+                       if (r)
+                               return r;
+               }
+               alu.dst.sel = ctx->temp_reg;
+               alu.dst.chan = i;
+               alu.dst.write = 1;
+               /* handle some special cases */
+               switch (ctx->inst_info->tgsi_opcode) {
+               case TGSI_OPCODE_DP2:
+                       if (i > 1) {
+                               alu.src[0].sel = alu.src[1].sel = 248;
+                               alu.src[0].chan = alu.src[1].chan = 0;
+                       }
+                       break;
+               case TGSI_OPCODE_DP3:
+                       if (i > 2) {
+                               alu.src[0].sel = alu.src[1].sel = 248;
+                               alu.src[0].chan = alu.src[1].chan = 0;
+                       }
+                       break;
+               default:
+                       break;
+               }
+               if (i == 3) {
+                       alu.last = 1;
+               }
+               r = r600_bc_add_alu(ctx->bc, &alu);
+               if (r)
+                       return r;
+       }
+       return tgsi_helper_copy(ctx, inst);
+}
+
+static int tgsi_tex(struct r600_shader_ctx *ctx)
+{
+       struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
+       struct r600_bc_tex tex;
+
+       memset(&tex, 0, sizeof(struct r600_bc_tex));
+       tex.inst = ctx->inst_info->r600_opcode;
+       tex.resource_id = ctx->file_offset[inst->Src[1].Register.File] + inst->Src[1].Register.Index;
+       tex.sampler_id = tex.resource_id;
+       tex.src_gpr = ctx->file_offset[inst->Src[0].Register.File] + inst->Src[0].Register.Index;
+       tex.dst_gpr = ctx->file_offset[inst->Dst[0].Register.File] + inst->Src[0].Register.Index;
+       tex.dst_sel_x = 0;
+       tex.dst_sel_y = 1;
+       tex.dst_sel_z = 2;
+       tex.dst_sel_w = 3;
+       tex.src_sel_x = 0;
+       tex.src_sel_y = 1;
+       tex.src_sel_z = 2;
+       tex.src_sel_w = 3;
+       return r600_bc_add_tex(ctx->bc, &tex);
+}
+
+static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = {
+       {TGSI_OPCODE_ARL,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_MOV,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV, tgsi_op2},
+       {TGSI_OPCODE_LIT,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_lit},
+       {TGSI_OPCODE_RCP,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_RSQ,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE, tgsi_trans},
+       {TGSI_OPCODE_EXP,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_LOG,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_MUL,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL, tgsi_op2},
+       {TGSI_OPCODE_ADD,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD, tgsi_op2},
+       {TGSI_OPCODE_DP3,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, tgsi_dp},
+       {TGSI_OPCODE_DP4,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, tgsi_dp},
+       {TGSI_OPCODE_DST,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_MIN,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_MAX,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX, tgsi_op2},
+       {TGSI_OPCODE_SLT,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT, tgsi_slt},
+       {TGSI_OPCODE_SGE,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_MAD,       1, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD, tgsi_op3},
+       {TGSI_OPCODE_SUB,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD, tgsi_op2},
+       {TGSI_OPCODE_LRP,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_CND,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       /* gap */
+       {20,                    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_DP2A,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       /* gap */
+       {22,                    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {23,                    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_FRC,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_CLAMP,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_FLR,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ROUND,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_EX2,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_LG2,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_POW,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_XPD,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       /* gap */
+       {32,                    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ABS,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_RCC,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_DPH,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_COS,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_DDX,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_DDY,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_KILP,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},  /* predicated kill */
+       {TGSI_OPCODE_PK2H,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_PK2US,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_PK4B,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_PK4UB,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_RFL,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SEQ,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SFL,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SGT,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SIN,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SLE,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SNE,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_STR,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_TEX,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_TXD,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_TXP,       0, 0x10, tgsi_tex},
+       {TGSI_OPCODE_UP2H,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UP2US,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UP4B,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UP4UB,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_X2D,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ARA,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ARR,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_BRA,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_CAL,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_RET,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SSG,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, /* SGN */
+       {TGSI_OPCODE_CMP,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SCS,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_TXB,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_NRM,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_DIV,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_DP2,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, tgsi_dp},
+       {TGSI_OPCODE_TXL,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_BRK,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_IF,        0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       /* gap */
+       {75,                    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {76,                    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ELSE,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ENDIF,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       /* gap */
+       {79,                    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {80,                    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_PUSHA,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_POPA,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_CEIL,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_I2F,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_NOT,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_TRUNC,     0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SHL,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       /* gap */
+       {88,                    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_AND,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_OR,        0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_MOD,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_XOR,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SAD,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_TXF,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_TXQ,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_CONT,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_EMIT,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ENDPRIM,   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_BGNLOOP,   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_BGNSUB,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ENDLOOP,   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ENDSUB,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       /* gap */
+       {103,                   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {104,                   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {105,                   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {106,                   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_NOP,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       /* gap */
+       {108,                   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {109,                   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {110,                   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {111,                   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_NRM4,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_CALLNZ,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_IFC,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_BREAKC,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_KIL,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},  /* conditional kill */
+       {TGSI_OPCODE_END,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_end},  /* aka HALT */
+       /* gap */
+       {118,                   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_F2I,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_IDIV,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_IMAX,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_IMIN,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_INEG,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ISGE,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ISHR,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ISLT,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_F2U,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_U2F,       0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UADD,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UDIV,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UMAD,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UMAX,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UMIN,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UMOD,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_UMUL,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_USEQ,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_USGE,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_USHR,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_USLT,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_USNE,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_SWITCH,    0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_CASE,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_DEFAULT,   0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_ENDSWITCH, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+       {TGSI_OPCODE_LAST,      0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported},
+};
index 7d30ca79d1bef50fc56e48e9a343babff5b81296..23b6a83b9a923d1fb3c23c35ff78f3741f32dbfc 100644 (file)
 #ifndef R600_SHADER_H
 #define R600_SHADER_H
 
-#include "r600_compiler.h"
-#include "radeon.h"
-
-struct r600_shader_operand {
-       struct c_vector                 *vector;
-       unsigned                        sel;
-       unsigned                        chan;
-       unsigned                        neg;
-       unsigned                        abs;
-};
-
-struct r600_shader_vfetch {
-       struct r600_shader_vfetch       *next;
-       struct r600_shader_vfetch       *prev;
-       unsigned                        cf_addr;
-       struct r600_shader_operand      src[2];
-       struct r600_shader_operand      dst[4];
-};
-
-struct r600_shader_inst {
-       unsigned                        is_op3;
-       unsigned                        opcode;
-       unsigned                        inst;
-       struct r600_shader_operand      src[3];
-       struct r600_shader_operand      dst;
-       unsigned                        last;
-};
-
-struct r600_shader_alu {
-       struct r600_shader_alu          *next;
-       struct r600_shader_alu          *prev;
-       unsigned                        nalu;
-       unsigned                        nliteral;
-       unsigned                        nconstant;
-       struct r600_shader_inst         alu[5];
-       u32                             literal[4];
-};
-
-struct r600_shader_node {
-       struct r600_shader_node         *next;
-       struct r600_shader_node         *prev;
-       unsigned                        cf_id;          /**< cf index (in dw) in byte code */
-       unsigned                        cf_addr;        /**< instructions index (in dw) in byte code */
-       unsigned                        nslot;          /**< number of slot (2 dw) needed by this node */
-       unsigned                        nfetch;
-       struct c_node                   *node;          /**< compiler node from which this node originate */
-       struct r600_shader_vfetch       vfetch;         /**< list of vfetch instructions */
-       struct r600_shader_alu          alu;            /**< list of alu instructions */
-};
+#include "r600_asm.h"
 
 struct r600_shader_io {
-       unsigned        name;
-       unsigned        gpr;
-       int             sid;
+       unsigned                name;
+       unsigned                gpr;
+       int                     sid;
 };
 
 struct r600_shader {
-       unsigned                        stack_size;             /**< stack size needed by this shader */
-       unsigned                        ngpr;                   /**< number of GPR needed by this shader */
-       unsigned                        nconstant;              /**< number of constants used by this shader */
-       unsigned                        nresource;              /**< number of resources used by this shader */
-       unsigned                        noutput;
-       unsigned                        ninput;
-       unsigned                        nvector;
-       unsigned                        ncf;                    /**< total number of cf clauses */
-       unsigned                        nslot;                  /**< total number of slots (2 dw) */
-       unsigned                        flat_shade;             /**< are we flat shading */
-       struct r600_shader_node         nodes;                  /**< list of node */
-       struct r600_shader_io           input[32];
-       struct r600_shader_io           output[32];
-       /* TODO replace GPR by some better register allocator */
-       struct c_vector                 **gpr;
-       unsigned                        ndw;                    /**< bytes code size in dw */
-       u32                             *bcode;                 /**< bytes code */
-       enum pipe_format                resource_format[160];   /**< format of resource */
-       struct c_shader                 cshader;
+       unsigned                processor_type;
+       struct r600_bc          bc;
+       boolean                 flat_shade;
+       unsigned                ninput;
+       unsigned                noutput;
+       struct r600_shader_io   input[32];
+       struct r600_shader_io   output[32];
+       enum radeon_family      family;
 };
 
-void r600_shader_cleanup(struct r600_shader *rshader);
-int r600_shader_register(struct r600_shader *rshader);
-int r600_shader_node(struct r600_shader *shader);
-void r600_shader_node_place(struct r600_shader *rshader);
-int r600_shader_find_gpr(struct r600_shader *rshader, struct c_vector *v, unsigned swizzle,
-                       struct r600_shader_operand *operand);
-int r600_shader_vfetch_bytecode(struct r600_shader *rshader,
-                               struct r600_shader_node *rnode,
-                               struct r600_shader_vfetch *vfetch,
-                               unsigned *cid);
-int r600_shader_update(struct r600_shader *rshader,
-                       enum pipe_format *resource_format);
-int r600_shader_legalize(struct r600_shader *rshader);
-int r600_cshader_legalize(struct c_shader *shader);
-
-int r700_shader_translate(struct r600_shader *rshader);
-
-int c_shader_from_tgsi(struct c_shader *shader, unsigned type,
-                       const struct tgsi_token *tokens);
-int r600_shader_register(struct r600_shader *rshader);
-int r600_shader_translate_rec(struct r600_shader *rshader, struct c_node *node);
-int r700_shader_translate(struct r600_shader *rshader);
-int r600_shader_insert_fetch(struct c_shader *shader);
-
-enum r600_instruction {
-       INST_ADD                        = 0,
-       INST_MUL                        = 1,
-       INST_MUL_IEEE                   = 2,
-       INST_MAX                        = 3,
-       INST_MIN                        = 4,
-       INST_MAX_DX10                   = 5,
-       INST_MIN_DX10                   = 6,
-       INST_SETE                       = 7,
-       INST_SETGT                      = 8,
-       INST_SETGE                      = 9,
-       INST_SETNE                      = 10,
-       INST_SETE_DX10                  = 11,
-       INST_SETGT_DX10                 = 12,
-       INST_SETGE_DX10                 = 13,
-       INST_SETNE_DX10                 = 14,
-       INST_FRACT                      = 15,
-       INST_TRUNC                      = 16,
-       INST_CEIL                       = 17,
-       INST_RNDNE                      = 18,
-       INST_FLOOR                      = 19,
-       INST_MOVA                       = 20,
-       INST_MOVA_FLOOR                 = 21,
-       INST_MOVA_INT                   = 22,
-       INST_MOV                        = 23,
-       INST_NOP                        = 24,
-       INST_PRED_SETGT_UINT            = 25,
-       INST_PRED_SETGE_UINT            = 26,
-       INST_PRED_SETE                  = 27,
-       INST_PRED_SETGT                 = 28,
-       INST_PRED_SETGE                 = 29,
-       INST_PRED_SETNE                 = 30,
-       INST_PRED_SET_INV               = 31,
-       INST_PRED_SET_POP               = 32,
-       INST_PRED_SET_CLR               = 33,
-       INST_PRED_SET_RESTORE           = 34,
-       INST_PRED_SETE_PUSH             = 35,
-       INST_PRED_SETGT_PUSH            = 36,
-       INST_PRED_SETGE_PUSH            = 37,
-       INST_PRED_SETNE_PUSH            = 38,
-       INST_KILLE                      = 39,
-       INST_KILLGT                     = 40,
-       INST_KILLGE                     = 41,
-       INST_KILLNE                     = 42,
-       INST_AND_INT                    = 43,
-       INST_OR_INT                     = 44,
-       INST_XOR_INT                    = 45,
-       INST_NOT_INT                    = 46,
-       INST_ADD_INT                    = 47,
-       INST_SUB_INT                    = 48,
-       INST_MAX_INT                    = 49,
-       INST_MIN_INT                    = 50,
-       INST_MAX_UINT                   = 51,
-       INST_MIN_UINT                   = 52,
-       INST_SETE_INT                   = 53,
-       INST_SETGT_INT                  = 54,
-       INST_SETGE_INT                  = 55,
-       INST_SETNE_INT                  = 56,
-       INST_SETGT_UINT                 = 57,
-       INST_SETGE_UINT                 = 58,
-       INST_KILLGT_UINT                = 59,
-       INST_KILLGE_UINT                = 60,
-       INST_PRED_SETE_INT              = 61,
-       INST_PRED_SETGT_INT             = 62,
-       INST_PRED_SETGE_INT             = 63,
-       INST_PRED_SETNE_INT             = 64,
-       INST_KILLE_INT                  = 65,
-       INST_KILLGT_INT                 = 66,
-       INST_KILLGE_INT                 = 67,
-       INST_KILLNE_INT                 = 68,
-       INST_PRED_SETE_PUSH_INT         = 69,
-       INST_PRED_SETGT_PUSH_INT        = 70,
-       INST_PRED_SETGE_PUSH_INT        = 71,
-       INST_PRED_SETNE_PUSH_INT        = 72,
-       INST_PRED_SETLT_PUSH_INT        = 73,
-       INST_PRED_SETLE_PUSH_INT        = 74,
-       INST_DOT4                       = 75,
-       INST_DOT4_IEEE                  = 76,
-       INST_CUBE                       = 77,
-       INST_MAX4                       = 78,
-       INST_MOVA_GPR_INT               = 79,
-       INST_EXP_IEEE                   = 80,
-       INST_LOG_CLAMPED                = 81,
-       INST_LOG_IEEE                   = 82,
-       INST_RECIP_CLAMPED              = 83,
-       INST_RECIP_FF                   = 84,
-       INST_RECIP_IEEE                 = 85,
-       INST_RECIPSQRT_CLAMPED          = 86,
-       INST_RECIPSQRT_FF               = 87,
-       INST_RECIPSQRT_IEEE             = 88,
-       INST_SQRT_IEEE                  = 89,
-       INST_FLT_TO_INT                 = 90,
-       INST_INT_TO_FLT                 = 91,
-       INST_UINT_TO_FLT                = 92,
-       INST_SIN                        = 93,
-       INST_COS                        = 94,
-       INST_ASHR_INT                   = 95,
-       INST_LSHR_INT                   = 96,
-       INST_LSHL_INT                   = 97,
-       INST_MULLO_INT                  = 98,
-       INST_MULHI_INT                  = 99,
-       INST_MULLO_UINT                 = 100,
-       INST_MULHI_UINT                 = 101,
-       INST_RECIP_INT                  = 102,
-       INST_RECIP_UINT                 = 103,
-       INST_FLT_TO_UINT                = 104,
-       INST_MUL_LIT                    = 105,
-       INST_MUL_LIT_M2                 = 106,
-       INST_MUL_LIT_M4                 = 107,
-       INST_MUL_LIT_D2                 = 108,
-       INST_MULADD                     = 109,
-       INST_MULADD_M2                  = 110,
-       INST_MULADD_M4                  = 111,
-       INST_MULADD_D2                  = 112,
-       INST_MULADD_IEEE                = 113,
-       INST_MULADD_IEEE_M2             = 114,
-       INST_MULADD_IEEE_M4             = 115,
-       INST_MULADD_IEEE_D2             = 116,
-       INST_CNDE                       = 117,
-       INST_CNDGT                      = 118,
-       INST_CNDGE                      = 119,
-       INST_CNDE_INT                   = 120,
-       INST_CNDGT_INT                  = 121,
-       INST_CNDGE_INT                  = 122,
-       INST_COUNT
-};
-
-struct r600_instruction_info {
-       enum r600_instruction           instruction;
-       unsigned                        opcode;
-       unsigned                        is_trans;
-       unsigned                        is_op3;
-};
-
-
 #endif
index 71aa09719e09c936032c6ec10b0f858b3299859a..002660c654a10ed7142cc92088f2beddca2f3608 100644 (file)
@@ -87,9 +87,9 @@
 #define   G_SQ_CF_WORD1_BARRIER(x)                                   (((x) >> 31) & 0x1)
 #define   C_SQ_CF_WORD1_BARRIER                                      0x7FFFFFFF
 #define P_SQ_CF_ALU_WORD0
-#define   S_SQ_CF_ALU_WORD0_ALU_ADDR(x)                              (((x) & 0x3FFFFF) << 0)
-#define   G_SQ_CF_ALU_WORD0_ALU_ADDR(x)                              (((x) >> 0) & 0x3FFFFF)
-#define   C_SQ_CF_ALU_WORD0_ALU_ADDR                                 0xFFC00000
+#define   S_SQ_CF_ALU_WORD0_ADDR(x)                                  (((x) & 0x3FFFFF) << 0)
+#define   G_SQ_CF_ALU_WORD0_ADDR(x)                                  (((x) >> 0) & 0x3FFFFF)
+#define   C_SQ_CF_ALU_WORD0_ADDR                                     0xFFC00000
 #define   S_SQ_CF_ALU_WORD0_KCACHE_BANK0(x)                          (((x) & 0xF) << 22)
 #define   G_SQ_CF_ALU_WORD0_KCACHE_BANK0(x)                          (((x) >> 22) & 0xF)
 #define   C_SQ_CF_ALU_WORD0_KCACHE_BANK0                             0xFC3FFFFF
 #define   S_SQ_CF_ALU_WORD1_KCACHE_ADDR1(x)                          (((x) & 0xFF) << 10)
 #define   G_SQ_CF_ALU_WORD1_KCACHE_ADDR1(x)                          (((x) >> 10) & 0xFF)
 #define   C_SQ_CF_ALU_WORD1_KCACHE_ADDR1                             0xFFFC03FF
-#define   S_SQ_CF_ALU_WORD1_ALU_COUNT(x)                             (((x) & 0x7F) << 18)
-#define   G_SQ_CF_ALU_WORD1_ALU_COUNT(x)                             (((x) >> 18) & 0x7F)
-#define   C_SQ_CF_ALU_WORD1_ALU_COUNT                                0xFE03FFFF
+#define   S_SQ_CF_ALU_WORD1_COUNT(x)                                 (((x) & 0x7F) << 18)
+#define   G_SQ_CF_ALU_WORD1_COUNT(x)                                 (((x) >> 18) & 0x7F)
+#define   C_SQ_CF_ALU_WORD1_COUNT                                    0xFE03FFFF
 #define   S_SQ_CF_ALU_WORD1_USES_WATERFALL(x)                        (((x) & 0x1) << 25)
 #define   G_SQ_CF_ALU_WORD1_USES_WATERFALL(x)                        (((x) >> 25) & 0x1)
 #define   C_SQ_CF_ALU_WORD1_USES_WATERFALL                           0xFDFFFFFF
-#define   S_SQ_CF_ALU_WORD1_CF_ALU_INST(x)                           (((x) & 0xF) << 26)
-#define   G_SQ_CF_ALU_WORD1_CF_ALU_INST(x)                           (((x) >> 26) & 0xF)
-#define   C_SQ_CF_ALU_WORD1_CF_ALU_INST                              0xC3FFFFFF
+#define   S_SQ_CF_ALU_WORD1_CF_INST(x)                               (((x) & 0xF) << 26)
+#define   G_SQ_CF_ALU_WORD1_CF_INST(x)                               (((x) >> 26) & 0xF)
+#define   C_SQ_CF_ALU_WORD1_CF_INST                                  0xC3FFFFFF
 #define     V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU                         0x00000008
 #define     V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE             0x00000009
 #define     V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER               0x0000000A
 #define   S_SQ_TEX_WORD1_COORD_TYPE_X(x)                             (((x) & 0x1) << 28)
 #define   G_SQ_TEX_WORD1_COORD_TYPE_X(x)                             (((x) >> 28) & 0x1)
 #define   C_SQ_TEX_WORD1_COORD_TYPE_X                                0xEFFFFFFF
+#define     V_SQ_TEX_WORD1_COORD_UNNORMALIZED                        0x00000000
+#define     V_SQ_TEX_WORD1_COORD_NORMALIZED                          0x00000001
 #define   S_SQ_TEX_WORD1_COORD_TYPE_Y(x)                             (((x) & 0x1) << 29)
 #define   G_SQ_TEX_WORD1_COORD_TYPE_Y(x)                             (((x) >> 29) & 0x1)
 #define   C_SQ_TEX_WORD1_COORD_TYPE_Y                                0xDFFFFFFF
 #define   S_SQ_TEX_WORD2_SRC_SEL_W(x)                                (((x) & 0x7) << 29)
 #define   G_SQ_TEX_WORD2_SRC_SEL_W(x)                                (((x) >> 29) & 0x7)
 #define   C_SQ_TEX_WORD2_SRC_SEL_W                                   0x1FFFFFFF
-#define P_SQ_ALU_WORD1_OP2_V2
-#define   S_SQ_ALU_WORD1_OP2_V2_SRC0_ABS(x)                          (((x) & 0x1) << 0)
-#define   G_SQ_ALU_WORD1_OP2_V2_SRC0_ABS(x)                          (((x) >> 0) & 0x1)
-#define   C_SQ_ALU_WORD1_OP2_V2_SRC0_ABS                             0xFFFFFFFE
-#define   S_SQ_ALU_WORD1_OP2_V2_SRC1_ABS(x)                          (((x) & 0x1) << 1)
-#define   G_SQ_ALU_WORD1_OP2_V2_SRC1_ABS(x)                          (((x) >> 1) & 0x1)
-#define   C_SQ_ALU_WORD1_OP2_V2_SRC1_ABS                             0xFFFFFFFD
-#define   S_SQ_ALU_WORD1_OP2_V2_UPDATE_EXECUTE_MASK(x)               (((x) & 0x1) << 2)
-#define   G_SQ_ALU_WORD1_OP2_V2_UPDATE_EXECUTE_MASK(x)               (((x) >> 2) & 0x1)
-#define   C_SQ_ALU_WORD1_OP2_V2_UPDATE_EXECUTE_MASK                  0xFFFFFFFB
-#define   S_SQ_ALU_WORD1_OP2_V2_UPDATE_PRED(x)                       (((x) & 0x1) << 3)
-#define   G_SQ_ALU_WORD1_OP2_V2_UPDATE_PRED(x)                       (((x) >> 3) & 0x1)
-#define   C_SQ_ALU_WORD1_OP2_V2_UPDATE_PRED                          0xFFFFFFF7
-#define   S_SQ_ALU_WORD1_OP2_V2_WRITE_MASK(x)                        (((x) & 0x1) << 4)
-#define   G_SQ_ALU_WORD1_OP2_V2_WRITE_MASK(x)                        (((x) >> 4) & 0x1)
-#define   C_SQ_ALU_WORD1_OP2_V2_WRITE_MASK                           0xFFFFFFEF
-#define   S_SQ_ALU_WORD1_OP2_V2_OMOD(x)                              (((x) & 0x3) << 5)
-#define   G_SQ_ALU_WORD1_OP2_V2_OMOD(x)                              (((x) >> 5) & 0x3)
-#define   C_SQ_ALU_WORD1_OP2_V2_OMOD                                 0xFFFFFF9F
-#define   S_SQ_ALU_WORD1_OP2_V2_ALU_INST(x)                          (((x) & 0x7FF) << 7)
-#define   G_SQ_ALU_WORD1_OP2_V2_ALU_INST(x)                          (((x) >> 7) & 0x7FF)
-#define   C_SQ_ALU_WORD1_OP2_V2_ALU_INST                             0xFFFC007F
 
 #endif
index 4150f88785efbffa2152337e776b16123aa48be8..84a13e4ef7af1aba58c96d429400286a82477b9b 100644 (file)
@@ -151,7 +151,7 @@ static void r600_set_framebuffer_state(struct pipe_context *ctx,
 static void *r600_create_fs_state(struct pipe_context *ctx,
                                        const struct pipe_shader_state *shader)
 {
-       return r600_pipe_shader_create(ctx, C_PROGRAM_TYPE_FS, shader->tokens);
+       return r600_pipe_shader_create(ctx, shader->tokens);
 }
 
 static void r600_bind_fs_state(struct pipe_context *ctx, void *state)
@@ -164,7 +164,7 @@ static void r600_bind_fs_state(struct pipe_context *ctx, void *state)
 static void *r600_create_vs_state(struct pipe_context *ctx,
                                        const struct pipe_shader_state *shader)
 {
-       return r600_pipe_shader_create(ctx, C_PROGRAM_TYPE_VS, shader->tokens);
+       return r600_pipe_shader_create(ctx, shader->tokens);
 }
 
 static void r600_bind_vs_state(struct pipe_context *ctx, void *state)
index 7d94bbe510f4a1bb5e264e6e608c02328abc3a14..903cfad80a87a2e5817af263f459b267d8f87609 100644 (file)
@@ -29,7 +29,7 @@
 #include <util/u_math.h>
 #include <util/u_inlines.h>
 #include <util/u_memory.h>
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drm_driver.h"
 #include "r600_screen.h"
 #include "r600_texture.h"
 
index d2c7248ff2bd17d7e544f2098b71a2738e73aebd..44834984c68d1376ad7cf1a3ec1688e63359d891 100644 (file)
 #define PKT3(op, count) (PKT_TYPE_S(3) | PKT3_IT_OPCODE_S(op) | PKT_COUNT_S(count))
 
 /* Registers */
+#define R_008C00_SQ_CONFIG                           0x00008C00
+#define   S_008C00_VC_ENABLE(x)                        (((x) & 0x1) << 0)
+#define   G_008C00_VC_ENABLE(x)                        (((x) >> 0) & 0x1)
+#define   C_008C00_VC_ENABLE(x)                        0xFFFFFFFE
+#define   S_008C00_EXPORT_SRC_C(x)                     (((x) & 0x1) << 1)
+#define   G_008C00_EXPORT_SRC_C(x)                     (((x) >> 1) & 0x1)
+#define   C_008C00_EXPORT_SRC_C(x)                     0xFFFFFFFD
+#define   S_008C00_DX9_CONSTS(x)                       (((x) & 0x1) << 2)
+#define   G_008C00_DX9_CONSTS(x)                       (((x) >> 2) & 0x1)
+#define   C_008C00_DX9_CONSTS(x)                       0xFFFFFFFB
+#define   S_008C00_ALU_INST_PREFER_VECTOR(x)           (((x) & 0x1) << 3)
+#define   G_008C00_ALU_INST_PREFER_VECTOR(x)           (((x) >> 3) & 0x1)
+#define   C_008C00_ALU_INST_PREFER_VECTOR(x)           0xFFFFFFF7
+#define   S_008C00_DX10_CLAMP(x)                       (((x) & 0x1) << 4)
+#define   G_008C00_DX10_CLAMP(x)                       (((x) >> 4) & 0x1)
+#define   C_008C00_DX10_CLAMP(x)                       0xFFFFFFEF
+#define   S_008C00_CLAUSE_SEQ_PRIO(x)                  (((x) & 0x3) << 8)
+#define   G_008C00_CLAUSE_SEQ_PRIO(x)                  (((x) >> 8) & 0x3)
+#define   C_008C00_CLAUSE_SEQ_PRIO(x)                  0xFFFFFCFF
+#define   S_008C00_PS_PRIO(x)                          (((x) & 0x3) << 24)
+#define   G_008C00_PS_PRIO(x)                          (((x) >> 24) & 0x3)
+#define   C_008C00_PS_PRIO(x)                          0xFCFFFFFF
+#define   S_008C00_VS_PRIO(x)                          (((x) & 0x3) << 26)
+#define   G_008C00_VS_PRIO(x)                          (((x) >> 26) & 0x3)
+#define   C_008C00_VS_PRIO(x)                          0xF3FFFFFF
+#define   S_008C00_GS_PRIO(x)                          (((x) & 0x3) << 28)
+#define   G_008C00_GS_PRIO(x)                          (((x) >> 28) & 0x3)
+#define   C_008C00_GS_PRIO(x)                          0xCFFFFFFF
+#define   S_008C00_ES_PRIO(x)                          (((x) & 0x3) << 30)
+#define   G_008C00_ES_PRIO(x)                          (((x) >> 30) & 0x3)
+#define   C_008C00_ES_PRIO(x)                          0x3FFFFFFF
+#define R_008C04_SQ_GPR_RESOURCE_MGMT_1              0x00008C04
+#define   S_008C04_NUM_PS_GPRS(x)                      (((x) & 0xFF) << 0)
+#define   G_008C04_NUM_PS_GPRS(x)                      (((x) >> 0) & 0xFF)
+#define   C_008C04_NUM_PS_GPRS(x)                      0xFFFFFF00
+#define   S_008C04_NUM_VS_GPRS(x)                      (((x) & 0xFF) << 16)
+#define   G_008C04_NUM_VS_GPRS(x)                      (((x) >> 16) & 0xFF)
+#define   C_008C04_NUM_VS_GPRS(x)                      0xFF00FFFF
+#define   S_008C04_NUM_CLAUSE_TEMP_GPRS(x)             (((x) & 0xF) << 28)
+#define   G_008C04_NUM_CLAUSE_TEMP_GPRS(x)             (((x) >> 28) & 0xF)
+#define   C_008C04_NUM_CLAUSE_TEMP_GPRS(x)             0x0FFFFFFF
+#define R_008C08_SQ_GPR_RESOURCE_MGMT_2              0x00008C08
+#define   S_008C08_NUM_GS_GPRS(x)                      (((x) & 0xFF) << 0)
+#define   G_008C08_NUM_GS_GPRS(x)                      (((x) >> 0) & 0xFF)
+#define   C_008C08_NUM_GS_GPRS(x)                      0xFFFFFF00
+#define   S_008C08_NUM_ES_GPRS(x)                      (((x) & 0xFF) << 16)
+#define   G_008C08_NUM_ES_GPRS(x)                      (((x) >> 16) & 0xFF)
+#define   C_008C08_NUM_ES_GPRS(x)                      0xFF00FFFF
+#define R_008C0C_SQ_THREAD_RESOURCE_MGMT             0x00008C0C
+#define   S_008C0C_NUM_PS_THREADS(x)                   (((x) & 0xFF) << 0)
+#define   G_008C0C_NUM_PS_THREADS(x)                   (((x) >> 0) & 0xFF)
+#define   C_008C0C_NUM_PS_THREADS(x)                   0xFFFFFF00
+#define   S_008C0C_NUM_VS_THREADS(x)                   (((x) & 0xFF) << 8)
+#define   G_008C0C_NUM_VS_THREADS(x)                   (((x) >> 8) & 0xFF)
+#define   C_008C0C_NUM_VS_THREADS(x)                   0xFFFF00FF
+#define   S_008C0C_NUM_GS_THREADS(x)                   (((x) & 0xFF) << 16)
+#define   G_008C0C_NUM_GS_THREADS(x)                   (((x) >> 16) & 0xFF)
+#define   C_008C0C_NUM_GS_THREADS(x)                   0xFF00FFFF
+#define   S_008C0C_NUM_ES_THREADS(x)                   (((x) & 0xFF) << 24)
+#define   G_008C0C_NUM_ES_THREADS(x)                   (((x) >> 24) & 0xFF)
+#define   C_008C0C_NUM_ES_THREADS(x)                   0x00FFFFFF
+#define R_008C10_SQ_STACK_RESOURCE_MGMT_1            0x00008C10
+#define   S_008C10_NUM_PS_STACK_ENTRIES(x)             (((x) & 0xFFF) << 0)
+#define   G_008C10_NUM_PS_STACK_ENTRIES(x)             (((x) >> 0) & 0xFFF)
+#define   C_008C10_NUM_PS_STACK_ENTRIES(x)             0xFFFFF000
+#define   S_008C10_NUM_VS_STACK_ENTRIES(x)             (((x) & 0xFFF) << 16)
+#define   G_008C10_NUM_VS_STACK_ENTRIES(x)             (((x) >> 16) & 0xFFF)
+#define   C_008C10_NUM_VS_STACK_ENTRIES(x)             0xF000FFFF
+#define R_008C14_SQ_STACK_RESOURCE_MGMT_2            0x00008C14
+#define   S_008C14_NUM_GS_STACK_ENTRIES(x)             (((x) & 0xFFF) << 0)
+#define   G_008C14_NUM_GS_STACK_ENTRIES(x)             (((x) >> 0) & 0xFFF)
+#define   C_008C14_NUM_GS_STACK_ENTRIES(x)             0xFFFFF000
+#define   S_008C14_NUM_ES_STACK_ENTRIES(x)             (((x) & 0xFFF) << 16)
+#define   G_008C14_NUM_ES_STACK_ENTRIES(x)             (((x) >> 16) & 0xFFF)
+#define   C_008C14_NUM_ES_STACK_ENTRIES(x)             0xF000FFFF
 #define R_0280A0_CB_COLOR0_INFO                      0x0280A0
 #define   S_0280A0_ENDIAN(x)                           (((x) & 0x3) << 0)
 #define   G_0280A0_ENDIAN(x)                           (((x) >> 0) & 0x3)
diff --git a/src/gallium/drivers/r600/r700_asm.c b/src/gallium/drivers/r600/r700_asm.c
new file mode 100644 (file)
index 0000000..3532ba5
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "r600_asm.h"
+#include "r600_context.h"
+#include "util/u_memory.h"
+#include "r700_sq.h"
+#include <stdio.h>
+#include <errno.h>
+
+int r700_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id)
+{
+       unsigned i;
+
+       /* don't replace gpr by pv or ps for destination register */
+       if (alu->is_op3) {
+               bc->bytecode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |
+                                       S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |
+                                       S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |
+                                       S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |
+                                       S_SQ_ALU_WORD0_LAST(alu->last);
+               bc->bytecode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
+                                       S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
+                                       S_SQ_ALU_WORD1_OP3_SRC2_SEL(alu->src[2].sel) |
+                                       S_SQ_ALU_WORD1_OP3_SRC2_CHAN(alu->src[2].chan) |
+                                       S_SQ_ALU_WORD1_OP3_SRC2_NEG(alu->src[2].neg) |
+                                       S_SQ_ALU_WORD1_OP3_ALU_INST(alu->inst) |
+                                       S_SQ_ALU_WORD1_BANK_SWIZZLE(0);
+       } else {
+               bc->bytecode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |
+                                       S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |
+                                       S_SQ_ALU_WORD0_SRC0_NEG(alu->src[0].neg) |
+                                       S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |
+                                       S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |
+                                       S_SQ_ALU_WORD0_SRC1_NEG(alu->src[1].neg) |
+                                       S_SQ_ALU_WORD0_LAST(alu->last);
+               bc->bytecode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
+                                       S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
+                                       S_SQ_ALU_WORD1_OP2_SRC0_ABS(alu->src[0].abs) |
+                                       S_SQ_ALU_WORD1_OP2_SRC1_ABS(alu->src[1].abs) |
+                                       S_SQ_ALU_WORD1_OP2_WRITE_MASK(alu->dst.write) |
+                                       S_SQ_ALU_WORD1_OP2_ALU_INST(alu->inst) |
+                                       S_SQ_ALU_WORD1_BANK_SWIZZLE(0);
+       }
+       if (alu->last) {
+               for (i = 0; i < alu->nliteral; i++) {
+                       bc->bytecode[id++] = alu->value[i];
+               }
+       }
+       return 0;
+}
index 8266af6d1fce0c805c535719f04f23885030b994..9a117aeb1d3baf8cd11d52a68d830cb835711c57 100644 (file)
 #define   S_SQ_TEX_WORD2_SRC_SEL_W(x)                                (((x) & 0x7) << 29)
 #define   G_SQ_TEX_WORD2_SRC_SEL_W(x)                                (((x) >> 29) & 0x7)
 #define   C_SQ_TEX_WORD2_SRC_SEL_W                                   0x1FFFFFFF
-#define P_SQ_ALU_WORD1_OP2_V2
-#define   S_SQ_ALU_WORD1_OP2_V2_SRC0_ABS(x)                          (((x) & 0x1) << 0)
-#define   G_SQ_ALU_WORD1_OP2_V2_SRC0_ABS(x)                          (((x) >> 0) & 0x1)
-#define   C_SQ_ALU_WORD1_OP2_V2_SRC0_ABS                             0xFFFFFFFE
-#define   S_SQ_ALU_WORD1_OP2_V2_SRC1_ABS(x)                          (((x) & 0x1) << 1)
-#define   G_SQ_ALU_WORD1_OP2_V2_SRC1_ABS(x)                          (((x) >> 1) & 0x1)
-#define   C_SQ_ALU_WORD1_OP2_V2_SRC1_ABS                             0xFFFFFFFD
-#define   S_SQ_ALU_WORD1_OP2_V2_UPDATE_EXECUTE_MASK(x)               (((x) & 0x1) << 2)
-#define   G_SQ_ALU_WORD1_OP2_V2_UPDATE_EXECUTE_MASK(x)               (((x) >> 2) & 0x1)
-#define   C_SQ_ALU_WORD1_OP2_V2_UPDATE_EXECUTE_MASK                  0xFFFFFFFB
-#define   S_SQ_ALU_WORD1_OP2_V2_UPDATE_PRED(x)                       (((x) & 0x1) << 3)
-#define   G_SQ_ALU_WORD1_OP2_V2_UPDATE_PRED(x)                       (((x) >> 3) & 0x1)
-#define   C_SQ_ALU_WORD1_OP2_V2_UPDATE_PRED                          0xFFFFFFF7
-#define   S_SQ_ALU_WORD1_OP2_V2_WRITE_MASK(x)                        (((x) & 0x1) << 4)
-#define   G_SQ_ALU_WORD1_OP2_V2_WRITE_MASK(x)                        (((x) >> 4) & 0x1)
-#define   C_SQ_ALU_WORD1_OP2_V2_WRITE_MASK                           0xFFFFFFEF
-#define   S_SQ_ALU_WORD1_OP2_V2_OMOD(x)                              (((x) & 0x3) << 5)
-#define   G_SQ_ALU_WORD1_OP2_V2_OMOD(x)                              (((x) >> 5) & 0x3)
-#define   C_SQ_ALU_WORD1_OP2_V2_OMOD                                 0xFFFFFF9F
-#define   S_SQ_ALU_WORD1_OP2_V2_ALU_INST(x)                          (((x) & 0x7FF) << 7)
-#define   G_SQ_ALU_WORD1_OP2_V2_ALU_INST(x)                          (((x) >> 7) & 0x7FF)
-#define   C_SQ_ALU_WORD1_OP2_V2_ALU_INST                             0xFFFC007F
 
 #endif
index ec94b112d69539e12bb1f64392887d8e6eda8fe0..3a8405f9b40572af785cf398caa79908128ac656 100644 (file)
@@ -28,8 +28,6 @@ typedef uint8_t                       u8;
 
 struct radeon;
 
-struct pipe_screen *radeon_create_screen(struct radeon *rw);
-
 enum radeon_family {
        CHIP_UNKNOWN,
        CHIP_R100,
@@ -79,6 +77,8 @@ enum radeon_family {
        CHIP_LAST,
 };
 
+enum radeon_family radeon_get_family(struct radeon *rw);
+
 /*
  * radeon object functions
  */
index 00b167e256c4c6f657efb6de22ee46dc56ae9189..e0dd5cf8c2b17a226a229b233e40279ace9ff8b0 100644 (file)
@@ -97,15 +97,7 @@ rbug_draw_block_locked(struct rbug_context *rb_pipe, int flag)
    /* wait for rbug to clear the blocked flag */
    while (rb_pipe->draw_blocked & flag) {
       rb_pipe->draw_blocked |= flag;
-#ifdef PIPE_THREAD_HAVE_CONDVAR
       pipe_condvar_wait(rb_pipe->draw_cond, rb_pipe->draw_mutex);
-#else
-      pipe_mutex_unlock(rb_pipe->draw_mutex);
-#ifdef PIPE_SUBSYSTEM_WINDOWS_USER
-      Sleep(1);
-#endif
-      pipe_mutex_lock(rb_pipe->draw_mutex);
-#endif
    }
 
 }
index f1aab3869b5c24a0bb47c6cd0a3e65bc0a47fa1b..9dc663b079a0c6787b2739073aee4f11da354cd5 100644 (file)
@@ -407,9 +407,7 @@ rbug_context_draw_step(struct rbug_rbug *tr_rbug, struct rbug_header *header, ui
    }
    pipe_mutex_unlock(rb_context->draw_mutex);
 
-#ifdef PIPE_THREAD_HAVE_CONDVAR
    pipe_condvar_broadcast(rb_context->draw_cond);
-#endif
 
    pipe_mutex_unlock(rb_screen->list_mutex);
 
@@ -442,9 +440,7 @@ rbug_context_draw_unblock(struct rbug_rbug *tr_rbug, struct rbug_header *header,
    rb_context->draw_blocker &= ~unblock->unblock;
    pipe_mutex_unlock(rb_context->draw_mutex);
 
-#ifdef PIPE_THREAD_HAVE_CONDVAR
    pipe_condvar_broadcast(rb_context->draw_cond);
-#endif
 
    pipe_mutex_unlock(rb_screen->list_mutex);
 
@@ -476,9 +472,7 @@ rbug_context_draw_rule(struct rbug_rbug *tr_rbug, struct rbug_header *header, ui
    rb_context->draw_blocker |= RBUG_BLOCK_RULE;
    pipe_mutex_unlock(rb_context->draw_mutex);
 
-#ifdef PIPE_THREAD_HAVE_CONDVAR
    pipe_condvar_broadcast(rb_context->draw_cond);
-#endif
 
    pipe_mutex_unlock(rb_screen->list_mutex);
 
index 79daa68f3b3e8ae6dab00c0dae7fee7653afed90..9e727c93811f7b0e7ba4f744df3c00465242d184 100644 (file)
 
 
 
-
-/**
- * Draw vertex arrays, with optional indexing.
- * Basically, map the vertex buffers (and drawing surfaces), then hand off
- * the drawing to the 'draw' module.
- */
-static void
-softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
-                                       struct pipe_resource *indexBuffer,
-                                       unsigned indexSize,
-                                       int indexBias,
-                                       unsigned minIndex,
-                                       unsigned maxIndex,
-                                       unsigned mode,
-                                       unsigned start,
-                                       unsigned count,
-                                       unsigned startInstance,
-                                       unsigned instanceCount);
-
-
-void
-softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
-                     unsigned start, unsigned count)
-{
-   softpipe_draw_range_elements_instanced(pipe,
-                                          NULL,
-                                          0,
-                                          0,
-                                          0,
-                                          0xffffffff,
-                                          mode,
-                                          start,
-                                          count,
-                                          0,
-                                          1);
-}
-
 void
 softpipe_draw_stream_output(struct pipe_context *pipe, unsigned mode)
 {
@@ -136,6 +99,93 @@ softpipe_draw_stream_output(struct pipe_context *pipe, unsigned mode)
 }
 
 
+/**
+ * This function handles drawing indexed and non-indexed prims,
+ * instanced and non-instanced drawing, with or without min/max element
+ * indexes.
+ * All the other drawing functions are expressed in terms of this
+ * function.
+ *
+ * For non-indexed prims, indexBuffer should be NULL.
+ * For non-instanced drawing, instanceCount should be 1.
+ * When the min/max element indexes aren't known, minIndex should be 0
+ * and maxIndex should be ~0.
+ */
+static void
+softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
+                                       struct pipe_resource *indexBuffer,
+                                       unsigned indexSize,
+                                       int indexBias,
+                                       unsigned minIndex,
+                                       unsigned maxIndex,
+                                       unsigned mode,
+                                       unsigned start,
+                                       unsigned count,
+                                       unsigned startInstance,
+                                       unsigned instanceCount)
+{
+   struct softpipe_context *sp = softpipe_context(pipe);
+   struct draw_context *draw = sp->draw;
+   unsigned i;
+
+   if (!softpipe_check_render_cond(sp))
+      return;
+
+   sp->reduced_api_prim = u_reduced_prim(mode);
+
+   if (sp->dirty) {
+      softpipe_update_derived(sp);
+   }
+
+   softpipe_map_transfers(sp);
+
+   /* Map vertex buffers */
+   for (i = 0; i < sp->num_vertex_buffers; i++) {
+      void *buf = softpipe_resource(sp->vertex_buffer[i].buffer)->data;
+      draw_set_mapped_vertex_buffer(draw, i, buf);
+   }
+
+   /* Map index buffer, if present */
+   if (indexBuffer) {
+      void *mapped_indexes = softpipe_resource(indexBuffer)->data;
+      draw_set_mapped_element_buffer_range(draw,
+                                           indexSize,
+                                           indexBias,
+                                           minIndex,
+                                           maxIndex,
+                                           mapped_indexes);
+   } else {
+      /* no index/element buffer */
+      draw_set_mapped_element_buffer_range(draw,
+                                           0, 0,
+                                           start,
+                                           start + count - 1,
+                                           NULL);
+   }
+
+   /* draw! */
+   draw_arrays_instanced(draw, mode, start, count, startInstance, instanceCount);
+
+   /* unmap vertex/index buffers - will cause draw module to flush */
+   for (i = 0; i < sp->num_vertex_buffers; i++) {
+      draw_set_mapped_vertex_buffer(draw, i, NULL);
+   }
+   if (indexBuffer) {
+      draw_set_mapped_element_buffer(draw, 0, 0, NULL);
+   }
+
+   /*
+    * TODO: Flush only when a user vertex/index buffer is present
+    * (or even better, modify draw module to do this
+    * internally when this condition is seen?)
+    */
+   draw_flush(draw);
+
+   /* Note: leave drawing surfaces mapped */
+   sp->dirty_render_cache = TRUE;
+}
+
+
 void
 softpipe_draw_range_elements(struct pipe_context *pipe,
                              struct pipe_resource *indexBuffer,
@@ -223,76 +273,20 @@ softpipe_draw_elements_instanced(struct pipe_context *pipe,
                                           instanceCount);
 }
 
-static void
-softpipe_draw_range_elements_instanced(struct pipe_context *pipe,
-                                       struct pipe_resource *indexBuffer,
-                                       unsigned indexSize,
-                                       int indexBias,
-                                       unsigned minIndex,
-                                       unsigned maxIndex,
-                                       unsigned mode,
-                                       unsigned start,
-                                       unsigned count,
-                                       unsigned startInstance,
-                                       unsigned instanceCount)
+void
+softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
+                     unsigned start, unsigned count)
 {
-   struct softpipe_context *sp = softpipe_context(pipe);
-   struct draw_context *draw = sp->draw;
-   unsigned i;
-
-   if (!softpipe_check_render_cond(sp))
-      return;
-
-   sp->reduced_api_prim = u_reduced_prim(mode);
-
-   if (sp->dirty) {
-      softpipe_update_derived(sp);
-   }
-
-   softpipe_map_transfers(sp);
-
-   /* Map vertex buffers */
-   for (i = 0; i < sp->num_vertex_buffers; i++) {
-      void *buf = softpipe_resource(sp->vertex_buffer[i].buffer)->data;
-      draw_set_mapped_vertex_buffer(draw, i, buf);
-   }
-
-   /* Map index buffer, if present */
-   if (indexBuffer) {
-      void *mapped_indexes = softpipe_resource(indexBuffer)->data;
-      draw_set_mapped_element_buffer_range(draw,
-                                           indexSize,
-                                           indexBias,
-                                           minIndex,
-                                           maxIndex,
-                                           mapped_indexes);
-   } else {
-      /* no index/element buffer */
-      draw_set_mapped_element_buffer_range(draw,
-                                           0, 0,
-                                           start,
-                                           start + count - 1,
-                                           NULL);
-   }
-
-   /* draw! */
-   draw_arrays_instanced(draw, mode, start, count, startInstance, instanceCount);
-
-   /* unmap vertex/index buffers - will cause draw module to flush */
-   for (i = 0; i < sp->num_vertex_buffers; i++) {
-      draw_set_mapped_vertex_buffer(draw, i, NULL);
-   }
-   if (indexBuffer) {
-      draw_set_mapped_element_buffer(draw, 0, 0, NULL);
-   }
-
-   /*
-    * TODO: Flush only when a user vertex/index buffer is present
-    * (or even better, modify draw module to do this
-    * internally when this condition is seen?)
-    */
-   draw_flush(draw);
-
-   /* Note: leave drawing surfaces mapped */
-   sp->dirty_render_cache = TRUE;
+   softpipe_draw_range_elements_instanced(pipe,
+                                          NULL,
+                                          0,
+                                          0,
+                                          0,
+                                          0xffffffff,
+                                          mode,
+                                          start,
+                                          count,
+                                          0,
+                                          1);
 }
+
index 00187febf0c4c839fa0b573197b7adc955430908..6af1b2d0618b4882934621f945665b60cb686cfc 100644 (file)
@@ -208,7 +208,7 @@ logicop_quad(struct quad_stage *qs,
          res4[j] = ~0;
       break;
    default:
-      assert(0);
+      assert(0 && "invalid logicop mode");
    }
 
    for (j = 0; j < 4; j++) {
@@ -221,11 +221,18 @@ logicop_quad(struct quad_stage *qs,
 
 
 
+/**
+ * Do blending for a 2x2 quad for one color buffer.
+ * \param quadColor  the incoming quad colors
+ * \param dest  the destination/framebuffer quad colors
+ * \param blend_index  which set of blending terms to use
+ * \param has_dst_alpha  does the dest color buffer have an alpha channel?
+ */
 static void
 blend_quad(struct quad_stage *qs, 
            float (*quadColor)[4],
            float (*dest)[4],
-           unsigned cbuf,
+           unsigned blend_index,
            boolean has_dst_alpha)
 {
    static const float zero[4] = { 0, 0, 0, 0 };
@@ -236,7 +243,7 @@ blend_quad(struct quad_stage *qs,
    /*
     * Compute src/first term RGB
     */
-   switch (softpipe->blend->rt[cbuf].rgb_src_factor) {
+   switch (softpipe->blend->rt[blend_index].rgb_src_factor) {
    case PIPE_BLENDFACTOR_ONE:
       VEC4_COPY(source[0], quadColor[0]); /* R */
       VEC4_COPY(source[1], quadColor[1]); /* G */
@@ -395,13 +402,13 @@ blend_quad(struct quad_stage *qs,
       assert(0); /* to do */
       break;
    default:
-      assert(0);
+      assert(0 && "invalid rgb src factor");
    }
 
    /*
     * Compute src/first term A
     */
-   switch (softpipe->blend->rt[cbuf].alpha_src_factor) {
+   switch (softpipe->blend->rt[blend_index].alpha_src_factor) {
    case PIPE_BLENDFACTOR_ONE:
       VEC4_COPY(source[3], quadColor[3]); /* A */
       break;
@@ -469,14 +476,14 @@ blend_quad(struct quad_stage *qs,
    }
    break;
    default:
-      assert(0);
+      assert(0 && "invalid alpha src factor");
    }
 
 
    /*
     * Compute dest/second term RGB
     */
-   switch (softpipe->blend->rt[cbuf].rgb_dst_factor) {
+   switch (softpipe->blend->rt[blend_index].rgb_dst_factor) {
    case PIPE_BLENDFACTOR_ONE:
       /* dest = dest * 1   NO-OP, leave dest as-is */
       break;
@@ -625,13 +632,13 @@ blend_quad(struct quad_stage *qs,
       assert(0);
       break;
    default:
-      assert(0);
+      assert(0 && "invalid rgb dst factor");
    }
 
    /*
     * Compute dest/second term A
     */
-   switch (softpipe->blend->rt[cbuf].alpha_dst_factor) {
+   switch (softpipe->blend->rt[blend_index].alpha_dst_factor) {
    case PIPE_BLENDFACTOR_ONE:
       /* dest = dest * 1   NO-OP, leave dest as-is */
       break;
@@ -696,13 +703,13 @@ blend_quad(struct quad_stage *qs,
    }
    break;
    default:
-      assert(0);
+      assert(0 && "invalid alpha dst factor");
    }
 
    /*
     * Combine RGB terms
     */
-   switch (softpipe->blend->rt[cbuf].rgb_func) {
+   switch (softpipe->blend->rt[blend_index].rgb_func) {
    case PIPE_BLEND_ADD:
       VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */
       VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */
@@ -729,13 +736,13 @@ blend_quad(struct quad_stage *qs,
       VEC4_MAX(quadColor[2], source[2], dest[2]); /* B */
       break;
    default:
-      assert(0);
+      assert(0 && "invalid rgb blend func");
    }
 
    /*
     * Combine A terms
     */
-   switch (softpipe->blend->rt[cbuf].alpha_func) {
+   switch (softpipe->blend->rt[blend_index].alpha_func) {
    case PIPE_BLEND_ADD:
       VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */
       break;
@@ -752,7 +759,7 @@ blend_quad(struct quad_stage *qs,
       VEC4_MAX(quadColor[3], source[3], dest[3]); /* A */
       break;
    default:
-      assert(0);
+      assert(0 && "invalid alpha blend func");
    }
 }
 
@@ -822,7 +829,7 @@ blend_fallback(struct quad_stage *qs,
             logicop_quad( qs, quadColor, dest );
          }
          else if (blend->rt[blend_buf].blend_enable) {
-            blend_quad( qs, quadColor, dest, cbuf, has_dst_alpha );
+            blend_quad( qs, quadColor, dest, blend_buf, has_dst_alpha );
          }
 
          if (blend->rt[blend_buf].colormask != 0xf)
index 72117c233e525c882f09b581d3a8febf7ff7b1ae..5590d4089291f0ceebfae31deeb3ce12eb1fb365 100644 (file)
@@ -82,7 +82,7 @@ get_depth_stencil_values( struct depth_data *data,
          data->bzzzz[j] = tile->data.depth32[y][x] & 0xffffff;
          data->stencilVals[j] = tile->data.depth32[y][x] >> 24;
       }
-   break;
+      break;
    case PIPE_FORMAT_X8Z24_UNORM:
    case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
       for (j = 0; j < QUAD_SIZE; j++) {
@@ -92,6 +92,14 @@ get_depth_stencil_values( struct depth_data *data,
          data->stencilVals[j] = tile->data.depth32[y][x] & 0xff;
       }
       break;
+   case PIPE_FORMAT_S8_USCALED:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         int x = quad->input.x0 % TILE_SIZE + (j & 1);
+         int y = quad->input.y0 % TILE_SIZE + (j >> 1);
+         data->bzzzz[j] = 0;
+         data->stencilVals[j] = tile->data.stencil8[y][x];
+      }
+      break;
    default:
       assert(0);
    }
@@ -227,6 +235,14 @@ write_depth_stencil_values( struct depth_data *data,
          tile->data.depth32[y][x] = data->bzzzz[j] << 8;
       }
       break;
+   case PIPE_FORMAT_S8_USCALED:
+      for (j = 0; j < QUAD_SIZE; j++) {
+         int x = quad->input.x0 % TILE_SIZE + (j & 1);
+         int y = quad->input.y0 % TILE_SIZE + (j >> 1);
+         tile->data.stencil8[y][x] = data->stencilVals[j];
+      }
+      break;
+
    default:
       assert(0);
    }
@@ -661,20 +677,6 @@ static unsigned mask_count[16] =
 
 
 
-/** helper to get number of Z buffer bits */
-static unsigned
-get_depth_bits(struct quad_stage *qs)
-{
-   struct pipe_surface *zsurf = qs->softpipe->framebuffer.zsbuf;
-   if (zsurf)
-      return util_format_get_component_bits(zsurf->format,
-                                            UTIL_FORMAT_COLORSPACE_ZS, 0);
-   else
-      return 0;
-}
-
-
-
 /**
  * General depth/stencil test function.  Used when there's no fast-path.
  */
@@ -693,9 +695,8 @@ depth_test_quads_fallback(struct quad_stage *qs,
       nr = alpha_test_quads(qs, quads, nr);
    }
 
-   if (get_depth_bits(qs) > 0 &&
-       (qs->softpipe->depth_stencil->depth.enabled ||
-        qs->softpipe->depth_stencil->stencil[0].enabled)) {
+   if (qs->softpipe->depth_stencil->depth.enabled ||
+       qs->softpipe->depth_stencil->stencil[0].enabled) {
 
       data.ps = qs->softpipe->framebuffer.zsbuf;
       data.format = data.ps->format;
@@ -794,8 +795,7 @@ choose_depth_test(struct quad_stage *qs,
 
    boolean alpha = qs->softpipe->depth_stencil->alpha.enabled;
 
-   boolean depth = (get_depth_bits(qs) > 0 &&
-                    qs->softpipe->depth_stencil->depth.enabled);
+   boolean depth = qs->softpipe->depth_stencil->depth.enabled;
 
    unsigned depthfunc = qs->softpipe->depth_stencil->depth.func;
 
index 907e94b59b98ab924af61527346fdc5be9d47801..d240bcbf3bb4d1ef9abf06e73996bfcde5204afe 100644 (file)
@@ -109,7 +109,7 @@ shade_quads(struct quad_stage *qs,
 {
    struct softpipe_context *softpipe = qs->softpipe;
    struct tgsi_exec_machine *machine = softpipe->fs_machine;
-   unsigned i, pass = 0;
+   unsigned i, nr_quads = 0;
 
    for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
       machine->Consts[i] = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT][i];
@@ -123,11 +123,11 @@ shade_quads(struct quad_stage *qs,
       if (/*do_coverage*/ 0)
          coverage_quad( qs, quads[i] );
 
-      quads[pass++] = quads[i];
+      quads[nr_quads++] = quads[i];
    }
    
-   if (pass)
-      qs->next->run(qs->next, quads, pass);
+   if (nr_quads)
+      qs->next->run(qs->next, quads, nr_quads);
 }
    
 
index fc57d3eb611d0003aee465bab05a82f051fe0c5b..93af6ee5b02a780b72c3ba4dc1fa7e7a437c59da 100644 (file)
@@ -149,6 +149,9 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
 
    case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
       return 0;
+
+   case PIPE_CAP_GEOMETRY_SHADER4:
+      return 1;
    default:
       return 0;
    }
index ff83c66d8b25f8afe73fd3d77822014f3dbe6e04..cf7ab81405c5fb5ead4e4d4b5651550de6b3c838 100644 (file)
@@ -71,7 +71,7 @@ lerp(float a, float v0, float v1)
 
 
 /**
- * Do 2D/biliner interpolation of float values.
+ * Do 2D/bilinear interpolation of float values.
  * v00, v10, v01 and v11 are typically four texture samples in a square/box.
  * a and b are the horizontal and vertical interpolants.
  * It's important that this function is inlined when compiled with
index b3e1c49406971ddb6ac3188968d0e4a542aede4f..eb74f14a7bef52597c822e7e73ecd8884f1e0f70 100644 (file)
@@ -63,19 +63,21 @@ sp_create_tex_tile_cache( struct pipe_context *pipe )
 void
 sp_destroy_tex_tile_cache(struct softpipe_tex_tile_cache *tc)
 {
-   uint pos;
+   if (tc) {
+      uint pos;
 
-   for (pos = 0; pos < NUM_ENTRIES; pos++) {
-      /*assert(tc->entries[pos].x < 0);*/
-   }
-   if (tc->transfer) {
-      tc->pipe->transfer_destroy(tc->pipe, tc->transfer);
-   }
-   if (tc->tex_trans) {
-      tc->pipe->transfer_destroy(tc->pipe, tc->tex_trans);
-   }
+      for (pos = 0; pos < NUM_ENTRIES; pos++) {
+         /*assert(tc->entries[pos].x < 0);*/
+      }
+      if (tc->transfer) {
+         tc->pipe->transfer_destroy(tc->pipe, tc->transfer);
+      }
+      if (tc->tex_trans) {
+         tc->pipe->transfer_destroy(tc->pipe, tc->tex_trans);
+      }
 
-   FREE( tc );
+      FREE( tc );
+   }
 }
 
 
index f4db6f6ef00c631571b0ab4741fe0ff08f0c7105..bf33fd941737716e39feff5d2c3b41330245a343 100644 (file)
@@ -115,16 +115,18 @@ sp_create_tile_cache( struct pipe_context *pipe )
 void
 sp_destroy_tile_cache(struct softpipe_tile_cache *tc)
 {
-   uint pos;
+   if (tc) {
+      uint pos;
 
-   for (pos = 0; pos < NUM_ENTRIES; pos++) {
-      /*assert(tc->entries[pos].x < 0);*/
-   }
-   if (tc->transfer) {
-      tc->pipe->transfer_destroy(tc->pipe, tc->transfer);
-   }
+      for (pos = 0; pos < NUM_ENTRIES; pos++) {
+         /*assert(tc->entries[pos].x < 0);*/
+      }
+      if (tc->transfer) {
+         tc->pipe->transfer_destroy(tc->pipe, tc->transfer);
+      }
 
-   FREE( tc );
+      FREE( tc );
+   }
 }
 
 
@@ -284,7 +286,11 @@ sp_tile_cache_flush_clear(struct softpipe_tile_cache *tc)
 
    assert(pt->resource);
    /* clear the scratch tile to the clear value */
-   clear_tile(&tc->tile, pt->resource->format, tc->clear_val);
+   if (tc->depth_stencil) {
+      clear_tile(&tc->tile, pt->resource->format, tc->clear_val);
+   } else {
+      clear_tile_rgba(&tc->tile, pt->resource->format, tc->clear_color);
+   }
 
    /* push the tile to all positions marked as clear */
    for (y = 0; y < h; y += TILE_SIZE) {
@@ -292,11 +298,18 @@ sp_tile_cache_flush_clear(struct softpipe_tile_cache *tc)
          union tile_address addr = tile_address(x, y);
 
          if (is_clear_flag_set(tc->clear_flags, addr)) {
-            pipe_put_tile_raw(tc->pipe,
-                              pt,
-                              x, y, TILE_SIZE, TILE_SIZE,
-                              tc->tile.data.color32, 0/*STRIDE*/);
-
+            /* write the scratch tile to the surface */
+            if (tc->depth_stencil) {
+               pipe_put_tile_raw(tc->pipe,
+                                 pt,
+                                 x, y, TILE_SIZE, TILE_SIZE,
+                                 tc->tile.data.any, 0/*STRIDE*/);
+            }
+            else {
+               pipe_put_tile_rgba(tc->pipe, pt,
+                                  x, y, TILE_SIZE, TILE_SIZE,
+                                  (float *) tc->tile.data.color);
+            }
             numCleared++;
          }
       }
diff --git a/src/gallium/drivers/svga/svga_public.h b/src/gallium/drivers/svga/svga_public.h
new file mode 100644 (file)
index 0000000..ded2e24
--- /dev/null
@@ -0,0 +1,42 @@
+/**********************************************************
+ * Copyright 2010 VMware, 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 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 THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION 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
+ * VMware SVGA public interface. Used by targets to create a stack.
+ *
+ * @author Jakob Bornecrantz Fonseca <jakob@vmware.com>
+ */
+
+#ifndef SVGA_PUBLIC_H_
+#define SVGA_PUBLIC_H_
+
+struct pipe_screen;
+struct svga_winsys_screen;
+
+struct pipe_screen *
+svga_screen_create(struct svga_winsys_screen *sws);
+
+#endif /* SVGA_PUBLIC_H_ */
index 54d9faeb72a7d4596a7d2ccdc8b5fe29d554380f..077ff9a2cf6bfe58a58d1748eafe9a64c613c270 100644 (file)
@@ -29,6 +29,7 @@
 #include "util/u_math.h"
 
 #include "svga_winsys.h"
+#include "svga_public.h"
 #include "svga_context.h"
 #include "svga_screen.h"
 #include "svga_resource_texture.h"
index a2dcc84f7daa8066e3bb2e6024f151c70aa0e389..5e4bdeff2ee275eff595cb876d956620c5a249a1 100644 (file)
@@ -288,9 +288,6 @@ struct svga_winsys_screen
 };
 
 
-struct pipe_screen *
-svga_screen_create(struct svga_winsys_screen *sws);
-
 struct svga_winsys_screen *
 svga_winsys_screen(struct pipe_screen *screen);
 
index 1b0c087a2a4193039cbe075e5a41980ee1333043..99e5fb81c2241a62019c65cb0b8438131041f5bf 100644 (file)
@@ -8,7 +8,6 @@ C_SOURCES = \
        tr_dump.c \
        tr_dump_state.c \
        tr_screen.c \
-       tr_drm.c \
        tr_texture.c
 
 include ../../Makefile.template
index 0dc43a9ec415e295488288ddf39be79837c89c61..06b0c4863a4572512846d7cd4ce5a3d5acb5aa91 100644 (file)
@@ -6,7 +6,6 @@ trace = env.ConvenienceLibrary(
     target = 'trace',
     source = [
         'tr_context.c',
-        'tr_drm.c',
         'tr_dump.c',
         'tr_dump_state.c',
         'tr_screen.c',
diff --git a/src/gallium/drivers/trace/tr_drm.c b/src/gallium/drivers/trace/tr_drm.c
deleted file mode 100644 (file)
index e685033..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2009 VMware, 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 the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL VMWARE 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 "state_tracker/drm_api.h"
-
-#include "util/u_memory.h"
-#include "rbug/rbug_public.h"
-#include "tr_drm.h"
-#include "tr_screen.h"
-#include "tr_public.h"
-
-struct trace_drm_api
-{
-   struct drm_api base;
-
-   struct drm_api *api;
-};
-
-static INLINE struct trace_drm_api *
-trace_drm_api(struct drm_api *_api)
-{
-   return (struct trace_drm_api *)_api;
-}
-
-static struct pipe_screen *
-trace_drm_create_screen(struct drm_api *_api, int fd)
-{
-   struct trace_drm_api *tr_api = trace_drm_api(_api);
-   struct drm_api *api = tr_api->api;
-   struct pipe_screen *screen;
-
-   /* TODO trace call */
-
-   screen = api->create_screen(api, fd);
-
-   return trace_screen_create(rbug_screen_create(screen));
-}
-
-static void
-trace_drm_destroy(struct drm_api *_api)
-{
-   struct trace_drm_api *tr_api = trace_drm_api(_api);
-   struct drm_api *api = tr_api->api;
-
-   if (api->destroy)
-      api->destroy(api);
-
-   FREE(tr_api);
-}
-
-struct drm_api *
-trace_drm_create(struct drm_api *api)
-{
-   struct trace_drm_api *tr_api;
-
-   if (!api)
-      goto error;
-
-   if (!trace_enabled() && !rbug_enabled())
-      goto error;
-
-   tr_api = CALLOC_STRUCT(trace_drm_api);
-
-   if (!tr_api)
-      goto error;
-
-   tr_api->base.name = api->name;
-   tr_api->base.driver_name = api->driver_name;
-   tr_api->base.create_screen = trace_drm_create_screen;
-   tr_api->base.destroy = trace_drm_destroy;
-   tr_api->api = api;
-
-   return &tr_api->base;
-
-error:
-   return api;
-}
diff --git a/src/gallium/drivers/trace/tr_drm.h b/src/gallium/drivers/trace/tr_drm.h
deleted file mode 100644 (file)
index 845c66a..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2009 VMware, 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 the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL VMWARE 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 TR_DRM_H
-#define TR_DRM_H
-
-struct drm_api;
-
-struct drm_api* trace_drm_create(struct drm_api *api);
-
-#endif /* ID_DRM_H */
index a14486a5fb5cb1e3fe80b310888c35772851293e..0358c14e24b03b3cee615292739278299b6b8663 100644 (file)
 #include <stdbool.h>
 
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
 #if !defined(__HAIKU__) && !defined(__USE_MISC)
 typedef unsigned int       uint;
 typedef unsigned short     ushort;
@@ -184,6 +189,25 @@ typedef unsigned char boolean;
 
 #endif
 
+
+#if defined(__GNUC__)
+
+#define PIPE_READ_WRITE_BARRIER() __asm__("":::"memory")
+
+#elif defined(_MSC_VER)
+
+void _ReadWriteBarrier(void);
+#pragma intrinsic(_ReadWriteBarrier)
+#define PIPE_READ_WRITE_BARRIER() _ReadWriteBarrier()
+
+#else
+
+#warning "Unsupported compiler"
+#define PIPE_READ_WRITE_BARRIER() /* */
+
+#endif
+
+
 /* You should use these macros to mark if blocks where the if condition
  * is either likely to be true, or unlikely to be true.
  *
@@ -224,4 +248,10 @@ typedef unsigned char boolean;
 #define unlikely(x) !!(x)
 #endif
 
+
+#if defined(__cplusplus)
+}
+#endif
+
+
 #endif /* P_COMPILER_H */
index b81702a4fac0792f750bca7ca755317c87c9a5b0..74a1fa297812c277d4f46c3b828b79b2fe4b7de7 100644 (file)
 #else
 #define PIPE_ARCH_SSE
 #endif
+#if defined(PIPE_CC_GCC) && !defined(__SSSE3__)
+/* #warning SSE3 support requires -msse3 compiler options */
+#else
+#define PIPE_ARCH_SSSE3
+#endif
 #endif
 
 #if defined(__PPC__)
 #define PIPE_OS_UNIX
 #endif
 
+#if defined(__GNU__)
+#define PIPE_OS_HURD
+#define PIPE_OS_UNIX
+#endif
+
 #if defined(__sun)
 #define PIPE_OS_SOLARIS
 #define PIPE_OS_UNIX
index 3b87d998ceb5f8140000a2ac6efc6a616f77a5f7..00aa2076ed5f13c501595f23bdc5ac132057ca3e 100644 (file)
@@ -489,7 +489,10 @@ enum pipe_cap {
    PIPE_CAP_MAX_VS_CONSTS,
    PIPE_CAP_MAX_VS_TEMPS,
    PIPE_CAP_MAX_VS_ADDRS,
-   PIPE_CAP_MAX_VS_PREDS
+   PIPE_CAP_MAX_VS_PREDS,
+
+   PIPE_CAP_GEOMETRY_SHADER4,
+   PIPE_CAP_DEPTH_CLAMP
 };
 
 
index 6231f06ec718c17fdd0b48501a1f5d84113073b1..301fe2b74f0158555840659172ba74420ec2951d 100644 (file)
@@ -61,8 +61,8 @@ extern "C" {
 #define PIPE_MAX_SAMPLERS         16
 #define PIPE_MAX_VERTEX_SAMPLERS  16
 #define PIPE_MAX_GEOMETRY_SAMPLERS  16
-#define PIPE_MAX_SHADER_INPUTS    16
-#define PIPE_MAX_SHADER_OUTPUTS   16
+#define PIPE_MAX_SHADER_INPUTS    32
+#define PIPE_MAX_SHADER_OUTPUTS   32
 #define PIPE_MAX_TEXTURE_LEVELS   16
 #define PIPE_MAX_SO_BUFFERS        4
 
@@ -155,6 +155,7 @@ struct pipe_clip_state
 {
    float ucp[PIPE_MAX_CLIP_PLANES][4];
    unsigned nr;
+   unsigned depth_clamp:1;
 };
 
 
@@ -419,7 +420,7 @@ struct pipe_vertex_element
    /** Which vertex_buffer (as given to pipe->set_vertex_buffer()) does
     * this attribute live in?
     */
-   unsigned vertex_buffer_index:8;
+   unsigned vertex_buffer_index;
  
    enum pipe_format src_format;
 };
diff --git a/src/gallium/include/state_tracker/drm_api.h b/src/gallium/include/state_tracker/drm_api.h
deleted file mode 100644 (file)
index 4572c7e..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-
-#ifndef _DRM_API_H_
-#define _DRM_API_H_
-
-#include "pipe/p_compiler.h"
-
-struct pipe_screen;
-struct pipe_winsys;
-struct pipe_context;
-struct pipe_resource;
-
-#define DRM_API_HANDLE_TYPE_SHARED 0
-#define DRM_API_HANDLE_TYPE_KMS    1
-
-/**
- * For use with pipe_screen::{texture_from_handle|texture_get_handle}.
- */
-struct winsys_handle
-{
-       /**
-        * Unused for texture_from_handle, always
-        * DRM_API_HANDLE_TYPE_SHARED.  Input to texture_get_handle,
-        * use TEXTURE_USAGE to select handle for kms or ipc.
-        */
-       unsigned type;
-       /**
-        * Input to texture_from_handle.
-        * Output for texture_get_handle.
-        */
-       unsigned handle;
-       /**
-        * Input to texture_from_handle.
-        * Output for texture_get_handle.
-        */
-       unsigned stride;
-};
-
-struct drm_api
-{
-       void (*destroy)(struct drm_api *api);
-
-        const char *name;
-
-       /**
-        * Kernel driver name, as accepted by drmOpenByName.
-        */
-       const char *driver_name;
-
-       /**
-        * Create a pipe srcreen.
-        */
-       struct pipe_screen* (*create_screen)(struct drm_api *api, int drm_fd);
-};
-
-extern struct drm_api * drm_api_create(void);
-
-#endif
diff --git a/src/gallium/include/state_tracker/drm_driver.h b/src/gallium/include/state_tracker/drm_driver.h
new file mode 100644 (file)
index 0000000..d94c1e6
--- /dev/null
@@ -0,0 +1,71 @@
+
+#ifndef _DRM_DRIVER_H_
+#define _DRM_DRIVER_H_
+
+#include "pipe/p_compiler.h"
+
+struct pipe_screen;
+struct pipe_winsys;
+struct pipe_context;
+struct pipe_resource;
+
+#define DRM_API_HANDLE_TYPE_SHARED 0
+#define DRM_API_HANDLE_TYPE_KMS    1
+
+/**
+ * For use with pipe_screen::{texture_from_handle|texture_get_handle}.
+ */
+struct winsys_handle
+{
+   /**
+    * Unused for texture_from_handle, always
+    * DRM_API_HANDLE_TYPE_SHARED.  Input to texture_get_handle,
+    * use TEXTURE_USAGE to select handle for kms or ipc.
+    */
+   unsigned type;
+   /**
+    * Input to texture_from_handle.
+    * Output for texture_get_handle.
+    */
+   unsigned handle;
+   /**
+    * Input to texture_from_handle.
+    * Output for texture_get_handle.
+    */
+   unsigned stride;
+};
+
+struct drm_driver_descriptor
+{
+   /**
+    * Identifying sufix/prefix of the binary, used by egl.
+    */
+   const char *name;
+
+   /**
+    * Kernel driver name, as accepted by drmOpenByName.
+    */
+   const char *driver_name;
+
+   /**
+    * Create a pipe srcreen.
+    *
+    * This function does any wrapping of the screen.
+    * For example wrapping trace or rbug debugging drivers around it.
+    */
+   struct pipe_screen* (*create_screen)(int drm_fd);
+};
+
+extern struct drm_driver_descriptor driver_descriptor;
+
+/**
+ * Instantiate a drm_driver_descriptor struct.
+ */
+#define DRM_DRIVER_DESCRIPTOR(name_str, driver_name_str, func) \
+struct drm_driver_descriptor driver_descriptor = {             \
+   .name = name_str,                                           \
+   .driver_name = driver_name_str,                             \
+   .create_screen = func,                                      \
+};
+
+#endif
index 621bdae5c8528933c97ebe563dcc95b9c8255464..114246118814a43c1a1e625318f9573fce4721b7 100644 (file)
@@ -368,12 +368,6 @@ struct st_api
     */
    st_proc_t (*get_proc_address)(struct st_api *stapi, const char *procname);
 
-   /**
-    * Return true if the visual is supported by the state tracker.
-    */
-   boolean (*is_visual_supported)(struct st_api *stapi,
-                                  const struct st_visual *visual);
-
    /**
     * Create a rendering context.
     */
index 9ff925d4bef06dc23effc788bfa048245e8833d0..087ae8d2a4a2e6aa12a557021c0988a8a35052ab 100644 (file)
@@ -39,7 +39,6 @@
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
 #include "state_tracker/st_api.h"
-#include "state_tracker/drm_api.h"
 
 struct dri_context;
 struct dri_drawable;
@@ -75,7 +74,6 @@ struct dri_screen
                              enum st_attachment_type statt);
 
    /* gallium */
-   struct drm_api *api;
    boolean d_depth_bits_last;
    boolean sd_depth_bits_last;
    boolean auto_fake_front;
index f4cc8d77ebdb1cb4932cb4ca3a2fbb730732c163..5c6573fa69b80adc67b7d1f231d232fb3de28adf 100644 (file)
@@ -33,7 +33,7 @@
 #include "util/u_inlines.h"
 #include "util/u_format.h"
 #include "util/u_debug.h"
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drm_driver.h"
 
 #include "dri_screen.h"
 #include "dri_context.h"
@@ -484,11 +484,11 @@ static const __DRIextension *dri_screen_extensions[] = {
    &driReadDrawableExtension,
    &driCopySubBufferExtension.base,
    &driSwapControlExtension.base,
-   &driFrameTrackingExtension.base,
    &driMediaStreamCounterExtension.base,
    &dri2TexBufferExtension.base,
    &dri2FlushExtension.base,
    &dri2ImageExtension.base,
+   &dri2ConfigQueryExtension.base,
    NULL
 };
 
@@ -508,7 +508,6 @@ dri2_init_screen(__DRIscreen * sPriv)
    if (!screen)
       return NULL;
 
-   screen->api = drm_api_create();
    screen->sPriv = sPriv;
    screen->fd = sPriv->fd;
    screen->lookup_egl_image = dri2_lookup_egl_image;
@@ -518,7 +517,7 @@ dri2_init_screen(__DRIscreen * sPriv)
    sPriv->private = (void *)screen;
    sPriv->extensions = dri_screen_extensions;
 
-   pscreen = screen->api->create_screen(screen->api, screen->fd);
+   pscreen = driver_descriptor.create_screen(screen->fd);
    /* dri_init_screen_helper checks pscreen for us */
 
    configs = dri_init_screen_helper(screen, pscreen, 32);
index dcf645593fb1f46e09f14bf476ed444484494278..23e99aa0addec4adb4c2fa85b94352011f321551 100644 (file)
@@ -255,7 +255,6 @@ drisw_init_screen(__DRIscreen * sPriv)
    if (!screen)
       return NULL;
 
-   screen->api = NULL; /* not needed */
    screen->sPriv = sPriv;
    screen->fd = -1;
    screen->allocate_textures = drisw_allocate_textures;
index fec178ffb30a2e39796b2cb0350d60f2d9d3194e..9e9e479e7e0a1484a60986c2cdff8f4b702b10c1 100644 (file)
@@ -5,14 +5,12 @@ common_INCLUDES = \
        -I. \
        -I$(TOP)/src/gallium/include \
        -I$(TOP)/src/gallium/auxiliary \
-       -I$(TOP)/src/gallium/drivers \
        -I$(TOP)/src/egl/main \
        -I$(TOP)/include
 
 common_SOURCES = $(wildcard common/*.c)
 common_OBJECTS = $(common_SOURCES:.c=.o)
 
-
 x11_INCLUDES = \
        -I$(TOP)/src/gallium/drivers \
        -I$(TOP)/src/glx \
@@ -31,30 +29,37 @@ kms_SOURCES = $(wildcard kms/*.c)
 kms_OBJECTS = $(kms_SOURCES:.c=.o)
 
 
-fbdev_INCLUDES = -I$(TOP)/src/gallium/winsys/sw -I$(TOP)/src/gallium/drivers
+fbdev_INCLUDES = -I$(TOP)/src/gallium/winsys/sw
 fbdev_SOURCES = $(wildcard fbdev/*.c)
 fbdev_OBJECTS = $(fbdev_SOURCES:.c=.o)
 
 
 ALL_INCLUDES = $(common_INCLUDES) $(x11_INCLUDES) $(kms_INCLUDES) $(fbdev_INCLUDES)
 ALL_SOURCES = $(common_SOURCES) $(x11_SOURCES) $(kms_SOURCES) $(fbdev_SOURCES)
-ALL_OBJECTS = $(common_OBJECTS) $(x11_OBJECTS) $(kms_OBJECTS) $(fbdev_OBJECTS)
-
-##### TARGETS #####
 
-EGL_PLATFORMS_MODS = $(foreach plat, $(EGL_PLATFORMS), libegl$(plat).a)
+EGL_OBJECTS = $(common_OBJECTS)
+EGL_CPPFLAGS = $(common_INCLUDES)
+
+# add backends
+ifneq ($(findstring x11, $(EGL_PLATFORMS)),)
+EGL_OBJECTS += $(x11_OBJECTS)
+EGL_CPPFLAGS += -DHAVE_X11_BACKEND
+endif
+ifneq ($(findstring kms, $(EGL_PLATFORMS)),)
+EGL_OBJECTS += $(kms_OBJECTS)
+EGL_CPPFLAGS += -DHAVE_KMS_BACKEND
+endif
+ifneq ($(findstring fbdev, $(EGL_PLATFORMS)),)
+EGL_OBJECTS += $(fbdev_OBJECTS)
+EGL_CPPFLAGS += -DHAVE_FBDEV_BACKEND
+endif
 
-default: depend $(EGL_PLATFORMS_MODS)
-
-
-libeglx11.a: $(x11_OBJECTS) $(common_OBJECTS) Makefile
-       $(MKLIB) -o eglx11 -static $(x11_OBJECTS) $(common_OBJECTS)
+##### TARGETS #####
 
-libeglkms.a: $(kms_OBJECTS) $(common_OBJECTS) Makefile
-       $(MKLIB) -o eglkms -static $(kms_OBJECTS) $(common_OBJECTS)
+default: depend libegl.a
 
-libeglfbdev.a: $(fbdev_OBJECTS) $(common_OBJECTS) Makefile
-       $(MKLIB) -o eglfbdev -static $(fbdev_OBJECTS) $(common_OBJECTS)
+libegl.a: $(EGL_OBJECTS) Makefile
+       $(MKLIB) -o egl -static $(EGL_OBJECTS)
 
 depend: 
        rm -f depend
@@ -62,8 +67,8 @@ depend:
        $(MKDEP) $(MKDEP_OPTIONS) $(ALL_INCLUDES) $(ALL_SOURCES) 2> /dev/null
 
 clean:
-       rm -f $(ALL_OBJECTS)
-       rm -f $(EGL_PLATFORMS_MODS)
+       rm -f libegl.a
+       rm -f $(EGL_OBJECTS)
        rm -f depend depend.bak
 
 # Dummy target
@@ -72,16 +77,20 @@ install:
 
 ##### RULES #####
 
+define egl-cc
+$(CC) -c $(common_INCLUDES) $($(1)_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
+endef
+
 $(common_OBJECTS): %.o: %.c
-       $(CC) -c $(common_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
+       $(CC) -c $(EGL_CPPFLAGS) $(DEFINES) $(CFLAGS) $< -o $@
 
 $(x11_OBJECTS): %.o: %.c
-       $(CC) -c $(common_INCLUDES) $(x11_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
+       $(call egl-cc,x11)
 
 $(kms_OBJECTS): %.o: %.c
-       $(CC) -c $(common_INCLUDES) $(kms_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
+       $(call egl-cc,kms)
 
 $(fbdev_OBJECTS): %.o: %.c
-       $(CC) -c $(common_INCLUDES) $(fbdev_INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
+       $(call egl-cc,fbdev)
 
 sinclude depend
index c4d01d6b2876412e48990c51d1e5d603d0ed3291..e71aec35b7351911433b8831fbbe17f8a21f971c 100644 (file)
@@ -12,6 +12,9 @@ if 'egl' in env['statetrackers']:
        '#/src/gallium/winsys/sw',
        '.',
     ])
+    env.Append(CPPDEFINES = [
+       'HAVE_GDI_BACKEND',
+    ])
 
     common_sources = [
         'common/egl_g3d.c',
index 361cc7960bdc5f3dcd762e7451dfefafed55a675..b6321e6b437589c84a6f7fb1361a2ed5c0c26667 100644 (file)
 #include "egl_g3d.h"
 #include "egl_g3d_api.h"
 #include "egl_g3d_st.h"
+#include "egl_g3d_loader.h"
 #include "native.h"
 
 /**
- * Initialize the state trackers.
+ * Get the native platform.
  */
-static void
-egl_g3d_init_st(_EGLDriver *drv)
+static const struct native_platform *
+egl_g3d_get_platform(_EGLDriver *drv, _EGLPlatformType plat)
 {
    struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
-   EGLint i;
 
-   /* already initialized */
-   if (gdrv->api_mask)
-      return;
+   if (!gdrv->platforms[plat]) {
+      const char *plat_name = NULL;
+      const struct native_platform *nplat = NULL;
 
-   egl_g3d_init_st_apis(gdrv->stapis);
-   for (i = 0; i < ST_API_COUNT; i++) {
-      if (gdrv->stapis[i])
-         gdrv->api_mask |= egl_g3d_st_api_bit(i);
-   }
+      switch (plat) {
+      case _EGL_PLATFORM_WINDOWS:
+         plat_name = "Windows";
+#ifdef HAVE_GDI_BACKEND
+         nplat = native_get_gdi_platform();
+#endif
+         break;
+      case _EGL_PLATFORM_X11:
+         plat_name = "X11";
+#ifdef HAVE_X11_BACKEND
+         nplat = native_get_x11_platform();
+#endif
+         break;
+      case _EGL_PLATFORM_DRM:
+         plat_name = "DRM";
+#ifdef HAVE_KMS_BACKEND
+         nplat = native_get_kms_platform();
+#endif
+         break;
+      case _EGL_PLATFORM_FBDEV:
+         plat_name = "FBDEV";
+#ifdef HAVE_FBDEV_BACKEND
+         nplat = native_get_fbdev_platform();
+#endif
+         break;
+      default:
+         break;
+      }
 
-   if (gdrv->api_mask)
-      _eglLog(_EGL_DEBUG, "Driver API mask: 0x%x", gdrv->api_mask);
-   else
-      _eglLog(_EGL_WARNING, "No supported client API");
-}
+      if (!nplat)
+         _eglLog(_EGL_WARNING, "unsupported platform %s", plat_name);
 
-/**
- * Get the probe object of the display.
- *
- * Note that this function may be called before the display is initialized.
- */
-static struct native_probe *
-egl_g3d_get_probe(_EGLDriver *drv, _EGLDisplay *dpy)
-{
-   struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
-   struct native_probe *nprobe;
-
-   nprobe = (struct native_probe *) _eglGetProbeCache(gdrv->probe_key);
-   if (!nprobe || nprobe->display != dpy->NativeDisplay) {
-      if (nprobe)
-         nprobe->destroy(nprobe);
-      nprobe = native_create_probe(dpy->NativeDisplay);
-      _eglSetProbeCache(gdrv->probe_key, (void *) nprobe);
+      gdrv->platforms[plat] = nplat;
    }
 
-   return nprobe;
-}
-
-/**
- * Destroy the probe object of the display.  The display may be NULL.
- *
- * Note that this function may be called before the display is initialized.
- */
-static void
-egl_g3d_destroy_probe(_EGLDriver *drv, _EGLDisplay *dpy)
-{
-   struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
-   struct native_probe *nprobe;
-
-   nprobe = (struct native_probe *) _eglGetProbeCache(gdrv->probe_key);
-   if (nprobe && (!dpy || nprobe->display == dpy->NativeDisplay)) {
-      nprobe->destroy(nprobe);
-      _eglSetProbeCache(gdrv->probe_key, NULL);
-   }
+   return gdrv->platforms[plat];
 }
 
 #ifdef EGL_MESA_screen_surface
@@ -268,11 +254,9 @@ egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy,
                     _EGLConfig *conf, const struct native_config *nconf,
                     enum pipe_format depth_stencil_format)
 {
-   struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
    struct egl_g3d_config *gconf = egl_g3d_config(conf);
    EGLint buffer_mask, api_mask;
    EGLBoolean valid;
-   EGLint i;
 
    buffer_mask = 0x0;
    if (nconf->buffer_mask & (1 << NATIVE_ATTACHMENT_FRONT_LEFT))
@@ -293,14 +277,7 @@ egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy,
    gconf->stvis.render_buffer = (buffer_mask & ST_ATTACHMENT_BACK_LEFT_MASK) ?
       ST_ATTACHMENT_BACK_LEFT : ST_ATTACHMENT_FRONT_LEFT;
 
-   api_mask = 0;
-   for (i = 0; i < ST_API_COUNT; i++) {
-      struct st_api *stapi = gdrv->stapis[i];
-      if (stapi) {
-         if (stapi->is_visual_supported(stapi, &gconf->stvis))
-            api_mask |= egl_g3d_st_api_bit(i);
-      }
-   }
+   api_mask = dpy->ClientAPIsMask;
    /* this is required by EGL, not by OpenGL ES */
    if (nconf->window_bit &&
        gconf->stvis.render_buffer != ST_ATTACHMENT_BACK_LEFT)
@@ -425,31 +402,64 @@ egl_g3d_invalid_surface(struct native_display *ndpy,
       gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi);
 }
 
+static struct pipe_screen *
+egl_g3d_new_drm_screen(struct native_display *ndpy, const char *name, int fd)
+{
+   _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
+   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+   return gdpy->loader->create_drm_screen(name, fd);
+}
+
+static struct pipe_screen *
+egl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws)
+{
+   _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
+   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+   return gdpy->loader->create_sw_screen(ws);
+}
+
 static struct native_event_handler egl_g3d_native_event_handler = {
-   egl_g3d_invalid_surface
+   egl_g3d_invalid_surface,
+   egl_g3d_new_drm_screen,
+   egl_g3d_new_sw_screen
 };
 
+static void
+egl_g3d_free_config(void *conf)
+{
+   struct egl_g3d_config *gconf = egl_g3d_config((_EGLConfig *) conf);
+   FREE(gconf);
+}
+
+static void
+egl_g3d_free_screen(void *scr)
+{
+   struct egl_g3d_screen *gscr = egl_g3d_screen((_EGLScreen *) scr);
+   FREE(gscr->native_modes);
+   FREE(gscr);
+}
+
 static EGLBoolean
 egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
 {
    struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
-   EGLint i;
 
    _eglReleaseDisplayResources(drv, dpy);
-   _eglCleanupDisplay(dpy);
 
    if (gdpy->pipe)
       gdpy->pipe->destroy(gdpy->pipe);
 
+   if (dpy->Configs) {
+      _eglDestroyArray(dpy->Configs, egl_g3d_free_config);
+      dpy->Configs = NULL;
+   }
    if (dpy->Screens) {
-      for (i = 0; i < dpy->NumScreens; i++) {
-         struct egl_g3d_screen *gscr = egl_g3d_screen(dpy->Screens[i]);
-         FREE(gscr->native_modes);
-         FREE(gscr);
-      }
-      FREE(dpy->Screens);
+      _eglDestroyArray(dpy->Screens, egl_g3d_free_screen);
+      dpy->Screens = NULL;
    }
 
+   _eglCleanupDisplay(dpy);
+
    if (gdpy->smapi)
       egl_g3d_destroy_st_manager(gdpy->smapi);
 
@@ -468,28 +478,36 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
 {
    struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
    struct egl_g3d_display *gdpy;
+   const struct native_platform *nplat;
 
-   /* the probe object is unlikely to be needed again */
-   egl_g3d_destroy_probe(drv, dpy);
+   nplat = egl_g3d_get_platform(drv, dpy->Platform);
+   if (!nplat)
+      return EGL_FALSE;
 
    gdpy = CALLOC_STRUCT(egl_g3d_display);
    if (!gdpy) {
       _eglError(EGL_BAD_ALLOC, "eglInitialize");
       goto fail;
    }
+   gdpy->loader = gdrv->loader;
    dpy->DriverData = gdpy;
 
-   gdpy->native = native_create_display(dpy->NativeDisplay,
-         &egl_g3d_native_event_handler);
+   _eglLog(_EGL_INFO, "use %s for display %p", nplat->name, dpy->PlatformDisplay);
+   gdpy->native = nplat->create_display(dpy->PlatformDisplay,
+         &egl_g3d_native_event_handler, (void *) dpy);
    if (!gdpy->native) {
       _eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)");
       goto fail;
    }
 
-   gdpy->native->user_data = (void *) dpy;
-
-   egl_g3d_init_st(&gdrv->base);
-   dpy->ClientAPIsMask = gdrv->api_mask;
+   if (gdpy->loader->api_mask & (1 << ST_API_OPENGL))
+      dpy->ClientAPIsMask |= EGL_OPENGL_BIT;
+   if (gdpy->loader->api_mask & (1 << ST_API_OPENGL_ES1))
+      dpy->ClientAPIsMask |= EGL_OPENGL_ES_BIT;
+   if (gdpy->loader->api_mask & (1 << ST_API_OPENGL_ES2))
+      dpy->ClientAPIsMask |= EGL_OPENGL_ES2_BIT;
+   if (gdpy->loader->api_mask & (1 << ST_API_OPENVG))
+      dpy->ClientAPIsMask |= EGL_OPENVG_BIT;
 
    gdpy->smapi = egl_g3d_create_st_manager(dpy);
    if (!gdpy->smapi) {
@@ -530,87 +548,51 @@ static _EGLProc
 egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname)
 {
    struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
-   _EGLProc proc;
-   EGLint i;
-
-   /* in case this is called before a display is initialized */
-   egl_g3d_init_st(&gdrv->base);
+   struct st_api *stapi = NULL;
 
-   for (i = 0; i < ST_API_COUNT; i++) {
-      struct st_api *stapi = gdrv->stapis[i];
-      if (stapi) {
-         proc = (_EGLProc) stapi->get_proc_address(stapi, procname);
-         if (proc)
-            return proc;
-      }
-   }
+   if (procname && procname[0] == 'v' && procname[1] == 'g')
+      stapi = gdrv->loader->get_st_api(ST_API_OPENVG);
+   else if (procname && procname[0] == 'g' && procname[1] == 'l')
+      stapi = gdrv->loader->guess_gl_api();
 
-   return (_EGLProc) NULL;
+   return (_EGLProc) ((stapi) ?
+         stapi->get_proc_address(stapi, procname) : NULL);
 }
 
 static EGLint
 egl_g3d_probe(_EGLDriver *drv, _EGLDisplay *dpy)
 {
-   struct native_probe *nprobe;
-   enum native_probe_result res;
-   EGLint score;
-
-   nprobe = egl_g3d_get_probe(drv, dpy);
-   res = native_get_probe_result(nprobe);
-
-   switch (res) {
-   case NATIVE_PROBE_UNKNOWN:
-   default:
-      score = 0;
-      break;
-   case NATIVE_PROBE_FALLBACK:
-      score = 40;
-      break;
-   case NATIVE_PROBE_SUPPORTED:
-      score = 50;
-      break;
-   case NATIVE_PROBE_EXACT:
-      score = 100;
-      break;
-   }
-
-   return score;
-}
-
-static void
-egl_g3d_unload(_EGLDriver *drv)
-{
-   struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
-
-   egl_g3d_destroy_st_apis();
-   egl_g3d_destroy_probe(drv, NULL);
-   FREE(gdrv);
+   return (egl_g3d_get_platform(drv, dpy->Platform)) ? 90 : 0;
 }
 
 _EGLDriver *
-_eglMain(const char *args)
+egl_g3d_create_driver(const struct egl_g3d_loader *loader)
 {
-   static char driver_name[64];
    struct egl_g3d_driver *gdrv;
 
-   util_snprintf(driver_name, sizeof(driver_name),
-         "Gallium/%s", native_get_name());
-
    gdrv = CALLOC_STRUCT(egl_g3d_driver);
    if (!gdrv)
       return NULL;
 
+   gdrv->loader = loader;
+
    egl_g3d_init_driver_api(&gdrv->base);
    gdrv->base.API.Initialize = egl_g3d_initialize;
    gdrv->base.API.Terminate = egl_g3d_terminate;
    gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address;
 
-   gdrv->base.Name = driver_name;
    gdrv->base.Probe = egl_g3d_probe;
-   gdrv->base.Unload = egl_g3d_unload;
 
-   /* the key is " EGL G3D" */
-   gdrv->probe_key = 0x0E61063D;
+   /* to be filled by the caller */
+   gdrv->base.Name = NULL;
+   gdrv->base.Unload = NULL;
 
    return &gdrv->base;
 }
+
+void
+egl_g3d_destroy_driver(_EGLDriver *drv)
+{
+   struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
+   FREE(gdrv);
+}
index d516d8fe03c70a0f608f44b0cf528421e4156240..ed2b0409bb995aabe3e40c60edf06ecc928f18d5 100644 (file)
 
 #include "native.h"
 #include "egl_g3d_st.h"
+#include "egl_g3d_loader.h"
 
 struct egl_g3d_driver {
    _EGLDriver base;
-   struct st_api *stapis[ST_API_COUNT];
-   EGLint api_mask;
-
-   EGLint probe_key;
+   const struct egl_g3d_loader *loader;
+   const struct native_platform *platforms[_EGL_NUM_PLATFORMS];
 };
 
 struct egl_g3d_display {
    struct native_display *native;
 
+   const struct egl_g3d_loader *loader;
    struct st_manager *smapi;
    struct pipe_context *pipe;
 };
index 255a1fb730ad5b87162b6a7dc7da5d707b9c8070..edac72a82232da8c7d5a9ef9c4865569486fbda0 100644 (file)
@@ -35,6 +35,7 @@
 #include "egl_g3d_api.h"
 #include "egl_g3d_image.h"
 #include "egl_g3d_st.h"
+#include "egl_g3d_loader.h"
 #include "native.h"
 
 /**
@@ -44,7 +45,6 @@ static struct st_api *
 egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
 {
    struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
-   struct st_api *stapi;
    EGLint idx = -1;
 
    switch (ctx->ClientAPI) {
@@ -73,8 +73,7 @@ egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
       break;
    }
 
-   stapi = (idx >= 0) ? gdrv->stapis[idx] : NULL;
-   return stapi;
+   return (idx >= 0) ? gdrv->loader->get_st_api(idx) : NULL;
 }
 
 static _EGLContext *
@@ -774,13 +773,13 @@ egl_g3d_find_pixmap_config(_EGLDisplay *dpy, EGLNativePixmapType pix)
    struct egl_g3d_config *gconf;
    EGLint i;
 
-   for (i = 0; i < dpy->NumConfigs; i++) {
-      gconf = egl_g3d_config(dpy->Configs[i]);
+   for (i = 0; i < dpy->Configs->Size; i++) {
+      gconf = egl_g3d_config((_EGLConfig *) dpy->Configs->Elements[i]);
       if (gdpy->native->is_pixmap_supported(gdpy->native, pix, gconf->native))
          break;
    }
 
-   return (i < dpy->NumConfigs) ? &gconf->base : NULL;
+   return (i < dpy->Configs->Size) ? &gconf->base : NULL;
 }
 
 void
index b1fe30a776ccb42bd63b55af107bd33870fea166..1e13cfcf7e9fbdda5bc9ffa3e6614e6986e05c9a 100644 (file)
@@ -78,7 +78,7 @@ egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx,
 
    gimg = CALLOC_STRUCT(egl_g3d_image);
    if (!gimg) {
-      _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
+      _eglError(EGL_BAD_ALLOC, "eglCreateEGLImageKHR");
       return NULL;
    }
 
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_loader.h b/src/gallium/state_trackers/egl/common/egl_g3d_loader.h
new file mode 100644 (file)
index 0000000..c9141f8
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION 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:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#ifndef _EGL_G3D_LOADER_H_
+#define _EGL_G3D_LOADER_H_
+
+#include "pipe/p_compiler.h"
+#include "state_tracker/st_api.h"
+#include "egltypedefs.h"
+
+struct pipe_screen;
+struct sw_winsys;
+
+struct egl_g3d_loader {
+   uint api_mask;
+   struct st_api *(*get_st_api)(enum st_api_type api);
+   struct st_api *(*guess_gl_api)(void);
+
+   struct pipe_screen *(*create_drm_screen)(const char *name, int fd);
+   struct pipe_screen *(*create_sw_screen)(struct sw_winsys *ws);
+};
+
+_EGLDriver *
+egl_g3d_create_driver(const struct egl_g3d_loader *loader);
+
+void
+egl_g3d_destroy_driver(_EGLDriver *drv);
+
+#endif /* _EGL_G3D_LOADER_H_ */
index 683b74f62b25b6f16e66024229cc08e8391a8f81..05cdb0d421c8faf8f8c0441bb43c6c890c441990 100644 (file)
@@ -49,173 +49,6 @@ egl_g3d_st_manager(struct st_manager *smapi)
    return (struct egl_g3d_st_manager *) smapi;
 }
 
-static struct egl_g3d_st_module {
-   const char *filename;
-   struct util_dl_library *lib;
-   struct st_api *stapi;
-} egl_g3d_st_modules[ST_API_COUNT];
-
-static EGLBoolean
-egl_g3d_search_path_callback(const char *dir, size_t len, void *callback_data)
-{
-   struct egl_g3d_st_module *stmod =
-      (struct egl_g3d_st_module *) callback_data;
-   char path[1024];
-   int ret;
-
-   if (!len) {
-      stmod->lib = util_dl_open(stmod->filename);
-      return !(stmod->lib);
-   }
-
-   ret = util_snprintf(path, sizeof(path),
-         "%.*s/%s", len, dir, stmod->filename);
-   if (ret > 0 && ret < sizeof(path))
-      stmod->lib = util_dl_open(path);
-
-   return !(stmod->lib);
-}
-
-static boolean
-egl_g3d_load_st_module(struct egl_g3d_st_module *stmod,
-                       const char *filename, const char *procname)
-{
-   struct st_api *(*create_api)(void);
-
-   stmod->filename = filename;
-   if (stmod->filename)
-      _eglSearchPathForEach(egl_g3d_search_path_callback, (void *) stmod);
-   else
-      stmod->lib = util_dl_open(NULL);
-
-   if (stmod->lib) {
-      create_api = (struct st_api *(*)(void))
-         util_dl_get_proc_address(stmod->lib, procname);
-      if (create_api)
-         stmod->stapi = create_api();
-
-      if (!stmod->stapi) {
-         util_dl_close(stmod->lib);
-         stmod->lib = NULL;
-      }
-   }
-
-   if (stmod->stapi) {
-      return TRUE;
-   }
-   else {
-      stmod->filename = NULL;
-      return FALSE;
-   }
-}
-
-#ifdef PIPE_OS_WINDOWS
-#define ST_MODULE_SUFFIX ".dll"
-#else
-#define ST_MODULE_SUFFIX ".so"
-#endif
-
-void
-egl_g3d_init_st_apis(struct st_api *stapis[ST_API_COUNT])
-{
-   const char *skip_checks[ST_API_COUNT], *symbols[ST_API_COUNT];
-   const char *filenames[ST_API_COUNT][4];
-   struct util_dl_library *self;
-   int num_needed = 0, api;
-
-   self = util_dl_open(NULL);
-
-   /* collect the necessary data for loading modules */
-   for (api = 0; api < ST_API_COUNT; api++) {
-      int count = 0;
-
-      switch (api) {
-      case ST_API_OPENGL:
-         skip_checks[api] = "glColor4d";
-         symbols[api] = ST_CREATE_OPENGL_SYMBOL;
-         filenames[api][count++] = "api_GL" ST_MODULE_SUFFIX;
-         break;
-      case ST_API_OPENGL_ES1:
-         skip_checks[api] = "glColor4x";
-         symbols[api] = ST_CREATE_OPENGL_ES1_SYMBOL;
-         filenames[api][count++] = "api_GLESv1_CM" ST_MODULE_SUFFIX;
-         filenames[api][count++] = "api_GL" ST_MODULE_SUFFIX;
-         break;
-      case ST_API_OPENGL_ES2:
-         skip_checks[api] = "glShaderBinary";
-         symbols[api] = ST_CREATE_OPENGL_ES2_SYMBOL;
-         filenames[api][count++] = "api_GLESv2" ST_MODULE_SUFFIX;
-         filenames[api][count++] = "api_GL" ST_MODULE_SUFFIX;
-         break;
-      case ST_API_OPENVG:
-         skip_checks[api] = "vgClear";
-         symbols[api] = ST_CREATE_OPENVG_SYMBOL;
-         filenames[api][count++]= "api_OpenVG" ST_MODULE_SUFFIX;
-         break;
-      default:
-         assert(!"Unknown API Type\n");
-         skip_checks[api] = NULL;
-         symbols[api] = NULL;
-         break;
-      }
-      filenames[api][count++]= NULL;
-      assert(count < Elements(filenames[api]));
-
-      /* heuristicically decide if the module is needed */
-      if (!self || !skip_checks[api] ||
-          util_dl_get_proc_address(self, skip_checks[api])) {
-         /* unset so the module is not skipped */
-         skip_checks[api] = NULL;
-         num_needed++;
-      }
-   }
-   /* mark all moudles needed if we wrongly decided that none is needed */
-   if (!num_needed)
-      memset(skip_checks, 0, sizeof(skip_checks));
-
-   if (self)
-      util_dl_close(self);
-
-   for (api = 0; api < ST_API_COUNT; api++) {
-      struct egl_g3d_st_module *stmod = &egl_g3d_st_modules[api];
-      const char **p;
-
-      /* skip the module */
-      if (skip_checks[api])
-         continue;
-
-      /* try all filenames, including NULL */
-      for (p = filenames[api]; *p; p++) {
-         if (egl_g3d_load_st_module(stmod, *p, symbols[api]))
-            break;
-      }
-      if (!stmod->stapi)
-         egl_g3d_load_st_module(stmod, NULL, symbols[api]);
-
-      stapis[api] = stmod->stapi;
-   }
-}
-
-void
-egl_g3d_destroy_st_apis(void)
-{
-   int api;
-
-   for (api = 0; api < ST_API_COUNT; api++) {
-      struct egl_g3d_st_module *stmod = &egl_g3d_st_modules[api];
-
-      if (stmod->stapi) {
-         stmod->stapi->destroy(stmod->stapi);
-         stmod->stapi = NULL;
-      }
-      if (stmod->lib) {
-         util_dl_close(stmod->lib);
-         stmod->lib = NULL;
-      }
-      stmod->filename = NULL;
-   }
-}
-
 static boolean
 egl_g3d_st_manager_get_egl_image(struct st_manager *smapi,
                                  struct st_context_iface *stctx,
index ee53799b0297a9103abd8272281c7728afe633a6..aa25cc042d7fd01ae2b7e12dda4f7704b63f832c 100644 (file)
 #include "state_tracker/st_api.h"
 #include "egltypedefs.h"
 
-void
-egl_g3d_init_st_apis(struct st_api *stapis[ST_API_COUNT]);
-
-void
-egl_g3d_destroy_st_apis(void);
-
 struct st_manager *
 egl_g3d_create_st_manager(_EGLDisplay *dpy);
 
index 3f60348c48932555b2197716961364f95bbde5fa..9f34c517ef8cd9038cdbb5fad6ae340abe0ac818 100644 (file)
@@ -32,8 +32,8 @@
 #include "pipe/p_screen.h"
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
+#include "state_tracker/sw_winsys.h"
 
-#include "native_probe.h"
 #include "native_modeset.h"
 
 /**
@@ -196,6 +196,11 @@ struct native_event_handler {
    void (*invalid_surface)(struct native_display *ndpy,
                            struct native_surface *nsurf,
                            unsigned int seq_num);
+
+   struct pipe_screen *(*new_drm_screen)(struct native_display *ndpy,
+                                         const char *name, int fd);
+   struct pipe_screen *(*new_sw_screen)(struct native_display *ndpy,
+                                        struct sw_winsys *ws);
 };
 
 /**
@@ -207,11 +212,24 @@ native_attachment_mask_test(uint mask, enum native_attachment att)
    return !!(mask & (1 << att));
 }
 
-const char *
-native_get_name(void);
+struct native_platform {
+   const char *name;
+
+   struct native_display *(*create_display)(void *dpy,
+                                            struct native_event_handler *handler,
+                                            void *user_data);
+};
+
+const struct native_platform *
+native_get_gdi_platform(void);
+
+const struct native_platform *
+native_get_x11_platform(void);
+
+const struct native_platform *
+native_get_kms_platform(void);
 
-struct native_display *
-native_create_display(EGLNativeDisplayType dpy,
-                      struct native_event_handler *handler);
+const struct native_platform *
+native_get_fbdev_platform(void);
 
 #endif /* _NATIVE_H_ */
index 206817ed666e237cfd558371380e1d920eccb972..7832b2b693f572d904183a8cbe2d2e8ca12be663 100644 (file)
@@ -31,9 +31,6 @@
 #include "pipe/p_screen.h"
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
-#include "softpipe/sp_public.h"
-#include "llvmpipe/lp_public.h"
-#include "target-helpers/wrap_screen.h"
 
 #include "native_helper.h"
 
@@ -236,18 +233,3 @@ resource_surface_present(struct resource_surface *rsurf,
 
    return TRUE;
 }
-
-struct pipe_screen *
-native_create_sw_screen(struct sw_winsys *ws)
-{
-   struct pipe_screen *screen = NULL;
-
-#if defined(GALLIUM_LLVMPIPE)
-   if (!screen && !debug_get_bool_option("GALLIUM_NO_LLVM", FALSE))
-      screen = llvmpipe_create_screen(ws);
-#endif
-   if (!screen)
-      screen = softpipe_create_screen(ws);
-
-   return (screen) ? gallium_wrap_screen(screen) : NULL;
-}
index bdb9629466be3ba87e60dc5494379667b3c22a3e..d1569ac3ea6dd561564527f6eee19897af88ecc6 100644 (file)
@@ -69,6 +69,3 @@ boolean
 resource_surface_present(struct resource_surface *rsurf,
                          enum native_attachment which,
                          void *winsys_drawable_handle);
-
-struct pipe_screen *
-native_create_sw_screen(struct sw_winsys *ws);
diff --git a/src/gallium/state_trackers/egl/common/native_probe.h b/src/gallium/state_trackers/egl/common/native_probe.h
deleted file mode 100644 (file)
index aeed9f8..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.8
- *
- * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and 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
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION 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 _NATIVE_PROBE_H_
-#define _NATIVE_PROBE_H_
-
-#include "EGL/egl.h"  /* for EGL native types */
-
-/**
- * Enumerations for probe results.
- */
-enum native_probe_result {
-   NATIVE_PROBE_UNKNOWN,
-   NATIVE_PROBE_FALLBACK,
-   NATIVE_PROBE_SUPPORTED,
-   NATIVE_PROBE_EXACT,
-};
-
-/**
- * A probe object for display probe.
- */
-struct native_probe {
-   int magic;
-   EGLNativeDisplayType display;
-   void *data;
-
-   void (*destroy)(struct native_probe *nprobe);
-};
-
-/**
- * Return a probe object for the given display.
- *
- * Note that the returned object may be cached and used by different native
- * display modules.  It allows fast probing when multiple modules probe the
- * same display.
- */
-struct native_probe *
-native_create_probe(EGLNativeDisplayType dpy);
-
-/**
- * Probe the probe object.
- */
-enum native_probe_result
-native_get_probe_result(struct native_probe *nprobe);
-
-#endif /* _NATIVE_PROBE_H_ */
index d70b7c6eb965f3014ce070cca3275a3c48a6e55c..e459402076db66d790a5202aaf08b98588f9ba0a 100644 (file)
@@ -386,8 +386,10 @@ fbdev_display_init(struct native_display *ndpy)
       return FALSE;
 
    ws = fbdev_create_sw_winsys(fbdpy->fd, fbdpy->config.color_format);
-   if (ws)
-      fbdpy->base.screen = native_create_sw_screen(ws);
+   if (ws) {
+      fbdpy->base.screen =
+         fbdpy->event_handler->new_sw_screen(&fbdpy->base, ws);
+   }
 
    if (fbdpy->base.screen) {
       if (!fbdpy->base.screen->is_format_supported(fbdpy->base.screen,
@@ -402,7 +404,8 @@ fbdev_display_init(struct native_display *ndpy)
 }
 
 static struct native_display *
-fbdev_display_create(int fd, struct native_event_handler *event_handler)
+fbdev_display_create(int fd, struct native_event_handler *event_handler,
+                     void *user_data)
 {
    struct fbdev_display *fbdpy;
 
@@ -412,6 +415,7 @@ fbdev_display_create(int fd, struct native_event_handler *event_handler)
 
    fbdpy->fd = fd;
    fbdpy->event_handler = event_handler;
+   fbdpy->base.user_data = user_data;
 
    if (!fbdev_display_init(&fbdpy->base)) {
       FREE(fbdpy);
@@ -427,44 +431,37 @@ fbdev_display_create(int fd, struct native_event_handler *event_handler)
    return &fbdpy->base;
 }
 
-struct native_probe *
-native_create_probe(EGLNativeDisplayType dpy)
-{
-   return NULL;
-}
-
-enum native_probe_result
-native_get_probe_result(struct native_probe *nprobe)
-{
-   return NATIVE_PROBE_UNKNOWN;
-}
-
-const char *
-native_get_name(void)
-{
-   return "FBDEV";
-}
-
-struct native_display *
-native_create_display(EGLNativeDisplayType dpy,
-                      struct native_event_handler *event_handler)
+static struct native_display *
+native_create_display(void *dpy, struct native_event_handler *event_handler,
+                      void *user_data)
 {
    struct native_display *ndpy;
    int fd;
 
    /* well, this makes fd 0 being ignored */
-   if (dpy == EGL_DEFAULT_DISPLAY) {
+   if (!dpy) {
       fd = open("/dev/fb0", O_RDWR);
    }
    else {
-      fd = dup((int) pointer_to_intptr((void *) dpy));
+      fd = dup((int) pointer_to_intptr(dpy));
    }
    if (fd < 0)
       return NULL;
 
-   ndpy = fbdev_display_create(fd, event_handler);
+   ndpy = fbdev_display_create(fd, event_handler, user_data);
    if (!ndpy)
       close(fd);
 
    return ndpy;
 }
+
+static const struct native_platform fbdev_platform = {
+   "FBDEV", /* name */
+   native_create_display
+};
+
+const struct native_platform *
+native_get_fbdev_platform(void)
+{
+   return &fbdev_platform;
+}
index 1791d198d50212b6d271a4374c76fc86110066f0..91701e5b7df2675ea2d2d70607b9e276acf8a3f8 100644 (file)
@@ -343,10 +343,11 @@ gdi_display_destroy(struct native_display *ndpy)
 }
 
 static struct native_display *
-gdi_create_display(HDC hDC, struct pipe_screen *screen,
-                   struct native_event_handler *event_handler)
+gdi_create_display(HDC hDC, struct native_event_handler *event_handler,
+                   void *user_data)
 {
    struct gdi_display *gdpy;
+   struct sw_winsys *winsys;
 
    gdpy = CALLOC_STRUCT(gdi_display);
    if (!gdpy)
@@ -354,8 +355,21 @@ gdi_create_display(HDC hDC, struct pipe_screen *screen,
 
    gdpy->hDC = hDC;
    gdpy->event_handler = event_handler;
+   gdpy->base.user_data = user_data;
 
-   gdpy->base.screen = screen;
+   winsys = gdi_create_sw_winsys();
+   if (!winsys) {
+      FREE(gdpy);
+      return NULL;
+   }
+
+   gdpy->base.screen = gdpy->event_handler->new_sw_screen(&gdpy->base, winsys);
+   if (!gdpy->base.screen) {
+      if (winsys->destroy)
+         winsys->destroy(winsys);
+      FREE(gdpy);
+      return NULL;
+   }
 
    gdpy->base.destroy = gdi_display_destroy;
    gdpy->base.get_param = gdi_display_get_param;
@@ -366,41 +380,20 @@ gdi_create_display(HDC hDC, struct pipe_screen *screen,
    return &gdpy->base;
 }
 
-struct native_probe *
-native_create_probe(EGLNativeDisplayType dpy)
-{
-   return NULL;
-}
-
-enum native_probe_result
-native_get_probe_result(struct native_probe *nprobe)
+static struct native_display *
+native_create_display(void *dpy, struct native_event_handler *event_handler,
+                      void *user_data)
 {
-   return NATIVE_PROBE_UNKNOWN;
+   return gdi_create_display((HDC) dpy, event_handler, user_data);
 }
 
-const char *
-native_get_name(void)
-{
-   return "GDI";
-}
+static const struct native_platform gdi_platform = {
+   "GDI", /* name */
+   native_create_display
+};
 
-struct native_display *
-native_create_display(EGLNativeDisplayType dpy,
-                      struct native_event_handler *event_handler)
+const struct native_platform *
+native_get_gdi_platform(void)
 {
-   struct sw_winsys *winsys;
-   struct pipe_screen *screen;
-
-   winsys = gdi_create_sw_winsys();
-   if (!winsys)
-      return NULL;
-
-   screen = native_create_sw_screen(winsys);
-   if (!screen) {
-      if (winsys->destroy)
-         winsys->destroy(winsys);
-      return NULL;
-   }
-
-   return gdi_create_display((HDC) dpy, screen, event_handler);
+   return &gdi_platform;
 }
index bfb4a9d25889bfe81f94b0e803185c487278d3ea..d4e8fbc9131fffa86553ff9dfb2c9a4291de5b06 100644 (file)
  * DEALINGS IN THE SOFTWARE.
  */
 
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
 #include "pipe/p_screen.h"
 #include "pipe/p_context.h"
 #include "util/u_debug.h"
@@ -655,10 +659,8 @@ kms_display_destroy(struct native_display *ndpy)
       kdpy->base.screen->destroy(kdpy->base.screen);
 
    if (kdpy->fd >= 0)
-      drmClose(kdpy->fd);
+      close(kdpy->fd);
 
-   if (kdpy->api && kdpy->api->destroy)
-      kdpy->api->destroy(kdpy->api);
    FREE(kdpy);
 }
 
@@ -669,50 +671,23 @@ static boolean
 kms_display_init_screen(struct native_display *ndpy)
 {
    struct kms_display *kdpy = kms_display(ndpy);
-   int fd;
-
-   fd = kdpy->fd;
-   if (fd >= 0) {
-      drmVersionPtr version = drmGetVersion(fd);
-      if (!version || strcmp(version->name, kdpy->api->driver_name)) {
-         if (version) {
-            _eglLog(_EGL_WARNING, "unknown driver name %s", version->name);
-            drmFreeVersion(version);
-         }
-         else {
-            _eglLog(_EGL_WARNING, "invalid fd %d", fd);
-         }
-
-         return FALSE;
-      }
-
-      drmFreeVersion(version);
-   }
-   else {
-      fd = drmOpen(kdpy->api->driver_name, NULL);
-   }
+   drmVersionPtr version;
 
-   if (fd < 0) {
-      _eglLog(_EGL_WARNING, "failed to open DRM device");
+   version = drmGetVersion(kdpy->fd);
+   if (!version) {
+      _eglLog(_EGL_WARNING, "invalid fd %d", kdpy->fd);
       return FALSE;
    }
 
-#if 0
-   if (drmSetMaster(fd)) {
-      _eglLog(_EGL_WARNING, "failed to become DRM master");
-      return FALSE;
-   }
-#endif
+   kdpy->base.screen = kdpy->event_handler->new_drm_screen(&kdpy->base,
+         version->name, kdpy->fd);;
+   drmFreeVersion(version);
 
-   kdpy->base.screen = kdpy->api->create_screen(kdpy->api, fd);
    if (!kdpy->base.screen) {
       _eglLog(_EGL_WARNING, "failed to create DRM screen");
-      drmClose(fd);
       return FALSE;
    }
 
-   kdpy->fd = fd;
-
    return TRUE;
 }
 
@@ -725,7 +700,7 @@ static struct native_display_modeset kms_display_modeset = {
 
 static struct native_display *
 kms_create_display(int fd, struct native_event_handler *event_handler,
-                   struct drm_api *api)
+                   void *user_data)
 {
    struct kms_display *kdpy;
 
@@ -733,16 +708,10 @@ kms_create_display(int fd, struct native_event_handler *event_handler,
    if (!kdpy)
       return NULL;
 
+   kdpy->fd = fd;
    kdpy->event_handler = event_handler;
+   kdpy->base.user_data = user_data;
 
-   kdpy->api = api;
-   if (!kdpy->api) {
-      _eglLog(_EGL_WARNING, "failed to create DRM API");
-      FREE(kdpy);
-      return NULL;
-   }
-
-   kdpy->fd = fd;
    if (!kms_display_init_screen(&kdpy->base)) {
       kms_display_destroy(&kdpy->base);
       return NULL;
@@ -778,53 +747,31 @@ kms_create_display(int fd, struct native_event_handler *event_handler,
    return &kdpy->base;
 }
 
-struct native_probe *
-native_create_probe(EGLNativeDisplayType dpy)
-{
-   return NULL;
-}
-
-enum native_probe_result
-native_get_probe_result(struct native_probe *nprobe)
-{
-   return NATIVE_PROBE_UNKNOWN;
-}
-
-/* the api is destroyed with the native display */
-static struct drm_api *drm_api;
-
-const char *
-native_get_name(void)
+static struct native_display *
+native_create_display(void *dpy, struct native_event_handler *event_handler,
+                      void *user_data)
 {
-   static char kms_name[32];
-
-   if (!drm_api)
-      drm_api = drm_api_create();
+   int fd;
 
-   if (drm_api)
-      util_snprintf(kms_name, sizeof(kms_name), "KMS/%s", drm_api->name);
-   else
-      util_snprintf(kms_name, sizeof(kms_name), "KMS");
+   if (dpy) {
+      fd = dup((int) pointer_to_intptr(dpy));
+   }
+   else {
+      fd = open("/dev/dri/card0", O_RDWR);
+   }
+   if (fd < 0)
+      return NULL;
 
-   return kms_name;
+   return kms_create_display(fd, event_handler, user_data);
 }
 
-struct native_display *
-native_create_display(EGLNativeDisplayType dpy,
-                      struct native_event_handler *event_handler)
-{
-   struct native_display *ndpy = NULL;
-   int fd;
-
-   if (!drm_api)
-      drm_api = drm_api_create();
-
-   if (drm_api) {
-      /* well, this makes fd 0 being ignored */
-      fd = (dpy != EGL_DEFAULT_DISPLAY) ?
-         (int) pointer_to_intptr((void *) dpy) : -1;
-      ndpy = kms_create_display(fd, event_handler, drm_api);
-   }
+static const struct native_platform kms_platform = {
+   "KMS", /* name */
+   native_create_display
+};
 
-   return ndpy;
+const struct native_platform *
+native_get_kms_platform(void)
+{
+   return &kms_platform;
 }
index d69c8d38c83ba65cae4b80bb4458b6c52e045c7d..cd8e4ff0b2dddfa90a6ce9dce4f320d2edc94c8e 100644 (file)
@@ -32,7 +32,7 @@
 #include "pipe/p_compiler.h"
 #include "util/u_format.h"
 #include "pipe/p_state.h"
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drm_driver.h"
 
 #include "common/native.h"
 #include "common/native_helper.h"
@@ -53,7 +53,6 @@ struct kms_display {
    struct native_event_handler *event_handler;
 
    int fd;
-   struct drm_api *api;
    drmModeResPtr resources;
    struct kms_config *config;
 
index 1ed2afd3458cf2af274603e878089fc8ef3855f2..809a0987e55933c83470c1b13033fc31806acf26 100644 (file)
@@ -16,6 +16,8 @@
 
 #include "glxinit.h"
 
+#ifdef GLX_DIRECT_RENDERING
+
 typedef struct GLXGenericGetString
 {
    CARD8 reqType;
@@ -183,9 +185,11 @@ FreeScreenConfigs(__GLXdisplayPrivate * priv)
    GLint i, screens;
 
    /* Free screen configuration information */
-   psc = priv->screenConfigs;
    screens = ScreenCount(priv->dpy);
-   for (i = 0; i < screens; i++, psc++) {
+   for (i = 0; i < screens; i++) {
+      psc = priv->screenConfigs[i];
+      if (!psc)
+         continue;
       if (psc->configs) {
          _gl_context_modes_destroy(psc->configs);
          psc->configs = NULL;   /* NOTE: just for paranoia */
@@ -502,15 +506,15 @@ createConfigsFromProperties(Display * dpy, int nvisuals, int nprops,
 }
 
 static GLboolean
-getVisualConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
+getVisualConfigs(__GLXscreenConfigs *psc,
+                 __GLXdisplayPrivate *priv, int screen)
 {
    xGLXGetVisualConfigsReq *req;
-   __GLXscreenConfigs *psc;
    xGLXGetVisualConfigsReply reply;
+   Display *dpy = priv->dpy;
 
    LockDisplay(dpy);
 
-   psc = priv->screenConfigs + screen;
    psc->visuals = NULL;
    GetReq(GLXGetVisualConfigs, req);
    req->reqType = priv->majorOpcode;
@@ -531,15 +535,14 @@ getVisualConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
 }
 
 static GLboolean
-getFBConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
+getFBConfigs(__GLXscreenConfigs *psc, __GLXdisplayPrivate *priv, int screen)
 {
    xGLXGetFBConfigsReq *fb_req;
    xGLXGetFBConfigsSGIXReq *sgi_req;
    xGLXVendorPrivateWithReplyReq *vpreq;
    xGLXGetFBConfigsReply reply;
-   __GLXscreenConfigs *psc;
+   Display *dpy = priv->dpy;
 
-   psc = priv->screenConfigs + screen;
    psc->serverGLXexts =
       __glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS);
 
@@ -578,6 +581,32 @@ getFBConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
    return psc->configs != NULL;
 }
 
+_X_HIDDEN Bool
+glx_screen_init(__GLXscreenConfigs *psc,
+               int screen, __GLXdisplayPrivate * priv)
+{
+   /* Initialize per screen dynamic client GLX extensions */
+   psc->ext_list_first_time = GL_TRUE;
+   psc->scr = screen;
+   psc->dpy = priv->dpy;
+
+   getVisualConfigs(psc, priv, screen);
+   getFBConfigs(psc, priv, screen);
+
+   return GL_TRUE;
+}
+
+static __GLXscreenConfigs *
+createIndirectScreen()
+{
+   __GLXscreenConfigs *psc;
+
+   psc = Xmalloc(sizeof *psc);
+   memset(psc, 0, sizeof *psc);
+
+   return psc;
+}
+
 static GLboolean
 AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
 {
@@ -588,12 +617,10 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
     ** First allocate memory for the array of per screen configs.
     */
    screens = ScreenCount(dpy);
-   psc = (__GLXscreenConfigs *) Xmalloc(screens * sizeof(__GLXscreenConfigs));
-   if (!psc) {
+   priv->screenConfigs = Xmalloc(screens * sizeof *priv->screenConfigs);
+   if (!priv->screenConfigs) {
       return GL_FALSE;
    }
-   memset(psc, 0, screens * sizeof(__GLXscreenConfigs));
-   priv->screenConfigs = psc;
 
    priv->serverGLXversion =
       __glXQueryServerString(dpy, priv->majorOpcode, 0, GLX_VERSION);
@@ -602,11 +629,12 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
       return GL_FALSE;
    }
 
-   for (i = 0; i < screens; i++, psc++) {
-      getFBConfigs(dpy, priv, i);
-      getVisualConfigs(dpy, priv, i);
-      psc->scr = i;
-      psc->dpy = dpy;
+   for (i = 0; i < screens; i++) {
+      psc = createIndirectScreen();
+      if (!psc)
+         return GL_FALSE;
+      glx_screen_init(psc, i, priv);
+      priv->screenConfigs[i] = psc;
    }
 
    SyncHandle();
@@ -680,3 +708,5 @@ __glXInitialize(Display * dpy)
 
    return dpyPriv;
 }
+
+#endif /* GLX_DIRECT_RENDERING */
index 3f802dd713f0d2be8393b11bacaeeab8cf41af7a..1be1e42468c2c49d4533609b3f2421f63ba9379f 100644 (file)
 #include "pipe/p_screen.h"
 #include "pipe/p_context.h"
 #include "pipe/p_state.h"
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drm_driver.h"
 #include "egllog.h"
 
 #include "native_x11.h"
 #include "x11_screen.h"
 
+#ifdef GLX_DIRECT_RENDERING
+
 enum dri2_surface_type {
    DRI2_SURFACE_TYPE_WINDOW,
    DRI2_SURFACE_TYPE_PIXMAP,
@@ -50,7 +52,6 @@ struct dri2_display {
 
    struct native_event_handler *event_handler;
 
-   struct drm_api *api;
    struct x11_screen *xscr;
    int xscr_number;
    const char *dri_driver;
@@ -662,8 +663,6 @@ dri2_display_destroy(struct native_display *ndpy)
       x11_screen_destroy(dri2dpy->xscr);
    if (dri2dpy->own_dpy)
       XCloseDisplay(dri2dpy->dpy);
-   if (dri2dpy->api && dri2dpy->api->destroy)
-      dri2dpy->api->destroy(dri2dpy->api);
    FREE(dri2dpy);
 }
 
@@ -695,7 +694,6 @@ static boolean
 dri2_display_init_screen(struct native_display *ndpy)
 {
    struct dri2_display *dri2dpy = dri2_display(ndpy);
-   const char *driver = dri2dpy->api->name;
    int fd;
 
    if (!x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_DRI2) ||
@@ -706,19 +704,15 @@ dri2_display_init_screen(struct native_display *ndpy)
 
    dri2dpy->dri_driver = x11_screen_probe_dri2(dri2dpy->xscr,
          &dri2dpy->dri_major, &dri2dpy->dri_minor);
-   if (!dri2dpy->dri_driver || !driver ||
-       strcmp(dri2dpy->dri_driver, driver) != 0) {
-      _eglLog(_EGL_WARNING, "Driver mismatch: %s != %s",
-            dri2dpy->dri_driver, dri2dpy->api->name);
-      return FALSE;
-   }
 
    fd = x11_screen_enable_dri2(dri2dpy->xscr,
          dri2_display_invalidate_buffers, &dri2dpy->base);
    if (fd < 0)
       return FALSE;
 
-   dri2dpy->base.screen = dri2dpy->api->create_screen(dri2dpy->api, fd);
+   dri2dpy->base.screen =
+      dri2dpy->event_handler->new_drm_screen(&dri2dpy->base,
+            dri2dpy->dri_driver, fd);
    if (!dri2dpy->base.screen) {
       _eglLog(_EGL_WARNING, "failed to create DRM screen");
       return FALSE;
@@ -741,9 +735,9 @@ dri2_display_hash_table_compare(void *key1, void *key2)
 }
 
 struct native_display *
-x11_create_dri2_display(EGLNativeDisplayType dpy,
+x11_create_dri2_display(Display *dpy,
                         struct native_event_handler *event_handler,
-                        struct drm_api *api)
+                        void *user_data)
 {
    struct dri2_display *dri2dpy;
 
@@ -752,7 +746,7 @@ x11_create_dri2_display(EGLNativeDisplayType dpy,
       return NULL;
 
    dri2dpy->event_handler = event_handler;
-   dri2dpy->api = api;
+   dri2dpy->base.user_data = user_data;
 
    dri2dpy->dpy = dpy;
    if (!dri2dpy->dpy) {
@@ -792,3 +786,15 @@ x11_create_dri2_display(EGLNativeDisplayType dpy,
 
    return &dri2dpy->base;
 }
+
+#else /* GLX_DIRECT_RENDERING */
+
+struct native_display *
+x11_create_dri2_display(Display *dpy,
+                        struct native_event_handler *event_handler,
+                        void *user_data)
+{
+   return NULL;
+}
+
+#endif /* GLX_DIRECT_RENDERING */
index b6d51bbf9fbe3063b1881fcc116b1e57fb02830d..37c8b01541f65160be70d8189ec6f5b7b71013f1 100644 (file)
  * DEALINGS IN THE SOFTWARE.
  */
 
-#include <string.h>
 #include "util/u_debug.h"
 #include "util/u_memory.h"
 #include "util/u_string.h"
-#include "state_tracker/drm_api.h"
 #include "egllog.h"
 
 #include "native_x11.h"
-#include "x11_screen.h"
 
-#define X11_PROBE_MAGIC 0x11980BE /* "X11PROBE" */
-
-static struct drm_api *api;
-
-static void
-x11_probe_destroy(struct native_probe *nprobe)
-{
-   if (nprobe->data)
-      FREE(nprobe->data);
-   FREE(nprobe);
-}
-
-struct native_probe *
-native_create_probe(EGLNativeDisplayType dpy)
-{
-   struct native_probe *nprobe;
-   struct x11_screen *xscr;
-   int scr;
-   const char *driver_name = NULL;
-   Display *xdpy;
-
-   nprobe = CALLOC_STRUCT(native_probe);
-   if (!nprobe)
-      return NULL;
-
-   xdpy = dpy;
-   if (!xdpy) {
-      xdpy = XOpenDisplay(NULL);
-      if (!xdpy) {
-         FREE(nprobe);
-         return NULL;
-      }
-   }
-
-   scr = DefaultScreen(xdpy);
-   xscr = x11_screen_create(xdpy, scr);
-   if (xscr) {
-      if (x11_screen_support(xscr, X11_SCREEN_EXTENSION_DRI2)) {
-         driver_name = x11_screen_probe_dri2(xscr, NULL, NULL);
-         if (driver_name)
-            nprobe->data = strdup(driver_name);
-      }
-
-      x11_screen_destroy(xscr);
-   }
-
-   if (xdpy != dpy)
-      XCloseDisplay(xdpy);
-
-   nprobe->magic = X11_PROBE_MAGIC;
-   nprobe->display = dpy;
-
-   nprobe->destroy = x11_probe_destroy;
-
-   return nprobe;
-}
-
-enum native_probe_result
-native_get_probe_result(struct native_probe *nprobe)
-{
-   if (!nprobe || nprobe->magic != X11_PROBE_MAGIC)
-      return NATIVE_PROBE_UNKNOWN;
-
-   if (!api)
-      api = drm_api_create();
-
-   /* this is a software driver */
-   if (!api)
-      return NATIVE_PROBE_SUPPORTED;
-
-   /* the display does not support DRI2 or the driver mismatches */
-   if (!nprobe->data || strcmp(api->name, (const char *) nprobe->data) != 0)
-      return NATIVE_PROBE_FALLBACK;
-
-   return NATIVE_PROBE_EXACT;
-}
-
-const char *
-native_get_name(void)
-{
-   static char x11_name[32];
-
-   if (!api)
-      api = drm_api_create();
-
-   if (api)
-      util_snprintf(x11_name, sizeof(x11_name), "X11/%s", api->name);
-   else
-      util_snprintf(x11_name, sizeof(x11_name), "X11");
-
-   return x11_name;
-}
-
-struct native_display *
-native_create_display(EGLNativeDisplayType dpy,
-                      struct native_event_handler *event_handler)
+static struct native_display *
+native_create_display(void *dpy, struct native_event_handler *event_handler,
+                      void *user_data)
 {
    struct native_display *ndpy = NULL;
    boolean force_sw;
 
-   if (!api)
-      api = drm_api_create();
-
    force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE);
-   if (api && !force_sw) {
-      ndpy = x11_create_dri2_display(dpy, event_handler, api);
+   if (!force_sw) {
+      ndpy = x11_create_dri2_display((Display *) dpy,
+            event_handler, user_data);
    }
 
    if (!ndpy) {
       EGLint level = (force_sw) ? _EGL_INFO : _EGL_WARNING;
 
       _eglLog(level, "use software fallback");
-      ndpy = x11_create_ximage_display(dpy, event_handler);
+      ndpy = x11_create_ximage_display((Display *) dpy,
+            event_handler, user_data);
    }
 
    return ndpy;
 }
+
+static const struct native_platform x11_platform = {
+   "X11", /* name */
+   native_create_display
+};
+
+const struct native_platform *
+native_get_x11_platform(void)
+{
+   return &x11_platform;
+}
index 1678403b45974e3db6f9ee06c86a20df0041eeb0..0b47837e1b5394ba6251e747e39ae4aec3487a5c 100644 (file)
 #ifndef _NATIVE_X11_H_
 #define _NATIVE_X11_H_
 
-#include "state_tracker/drm_api.h"
 #include "common/native.h"
 
 struct native_display *
-x11_create_ximage_display(EGLNativeDisplayType dpy,
-                          struct native_event_handler *event_handler);
+x11_create_ximage_display(Display *dpy,
+                          struct native_event_handler *event_handler,
+                          void *user_data);
 
 struct native_display *
-x11_create_dri2_display(EGLNativeDisplayType dpy,
+x11_create_dri2_display(Display *dpy,
                         struct native_event_handler *event_handler,
-                        struct drm_api *api);
+                        void *user_data);
 
 #endif /* _NATIVE_X11_H_ */
index 45679fc9b4e5f5dd08a4102f7aba72685c41b4c6..4b32f6e36e0490a4d7f4d00186b3b9576c8d3b0b 100644 (file)
@@ -441,8 +441,9 @@ ximage_display_destroy(struct native_display *ndpy)
 }
 
 struct native_display *
-x11_create_ximage_display(EGLNativeDisplayType dpy,
-                          struct native_event_handler *event_handler)
+x11_create_ximage_display(Display *dpy,
+                          struct native_event_handler *event_handler,
+                          void *user_data)
 {
    struct ximage_display *xdpy;
    struct sw_winsys *winsys = NULL;
@@ -462,6 +463,7 @@ x11_create_ximage_display(EGLNativeDisplayType dpy,
    }
 
    xdpy->event_handler = event_handler;
+   xdpy->base.user_data = user_data;
 
    xdpy->xscr_number = DefaultScreen(xdpy->dpy);
    xdpy->xscr = x11_screen_create(xdpy->dpy, xdpy->xscr_number);
@@ -472,7 +474,8 @@ x11_create_ximage_display(EGLNativeDisplayType dpy,
    if (!winsys)
       goto fail;
 
-   xdpy->base.screen = native_create_sw_screen(winsys);
+   xdpy->base.screen =
+      xdpy->event_handler->new_sw_screen(&xdpy->base, winsys);
    if (!xdpy->base.screen)
       goto fail;
 
index 6bdff26ec08e198eae2b950b08634d08ce8b0df4..bc6482ab15da9e06c855c0a27d051649cf615366 100644 (file)
 #include "glxinit.h"
 
 struct x11_screen {
+#ifdef GLX_DIRECT_RENDERING
    /* dummy base class */
    struct __GLXDRIdisplayRec base;
+#endif
 
    Display *dpy;
    int number;
@@ -103,15 +105,19 @@ x11_screen_destroy(struct x11_screen *xscr)
    if (xscr->dri_device)
       Xfree(xscr->dri_device);
 
+#ifdef GLX_DIRECT_RENDERING
    /* xscr->glx_dpy will be destroyed with the X display */
    if (xscr->glx_dpy)
       xscr->glx_dpy->dri2Display = NULL;
+#endif
 
    if (xscr->visuals)
       XFree(xscr->visuals);
    FREE(xscr);
 }
 
+#ifdef GLX_DIRECT_RENDERING
+
 static boolean
 x11_screen_init_dri2(struct x11_screen *xscr)
 {
@@ -133,6 +139,8 @@ x11_screen_init_glx(struct x11_screen *xscr)
    return (xscr->glx_dpy != NULL);
 }
 
+#endif /* GLX_DIRECT_RENDERING */
+
 /**
  * Return true if the screen supports the extension.
  */
@@ -145,12 +153,14 @@ x11_screen_support(struct x11_screen *xscr, enum x11_screen_extension ext)
    case X11_SCREEN_EXTENSION_XSHM:
       supported = XShmQueryExtension(xscr->dpy);
       break;
+#ifdef GLX_DIRECT_RENDERING
    case X11_SCREEN_EXTENSION_GLX:
       supported = x11_screen_init_glx(xscr);
       break;
    case X11_SCREEN_EXTENSION_DRI2:
       supported = x11_screen_init_dri2(xscr);
       break;
+#endif
    default:
       break;
    }
@@ -176,6 +186,39 @@ x11_screen_get_visuals(struct x11_screen *xscr, int *num_visuals)
    return xscr->visuals;
 }
 
+/**
+ * Return the depth of a drawable.
+ *
+ * Unlike other drawable functions, the drawable needs not be a DRI2 drawable.
+ */
+uint
+x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable)
+{
+   unsigned int depth;
+
+   if (drawable != xscr->last_drawable) {
+      Window root;
+      int x, y;
+      unsigned int w, h, border;
+      Status ok;
+
+      ok = XGetGeometry(xscr->dpy, drawable, &root,
+            &x, &y, &w, &h, &border, &depth);
+      if (!ok)
+         depth = 0;
+
+      xscr->last_drawable = drawable;
+      xscr->last_depth = depth;
+   }
+   else {
+      depth = xscr->last_depth;
+   }
+
+   return depth;
+}
+
+#ifdef GLX_DIRECT_RENDERING
+
 /**
  * Return the GLX fbconfigs.
  */
@@ -183,7 +226,7 @@ const __GLcontextModes *
 x11_screen_get_glx_configs(struct x11_screen *xscr)
 {
    return (x11_screen_init_glx(xscr))
-      ? xscr->glx_dpy->screenConfigs[xscr->number].configs
+      ? xscr->glx_dpy->screenConfigs[xscr->number]->configs
       : NULL;
 }
 
@@ -194,7 +237,7 @@ const __GLcontextModes *
 x11_screen_get_glx_visuals(struct x11_screen *xscr)
 {
    return (x11_screen_init_glx(xscr))
-      ? xscr->glx_dpy->screenConfigs[xscr->number].visuals
+      ? xscr->glx_dpy->screenConfigs[xscr->number]->visuals
       : NULL;
 }
 
@@ -334,37 +377,6 @@ x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable,
    return (struct x11_drawable_buffer *) dri2bufs;
 }
 
-/**
- * Return the depth of a drawable.
- *
- * Unlike other drawable functions, the drawable needs not be a DRI2 drawable.
- */
-uint
-x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable)
-{
-   unsigned int depth;
-
-   if (drawable != xscr->last_drawable) {
-      Window root;
-      int x, y;
-      unsigned int w, h, border;
-      Status ok;
-
-      ok = XGetGeometry(xscr->dpy, drawable, &root,
-            &x, &y, &w, &h, &border, &depth);
-      if (!ok)
-         depth = 0;
-
-      xscr->last_drawable = drawable;
-      xscr->last_depth = depth;
-   }
-   else {
-      depth = xscr->last_depth;
-   }
-
-   return depth;
-}
-
 /**
  * Create a mode list of the given size.
  */
@@ -432,3 +444,5 @@ dri2InvalidateBuffers(Display *dpy, XID drawable)
 
    xscr->dri_invalidate_buffers(xscr, drawable, xscr->dri_user_data);
 }
+
+#endif /* GLX_DIRECT_RENDERING */
index a3c5ee1491e31ac128afb85f3ae050642ce141f4..bc0ef69ec6633c37458ed78f3952fb5ebac72bd6 100644 (file)
@@ -67,20 +67,18 @@ x11_screen_support(struct x11_screen *xscr, enum x11_screen_extension ext);
 const XVisualInfo *
 x11_screen_get_visuals(struct x11_screen *xscr, int *num_visuals);
 
+uint
+x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable);
+
+#ifdef GLX_DIRECT_RENDERING
+
+/* GLX */
 const __GLcontextModes *
 x11_screen_get_glx_configs(struct x11_screen *xscr);
 
 const __GLcontextModes *
 x11_screen_get_glx_visuals(struct x11_screen *xscr);
 
-const char *
-x11_screen_probe_dri2(struct x11_screen *xscr, int *major, int *minor);
-
-int
-x11_screen_enable_dri2(struct x11_screen *xscr,
-                       x11_drawable_invalidate_buffers invalidate_buffers,
-                       void *user_data);
-
 __GLcontextModes *
 x11_context_modes_create(unsigned count);
 
@@ -90,6 +88,15 @@ x11_context_modes_destroy(__GLcontextModes *modes);
 unsigned
 x11_context_modes_count(const __GLcontextModes *modes);
 
+/* DRI2 */
+const char *
+x11_screen_probe_dri2(struct x11_screen *xscr, int *major, int *minor);
+
+int
+x11_screen_enable_dri2(struct x11_screen *xscr,
+                       x11_drawable_invalidate_buffers invalidate_buffers,
+                       void *user_data);
+
 void
 x11_drawable_enable_dri2(struct x11_screen *xscr,
                          Drawable drawable, boolean on);
@@ -104,7 +111,6 @@ x11_drawable_get_buffers(struct x11_screen *xscr, Drawable drawable,
                          int *width, int *height, unsigned int *attachments,
                          boolean with_format, int num_ins, int *num_outs);
 
-uint
-x11_drawable_get_depth(struct x11_screen *xscr, Drawable drawable);
+#endif /* GLX_DIRECT_RENDERING */
 
 #endif /* _X11_SCREEN_H_ */
index 7c421dfcd4e028e314c90a8a1281ed398a84fbb7..c12dc71b86042b0409f2cc5b7cf9f53506c4c29a 100644 (file)
@@ -355,7 +355,7 @@ void image_destroy(struct vg_image *img)
    }
 
    pipe_sampler_view_reference(&img->sampler_view, NULL);
-   free(img);
+   FREE(img);
 }
 
 void image_clear(struct vg_image *img,
index 6d627b0e8da4029829bab416a93f8e63cee637d1..ef28ebd740c7919aecf4657e955313b8208e056a 100644 (file)
@@ -520,7 +520,7 @@ void mask_layer_destroy(struct vg_mask_layer *layer)
 
    vg_context_remove_object(ctx, VG_OBJECT_MASK, layer);
    pipe_resource_release(&layer->texture);
-   free(layer);
+   FREE(layer);
 }
 
 void mask_layer_fill(struct vg_mask_layer *layer,
index 05540e82752979e2f7297df179331789d2a25e76..2c0eb6b23d2464cd317ea684216b645906ba9ce3 100644 (file)
@@ -236,7 +236,7 @@ void paint_destroy(struct vg_paint *paint)
 
    free(paint->gradient.ramp_stopsi);
    free(paint->gradient.ramp_stops);
-   free(paint);
+   FREE(paint);
 }
 
 void paint_set_color(struct vg_paint *paint,
index 4fc23a7a278d2a7b936e754b505eb2379679db23..05f8b0d9979ed181c9319c8369592f1e068eb318 100644 (file)
@@ -218,7 +218,7 @@ void path_destroy(struct path *p)
    if (p->stroked.path)
       path_destroy(p->stroked.path);
 
-   free(p);
+   FREE(p);
 }
 
 VGbitfield path_capabilities(struct path *p)
index c40ea8675e5666793b167d2a61a18f8b476df429..8c023044c4504e0400a0d0957a618c35cbeaa300 100644 (file)
@@ -203,7 +203,7 @@ void renderer_destroy(struct renderer *ctx)
       ctx->fs = NULL;
    }
 #endif
-   free(ctx);
+   FREE(ctx);
 }
 
 void renderer_draw_quad(struct renderer *r,
index 6eef94ce7670e5384820cf28a5480d0f7eb7dba3..eab1349639c2881f41c651864ffd5b81c2b0736e 100644 (file)
@@ -68,7 +68,7 @@ struct shader * shader_create(struct vg_context *ctx)
 
 void shader_destroy(struct shader *shader)
 {
-   free(shader);
+   FREE(shader);
 }
 
 void shader_set_masking(struct shader *shader, VGboolean set)
index f43fe6ee4cbf3f88a3b57124af0184528f76cf25..53e6bfcf16b7072fe3b15eaad851936617d45114 100644 (file)
@@ -381,7 +381,7 @@ void shaders_cache_destroy(struct shaders_cache *sc)
    }
 
    cso_hash_delete(sc->hash);
-   free(sc);
+   FREE(sc);
 }
 
 void * shaders_cache_fill(struct shaders_cache *sc,
@@ -410,7 +410,7 @@ struct vg_shader * shader_create_from_text(struct pipe_context *pipe,
                                            const char *txt, int num_tokens,
                                            int type)
 {
-   struct vg_shader *shader = (struct vg_shader *)malloc(
+   struct vg_shader *shader = (struct vg_shader *)MALLOC(
       sizeof(struct vg_shader));
    struct tgsi_token *tokens = tokens_from_assembly(txt, num_tokens);
    struct pipe_shader_state state;
@@ -435,6 +435,6 @@ void vg_shader_destroy(struct vg_context *ctx, struct vg_shader *shader)
       cso_delete_fragment_shader(ctx->cso_context, shader->driver);
    else
       cso_delete_vertex_shader(ctx->cso_context, shader->driver);
-   free(shader->tokens);
-   free(shader);
+   FREE(shader->tokens);
+   FREE(shader);
 }
index f02db8949df3884307fac872545a98ab83200485..5cb25906027e9f9bdcb240f3b77be9e3d6e28987 100644 (file)
@@ -65,6 +65,32 @@ static void init_clear(struct vg_context *st)
    st->clear.fs =
       util_make_fragment_passthrough_shader(pipe);
 }
+
+/**
+ * A depth/stencil rb will be needed regardless of what the visual says.
+ */
+static boolean
+choose_depth_stencil_format(struct vg_context *ctx)
+{
+   struct pipe_screen *screen = ctx->pipe->screen;
+   enum pipe_format formats[] = {
+      PIPE_FORMAT_Z24_UNORM_S8_USCALED,
+      PIPE_FORMAT_S8_USCALED_Z24_UNORM,
+      PIPE_FORMAT_NONE
+   };
+   enum pipe_format *fmt;
+
+   for (fmt = formats; *fmt != PIPE_FORMAT_NONE; fmt++) {
+      if (screen->is_format_supported(screen, *fmt,
+               PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0))
+         break;
+   }
+
+   ctx->ds_format = *fmt;
+
+   return (ctx->ds_format != PIPE_FORMAT_NONE);
+}
+
 void vg_set_current_context(struct vg_context *ctx)
 {
    _vg_context = ctx;
@@ -81,6 +107,10 @@ struct vg_context * vg_create_context(struct pipe_context *pipe,
    ctx = CALLOC_STRUCT(vg_context);
 
    ctx->pipe = pipe;
+   if (!choose_depth_stencil_format(ctx)) {
+      FREE(ctx);
+      return NULL;
+   }
 
    ctx->dispatch = api_create_dispatch();
 
@@ -191,7 +221,7 @@ void vg_destroy_context(struct vg_context *ctx)
 
    api_destroy_dispatch(ctx->dispatch);
 
-   free(ctx);
+   FREE(ctx);
 }
 
 void vg_init_object(struct vg_object *obj, struct vg_context *ctx, enum vg_object_type type)
index 7b59ad512a0ecc19f2498b79a071b3504686c3b4..80a6c07c693eb28c5667f4071325bcfd367c5f4d 100644 (file)
@@ -94,6 +94,7 @@ struct vg_context
    struct mapi_table *dispatch;
 
    struct pipe_context *pipe;
+   enum pipe_format ds_format;
 
    struct {
       struct vg_state vg;
index 3b04816df04dfc8533040b92aa88e5356307e799..c2aa98b231cdece13b8fface160462914879f001 100644 (file)
@@ -388,7 +388,7 @@ destroy_renderbuffer(struct st_renderbuffer *strb)
 {
    pipe_surface_reference(&strb->surface, NULL);
    pipe_resource_reference(&strb->texture, NULL);
-   free(strb);
+   FREE(strb);
 }
 
 /**
@@ -448,11 +448,10 @@ vg_context_bind_framebuffers(struct st_context_iface *stctxi,
       /* free the existing fb */
       if (!stdrawi ||
           stfb->strb_att != strb_att ||
-          stfb->strb->format != stdrawi->visual->color_format ||
-          stfb->dsrb->format != stdrawi->visual->depth_stencil_format) {
+          stfb->strb->format != stdrawi->visual->color_format) {
          destroy_renderbuffer(stfb->strb);
          destroy_renderbuffer(stfb->dsrb);
-         free(stfb);
+         FREE(stfb);
 
          ctx->draw_buffer = NULL;
       }
@@ -472,14 +471,14 @@ vg_context_bind_framebuffers(struct st_context_iface *stctxi,
 
       stfb->strb = create_renderbuffer(stdrawi->visual->color_format);
       if (!stfb->strb) {
-         free(stfb);
+         FREE(stfb);
          return FALSE;
       }
 
-      stfb->dsrb = create_renderbuffer(stdrawi->visual->depth_stencil_format);
+      stfb->dsrb = create_renderbuffer(ctx->ds_format);
       if (!stfb->dsrb) {
-         free(stfb->strb);
-         free(stfb);
+         FREE(stfb->strb);
+         FREE(stfb);
          return FALSE;
       }
 
@@ -517,14 +516,6 @@ vg_api_get_current(struct st_api *stapi)
    return (ctx) ? &ctx->iface : NULL;
 }
 
-static boolean
-vg_api_is_visual_supported(struct st_api *stapi,
-                           const struct st_visual *visual)
-{
-   /* the impl requires a depth/stencil buffer */
-   return util_format_is_depth_and_stencil(visual->depth_stencil_format);
-}
-
 static st_proc_t
 vg_api_get_proc_address(struct st_api *stapi, const char *procname)
 {
@@ -539,7 +530,6 @@ vg_api_destroy(struct st_api *stapi)
 static const struct st_api vg_api = {
    vg_api_destroy,
    vg_api_get_proc_address,
-   vg_api_is_visual_supported,
    vg_api_create_context,
    vg_api_make_current,
    vg_api_get_current,
index f1a07bd863bf8f187dcc51c030ce0046bd3c4df1..26a907f205e7f8bbed34bb02ff7dcd5931c20f3d 100644 (file)
@@ -50,6 +50,7 @@
 #include <X11/extensions/dpms.h>
 #endif
 
+#include "state_tracker/drm_driver.h"
 #include "util/u_inlines.h"
 #include "util/u_rect.h"
 
@@ -93,7 +94,8 @@ crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
     struct crtc_private *crtcp = crtc->driver_private;
     drmModeCrtcPtr drm_crtc = crtcp->drm_crtc;
     drmModeModeInfo drm_mode;
-    int i, ret, connector_id;
+    int i, ret;
+    unsigned int connector_id;
 
     for (i = 0; i < config->num_output; output = NULL, i++) {
        output = config->output[i];
index 4e01bd103066bb1ea671b64f6af0ab5b362f3d08..704aed6a82cd294ba2c4166e2500b2ca56f6b95a 100644 (file)
@@ -42,6 +42,8 @@
 
 #include "util/u_format.h"
 
+#include "state_tracker/drm_driver.h"
+
 /* Make all the #if cases in the code esier to read */
 #ifndef DRI2INFOREC_VERSION
 #define DRI2INFOREC_VERSION 1
index a7e57634aec0aa9b6fcede624817a0f3c63578f3..e10ff2f95087053eb075ff222178d2178a8c90bc 100644 (file)
@@ -51,6 +51,7 @@
 
 #include <pciaccess.h>
 
+#include "state_tracker/drm_driver.h"
 #include "pipe/p_context.h"
 #include "xorg_tracker.h"
 #include "xorg_winsys.h"
@@ -189,6 +190,7 @@ drv_crtc_resize(ScrnInfoPtr pScrn, int width, int height)
 {
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
     modesettingPtr ms = modesettingPTR(pScrn);
+    CustomizerPtr cust = ms->cust;
     ScreenPtr pScreen = pScrn->pScreen;
     int old_width, old_height;
     PixmapPtr rootPixmap;
@@ -197,6 +199,16 @@ drv_crtc_resize(ScrnInfoPtr pScrn, int width, int height)
     if (width == pScrn->virtualX && height == pScrn->virtualY)
        return TRUE;
 
+    if (cust && cust->winsys_check_fb_size &&
+       !cust->winsys_check_fb_size(cust, width*pScrn->bitsPerPixel / 8,
+                                   height)) {
+       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+                  "Requested framebuffer size %dx%dx%d will not fit "
+                  "in display memory.\n",
+                  width, height, pScrn->bitsPerPixel);
+       return FALSE;
+    }
+
     old_width = pScrn->virtualX;
     old_height = pScrn->virtualY;
     pScrn->virtualX = width;
@@ -269,39 +281,19 @@ drv_init_drm(ScrnInfoPtr pScrn)
            );
 
 
-       ms->api = drm_api_create();
-       ms->fd = drmOpen(ms->api ? ms->api->driver_name : NULL, BusID);
+       ms->fd = drmOpen(driver_descriptor.driver_name, BusID);
+       ms->isMaster = TRUE;
        xfree(BusID);
 
        if (ms->fd >= 0)
            return TRUE;
 
-       if (ms->api && ms->api->destroy)
-           ms->api->destroy(ms->api);
-
-       ms->api = NULL;
-
        return FALSE;
     }
 
     return TRUE;
 }
 
-static Bool
-drv_close_drm(ScrnInfoPtr pScrn)
-{
-    modesettingPtr ms = modesettingPTR(pScrn);
-
-    if (ms->api && ms->api->destroy)
-       ms->api->destroy(ms->api);
-    ms->api = NULL;
-
-    drmClose(ms->fd);
-    ms->fd = -1;
-
-    return TRUE;
-}
-
 static Bool
 drv_init_resource_management(ScrnInfoPtr pScrn)
 {
@@ -316,18 +308,11 @@ drv_init_resource_management(ScrnInfoPtr pScrn)
     if (ms->screen || ms->kms)
        return TRUE;
 
-    if (ms->api) {
-       ms->screen = ms->no3D ? NULL :
-           ms->api->create_screen(ms->api, ms->fd);
-
-       if (ms->screen)
-           return TRUE;
-
-       if (ms->api->destroy)
-           ms->api->destroy(ms->api);
+    if (!ms->no3D)
+       ms->screen = driver_descriptor.create_screen(ms->fd);
 
-       ms->api = NULL;
-    }
+    if (ms->screen)
+       return TRUE;
 
 #ifdef HAVE_LIBKMS
     if (!kms_create(ms->fd, &ms->kms))
@@ -337,25 +322,6 @@ drv_init_resource_management(ScrnInfoPtr pScrn)
     return FALSE;
 }
 
-static Bool
-drv_close_resource_management(ScrnInfoPtr pScrn)
-{
-    modesettingPtr ms = modesettingPTR(pScrn);
-
-    if (ms->screen) {
-       assert(ms->ctx == NULL);
-       ms->screen->destroy(ms->screen);
-    }
-    ms->screen = NULL;
-
-#ifdef HAVE_LIBKMS
-    if (ms->kms)
-       kms_destroy(&ms->kms);
-#endif
-
-    return TRUE;
-}
-
 static void
 drv_cleanup_fences(ScrnInfoPtr pScrn)
 {
@@ -380,8 +346,8 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
     rgb defaultWeight = { 0, 0, 0 };
     EntityInfoPtr pEnt;
     EntPtr msEnt = NULL;
-    int max_width, max_height;
     CustomizerPtr cust;
+    Bool use3D;
 
     if (pScrn->numEntities != 1)
        return FALSE;
@@ -433,10 +399,22 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
     }
 
     ms->fd = -1;
-    ms->api = NULL;
     if (!drv_init_drm(pScrn))
        return FALSE;
 
+    use3D = cust ? !cust->no_3d : TRUE;
+    ms->from_3D = xf86GetOptValBool(ms->Options, OPTION_3D_ACCEL,
+                                   &use3D) ?
+       X_CONFIG : X_PROBED;
+
+    ms->no3D = !use3D;
+
+    if (!drv_init_resource_management(pScrn)) {
+       xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not init "
+                                              "Gallium3D or libKMS.");
+       return FALSE;
+    }
+
     pScrn->monitor = pScrn->confScreen->monitor;
     pScrn->progClock = TRUE;
     pScrn->rgbBits = 8;
@@ -475,9 +453,36 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
     xf86CrtcConfigInit(pScrn, &crtc_config_funcs);
     xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
 
-    max_width = 2048;  /* A very low default */
-    max_height = 2048; /* see screen_init */
-    xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height);
+    /* get max width and height */
+    {
+       drmModeResPtr res;
+       int max_width, max_height;
+
+       res = drmModeGetResources(ms->fd);
+       max_width = res->max_width;
+       max_height = res->max_height;
+
+       if (ms->screen) {
+           int max;
+
+           max = ms->screen->get_param(ms->screen,
+                                       PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
+           max = 1 << (max - 1);
+           max_width = max < max_width ? max : max_width;
+           max_height = max < max_height ? max : max_height;
+       }
+
+       xf86CrtcSetSizeRange(pScrn, res->min_width,
+                            res->min_height, max_width, max_height);
+       xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+                  "Min width %d, Max Width %d.\n",
+                  res->min_width, max_width);
+       xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+                  "Min height %d, Max Height %d.\n",
+                  res->min_height, max_height);
+       drmModeFreeResources(res);
+    }
+
 
     if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) {
        ms->SWCursor = TRUE;
@@ -486,6 +491,9 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
     xorg_crtc_init(pScrn);
     xorg_output_init(pScrn);
 
+    if (cust && cust->winsys_pre_init && !cust->winsys_pre_init(cust, ms->fd))
+       return FALSE;
+
     if (!xf86InitialConfiguration(pScrn, TRUE)) {
        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
        return FALSE;
@@ -639,60 +647,46 @@ drv_create_screen_resources(ScreenPtr pScreen)
     return ret;
 }
 
+static Bool
+drv_set_master(ScrnInfoPtr pScrn)
+{
+    modesettingPtr ms = modesettingPTR(pScrn);
+
+    if (!ms->isMaster && drmSetMaster(ms->fd) != 0) {
+       if (errno == EINVAL) {
+           xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                      "drmSetMaster failed: 2.6.29 or newer kernel required for "
+                      "multi-server DRI\n");
+       } else {
+           xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+                      "drmSetMaster failed: %s\n", strerror(errno));
+       }
+       return FALSE;
+    }
+
+    ms->isMaster = TRUE;
+    return TRUE;
+}
+
+
 static Bool
 drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
 {
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     modesettingPtr ms = modesettingPTR(pScrn);
-    unsigned max_width, max_height;
     VisualPtr visual;
     CustomizerPtr cust = ms->cust;
     MessageType from_st;
     MessageType from_dt;
-    MessageType from_3D;
-    Bool use3D;
 
-    if (!drv_init_drm(pScrn)) {
-       FatalError("Could not init DRM");
+    if (!drv_set_master(pScrn))
        return FALSE;
-    }
-
-    use3D = cust ? !cust->no_3d : TRUE;
-    from_3D = xf86GetOptValBool(ms->Options, OPTION_3D_ACCEL,
-                               &use3D) ?
-       X_CONFIG : X_PROBED;
-
-    ms->no3D = !use3D;
-
-    if (!drv_init_resource_management(pScrn)) {
-       FatalError("Could not init resource management (!pipe_screen && !libkms)");
-       return FALSE;
-    }
 
     if (!drv_init_front_buffer_functions(pScrn)) {
        FatalError("Could not init front buffer manager");
        return FALSE;
     }
 
-    /* get max width and height */
-    {
-       drmModeResPtr res;
-       res = drmModeGetResources(ms->fd);
-       max_width = res->max_width;
-       max_height = res->max_height;
-       drmModeFreeResources(res);
-    }
-
-    if (ms->screen) {
-       int max;
-       max = ms->screen->get_param(ms->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
-       max = 1 << (max - 1);
-       max_width = max < max_width ? max : max_width;
-       max_height = max < max_height ? max : max_height;
-    }
-
-    xf86CrtcSetSizeRange(pScrn, 1, 1, max_width, max_height);
-
     pScrn->pScreen = pScreen;
 
     /* HW dependent - FIXME */
@@ -745,7 +739,7 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     ms->debug_fallback = xf86ReturnOptValBool(ms->Options, OPTION_DEBUG_FALLBACK, ms->accelerate_2d);
 
     if (cust && cust->winsys_screen_init)
-       cust->winsys_screen_init(cust, ms->fd);
+       cust->winsys_screen_init(cust);
 
     ms->swapThrottling = cust ?  cust->swap_throttling : TRUE;
     from_st = xf86GetOptValBool(ms->Options, OPTION_THROTTLE_SWAP,
@@ -776,7 +770,7 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Fallback debugging is %s\n",
               ms->debug_fallback ? "enabled" : "disabled");
 #ifdef DRI2
-    xf86DrvMsg(pScrn->scrnIndex, from_3D, "3D Acceleration is %s\n",
+    xf86DrvMsg(pScrn->scrnIndex, ms->from_3D, "3D Acceleration is %s\n",
               ms->screen ? "enabled" : "disabled");
 #else
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D Acceleration is disabled\n");
@@ -879,6 +873,7 @@ drv_leave_vt(int scrnIndex, int flags)
        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
                   "drmDropMaster failed: %s\n", strerror(errno));
 
+    ms->isMaster = FALSE;
     pScrn->vtSema = FALSE;
 }
 
@@ -892,16 +887,8 @@ drv_enter_vt(int scrnIndex, int flags)
     modesettingPtr ms = modesettingPTR(pScrn);
     CustomizerPtr cust = ms->cust;
 
-    if (drmSetMaster(ms->fd)) {
-       if (errno == EINVAL) {
-           xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-                      "drmSetMaster failed: 2.6.29 or newer kernel required for "
-                      "multi-server DRI\n");
-       } else {
-           xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
-                      "drmSetMaster failed: %s\n", strerror(errno));
-       }
-    }
+    if (!drv_set_master(pScrn))
+       return FALSE;
 
     if (!ms->create_front_buffer(pScrn))
        return FALSE;
@@ -969,12 +956,9 @@ drv_close_screen(int scrnIndex, ScreenPtr pScreen)
        drv_leave_vt(scrnIndex, 0);
     }
 
-    drv_close_resource_management(pScrn);
-
-    drv_close_drm(pScrn);
-
     pScrn->vtSema = FALSE;
     pScreen->CloseScreen = ms->CloseScreen;
+
     return (*pScreen->CloseScreen) (scrnIndex, pScreen);
 }
 
index bd8466830008c8e26a258ed00a639783ea0262df..6b2c80fbca60a1607d1098e62786b248d56e037b 100644 (file)
@@ -881,7 +881,6 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
 
        if (priv->tex) {
            struct pipe_subresource subdst, subsrc;
-           struct pipe_surface *src_surf;
 
            subdst.face = 0;
            subdst.level = 0;
index 3e5e6bd6a6e29a4d02a23dc9d69583869af63088..fe1aab3ab981675341bc24a68b35b92fe909da16 100644 (file)
@@ -642,7 +642,7 @@ void xorg_shaders_destroy(struct xorg_shaders *sc)
    cache_destroy(sc->r->cso, sc->fs_hash,
                  PIPE_SHADER_FRAGMENT);
 
-   free(sc);
+   FREE(sc);
 }
 
 static INLINE void *
index 056098f76b41f815807cf10ffdc72efc75fdce51..61206ed751ca9385c6d23e34c82b031c3f86f57c 100644 (file)
@@ -162,6 +162,15 @@ output_get_modes(xf86OutputPtr output)
 static int
 output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
 {
+    modesettingPtr ms = modesettingPTR(output->scrn);
+    CustomizerPtr cust = ms->cust;
+
+    if (cust && cust->winsys_check_fb_size &&
+       !cust->winsys_check_fb_size(cust, pMode->HDisplay *
+                                   output->scrn->bitsPerPixel / 8,
+                                   pMode->VDisplay))
+       return MODE_BAD;
+
     return MODE_OK;
 }
 
index df56ad1b155464c608f37df70674fe954a235f90..be1a9fda48d1f037655a05f9846d705903a6386a 100644 (file)
@@ -49,7 +49,6 @@
 #include "pipe/p_screen.h"
 #include "util/u_inlines.h"
 #include "util/u_debug.h"
-#include "state_tracker/drm_api.h"
 
 #define DRV_ERROR(msg) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg);
 
@@ -77,13 +76,17 @@ typedef struct _CustomizerRec
     Bool dirty_throttling;
     Bool swap_throttling;
     Bool no_3d;
-    Bool (*winsys_screen_init)(struct _CustomizerRec *cust, int fd);
+    Bool (*winsys_pre_init) (struct _CustomizerRec *cust, int fd);
+    Bool (*winsys_screen_init)(struct _CustomizerRec *cust);
     Bool (*winsys_screen_close)(struct _CustomizerRec *cust);
     Bool (*winsys_enter_vt)(struct _CustomizerRec *cust);
     Bool (*winsys_leave_vt)(struct _CustomizerRec *cust);
     void (*winsys_context_throttle)(struct _CustomizerRec *cust,
                                    struct pipe_context *pipe,
                                    enum xorg_throttling_reason reason);
+    Bool (*winsys_check_fb_size) (struct _CustomizerRec *cust,
+                                 unsigned long pitch,
+                                 unsigned long height);
 } CustomizerRec, *CustomizerPtr;
 
 typedef struct _modesettingRec
@@ -106,6 +109,8 @@ typedef struct _modesettingRec
     Bool dirtyThrottling;
     CloseScreenProcPtr CloseScreen;
     Bool no3D;
+    Bool from_3D;
+    Bool isMaster;
 
     /* Broken-out options. */
     OptionInfoPtr Options;
@@ -125,7 +130,6 @@ typedef struct _modesettingRec
     struct kms_bo *root_bo;
 
     /* gallium */
-    struct drm_api *api;
     struct pipe_screen *screen;
     struct pipe_context *ctx;
     boolean d_depth_bits_last;
diff --git a/src/gallium/targets/Makefile.egl b/src/gallium/targets/Makefile.egl
deleted file mode 100644 (file)
index 3158560..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-# src/gallium/winsys/drm/Makefile.egl
-
-# The driver Makefile should define
-#
-#   EGL_DRIVER_NAME, the name of the driver
-#   EGL_DRIVER_SOURCES, the sources of the driver
-#   EGL_DRIVER_LIBS, extra libraries needed by the driver
-#   EGL_DRIVER_PIPES, the pipe drivers of the driver
-#
-# before including this file.
-
-EGL_DRIVER_OBJECTS = $(EGL_DRIVER_SOURCES:.c=.o)
-
-common_LIBS = -ldrm -lm -ldl
-
-# ximage backend calls gallium_wrap_screen, which requires libidentity.a and
-# libtrace.a
-x11_ST = $(TOP)/src/gallium/state_trackers/egl/libeglx11.a \
-        $(TOP)/src/gallium/winsys/sw/xlib/libws_xlib.a \
-        $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
-        $(TOP)/src/gallium/drivers/identity/libidentity.a \
-        $(TOP)/src/gallium/drivers/trace/libtrace.a \
-        $(TOP)/src/gallium/drivers/rbug/librbug.a
-
-x11_LIBS = $(common_LIBS) -lX11 -lXext -lXfixes
-
-kms_ST = $(TOP)/src/gallium/state_trackers/egl/libeglkms.a
-kms_LIBS = $(common_LIBS)
-
-fbdev_ST = \
-       $(TOP)/src/gallium/state_trackers/egl/libeglfbdev.a \
-       $(TOP)/src/gallium/winsys/sw/fbdev/libfbdev.a \
-       $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
-       $(TOP)/src/gallium/drivers/identity/libidentity.a \
-       $(TOP)/src/gallium/drivers/trace/libtrace.a \
-       $(TOP)/src/gallium/drivers/rbug/librbug.a
-fbdev_LIBS = $(common_LIBS)
-
-ifeq ($(MESA_LLVM),1)
-x11_ST += $(TOP)/src/gallium/drivers/llvmpipe/libllvmpipe.a
-x11_LIBS += $(LLVM_LIBS)
-fbdev_ST += $(TOP)/src/gallium/drivers/llvmpipe/libllvmpipe.a
-fbdev_LIBS += $(LLVM_LIBS)
-LDFLAGS += $(LLVM_LDFLAGS)
-endif
-
-### Include directories
-INCLUDES = \
-       -I$(TOP)/include \
-       -I$(TOP)/src/gallium/include \
-       -I$(TOP)/src/gallium/auxiliary \
-       -I$(TOP)/src/gallium/drivers \
-       -I$(TOP)/src/gallium/winsys \
-       -I$(TOP)/src/egl/main \
-       $(LIBDRM_CFLAGS)
-
-##### RULES #####
-
-.c.o:
-       $(CC) -c $(INCLUDES) $(CFLAGS) $(EGL_DRIVER_DEFINES) $< -o $@
-
-
-##### TARGETS #####
-
-ifeq ($(EGL_DRIVER_NAME),swrast)
-EGL_PLATFORMS := $(filter-out kms, $(EGL_PLATFORMS))
-else
-EGL_PLATFORMS := $(filter-out fbdev, $(EGL_PLATFORMS))
-endif
-
-EGL_PLATFORM_DRIVERS = $(foreach plat, $(EGL_PLATFORMS), egl_$(plat)_$(EGL_DRIVER_NAME).so)
-
-EGL_PLATFORM_LIBS = $(foreach drv, $(EGL_PLATFORM_DRIVERS), $(TOP)/$(LIB_DIR)/egl/$(drv))
-
-default: $(EGL_PLATFORM_LIBS)
-
-$(EGL_PLATFORM_LIBS): $(TOP)/$(LIB_DIR)/egl/%.so: %.so
-       @$(INSTALL) -d $(TOP)/$(LIB_DIR)/egl
-       $(INSTALL) $< $(TOP)/$(LIB_DIR)/egl
-
-define mklib-egl
-$(MKLIB) -o $@ -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \
-       $(MKLIB_OPTIONS) $(EGL_DRIVER_OBJECTS) \
-       -Wl,--start-group $($(1)_ST) $(EGL_DRIVER_PIPES) \
-       $(GALLIUM_AUXILIARIES) -Wl,--end-group \
-       $($(1)_LIBS) $(EGL_DRIVER_LIBS) -L$(TOP)/$(LIB_DIR) -l$(EGL_LIB)
-endef
-
-egl_x11_$(EGL_DRIVER_NAME).so: $(EGL_DRIVER_OBJECTS) $(x11_ST) $(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) Makefile
-       $(call mklib-egl,x11)
-
-egl_kms_$(EGL_DRIVER_NAME).so: $(EGL_DRIVER_OBJECTS) $(kms_ST) $(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) Makefile
-       $(call mklib-egl,kms)
-
-egl_fbdev_$(EGL_DRIVER_NAME).so: $(EGL_DRIVER_OBJECTS) $(fbdev_ST) $(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) Makefile
-       $(call mklib-egl,fbdev)
-
-clean:
-       -rm -f $(EGL_DRIVER_OBJECTS)
-       -rm -f $(EGL_PLATFORM_DRIVERS)
-
-install: $(EGL_PLATFORM_LIBS)
-       $(INSTALL) -d $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR)
-       for lib in $(EGL_PLATFORM_LIBS); do \
-               $(MINSTALL) -m 755 "$$lib" $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR); \
-       done
-
-depend:
index 4237f944e0d707b502648ddb8da10cc6a3ad7fbf..762c905985e3608d796e1fb0ae3ec838ad6083bb 100644 (file)
@@ -9,7 +9,8 @@
 # Optional defines:
 #   DRIVER_INCLUDES are appended to the list of includes directories.
 #   DRIVER_DEFINES is not used for makedepend, but for compilation.
-#   DRIVER_LINKS are flags given to the linker
+#   DRIVER_PIPES are pipe drivers and modules that the driver depends on.
+#   DRIVER_LINKS are flags given to the linker.
 
 ### Basic defines ###
 
@@ -27,13 +28,21 @@ INCLUDES = \
 
 LIBNAME_STAGING = $(TOP)/$(LIB_DIR)/gallium/$(TARGET)
 
+ifeq ($(MESA_LLVM),1)
+LD = g++
+LDFLAGS += $(LLVM_LDFLAGS)
+USE_CXX=1
+DRIVER_PIPES += $(TOP)/src/gallium/drivers/llvmpipe/libllvmpipe.a
+DRIVER_LINKS += $(LLVM_LIBS) -lm -ldl
+endif
+
 
 ##### TARGETS #####
 
 default: depend $(TOP)/$(LIB_DIR)/gallium $(LIBNAME) $(LIBNAME_STAGING)
 
-$(LIBNAME): $(OBJECTS) Makefile $(LIBS)
-       $(MKLIB) -noprefix -o $@ $(OBJECTS) $(DRIVER_LINKS)
+$(LIBNAME): $(OBJECTS) Makefile ../Makefile.xorg $(LIBS) $(DRIVER_PIPES)
+       $(MKLIB) -noprefix -o $@ $(LDFLAGS) $(OBJECTS) $(DRIVER_PIPES) $(GALLIUM_AUXILIARIES) $(DRIVER_LINKS)
 
 depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) $(GENERATED_SOURCES)
        rm -f depend
index 97187030abc2c5195ecb09d181b49462c416f431..f8276b155587a1621a71d0d6011c93c49affc245 100644 (file)
@@ -32,8 +32,7 @@ if 'xorg' in env['statetrackers']:
 
 if 'egl' in env['statetrackers']:
        SConscript([
-               'egl-swrast/SConscript',
-               'egl-apis/SConscript',
+               'egl-gdi/SConscript',
        ])
 
 # Ideally all non-target directories would produce convenience
index 74b53e5023f8fe364e847119d7adc713ffbd61c3..e5981c2461e2a8092bfd85f9c14574b60f1a73b6 100644 (file)
@@ -13,6 +13,7 @@ drienv.Replace(CPPPATH = [
        '#src/gallium/include',
        '#src/gallium/auxiliary',
        '#src/gallium/drivers',
+       '#src/gallium/winsys',
        '#src/mesa',
        '#src/mesa/main',
        '#src/mesa/glapi',
index fdcfd08c2275ad44d48867e8ad2b8fa2aba570a2..9c10d71a4a67b3b3bfa97af560b1a86643b2d816 100644 (file)
@@ -6,16 +6,25 @@ LIBNAME = i915_dri.so
 PIPE_DRIVERS = \
        $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \
        $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \
+       $(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a \
+       $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+       $(TOP)/src/gallium/drivers/galahad/libgalahad.a \
        $(TOP)/src/gallium/drivers/trace/libtrace.a \
        $(TOP)/src/gallium/drivers/rbug/librbug.a \
-       $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
-       $(TOP)/src/gallium/drivers/identity/libidentity.a \
        $(TOP)/src/gallium/drivers/i915/libi915.a
 
 C_SOURCES = \
+       target.c \
        $(COMMON_GALLIUM_SOURCES) \
        $(DRIVER_SOURCES)
 
+DRIVER_DEFINES = \
+       -DGALLIUM_RBUG -DGALLIUM_TRACE -DGALLIUM_GALAHAD -DGALLIUM_SOFTPIPE
+
+ifeq ($(MESA_LLVM),1)
+DRIVER_DEFINES += -DGALLIUM_LLVMPIPE
+endif
+
 include ../Makefile.dri
 
 DRI_LIB_DEPS += -ldrm_intel
index 65c423988755d4d93acc8629f78bde9aeaa6d842..6f9336b5ac14ff3e4ee78a4b8b6ece23e14d05d9 100644 (file)
@@ -8,10 +8,13 @@ env = drienv.Clone()
 
 env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
 
+env.Append(CPPDEFINES = ['GALLIUM_RBUG', 'GALLIUM_TRACE', 'GALLIUM_GALAHAD'])
+
 env.Prepend(LIBS = [
     st_dri,
     i915drm,
     i915,
+    galahad,
     trace,
     rbug,
     mesa,
@@ -22,6 +25,6 @@ env.Prepend(LIBS = [
 
 env.LoadableModule(
     target = 'i915_dri.so',
-    source = 'dummy.c',
+    source = 'target.c',
     SHLIBPREFIX = '',
 )
diff --git a/src/gallium/targets/dri-i915/dummy.c b/src/gallium/targets/dri-i915/dummy.c
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/src/gallium/targets/dri-i915/target.c b/src/gallium/targets/dri-i915/target.c
new file mode 100644 (file)
index 0000000..5ae6ca3
--- /dev/null
@@ -0,0 +1,30 @@
+
+#include "state_tracker/drm_driver.h"
+#include "target-helpers/inline_wrapper_sw_helper.h"
+#include "target-helpers/inline_debug_helper.h"
+#include "i915/drm/i915_drm_public.h"
+#include "i915/i915_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct i915_winsys *iws;
+   struct pipe_screen *screen;
+
+   iws = i915_drm_winsys_create(fd);
+   if (!iws)
+      return NULL;
+
+   screen = i915_screen_create(iws);
+   if (!screen)
+      return NULL;
+
+   if (debug_get_bool_option("I915_SOFTWARE", FALSE))
+      screen = sw_screen_wrap(screen);
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("i915", "i915", create_screen)
index 13987c643e20393ca6ce03e7612607aa78f22f67..4b50d04255f30a3253ddcf9186acbb04973865a0 100644 (file)
@@ -6,18 +6,25 @@ LIBNAME = i965_dri.so
 PIPE_DRIVERS = \
        $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \
        $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \
-       $(TOP)/src/gallium/drivers/trace/libtrace.a \
-       $(TOP)/src/gallium/drivers/rbug/librbug.a \
-       $(TOP)/src/gallium/winsys/sw/drm/libswdrm.a \
        $(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a \
        $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
-       $(TOP)/src/gallium/drivers/identity/libidentity.a \
+       $(TOP)/src/gallium/drivers/galahad/libgalahad.a \
+       $(TOP)/src/gallium/drivers/trace/libtrace.a \
+       $(TOP)/src/gallium/drivers/rbug/librbug.a \
        $(TOP)/src/gallium/drivers/i965/libi965.a
 
 C_SOURCES = \
+       target.c \
        $(COMMON_GALLIUM_SOURCES) \
        $(DRIVER_SOURCES)
 
+DRIVER_DEFINES = \
+       -DGALLIUM_RBUG -DGALLIUM_TRACE -DGALLIUM_GALAHAD -DGALLIUM_SOFTPIPE
+
+ifeq ($(MESA_LLVM),1)
+DRIVER_DEFINES += -DGALLIUM_LLVMPIPE
+endif
+
 include ../Makefile.dri
 
 DRI_LIB_DEPS += -ldrm_intel
index 13ac5a2d8ea6f058b3fb938c22ab758f47fd416c..684e3488f71c7bd07c547e42824eaafdfaadfed6 100644 (file)
@@ -8,10 +8,15 @@ env = drienv.Clone()
 
 env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
 
+env.Append(CPPDEFINES = [
+    'GALLIUM_SOFTPIPE',
+    'GALLIUM_RBUG',
+    'GALLIUM_TRACE'
+])
+
 env.Prepend(LIBS = [
     st_dri,
     i965drm,
-    ws_drm,
     ws_wrapper,
     i965,
     trace,
@@ -24,6 +29,6 @@ env.Prepend(LIBS = [
 
 env.LoadableModule(
     target = 'i965_dri.so',
-    source = 'dummy.c',
+    source = 'target.c',
     SHLIBPREFIX = '',
 )
diff --git a/src/gallium/targets/dri-i965/dummy.c b/src/gallium/targets/dri-i965/dummy.c
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/src/gallium/targets/dri-i965/target.c b/src/gallium/targets/dri-i965/target.c
new file mode 100644 (file)
index 0000000..ce97f82
--- /dev/null
@@ -0,0 +1,30 @@
+
+#include "target-helpers/inline_wrapper_sw_helper.h"
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "i965/drm/i965_drm_public.h"
+#include "i965/brw_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct brw_winsys_screen *bws;
+   struct pipe_screen *screen;
+
+   bws = i965_drm_winsys_screen_create(fd);
+   if (!bws)
+      return NULL;
+
+   screen = brw_screen_create(bws);
+   if (!screen)
+      return NULL;
+
+   if (debug_get_bool_option("BRW_SOFTPIPE", FALSE))
+      screen = sw_screen_wrap(screen);
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("i915", "i965", create_screen)
index 74d352c6a705fffadc570f0e03690f862f357e10..2f64f312b841cdad42c8f7120ddd8ac10fd4a5b4 100644 (file)
@@ -6,14 +6,20 @@ LIBNAME = nouveau_dri.so
 PIPE_DRIVERS = \
        $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \
        $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \
+       $(TOP)/src/gallium/drivers/trace/libtrace.a \
+       $(TOP)/src/gallium/drivers/rbug/librbug.a \
        $(TOP)/src/gallium/drivers/nvfx/libnvfx.a \
        $(TOP)/src/gallium/drivers/nv50/libnv50.a \
        $(TOP)/src/gallium/drivers/nouveau/libnouveau.a
 
 C_SOURCES = \
+       target.c \
        $(COMMON_GALLIUM_SOURCES) \
        $(DRIVER_SOURCES)
 
+DRIVER_DEFINES = \
+       -DGALLIUM_RBUG -DGALLIUM_TRACE
+
 include ../Makefile.dri
 
 DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs)
diff --git a/src/gallium/targets/dri-nouveau/target.c b/src/gallium/targets/dri-nouveau/target.c
new file mode 100644 (file)
index 0000000..e725a4d
--- /dev/null
@@ -0,0 +1,20 @@
+
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "nouveau/drm/nouveau_drm_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct pipe_screen *screen;
+
+   screen = nouveau_drm_screen_create(fd);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("nouveau", "nouveau", create_screen)
index 0213200fbcc3e8f6ce1fd221ca34c9e099c9697c..932303d194efd123f03202f52a617e1218526aa9 100644 (file)
@@ -12,9 +12,13 @@ PIPE_DRIVERS = \
        $(TOP)/src/gallium/drivers/r600/libr600.a
 
 C_SOURCES = \
+       target.c \
        $(COMMON_GALLIUM_SOURCES) \
        $(DRIVER_SOURCES)
 
+DRIVER_DEFINES = \
+       -DGALLIUM_RBUG -DGALLIUM_TRACE
+
 include ../Makefile.dri
 
 DRI_LIB_DEPS += -ldrm_radeon
index 6c23c050eb863adfb62d25bf90e3252487410b97..97c5df01fe27447be3e43cc4e0217f0d7f1bec0a 100644 (file)
@@ -8,6 +8,8 @@ env = drienv.Clone()
 
 env.ParseConfig('pkg-config --cflags --libs libdrm_radeon')
 
+env.Append(CPPDEFINES = ['GALLIUM_RBUG', 'GALLIUM_TRACE'])
+
 env.Prepend(LIBS = [
     st_dri,
     r600drm,
@@ -22,6 +24,6 @@ env.Prepend(LIBS = [
 
 env.SharedLibrary(
     target ='r600_dri.so',
-    source = 'dummy.c',
+    source = 'target.c',
     SHLIBPREFIX = '',
 )
diff --git a/src/gallium/targets/dri-r600/dummy.c b/src/gallium/targets/dri-r600/dummy.c
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/src/gallium/targets/dri-r600/target.c b/src/gallium/targets/dri-r600/target.c
new file mode 100644 (file)
index 0000000..a01f4ed
--- /dev/null
@@ -0,0 +1,26 @@
+
+#include "state_tracker/drm_driver.h"
+#include "target-helpers/inline_debug_helper.h"
+#include "r600/drm/r600_drm_public.h"
+#include "r600/r600_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct radeon *rw;
+   struct pipe_screen *screen;
+
+   rw = r600_drm_winsys_create(fd);
+   if (!rw)
+      return NULL;
+
+   screen = r600_screen_create(rw);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("r600", "radeon", create_screen)
index 8ef24c08215ff85af6e391f6dec9f743c6ebe201..3f9ec3616644acffddb67d453832d8e747c505f0 100644 (file)
@@ -7,14 +7,19 @@ PIPE_DRIVERS = \
        $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \
        $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \
        $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+       $(TOP)/src/gallium/drivers/galahad/libgalahad.a \
        $(TOP)/src/gallium/drivers/trace/libtrace.a \
        $(TOP)/src/gallium/drivers/rbug/librbug.a \
        $(TOP)/src/gallium/drivers/r300/libr300.a
 
 C_SOURCES = \
+       target.c \
        $(COMMON_GALLIUM_SOURCES) \
        $(DRIVER_SOURCES)
 
+DRIVER_DEFINES = \
+       -DGALLIUM_RBUG -DGALLIUM_TRACE -DGALLIUM_GALAHAD
+
 include ../Makefile.dri
 
 DRI_LIB_DEPS += -ldrm_radeon
index 4c6cfb84ebade0ed5b80dd5658ee0aa373dd4573..1402c3bd1205406d5d177fd4c2dbf6a22ebe4634 100644 (file)
@@ -8,10 +8,13 @@ env = drienv.Clone()
 
 env.ParseConfig('pkg-config --cflags --libs libdrm_radeon')
 
+env.Append(CPPDEFINES = ['GALLIUM_RBUG', 'GALLIUM_TRACE', 'GALLIUM_GALAHAD'])
+
 env.Prepend(LIBS = [
     st_dri,
     radeonwinsys,
     r300,
+    galahad,
     trace,
     rbug,
     mesa,
@@ -22,6 +25,6 @@ env.Prepend(LIBS = [
 
 env.SharedLibrary(
     target ='radeon_dri.so',
-    source = 'dummy.c',
+    source = 'target.c',
     SHLIBPREFIX = '',
 )
diff --git a/src/gallium/targets/dri-radeong/dummy.c b/src/gallium/targets/dri-radeong/dummy.c
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/src/gallium/targets/dri-radeong/target.c b/src/gallium/targets/dri-radeong/target.c
new file mode 100644 (file)
index 0000000..5a0a8dc
--- /dev/null
@@ -0,0 +1,26 @@
+
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "radeon/drm/radeon_drm_public.h"
+#include "r300/r300_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct r300_winsys_screen *sws;
+   struct pipe_screen *screen;
+
+   sws = r300_drm_winsys_screen_create(fd);
+   if (!sws)
+      return NULL;
+
+   screen = r300_screen_create(sws);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("radeon", "radeon", create_screen)
index 0a53eb56c455c8283d30b5b7ab81d679eb766860..948c45abe5c64c4c73c78ae863e2c40d19581ff4 100644 (file)
@@ -3,7 +3,9 @@ include $(TOP)/configs/current
 
 LIBNAME = swrastg_dri.so
 
-DRIVER_DEFINES = -D__NOT_HAVE_DRM_H -DGALLIUM_SOFTPIPE
+DRIVER_DEFINES = \
+       -D__NOT_HAVE_DRM_H -DGALLIUM_SOFTPIPE \
+       -DGALLIUM_RBUG -DGALLIUM_TRACE
 
 PIPE_DRIVERS = \
        $(TOP)/src/gallium/state_trackers/dri/sw/libdrisw.a \
index 679afab41c7bc049251740079370248dbab052e7..d8143471194db6344464721194b16f0d041033e9 100644 (file)
@@ -18,7 +18,11 @@ env.Prepend(LIBS = [
 ])
 
 if True:
-    env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE')
+    env.Append(CPPDEFINES = [
+        'GALLIUM_SOFTPIPE',
+        'GALLIUM_RBUG',
+        'GALLIUM_TRACE',
+    ])
     env.Prepend(LIBS = [softpipe])
 
 if env['llvm']:
index 84142be80c8c16878cd9d60c4d7b459b239b17f0..8d741c6343c86db07c172d15e77cd4fa45a79146 100644 (file)
 
 #include "pipe/p_compiler.h"
 #include "util/u_memory.h"
-#include "state_tracker/drm_api.h"
-#include "state_tracker/sw_winsys.h"
 #include "dri_sw_winsys.h"
-#include "trace/tr_public.h"
 
-/* Copied from targets/libgl-xlib */
+#include "target-helpers/inline_debug_helper.h"
+#include "target-helpers/inline_sw_helper.h"
 
-#ifdef GALLIUM_SOFTPIPE
-#include "softpipe/sp_public.h"
-#endif
-
-#ifdef GALLIUM_LLVMPIPE
-#include "llvmpipe/lp_public.h"
-#endif
-
-#ifdef GALLIUM_CELL
-#include "cell/ppu/cell_public.h"
-#endif
-
-static struct pipe_screen *
-swrast_create_screen(struct sw_winsys *winsys)
-{
-   const char *default_driver;
-   const char *driver;
-   struct pipe_screen *screen = NULL;
-
-#if defined(GALLIUM_CELL)
-   default_driver = "cell";
-#elif defined(GALLIUM_LLVMPIPE)
-   default_driver = "llvmpipe";
-#elif defined(GALLIUM_SOFTPIPE)
-   default_driver = "softpipe";
-#else
-   default_driver = "";
-#endif
-
-   driver = debug_get_option("GALLIUM_DRIVER", default_driver);
-
-#if defined(GALLIUM_CELL)
-   if (screen == NULL && strcmp(driver, "cell") == 0)
-      screen = cell_create_screen( winsys );
-#endif
-
-#if defined(GALLIUM_LLVMPIPE)
-   if (screen == NULL && strcmp(driver, "llvmpipe") == 0)
-      screen = llvmpipe_create_screen( winsys );
-#endif
-
-#if defined(GALLIUM_SOFTPIPE)
-   if (screen == NULL)
-      screen = softpipe_create_screen( winsys );
-#endif
-
-   return trace_screen_create(screen);;
-}
 
 struct pipe_screen *
 drisw_create_screen(struct drisw_loader_funcs *lf)
@@ -94,10 +44,12 @@ drisw_create_screen(struct drisw_loader_funcs *lf)
    if (winsys == NULL)
       return NULL;
 
-   screen = swrast_create_screen(winsys);
+   screen = sw_screen_create(winsys);
    if (!screen)
       goto fail;
 
+   screen = debug_screen_wrap(screen);
+
    return screen;
 
 fail:
index b5b679f3c7c9e558093b9d24e9d8180ac9fdc2b7..97c703b3739f2518099d7e135d3fb42bca1f22d6 100644 (file)
@@ -11,8 +11,12 @@ PIPE_DRIVERS = \
        $(TOP)/src/gallium/drivers/svga/libsvga.a
 
 C_SOURCES = \
+       target.c \
        $(COMMON_GALLIUM_SOURCES)
 
+DRIVER_DEFINES = \
+       -DGALLIUM_RBUG -DGALLIUM_TRACE
+
 include ../Makefile.dri
 
 symlinks:
index 09a0c254c304e651f36190e9a757e2fcdd4fe6e7..7afabc7429f71d696734b7df3435629b1486bb33 100644 (file)
@@ -6,6 +6,8 @@ if not 'svga' in env['drivers']:
 
 env = drienv.Clone()
 
+env.Append(CPPDEFINES = ['GALLIUM_RBUG', 'GALLIUM_TRACE'])
+
 env.Prepend(LIBS = [
     st_dri,
     svgadrm,
@@ -20,6 +22,6 @@ env.Prepend(LIBS = [
 
 env.LoadableModule(
     target = 'vmwgfx_dri.so',
-    source = 'dummy.c',
+    source = 'target.c',
     SHLIBPREFIX = '',
 )
diff --git a/src/gallium/targets/dri-vmwgfx/dummy.c b/src/gallium/targets/dri-vmwgfx/dummy.c
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/src/gallium/targets/dri-vmwgfx/target.c b/src/gallium/targets/dri-vmwgfx/target.c
new file mode 100644 (file)
index 0000000..15089d6
--- /dev/null
@@ -0,0 +1,26 @@
+
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "svga/drm/svga_drm_public.h"
+#include "svga/svga_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct svga_winsys_screen *sws;
+   struct pipe_screen *screen;
+
+   sws = svga_drm_winsys_screen_create(fd);
+   if (!sws)
+      return NULL;
+
+   screen = svga_screen_create(sws);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("vmwgfx", "vmwgfx", create_screen)
diff --git a/src/gallium/targets/egl-apis/Makefile b/src/gallium/targets/egl-apis/Makefile
deleted file mode 100644 (file)
index 88915bf..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-# src/gallium/targets/egl-apis
-
-TOP = ../../../..
-include $(TOP)/configs/current
-
-OUTPUT_PREFIX := api_
-OUTPUT_PATH := $(TOP)/$(LIB_DIR)/egl
-
-OUTPUTS := $(addsuffix .so, $(EGL_CLIENT_APIS))
-OUTPUTS := $(addprefix $(OUTPUT_PATH)/$(OUTPUT_PREFIX), $(OUTPUTS))
-
-# include dirs
-GL_INCLUDES := -I$(TOP)/src/mesa -I$(TOP)/src/gallium/include
-GLESv1_CM_INCLUDES := $(GL_INCLUDES)
-GLESv2_INCLUDES := $(GL_INCLUDES)
-OpenVG_INCLUDES := -I$(TOP)/src/gallium/state_trackers/vega -I$(TOP)/src/gallium/include
-
-# system libs
-GL_SYS := -lpthread -lm -L$(TOP)/$(LIB_DIR) -l$(GL_LIB)
-GLESv1_CM_SYS := -lpthread -lm -L$(TOP)/$(LIB_DIR) -l$(GLESv1_CM_LIB)
-GLESv2_SYS := -lpthread -lm -L$(TOP)/$(LIB_DIR) -l$(GLESv2_LIB)
-OpenVG_SYS := -lm -L$(TOP)/$(LIB_DIR) -l$(VG_LIB)
-
-# $(LLVM_LIBS) will be discarded except for OpenGL, which creates a private
-# draw context for selection/feedback mode.
-ifeq ($(MESA_LLVM),1)
-GL_SYS += $(LLVM_LIBS)
-GLESv1_CM_SYS += $(LLVM_LIBS)
-GLESv2_SYS += $(LLVM_LIBS)
-OpenVG_SYS += $(LLVM_LIBS)
-LDFLAGS += $(LLVM_LDFLAGS)
-endif
-
-# project libs
-GL_LIBS := $(TOP)/src/mesa/libmesagallium.a
-GLESv1_CM_LIBS := $(TOP)/src/mesa/libes1gallium.a
-GLESv2_LIBS := $(TOP)/src/mesa/libes2gallium.a
-OpenVG_LIBS := $(TOP)/src/gallium/state_trackers/vega/libvega.a
-
-# objects
-GL_OBJECTS := api_GL.o
-GLESv1_CM_OBJECTS := api_GLESv1_CM.o
-GLESv2_OBJECTS := api_GLESv2.o
-OpenVG_OBJECTS := api_OpenVG.o
-
-default: $(OUTPUTS)
-
-api_%.o: api_%.c
-       $(CC) -c -o $@ $< $($*_INCLUDES) $(DEFINES) $(CFLAGS)
-
-define mklib
-$(MKLIB) -o $(notdir $@) -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \
-       -install $(OUTPUT_PATH) $(MKLIB_OPTIONS) \
-       $($(1)_OBJECTS) $($(1)_LIBS) $(GALLIUM_AUXILIARIES) $($(1)_SYS)
-endef
-
-$(OUTPUT_PATH)/$(OUTPUT_PREFIX)$(GL_LIB).so: $(GL_OBJECTS) $(GL_LIBS)
-       $(call mklib,GL)
-
-$(OUTPUT_PATH)/$(OUTPUT_PREFIX)$(GLESv1_CM_LIB).so: $(GLESv1_CM_OBJECTS) $(GLESv1_CM_LIBS)
-       $(call mklib,GLESv1_CM)
-
-$(OUTPUT_PATH)/$(OUTPUT_PREFIX)$(GLESv2_LIB).so: $(GLESv2_OBJECTS) $(GLESv2_LIBS)
-       $(call mklib,GLESv2)
-
-$(OUTPUT_PATH)/$(OUTPUT_PREFIX)$(VG_LIB).so: $(OpenVG_OBJECTS) $(OpenVG_LIBS)
-       $(call mklib,OpenVG)
-
-install: $(OUTPUTS)
-       $(INSTALL) -d $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR)
-       for out in $(OUTPUTS); do \
-               $(MINSTALL) -m 755 "$$out" $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR); \
-       done
-
-clean:
-       -rm -f $(OUTPUTS)
-       -rm -f *.o
diff --git a/src/gallium/targets/egl-apis/SConscript b/src/gallium/targets/egl-apis/SConscript
deleted file mode 100644 (file)
index 0ca3d1f..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#######################################################################
-# SConscript for egl-apis target
-
-Import('*')
-
-if env['platform'] == 'windows':
-
-    env = env.Clone()
-
-    env.Append(CPPPATH = [
-            '#/src/gallium/state_trackers/vega',
-    ])
-
-    env.Append(LIBS = [
-        'gdi32',
-        'user32',
-        'kernel32',
-        'ws2_32',
-    ])
-
-    env['no_import_lib'] = 1
-
-    api_libs = {
-        'OpenVG': vgapi + st_vega,
-    }
-
-    for name in api_libs.keys():
-        api = env.SharedLibrary(
-            target = 'api_' + name,
-            source = ['api_' + name + '.c'],
-            LIBS = api_libs[name] + gallium + env['LIBS'],
-        )
-        env.InstallSharedLibrary(api)
diff --git a/src/gallium/targets/egl-apis/api_GL.c b/src/gallium/targets/egl-apis/api_GL.c
deleted file mode 100644 (file)
index 6d17274..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "state_tracker/st_gl_api.h"
-
-PUBLIC struct st_api *
-st_api_create_OpenGL()
-{
-   return st_gl_api_create();
-}
diff --git a/src/gallium/targets/egl-apis/api_GLESv1_CM.c b/src/gallium/targets/egl-apis/api_GLESv1_CM.c
deleted file mode 100644 (file)
index 825fdac..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#include "state_tracker/st_gl_api.h"
-
-PUBLIC struct st_api *
-st_api_create_OpenGL_ES1()
-{
-   return st_gl_api_create();
-}
diff --git a/src/gallium/targets/egl-apis/api_GLESv2.c b/src/gallium/targets/egl-apis/api_GLESv2.c
deleted file mode 100644 (file)
index 5c773aa..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "state_tracker/st_gl_api.h"
-
-PUBLIC struct st_api *
-st_api_create_OpenGL_ES2()
-{
-   /* linker magic creates different versions */
-   return st_gl_api_create();
-}
diff --git a/src/gallium/targets/egl-apis/api_OpenVG.c b/src/gallium/targets/egl-apis/api_OpenVG.c
deleted file mode 100644 (file)
index f85ebea..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "state_tracker/st_api.h"
-#include "vg_api.h"
-
-PUBLIC struct st_api *
-st_api_create_OpenVG()
-{
-   return (struct st_api *) vg_api_get();
-}
diff --git a/src/gallium/targets/egl-gdi/SConscript b/src/gallium/targets/egl-gdi/SConscript
new file mode 100644 (file)
index 0000000..8f8b28e
--- /dev/null
@@ -0,0 +1,47 @@
+#######################################################################
+# SConscript for egl-gdi target
+
+Import('*')
+
+if env['platform'] == 'windows':
+
+    env = env.Clone()
+
+    env.Append(CPPPATH = [
+            '#/src/gallium/state_trackers/egl',
+            '#/src/gallium/state_trackers/vega',
+            '#/src/egl/main',
+            '#/src/mesa',
+    ])
+
+    env.Append(CPPDEFINES = [
+            'FEATURE_VG=1',
+            'GALLIUM_SOFTPIPE',
+            'GALLIUM_RBUG',
+            'GALLIUM_TRACE',
+    ])
+
+    env.Append(LIBS = [
+        'gdi32',
+        'user32',
+        'kernel32',
+        'ws2_32',
+    ])
+
+    env['no_import_lib'] = 1
+
+    drivers = [softpipe]
+    if env['llvm']:
+        env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE')
+        drivers += [llvmpipe]
+    drivers += [identity, trace, rbug]
+
+    apis = [vgapi, st_vega]
+
+    egl_gallium = env.SharedLibrary(
+        target ='egl_gallium',
+        source = 'egl-static.c',
+        LIBS = st_egl_gdi + ws_gdi + drivers + apis + gallium + egl + env['LIBS'],
+    )
+
+    env.InstallSharedLibrary(egl_gallium)
diff --git a/src/gallium/targets/egl-gdi/egl-static.c b/src/gallium/targets/egl-gdi/egl-static.c
new file mode 100644 (file)
index 0000000..ec2f865
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION 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:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "common/egl_g3d_loader.h"
+#include "state_tracker/st_gl_api.h"
+#include "vg_api.h"
+#include "target-helpers/inline_sw_helper.h"
+#include "target-helpers/inline_debug_helper.h"
+#include "egldriver.h"
+
+static uint
+get_api_mask(void)
+{
+   uint api_mask = 0x0;
+
+#if FEATURE_GL
+   api_mask |= 1 << ST_API_OPENGL;
+#endif
+#if FEATURE_ES1
+   api_mask |= 1 << ST_API_OPENGL_ES1;
+#endif
+#if FEATURE_ES2
+   api_mask |= 1 << ST_API_OPENGL_ES2;
+#endif
+#if FEATURE_VG
+   api_mask |= 1 << ST_API_OPENVG;
+#endif
+
+   return api_mask;
+}
+
+static struct st_api *
+get_st_api(enum st_api_type api)
+{
+   struct st_api *stapi = NULL;
+
+   switch (api) {
+#if FEATURE_GL
+      case ST_API_OPENGL:
+         stapi = st_gl_api_create();
+         break;
+#endif
+#if FEATURE_ES1
+      case ST_API_OPENGL_ES1:
+         stapi = st_gl_api_create_es1();
+         break;
+#endif
+#if FEATURE_ES2
+      case ST_API_OPENGL_ES2:
+         stapi = st_gl_api_create_es2();
+         break;
+#endif
+#if FEATURE_VG
+      case ST_API_OPENVG:
+         stapi = (struct st_api *) vg_api_get();
+         break;
+#endif
+      default:
+         break;
+   }
+
+   return stapi;
+}
+
+static struct st_api *
+guess_gl_api(void)
+{
+   return NULL;
+}
+
+static struct pipe_screen *
+create_drm_screen(const char *name, int fd)
+{
+   return NULL;
+}
+
+static struct pipe_screen *
+create_sw_screen(struct sw_winsys *ws)
+{
+   struct pipe_screen *screen;
+
+   screen = sw_screen_create(ws);
+   if (screen)
+      screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+static void
+init_loader(struct egl_g3d_loader *loader)
+{
+   if (loader->api_mask)
+      return;
+
+   loader->api_mask = get_api_mask();
+   loader->get_st_api = get_st_api;
+   loader->guess_gl_api = guess_gl_api;
+   loader->create_drm_screen = create_drm_screen;
+   loader->create_sw_screen = create_sw_screen;
+}
+
+static void
+egl_g3d_unload(_EGLDriver *drv)
+{
+   egl_g3d_destroy_driver(drv);
+}
+
+static struct egl_g3d_loader loader;
+
+_EGLDriver *
+_eglMain(const char *args)
+{
+   _EGLDriver *drv;
+
+   init_loader(&loader);
+   drv = egl_g3d_create_driver(&loader);
+   if (drv) {
+      drv->Name = "Gallium";
+      drv->Unload = egl_g3d_unload;
+   }
+
+   return drv;
+}
diff --git a/src/gallium/targets/egl-i915/Makefile b/src/gallium/targets/egl-i915/Makefile
deleted file mode 100644 (file)
index a4b4184..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-EGL_DRIVER_NAME = i915
-EGL_DRIVER_SOURCES = dummy.c
-EGL_DRIVER_LIBS = -ldrm_intel
-
-EGL_DRIVER_PIPES = \
-       $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \
-       $(TOP)/src/gallium/drivers/trace/libtrace.a \
-       $(TOP)/src/gallium/drivers/rbug/librbug.a \
-       $(TOP)/src/gallium/drivers/i915/libi915.a
-
-include ../Makefile.egl
diff --git a/src/gallium/targets/egl-i915/dummy.c b/src/gallium/targets/egl-i915/dummy.c
deleted file mode 100644 (file)
index 3181d0b..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-/* A poor man's --whole-archive for EGL drivers */
-void *_eglMain(void *);
-void *_eglWholeArchive = (void *) _eglMain;
diff --git a/src/gallium/targets/egl-i965/Makefile b/src/gallium/targets/egl-i965/Makefile
deleted file mode 100644 (file)
index d473082..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-EGL_DRIVER_NAME = i965
-EGL_DRIVER_SOURCES = dummy.c
-EGL_DRIVER_LIBS = -ldrm_intel
-
-EGL_DRIVER_PIPES = \
-       $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \
-       $(TOP)/src/gallium/drivers/trace/libtrace.a \
-       $(TOP)/src/gallium/drivers/rbug/librbug.a \
-       $(TOP)/src/gallium/drivers/i965/libi965.a \
-       $(TOP)/src/gallium/winsys/sw/drm/libswdrm.a \
-       $(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a \
-       $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a
-
-include ../Makefile.egl
diff --git a/src/gallium/targets/egl-i965/dummy.c b/src/gallium/targets/egl-i965/dummy.c
deleted file mode 100644 (file)
index 3181d0b..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-/* A poor man's --whole-archive for EGL drivers */
-void *_eglMain(void *);
-void *_eglWholeArchive = (void *) _eglMain;
diff --git a/src/gallium/targets/egl-nouveau/Makefile b/src/gallium/targets/egl-nouveau/Makefile
deleted file mode 100644 (file)
index e3fa893..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-EGL_DRIVER_NAME = nouveau
-EGL_DRIVER_SOURCES = dummy.c
-EGL_DRIVER_LIBS = -ldrm_nouveau
-
-EGL_DRIVER_PIPES = \
-       $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \
-       $(TOP)/src/gallium/drivers/nvfx/libnvfx.a \
-       $(TOP)/src/gallium/drivers/nv50/libnv50.a \
-       $(TOP)/src/gallium/drivers/nouveau/libnouveau.a
-
-include ../Makefile.egl
diff --git a/src/gallium/targets/egl-nouveau/dummy.c b/src/gallium/targets/egl-nouveau/dummy.c
deleted file mode 100644 (file)
index 3181d0b..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-/* A poor man's --whole-archive for EGL drivers */
-void *_eglMain(void *);
-void *_eglWholeArchive = (void *) _eglMain;
diff --git a/src/gallium/targets/egl-radeon/Makefile b/src/gallium/targets/egl-radeon/Makefile
deleted file mode 100644 (file)
index 8fcca26..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-EGL_DRIVER_NAME = radeon
-EGL_DRIVER_SOURCES = dummy.c
-EGL_DRIVER_LIBS = -ldrm_radeon
-
-EGL_DRIVER_PIPES = \
-       $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \
-       $(TOP)/src/gallium/drivers/trace/libtrace.a \
-       $(TOP)/src/gallium/drivers/rbug/librbug.a \
-       $(TOP)/src/gallium/drivers/r300/libr300.a
-
-include ../Makefile.egl
diff --git a/src/gallium/targets/egl-radeon/dummy.c b/src/gallium/targets/egl-radeon/dummy.c
deleted file mode 100644 (file)
index 3181d0b..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-/* A poor man's --whole-archive for EGL drivers */
-void *_eglMain(void *);
-void *_eglWholeArchive = (void *) _eglMain;
diff --git a/src/gallium/targets/egl-swrast/Makefile b/src/gallium/targets/egl-swrast/Makefile
deleted file mode 100644 (file)
index 7d4f505..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-# Do propperly
-CFLAGS+="-I$(TOP)/src/gallium/include"
-
-EGL_DRIVER_NAME = swrast
-EGL_DRIVER_SOURCES = swrast_glue.c
-EGL_DRIVER_LIBS =
-EGL_DRIVER_PIPES =
-
-include ../Makefile.egl
diff --git a/src/gallium/targets/egl-swrast/SConscript b/src/gallium/targets/egl-swrast/SConscript
deleted file mode 100644 (file)
index 213e5b3..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#######################################################################
-# SConscript for egl-swrast target
-
-Import('*')
-
-if env['platform'] == 'windows':
-
-    env = env.Clone()
-
-    env.Append(LIBS = [
-        'gdi32',
-        'user32',
-        'kernel32',
-        'ws2_32',
-    ])
-
-    drivers = [softpipe]
-    if env['llvm']:
-        drivers += [llvmpipe]
-    drivers += [identity, trace, rbug]
-
-    env['no_import_lib'] = 1
-
-    egl_gdi_swrast = env.SharedLibrary(
-        target ='egl_gdi_swrast',
-       source = 'swrast_glue.c',
-        LIBS = st_egl_gdi + ws_gdi + drivers + gallium + egl + env['LIBS'],
-    )
-
-    env.InstallSharedLibrary(egl_gdi_swrast)
diff --git a/src/gallium/targets/egl-swrast/swrast_glue.c b/src/gallium/targets/egl-swrast/swrast_glue.c
deleted file mode 100644 (file)
index defd11c..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#include "state_tracker/drm_api.h"
-
-struct drm_api *
-drm_api_create()
-{
-   return NULL;
-}
-
-/* A poor man's --whole-archive for EGL drivers */
-void *_eglMain(void *);
-void *_eglWholeArchive = (void *) _eglMain;
diff --git a/src/gallium/targets/egl-vmwgfx/Makefile b/src/gallium/targets/egl-vmwgfx/Makefile
deleted file mode 100644 (file)
index a9f6874..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-TOP = ../../../..
-include $(TOP)/configs/current
-
-EGL_DRIVER_NAME = vmwgfx
-EGL_DRIVER_SOURCES = dummy.c
-EGL_DRIVER_LIBS =
-
-EGL_DRIVER_PIPES = \
-       $(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \
-       $(TOP)/src/gallium/drivers/trace/libtrace.a \
-       $(TOP)/src/gallium/drivers/rbug/librbug.a \
-       $(TOP)/src/gallium/drivers/svga/libsvga.a
-
-include ../Makefile.egl
diff --git a/src/gallium/targets/egl-vmwgfx/dummy.c b/src/gallium/targets/egl-vmwgfx/dummy.c
deleted file mode 100644 (file)
index 3181d0b..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-/* A poor man's --whole-archive for EGL drivers */
-void *_eglMain(void *);
-void *_eglWholeArchive = (void *) _eglMain;
diff --git a/src/gallium/targets/egl/Makefile b/src/gallium/targets/egl/Makefile
new file mode 100644 (file)
index 0000000..1e4bb4d
--- /dev/null
@@ -0,0 +1,229 @@
+# src/gallium/targets/egl/Makefile
+#
+# This is the Makefile for EGL Gallium driver package.  The package consists of
+#
+#   egl_gallium.so - EGL driver
+#   pipe_<HW>.so   - pipe drivers
+#   st_<API>.so    - client API state trackers
+#
+# The following variables are examined
+#
+#   EGL_PLATFORMS       - platforms to support
+#   GALLIUM_WINSYS_DIRS - pipe drivers to support
+#   EGL_CLIENT_APIS     - state trackers to support
+#
+
+TOP = ../../../..
+include $(TOP)/configs/current
+
+ST_PREFIX := st_
+PIPE_PREFIX := pipe_
+
+common_CPPFLAGS := \
+       -I$(TOP)/include \
+       -I$(TOP)/src/gallium/auxiliary \
+       -I$(TOP)/src/gallium/drivers \
+       -I$(TOP)/src/gallium/include \
+       -I$(TOP)/src/gallium/winsys
+common_SYS :=
+common_LIBS := \
+       $(TOP)/src/gallium/drivers/identity/libidentity.a \
+       $(TOP)/src/gallium/drivers/trace/libtrace.a \
+       $(TOP)/src/gallium/drivers/rbug/librbug.a \
+       $(GALLIUM_AUXILIARIES)
+
+# EGL driver
+egl_CPPFLAGS := \
+       -I$(TOP)/src/gallium/state_trackers/egl \
+       -I$(TOP)/src/egl/main \
+       -DPIPE_PREFIX=\"$(PIPE_PREFIX)\" -DST_PREFIX=\"$(ST_PREFIX)\"
+egl_SYS := -lm $(DLOPEN_LIBS) -L$(TOP)/$(LIB_DIR) -lEGL
+egl_LIBS := $(TOP)/src/gallium/state_trackers/egl/libegl.a
+
+ifneq ($(findstring x11, $(EGL_PLATFORMS)),)
+egl_SYS += -lX11 -lXext -lXfixes
+egl_LIBS += $(TOP)/src/gallium/winsys/sw/xlib/libws_xlib.a
+endif
+ifneq ($(findstring kms, $(EGL_PLATFORMS)),)
+egl_SYS += -ldrm
+endif
+ifneq ($(findstring fbdev, $(EGL_PLATFORMS)),)
+egl_LIBS += $(TOP)/src/gallium/winsys/sw/fbdev/libfbdev.a
+endif
+
+# EGL_RENDERABLE_TYPE is a compile time attribute
+egl_CPPFLAGS += $(API_DEFINES)
+ifneq ($(filter $(GL_LIB), $(EGL_CLIENT_APIS)),)
+egl_CPPFLAGS += -DFEATURE_GL=1
+endif
+ifneq ($(filter $(GLESv1_CM_LIB), $(EGL_CLIENT_APIS)),)
+egl_CPPFLAGS += -DFEATURE_ES1=1
+endif
+ifneq ($(filter $(GLESv2_LIB), $(EGL_CLIENT_APIS)),)
+egl_CPPFLAGS += -DFEATURE_ES2=1
+endif
+ifneq ($(filter $(VG_LIB), $(EGL_CLIENT_APIS)),)
+egl_CPPFLAGS += -DFEATURE_VG=1
+endif
+egl_CPPFLAGS := $(sort $(egl_CPPFLAGS))
+
+# i915 pipe driver
+i915_CPPFLAGS :=
+i915_SYS := -ldrm_intel
+i915_LIBS := \
+       $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \
+       $(TOP)/src/gallium/drivers/i915/libi915.a
+
+# i965 pipe driver
+i965_CPPFLAGS :=
+i965_SYS := -ldrm_intel
+i965_LIBS := \
+       $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \
+       $(TOP)/src/gallium/drivers/i965/libi965.a
+
+# nouveau pipe driver
+nouveau_CPPFLAGS :=
+nouveau_SYS := -ldrm_nouveau
+nouveau_LIBS := \
+       $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \
+       $(TOP)/src/gallium/drivers/nvfx/libnvfx.a \
+       $(TOP)/src/gallium/drivers/nv50/libnv50.a \
+       $(TOP)/src/gallium/drivers/nouveau/libnouveau.a
+
+# radeon pipe driver
+radeon_CPPFLAGS :=
+radeon_SYS := -ldrm -ldrm_radeon
+radeon_LIBS := \
+       $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \
+       $(TOP)/src/gallium/drivers/r300/libr300.a
+
+# vmwgfx pipe driver
+vmwgfx_CPPFLAGS :=
+vmwgfx_SYS :=
+vmwgfx_LIBS := \
+       $(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \
+       $(TOP)/src/gallium/drivers/svga/libsvga.a
+
+# swrast (pseudo) pipe driver
+swrast_CPPFLAGS := -DGALLIUM_SOFTPIPE -DGALLIUM_RBUG -DGALLIUM_TRACE
+swrast_SYS := -lm
+swrast_LIBS := $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a
+
+# LLVM
+ifeq ($(MESA_LLVM),1)
+common_SYS += $(LLVM_LIBS)
+swrast_CPPFLAGS += -DGALLIUM_LLVMPIPE
+swrast_LIBS += $(TOP)/src/gallium/drivers/llvmpipe/libllvmpipe.a
+LDFLAGS += $(LLVM_LDFLAGS)
+endif
+
+# OpenGL state tracker
+GL_CPPFLAGS := -I$(TOP)/src/mesa $(API_DEFINES)
+GL_SYS := -lpthread -lm -L$(TOP)/$(LIB_DIR) -l$(GL_LIB)
+GL_LIBS := $(TOP)/src/mesa/libmesagallium.a
+
+# OpenGL ES 1.x state tracker
+GLESv1_CM_CPPFLAGS := -I$(TOP)/src/mesa
+GLESv1_CM_SYS := -lpthread -lm -L$(TOP)/$(LIB_DIR) -l$(GLESv1_CM_LIB)
+GLESv1_CM_LIBS := $(TOP)/src/mesa/libes1gallium.a
+
+# OpenGL ES 2.x state tracker
+GLESv2_CPPFLAGS := -I$(TOP)/src/mesa
+GLESv2_SYS := -lpthread -lm -L$(TOP)/$(LIB_DIR) -l$(GLESv2_LIB)
+GLESv2_LIBS := $(TOP)/src/mesa/libes2gallium.a
+
+# OpenVG state tracker
+OpenVG_CPPFLAGS := -I$(TOP)/src/gallium/state_trackers/vega
+OpenVG_SYS := -lm -L$(TOP)/$(LIB_DIR) -l$(VG_LIB)
+OpenVG_LIBS := $(TOP)/src/gallium/state_trackers/vega/libvega.a
+
+
+OUTPUT_PATH := $(TOP)/$(LIB_DIR)/egl
+
+# determine the outputs
+ifneq ($(findstring i915/drm,$(GALLIUM_WINSYS_DIRS)),)
+OUTPUTS += i915
+endif
+ifneq ($(findstring i965/drm,$(GALLIUM_WINSYS_DIRS)),)
+OUTPUTS += i965
+endif
+ifneq ($(findstring nouveau/drm,$(GALLIUM_WINSYS_DIRS)),)
+OUTPUTS += nouveau
+endif
+ifneq ($(findstring radeon/drm,$(GALLIUM_WINSYS_DIRS)),)
+OUTPUTS += radeon
+endif
+ifneq ($(findstring svga/drm,$(GALLIUM_WINSYS_DIRS)),)
+OUTPUTS += vmwgfx
+endif
+OUTPUTS += swrast
+OUTPUTS := $(addprefix $(PIPE_PREFIX), $(OUTPUTS))
+
+# EGL driver and state trackers
+OUTPUTS += egl_gallium $(addprefix $(ST_PREFIX), $(EGL_CLIENT_APIS))
+
+OUTPUTS := $(addsuffix .so, $(OUTPUTS))
+OUTPUTS := $(addprefix $(OUTPUT_PATH)/, $(OUTPUTS))
+
+default: $(OUTPUTS)
+
+define mklib
+$(MKLIB) -o $(notdir $@) -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \
+       -install $(OUTPUT_PATH) $(MKLIB_OPTIONS) $< \
+       -Wl,--start-group $(common_LIBS) $($(1)_LIBS) -Wl,--end-group \
+       $(common_SYS) $($(1)_SYS)
+endef
+
+# EGL driver
+$(OUTPUT_PATH)/egl_gallium.so: egl.o $(egl_LIBS)
+       $(call mklib,egl)
+
+# pipe drivers
+$(OUTPUT_PATH)/$(PIPE_PREFIX)i915.so: pipe_i915.o $(i915_LIBS)
+       $(call mklib,i915)
+
+$(OUTPUT_PATH)/$(PIPE_PREFIX)i965.so: pipe_i965.o $(i965_LIBS)
+       $(call mklib,i965)
+
+$(OUTPUT_PATH)/$(PIPE_PREFIX)nouveau.so: pipe_nouveau.o $(nouveau_LIBS)
+       $(call mklib,nouveau)
+
+$(OUTPUT_PATH)/$(PIPE_PREFIX)radeon.so: pipe_radeon.o $(radeon_LIBS)
+       $(call mklib,radeon)
+
+$(OUTPUT_PATH)/$(PIPE_PREFIX)vmwgfx.so: pipe_vmwgfx.o $(vmwgfx_LIBS)
+       $(call mklib,vmwgfx)
+
+$(OUTPUT_PATH)/$(PIPE_PREFIX)swrast.so: pipe_swrast.o $(swrast_LIBS)
+       $(call mklib,swrast)
+
+# state trackers
+$(OUTPUT_PATH)/$(ST_PREFIX)$(GL_LIB).so: st_GL.o $(GL_LIBS)
+       $(call mklib,GL)
+
+$(OUTPUT_PATH)/$(ST_PREFIX)$(GLESv1_CM_LIB).so: st_GLESv1_CM.o $(GLESv1_CM_LIBS)
+       $(call mklib,GLESv1_CM)
+
+$(OUTPUT_PATH)/$(ST_PREFIX)$(GLESv2_LIB).so: st_GLESv2.o $(GLESv2_LIBS)
+       $(call mklib,GLESv2)
+
+$(OUTPUT_PATH)/$(ST_PREFIX)$(VG_LIB).so: st_OpenVG.o $(OpenVG_LIBS)
+       $(call mklib,OpenVG)
+
+egl.o: egl.c
+       $(CC) -c -o $@ $< $(common_CPPFLAGS) $(egl_CPPFLAGS) $(DEFINES) $(CFLAGS)
+
+pipe_%.o: pipe_%.c
+       $(CC) -c -o $@ $< $(common_CPPFLAGS) $($*_CPPFLAGS) $(DEFINES) $(CFLAGS)
+
+st_%.o: st_%.c
+       $(CC) -c -o $@ $< $(common_CPPFLAGS) $($*_CPPFLAGS) $(DEFINES) $(CFLAGS)
+
+install: $(OUTPUTS)
+       $(INSTALL) -d $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR)
+       for out in $(OUTPUTS); do \
+               $(MINSTALL) -m 755 "$$out" $(DESTDIR)$(EGL_DRIVER_INSTALL_DIR); \
+       done
+
+clean:
+       rm -f *.o
diff --git a/src/gallium/targets/egl/egl.c b/src/gallium/targets/egl/egl.c
new file mode 100644 (file)
index 0000000..d9d8948
--- /dev/null
@@ -0,0 +1,428 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION 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:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "util/u_debug.h"
+#include "util/u_string.h"
+#include "util/u_memory.h"
+#include "util/u_dl.h"
+#include "egldriver.h"
+#include "egllog.h"
+
+#include "state_tracker/st_api.h"
+#include "state_tracker/drm_driver.h"
+#include "common/egl_g3d_loader.h"
+
+struct egl_g3d_loader egl_g3d_loader;
+
+static struct st_module {
+   boolean initialized;
+   char *name;
+   struct util_dl_library *lib;
+   struct st_api *stapi;
+} st_modules[ST_API_COUNT];
+
+static struct pipe_module {
+   boolean initialized;
+   char *name;
+   struct util_dl_library *lib;
+   const struct drm_driver_descriptor *drmdd;
+   struct pipe_screen *(*swrast_create_screen)(struct sw_winsys *);
+} pipe_modules[16];
+
+static char *
+loader_strdup(const char *s)
+{
+   size_t len = (s) ? strlen(s) : 0;
+   char *t = MALLOC(len + 1);
+   if (t) {
+      memcpy(t, s, len);
+      t[len] = '\0';
+   }
+   return t;
+}
+
+static EGLBoolean
+dlopen_st_module_cb(const char *dir, size_t len, void *callback_data)
+{
+   struct st_module *stmod =
+      (struct st_module *) callback_data;
+   char path[1024];
+   int ret;
+
+   if (len) {
+      ret = util_snprintf(path, sizeof(path),
+            "%.*s/" ST_PREFIX "%s" UTIL_DL_EXT, len, dir, stmod->name);
+   }
+   else {
+      ret = util_snprintf(path, sizeof(path),
+            ST_PREFIX "%s" UTIL_DL_EXT, stmod->name);
+   }
+
+   if (ret > 0 && ret < sizeof(path)) {
+      stmod->lib = util_dl_open(path);
+      if (stmod->lib)
+         _eglLog(_EGL_DEBUG, "loaded %s", path);
+   }
+
+   return !(stmod->lib);
+}
+
+static boolean
+load_st_module(struct st_module *stmod,
+                       const char *name, const char *procname)
+{
+   struct st_api *(*create_api)(void);
+
+   stmod->name = loader_strdup(name);
+   if (stmod->name)
+      _eglSearchPathForEach(dlopen_st_module_cb, (void *) stmod);
+   else
+      stmod->lib = util_dl_open(NULL);
+
+   if (stmod->lib) {
+      create_api = (struct st_api *(*)(void))
+         util_dl_get_proc_address(stmod->lib, procname);
+      if (create_api)
+         stmod->stapi = create_api();
+
+      if (!stmod->stapi) {
+         util_dl_close(stmod->lib);
+         stmod->lib = NULL;
+      }
+   }
+
+   if (!stmod->stapi) {
+      FREE(stmod->name);
+      stmod->name = NULL;
+   }
+
+   return (stmod->stapi != NULL);
+}
+
+static EGLBoolean
+dlopen_pipe_module_cb(const char *dir, size_t len, void *callback_data)
+{
+   struct pipe_module *pmod = (struct pipe_module *) callback_data;
+   char path[1024];
+   int ret;
+
+   if (len) {
+      ret = util_snprintf(path, sizeof(path),
+            "%.*s/" PIPE_PREFIX "%s" UTIL_DL_EXT, len, dir, pmod->name);
+   }
+   else {
+      ret = util_snprintf(path, sizeof(path),
+            PIPE_PREFIX "%s" UTIL_DL_EXT, pmod->name);
+   }
+   if (ret > 0 && ret < sizeof(path)) {
+      pmod->lib = util_dl_open(path);
+      if (pmod->lib)
+         _eglLog(_EGL_DEBUG, "loaded %s", path);
+   }
+
+   return !(pmod->lib);
+}
+
+static boolean
+load_pipe_module(struct pipe_module *pmod, const char *name)
+{
+   pmod->name = loader_strdup(name);
+   if (!pmod->name)
+      return FALSE;
+
+   _eglSearchPathForEach(dlopen_pipe_module_cb, (void *) pmod);
+   if (pmod->lib) {
+      pmod->drmdd = (const struct drm_driver_descriptor *)
+         util_dl_get_proc_address(pmod->lib, "driver_descriptor");
+      if (pmod->drmdd) {
+         if (pmod->drmdd->driver_name) {
+            /* driver name mismatch */
+            if (strcmp(pmod->drmdd->driver_name, pmod->name) != 0)
+               pmod->drmdd = NULL;
+         }
+         else {
+            /* swrast */
+            pmod->swrast_create_screen =
+               (struct pipe_screen *(*)(struct sw_winsys *))
+               util_dl_get_proc_address(pmod->lib, "swrast_create_screen");
+            if (!pmod->swrast_create_screen)
+               pmod->drmdd = NULL;
+         }
+      }
+
+      if (!pmod->drmdd) {
+         util_dl_close(pmod->lib);
+         pmod->lib = NULL;
+      }
+   }
+
+   if (!pmod->drmdd)
+      pmod->name = NULL;
+
+   return (pmod->drmdd != NULL);
+}
+
+static struct st_api *
+get_st_api(enum st_api_type api)
+{
+   struct st_module *stmod = &st_modules[api];
+   const char *names[8], *symbol;
+   int i, count = 0;
+
+   if (stmod->initialized)
+      return stmod->stapi;
+
+   switch (api) {
+   case ST_API_OPENGL:
+      symbol = ST_CREATE_OPENGL_SYMBOL;
+      names[count++] = "GL";
+      break;
+   case ST_API_OPENGL_ES1:
+      symbol = ST_CREATE_OPENGL_ES1_SYMBOL;
+      names[count++] = "GLESv1_CM";
+      names[count++] = "GL";
+      break;
+   case ST_API_OPENGL_ES2:
+      symbol = ST_CREATE_OPENGL_ES2_SYMBOL;
+      names[count++] = "GLESv2";
+      names[count++] = "GL";
+      break;
+   case ST_API_OPENVG:
+      symbol = ST_CREATE_OPENVG_SYMBOL;
+      names[count++] = "OpenVG";
+      break;
+   default:
+      symbol = NULL;
+      assert(!"Unknown API Type\n");
+      break;
+   }
+
+   /* NULL means the process itself */
+   names[count++] = NULL;
+
+   for (i = 0; i < count; i++) {
+      if (load_st_module(stmod, names[i], symbol))
+         break;
+   }
+
+   if (!stmod->stapi) {
+      EGLint level = (egl_g3d_loader.api_mask & (1 << api)) ?
+         _EGL_WARNING : _EGL_DEBUG;
+      _eglLog(level, "unable to load " ST_PREFIX "%s" UTIL_DL_EXT, names[0]);
+   }
+
+   stmod->initialized = TRUE;
+
+   return stmod->stapi;
+}
+
+static struct st_api *
+guess_gl_api(void)
+{
+   struct st_api *stapi;
+   int gl_apis[] = {
+      ST_API_OPENGL,
+      ST_API_OPENGL_ES1,
+      ST_API_OPENGL_ES2,
+      -1
+   };
+   int i, api = -1;
+
+   /* determine the api from the loaded libraries */
+   for (i = 0; gl_apis[i] != -1; i++) {
+      if (st_modules[gl_apis[i]].stapi) {
+         api = gl_apis[i];
+         break;
+      }
+   }
+   /* determine the api from the linked libraries */
+   if (api == -1) {
+      struct util_dl_library *self = util_dl_open(NULL);
+
+      if (self) {
+         if (util_dl_get_proc_address(self, "glColor4d"))
+            api = ST_API_OPENGL;
+         else if (util_dl_get_proc_address(self, "glColor4x"))
+            api = ST_API_OPENGL_ES1;
+         else if (util_dl_get_proc_address(self, "glShaderBinary"))
+            api = ST_API_OPENGL_ES2;
+         util_dl_close(self);
+      }
+   }
+
+   stapi = (api != -1) ? get_st_api(api) : NULL;
+   if (!stapi) {
+      for (i = 0; gl_apis[i] != -1; i++) {
+         api = gl_apis[i];
+         stapi = get_st_api(api);
+         if (stapi)
+            break;
+      }
+   }
+
+   return stapi;
+}
+
+static struct pipe_module *
+get_pipe_module(const char *name)
+{
+   struct pipe_module *pmod = NULL;
+   int i;
+
+   if (!name)
+      return NULL;
+
+   for (i = 0; i < Elements(pipe_modules); i++) {
+      if (!pipe_modules[i].initialized ||
+          strcmp(pipe_modules[i].name, name) == 0) {
+         pmod = &pipe_modules[i];
+         break;
+      }
+   }
+   if (!pmod)
+      return NULL;
+
+   if (!pmod->initialized) {
+      load_pipe_module(pmod, name);
+      pmod->initialized = TRUE;
+   }
+
+   return pmod;
+}
+
+static struct pipe_screen *
+create_drm_screen(const char *name, int fd)
+{
+   struct pipe_module *pmod = get_pipe_module(name);
+   return (pmod && pmod->drmdd->create_screen) ?
+      pmod->drmdd->create_screen(fd) : NULL;
+}
+
+static struct pipe_screen *
+create_sw_screen(struct sw_winsys *ws)
+{
+   struct pipe_module *pmod = get_pipe_module("swrast");
+   return (pmod && pmod->swrast_create_screen) ?
+      pmod->swrast_create_screen(ws) : NULL;
+}
+
+static const struct egl_g3d_loader *
+loader_init(void)
+{
+   uint api_mask = 0x0;
+
+   /* TODO detect at runtime? */
+#if FEATURE_GL
+   api_mask |= 1 << ST_API_OPENGL;
+#endif
+#if FEATURE_ES1
+   api_mask |= 1 << ST_API_OPENGL_ES1;
+#endif
+#if FEATURE_ES2
+   api_mask |= 1 << ST_API_OPENGL_ES2;
+#endif
+#if FEATURE_VG
+   api_mask |= 1 << ST_API_OPENVG;
+#endif
+
+   egl_g3d_loader.api_mask = api_mask;
+   egl_g3d_loader.get_st_api = get_st_api;
+   egl_g3d_loader.guess_gl_api = guess_gl_api;
+   egl_g3d_loader.create_drm_screen = create_drm_screen;
+   egl_g3d_loader.create_sw_screen = create_sw_screen;
+
+   return &egl_g3d_loader;
+}
+
+static void
+loader_fini(void)
+{
+   int i;
+
+   for (i = 0; i < ST_API_COUNT; i++) {
+      struct st_module *stmod = &st_modules[i];
+
+      if (stmod->stapi) {
+         stmod->stapi->destroy(stmod->stapi);
+         stmod->stapi = NULL;
+      }
+      if (stmod->lib) {
+         util_dl_close(stmod->lib);
+         stmod->lib = NULL;
+      }
+      if (stmod->name) {
+         FREE(stmod->name);
+         stmod->name = NULL;
+      }
+      stmod->initialized = FALSE;
+   }
+   for (i = 0; i < Elements(pipe_modules); i++) {
+      struct pipe_module *pmod = &pipe_modules[i];
+
+      if (!pmod->initialized)
+         break;
+
+      pmod->drmdd = NULL;
+      pmod->swrast_create_screen = NULL;
+      if (pmod->lib) {
+         util_dl_close(pmod->lib);
+         pmod->lib = NULL;
+      }
+      if (pmod->name) {
+         FREE(pmod->name);
+         pmod->name = NULL;
+      }
+      pmod->initialized = FALSE;
+   }
+}
+
+static void
+egl_g3d_unload(_EGLDriver *drv)
+{
+   egl_g3d_destroy_driver(drv);
+   loader_fini();
+}
+
+_EGLDriver *
+_eglMain(const char *args)
+{
+   const struct egl_g3d_loader *loader;
+   _EGLDriver *drv;
+
+   loader = loader_init();
+   drv = egl_g3d_create_driver(loader);
+   if (!drv) {
+      loader_fini();
+      return NULL;
+   }
+
+   drv->Name = "Gallium";
+   drv->Unload = egl_g3d_unload;
+
+   return drv;
+}
diff --git a/src/gallium/targets/egl/pipe_i915.c b/src/gallium/targets/egl/pipe_i915.c
new file mode 100644 (file)
index 0000000..758a921
--- /dev/null
@@ -0,0 +1,28 @@
+
+#include "target-helpers/inline_wrapper_sw_helper.h"
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "i915/drm/i915_drm_public.h"
+#include "i915/i915_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct i915_winsys *iws;
+   struct pipe_screen *screen;
+
+   iws = i915_drm_winsys_create(fd);
+   if (!iws)
+      return NULL;
+
+   screen = i915_screen_create(iws);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+PUBLIC
+DRM_DRIVER_DESCRIPTOR("i915", "i915", create_screen)
diff --git a/src/gallium/targets/egl/pipe_i965.c b/src/gallium/targets/egl/pipe_i965.c
new file mode 100644 (file)
index 0000000..43bf646
--- /dev/null
@@ -0,0 +1,31 @@
+
+#include "target-helpers/inline_wrapper_sw_helper.h"
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "i965/drm/i965_drm_public.h"
+#include "i965/brw_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct brw_winsys_screen *bws;
+   struct pipe_screen *screen;
+
+   bws = i965_drm_winsys_screen_create(fd);
+   if (!bws)
+      return NULL;
+
+   screen = brw_screen_create(bws);
+   if (!screen)
+      return NULL;
+
+   if (debug_get_bool_option("BRW_SOFTPIPE", FALSE))
+      screen = sw_screen_wrap(screen);
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+PUBLIC
+DRM_DRIVER_DESCRIPTOR("i965", "i965", create_screen)
diff --git a/src/gallium/targets/egl/pipe_nouveau.c b/src/gallium/targets/egl/pipe_nouveau.c
new file mode 100644 (file)
index 0000000..0c9081b
--- /dev/null
@@ -0,0 +1,21 @@
+
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "nouveau/drm/nouveau_drm_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct pipe_screen *screen;
+
+   screen = nouveau_drm_screen_create(fd);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+PUBLIC
+DRM_DRIVER_DESCRIPTOR("nouveau", "nouveau", create_screen)
diff --git a/src/gallium/targets/egl/pipe_radeon.c b/src/gallium/targets/egl/pipe_radeon.c
new file mode 100644 (file)
index 0000000..35550bc
--- /dev/null
@@ -0,0 +1,27 @@
+
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "radeon/drm/radeon_drm_public.h"
+#include "r300/r300_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct r300_winsys_screen *sws;
+   struct pipe_screen *screen;
+
+   sws = r300_drm_winsys_screen_create(fd);
+   if (!sws)
+      return NULL;
+
+   screen = r300_screen_create(sws);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+PUBLIC
+DRM_DRIVER_DESCRIPTOR("radeon", "radeon", create_screen)
diff --git a/src/gallium/targets/egl/pipe_swrast.c b/src/gallium/targets/egl/pipe_swrast.c
new file mode 100644 (file)
index 0000000..b2e3289
--- /dev/null
@@ -0,0 +1,22 @@
+
+#include "target-helpers/inline_sw_helper.h"
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+
+PUBLIC struct pipe_screen *
+swrast_create_screen(struct sw_winsys *ws);
+
+PUBLIC
+DRM_DRIVER_DESCRIPTOR("swrast", NULL, NULL)
+
+struct pipe_screen *
+swrast_create_screen(struct sw_winsys *ws)
+{
+   struct pipe_screen *screen;
+
+   screen = sw_screen_create(ws);
+   if (screen)
+      screen = debug_screen_wrap(screen);
+
+   return screen;
+}
diff --git a/src/gallium/targets/egl/pipe_vmwgfx.c b/src/gallium/targets/egl/pipe_vmwgfx.c
new file mode 100644 (file)
index 0000000..22a28fa
--- /dev/null
@@ -0,0 +1,27 @@
+
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "svga/drm/svga_drm_public.h"
+#include "svga/svga_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct svga_winsys_screen *sws;
+   struct pipe_screen *screen;
+
+   sws = svga_drm_winsys_screen_create(fd);
+   if (!sws)
+      return NULL;
+
+   screen = svga_screen_create(sws);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+PUBLIC
+DRM_DRIVER_DESCRIPTOR("vmwgfx", "vmwgfx", create_screen)
diff --git a/src/gallium/targets/egl/st_GL.c b/src/gallium/targets/egl/st_GL.c
new file mode 100644 (file)
index 0000000..676300b
--- /dev/null
@@ -0,0 +1,25 @@
+#include "state_tracker/st_gl_api.h"
+
+#if FEATURE_GL
+PUBLIC struct st_api *
+st_api_create_OpenGL(void)
+{
+   return st_gl_api_create();
+}
+#endif
+
+#if FEATURE_ES1
+PUBLIC struct st_api *
+st_api_create_OpenGL_ES1(void)
+{
+   return st_gl_api_create_es1();
+}
+#endif
+
+#if FEATURE_ES2
+PUBLIC struct st_api *
+st_api_create_OpenGL_ES2(void)
+{
+   return st_gl_api_create_es2();
+}
+#endif
diff --git a/src/gallium/targets/egl/st_GLESv1_CM.c b/src/gallium/targets/egl/st_GLESv1_CM.c
new file mode 100644 (file)
index 0000000..0c8de89
--- /dev/null
@@ -0,0 +1,7 @@
+#include "state_tracker/st_gl_api.h"
+
+PUBLIC struct st_api *
+st_api_create_OpenGL_ES1(void)
+{
+   return st_gl_api_create_es1();
+}
diff --git a/src/gallium/targets/egl/st_GLESv2.c b/src/gallium/targets/egl/st_GLESv2.c
new file mode 100644 (file)
index 0000000..87b3e65
--- /dev/null
@@ -0,0 +1,7 @@
+#include "state_tracker/st_gl_api.h"
+
+PUBLIC struct st_api *
+st_api_create_OpenGL_ES2(void)
+{
+   return st_gl_api_create_es2();
+}
diff --git a/src/gallium/targets/egl/st_OpenVG.c b/src/gallium/targets/egl/st_OpenVG.c
new file mode 100644 (file)
index 0000000..e29a237
--- /dev/null
@@ -0,0 +1,8 @@
+#include "state_tracker/st_api.h"
+#include "vg_api.h"
+
+PUBLIC struct st_api *
+st_api_create_OpenVG(void)
+{
+   return (struct st_api *) vg_api_get();
+}
index b173ceb994ab4e9b260e7dc888c8cf690afa13b8..e745023ba598ce439066e41e4e4b01b7463c02bf 100644 (file)
@@ -97,7 +97,7 @@ tags:
        etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h
 
 clean:
-       -rm -f *.o
+       -rm -f *.o depend
 
 
 include depend
index 18f07d6d8f217595db179e5c096c198fc137fed6..865240404ca21bda00d873be7bbe1073ee0f539f 100644 (file)
@@ -4,19 +4,21 @@ include $(TOP)/configs/current
 LIBNAME = modesetting_drv.so
 
 C_SOURCES = \
+       intel_target.c \
        intel_xorg.c
 
 DRIVER_DEFINES = \
-       -DHAVE_CONFIG_H
+       -DHAVE_CONFIG_H -DGALLIUM_RBUG -DGALLIUM_TRACE -DGALLIUM_GALAHAD
 
-DRIVER_LINKS = \
+DRIVER_PIPES = \
        $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
        $(TOP)/src/gallium/winsys/i915/drm/libi915drm.a \
        $(TOP)/src/gallium/drivers/i915/libi915.a \
+       $(TOP)/src/gallium/drivers/galahad/libgalahad.a \
        $(TOP)/src/gallium/drivers/trace/libtrace.a \
-       $(TOP)/src/gallium/drivers/rbug/librbug.a \
-       $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
-       $(GALLIUM_AUXILIARIES) \
+       $(TOP)/src/gallium/drivers/rbug/librbug.a
+
+DRIVER_LINKS = \
        $(shell pkg-config --libs libdrm libdrm_intel)
 
 include ../Makefile.xorg
diff --git a/src/gallium/targets/xorg-i915/intel_target.c b/src/gallium/targets/xorg-i915/intel_target.c
new file mode 100644 (file)
index 0000000..8c8ef7e
--- /dev/null
@@ -0,0 +1,26 @@
+
+#include "state_tracker/drm_driver.h"
+#include "target-helpers/inline_debug_helper.h"
+#include "i915/drm/i915_drm_public.h"
+#include "i915/i915_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct i915_winsys *iws;
+   struct pipe_screen *screen;
+
+   iws = i915_drm_winsys_create(fd);
+   if (!iws)
+      return NULL;
+
+   screen = i915_screen_create(iws);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("i915", "i915", create_screen)
index 2b0c7d6fdf67ec8fef9dcfafed427670edb3e021..494dce41c8ad3c3583fc23dbf4a73bfe0ee04ca8 100644 (file)
@@ -4,19 +4,23 @@ include $(TOP)/configs/current
 LIBNAME = i965g_drv.so
 
 C_SOURCES = \
+       intel_target.c \
        intel_xorg.c
 
 DRIVER_DEFINES = \
-       -DHAVE_CONFIG_H
+       -DHAVE_CONFIG_H -DGALLIUM_SOFTPIPE \
+       -DGALLIUM_RBUG -DGALLIUM_TRACE
 
-DRIVER_LINKS = \
+DRIVER_PIPES = \
        $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
        $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \
        $(TOP)/src/gallium/drivers/i965/libi965.a \
        $(TOP)/src/gallium/drivers/trace/libtrace.a \
        $(TOP)/src/gallium/drivers/rbug/librbug.a \
-       $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
-       $(GALLIUM_AUXILIARIES) \
+       $(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a \
+       $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a
+
+DRIVER_LINKS = \
        $(shell pkg-config --libs libdrm libdrm_intel)
 
 include ../Makefile.xorg
diff --git a/src/gallium/targets/xorg-i965/intel_target.c b/src/gallium/targets/xorg-i965/intel_target.c
new file mode 100644 (file)
index 0000000..ce97f82
--- /dev/null
@@ -0,0 +1,30 @@
+
+#include "target-helpers/inline_wrapper_sw_helper.h"
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "i965/drm/i965_drm_public.h"
+#include "i965/brw_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct brw_winsys_screen *bws;
+   struct pipe_screen *screen;
+
+   bws = i965_drm_winsys_screen_create(fd);
+   if (!bws)
+      return NULL;
+
+   screen = brw_screen_create(bws);
+   if (!screen)
+      return NULL;
+
+   if (debug_get_bool_option("BRW_SOFTPIPE", FALSE))
+      screen = sw_screen_wrap(screen);
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("i915", "i965", create_screen)
index f50872362f663d2c6f28f4e3d7ad43428df31f25..2fcd9ffb7d65cb922862ceb6e1fc9bca6843cb68 100644 (file)
@@ -4,18 +4,22 @@ include $(TOP)/configs/current
 LIBNAME = modesetting_drv.so
 
 C_SOURCES = \
+       nouveau_target.c \
        nouveau_xorg.c
 
 DRIVER_DEFINES = \
-       -DHAVE_CONFIG_H
+       -DHAVE_CONFIG_H -DGALLIUM_RBUG -DGALLIUM_TRACE
 
-DRIVER_LINKS = \
+DRIVER_PIPES = \
        $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
        $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \
        $(TOP)/src/gallium/drivers/nvfx/libnvfx.a \
        $(TOP)/src/gallium/drivers/nv50/libnv50.a \
        $(TOP)/src/gallium/drivers/nouveau/libnouveau.a \
-       $(GALLIUM_AUXILIARIES) \
+       $(TOP)/src/gallium/drivers/trace/libtrace.a \
+       $(TOP)/src/gallium/drivers/rbug/librbug.a
+
+DRIVER_LINKS = \
        $(shell pkg-config --libs libdrm libdrm_nouveau)
 
 include ../Makefile.xorg
diff --git a/src/gallium/targets/xorg-nouveau/nouveau_target.c b/src/gallium/targets/xorg-nouveau/nouveau_target.c
new file mode 100644 (file)
index 0000000..e725a4d
--- /dev/null
@@ -0,0 +1,20 @@
+
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "nouveau/drm/nouveau_drm_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct pipe_screen *screen;
+
+   screen = nouveau_drm_screen_create(fd);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("nouveau", "nouveau", create_screen)
index a4951c4bba0cc0d646e2078868901ef1c1ac9c15..d3bc35699290d5d97239dc78fa1a6a4aca9a6cdc 100644 (file)
@@ -4,19 +4,21 @@ include $(TOP)/configs/current
 LIBNAME = radeon_drv.so
 
 C_SOURCES = \
+       radeon_target.c \
        radeon_xorg.c
 
 DRIVER_DEFINES = \
-       -DHAVE_CONFIG_H
+       -DHAVE_CONFIG_H -DGALLIUM_RBUG -DGALLIUM_TRACE -DGALLIUM_GALAHAD
+
+DRIVER_PIPES = \
+       $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
+       $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \
+       $(TOP)/src/gallium/drivers/r300/libr300.a \
+       $(TOP)/src/gallium/drivers/galahad/libgalahad.a \
+       $(TOP)/src/gallium/drivers/trace/libtrace.a \
+       $(TOP)/src/gallium/drivers/rbug/librbug.a
 
 DRIVER_LINKS = \
-        $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
-        $(TOP)/src/gallium/winsys/radeon/drm/libradeonwinsys.a \
-        $(TOP)/src/gallium/drivers/r300/libr300.a \
-        $(TOP)/src/gallium/drivers/trace/libtrace.a \
-        $(TOP)/src/gallium/drivers/rbug/librbug.a \
-        $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
-        $(GALLIUM_AUXILIARIES) \
-       $(shell pkg-config --libs libdrm libdrm_intel)
+       $(shell pkg-config --libs libdrm libdrm_radeon)
 
 include ../Makefile.xorg
diff --git a/src/gallium/targets/xorg-radeon/radeon_target.c b/src/gallium/targets/xorg-radeon/radeon_target.c
new file mode 100644 (file)
index 0000000..5a0a8dc
--- /dev/null
@@ -0,0 +1,26 @@
+
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "radeon/drm/radeon_drm_public.h"
+#include "r300/r300_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct r300_winsys_screen *sws;
+   struct pipe_screen *screen;
+
+   sws = r300_drm_winsys_screen_create(fd);
+   if (!sws)
+      return NULL;
+
+   screen = r300_screen_create(sws);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("radeon", "radeon", create_screen)
index c0ff999116533913c491e658ad8e3d879457cd6e..04a444f5e93b5c0770b1fc9eb287e152d787bf62 100644 (file)
@@ -8,6 +8,7 @@ C_SOURCES = \
        vmw_video.c \
        vmw_ioctl.c \
        vmw_ctrl.c \
+       vmw_target.c \
        vmw_screen.c
 
 DRIVER_INCLUDES = \
@@ -15,16 +16,18 @@ DRIVER_INCLUDES = \
 
 DRIVER_DEFINES = \
        -std=gnu99 \
+       -DGALLIUM_RBUG \
+       -DGALLIUM_TRACE \
        -DHAVE_CONFIG_H
 
-DRIVER_LINKS = \
+DRIVER_PIPES = \
        $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
        $(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \
-       $(TOP)/src/gallium/drivers/trace/libtrace.a \
-       $(TOP)/src/gallium/drivers/rbug/librbug.a \
        $(TOP)/src/gallium/drivers/svga/libsvga.a \
-       $(GALLIUM_AUXILIARIES) \
-       $(shell pkg-config --libs --silence-errors libkms) \
-       $(shell pkg-config --libs libdrm)
+       $(TOP)/src/gallium/drivers/trace/libtrace.a \
+       $(TOP)/src/gallium/drivers/rbug/librbug.a
+
+DRIVER_LINKS = \
+       $(shell pkg-config --libs libdrm libkms)
 
 include ../Makefile.xorg
index 1cc8ddaac34c1accbb375a974b5e7c5dd50c5b79..237b308ae353f6c56086743b469020768fcc3452 100644 (file)
@@ -32,9 +32,6 @@
  *      allows X clients to communicate with the driver.
  */
 
-
-#define NEED_REPLIES
-#define NEED_EVENTS
 #include "dixstruct.h"
 #include "extnsionst.h"
 #include <X11/X.h>
index d6e3620cd3d1baf8cfbb7a1a578e6afc566b89b6..8dfc9d2efb4bd772af3a87eb997dd6cb3f77ce49 100644 (file)
@@ -59,6 +59,7 @@ struct vmw_customizer
 
     /* vmw_video.c */
     void *video_priv;
+    uint64_t max_fb_size;
 };
 
 static INLINE struct vmw_customizer *
index 64934d53f6893ef9174d86c6b5824e94cc50ec22..8173908f551338f5e99d484166ae5f0583c674e7 100644 (file)
@@ -35,6 +35,7 @@
 #include <pipe/p_context.h>
 
 #include "cursorstr.h"
+#include "../../winsys/svga/drm/vmwgfx_drm.h"
 
 void vmw_winsys_screen_set_throttling(struct pipe_screen *screen,
                                      uint32_t throttle_us);
@@ -111,13 +112,29 @@ vmw_context_no_throttle(CustomizerPtr cust,
 }
 
 static Bool
-vmw_screen_init(CustomizerPtr cust, int fd)
+vmw_check_fb_size(CustomizerPtr cust,
+                 unsigned long pitch,
+                 unsigned long height)
+{
+    struct vmw_customizer *vmw = vmw_customizer(cust);
+
+    /**
+     *  1) Is there a pitch alignment?
+     *  2) The 1024 byte pad is an arbitrary value to be on
+     */
+
+    return ((uint64_t) pitch * height + 1024ULL < vmw->max_fb_size);
+}
+
+static Bool
+vmw_pre_init(CustomizerPtr cust, int fd)
 {
     struct vmw_customizer *vmw = vmw_customizer(cust);
     drmVersionPtr ver;
 
     vmw->fd = fd;
-    ver = drmGetVersion(fd);
+
+    ver = drmGetVersion(vmw->fd);
     if (ver == NULL ||
        (ver->version_major == 1 && ver->version_minor < 1)) {
        cust->swap_throttling = TRUE;
@@ -128,11 +145,34 @@ vmw_screen_init(CustomizerPtr cust, int fd)
        cust->dirty_throttling = FALSE;
        cust->winsys_context_throttle = vmw_context_throttle;
        debug_printf("%s: Enabling kernel throttling.\n", __func__);
+
+       if (ver->version_major > 1 ||
+           (ver->version_major == 1 && ver->version_minor >= 3)) {
+           struct drm_vmw_getparam_arg arg;
+           int ret;
+
+           arg.param = DRM_VMW_PARAM_MAX_FB_SIZE;
+           ret = drmCommandWriteRead(fd, DRM_VMW_GET_PARAM, &arg,
+                                     sizeof(arg));
+           if (!ret) {
+               vmw->max_fb_size = arg.value;
+               cust->winsys_check_fb_size = vmw_check_fb_size;
+               debug_printf("%s: Enabling fb size check.\n", __func__);
+           }
+       }
     }
 
     if (ver)
        drmFreeVersion(ver);
 
+    return TRUE;
+}
+
+static Bool
+vmw_screen_init(CustomizerPtr cust)
+{
+    struct vmw_customizer *vmw = vmw_customizer(cust);
+
     vmw_screen_cursor_init(vmw);
 
     vmw_ctrl_ext_init(vmw);
@@ -199,6 +239,7 @@ vmw_screen_pre_init(ScrnInfoPtr pScrn, int flags)
 
     cust = &vmw->base;
 
+    cust->winsys_pre_init = vmw_pre_init;
     cust->winsys_screen_init = vmw_screen_init;
     cust->winsys_screen_close = vmw_screen_close;
     cust->winsys_enter_vt = vmw_screen_enter_vt;
diff --git a/src/gallium/targets/xorg-vmwgfx/vmw_target.c b/src/gallium/targets/xorg-vmwgfx/vmw_target.c
new file mode 100644 (file)
index 0000000..15089d6
--- /dev/null
@@ -0,0 +1,26 @@
+
+#include "target-helpers/inline_debug_helper.h"
+#include "state_tracker/drm_driver.h"
+#include "svga/drm/svga_drm_public.h"
+#include "svga/svga_public.h"
+
+static struct pipe_screen *
+create_screen(int fd)
+{
+   struct svga_winsys_screen *sws;
+   struct pipe_screen *screen;
+
+   sws = svga_drm_winsys_screen_create(fd);
+   if (!sws)
+      return NULL;
+
+   screen = svga_screen_create(sws);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("vmwgfx", "vmwgfx", create_screen)
index a40d66d4a1d24483b6fb8dd85ec7f48a04156993..61121732e387f2678081f7b3dc5e1be3192a23bc 100644 (file)
@@ -14,6 +14,7 @@ env.Prepend(LIBS = ['graw'] + gallium)
 progs = [
     'clear',
     'tri',
+    'tri-instanced',
     'quad-tex',
     'fs-test',
     'vs-test',
diff --git a/src/gallium/tests/graw/tri-instanced.c b/src/gallium/tests/graw/tri-instanced.c
new file mode 100644 (file)
index 0000000..30e205f
--- /dev/null
@@ -0,0 +1,340 @@
+/*
+ * Test draw instancing.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "state_tracker/graw.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "pipe/p_defines.h"
+
+#include "util/u_debug.h"       /* debug_dump_surface_bmp() */
+#include "util/u_memory.h"      /* Offset() */
+
+
+enum pipe_format formats[] = {
+   PIPE_FORMAT_R8G8B8A8_UNORM,
+   PIPE_FORMAT_B8G8R8A8_UNORM,
+   PIPE_FORMAT_NONE
+};
+
+static const int WIDTH = 300;
+static const int HEIGHT = 300;
+
+static struct pipe_screen *screen = NULL;
+static struct pipe_context *ctx = NULL;
+static struct pipe_surface *surf = NULL;
+static struct pipe_resource *indexBuffer = NULL;
+static void *window = NULL;
+
+struct vertex {
+   float position[4];
+   float color[4];
+};
+
+
+static int draw_elements = 0;
+
+
+/**
+ * Vertex data.
+ * Each vertex has three attributes: position, color and translation.
+ * The translation attribute is a per-instance attribute.  See
+ * "instance_divisor" below.
+ */
+static struct vertex vertices[4] =
+{
+   {
+      { 0.0f, -0.3f, 0.0f, 1.0f },  /* pos */
+      { 1.0f, 0.0f, 0.0f, 1.0f }    /* color */
+   },
+   {
+      { -0.2f, 0.3f, 0.0f, 1.0f },
+      { 0.0f, 1.0f, 0.0f, 1.0f }
+   },
+   {
+      { 0.2f, 0.3f, 0.0f, 1.0f },
+      { 0.0f, 0.0f, 1.0f, 1.0f }
+   }
+};
+
+
+#define NUM_INST 5
+
+static float inst_data[NUM_INST][4] =
+{
+   { -0.50f, 0.4f, 0.0f, 0.0f },
+   { -0.25f, 0.1f, 0.0f, 0.0f },
+   { 0.00f, 0.2f, 0.0f, 0.0f },
+   { 0.25f, 0.1f, 0.0f, 0.0f },
+   { 0.50f, 0.3f, 0.0f, 0.0f }
+};
+
+
+static ushort indices[3] = { 0, 2, 1 };
+
+
+static void set_viewport( float x, float y,
+                          float width, float height,
+                          float near, float far)
+{
+   float z = far;
+   float half_width = (float)width / 2.0f;
+   float half_height = (float)height / 2.0f;
+   float half_depth = ((float)far - (float)near) / 2.0f;
+   struct pipe_viewport_state vp;
+
+   vp.scale[0] = half_width;
+   vp.scale[1] = half_height;
+   vp.scale[2] = half_depth;
+   vp.scale[3] = 1.0f;
+
+   vp.translate[0] = half_width + x;
+   vp.translate[1] = half_height + y;
+   vp.translate[2] = half_depth + z;
+   vp.translate[3] = 0.0f;
+
+   ctx->set_viewport_state( ctx, &vp );
+}
+
+
+static void set_vertices( void )
+{
+   struct pipe_vertex_element ve[3];
+   struct pipe_vertex_buffer vbuf[2];
+   void *handle;
+
+   memset(ve, 0, sizeof ve);
+
+   /* pos */
+   ve[0].src_offset = Offset(struct vertex, position);
+   ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+   ve[0].vertex_buffer_index = 0;
+
+   /* color */
+   ve[1].src_offset = Offset(struct vertex, color);
+   ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+   ve[1].vertex_buffer_index = 0;
+
+   /* per-instance info */
+   ve[2].src_offset = 0;
+   ve[2].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+   ve[2].vertex_buffer_index = 1;
+   ve[2].instance_divisor = 1;
+
+   handle = ctx->create_vertex_elements_state(ctx, 3, ve);
+   ctx->bind_vertex_elements_state(ctx, handle);
+
+
+   /* vertex data */
+   vbuf[0].stride = sizeof( struct vertex );
+   vbuf[0].max_index = sizeof(vertices) / vbuf[0].stride;
+   vbuf[0].buffer_offset = 0;
+   vbuf[0].buffer = screen->user_buffer_create(screen,
+                                               vertices,
+                                               sizeof(vertices),
+                                               PIPE_BIND_VERTEX_BUFFER);
+
+   /* instance data */
+   vbuf[1].stride = sizeof( inst_data[0] );
+   vbuf[1].max_index = sizeof(inst_data) / vbuf[1].stride;
+   vbuf[1].buffer_offset = 0;
+   vbuf[1].buffer = screen->user_buffer_create(screen,
+                                               inst_data,
+                                               sizeof(inst_data),
+                                               PIPE_BIND_VERTEX_BUFFER);
+
+
+   ctx->set_vertex_buffers(ctx, 2, vbuf);
+
+   /* index data */
+   indexBuffer = screen->user_buffer_create(screen,
+                                            indices,
+                                            sizeof(indices),
+                                            PIPE_BIND_VERTEX_BUFFER);
+
+
+}
+
+static void set_vertex_shader( void )
+{
+   void *handle;
+   const char *text =
+      "VERT\n"
+      "DCL IN[0]\n"
+      "DCL IN[1]\n"
+      "DCL IN[2]\n"
+      "DCL OUT[0], POSITION\n"
+      "DCL OUT[1], COLOR\n"
+      "  0: MOV OUT[1], IN[1]\n"
+      "  1: ADD OUT[0], IN[0], IN[2]\n"  /* add instance pos to vertex pos */
+      "  2: END\n";
+
+   handle = graw_parse_vertex_shader(ctx, text);
+   ctx->bind_vs_state(ctx, handle);
+}
+
+static void set_fragment_shader( void )
+{
+   void *handle;
+   const char *text =
+      "FRAG\n"
+      "DCL IN[0], COLOR, LINEAR\n"
+      "DCL OUT[0], COLOR\n"
+      "  0: MOV OUT[0], IN[0]\n"
+      "  1: END\n";
+
+   handle = graw_parse_fragment_shader(ctx, text);
+   ctx->bind_fs_state(ctx, handle);
+}
+
+
+static void draw( void )
+{
+   float clear_color[4] = {1,0,1,1};
+
+   ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0);
+
+   /* draw NUM_INST triangles */
+   if (draw_elements)
+      ctx->draw_elements_instanced(ctx, indexBuffer, 2,
+                                   0, /* indexBias */
+                                   PIPE_PRIM_TRIANGLES,
+                                   0, 3, /* start, count */
+                                   0, NUM_INST); /* startInst, instCount */
+   else
+      ctx->draw_arrays_instanced(ctx, PIPE_PRIM_TRIANGLES, 0, 3, 0, NUM_INST);
+
+   ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+#if 0
+   /* At the moment, libgraw leaks out/makes available some of the
+    * symbols from gallium/auxiliary, including these debug helpers.
+    * Will eventually want to bless some of these paths, and lock the
+    * others down so they aren't accessible from test programs.
+    *
+    * This currently just happens to work on debug builds - a release
+    * build will probably fail to link here:
+    */
+   debug_dump_surface_bmp(ctx, "result.bmp", surf);
+#endif
+
+   screen->flush_frontbuffer(screen, surf, window);
+}
+
+
+static void init( void )
+{
+   struct pipe_framebuffer_state fb;
+   struct pipe_resource *tex, templat;
+   int i;
+
+   /* It's hard to say whether window or screen should be created
+    * first.  Different environments would prefer one or the other.
+    *
+    * Also, no easy way of querying supported formats if the screen
+    * cannot be created first.
+    */
+   for (i = 0; 
+        window == NULL && formats[i] != PIPE_FORMAT_NONE;
+        i++) {
+      
+      screen = graw_create_window_and_screen(0,0,300,300,
+                                             formats[i],
+                                             &window);
+   }
+   
+   ctx = screen->context_create(screen, NULL);
+   if (ctx == NULL)
+      exit(3);
+
+   templat.target = PIPE_TEXTURE_2D;
+   templat.format = formats[i];
+   templat.width0 = WIDTH;
+   templat.height0 = HEIGHT;
+   templat.depth0 = 1;
+   templat.last_level = 0;
+   templat.nr_samples = 1;
+   templat.bind = (PIPE_BIND_RENDER_TARGET |
+                   PIPE_BIND_DISPLAY_TARGET);
+   
+   tex = screen->resource_create(screen,
+                                 &templat);
+   if (tex == NULL)
+      exit(4);
+
+   surf = screen->get_tex_surface(screen, tex, 0, 0, 0,
+                                  PIPE_BIND_RENDER_TARGET |
+                                  PIPE_BIND_DISPLAY_TARGET);
+   if (surf == NULL)
+      exit(5);
+
+   memset(&fb, 0, sizeof fb);
+   fb.nr_cbufs = 1;
+   fb.width = WIDTH;
+   fb.height = HEIGHT;
+   fb.cbufs[0] = surf;
+
+   ctx->set_framebuffer_state(ctx, &fb);
+   
+   {
+      struct pipe_blend_state blend;
+      void *handle;
+      memset(&blend, 0, sizeof blend);
+      blend.rt[0].colormask = PIPE_MASK_RGBA;
+      handle = ctx->create_blend_state(ctx, &blend);
+      ctx->bind_blend_state(ctx, handle);
+   }
+
+   {
+      struct pipe_depth_stencil_alpha_state depthstencil;
+      void *handle;
+      memset(&depthstencil, 0, sizeof depthstencil);
+      handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);
+      ctx->bind_depth_stencil_alpha_state(ctx, handle);
+   }
+
+   {
+      struct pipe_rasterizer_state rasterizer;
+      void *handle;
+      memset(&rasterizer, 0, sizeof rasterizer);
+      rasterizer.cull_face = PIPE_FACE_NONE;
+      rasterizer.gl_rasterization_rules = 1;
+      handle = ctx->create_rasterizer_state(ctx, &rasterizer);
+      ctx->bind_rasterizer_state(ctx, handle);
+   }
+
+   set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);
+   set_vertices();
+   set_vertex_shader();
+   set_fragment_shader();
+}
+
+
+static void options(int argc, char *argv[])
+{
+   int i;
+   for (i = 1; i < argc; i++) {
+      if (strcmp(argv[i], "-e") == 0)
+         draw_elements = 1;
+   }
+   if (draw_elements)
+      printf("Using pipe_context::draw_elements_instanced()\n");
+   else
+      printf("Using pipe_context::draw_arrays_instanced()\n");
+}
+
+
+int main( int argc, char *argv[] )
+{
+   options(argc, argv);
+
+   init();
+
+   graw_set_display_func( draw );
+   graw_main_loop();
+   return 0;
+}
index bfcbdd9712db59f3ef7e0d188c7010f93b67bc73..2ed63419c7ecf05013dd3da472e43c9a1510bf24 100644 (file)
@@ -12,7 +12,9 @@ INCLUDES = \
        $(PROG_INCLUDES)
 
 LINKS = \
+       $(TOP)/src/gallium/drivers/rbug/librbug.a \
        $(TOP)/src/gallium/drivers/trace/libtrace.a \
+       $(TOP)/src/gallium/drivers/galahad/libgalahad.a \
        $(TOP)/src/gallium/winsys/sw/null/libws_null.a \
        $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
        $(GALLIUM_AUXILIARIES) \
@@ -26,6 +28,9 @@ OBJECTS = $(SOURCES:.c=.o)
 
 PROGS = $(OBJECTS:.o=)
 
+PROG_DEFINES = \
+       -DGALLIUM_SOFTPIPE -DGALLIUM_RBUG -DGALLIUM_TRACE -DGALLIUM_GALAHAD
+
 ##### TARGETS #####
 
 default: $(PROGS)
index 93f24876cbb9099bb06ebee16ded82bd932c9f47..cf88edcdc56f91322ea3be2bad43c4570fe24e78 100644 (file)
 /* util_make_[fragment|vertex]_passthrough_shader */
 #include "util/u_simple_shaders.h"
 
-/* softpipe software driver */
-#include "softpipe/sp_public.h"
-
+/* sw_screen_create: to get a software pipe driver */
+#include "target-helpers/inline_sw_helper.h"
+/* debug_screen_wrap: to wrap with debug pipe drivers */
+#include "target-helpers/inline_debug_helper.h"
 /* null software winsys */
 #include "sw/null/null_sw_winsys.h"
 
-/* traceing support see src/gallium/drivers/trace/README for more info. */
-#if USE_TRACE
-#include "trace/tr_screen.h"
-#include "trace/tr_context.h"
-#endif
-
 struct program
 {
        struct pipe_screen *screen;
@@ -98,10 +93,11 @@ struct program
 static void init_prog(struct program *p)
 {
        /* create the software rasterizer */
-       p->screen = softpipe_create_screen(null_sw_create());
-#if USE_TRACE
-       p->screen = trace_screen_create(p->screen);
-#endif
+       p->screen = sw_screen_create(null_sw_create());
+       /* wrap the screen with any debugger */
+       p->screen = debug_screen_wrap(p->screen);
+
+       /* create the pipe driver context and cso context */
        p->pipe = p->screen->context_create(p->screen, NULL);
        p->cso = cso_create_context(p->pipe);
 
@@ -271,7 +267,7 @@ static void init_prog(struct program *p)
        }
 
        /* fragment shader */
-       p->fs = util_make_fragment_tex_shader(p->pipe, TGSI_TEXTURE_2D);
+       p->fs = util_make_fragment_tex_shader(p->pipe, TGSI_TEXTURE_2D, TGSI_INTERPOLATE_LINEAR);
 }
 
 static void close_prog(struct program *p)
index 7823c27727dab987b44c42ee5fc8dc11708f3dc8..667a27b28ab87363e55ecca72be4459b7c9ae4f8 100644 (file)
 /* util_make_[fragment|vertex]_passthrough_shader */
 #include "util/u_simple_shaders.h"
 
-/* softpipe software driver */
-#include "softpipe/sp_public.h"
-
+/* sw_screen_create: to get a software pipe driver */
+#include "target-helpers/inline_sw_helper.h"
+/* debug_screen_wrap: to wrap with debug pipe drivers */
+#include "target-helpers/inline_debug_helper.h"
 /* null software winsys */
 #include "sw/null/null_sw_winsys.h"
 
-/* traceing support see src/gallium/drivers/trace/README for more info. */
-#if USE_TRACE
-#include "trace/tr_screen.h"
-#include "trace/tr_context.h"
-#endif
-
 struct program
 {
        struct pipe_screen *screen;
@@ -93,10 +88,11 @@ struct program
 static void init_prog(struct program *p)
 {
        /* create the software rasterizer */
-       p->screen = softpipe_create_screen(null_sw_create());
-#if USE_TRACE
-       p->screen = trace_screen_create(p->screen);
-#endif
+       p->screen = sw_screen_create(null_sw_create());
+       /* wrap the screen with any debugger */
+       p->screen = debug_screen_wrap(p->screen);
+
+       /* create the pipe driver context and cso context */
        p->pipe = p->screen->context_create(p->screen, NULL);
        p->cso = cso_create_context(p->pipe);
 
index 907ac90bf04c323c8f1c116ddf5ee7d61befaf22..65b12287df7a82b08a3def547d6a276fdbea4804 100644 (file)
@@ -17,7 +17,6 @@ if 'gdi' in env['winsys']:
 
 if env['dri']:
        SConscript([
-               'sw/drm/SConscript',
                'sw/dri/SConscript',
        ])
 
index 102f59dc54172b55702a14aa66ddcb3be1668581..e50e7801c0a822c63bb995df2e9ba9f76201bbda 100644 (file)
@@ -3,6 +3,7 @@
 #include "util/u_memory.h"
 
 #include "i915_drm.h"
+#include "i915/i915_debug.h"
 
 #define BATCH_RESERVED 16
 
@@ -151,7 +152,6 @@ i915_drm_batchbuffer_flush(struct i915_winsys_batchbuffer *ibatch,
    struct i915_drm_batchbuffer *batch = i915_drm_batchbuffer(ibatch);
    unsigned used = 0;
    int ret = 0;
-   int i;
 
    assert(i915_winsys_batchbuffer_space(ibatch) >= 0);
 
@@ -186,20 +186,28 @@ i915_drm_batchbuffer_flush(struct i915_winsys_batchbuffer *ibatch,
 #endif
 
    /* Do the sending to HW */
-   ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
-   assert(ret == 0);
-
-   if (i915_drm_winsys(ibatch->iws)->dump_cmd) {
-      unsigned *ptr;
-      drm_intel_bo_map(batch->bo, FALSE);
-      ptr = (unsigned*)batch->bo->virtual;
+   if (i915_drm_winsys(ibatch->iws)->send_cmd)
+      ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
+   else
+      ret = 0;
 
-      debug_printf("%s:\n", __func__);
-      for (i = 0; i < used / 4; i++, ptr++) {
-         debug_printf("\t%08x:    %08x\n", i*4, *ptr);
-      }
-
-      drm_intel_bo_unmap(batch->bo);
+   if (ret != 0 || i915_drm_winsys(ibatch->iws)->dump_cmd) {
+#ifdef INTEL_MAP_BATCHBUFFER
+#ifdef INTEL_MAP_GTT
+      drm_intel_gem_bo_map_gtt(batch->bo);
+#else
+      drm_intel_bo_map(batch->bo, 0);
+#endif
+#endif
+      i915_dump_batchbuffer(ibatch);
+      assert(ret == 0);
+#ifdef INTEL_MAP_BATCHBUFFER
+#ifdef INTEL_MAP_GTT
+   drm_intel_gem_bo_unmap_gtt(batch->bo);
+#else
+   drm_intel_bo_unmap(batch->bo);
+#endif
+#endif
    } else {
 #ifdef INTEL_RUN_SYNC
       drm_intel_bo_map(batch->bo, FALSE);
index 3bd85026b211d131116a299107bd4856e0e34759..6b06e7ae99508daddfef1d68a47c5980632d1c3d 100644 (file)
@@ -1,5 +1,5 @@
 
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drm_driver.h"
 #include "i915_drm_winsys.h"
 #include "util/u_memory.h"
 
diff --git a/src/gallium/winsys/i915/drm/i915_drm_public.h b/src/gallium/winsys/i915/drm/i915_drm_public.h
new file mode 100644 (file)
index 0000000..b828d8d
--- /dev/null
@@ -0,0 +1,9 @@
+
+#ifndef I915_DRM_PUBLIC_H
+#define I915_DRM_PUBLIC_H
+
+struct i915_winsys;
+
+struct i915_winsys * i915_drm_winsys_create(int drmFD);
+
+#endif
index 5a6b45e6c9f92d60157b42cc7b4c88ea4609ab81..179a84a704b6788440b4cae253ed3952709f6bb8 100644 (file)
@@ -1,14 +1,11 @@
 #include <stdio.h>
 
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drm_driver.h"
 
 #include "i915_drm_winsys.h"
+#include "i915_drm_public.h"
 #include "util/u_memory.h"
 
-#include "i915/i915_context.h"
-#include "i915/i915_screen.h"
-
-#include "trace/tr_drm.h"
 
 /*
  * Helper functions
@@ -48,8 +45,8 @@ i915_drm_winsys_destroy(struct i915_winsys *iws)
    FREE(idws);
 }
 
-static struct pipe_screen *
-i915_drm_create_screen(struct drm_api *api, int drmFD)
+struct i915_winsys *
+i915_drm_winsys_create(int drmFD)
 {
    struct i915_drm_winsys *idws;
    unsigned int deviceID;
@@ -73,21 +70,8 @@ i915_drm_create_screen(struct drm_api *api, int drmFD)
    idws->pools.gem = drm_intel_bufmgr_gem_init(idws->fd, idws->max_batch_size);
    drm_intel_bufmgr_gem_enable_reuse(idws->pools.gem);
 
-   idws->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE);
-
-   return i915_screen_create(&idws->base);
-}
+   idws->dump_cmd = debug_get_bool_option("I915_DUMP_CMD", FALSE);
+   idws->send_cmd = !debug_get_bool_option("I915_NO_HW", FALSE);
 
-static struct drm_api i915_drm_api =
-{
-   .name = "i915",
-   .driver_name = "i915",
-   .create_screen = i915_drm_create_screen,
-   .destroy = NULL,
-};
-
-struct drm_api *
-drm_api_create()
-{
-   return trace_drm_create(&i915_drm_api);
+   return &idws->base;
 }
index 99667bde4ef94aee1b397ee3b3f1ef597aed40a7..88a71f2424dc513138ba1cf1861745ffedcb008b 100644 (file)
@@ -18,6 +18,7 @@ struct i915_drm_winsys
    struct i915_winsys base;
 
    boolean dump_cmd;
+   boolean send_cmd;
 
    int fd; /**< Drm file discriptor */
 
@@ -34,7 +35,6 @@ i915_drm_winsys(struct i915_winsys *iws)
    return (struct i915_drm_winsys *)iws;
 }
 
-struct i915_drm_winsys * i915_drm_winsys_create(int fd, unsigned pci_id);
 struct pipe_fence_handle * i915_drm_fence_create(drm_intel_bo *bo);
 
 void i915_drm_winsys_init_batchbuffer_functions(struct i915_drm_winsys *idws);
diff --git a/src/gallium/winsys/i915/sw/i915_sw_public.h b/src/gallium/winsys/i915/sw/i915_sw_public.h
new file mode 100644 (file)
index 0000000..e951a32
--- /dev/null
@@ -0,0 +1,9 @@
+
+#ifndef I915_SW_PUBLIC_H
+#define I915_SW_PUBLIC_H
+
+struct i915_winsys;
+
+struct i915_winsys * i915_sw_winsys_create(void);
+
+#endif
index bb1c107c056123023707eca260a7d1ee80dd3efe..058ddc44aaf673e467f37ac9ad18af56186605c2 100644 (file)
@@ -1,5 +1,6 @@
 
 #include "i915_sw_winsys.h"
+#include "i915_sw_public.h"
 #include "util/u_memory.h"
 
 
@@ -28,8 +29,8 @@ i915_sw_destroy(struct i915_winsys *iws)
  */
 
 
-struct pipe_screen *
-i915_sw_create_screen()
+struct i915_winsys *
+i915_sw_winsys_create()
 {
    struct i915_sw_winsys *isws;
    unsigned int deviceID;
@@ -51,6 +52,5 @@ i915_sw_create_screen()
 
    isws->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE);
 
-   /* XXX so this will leak winsys:es */
-   return i915_screen_create(&isws->base);
+   return &isws->base;
 }
index b8aa9ef4ac506a1874233985994a9f995c458327..b7b43669f30674a5b4dfe8ba2c53c3f38d2af9d6 100644 (file)
@@ -25,7 +25,6 @@ i915_sw_winsys(struct i915_winsys *iws)
    return (struct i915_sw_winsys *)iws;
 }
 
-struct pipe_screen* i915_sw_create_screen(void);
 struct pipe_fence_handle * i915_sw_fence_create(void);
 
 void i915_sw_winsys_init_batchbuffer_functions(struct i915_sw_winsys *idws);
index bbb71e25d84ed184696883e4f3613c0595c2163b..46f98d7a24afa0f6a1cefe12abc75f8365c8d777 100644 (file)
@@ -5,7 +5,7 @@ LIBNAME = i965drm
 
 C_SOURCES = \
        i965_drm_buffer.c \
-       i965_drm_api.c
+       i965_drm_winsys.c
 
 LIBRARY_INCLUDES = $(shell pkg-config libdrm --cflags-only-I)
 
index abf9aac5c012fa088c62505fa557bba07860cc95..785be449f70ea50d91b54540e4d7a013f888eba1 100644 (file)
@@ -5,8 +5,8 @@ env = env.Clone()
 env.ParseConfig('pkg-config --cflags libdrm')
 
 i965drm_sources = [
-    'i965_drm_api.c',
     'i965_drm_buffer.c',
+    'i965_drm_winsys.c',
 ]
 
 i965drm = env.ConvenienceLibrary(
diff --git a/src/gallium/winsys/i965/drm/i965_drm_api.c b/src/gallium/winsys/i965/drm/i965_drm_api.c
deleted file mode 100644 (file)
index 87ee807..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-
-#include <stdio.h>
-#include "state_tracker/drm_api.h"
-
-#include "i965_drm_winsys.h"
-#include "util/u_memory.h"
-
-#include "i965/brw_context.h"        /* XXX: shouldn't be doing this */
-#include "i965/brw_screen.h"         /* XXX: shouldn't be doing this */
-
-#include "trace/tr_drm.h"
-
-#include "../../sw/drm/sw_drm_api.h"
-
-/*
- * Helper functions
- */
-
-
-static void
-i965_libdrm_get_device_id(unsigned int *device_id)
-{
-   char path[512];
-   FILE *file;
-   void *shutup_gcc;
-
-   /*
-    * FIXME: Fix this up to use a drm ioctl or whatever.
-    */
-
-   snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device");
-   file = fopen(path, "r");
-   if (!file) {
-      return;
-   }
-
-   shutup_gcc = fgets(path, sizeof(path), file);
-   sscanf(path, "%x", device_id);
-   fclose(file);
-}
-
-static void
-i965_libdrm_winsys_destroy(struct brw_winsys_screen *iws)
-{
-   struct i965_libdrm_winsys *idws = i965_libdrm_winsys(iws);
-
-   if (BRW_DUMP)
-      debug_printf("%s\n", __FUNCTION__);
-
-   drm_intel_bufmgr_destroy(idws->gem);
-
-   FREE(idws);
-}
-
-static struct pipe_screen *
-i965_libdrm_create_screen(struct drm_api *api, int drmFD)
-{
-   struct i965_libdrm_winsys *idws;
-   unsigned int deviceID;
-
-   debug_printf("%s\n", __FUNCTION__);
-
-   idws = CALLOC_STRUCT(i965_libdrm_winsys);
-   if (!idws)
-      return NULL;
-
-   i965_libdrm_get_device_id(&deviceID);
-
-   i965_libdrm_winsys_init_buffer_functions(idws);
-
-   idws->fd = drmFD;
-   idws->id = deviceID;
-
-   idws->base.destroy = i965_libdrm_winsys_destroy;
-
-   idws->gem = drm_intel_bufmgr_gem_init(idws->fd, BRW_BATCH_SIZE);
-   drm_intel_bufmgr_gem_enable_reuse(idws->gem);
-
-   idws->send_cmd = !debug_get_bool_option("BRW_NO_HW", FALSE);
-
-   return brw_create_screen(&idws->base, deviceID);
-}
-
-struct drm_api i965_libdrm_api =
-{
-   .name = "i965",
-   .driver_name = "i915",
-   .create_screen = i965_libdrm_create_screen,
-   .destroy = NULL,
-};
-
-struct drm_api *
-drm_api_create()
-{
-   struct drm_api *api = NULL;
-
-   if (api == NULL && debug_get_bool_option("BRW_SOFTPIPE", FALSE))
-      api = sw_drm_api_create(&i965_libdrm_api);
-
-   if (api == NULL)
-      api = &i965_libdrm_api;
-
-   return trace_drm_create(api);
-}
index fb5e50ce810c386c39d78790d01a84eb384ca7f3..ed62db60bbb9cc5912a29afc731b210467835dda 100644 (file)
@@ -1,5 +1,5 @@
 
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drm_driver.h"
 #include "i965_drm_winsys.h"
 #include "util/u_memory.h"
 #include "util/u_inlines.h"
@@ -322,7 +322,7 @@ i965_libdrm_bo_subdata(struct brw_winsys_buffer *buffer,
                   nr_reloc);
 
    if (BRW_DUMP)
-      brw_dump_data( idws->id,
+      brw_dump_data( idws->base.pci_id,
                     data_type,
                     buf->bo->offset + offset, 
                     data, size );
@@ -460,7 +460,7 @@ i965_libdrm_bo_flush_range(struct brw_winsys_buffer *buffer,
                   offset, length);
 
    if (BRW_DUMP)
-      brw_dump_data( idws->id,
+      brw_dump_data( idws->base.pci_id,
                     buf->data_type,
                     buf->bo->offset + offset, 
                     (char*)buf->bo->virtual + offset, 
diff --git a/src/gallium/winsys/i965/drm/i965_drm_public.h b/src/gallium/winsys/i965/drm/i965_drm_public.h
new file mode 100644 (file)
index 0000000..2913b07
--- /dev/null
@@ -0,0 +1,9 @@
+
+#ifndef I965_DRM_PUBLIC_H
+#define I965_DRM_PUBLIC_H
+
+struct brw_winsys_screen;
+
+struct brw_winsys_screen * i965_drm_winsys_screen_create(int drmFD);
+
+#endif
diff --git a/src/gallium/winsys/i965/drm/i965_drm_winsys.c b/src/gallium/winsys/i965/drm/i965_drm_winsys.c
new file mode 100644 (file)
index 0000000..b08e622
--- /dev/null
@@ -0,0 +1,74 @@
+
+#include <stdio.h>
+#include "state_tracker/drm_driver.h"
+
+#include "i965_drm_winsys.h"
+#include "i965_drm_public.h"
+#include "util/u_memory.h"
+
+/*
+ * Helper functions
+ */
+
+
+static void
+i965_libdrm_get_device_id(unsigned int *device_id)
+{
+   char path[512];
+   FILE *file;
+   void *shutup_gcc;
+
+   /*
+    * FIXME: Fix this up to use a drm ioctl or whatever.
+    */
+
+   snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device");
+   file = fopen(path, "r");
+   if (!file) {
+      return;
+   }
+
+   shutup_gcc = fgets(path, sizeof(path), file);
+   sscanf(path, "%x", device_id);
+   fclose(file);
+}
+
+static void
+i965_libdrm_winsys_destroy(struct brw_winsys_screen *iws)
+{
+   struct i965_libdrm_winsys *idws = i965_libdrm_winsys(iws);
+
+   if (BRW_DUMP)
+      debug_printf("%s\n", __FUNCTION__);
+
+   drm_intel_bufmgr_destroy(idws->gem);
+
+   FREE(idws);
+}
+
+struct brw_winsys_screen *
+i965_drm_winsys_screen_create(int drmFD)
+{
+   struct i965_libdrm_winsys *idws;
+
+   debug_printf("%s\n", __FUNCTION__);
+
+   idws = CALLOC_STRUCT(i965_libdrm_winsys);
+   if (!idws)
+      return NULL;
+
+   i965_libdrm_get_device_id(&idws->base.pci_id);
+
+   i965_libdrm_winsys_init_buffer_functions(idws);
+
+   idws->fd = drmFD;
+
+   idws->base.destroy = i965_libdrm_winsys_destroy;
+
+   idws->gem = drm_intel_bufmgr_gem_init(idws->fd, BRW_BATCH_SIZE);
+   drm_intel_bufmgr_gem_enable_reuse(idws->gem);
+
+   idws->send_cmd = !debug_get_bool_option("BRW_NO_HW", FALSE);
+
+   return &idws->base;
+}
index c6a7d4a8c51d1f14f7029a96098b0dcadd6d7ae9..82dbe61cc5122abc9e77d1aaffad30d660bea89f 100644 (file)
@@ -22,8 +22,6 @@ struct i965_libdrm_winsys
    boolean send_cmd;
 
    int fd; /**< Drm file discriptor */
-
-   unsigned id;
 };
 
 static INLINE struct i965_libdrm_winsys *
@@ -32,8 +30,6 @@ i965_libdrm_winsys(struct brw_winsys_screen *iws)
    return (struct i965_libdrm_winsys *)iws;
 }
 
-struct i965_libdrm_winsys *i965_libdrm_winsys_create(int fd, unsigned pci_id);
-
 void i965_libdrm_winsys_init_buffer_functions(struct i965_libdrm_winsys *idws);
 
 
index 063e9f600b9c524169d577e88ff0a998f4bbb9f4..baadd6e89cad70b906483649a02cc81cb2206107 100644 (file)
@@ -395,6 +395,7 @@ xlib_create_brw_winsys_screen( void )
       return NULL;
 
    ws->used = 0;
+   ws->base.pci_id = PCI_CHIP_GM45_GM;
 
    ws->base.destroy              = xlib_brw_winsys_destroy;
    ws->base.bo_alloc             = xlib_brw_bo_alloc;
@@ -452,7 +453,7 @@ xlib_create_i965_screen( void )
    if (winsys == NULL)
       return NULL;
 
-   screen = brw_create_screen(winsys, PCI_CHIP_GM45_GM);
+   screen = brw_create_screen(winsys);
    if (screen == NULL)
       goto fail;
 
index 71029858f75b79615b19d276cab599f36ead091a..74a3c6a0d70b1979b25b7f4c299acaee66ce2357 100644 (file)
@@ -3,7 +3,7 @@ include $(TOP)/configs/current
 
 LIBNAME = nouveaudrm
 
-C_SOURCES = nouveau_drm_api.c
+C_SOURCES = nouveau_drm_winsys.c
 
 LIBRARY_INCLUDES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-I)
 LIBRARY_DEFINES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-other)
diff --git a/src/gallium/winsys/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/nouveau/drm/nouveau_drm_api.c
deleted file mode 100644 (file)
index 2f24431..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-#include "pipe/p_context.h"
-#include "pipe/p_state.h"
-#include "util/u_format.h"
-#include "util/u_memory.h"
-#include "util/u_inlines.h"
-
-#include "nouveau_drm_api.h"
-
-#include "nouveau_drmif.h"
-#include "nouveau_channel.h"
-#include "nouveau_bo.h"
-
-#include "nouveau/nouveau_winsys.h"
-#include "nouveau/nouveau_screen.h"
-
-static void
-nouveau_drm_destroy_winsys(struct pipe_winsys *s)
-{
-       struct nouveau_winsys *nv_winsys = nouveau_winsys(s);
-       struct nouveau_screen *nv_screen= nouveau_screen(nv_winsys->pscreen);
-       nouveau_device_close(&nv_screen->device);
-       FREE(nv_winsys);
-}
-
-static struct pipe_screen *
-nouveau_drm_create_screen(struct drm_api *api, int fd)
-{
-       struct nouveau_winsys *nvws;
-       struct pipe_winsys *ws;
-       struct nouveau_device *dev = NULL;
-       struct pipe_screen *(*init)(struct pipe_winsys *,
-                                   struct nouveau_device *);
-       int ret;
-
-       ret = nouveau_device_open_existing(&dev, 0, fd, 0);
-       if (ret)
-               return NULL;
-
-       switch (dev->chipset & 0xf0) {
-       case 0x30:
-       case 0x40:
-       case 0x60:
-               init = nvfx_screen_create;
-               break;
-       case 0x50:
-       case 0x80:
-       case 0x90:
-       case 0xa0:
-               init = nv50_screen_create;
-               break;
-       default:
-               debug_printf("%s: unknown chipset nv%02x\n", __func__,
-                            dev->chipset);
-               return NULL;
-       }
-
-       nvws = CALLOC_STRUCT(nouveau_winsys);
-       if (!nvws) {
-               nouveau_device_close(&dev);
-               return NULL;
-       }
-       ws = &nvws->base;
-       ws->destroy = nouveau_drm_destroy_winsys;
-
-       nvws->pscreen = init(ws, dev);
-       if (!nvws->pscreen) {
-               ws->destroy(ws);
-               return NULL;
-       }
-
-       return nvws->pscreen;
-}
-
-static struct drm_api nouveau_drm_api_hooks = {
-       .name = "nouveau",
-       .driver_name = "nouveau",
-       .create_screen = nouveau_drm_create_screen,
-       .destroy = NULL,
-};
-
-struct drm_api *
-drm_api_create() {
-       return &nouveau_drm_api_hooks;
-}
-
diff --git a/src/gallium/winsys/nouveau/drm/nouveau_drm_api.h b/src/gallium/winsys/nouveau/drm/nouveau_drm_api.h
deleted file mode 100644 (file)
index ba6305c..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef __NOUVEAU_DRM_API_H__
-#define __NOUVEAU_DRM_API_H__
-
-#include "state_tracker/drm_api.h"
-
-#include "util/u_simple_screen.h"
-
-#include "nouveau_dri.h"
-
-struct nouveau_winsys {
-       struct pipe_winsys base;
-
-       struct pipe_screen *pscreen;
-
-       struct pipe_surface *front;
-};
-
-static INLINE struct nouveau_winsys *
-nouveau_winsys(struct pipe_winsys *ws)
-{
-       return (struct nouveau_winsys *)ws;
-}
-
-static INLINE struct nouveau_winsys *
-nouveau_winsys_screen(struct pipe_screen *pscreen)
-{
-       return nouveau_winsys(pscreen->winsys);
-}
-
-#endif
diff --git a/src/gallium/winsys/nouveau/drm/nouveau_drm_public.h b/src/gallium/winsys/nouveau/drm/nouveau_drm_public.h
new file mode 100644 (file)
index 0000000..67b7c44
--- /dev/null
@@ -0,0 +1,9 @@
+
+#ifndef __NOUVEAU_DRM_PUBLIC_H__
+#define __NOUVEAU_DRM_PUBLIC_H__
+
+struct pipe_screen;
+
+struct pipe_screen *nouveau_drm_screen_create(int drmFD);
+
+#endif
diff --git a/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.c
new file mode 100644 (file)
index 0000000..660dbd0
--- /dev/null
@@ -0,0 +1,73 @@
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "util/u_format.h"
+#include "util/u_memory.h"
+#include "util/u_inlines.h"
+
+#include "nouveau_drm_winsys.h"
+#include "nouveau_drm_public.h"
+
+#include "nouveau_drmif.h"
+#include "nouveau_channel.h"
+#include "nouveau_bo.h"
+
+#include "nouveau/nouveau_winsys.h"
+#include "nouveau/nouveau_screen.h"
+
+static void
+nouveau_drm_destroy_winsys(struct pipe_winsys *s)
+{
+       struct nouveau_winsys *nv_winsys = nouveau_winsys(s);
+       struct nouveau_screen *nv_screen= nouveau_screen(nv_winsys->pscreen);
+       nouveau_device_close(&nv_screen->device);
+       FREE(nv_winsys);
+}
+
+struct pipe_screen *
+nouveau_drm_screen_create(int fd)
+{
+       struct nouveau_winsys *nvws;
+       struct pipe_winsys *ws;
+       struct nouveau_device *dev = NULL;
+       struct pipe_screen *(*init)(struct pipe_winsys *,
+                                   struct nouveau_device *);
+       int ret;
+
+       ret = nouveau_device_open_existing(&dev, 0, fd, 0);
+       if (ret)
+               return NULL;
+
+       switch (dev->chipset & 0xf0) {
+       case 0x30:
+       case 0x40:
+       case 0x60:
+               init = nvfx_screen_create;
+               break;
+       case 0x50:
+       case 0x80:
+       case 0x90:
+       case 0xa0:
+               init = nv50_screen_create;
+               break;
+       default:
+               debug_printf("%s: unknown chipset nv%02x\n", __func__,
+                            dev->chipset);
+               return NULL;
+       }
+
+       nvws = CALLOC_STRUCT(nouveau_winsys);
+       if (!nvws) {
+               nouveau_device_close(&dev);
+               return NULL;
+       }
+       ws = &nvws->base;
+       ws->destroy = nouveau_drm_destroy_winsys;
+
+       nvws->pscreen = init(ws, dev);
+       if (!nvws->pscreen) {
+               ws->destroy(ws);
+               return NULL;
+       }
+
+       return nvws->pscreen;
+}
diff --git a/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.h b/src/gallium/winsys/nouveau/drm/nouveau_drm_winsys.h
new file mode 100644 (file)
index 0000000..9e529ec
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef __NOUVEAU_DRM_WINSYS_H__
+#define __NOUVEAU_DRM_WINSYS_H__
+
+#include "util/u_simple_screen.h"
+
+#include "nouveau_dri.h"
+
+struct nouveau_winsys {
+       struct pipe_winsys base;
+
+       struct pipe_screen *pscreen;
+
+       struct pipe_surface *front;
+};
+
+static INLINE struct nouveau_winsys *
+nouveau_winsys(struct pipe_winsys *ws)
+{
+       return (struct nouveau_winsys *)ws;
+}
+
+static INLINE struct nouveau_winsys *
+nouveau_winsys_screen(struct pipe_screen *pscreen)
+{
+       return nouveau_winsys(pscreen->winsys);
+}
+
+#endif
index 803049d58c99d7a3a1fb88547a02d7ea591a7338..3d87a994c150a4bc0453faf281605d0e552e4fa3 100644 (file)
  *      Joakim Sindholt <opensource@zhasha.com>
  */
 #include <sys/ioctl.h>
-#include "trace/tr_drm.h"
 #include "util/u_inlines.h"
 #include "util/u_debug.h"
-#include "state_tracker/drm_api.h"
 #include "radeon_priv.h"
 #include "r600_screen.h"
 #include "r600_texture.h"
+#include "r600_public.h"
+#include "r600_drm_public.h"
+#include "state_tracker/drm_driver.h"
 
-static struct pipe_screen *r600_drm_create_screen(struct drm_api* api, int drmfd)
+struct radeon *r600_drm_winsys_create(int drmfd)
 {
-       struct radeon *rw = radeon_new(drmfd, 0);
-
-       if (rw == NULL)
-               return NULL;
-       return radeon_create_screen(rw);
+       return radeon_new(drmfd, 0);
 }
 
 boolean r600_buffer_get_handle(struct radeon *rw,
@@ -66,24 +63,3 @@ boolean r600_buffer_get_handle(struct radeon *rw,
        }
        return TRUE;
 }
-
-static void r600_drm_api_destroy(struct drm_api *api)
-{
-       return;
-}
-
-struct drm_api drm_api_hooks = {
-       .name = "r600",
-       .driver_name = "r600",
-       .create_screen = r600_drm_create_screen,
-       .destroy = r600_drm_api_destroy,
-};
-
-struct drm_api* drm_api_create()
-{
-#ifdef DEBUG
-       return trace_drm_create(&drm_api_hooks);
-#else
-       return &drm_api_hooks;
-#endif
-}
diff --git a/src/gallium/winsys/r600/drm/r600_drm_public.h b/src/gallium/winsys/r600/drm/r600_drm_public.h
new file mode 100644 (file)
index 0000000..84f2dce
--- /dev/null
@@ -0,0 +1,9 @@
+
+#ifndef R600_DRM_PUBLIC_H
+#define R600_DRM_PUBLIC_H
+
+struct radeon;
+
+struct radeon *r600_drm_winsys_create(int drmFD);
+
+#endif
index f2113c5807e4d0e19c70b2a77da455628607250d..7e6566980640c28db5afdcec37a3de142db1fd08 100644 (file)
 #include "radeon_drm.h"
 #include "r600d.h"
 
+enum radeon_family radeon_get_family(struct radeon *radeon)
+{
+       return radeon->family;
+}
+
 static int radeon_get_device(struct radeon *radeon)
 {
        struct drm_radeon_info info;
index 73cb6a579b42cf967a89f81c8d92bf934d0a43c3..a8137d85e8359536121d6ecfd445d78cf997973b 100644 (file)
 
 #include "radeon_winsys.h"
 
-#define RADEON_USAGE_DOMAIN_GTT  (1 << 29)
-#define RADEON_USAGE_DOMAIN_VRAM (1 << 30)
-
-#define RADEON_MAX_BOS 24
+#define RADEON_PB_USAGE_VERTEX      (1 << 28)
+#define RADEON_PB_USAGE_DOMAIN_GTT  (1 << 29)
+#define RADEON_PB_USAGE_DOMAIN_VRAM (1 << 30)
 
 static INLINE struct pb_buffer *
 radeon_pb_buffer(struct r300_winsys_buffer *buffer)
@@ -63,24 +62,26 @@ radeon_libdrm_winsys_buffer(struct pb_buffer *buffer)
 struct pb_manager *
 radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws);
 
-boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf,
-                                    enum r300_buffer_domain rd,
-                                     enum r300_buffer_domain wd);
-
+void radeon_drm_bufmgr_add_buffer(struct r300_winsys_cs *cs,
+                                  struct r300_winsys_buffer *buf,
+                                  enum r300_buffer_domain rd,
+                                  enum r300_buffer_domain wd);
 
-void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf,
+void radeon_drm_bufmgr_write_reloc(struct r300_winsys_cs *cs,
+                                   struct r300_winsys_buffer *buf,
                                   enum r300_buffer_domain rd,
-                                   enum r300_buffer_domain wd,
-                                  uint32_t flags);
+                                   enum r300_buffer_domain wd);
 
 struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr,
                                                              uint32_t handle);
 
-void radeon_drm_bufmgr_get_tiling(struct pb_buffer *_buf,
+void radeon_drm_bufmgr_get_tiling(struct r300_winsys_screen *ws,
+                                  struct r300_winsys_buffer *buf,
                                   enum r300_buffer_tiling *microtiled,
                                   enum r300_buffer_tiling *macrotiled);
 
-void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf,
+void radeon_drm_bufmgr_set_tiling(struct r300_winsys_screen *ws,
+                                  struct r300_winsys_buffer *buf,
                                   enum r300_buffer_tiling microtiled,
                                   enum r300_buffer_tiling macrotiled,
                                   uint32_t pitch);
@@ -90,9 +91,19 @@ void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr);
 boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf,
                                     struct winsys_handle *whandle);
 
-boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf,
+boolean radeon_drm_bufmgr_is_buffer_referenced(struct r300_winsys_cs *cs,
+                                               struct r300_winsys_buffer *buf,
                                                enum r300_reference_domain domain);
 
-void radeon_drm_bufmgr_wait(struct pb_buffer *_buf);
+void radeon_drm_bufmgr_wait(struct r300_winsys_screen *ws,
+                            struct r300_winsys_buffer *buf);
+
+void *radeon_drm_buffer_map(struct r300_winsys_screen *ws,
+                            struct r300_winsys_buffer *buf,
+                            struct r300_winsys_cs *cs,
+                            enum pipe_transfer_usage usage);
+
+void radeon_drm_buffer_unmap(struct r300_winsys_screen *ws,
+                             struct r300_winsys_buffer *buf);
 
 #endif
index 59f1b10230e3af915c7f296143832e350001e724..e9a276362f394a8b7b39423d8e221517b29f711b 100644 (file)
@@ -32,9 +32,9 @@
 #include "radeon_drm.h"
 #include "radeon_r300.h"
 #include "radeon_buffer.h"
+#include "radeon_drm_public.h"
 
 #include "r300_winsys.h"
-#include "trace/tr_drm.h"
 
 #include "util/u_memory.h"
 
@@ -153,7 +153,7 @@ static void do_ioctls(int fd, struct radeon_libdrm_winsys* winsys)
 }
 
 /* Create a pipe_screen. */
-struct pipe_screen* radeon_create_screen(struct drm_api* api, int drmFB)
+struct r300_winsys_screen* r300_drm_winsys_screen_create(int drmFB)
 {
     struct radeon_libdrm_winsys* rws; 
     boolean ret;
@@ -171,22 +171,10 @@ struct pipe_screen* radeon_create_screen(struct drm_api* api, int drmFB)
         ret = radeon_setup_winsys(drmFB, rws);
        if (ret == FALSE)
            goto fail;
-        return r300_create_screen(&rws->base);
+        return &rws->base;
     }
 
 fail:
     FREE(rws);
     return NULL;
 }
-
-static struct drm_api radeon_drm_api_hooks = {
-    .name = "radeon",
-    .driver_name = "radeon",
-    .create_screen = radeon_create_screen,
-    .destroy = NULL,
-};
-
-struct drm_api* drm_api_create()
-{
-    return trace_drm_create(&radeon_drm_api_hooks);
-}
index 3544c926d9975c07328151b53e37abb4c50d66f9..df6dd91ad54b473be0853dfa3c3b4d3a26f9d492 100644 (file)
 #ifndef RADEON_DRM_H
 #define RADEON_DRM_H
 
-#include "state_tracker/drm_api.h"
-
-
-struct pipe_screen* radeon_create_screen(struct drm_api* api, int drmFB);
-
-void radeon_destroy_drm_api(struct drm_api* api);
+#include "state_tracker/drm_driver.h"
 
 /* Guess at whether this chipset should use r300g.
  *
index a4b6cff33d1c1900cca553c528434bfd31ad2af3..017eac8464e16b04d7c0e87ec3bc4ad8559bb1af 100644 (file)
@@ -20,10 +20,11 @@ struct radeon_drm_buffer {
 
     struct radeon_bo *bo;
 
+    /* The CS associated with the last buffer_map. */
+    struct radeon_libdrm_cs *cs;
+
     boolean flinked;
     uint32_t flink;
-    uint32_t tileflags;
-    uint32_t pitch;
 
     struct radeon_drm_buffer *next, *prev;
 };
@@ -67,34 +68,53 @@ radeon_drm_buffer_destroy(struct pb_buffer *_buf)
     FREE(buf);
 }
 
+static unsigned get_pb_usage_from_transfer_flags(enum pipe_transfer_usage usage)
+{
+    unsigned res = 0;
+
+    if (usage & PIPE_TRANSFER_READ)
+        res |= PB_USAGE_CPU_READ;
+
+    if (usage & PIPE_TRANSFER_WRITE)
+        res |= PB_USAGE_CPU_WRITE;
+
+    if (usage & PIPE_TRANSFER_DONTBLOCK)
+        res |= PB_USAGE_DONTBLOCK;
+
+    if (usage & PIPE_TRANSFER_UNSYNCHRONIZED)
+        res |= PB_USAGE_UNSYNCHRONIZED;
+
+    return res;
+}
+
 static void *
-radeon_drm_buffer_map(struct pb_buffer *_buf,
+radeon_drm_buffer_map_internal(struct pb_buffer *_buf,
                      unsigned flags)
 {
     struct radeon_drm_buffer *buf = radeon_drm_buffer(_buf);
+    struct radeon_libdrm_cs *cs = buf->cs;
     int write = 0;
 
-    if (flags & PIPE_TRANSFER_DONTBLOCK) {
-       if ((_buf->base.usage & PIPE_BIND_VERTEX_BUFFER) ||
-           (_buf->base.usage & PIPE_BIND_INDEX_BUFFER))
-           if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs))
+    if (flags & PB_USAGE_DONTBLOCK) {
+        if (_buf->base.usage & RADEON_PB_USAGE_VERTEX)
+            if (cs && radeon_bo_is_referenced_by_cs(buf->bo, cs->cs))
                return NULL;
     }
 
     if (buf->bo->ptr != NULL)
        return buf->bo->ptr;
 
-    if (flags & PIPE_TRANSFER_DONTBLOCK) {
+    if (flags & PB_USAGE_DONTBLOCK) {
         uint32_t domain;
         if (radeon_bo_is_busy(buf->bo, &domain))
             return NULL;
     }
 
-    if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) {
-        buf->mgr->rws->flush_cb(buf->mgr->rws->flush_data);
+    if (cs && radeon_bo_is_referenced_by_cs(buf->bo, cs->cs)) {
+        cs->flush_cs(cs->flush_data);
     }
 
-    if (flags & PIPE_TRANSFER_WRITE) {
+    if (flags & PB_USAGE_CPU_WRITE) {
         write = 1;
     }
 
@@ -106,7 +126,7 @@ radeon_drm_buffer_map(struct pb_buffer *_buf,
 }
 
 static void
-radeon_drm_buffer_unmap(struct pb_buffer *_buf)
+radeon_drm_buffer_unmap_internal(struct pb_buffer *_buf)
 {
     (void)_buf;
 }
@@ -138,8 +158,8 @@ radeon_drm_buffer_fence(struct pb_buffer *buf,
 
 const struct pb_vtbl radeon_drm_buffer_vtbl = {
     radeon_drm_buffer_destroy,
-    radeon_drm_buffer_map,
-    radeon_drm_buffer_unmap,
+    radeon_drm_buffer_map_internal,
+    radeon_drm_buffer_unmap_internal,
     radeon_drm_buffer_validate,
     radeon_drm_buffer_fence,
     radeon_drm_buffer_get_base_buffer,
@@ -168,8 +188,8 @@ struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager
 
     pipe_reference_init(&buf->base.base.reference, 1);
     buf->base.base.alignment = 0;
-    buf->base.base.usage = PIPE_BIND_SAMPLER_VIEW;
-    buf->base.base.size = 0;
+    buf->base.base.usage = PB_USAGE_GPU_WRITE | PB_USAGE_GPU_READ;
+    buf->base.base.size = bo->size;
     buf->base.vtbl = &radeon_drm_buffer_vtbl;
     buf->mgr = mgr;
 
@@ -202,8 +222,8 @@ radeon_drm_bufmgr_create_buffer(struct pb_manager *_mgr,
     make_empty_list(buf);
 
     domain =
-        (desc->usage & RADEON_USAGE_DOMAIN_GTT  ? RADEON_GEM_DOMAIN_GTT  : 0) |
-        (desc->usage & RADEON_USAGE_DOMAIN_VRAM ? RADEON_GEM_DOMAIN_VRAM : 0);
+        (desc->usage & RADEON_PB_USAGE_DOMAIN_GTT  ? RADEON_GEM_DOMAIN_GTT  : 0) |
+        (desc->usage & RADEON_PB_USAGE_DOMAIN_VRAM ? RADEON_GEM_DOMAIN_VRAM : 0);
 
     buf->bo = radeon_bo_open(rws->bom, 0, size,
                             desc->alignment, domain, 0);
@@ -251,7 +271,8 @@ radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws)
 
 static struct radeon_drm_buffer *get_drm_buffer(struct pb_buffer *_buf)
 {
-    struct radeon_drm_buffer *buf;
+    struct radeon_drm_buffer *buf = NULL;
+
     if (_buf->vtbl == &radeon_drm_buffer_vtbl) {
         buf = radeon_drm_buffer(_buf);
     } else {
@@ -259,11 +280,35 @@ static struct radeon_drm_buffer *get_drm_buffer(struct pb_buffer *_buf)
        pb_size offset;
        pb_get_base_buffer(_buf, &base_buf, &offset);
 
-       buf = radeon_drm_buffer(base_buf);
+        if (base_buf->vtbl == &radeon_drm_buffer_vtbl)
+            buf = radeon_drm_buffer(base_buf);
     }
+
     return buf;
 }
 
+void *radeon_drm_buffer_map(struct r300_winsys_screen *ws,
+                            struct r300_winsys_buffer *buf,
+                            struct r300_winsys_cs *cs,
+                            enum pipe_transfer_usage usage)
+{
+    struct pb_buffer *_buf = radeon_pb_buffer(buf);
+    struct radeon_drm_buffer *rbuf = get_drm_buffer(_buf);
+
+    if (rbuf)
+        rbuf->cs = radeon_libdrm_cs(cs);
+
+    return pb_map(_buf, get_pb_usage_from_transfer_flags(usage));
+}
+
+void radeon_drm_buffer_unmap(struct r300_winsys_screen *ws,
+                             struct r300_winsys_buffer *buf)
+{
+    struct pb_buffer *_buf = radeon_pb_buffer(buf);
+
+    pb_unmap(_buf);
+}
+
 boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf,
                                     struct winsys_handle *whandle)
 {
@@ -288,18 +333,16 @@ boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf,
     return TRUE;
 }
 
-void radeon_drm_bufmgr_get_tiling(struct pb_buffer *_buf,
+void radeon_drm_bufmgr_get_tiling(struct r300_winsys_screen *ws,
+                                  struct r300_winsys_buffer *_buf,
                                   enum r300_buffer_tiling *microtiled,
                                   enum r300_buffer_tiling *macrotiled)
 {
-    struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+    struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
     uint32_t flags = 0, pitch;
 
     radeon_bo_get_tiling(buf->bo, &flags, &pitch);
 
-    buf->tileflags = flags;
-    buf->pitch = pitch;
-
     *microtiled = R300_BUFFER_LINEAR;
     *macrotiled = R300_BUFFER_LINEAR;
     if (flags & RADEON_BO_FLAGS_MICRO_TILE)
@@ -309,12 +352,13 @@ void radeon_drm_bufmgr_get_tiling(struct pb_buffer *_buf,
        *macrotiled = R300_BUFFER_TILED;
 }
 
-void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf,
+void radeon_drm_bufmgr_set_tiling(struct r300_winsys_screen *ws,
+                                  struct r300_winsys_buffer *_buf,
                                   enum r300_buffer_tiling microtiled,
                                   enum r300_buffer_tiling macrotiled,
                                   uint32_t pitch)
 {
-    struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+    struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
     uint32_t flags = 0;
     if (microtiled == R300_BUFFER_TILED)
         flags |= RADEON_BO_FLAGS_MICRO_TILE;
@@ -326,67 +370,63 @@ void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf,
     if (macrotiled == R300_BUFFER_TILED)
         flags |= RADEON_BO_FLAGS_MACRO_TILE;
 
-    if (flags != buf->tileflags || pitch != buf->pitch) {
-        /* Tiling determines how DRM treats the buffer data.
-         * We must flush CS when changing it if the buffer is referenced. */
-        if (radeon_bo_is_referenced_by_cs(buf->bo,  buf->mgr->rws->cs)) {
-           buf->mgr->rws->flush_cb(buf->mgr->rws->flush_data);
-        }
-
-        radeon_bo_set_tiling(buf->bo, flags, pitch);
-    }
+    radeon_bo_set_tiling(buf->bo, flags, pitch);
 }
 
-static uint32_t gem_domain(enum r300_buffer_domain dom)
+static uint32_t get_gem_domain(enum r300_buffer_domain domain)
 {
     uint32_t res = 0;
 
-    if (dom & R300_DOMAIN_GTT)
+    if (domain & R300_DOMAIN_GTT)
         res |= RADEON_GEM_DOMAIN_GTT;
-    if (dom & R300_DOMAIN_VRAM)
+    if (domain & R300_DOMAIN_VRAM)
         res |= RADEON_GEM_DOMAIN_VRAM;
     return res;
 }
 
-boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf,
-                                    enum r300_buffer_domain rd,
-                                     enum r300_buffer_domain wd)
+void radeon_drm_bufmgr_add_buffer(struct r300_winsys_cs *rcs,
+                                  struct r300_winsys_buffer *_buf,
+                                  enum r300_buffer_domain rd,
+                                  enum r300_buffer_domain wd)
 {
-    struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
-    uint32_t gem_rd = gem_domain(rd);
-    uint32_t gem_wd = gem_domain(wd);
+    struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
+    struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
+    uint32_t gem_rd = get_gem_domain(rd);
+    uint32_t gem_wd = get_gem_domain(wd);
 
-    radeon_cs_space_add_persistent_bo(buf->mgr->rws->cs, buf->bo,
-                                         gem_rd, gem_wd);
-    return TRUE;
+    radeon_cs_space_add_persistent_bo(cs->cs, buf->bo, gem_rd, gem_wd);
 }
 
-void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf,
+void radeon_drm_bufmgr_write_reloc(struct r300_winsys_cs *rcs,
+                                   struct r300_winsys_buffer *_buf,
                                   enum r300_buffer_domain rd,
-                                   enum r300_buffer_domain wd,
-                                  uint32_t flags)
+                                   enum r300_buffer_domain wd)
 {
-    struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+    struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
+    struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
     int retval;
-    uint32_t gem_rd = gem_domain(rd);
-    uint32_t gem_wd = gem_domain(wd);
+    uint32_t gem_rd = get_gem_domain(rd);
+    uint32_t gem_wd = get_gem_domain(wd);
 
-    retval = radeon_cs_write_reloc(buf->mgr->rws->cs,
-                                  buf->bo, gem_rd, gem_wd, flags);
+    cs->cs->cdw = cs->base.cdw;
+    retval = radeon_cs_write_reloc(cs->cs, buf->bo, gem_rd, gem_wd, 0);
+    cs->base.cdw = cs->cs->cdw;
     if (retval) {
-        debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n",
-                    buf, gem_rd, gem_wd, flags);
+        fprintf(stderr, "radeon: Relocation of %p (%d, %d, %d) failed!\n",
+                buf, gem_rd, gem_wd, 0);
     }
 }
 
-boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf,
+boolean radeon_drm_bufmgr_is_buffer_referenced(struct r300_winsys_cs *rcs,
+                                               struct r300_winsys_buffer *_buf,
                                                enum r300_reference_domain domain)
 {
-    struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+    struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
+    struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
     uint32_t tmp;
 
     if (domain & R300_REF_CS) {
-        if (radeon_bo_is_referenced_by_cs(buf->bo, buf->mgr->rws->cs)) {
+        if (radeon_bo_is_referenced_by_cs(buf->bo, cs->cs)) {
             return TRUE;
         }
     }
@@ -400,7 +440,6 @@ boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf,
     return FALSE;
 }
 
-
 void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr)
 {
     struct radeon_drm_bufmgr *mgr = radeon_drm_bufmgr(_mgr);
@@ -415,9 +454,10 @@ void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr)
     make_empty_list(&mgr->buffer_map_list);
 }
 
-void radeon_drm_bufmgr_wait(struct pb_buffer *_buf)
+void radeon_drm_bufmgr_wait(struct r300_winsys_screen *ws,
+                            struct r300_winsys_buffer *_buf)
 {
-    struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+    struct radeon_drm_buffer *buf = get_drm_buffer(radeon_pb_buffer(_buf));
 
     radeon_bo_wait(buf->bo);
 }
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_public.h b/src/gallium/winsys/radeon/drm/radeon_drm_public.h
new file mode 100644 (file)
index 0000000..0d96ae8
--- /dev/null
@@ -0,0 +1,9 @@
+
+#ifndef RADEON_DRM_PUBLIC_H
+#define RADEON_DRM_PUBLIC_H
+
+struct r300_winsys_screen;
+
+struct r300_winsys_screen *r300_drm_winsys_screen_create(int drmFD);
+
+#endif
index d2d317dc209e1bbd0bd0e2993fbf4fc85c4ce210..554450406710adb33647695a370bc645257defc5 100644 (file)
 
 #include "radeon_bo_gem.h"
 #include "radeon_cs_gem.h"
-#include "state_tracker/drm_api.h"
+#include "state_tracker/drm_driver.h"
+
+#include "util/u_memory.h"
+
+static unsigned get_pb_usage_from_create_flags(unsigned bind, unsigned usage,
+                                               enum r300_buffer_domain domain)
+{
+    unsigned res = 0;
+
+    if (bind & (PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET |
+                PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT))
+        res |= PB_USAGE_GPU_WRITE;
+
+    if (bind & PIPE_BIND_SAMPLER_VIEW)
+        res |= PB_USAGE_GPU_READ | PB_USAGE_GPU_WRITE;
+
+    if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER))
+        res |= PB_USAGE_GPU_READ;
+
+    if (bind & PIPE_BIND_TRANSFER_WRITE)
+        res |= PB_USAGE_CPU_WRITE;
+
+    if (bind & PIPE_BIND_TRANSFER_READ)
+        res |= PB_USAGE_CPU_READ;
+
+    /* Is usage of any use for us? Probably not. */
+
+    /* Now add driver-specific usage flags. */
+    if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER))
+        res |= RADEON_PB_USAGE_VERTEX;
+
+    if (domain & R300_DOMAIN_GTT)
+        res |= RADEON_PB_USAGE_DOMAIN_GTT;
+
+    if (domain & R300_DOMAIN_VRAM)
+        res |= RADEON_PB_USAGE_DOMAIN_VRAM;
+
+    return res;
+}
 
 static struct r300_winsys_buffer *
 radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws,
-                                unsigned alignment,
-                                unsigned usage,
-                                 enum r300_buffer_domain domain,
-                                unsigned size)
+                                 unsigned size,
+                                 unsigned alignment,
+                                 unsigned bind,
+                                 unsigned usage,
+                                 enum r300_buffer_domain domain)
 {
-    struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+    struct radeon_libdrm_winsys *ws = radeon_libdrm_winsys(rws);
     struct pb_desc desc;
     struct pb_manager *provider;
     struct pb_buffer *buffer;
 
-    /* XXX this is hackish, but it's the only way to pass these flags
-     * to the real create function. */
-    usage &= ~(RADEON_USAGE_DOMAIN_GTT | RADEON_USAGE_DOMAIN_VRAM);
-    if (domain & R300_DOMAIN_GTT)
-        usage |= RADEON_USAGE_DOMAIN_GTT;
-    if (domain & R300_DOMAIN_VRAM)
-        usage |= RADEON_USAGE_DOMAIN_VRAM;
-
     memset(&desc, 0, sizeof(desc));
     desc.alignment = alignment;
-    desc.usage = usage;
+    desc.usage = get_pb_usage_from_create_flags(bind, usage, domain);
 
-    if (usage & PIPE_BIND_CONSTANT_BUFFER)
-        provider = ws->mman;
-    else if ((usage & PIPE_BIND_VERTEX_BUFFER) ||
-            (usage & PIPE_BIND_INDEX_BUFFER))
+    /* Assign a buffer manager. */
+    if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER))
        provider = ws->cman;
     else
         provider = ws->kman;
+
     buffer = provider->create_buffer(provider, size, &desc);
     if (!buffer)
        return NULL;
@@ -65,55 +95,6 @@ radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws,
     return radeon_libdrm_winsys_buffer(buffer);
 }
 
-static void radeon_r300_winsys_buffer_destroy(struct r300_winsys_buffer *buf)
-{
-    struct pb_buffer *_buf = radeon_pb_buffer(buf);
-
-    pb_destroy(_buf);
-}
-static void radeon_r300_winsys_buffer_set_tiling(struct r300_winsys_screen *rws,
-                                                 struct r300_winsys_buffer *buf,
-                                                 uint32_t pitch,
-                                                 enum r300_buffer_tiling microtiled,
-                                                 enum r300_buffer_tiling macrotiled)
-{
-    struct pb_buffer *_buf = radeon_pb_buffer(buf);
-    radeon_drm_bufmgr_set_tiling(_buf, microtiled, macrotiled, pitch);
-}
-
-static void radeon_r300_winsys_buffer_get_tiling(struct r300_winsys_screen *rws,
-                                                 struct r300_winsys_buffer *buf,
-                                                 enum r300_buffer_tiling *microtiled,
-                                                 enum r300_buffer_tiling *macrotiled)
-{
-    struct pb_buffer *_buf = radeon_pb_buffer(buf);
-    radeon_drm_bufmgr_get_tiling(_buf, microtiled, macrotiled);
-}
-
-static void *radeon_r300_winsys_buffer_map(struct r300_winsys_screen *ws,
-                                          struct r300_winsys_buffer *buf,
-                                          unsigned usage)
-{
-    struct pb_buffer *_buf = radeon_pb_buffer(buf);
-
-    return pb_map(_buf, usage);
-}
-
-static void radeon_r300_winsys_buffer_unmap(struct r300_winsys_screen *ws,
-                                           struct r300_winsys_buffer *buf)
-{
-    struct pb_buffer *_buf = radeon_pb_buffer(buf);
-
-    pb_unmap(_buf);
-}
-
-static void radeon_r300_winsys_buffer_wait(struct r300_winsys_screen *ws,
-                                           struct r300_winsys_buffer *buf)
-{
-    struct pb_buffer *_buf = radeon_pb_buffer(buf);
-    radeon_drm_bufmgr_wait(_buf);
-}
-
 static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws,
                                                struct r300_winsys_buffer **pdst,
                                                struct r300_winsys_buffer *src)
@@ -126,140 +107,96 @@ static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws,
     *pdst = radeon_libdrm_winsys_buffer(_dst);
 }
 
-static boolean radeon_r300_winsys_is_buffer_referenced(struct r300_winsys_screen *rws,
-                                                      struct r300_winsys_buffer *buf,
-                                                       enum r300_reference_domain domain)
-{
-    struct pb_buffer *_buf = radeon_pb_buffer(buf);
-
-    return radeon_drm_bufmgr_is_buffer_referenced(_buf, domain);
-}
-
 static struct r300_winsys_buffer *radeon_r300_winsys_buffer_from_handle(struct r300_winsys_screen *rws,
-                                                                        unsigned handle)
+                                                                        struct winsys_handle *whandle,
+                                                                        unsigned *stride,
+                                                                        unsigned *size)
 {
-    struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+    struct radeon_libdrm_winsys *ws = radeon_libdrm_winsys(rws);
     struct pb_buffer *_buf;
 
-    _buf = radeon_drm_bufmgr_create_buffer_from_handle(ws->kman, handle);
+    _buf = radeon_drm_bufmgr_create_buffer_from_handle(ws->kman, whandle->handle);
+
+    if (stride)
+        *stride = whandle->stride;
+    if (size)
+        *size = _buf->base.size;
+
     return radeon_libdrm_winsys_buffer(_buf);
 }
 
 static boolean radeon_r300_winsys_buffer_get_handle(struct r300_winsys_screen *rws,
                                                    struct r300_winsys_buffer *buffer,
+                                                    unsigned stride,
                                                     struct winsys_handle *whandle)
 {
     struct pb_buffer *_buf = radeon_pb_buffer(buffer);
+    whandle->stride = stride;
     return radeon_drm_bufmgr_get_handle(_buf, whandle);
 }
 
-static void radeon_set_flush_cb(struct r300_winsys_screen *rws,
-                                void (*flush_cb)(void *),
-                                void *data)
-{
-    struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
-    ws->flush_cb = flush_cb;
-    ws->flush_data = data;
-    radeon_cs_space_set_flush(ws->cs, flush_cb, data);
-}
-
-static boolean radeon_add_buffer(struct r300_winsys_screen *rws,
-                                 struct r300_winsys_buffer *buf,
-                                 enum r300_buffer_domain rd,
-                                 enum r300_buffer_domain wd)
-{
-    struct pb_buffer *_buf = radeon_pb_buffer(buf);
-
-    return radeon_drm_bufmgr_add_buffer(_buf, rd, wd);
-}
-
-static boolean radeon_validate(struct r300_winsys_screen *rws)
-{
-    struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
-    if (radeon_cs_space_check(ws->cs) < 0) {
-        return FALSE;
-    }
-
-    /* Things are fine, we can proceed as normal. */
-    return TRUE;
-}
-
-static unsigned radeon_get_cs_free_dwords(struct r300_winsys_screen *rws)
+static void radeon_r300_winsys_cs_set_flush(struct r300_winsys_cs *rcs,
+                                            void (*flush)(void *),
+                                            void *user)
 {
-    struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
-    struct radeon_cs *cs = ws->cs;
-
-    return cs->ndw - cs->cdw;
-}
-
-static uint32_t *radeon_get_cs_pointer(struct r300_winsys_screen *rws,
-                                       unsigned count)
-{
-    struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
-    struct radeon_cs *cs = ws->cs;
-    uint32_t *ptr = cs->packets + cs->cdw;
-
-    cs->cdw += count;
-    return ptr;
-}
-
-static void radeon_write_cs_dword(struct r300_winsys_screen *rws,
-                                  uint32_t dword)
-{
-    struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
-    radeon_cs_write_dword(ws->cs, dword);
+    struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
+    cs->flush_cs = flush;
+    cs->flush_data = user;
+    radeon_cs_space_set_flush(cs->cs, flush, user);
 }
 
-static void radeon_write_cs_table(struct r300_winsys_screen *rws,
-                                  const void *table, unsigned count)
+static boolean radeon_r300_winsys_cs_validate(struct r300_winsys_cs *rcs)
 {
-    struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
-    radeon_cs_write_table(ws->cs, table, count);
-}
+    struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
 
-static void radeon_write_cs_reloc(struct r300_winsys_screen *rws,
-                                  struct r300_winsys_buffer *buf,
-                                  enum r300_buffer_domain rd,
-                                  enum r300_buffer_domain wd,
-                                  uint32_t flags)
-{
-    struct pb_buffer *_buf = radeon_pb_buffer(buf);
-    radeon_drm_bufmgr_write_reloc(_buf, rd, wd, flags);
+    return radeon_cs_space_check(cs->cs) >= 0;
 }
 
-static void radeon_reset_bos(struct r300_winsys_screen *rws)
+static void radeon_r300_winsys_cs_reset_buffers(struct r300_winsys_cs *rcs)
 {
-    struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
-    radeon_cs_space_reset_bos(ws->cs);
+    struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
+    radeon_cs_space_reset_bos(cs->cs);
 }
 
-static void radeon_flush_cs(struct r300_winsys_screen *rws)
+static void radeon_r300_winsys_cs_flush(struct r300_winsys_cs *rcs)
 {
-    struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
+    struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
     int retval;
 
     /* Don't flush a zero-sized CS. */
-    if (!ws->cs->cdw) {
+    if (!cs->base.cdw) {
         return;
     }
 
-    radeon_drm_bufmgr_flush_maps(ws->kman);
+    cs->cs->cdw = cs->base.cdw;
+
+    radeon_drm_bufmgr_flush_maps(cs->ws->kman);
+
     /* Emit the CS. */
-    retval = radeon_cs_emit(ws->cs);
+    retval = radeon_cs_emit(cs->cs);
     if (retval) {
-        debug_printf("radeon: Bad CS, dumping...\n");
-        radeon_cs_print(ws->cs, stderr);
+        if (debug_get_bool_option("RADEON_DUMP_CS", FALSE)) {
+            fprintf(stderr, "radeon: The kernel rejected CS, dumping...\n");
+            radeon_cs_print(cs->cs, stderr);
+        } else {
+            fprintf(stderr, "radeon: The kernel rejected CS, "
+                            "see dmesg for more information.\n");
+        }
     }
 
     /* Reset CS.
      * Someday, when we care about performance, we should really find a way
      * to rotate between two or three CS objects so that the GPU can be
      * spinning through one CS while another one is being filled. */
-    radeon_cs_erase(ws->cs);
+    radeon_cs_erase(cs->cs);
+
+    cs->base.ptr = cs->cs->packets;
+    cs->base.cdw = cs->cs->cdw;
+    cs->base.ndw = cs->cs->ndw;
 }
 
 static uint32_t radeon_get_value(struct r300_winsys_screen *rws,
-                            enum r300_value_id id)
+                                 enum r300_value_id id)
 {
     struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws;
 
@@ -278,24 +215,52 @@ static uint32_t radeon_get_value(struct r300_winsys_screen *rws,
     return 0;
 }
 
-static void
-radeon_winsys_destroy(struct r300_winsys_screen *rws)
+static struct r300_winsys_cs *radeon_r300_winsys_cs_create(struct r300_winsys_screen *rws)
+{
+    struct radeon_libdrm_winsys *ws = radeon_libdrm_winsys(rws);
+    struct radeon_libdrm_cs *cs = CALLOC_STRUCT(radeon_libdrm_cs);
+
+    if (!cs)
+        return NULL;
+
+    /* Size limit on IBs is 64 kibibytes. */
+    cs->cs = radeon_cs_create(ws->csm, 1024 * 64 / 4);
+    if (!cs->cs) {
+        FREE(cs);
+        return NULL;
+    }
+
+    radeon_cs_set_limit(cs->cs,
+            RADEON_GEM_DOMAIN_GTT, ws->gart_size);
+    radeon_cs_set_limit(cs->cs,
+            RADEON_GEM_DOMAIN_VRAM, ws->vram_size);
+
+    cs->ws = ws;
+    cs->base.ptr = cs->cs->packets;
+    cs->base.cdw = cs->cs->cdw;
+    cs->base.ndw = cs->cs->ndw;
+    return &cs->base;
+}
+
+static void radeon_r300_winsys_cs_destroy(struct r300_winsys_cs *rcs)
+{
+    struct radeon_libdrm_cs *cs = radeon_libdrm_cs(rcs);
+    radeon_cs_destroy(cs->cs);
+}
+
+static void radeon_winsys_destroy(struct r300_winsys_screen *rws)
 {
     struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws;
-    radeon_cs_destroy(ws->cs);
 
     ws->cman->destroy(ws->cman);
     ws->kman->destroy(ws->kman);
-    ws->mman->destroy(ws->mman);
 
     radeon_bo_manager_gem_dtor(ws->bom);
     radeon_cs_manager_gem_dtor(ws->csm);
 }
 
-boolean
-radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws)
+boolean radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws)
 {
-    
     ws->csm = radeon_cs_manager_gem_ctor(fd);
     if (!ws->csm)
        goto fail;
@@ -310,43 +275,28 @@ radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws)
     if (!ws->cman)
        goto fail;
 
-    ws->mman = pb_malloc_bufmgr_create();
-    if (!ws->mman)
-       goto fail;
-
-    /* Size limit on IBs is 64 kibibytes. */
-    ws->cs = radeon_cs_create(ws->csm, 1024 * 64 / 4);
-    if (!ws->cs)
-       goto fail;
-    radeon_cs_set_limit(ws->cs,
-            RADEON_GEM_DOMAIN_GTT, ws->gart_size);
-    radeon_cs_set_limit(ws->cs,
-            RADEON_GEM_DOMAIN_VRAM, ws->vram_size);
-
-    ws->base.add_buffer = radeon_add_buffer;
-    ws->base.validate = radeon_validate;
     ws->base.destroy = radeon_winsys_destroy;
-    ws->base.get_cs_free_dwords = radeon_get_cs_free_dwords;
-    ws->base.get_cs_pointer = radeon_get_cs_pointer;
-    ws->base.write_cs_dword = radeon_write_cs_dword;
-    ws->base.write_cs_table = radeon_write_cs_table;
-    ws->base.write_cs_reloc = radeon_write_cs_reloc;
-    ws->base.flush_cs = radeon_flush_cs;
-    ws->base.reset_bos = radeon_reset_bos;
-    ws->base.set_flush_cb = radeon_set_flush_cb;
     ws->base.get_value = radeon_get_value;
 
     ws->base.buffer_create = radeon_r300_winsys_buffer_create;
-    ws->base.buffer_destroy = radeon_r300_winsys_buffer_destroy;
-    ws->base.buffer_set_tiling = radeon_r300_winsys_buffer_set_tiling;
-    ws->base.buffer_get_tiling = radeon_r300_winsys_buffer_get_tiling;
-    ws->base.buffer_map = radeon_r300_winsys_buffer_map;
-    ws->base.buffer_unmap = radeon_r300_winsys_buffer_unmap;
-    ws->base.buffer_wait = radeon_r300_winsys_buffer_wait;
+    ws->base.buffer_set_tiling = radeon_drm_bufmgr_set_tiling;
+    ws->base.buffer_get_tiling = radeon_drm_bufmgr_get_tiling;
+    ws->base.buffer_map = radeon_drm_buffer_map;
+    ws->base.buffer_unmap = radeon_drm_buffer_unmap;
+    ws->base.buffer_wait = radeon_drm_bufmgr_wait;
     ws->base.buffer_reference = radeon_r300_winsys_buffer_reference;
     ws->base.buffer_from_handle = radeon_r300_winsys_buffer_from_handle;
     ws->base.buffer_get_handle = radeon_r300_winsys_buffer_get_handle;
-    ws->base.is_buffer_referenced = radeon_r300_winsys_is_buffer_referenced;
+
+    ws->base.cs_create = radeon_r300_winsys_cs_create;
+    ws->base.cs_destroy = radeon_r300_winsys_cs_destroy;
+    ws->base.cs_add_buffer = radeon_drm_bufmgr_add_buffer;
+    ws->base.cs_validate = radeon_r300_winsys_cs_validate;
+    ws->base.cs_write_reloc = radeon_drm_bufmgr_write_reloc;
+    ws->base.cs_flush = radeon_r300_winsys_cs_flush;
+    ws->base.cs_reset_buffers = radeon_r300_winsys_cs_reset_buffers;
+    ws->base.cs_set_flush = radeon_r300_winsys_cs_set_flush;
+    ws->base.cs_is_buffer_referenced = radeon_drm_bufmgr_is_buffer_referenced;
     return TRUE;
 
 fail:
@@ -360,10 +310,6 @@ fail:
        ws->cman->destroy(ws->cman);
     if (ws->kman)
        ws->kman->destroy(ws->kman);
-    if (ws->mman)
-       ws->mman->destroy(ws->mman);
 
-    if (ws->cs)
-       radeon_cs_destroy(ws->cs);
     return FALSE;
 }
index ca789be8e931fd869df1dff651553f4da99abc0d..533b7b2e2d286ef8a1789f8f4d5a28ada84fe0d4 100644 (file)
@@ -40,8 +40,6 @@ struct radeon_libdrm_winsys {
 
     struct pb_manager *cman;
 
-    struct pb_manager *mman;
-
     /* PCI ID */
     uint32_t pci_id;
 
@@ -75,19 +73,32 @@ struct radeon_libdrm_winsys {
 
     /* Radeon CS manager. */
     struct radeon_cs_manager *csm;
+};
+
+struct radeon_libdrm_cs {
+    struct r300_winsys_cs base;
+
+    /* The winsys. */
+    struct radeon_libdrm_winsys *ws;
 
-    /* Current CS. */
+    /* The libdrm command stream. */
     struct radeon_cs *cs;
 
-    /* Flush CB */
-    void (*flush_cb)(void *);
+    /* Flush CS. */
+    void (*flush_cs)(void *);
     void *flush_data;
 };
 
+static INLINE struct radeon_libdrm_cs *
+radeon_libdrm_cs(struct r300_winsys_cs *base)
+{
+    return (struct radeon_libdrm_cs*)base;
+}
+
 static INLINE struct radeon_libdrm_winsys *
-radeon_winsys_screen(struct r300_winsys_screen *base)
+radeon_libdrm_winsys(struct r300_winsys_screen *base)
 {
-  return (struct radeon_libdrm_winsys *)base;
+    return (struct radeon_libdrm_winsys*)base;
 }
 
 #endif
diff --git a/src/gallium/winsys/svga/drm/svga_drm_public.h b/src/gallium/winsys/svga/drm/svga_drm_public.h
new file mode 100644 (file)
index 0000000..e98c89d
--- /dev/null
@@ -0,0 +1,41 @@
+/**********************************************************
+ * Copyright 2010 VMware, 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 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 THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION 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
+ * VMware SVGA DRM winsys public interface. Used by targets to create a stack.
+ *
+ * @author Jakob Bornecrantz Fonseca <jakob@vmware.com>
+ */
+
+#ifndef SVGA_DRM_PUBLIC_H_
+#define SVGA_DRM_PUBLIC_H_
+
+struct svga_winsys_screen;
+
+struct svga_winsys_screen *
+svga_drm_winsys_screen_create(int fd);
+
+#endif /* SVGA_PUBLIC_H_ */
index fe285226918cd26fb3cc9ac22f47c1d98e6309e3..1b0d10f60d6635707815bf8a75953935f02f2bfe 100644 (file)
 #include "util/u_format.h"
 #include "vmw_screen.h"
 
-#include "trace/tr_drm.h"
-
 #include "vmw_screen.h"
 #include "vmw_surface.h"
 #include "vmw_fence.h"
 #include "vmw_context.h"
+#include "svga_drm_public.h"
+
+#include "state_tracker/drm_driver.h"
 
-#include <state_tracker/drm_api.h>
 #include "vmwgfx_drm.h"
 #include <xf86drm.h>
 
@@ -84,15 +84,13 @@ vmw_dri1_check_version(const struct dri1_api_version *cur,
    return FALSE;
 }
 
-/* This is actually the entrypoint to the entire driver, called by the
- * libGL (or EGL, or ...) code via the drm_api_hooks table at the
- * bottom of the file.
+/* This is actually the entrypoint to the entire driver,
+ * called by the target bootstrap code.
  */
-static struct pipe_screen *
-vmw_drm_create_screen(struct drm_api *drm_api, int fd)
+struct svga_winsys_screen *
+svga_drm_winsys_screen_create(int fd)
 {
    struct vmw_winsys_screen *vws;
-   struct pipe_screen *screen;
    boolean use_old_scanout_flag = FALSE;
 
    struct dri1_api_version drm_ver;
@@ -123,16 +121,7 @@ vmw_drm_create_screen(struct drm_api *drm_api, int fd)
    vws->base.surface_from_handle = vmw_drm_surface_from_handle;
    vws->base.surface_get_handle = vmw_drm_surface_get_handle;
 
-   screen = svga_screen_create( &vws->base );
-   if (!screen)
-      goto out_no_screen;
-
-   return screen;
-
-   /* Failure cases:
-    */
-out_no_screen:
-   vmw_winsys_destroy( vws );
+   return &vws->base;
 
 out_no_vws:
    return NULL;
@@ -253,15 +242,3 @@ vmw_drm_surface_get_handle(struct svga_winsys_screen *sws,
 
     return TRUE;
 }
-
-static struct drm_api vmw_drm_api_hooks = {
-   .name = "vmwgfx",
-   .driver_name = "vmwgfx",
-   .create_screen = vmw_drm_create_screen,
-   .destroy = NULL,
-};
-
-struct drm_api* drm_api_create()
-{
-   return trace_drm_create(&vmw_drm_api_hooks);
-}
index fbb1a8f9a21d07e91ec178dd125d45e644f0ca6e..2f2807df0b2b7813d92caa4962aab782b9de05b1 100644 (file)
@@ -72,6 +72,7 @@
 #define DRM_VMW_PARAM_FIFO_OFFSET      3
 #define DRM_VMW_PARAM_HW_CAPS          4
 #define DRM_VMW_PARAM_FIFO_CAPS        5
+#define DRM_VMW_PARAM_MAX_FB_SIZE      6
 
 /**
  * struct drm_vmw_getparam_arg
diff --git a/src/gallium/winsys/sw/drm/Makefile b/src/gallium/winsys/sw/drm/Makefile
deleted file mode 100644 (file)
index 7966453..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-TOP = ../../../../..
-include $(TOP)/configs/current
-
-LIBNAME = swdrm
-
-C_SOURCES = sw_drm_api.c
-
-LIBRARY_INCLUDES =
-
-LIBRARY_DEFINES =
-
-include ../../../Makefile.template
diff --git a/src/gallium/winsys/sw/drm/SConscript b/src/gallium/winsys/sw/drm/SConscript
deleted file mode 100644 (file)
index 15a2e05..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#######################################################################
-# SConscript for xlib winsys
-
-
-Import('*')
-
-env = env.Clone()
-
-env.Append(CPPPATH = [
-    '#/src/gallium/include',
-    '#/src/gallium/auxiliary',
-    '#/src/gallium/drivers',
-])
-
-ws_drm = env.ConvenienceLibrary(
-    target = 'ws_drm',
-    source = [
-       'sw_drm_api.c',
-    ]
-)
-Export('ws_drm')
diff --git a/src/gallium/winsys/sw/drm/sw_drm_api.c b/src/gallium/winsys/sw/drm/sw_drm_api.c
deleted file mode 100644 (file)
index 7b86382..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/**********************************************************
- * Copyright 2010 VMware, 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 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 THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION 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 "util/u_memory.h"
-#include "softpipe/sp_public.h"
-#include "state_tracker/drm_api.h"
-#include "../../sw/wrapper/wrapper_sw_winsys.h"
-#include "sw_drm_api.h"
-
-
-/*
- * Defines
- */
-
-
-struct sw_drm_api
-{
-   struct drm_api base;
-   struct drm_api *api;
-   struct sw_winsys *sw;
-};
-
-static INLINE struct sw_drm_api *
-sw_drm_api(struct drm_api *api)
-{
-   return (struct sw_drm_api *)api;
-}
-
-
-/*
- * Exported functions
- */
-
-
-static struct pipe_screen *
-sw_drm_create_screen(struct drm_api *_api, int drmFD)
-{
-   struct sw_drm_api *swapi = sw_drm_api(_api);
-   struct drm_api *api = swapi->api;
-   struct sw_winsys *sww;
-   struct pipe_screen *screen;
-
-   screen = api->create_screen(api, drmFD);
-   if (!screen)
-      return NULL;
-
-   sww = wrapper_sw_winsys_warp_pipe_screen(screen);
-   if (!sww)
-      return NULL;
-
-   return softpipe_create_screen(sww);
-}
-
-static void
-sw_drm_destroy(struct drm_api *api)
-{
-   struct sw_drm_api *swapi = sw_drm_api(api);
-   if (swapi->api->destroy)
-      swapi->api->destroy(swapi->api);
-
-   FREE(swapi);
-}
-
-struct drm_api *
-sw_drm_api_create(struct drm_api *api)
-{
-   struct sw_drm_api *swapi = CALLOC_STRUCT(sw_drm_api);
-
-   if (!swapi)
-      return api;
-
-   swapi->base.name = api->name;
-   swapi->base.driver_name = api->driver_name;
-   swapi->base.create_screen = sw_drm_create_screen;
-   swapi->base.destroy = sw_drm_destroy;
-
-   swapi->api = api;
-
-   return &swapi->base;
-}
diff --git a/src/gallium/winsys/sw/drm/sw_drm_api.h b/src/gallium/winsys/sw/drm/sw_drm_api.h
deleted file mode 100644 (file)
index ce90a04..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/**********************************************************
- * Copyright 2010 VMware, 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 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 THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION 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 SW_DRM_API_H
-#define SW_DRM_API_H
-
-struct drm_api;
-
-struct drm_api * sw_drm_api_create(struct drm_api *api);
-
-#endif
index f4b0fb55a784bce76acac67dca3bb9d31a4c7ec3..462d49e8840e06ca3d9b7337ba9672f31caf055b 100644 (file)
@@ -70,8 +70,8 @@ LIBS = \
 APPS = glsl_compiler glcpp/glcpp
 
 GLSL2_C_SOURCES = \
-       ../mesa/shader/hash_table.c \
-       ../mesa/shader/symbol_table.c
+       ../mesa/program/hash_table.c \
+       ../mesa/program/symbol_table.c
 GLSL2_CXX_SOURCES = \
        main.cpp
 
@@ -87,7 +87,7 @@ DEFINES = \
 
 GLCPP_OBJECTS = \
        $(GLCPP_SOURCES:.c=.o) \
-       ../mesa/shader/hash_table.o
+       ../mesa/program/hash_table.o
 
 OBJECTS = \
        $(C_SOURCES:.c=.o) \
@@ -97,7 +97,7 @@ INCLUDES = \
        -I. \
        -I../mesa \
        -I../mapi \
-       -I../mesa/shader \
+       -I../mesa/program \
        -I../../include \
        $(LIBRARY_INCLUDES)
 
index 21c2b7617e93b7197ffc44f4103682f2c67e5769..3aa4fd4d53e7c3b88075ba8126bac929693c9134 100644 (file)
@@ -37,7 +37,7 @@ static void
 usage(void)
 {
    printf("Usage:\n");
-   printf("  compile fragment|vertex <source> <output>\n");
+   printf("  compile fragment|vertex|geometry <source> <output>\n");
 }
 
 int
@@ -65,6 +65,8 @@ main(int argc,
       shader_type = 1;
    } else if (!strcmp(argv[1], "vertex")) {
       shader_type = 2;
+   } else if (!strcmp(argv[1], "geometry")) {
+      shader_type = 3;
    } else {
       usage();
       return 1;
@@ -80,6 +82,9 @@ main(int argc,
    fseek(in, 0, SEEK_END);
    size = ftell(in);
    assert(size != -1);
+   if (size == -1) {
+      return 1;
+   }
    fseek(in, 0, SEEK_SET);
 
    out = fopen(argv[3], "w");
index c8a1a1868cc8d2166202c71fade8896f3ed0a218..caf72a71cf149f02ed7188513383f7514caeb4a9 100644 (file)
@@ -59,6 +59,9 @@ main(int argc,
    fseek(in, 0, SEEK_END);
    size = ftell(in);
    assert(size != -1);
+   if (size == -1) {
+      return 1;
+   }
    fseek(in, 0, SEEK_SET);
 
    out = fopen(argv[2], "wb");
index 5ab6bae96d121918651cb79256ca8b6569a305b6..0f09b157efd7075868e83cbc0878f6e475215cb5 100644 (file)
@@ -58,6 +58,9 @@ main(int argc,
    fseek(in, 0, SEEK_END);
    size = ftell(in);
    assert(size != -1);
+   if (size == -1) {
+      return 1;
+   }
    fseek(in, 0, SEEK_SET);
 
    out = fopen(argv[2], "wb");
index b4c6d609300f4a2d09bdc395bb48f3d8f3a59b02..f89f47d0611631a6b269e3677b8b0078d6021b71 100644 (file)
@@ -58,6 +58,9 @@ main(int argc,
    fseek(in, 0, SEEK_END);
    size = ftell(in);
    assert(size != -1);
+   if (size == -1) {
+      return 1;
+   }
    fseek(in, 0, SEEK_SET);
 
    out = fopen(argv[2], "wb");
index 9820ad94dc9e5e126142de2211be082128c8c704..fa5c226da835d40c0c367e3bf3db7b358d8c9b55 100644 (file)
@@ -57,6 +57,9 @@ main(int argc,
    fseek(in, 0, SEEK_END);
    size = ftell(in);
    assert(size != -1);
+   if (size == -1) {
+      return 1;
+   }
    fseek(in, 0, SEEK_SET);
 
    out = fopen(argv[2], "wb");
index 663436dde99f5c45c91d78f134b1216e7a13ced6..09456f5219ae0e32edf1b6cdd32576637b657e51 100644 (file)
 #define PARAM_QUALIFIER_IN                         0
 #define PARAM_QUALIFIER_OUT                        1
 #define PARAM_QUALIFIER_INOUT                      2
+#define PARAM_QUALIFIER_NONE                       3
 
 /* function parameter */
 #define PARAMETER_NONE                             0
@@ -836,7 +837,6 @@ _parse_storage_qualifier(struct parse_context *ctx,
    return 0;
 }
 
-
 static int
 _parse_struct_declarator(struct parse_context *ctx,
                          struct parse_state *ps)
@@ -1114,6 +1114,21 @@ _parse_type_specifier(struct parse_context *ctx,
    return 0;
 }
 
+static int
+_parse_parameter_qualifier(struct parse_context *ctx,
+                           struct parse_state *ps)
+{
+   unsigned int e = _emit(ctx, &ps->out, PARAM_QUALIFIER_NONE);
+
+   if (_parse_id(ctx, ctx->dict.in, ps) == 0) {
+      _update(ctx, e, PARAM_QUALIFIER_IN);
+   } else if (_parse_id(ctx, ctx->dict.out, ps) == 0) {
+      _update(ctx, e, PARAM_QUALIFIER_OUT);
+   } else if (_parse_id(ctx, ctx->dict.inout, ps) == 0) {
+      _update(ctx, e, PARAM_QUALIFIER_INOUT);
+   }
+   return 0;
+}
 
 static int
 _parse_fully_specified_type(struct parse_context *ctx,
@@ -1136,6 +1151,7 @@ _parse_fully_specified_type(struct parse_context *ctx,
    if (_parse_storage_qualifier(ctx, &p)) {
       _emit(ctx, &p.out, TYPE_QUALIFIER_NONE);
    }
+   _parse_parameter_qualifier(ctx, &p);
    if (_parse_precision(ctx, &p)) {
       _emit(ctx, &p.out, PRECISION_DEFAULT);
    }
@@ -1167,23 +1183,6 @@ _parse_function_header(struct parse_context *ctx,
 }
 
 
-static int
-_parse_parameter_qualifier(struct parse_context *ctx,
-                           struct parse_state *ps)
-{
-   unsigned int e = _emit(ctx, &ps->out, PARAM_QUALIFIER_IN);
-
-   if (_parse_id(ctx, ctx->dict.out, ps) == 0) {
-      _update(ctx, e, PARAM_QUALIFIER_OUT);
-   } else if (_parse_id(ctx, ctx->dict.inout, ps) == 0) {
-      _update(ctx, e, PARAM_QUALIFIER_INOUT);
-   } else {
-      _parse_id(ctx, ctx->dict.in, ps);
-   }
-   return 0;
-}
-
-
 static int
 _parse_function_identifier(struct parse_context *ctx,
                            struct parse_state *ps)
@@ -2192,9 +2191,8 @@ _parse_asm_statement(struct parse_context *ctx,
    if (_parse_identifier(ctx, &p)) {
       return -1;
    }
-   if (_parse_asm_arguments(ctx, &p)) {
-      return -1;
-   }
+   /* optional arguments */
+   _parse_asm_arguments(ctx, &p);
    if (_parse_token(ctx, SL_PP_SEMICOLON, &p)) {
       return -1;
    }
index 8fbc66c974d081c07221af6d42c50867124937f6..27e825597c52a622222f8ee38825c72adcbd9bf9 100644 (file)
@@ -29,7 +29,7 @@
 #include <new>
 
 extern "C" {
-#include "symbol_table.h"
+#include "program/symbol_table.h"
 }
 #include "ir.h"
 #include "glsl_types.h"
index 7c30a40a6ce1fb89bb16489637e9989c35b26a52..ea0274eac33d96381d342c94d14ef6459e355e55 100644 (file)
@@ -74,11 +74,11 @@ extern "C" {
 
 #include "main/mtypes.h"
 #include "main/macros.h"
+#include "main/shaderobj.h"
 #include "glsl_symbol_table.h"
 #include "ir.h"
 #include "program.h"
 #include "hash_table.h"
-#include "shader_api.h"
 #include "linker.h"
 #include "ir_optimization.h"
 
index bb1cd919cd62d647643310dfc06c8fea432db6f1..0a49203d4b2f918edea159ee90b8320f967cf6ac 100644 (file)
@@ -25,8 +25,8 @@
 #include "main/mtypes.h"
 
 extern "C" {
-#include "shader/prog_parameter.h"
-#include "shader/prog_uniform.h"
+#include "program/prog_parameter.h"
+#include "program/prog_uniform.h"
 }
 
 extern void
index 7d3b8d8a6a57abfb4811ead281cffbfc178863fa..35b36a394c4f3fb79c014c9148cfc0190713996b 100644 (file)
@@ -198,7 +198,7 @@ printf("*********************%d\n",RandomInterpolate);
 
 #endif
 
-#define Swap(a,b)      if (1) { GLUvertex *t = a; a = b; b = t; } else
+#define Swap(a,b)      do { GLUvertex *t = a; a = b; b = t; } while (0)
 
 void __gl_edgeIntersect( GLUvertex *o1, GLUvertex *d1,
                         GLUvertex *o2, GLUvertex *d2,
index 95f87cdc9499dd118d80986137a9ddfcc46fe7b1..36cb3a7be29aa637fa0adc4a6c69d9575b6a8a43 100644 (file)
 #include "mesh.h"
 #include "memalloc.h"
 
+#ifndef TRUE
 #define TRUE 1
+#endif
+#ifndef FALSE
 #define FALSE 0
+#endif
 
 static GLUvertex *allocVertex()
 {
index 7ab83167bbdbc28ade3bf5a5b0f08ea31185e003..9a3bd43d3c9ef84c39f1aae406a6fc4a3568ac88 100644 (file)
 #include <math.h>
 #include <assert.h>
 
+#ifndef TRUE
 #define TRUE 1
+#endif
+#ifndef FALSE
 #define FALSE 0
+#endif
 
 #define Dot(u,v)       (u[0]*v[0] + u[1]*v[1] + u[2]*v[2])
 
index e3a6c6068a0d4b70425e4e6699d0ce9c88417933..52698b59cc53597b2dbbbcc0827bcbb4d92acc6a 100644 (file)
 
 #define INIT_SIZE      32
 
+#ifndef TRUE
 #define TRUE 1
+#endif
+#ifndef FALSE
 #define FALSE 0
+#endif
 
 #ifdef FOR_TRITE_TEST_PROGRAM
 #define LEQ(x,y)       (*pq->leq)(x,y)
@@ -159,7 +163,7 @@ void pqInit( PriorityQ *pq )
 PQhandle pqInsert( PriorityQ *pq, PQkey keyNew )
 {
   long curr;
-  PQhandle free;
+  PQhandle free_handle;
 
   curr = ++ pq->size;
   if( (curr*2) > pq->max ) {
@@ -186,21 +190,21 @@ PQhandle pqInsert( PriorityQ *pq, PQkey keyNew )
   }
 
   if( pq->freeList == 0 ) {
-    free = curr;
+    free_handle = curr;
   } else {
-    free = pq->freeList;
-    pq->freeList = pq->handles[free].node;
+    free_handle = pq->freeList;
+    pq->freeList = pq->handles[free_handle].node;
   }
 
-  pq->nodes[curr].handle = free;
-  pq->handles[free].node = curr;
-  pq->handles[free].key = keyNew;
+  pq->nodes[curr].handle = free_handle;
+  pq->handles[free_handle].node = curr;
+  pq->handles[free_handle].key = keyNew;
 
   if( pq->initialized ) {
     FloatUp( pq, curr );
   }
-  assert(free != LONG_MAX);
-  return free;
+  assert(free_handle != LONG_MAX);
+  return free_handle;
 }
 
 /* really __gl_pqHeapExtractMin */
index 11f0263ac93e595302653e4d1bb6599240e79a22..c6b99cce55200f85daada9db4b01823964821f99 100644 (file)
@@ -85,7 +85,7 @@ void pqDeletePriorityQ( PriorityQ *pq )
 
 #define LT(x,y)                (! LEQ(y,x))
 #define GT(x,y)                (! LEQ(x,y))
-#define Swap(a,b)      if(1){PQkey *tmp = *a; *a = *b; *b = tmp;}else
+#define Swap(a,b)      do{PQkey *tmp = *a; *a = *b; *b = tmp;}while(0)
 
 /* really __gl_pqSortInit */
 int pqInit( PriorityQ *pq )
index 4f376f7f42526e0da3b8883a58c261d872bdefdc..bca836f0467c1d6c1dcea6fea6ce1ed92c342e85 100644 (file)
 #include "tess.h"
 #include "render.h"
 
+#ifndef TRUE
 #define TRUE 1
+#endif
+#ifndef FALSE
 #define FALSE 0
+#endif
 
 /* This structure remembers the information we need about a primitive
  * to be able to render it later, once we have determined which
@@ -143,11 +147,11 @@ static void RenderMaximumFaceGroup( GLUtesselator *tess, GLUface *fOrig )
 
 #define AddToTrail(f,t)        ((f)->trail = (t), (t) = (f), (f)->marked = TRUE)
 
-#define FreeTrail(t)   if( 1 ) { \
+#define FreeTrail(t)   do { \
                          while( (t) != NULL ) { \
                            (t)->marked = FALSE; t = (t)->trail; \
                          } \
-                       } else /* absorb trailing semicolon */
+                       } while(0) /* absorb trailing semicolon */
 
 
 
index 744be6b47d73a87a76b1ef71637da08e946c7a53..eca828ff67fffd4b6ebd556bac63434fa12c9921 100644 (file)
 #include "memalloc.h"
 #include "sweep.h"
 
+#ifndef TRUE
 #define TRUE 1
+#endif
+#ifndef FALSE
 #define FALSE 0
+#endif
 
 #ifdef FOR_TRITE_TEST_PROGRAM
 extern void DebugEvent( GLUtesselator *tess );
index 029a02c3ae44dc46b3268e2e77b7ea0bae2ff25b..4a0e8dea7f79988bf35b6872f5f2f2a611234135 100644 (file)
 #define GLU_TESS_DEFAULT_TOLERANCE 0.0
 #define GLU_TESS_MESH          100112  /* void (*)(GLUmesh *mesh)          */
 
+#ifndef TRUE
 #define TRUE 1
+#endif
+#ifndef FALSE
 #define FALSE 0
+#endif
 
 /*ARGSUSED*/ static void GLAPIENTRY noBegin( GLenum type ) {}
 /*ARGSUSED*/ static void GLAPIENTRY noEdgeFlag( GLboolean boundaryEdge ) {}
index 8e63eaaad77e1a9aee02899257f06b724b14b1fc..026ab849c1b82e14df8ca6bab9bf73293a3fa0da 100644 (file)
@@ -5552,7 +5552,7 @@ static void shove233rev(const GLfloat shoveComponents[],
 static void extract565(int isSwap,
                       const void *packedPixel, GLfloat extractComponents[])
 {
-   GLushort ushort= *(const GLushort *)packedPixel;
+   GLushort ushort;
 
    if (isSwap) {
      ushort= __GLU_SWAP_2_BYTES(packedPixel);
@@ -5593,7 +5593,7 @@ static void shove565(const GLfloat shoveComponents[],
 static void extract565rev(int isSwap,
                          const void *packedPixel, GLfloat extractComponents[])
 {
-   GLushort ushort= *(const GLushort *)packedPixel;
+   GLushort ushort;
 
    if (isSwap) {
      ushort= __GLU_SWAP_2_BYTES(packedPixel);
index 6889cd4b402f561706ef79b46962a7358f08523a..69f8052c0927a005ddb8917c97ee7a63428a2be0 100644 (file)
@@ -137,4 +137,4 @@ depend: $(SOURCES)
        @ $(MKDEP) $(MKDEP_OPTIONS) -I$(TOP)/include $(SOURCES) \
                $(X11_INCLUDES) > /dev/null 
 
-include depend
+-include depend
index d8e336ceed752e3aa01026f8ea43ba2815dbb9dc..12feb41b6088ee79a4f417a21e4997eee0299502 100644 (file)
@@ -19,8 +19,6 @@
 #include "glutint.h"
 
 void (GLUTCALLBACK *__glutMenuStatusFunc) (int, int, int);
-GLUTmenu *__glutMappedMenu;
-GLUTwindow *__glutMenuWindow;
 GLUTmenuItem *__glutItemSelected;
 unsigned __glutMenuButton;
 
index 1fb3d3c320223402ddb137a17646b6cba11f4b16..776b1aa5bfb9b5e678f5b4e0e68487dfaca8a6f2 100644 (file)
@@ -17,7 +17,7 @@ OBJECTS = $(GLW_SOURCES:.c=.o)
 ##### RULES #####
 
 .c.o:
-       $(CC) -c $(INCDIRS) $(CFLAGS) $<
+       $(CC) -c $(INCDIRS) $(CFLAGS) $(GLW_CFLAGS) $<
 
 
 
@@ -71,4 +71,4 @@ depend: $(GLW_SOURCES)
                $(X11_INCLUDES) > /dev/null
 
 
-include depend
+-include depend
index d0e88805bccc9d2db11bfa757a7d0f138a0cb00e..36b43f0f84af100a26e9868c7f8fc37f54bb8125 100644 (file)
@@ -38,7 +38,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
 
-#define NEED_REPLIES
 #include <X11/Xlibint.h>
 #include <X11/extensions/Xext.h>
 #include <X11/extensions/extutil.h>
index 4f2e8f9914962e4061408bebf6a6915f709aa97f..46c84f3ab77419f5102cc1004ec4c016bf8a496d 100644 (file)
@@ -38,8 +38,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 /* THIS IS NOT AN X CONSORTIUM STANDARD */
 
-#define NEED_EVENTS
-#define NEED_REPLIES
 #include <X11/Xlibint.h>
 #include "appledristr.h"
 #include <X11/extensions/Xext.h>
index acfe6e6a9e64391b05e310c60a97cda3a5aea845..ed76929d8aa95b5675932bf7df8079a41083bd33 100644 (file)
@@ -82,8 +82,7 @@ proc main {argc argv} {
        glXBindSwapBarrierSGIX glXQueryMaxSwapBarriersSGIX \
        glXGetSyncValuesOML glXSwapBuffersMscOML \
        glXWaitForMscOML glXWaitForSbcOML \
-       glXAllocateMemoryMESA glXFreeMemoryMESA \
-       glXGetMemoryOffsetMESA glXReleaseBuffersMESA \
+       glXReleaseBuffersMESA \
        glXCreateGLXPixmapMESA glXCopySubBufferMESA \
        glXQueryGLXPbufferSGIX glXCreateGLXPbufferSGIX \
        glXDestroyGLXPbufferSGIX glXSelectEventSGIX \
index 44c5a256f2014a018850cdf70d8b51f083e0cb22..1569679c7130ca1c86b9cc9c7c786ee23924a69e 100644 (file)
@@ -31,54 +31,6 @@ glXGetSwapIntervalMESA(void)
 }
 
 
-/*
-** GLX_MESA_swap_frame_usage
-*/
-
-int
-glXBeginFrameTrackingMESA(Display * dpy, GLXDrawable drawable)
-{
-   int status = GLX_BAD_CONTEXT;
-   (void) dpy;
-   (void) drawable;
-   return status;
-}
-
-
-int
-glXEndFrameTrackingMESA(Display * dpy, GLXDrawable drawable)
-{
-   int status = GLX_BAD_CONTEXT;
-   (void) dpy;
-   (void) drawable;
-   return status;
-}
-
-
-int
-glXGetFrameUsageMESA(Display * dpy, GLXDrawable drawable, GLfloat * usage)
-{
-   int status = GLX_BAD_CONTEXT;
-   (void) dpy;
-   (void) drawable;
-   (void) usage;
-   return status;
-}
-
-int
-glXQueryFrameTrackingMESA(Display * dpy, GLXDrawable drawable,
-                          int64_t * sbc, int64_t * missedFrames,
-                          GLfloat * lastMissedUsage)
-{
-   int status = GLX_BAD_CONTEXT;
-   (void) dpy;
-   (void) drawable;
-   (void) sbc;
-   (void) missedFrames;
-   (void) lastMissedUsage;
-   return status;
-}
-
 /*
 ** GLX_SGI_video_sync
 */
@@ -191,52 +143,6 @@ glXWaitForSbcOML(Display * dpy, GLXDrawable drawable,
 }
 
 
-/**
- * GLX_MESA_allocate_memory
- */
-/*@{*/
-
-PUBLIC void *
-glXAllocateMemoryMESA(Display * dpy, int scrn,
-                      size_t size, float readFreq,
-                      float writeFreq, float priority)
-{
-   (void) dpy;
-   (void) scrn;
-   (void) size;
-   (void) readFreq;
-   (void) writeFreq;
-   (void) priority;
-   return NULL;
-}
-
-
-PUBLIC void
-glXFreeMemoryMESA(Display * dpy, int scrn, void *pointer)
-{
-#ifdef __DRI_ALLOCATE
-   __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, scrn);
-
-   if (psc && psc->allocate)
-      (*psc->allocate->freeMemory) (psc->__driScreen, pointer);
-
-#else
-   (void) dpy;
-   (void) scrn;
-   (void) pointer;
-#endif /* __DRI_ALLOCATE */
-}
-
-
-PUBLIC GLuint
-glXGetMemoryOffsetMESA(Display * dpy, int scrn, const void *pointer)
-{
-   (void) dpy;
-   (void) scrn;
-   (void) pointer;
-   return ~0L;
-}
-
 Bool
 glXReleaseBuffersMESA(Display * dpy, GLXDrawable d)
 {
index 6afa4149651b7ed6945af503e86877b1feea1814..d53431c19a64b2305a8836654feeaf1f28c500a7 100644 (file)
@@ -33,7 +33,6 @@
 
 #ifdef GLX_DIRECT_RENDERING
 
-#define NEED_REPLIES
 #include <stdio.h>
 #include <X11/Xlibint.h>
 #include <X11/extensions/Xext.h>
@@ -89,7 +88,7 @@ static Bool
 DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
 {
    XExtDisplayInfo *info = DRI2FindDisplay(dpy);
-   XExtDisplayInfo *glx_info = __glXFindDisplay(dpy);
+   __GLXdisplayPrivate *glx_dpy = __glXInitialize(dpy);
 
    XextCheckExtension(dpy, info, dri2ExtensionName, False);
 
@@ -100,8 +99,15 @@ DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
    {
       GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
       xDRI2BufferSwapComplete *awire = (xDRI2BufferSwapComplete *)wire;
+      __GLXDRIdrawable *pdraw;
+
+      /* Ignore swap events if we're not looking for them */
+      pdraw = dri2GetGlxDrawableFromXDrawableId(dpy, awire->drawable);
+      if (!(pdraw->eventMask & GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK))
+        return False;
+
       aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire);
-      aevent->type = glx_info->codes->first_event + GLX_BufferSwapComplete;
+      aevent->type = glx_dpy->codes->first_event + GLX_BufferSwapComplete;
       aevent->send_event = (awire->type & 0x80) != 0;
       aevent->display = dpy;
       aevent->drawable = awire->drawable;
index d4747388e30fe1cc89e1f255e7c23b1ae239c350..49c7ce75024433414bc811f9a1b33e223d1989e9 100644 (file)
 #undef DRI2_MINOR
 #define DRI2_MINOR 1
 
-typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
-typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
-typedef struct __GLXDRIdrawablePrivateRec __GLXDRIdrawablePrivate;
-
-struct __GLXDRIdisplayPrivateRec
+struct dri2_display
 {
    __GLXDRIdisplay base;
 
@@ -74,19 +70,39 @@ struct __GLXDRIdisplayPrivateRec
    int swapAvailable;
    int invalidateAvailable;
 
+   __glxHashTable *dri2Hash;
+
    const __DRIextension *loader_extensions[4];
 };
 
-struct __GLXDRIcontextPrivateRec
+struct dri2_screen {
+   __GLXscreenConfigs base;
+
+   __DRIscreen *driScreen;
+   __GLXDRIscreen vtable;
+   const __DRIdri2Extension *dri2;
+   const __DRIcoreExtension *core;
+
+   const __DRI2flushExtension *f;
+   const __DRI2configQueryExtension *config;
+   const __DRItexBufferExtension *texBuffer;
+   const __DRIconfig **driver_configs;
+
+   void *driver;
+   int fd;
+};
+
+struct dri2_context
 {
-   __GLXDRIcontext base;
+   __GLXcontext base;
+   __GLXDRIcontext dri_vtable;
    __DRIcontext *driContext;
-   __GLXscreenConfigs *psc;
 };
 
-struct __GLXDRIdrawablePrivateRec
+struct dri2_drawable
 {
    __GLXDRIdrawable base;
+   __DRIdrawable *driDrawable;
    __DRIbuffer buffers[5];
    int bufferCount;
    int width, height;
@@ -95,51 +111,61 @@ struct __GLXDRIdrawablePrivateRec
    int swap_interval;
 };
 
-static void dri2WaitX(__GLXDRIdrawable * pdraw);
+static const struct glx_context_vtable dri2_context_vtable;
 
 static void
-dri2DestroyContext(__GLXDRIcontext * context,
-                   __GLXscreenConfigs * psc, Display * dpy)
+dri2_destroy_context(__GLXcontext *context)
 {
-   __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
-   const __DRIcoreExtension *core = pcp->psc->core;
+   struct dri2_context *pcp = (struct dri2_context *) context;
+   struct dri2_screen *psc = (struct dri2_screen *) context->psc;
+
+   if (context->xid)
+      glx_send_destroy_context(psc->base.dpy, context->xid);
+
+   if (context->extensions)
+      XFree((char *) context->extensions);
 
-   (*core->destroyContext) (pcp->driContext);
+   GarbageCollectDRIDrawables(context->psc);
+
+   (*psc->core->destroyContext) (pcp->driContext);
 
    Xfree(pcp);
 }
 
 static Bool
-dri2BindContext(__GLXDRIcontext * context,
-                __GLXDRIdrawable * draw, __GLXDRIdrawable * read)
+dri2BindContext(__GLXcontext *context,
+               __GLXDRIdrawable *draw, __GLXDRIdrawable *read)
 {
-   __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
-   const __DRIcoreExtension *core = pcp->psc->core;
+   struct dri2_context *pcp = (struct dri2_context *) context;
+   struct dri2_screen *psc = (struct dri2_screen *) pcp->base.psc;
+   struct dri2_drawable *pdr = (struct dri2_drawable *) draw;
+   struct dri2_drawable *prd = (struct dri2_drawable *) read;
 
-   return (*core->bindContext) (pcp->driContext,
-                                draw->driDrawable, read->driDrawable);
+   return (*psc->core->bindContext) (pcp->driContext,
+                                    pdr->driDrawable, prd->driDrawable);
 }
 
 static void
-dri2UnbindContext(__GLXDRIcontext * context)
+dri2UnbindContext(__GLXcontext *context)
 {
-   __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
-   const __DRIcoreExtension *core = pcp->psc->core;
+   struct dri2_context *pcp = (struct dri2_context *) context;
+   struct dri2_screen *psc = (struct dri2_screen *) pcp->base.psc;
 
-   (*core->unbindContext) (pcp->driContext);
+   (*psc->core->unbindContext) (pcp->driContext);
 }
 
-static __GLXDRIcontext *
-dri2CreateContext(__GLXscreenConfigs * psc,
-                  const __GLcontextModes * mode,
-                  GLXContext gc, GLXContext shareList, int renderType)
+static __GLXcontext *
+dri2_create_context(__GLXscreenConfigs *base,
+                   const __GLcontextModes * mode,
+                   GLXContext shareList, int renderType)
 {
-   __GLXDRIcontextPrivate *pcp, *pcp_shared;
+   struct dri2_context *pcp, *pcp_shared;
+   struct dri2_screen *psc = (struct dri2_screen *) base;
    __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
    __DRIcontext *shared = NULL;
 
    if (shareList) {
-      pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext;
+      pcp_shared = (struct dri2_context *) shareList;
       shared = pcp_shared->driContext;
    }
 
@@ -147,59 +173,70 @@ dri2CreateContext(__GLXscreenConfigs * psc,
    if (pcp == NULL)
       return NULL;
 
-   pcp->psc = psc;
+   memset(pcp, 0, sizeof *pcp);
+   if (!glx_context_init(&pcp->base, &psc->base, mode)) {
+      Xfree(pcp);
+      return NULL;
+   }
+
    pcp->driContext =
-      (*psc->dri2->createNewContext) (psc->__driScreen,
+      (*psc->dri2->createNewContext) (psc->driScreen,
                                       config->driConfig, shared, pcp);
-   gc->__driContext = pcp->driContext;
 
    if (pcp->driContext == NULL) {
       Xfree(pcp);
       return NULL;
    }
 
-   pcp->base.destroyContext = dri2DestroyContext;
-   pcp->base.bindContext = dri2BindContext;
-   pcp->base.unbindContext = dri2UnbindContext;
+   pcp->base.vtable = &dri2_context_vtable;
+   pcp->base.driContext = &pcp->dri_vtable;
+   pcp->dri_vtable.bindContext = dri2BindContext;
+   pcp->dri_vtable.unbindContext = dri2UnbindContext;
 
    return &pcp->base;
 }
 
 static void
-dri2DestroyDrawable(__GLXDRIdrawable * pdraw)
+dri2DestroyDrawable(__GLXDRIdrawable *base)
 {
-   const __DRIcoreExtension *core = pdraw->psc->core;
-
-   (*core->destroyDrawable) (pdraw->driDrawable);
-   DRI2DestroyDrawable(pdraw->psc->dpy, pdraw->xDrawable);
+   struct dri2_screen *psc = (struct dri2_screen *) base->psc;
+   struct dri2_drawable *pdraw = (struct dri2_drawable *) base;
+   __GLXdisplayPrivate *dpyPriv = psc->base.display;
+   struct dri2_display *pdp = (struct dri2_display *)dpyPriv->dri2Display;
+
+   __glxHashDelete(pdp->dri2Hash, pdraw->base.xDrawable);
+   (*psc->core->destroyDrawable) (pdraw->driDrawable);
+   DRI2DestroyDrawable(psc->base.dpy, pdraw->base.xDrawable);
    Xfree(pdraw);
 }
 
 static __GLXDRIdrawable *
-dri2CreateDrawable(__GLXscreenConfigs * psc,
-                   XID xDrawable,
-                   GLXDrawable drawable, const __GLcontextModes * modes)
+dri2CreateDrawable(__GLXscreenConfigs *base, XID xDrawable,
+                  GLXDrawable drawable, const __GLcontextModes * modes)
 {
-   __GLXDRIdrawablePrivate *pdraw;
+   struct dri2_drawable *pdraw;
+   struct dri2_screen *psc = (struct dri2_screen *) base;
    __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
    __GLXdisplayPrivate *dpyPriv;
-   __GLXDRIdisplayPrivate *pdp;
+   struct dri2_display *pdp;
    GLint vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1;
 
    pdraw = Xmalloc(sizeof(*pdraw));
    if (!pdraw)
       return NULL;
 
+   memset(pdraw, 0, sizeof *pdraw);
    pdraw->base.destroyDrawable = dri2DestroyDrawable;
    pdraw->base.xDrawable = xDrawable;
    pdraw->base.drawable = drawable;
-   pdraw->base.psc = psc;
+   pdraw->base.psc = &psc->base;
    pdraw->bufferCount = 0;
    pdraw->swap_interval = 1; /* default may be overridden below */
    pdraw->have_back = 0;
 
    if (psc->config)
-      psc->config->configQueryi(psc->__driScreen, "vblank_mode", &vblank_mode);
+      psc->config->configQueryi(psc->driScreen,
+                               "vblank_mode", &vblank_mode);
 
    switch (vblank_mode) {
    case DRI_CONF_VBLANK_NEVER:
@@ -213,28 +250,36 @@ dri2CreateDrawable(__GLXscreenConfigs * psc,
       break;
    }
 
-   DRI2CreateDrawable(psc->dpy, xDrawable);
+   DRI2CreateDrawable(psc->base.dpy, xDrawable);
 
-   dpyPriv = __glXInitialize(psc->dpy);
-   pdp = (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display;;
+   dpyPriv = __glXInitialize(psc->base.dpy);
+   pdp = (struct dri2_display *)dpyPriv->dri2Display;;
    /* Create a new drawable */
-   pdraw->base.driDrawable =
-      (*psc->dri2->createNewDrawable) (psc->__driScreen,
+   pdraw->driDrawable =
+      (*psc->dri2->createNewDrawable) (psc->driScreen,
                                        config->driConfig, pdraw);
 
-   if (!pdraw->base.driDrawable) {
-      DRI2DestroyDrawable(psc->dpy, xDrawable);
+   if (!pdraw->driDrawable) {
+      DRI2DestroyDrawable(psc->base.dpy, xDrawable);
       Xfree(pdraw);
       return NULL;
    }
 
+   if (__glxHashInsert(pdp->dri2Hash, xDrawable, pdraw)) {
+      (*psc->core->destroyDrawable) (pdraw->driDrawable);
+      DRI2DestroyDrawable(psc->base.dpy, xDrawable);
+      Xfree(pdraw);
+      return None;
+   }
+
+
 #ifdef X_DRI2SwapInterval
    /*
     * Make sure server has the same swap interval we do for the new
     * drawable.
     */
    if (pdp->swapAvailable)
-      DRI2SwapInterval(psc->dpy, xDrawable, pdraw->swap_interval);
+      DRI2SwapInterval(psc->base.dpy, xDrawable, pdraw->swap_interval);
 #endif
 
    return &pdraw->base;
@@ -246,7 +291,16 @@ static int
 dri2DrawableGetMSC(__GLXscreenConfigs *psc, __GLXDRIdrawable *pdraw,
                   int64_t *ust, int64_t *msc, int64_t *sbc)
 {
-   return DRI2GetMSC(psc->dpy, pdraw->xDrawable, ust, msc, sbc);
+   CARD64 dri2_ust, dri2_msc, dri2_sbc;
+   int ret;
+
+   ret = DRI2GetMSC(psc->dpy, pdraw->xDrawable,
+                   &dri2_ust, &dri2_msc, &dri2_sbc);
+   *ust = dri2_ust;
+   *msc = dri2_msc;
+   *sbc = dri2_sbc;
+
+   return ret;
 }
 
 #endif
@@ -258,16 +312,32 @@ static int
 dri2WaitForMSC(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
               int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc)
 {
-   return DRI2WaitMSC(pdraw->psc->dpy, pdraw->xDrawable, target_msc, divisor,
-                     remainder, ust, msc, sbc);
+   CARD64 dri2_ust, dri2_msc, dri2_sbc;
+   int ret;
+
+   ret = DRI2WaitMSC(pdraw->psc->dpy, pdraw->xDrawable, target_msc, divisor,
+                    remainder, &dri2_ust, &dri2_msc, &dri2_sbc);
+   *ust = dri2_ust;
+   *msc = dri2_msc;
+   *sbc = dri2_sbc;
+
+   return ret;
 }
 
 static int
 dri2WaitForSBC(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust,
               int64_t *msc, int64_t *sbc)
 {
-   return DRI2WaitSBC(pdraw->psc->dpy, pdraw->xDrawable, target_sbc, ust, msc,
-                     sbc);
+   CARD64 dri2_ust, dri2_msc, dri2_sbc;
+   int ret;
+
+   ret = DRI2WaitSBC(pdraw->psc->dpy, pdraw->xDrawable,
+                    target_sbc, &dri2_ust, &dri2_msc, &dri2_sbc);
+   *ust = dri2_ust;
+   *msc = dri2_msc;
+   *sbc = dri2_sbc;
+
+   return ret;
 }
 
 #endif /* X_DRI2WaitMSC */
@@ -275,7 +345,8 @@ dri2WaitForSBC(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust,
 static void
 dri2CopySubBuffer(__GLXDRIdrawable *pdraw, int x, int y, int width, int height)
 {
-   __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
+   struct dri2_drawable *priv = (struct dri2_drawable *) pdraw;
+   struct dri2_screen *psc = (struct dri2_screen *) pdraw->psc;
    XRectangle xrect;
    XserverRegion region;
 
@@ -289,32 +360,30 @@ dri2CopySubBuffer(__GLXDRIdrawable *pdraw, int x, int y, int width, int height)
    xrect.height = height;
 
 #ifdef __DRI2_FLUSH
-   if (pdraw->psc->f)
-      (*pdraw->psc->f->flush) (pdraw->driDrawable);
+   if (psc->f)
+      (*psc->f->flush) (priv->driDrawable);
 #endif
 
-   region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
-   /* should get a fence ID back from here at some point */
-   DRI2CopyRegion(pdraw->psc->dpy, pdraw->xDrawable, region,
+   region = XFixesCreateRegion(psc->base.dpy, &xrect, 1);
+   DRI2CopyRegion(psc->base.dpy, pdraw->xDrawable, region,
                   DRI2BufferFrontLeft, DRI2BufferBackLeft);
-   XFixesDestroyRegion(pdraw->psc->dpy, region);
 
    /* Refresh the fake front (if present) after we just damaged the real
     * front.
     */
-   dri2WaitX(pdraw);
+   if (priv->have_fake_front)
+      DRI2CopyRegion(psc->base.dpy, pdraw->xDrawable, region,
+                    DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
+
+   XFixesDestroyRegion(psc->base.dpy, region);
 }
 
 static void
-dri2WaitX(__GLXDRIdrawable *pdraw)
+dri2_copy_drawable(struct dri2_drawable *priv, int dest, int src)
 {
-   __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
    XRectangle xrect;
    XserverRegion region;
-
-   /* Check we have the right attachments */
-   if (!priv->have_fake_front)
-      return;
+   struct dri2_screen *psc = (struct dri2_screen *) priv->base.psc;
 
    xrect.x = 0;
    xrect.y = 0;
@@ -322,64 +391,66 @@ dri2WaitX(__GLXDRIdrawable *pdraw)
    xrect.height = priv->height;
 
 #ifdef __DRI2_FLUSH
-   if (pdraw->psc->f)
-      (*pdraw->psc->f->flush) (pdraw->driDrawable);
+   if (psc->f)
+      (*psc->f->flush) (priv->driDrawable);
 #endif
 
-   region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
-   DRI2CopyRegion(pdraw->psc->dpy, pdraw->xDrawable, region,
-                  DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
-   XFixesDestroyRegion(pdraw->psc->dpy, region);
+   region = XFixesCreateRegion(psc->base.dpy, &xrect, 1);
+   DRI2CopyRegion(psc->base.dpy, priv->base.xDrawable, region, dest, src);
+   XFixesDestroyRegion(psc->base.dpy, region);
+
 }
 
 static void
-dri2WaitGL(__GLXDRIdrawable * pdraw)
+dri2_wait_x(__GLXcontext *gc)
 {
-   __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
-   XRectangle xrect;
-   XserverRegion region;
+   struct dri2_drawable *priv = (struct dri2_drawable *)
+      GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
 
-   if (!priv->have_fake_front)
+   if (priv == NULL || !priv->have_fake_front)
       return;
 
-   xrect.x = 0;
-   xrect.y = 0;
-   xrect.width = priv->width;
-   xrect.height = priv->height;
+   dri2_copy_drawable(priv, DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
+}
 
-#ifdef __DRI2_FLUSH
-   if (pdraw->psc->f)
-      (*pdraw->psc->f->flush) (pdraw->driDrawable);
-#endif
+static void
+dri2_wait_gl(__GLXcontext *gc)
+{
+   struct dri2_drawable *priv = (struct dri2_drawable *)
+      GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
 
-   region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
-   DRI2CopyRegion(pdraw->psc->dpy, pdraw->xDrawable, region,
-                  DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
-   XFixesDestroyRegion(pdraw->psc->dpy, region);
+   if (priv == NULL || !priv->have_fake_front)
+      return;
+
+   dri2_copy_drawable(priv, DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
 }
 
 static void
 dri2FlushFrontBuffer(__DRIdrawable *driDrawable, void *loaderPrivate)
 {
-   __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
+   struct dri2_drawable *pdraw = loaderPrivate;
    __GLXdisplayPrivate *priv = __glXInitialize(pdraw->base.psc->dpy);
-   __GLXDRIdisplayPrivate *pdp = (__GLXDRIdisplayPrivate *)priv->dri2Display;
+   struct dri2_display *pdp = (struct dri2_display *)priv->dri2Display;
+   GLXContext gc = __glXGetCurrentContext();
 
    /* Old servers don't send invalidate events */
    if (!pdp->invalidateAvailable)
        dri2InvalidateBuffers(priv->dpy, pdraw->base.drawable);
 
-   dri2WaitGL(loaderPrivate);
+   dri2_wait_gl(gc);
 }
 
 
 static void
-dri2DestroyScreen(__GLXscreenConfigs * psc)
+dri2DestroyScreen(__GLXscreenConfigs *base)
 {
+   struct dri2_screen *psc = (struct dri2_screen *) base;
+
    /* Free the direct rendering per screen data */
-   (*psc->core->destroyScreen) (psc->__driScreen);
+   (*psc->core->destroyScreen) (psc->driScreen);
+   driDestroyConfigs(psc->driver_configs);
    close(psc->fd);
-   psc->__driScreen = NULL;
+   Xfree(psc);
 }
 
 /**
@@ -389,7 +460,7 @@ dri2DestroyScreen(__GLXscreenConfigs * psc)
  * \c DRI2GetBuffers or \c DRI2GetBuffersWithFormat.
  */
 static void
-process_buffers(__GLXDRIdrawablePrivate * pdraw, DRI2Buffer * buffers,
+process_buffers(struct dri2_drawable * pdraw, DRI2Buffer * buffers,
                 unsigned count)
 {
    int i;
@@ -418,15 +489,16 @@ static int64_t
 dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
                int64_t remainder)
 {
-    __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
+    struct dri2_drawable *priv = (struct dri2_drawable *) pdraw;
     __GLXdisplayPrivate *dpyPriv = __glXInitialize(priv->base.psc->dpy);
-    __GLXDRIdisplayPrivate *pdp =
-       (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display;
-    int64_t ret;
+    struct dri2_screen *psc = (struct dri2_screen *) priv->base.psc;
+    struct dri2_display *pdp =
+       (struct dri2_display *)dpyPriv->dri2Display;
+    CARD64 ret;
 
 #ifdef __DRI2_FLUSH
-    if (pdraw->psc->f)
-       (*pdraw->psc->f->flush)(pdraw->driDrawable);
+    if (psc->f)
+       (*psc->f->flush)(priv->driDrawable);
 #endif
 
     /* Old servers don't send invalidate events */
@@ -440,7 +512,7 @@ dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
     }
 
 #ifdef X_DRI2SwapBuffers
-    DRI2SwapBuffers(pdraw->psc->dpy, pdraw->xDrawable, target_msc, divisor,
+    DRI2SwapBuffers(psc->base.dpy, pdraw->xDrawable, target_msc, divisor,
                    remainder, &ret);
 #endif
 
@@ -453,7 +525,7 @@ dri2GetBuffers(__DRIdrawable * driDrawable,
                unsigned int *attachments, int count,
                int *out_count, void *loaderPrivate)
 {
-   __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
+   struct dri2_drawable *pdraw = loaderPrivate;
    DRI2Buffer *buffers;
 
    buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable,
@@ -476,7 +548,7 @@ dri2GetBuffersWithFormat(__DRIdrawable * driDrawable,
                          unsigned int *attachments, int count,
                          int *out_count, void *loaderPrivate)
 {
-   __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
+   struct dri2_drawable *pdraw = loaderPrivate;
    DRI2Buffer *buffers;
 
    buffers = DRI2GetBuffersWithFormat(pdraw->base.psc->dpy,
@@ -497,35 +569,38 @@ dri2GetBuffersWithFormat(__DRIdrawable * driDrawable,
 
 #ifdef X_DRI2SwapInterval
 
-static void
+static int
 dri2SetSwapInterval(__GLXDRIdrawable *pdraw, int interval)
 {
-   __GLXscreenConfigs *psc = pdraw->psc;
-   __GLXDRIdrawablePrivate *priv =  (__GLXDRIdrawablePrivate *) pdraw;
+   struct dri2_drawable *priv =  (struct dri2_drawable *) pdraw;
    GLint vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1;
+   struct dri2_screen *psc = (struct dri2_screen *) priv->base.psc;
 
    if (psc->config)
-      psc->config->configQueryi(psc->__driScreen, "vblank_mode", &vblank_mode);
+      psc->config->configQueryi(psc->driScreen,
+                               "vblank_mode", &vblank_mode);
 
    switch (vblank_mode) {
    case DRI_CONF_VBLANK_NEVER:
-      return;
+      return GLX_BAD_VALUE;
    case DRI_CONF_VBLANK_ALWAYS_SYNC:
       if (interval <= 0)
-        return;
+        return GLX_BAD_VALUE;
       break;
    default:
       break;
    }
 
-   DRI2SwapInterval(priv->base.psc->dpy, pdraw->xDrawable, interval);
+   DRI2SwapInterval(priv->base.psc->dpy, priv->base.xDrawable, interval);
    priv->swap_interval = interval;
+
+   return 0;
 }
 
-static unsigned int
+static int
 dri2GetSwapInterval(__GLXDRIdrawable *pdraw)
 {
-   __GLXDRIdrawablePrivate *priv =  (__GLXDRIdrawablePrivate *) pdraw;
+   struct dri2_drawable *priv =  (struct dri2_drawable *) pdraw;
 
   return priv->swap_interval;
 }
@@ -555,11 +630,14 @@ static const __DRIuseInvalidateExtension dri2UseInvalidate = {
 _X_HIDDEN void
 dri2InvalidateBuffers(Display *dpy, XID drawable)
 {
-   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
+   __GLXDRIdrawable *pdraw =
+      dri2GetGlxDrawableFromXDrawableId(dpy, drawable);
+   struct dri2_screen *psc = (struct dri2_screen *) pdraw->psc;
+   struct dri2_drawable *pdp = (struct dri2_drawable *) pdraw;
 
 #if __DRI2_FLUSH_VERSION >= 3
-   if (pdraw && pdraw->psc->f)
-       pdraw->psc->f->invalidate(pdraw->driDrawable);
+   if (pdraw && psc->f)
+       psc->f->invalidate(pdp->driDrawable);
 #endif
 }
 
@@ -569,29 +647,32 @@ dri2_bind_tex_image(Display * dpy,
                    int buffer, const int *attrib_list)
 {
    GLXContext gc = __glXGetCurrentContext();
-   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
-    __GLXdisplayPrivate *dpyPriv = __glXInitialize(dpy);
-    __GLXDRIdisplayPrivate *pdp =
-       (__GLXDRIdisplayPrivate *) dpyPriv->dri2Display;
+   struct dri2_context *pcp = (struct dri2_context *) gc;
+   __GLXDRIdrawable *base = GetGLXDRIDrawable(dpy, drawable);
+   __GLXdisplayPrivate *dpyPriv = __glXInitialize(dpy);
+   struct dri2_drawable *pdraw = (struct dri2_drawable *) base;
+   struct dri2_display *pdp =
+      (struct dri2_display *) dpyPriv->dri2Display;
+   struct dri2_screen *psc = (struct dri2_screen *) base->psc;
 
    if (pdraw != NULL) {
 
 #if __DRI2_FLUSH_VERSION >= 3
-      if (!pdp->invalidateAvailable && pdraw->psc->f)
-        pdraw->psc->f->invalidate(pdraw->driDrawable);
+      if (!pdp->invalidateAvailable && psc->f)
+        psc->f->invalidate(pdraw->driDrawable);
 #endif
 
-      if (pdraw->psc->texBuffer->base.version >= 2 &&
-         pdraw->psc->texBuffer->setTexBuffer2 != NULL) {
-        (*pdraw->psc->texBuffer->setTexBuffer2) (gc->__driContext,
-                                                 pdraw->textureTarget,
-                                                 pdraw->textureFormat,
-                                                 pdraw->driDrawable);
+      if (psc->texBuffer->base.version >= 2 &&
+         psc->texBuffer->setTexBuffer2 != NULL) {
+        (*psc->texBuffer->setTexBuffer2) (pcp->driContext,
+                                          pdraw->base.textureTarget,
+                                          pdraw->base.textureFormat,
+                                          pdraw->driDrawable);
       }
       else {
-        (*pdraw->psc->texBuffer->setTexBuffer) (gc->__driContext,
-                                                pdraw->textureTarget,
-                                                pdraw->driDrawable);
+        (*psc->texBuffer->setTexBuffer) (pcp->driContext,
+                                         pdraw->base.textureTarget,
+                                         pdraw->driDrawable);
       }
    }
 }
@@ -602,30 +683,71 @@ dri2_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
 }
 
 static const struct glx_context_vtable dri2_context_vtable = {
+   dri2_destroy_context,
+   dri2_wait_gl,
+   dri2_wait_x,
+   DRI_glXUseXFont,
    dri2_bind_tex_image,
    dri2_release_tex_image,
 };
 
-static __GLXDRIscreen *
-dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
-                 __GLXdisplayPrivate * priv)
+static void
+dri2BindExtensions(struct dri2_screen *psc, const __DRIextension **extensions)
+{
+   int i;
+
+   __glXEnableDirectExtension(&psc->base, "GLX_SGI_video_sync");
+   __glXEnableDirectExtension(&psc->base, "GLX_SGI_swap_control");
+   __glXEnableDirectExtension(&psc->base, "GLX_MESA_swap_control");
+   __glXEnableDirectExtension(&psc->base, "GLX_SGI_make_current_read");
+
+   /* FIXME: if DRI2 version supports it... */
+   __glXEnableDirectExtension(&psc->base, "INTEL_swap_event");
+
+   for (i = 0; extensions[i]; i++) {
+      if ((strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0)) {
+        psc->texBuffer = (__DRItexBufferExtension *) extensions[i];
+        __glXEnableDirectExtension(&psc->base, "GLX_EXT_texture_from_pixmap");
+      }
+
+      if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0)) {
+        psc->f = (__DRI2flushExtension *) extensions[i];
+        /* internal driver extension, no GL extension exposed */
+      }
+
+      if ((strcmp(extensions[i]->name, __DRI2_CONFIG_QUERY) == 0))
+        psc->config = (__DRI2configQueryExtension *) extensions[i];
+   }
+}
+
+static const struct glx_screen_vtable dri2_screen_vtable = {
+   dri2_create_context
+};
+
+static __GLXscreenConfigs *
+dri2CreateScreen(int screen, __GLXdisplayPrivate * priv)
 {
    const __DRIconfig **driver_configs;
    const __DRIextension **extensions;
-   const __GLXDRIdisplayPrivate *const pdp = (__GLXDRIdisplayPrivate *)
+   const struct dri2_display *const pdp = (struct dri2_display *)
       priv->dri2Display;
+   struct dri2_screen *psc;
    __GLXDRIscreen *psp;
    char *driverName, *deviceName;
    drm_magic_t magic;
    int i;
 
-   psp = Xmalloc(sizeof *psp);
-   if (psp == NULL)
+   psc = Xmalloc(sizeof *psc);
+   if (psc == NULL)
       return NULL;
 
-   if (!DRI2Connect(psc->dpy, RootWindow(psc->dpy, screen),
+   memset(psc, 0, sizeof *psc);
+   if (!glx_screen_init(&psc->base, screen, priv))
+       return NULL;
+
+   if (!DRI2Connect(priv->dpy, RootWindow(priv->dpy, screen),
                    &driverName, &deviceName)) {
-      XFree(psp);
+      XFree(psc);
       return NULL;
    }
 
@@ -664,7 +786,7 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
       goto handle_error;
    }
 
-   if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic)) {
+   if (!DRI2Authenticate(priv->dpy, RootWindow(priv->dpy, screen), magic)) {
       ErrorMessageF("failed to authenticate magic %d\n", magic);
       goto handle_error;
    }
@@ -673,31 +795,33 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
    /* If the server does not support the protocol for
     * DRI2GetBuffersWithFormat, don't supply that interface to the driver.
     */
-   psc->__driScreen =
+   psc->driScreen =
       psc->dri2->createNewScreen(screen, psc->fd,
                                 (const __DRIextension **)
                                 &pdp->loader_extensions[0],
                                 &driver_configs, psc);
 
-   if (psc->__driScreen == NULL) {
+   if (psc->driScreen == NULL) {
       ErrorMessageF("failed to create dri screen\n");
       goto handle_error;
    }
 
-   driBindCommonExtensions(psc);
-   dri2BindExtensions(psc);
+   extensions = psc->core->getExtensions(psc->driScreen);
+   dri2BindExtensions(psc, extensions);
 
-   psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
-   psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
+   psc->base.configs =
+      driConvertConfigs(psc->core, psc->base.configs, driver_configs);
+   psc->base.visuals =
+      driConvertConfigs(psc->core, psc->base.visuals, driver_configs);
 
    psc->driver_configs = driver_configs;
 
+   psc->base.vtable = &dri2_screen_vtable;
+   psp = &psc->vtable;
+   psc->base.driScreen = psp;
    psp->destroyScreen = dri2DestroyScreen;
-   psp->createContext = dri2CreateContext;
    psp->createDrawable = dri2CreateDrawable;
    psp->swapBuffers = dri2SwapBuffers;
-   psp->waitGL = dri2WaitGL;
-   psp->waitX = dri2WaitX;
    psp->getDrawableMSC = NULL;
    psp->waitForMSC = NULL;
    psp->waitForSBC = NULL;
@@ -717,26 +841,24 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
       psp->getSwapInterval = dri2GetSwapInterval;
 #endif
 #if defined(X_DRI2GetMSC) && defined(X_DRI2WaitMSC) && defined(X_DRI2SwapInterval)
-      __glXEnableDirectExtension(psc, "GLX_OML_sync_control");
+      __glXEnableDirectExtension(&psc->base, "GLX_OML_sync_control");
 #endif
    }
 
    /* DRI2 suports SubBuffer through DRI2CopyRegion, so it's always
     * available.*/
    psp->copySubBuffer = dri2CopySubBuffer;
-   __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer");
-
-   psc->direct_context_vtable = &dri2_context_vtable;
+   __glXEnableDirectExtension(&psc->base, "GLX_MESA_copy_sub_buffer");
 
    Xfree(driverName);
    Xfree(deviceName);
 
-   return psp;
+   return &psc->base;
 
 handle_error:
    Xfree(driverName);
    Xfree(deviceName);
-   XFree(psp);
+   XFree(psc);
 
    /* FIXME: clean up here */
 
@@ -751,6 +873,19 @@ dri2DestroyDisplay(__GLXDRIdisplay * dpy)
    Xfree(dpy);
 }
 
+_X_HIDDEN __GLXDRIdrawable *
+dri2GetGlxDrawableFromXDrawableId(Display *dpy, XID id)
+{
+   __GLXdisplayPrivate *d = __glXInitialize(dpy);
+   struct dri2_display *pdp = (struct dri2_display *) d->dri2Display;
+   __GLXDRIdrawable *pdraw;
+
+   if (__glxHashLookup(pdp->dri2Hash, id, (void *) &pdraw) == 0)
+      return pdraw;
+
+   return NULL;
+}
+
 /*
  * Allocate, initialize and return a __DRIdisplayPrivate object.
  * This is called from __glXInitialize() when we are given a new
@@ -759,7 +894,7 @@ dri2DestroyDisplay(__GLXDRIdisplay * dpy)
 _X_HIDDEN __GLXDRIdisplay *
 dri2CreateDisplay(Display * dpy)
 {
-   __GLXDRIdisplayPrivate *pdp;
+   struct dri2_display *pdp;
    int eventBase, errorBase, i;
 
    if (!DRI2QueryExtension(dpy, &eventBase, &errorBase))
@@ -794,6 +929,12 @@ dri2CreateDisplay(Display * dpy)
 #endif
    pdp->loader_extensions[i++] = NULL;
 
+   pdp->dri2Hash = __glxHashCreate();
+   if (pdp->dri2Hash == NULL) {
+      Xfree(pdp);
+      return NULL;
+   }
+
    return &pdp->base;
 }
 
index 429fc6d89126d91cf495e713134d390bb79f12ed..9b7da3e7df56652e897307e3cd2ec458bb88fc3d 100644 (file)
@@ -159,10 +159,20 @@ driOpenDriver(const char *driverName)
    return handle;
 }
 
+static GLboolean
+__driGetMSCRate(__DRIdrawable *draw,
+               int32_t * numerator, int32_t * denominator,
+               void *loaderPrivate)
+{
+   __GLXDRIdrawable *glxDraw = loaderPrivate;
+
+   return __glxGetMscRate(glxDraw, numerator, denominator);
+}
+
 _X_HIDDEN const __DRIsystemTimeExtension systemTimeExtension = {
    {__DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION},
    __glXGetUST,
-   __driGetMscRateOML
+   __driGetMSCRate
 };
 
 #define __ATTRIB(attrib, field) \
@@ -336,120 +346,14 @@ driConvertConfigs(const __DRIcoreExtension * core,
    return head.next;
 }
 
-/* Bind DRI1 specific extensions */
-_X_HIDDEN void
-driBindExtensions(__GLXscreenConfigs *psc)
-{
-   const __DRIextension **extensions;
-   int i;
-
-   extensions = psc->core->getExtensions(psc->__driScreen);
-
-   for (i = 0; extensions[i]; i++) {
-#ifdef __DRI_SWAP_CONTROL
-      /* No DRI2 support for swap_control at the moment, since SwapBuffers
-       * is done by the X server */
-      if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
-        psc->swapControl = (__DRIswapControlExtension *) extensions[i];
-        __glXEnableDirectExtension(psc, "GLX_SGI_swap_control");
-        __glXEnableDirectExtension(psc, "GLX_MESA_swap_control");
-      }
-#endif
-
-#ifdef __DRI_MEDIA_STREAM_COUNTER
-      if (strcmp(extensions[i]->name, __DRI_MEDIA_STREAM_COUNTER) == 0) {
-         psc->msc = (__DRImediaStreamCounterExtension *) extensions[i];
-         __glXEnableDirectExtension(psc, "GLX_SGI_video_sync");
-      }
-#endif
-
-#ifdef __DRI_SWAP_BUFFER_COUNTER
-      /* No driver supports this at this time and the extension is
-       * not defined in dri_interface.h.  Will enable
-       * GLX_OML_sync_control if implemented. */
-#endif
-
-      /* Ignore unknown extensions */
-   }
-}
-
-/* Bind DRI2 specific extensions */
 _X_HIDDEN void
-dri2BindExtensions(__GLXscreenConfigs *psc)
+driDestroyConfigs(const __DRIconfig **configs)
 {
-   const __DRIextension **extensions;
    int i;
 
-   extensions = psc->core->getExtensions(psc->__driScreen);
-
-   for (i = 0; extensions[i]; i++) {
-#ifdef __DRI_TEX_BUFFER
-      if ((strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0)) {
-        psc->texBuffer = (__DRItexBufferExtension *) extensions[i];
-        __glXEnableDirectExtension(psc, "GLX_EXT_texture_from_pixmap");
-      }
-#endif
-
-      __glXEnableDirectExtension(psc, "GLX_SGI_video_sync");
-      __glXEnableDirectExtension(psc, "GLX_SGI_swap_control");
-      __glXEnableDirectExtension(psc, "GLX_MESA_swap_control");
-
-      /* FIXME: if DRI2 version supports it... */
-      __glXEnableDirectExtension(psc, "INTEL_swap_event");
-
-#ifdef __DRI2_FLUSH
-      if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0)) {
-        psc->f = (__DRI2flushExtension *) extensions[i];
-        /* internal driver extension, no GL extension exposed */
-      }
-#endif
-
-#ifdef __DRI2_CONFIG_QUERY
-      if ((strcmp(extensions[i]->name, __DRI2_CONFIG_QUERY) == 0))
-        psc->config = (__DRI2configQueryExtension *) extensions[i];
-#endif
-   }
-}
-
-/* Bind extensions common to DRI1 and DRI2 */
-_X_HIDDEN void
-driBindCommonExtensions(__GLXscreenConfigs *psc)
-{
-   const __DRIextension **extensions;
-   int i;
-
-   extensions = psc->core->getExtensions(psc->__driScreen);
-
-   for (i = 0; extensions[i]; i++) {
-#ifdef __DRI_COPY_SUB_BUFFER
-      if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
-        psc->driCopySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
-        __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer");
-      }
-#endif
-
-#ifdef __DRI_ALLOCATE
-      if (strcmp(extensions[i]->name, __DRI_ALLOCATE) == 0) {
-        psc->allocate = (__DRIallocateExtension *) extensions[i];
-        __glXEnableDirectExtension(psc, "GLX_MESA_allocate_memory");
-      }
-#endif
-
-#ifdef __DRI_FRAME_TRACKING
-      if (strcmp(extensions[i]->name, __DRI_FRAME_TRACKING) == 0) {
-        psc->frameTracking = (__DRIframeTrackingExtension *) extensions[i];
-        __glXEnableDirectExtension(psc, "GLX_MESA_swap_frame_usage");
-      }
-#endif
-
-#ifdef __DRI_READ_DRAWABLE
-      if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
-        __glXEnableDirectExtension(psc, "GLX_SGI_make_current_read");
-      }
-#endif
-
-      /* Ignore unknown extensions */
-   }
+   for (i = 0; configs[i]; i++)
+      free((__DRIconfig *) configs[i]);
+   free(configs);
 }
 
 #endif /* GLX_DIRECT_RENDERING */
index bb178db7875ff327212e65c8b46e4edcc4a69cf2..f3da50ecf093e8b2d8ac2936b5b3d0761e920534 100644 (file)
@@ -36,6 +36,8 @@
 #ifndef _DRI_COMMON_H
 #define _DRI_COMMON_H
 
+#include <GL/internal/dri_interface.h>
+
 typedef struct __GLXDRIconfigPrivateRec __GLXDRIconfigPrivate;
 
 struct __GLXDRIconfigPrivateRec
@@ -48,6 +50,8 @@ extern __GLcontextModes *driConvertConfigs(const __DRIcoreExtension * core,
                                            __GLcontextModes * modes,
                                            const __DRIconfig ** configs);
 
+extern void driDestroyConfigs(const __DRIconfig **configs);
+
 extern const __DRIsystemTimeExtension systemTimeExtension;
 
 extern void InfoMessageF(const char *f, ...);
@@ -56,8 +60,4 @@ extern void ErrorMessageF(const char *f, ...);
 
 extern void *driOpenDriver(const char *driverName);
 
-extern void driBindExtensions(__GLXscreenConfigs * psc);
-extern void dri2BindExtensions(__GLXscreenConfigs * psc);
-extern void driBindCommonExtensions(__GLXscreenConfigs * psc);
-
 #endif /* _DRI_COMMON_H */
index 12a2cf3af24585a177ed47db66121bcd017b0de9..fd14285a481ec20f79b6866197318fef447c5135 100644 (file)
@@ -47,10 +47,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "xf86drm.h"
 #include "dri_common.h"
 
-typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
-typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
-
-struct __GLXDRIdisplayPrivateRec
+struct dri_display
 {
    __GLXDRIdisplay base;
 
@@ -62,14 +59,40 @@ struct __GLXDRIdisplayPrivateRec
    int driPatch;
 };
 
-struct __GLXDRIcontextPrivateRec
+struct dri_screen
+{
+   __GLXscreenConfigs base;
+
+   __DRIscreen *driScreen;
+   __GLXDRIscreen vtable;
+   const __DRIlegacyExtension *legacy;
+   const __DRIcoreExtension *core;
+   const __DRIswapControlExtension *swapControl;
+   const __DRImediaStreamCounterExtension *msc;
+   const __DRIconfig **driver_configs;
+   const __DRIcopySubBufferExtension *driCopySubBuffer;
+
+   void *driver;
+   int fd;
+};
+
+struct dri_context
 {
-   __GLXDRIcontext base;
+   __GLXcontext base;
+   __GLXDRIcontext dri_vtable;
    __DRIcontext *driContext;
    XID hwContextID;
-   __GLXscreenConfigs *psc;
 };
 
+struct dri_drawable
+{
+   __GLXDRIdrawable base;
+
+   __DRIdrawable *driDrawable;
+};
+
+static const struct glx_context_vtable dri_context_vtable;
+
 /*
  * Given a display pointer and screen number, determine the name of
  * the DRI driver for the screen. (I.e. "r128", "tdfx", etc).
@@ -293,8 +316,8 @@ static const __DRIextension *loader_extensions[] = {
  *          the client-side driver on success, or \c NULL on failure.
  */
 static void *
-CallCreateNewScreen(Display * dpy, int scrn, __GLXscreenConfigs * psc,
-                    __GLXDRIdisplayPrivate * driDpy)
+CallCreateNewScreen(Display *dpy, int scrn, struct dri_screen *psc,
+                    struct dri_display * driDpy)
 {
    void *psp = NULL;
    drm_handle_t hSAREA;
@@ -424,8 +447,10 @@ CallCreateNewScreen(Display * dpy, int scrn, __GLXscreenConfigs * psc,
       goto handle_error;
    }
 
-   psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
-   psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
+   psc->base.configs =
+      driConvertConfigs(psc->core, psc->base.configs, driver_configs);
+   psc->base.visuals =
+      driConvertConfigs(psc->core, psc->base.visuals, driver_configs);
 
    psc->driver_configs = driver_configs;
 
@@ -433,7 +458,7 @@ CallCreateNewScreen(Display * dpy, int scrn, __GLXscreenConfigs * psc,
     * in the X server, so DRI1 can't render to them properly. Mark them as
     * non-conformant to prevent apps from picking them up accidentally.
     */
-   for (visual = psc->visuals; visual; visual = visual->next) {
+   for (visual = psc->base.visuals; visual; visual = visual->next) {
       XVisualInfo template;
       XVisualInfo *visuals;
       int num_visuals;
@@ -474,52 +499,72 @@ CallCreateNewScreen(Display * dpy, int scrn, __GLXscreenConfigs * psc,
 }
 
 static void
-driDestroyContext(__GLXDRIcontext * context,
-                  __GLXscreenConfigs * psc, Display * dpy)
+dri_destroy_context(__GLXcontext * context)
 {
-   __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
+   struct dri_context *pcp = (struct dri_context *) context;
+   struct dri_screen *psc = (struct dri_screen *) context->psc;
+
+   if (context->xid)
+      glx_send_destroy_context(psc->base.dpy, context->xid);
+
+   if (context->extensions)
+      XFree((char *) context->extensions);
+
+   GarbageCollectDRIDrawables(context->psc);
 
    (*psc->core->destroyContext) (pcp->driContext);
 
-   XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID);
+   XF86DRIDestroyContext(psc->base.dpy, psc->base.scr, pcp->hwContextID);
    Xfree(pcp);
 }
 
 static Bool
-driBindContext(__GLXDRIcontext * context,
-               __GLXDRIdrawable * draw, __GLXDRIdrawable * read)
+driBindContext(__GLXcontext *context,
+              __GLXDRIdrawable *draw, __GLXDRIdrawable *read)
 {
-   __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
-   const __DRIcoreExtension *core = pcp->psc->core;
+   struct dri_context *pcp = (struct dri_context *) context;
+   struct dri_screen *psc = (struct dri_screen *) pcp->base.psc;
+   struct dri_drawable *pdr = (struct dri_drawable *) draw;
+   struct dri_drawable *prd = (struct dri_drawable *) read;
 
-   return (*core->bindContext) (pcp->driContext,
-                                draw->driDrawable, read->driDrawable);
+   return (*psc->core->bindContext) (pcp->driContext,
+                                    pdr->driDrawable, prd->driDrawable);
 }
 
 static void
-driUnbindContext(__GLXDRIcontext * context)
+driUnbindContext(__GLXcontext * context)
 {
-   __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
-   const __DRIcoreExtension *core = pcp->psc->core;
+   struct dri_context *pcp = (struct dri_context *) context;
+   struct dri_screen *psc = (struct dri_screen *) pcp->base.psc;
 
-   (*core->unbindContext) (pcp->driContext);
+   (*psc->core->unbindContext) (pcp->driContext);
 }
 
-static __GLXDRIcontext *
-driCreateContext(__GLXscreenConfigs * psc,
-                 const __GLcontextModes * mode,
-                 GLXContext gc, GLXContext shareList, int renderType)
+static const struct glx_context_vtable dri_context_vtable = {
+   dri_destroy_context,
+   NULL,
+   NULL,
+   DRI_glXUseXFont,
+   NULL,
+   NULL,
+};
+
+static __GLXcontext *
+dri_create_context(__GLXscreenConfigs *base,
+                  const __GLcontextModes *mode,
+                  GLXContext shareList, int renderType)
 {
-   __GLXDRIcontextPrivate *pcp, *pcp_shared;
+   struct dri_context *pcp, *pcp_shared;
+   struct dri_screen *psc = (struct dri_screen *) base;
    drm_context_t hwContext;
    __DRIcontext *shared = NULL;
    __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
 
-   if (!psc || !psc->driScreen)
+   if (!psc->base.driScreen)
       return NULL;
 
    if (shareList) {
-      pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext;
+      pcp_shared = (struct dri_context *) shareList->driContext;
       shared = pcp_shared->driContext;
    }
 
@@ -527,8 +572,13 @@ driCreateContext(__GLXscreenConfigs * psc,
    if (pcp == NULL)
       return NULL;
 
-   pcp->psc = psc;
-   if (!XF86DRICreateContextWithConfig(psc->dpy, psc->scr,
+   memset(pcp, 0, sizeof *pcp);
+   if (!glx_context_init(&pcp->base, &psc->base, mode)) {
+      Xfree(pcp);
+      return NULL;
+   }
+
+   if (!XF86DRICreateContextWithConfig(psc->base.dpy, psc->base.scr,
                                        mode->visualID,
                                        &pcp->hwContextID, &hwContext)) {
       Xfree(pcp);
@@ -536,18 +586,19 @@ driCreateContext(__GLXscreenConfigs * psc,
    }
 
    pcp->driContext =
-      (*psc->legacy->createNewContext) (psc->__driScreen,
+      (*psc->legacy->createNewContext) (psc->driScreen,
                                         config->driConfig,
                                         renderType, shared, hwContext, pcp);
    if (pcp->driContext == NULL) {
-      XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID);
+      XF86DRIDestroyContext(psc->base.dpy, psc->base.scr, pcp->hwContextID);
       Xfree(pcp);
       return NULL;
    }
 
-   pcp->base.destroyContext = driDestroyContext;
-   pcp->base.bindContext = driBindContext;
-   pcp->base.unbindContext = driUnbindContext;
+   pcp->base.vtable = &dri_context_vtable;
+   pcp->base.driContext = &pcp->dri_vtable;
+   pcp->dri_vtable.bindContext = driBindContext;
+   pcp->dri_vtable.unbindContext = driUnbindContext;
 
    return &pcp->base;
 }
@@ -555,63 +606,70 @@ driCreateContext(__GLXscreenConfigs * psc,
 static void
 driDestroyDrawable(__GLXDRIdrawable * pdraw)
 {
-   __GLXscreenConfigs *psc = pdraw->psc;
+   struct dri_screen *psc = (struct dri_screen *) pdraw->psc;
+   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
 
-   (*psc->core->destroyDrawable) (pdraw->driDrawable);
-   XF86DRIDestroyDrawable(psc->dpy, psc->scr, pdraw->drawable);
+   (*psc->core->destroyDrawable) (pdp->driDrawable);
+   XF86DRIDestroyDrawable(psc->base.dpy, psc->base.scr, pdraw->drawable);
    Xfree(pdraw);
 }
 
 static __GLXDRIdrawable *
-driCreateDrawable(__GLXscreenConfigs * psc,
+driCreateDrawable(__GLXscreenConfigs *base,
                   XID xDrawable,
                   GLXDrawable drawable, const __GLcontextModes * modes)
 {
-   __GLXDRIdrawable *pdraw;
    drm_drawable_t hwDrawable;
    void *empty_attribute_list = NULL;
    __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
+   struct dri_screen *psc = (struct dri_screen *) base;
+   struct dri_drawable *pdp;
 
    /* Old dri can't handle GLX 1.3+ drawable constructors. */
    if (xDrawable != drawable)
       return NULL;
 
-   pdraw = Xmalloc(sizeof(*pdraw));
-   if (!pdraw)
+   pdp = Xmalloc(sizeof *pdp);
+   if (!pdp)
       return NULL;
 
-   pdraw->drawable = drawable;
-   pdraw->psc = psc;
+   memset(pdp, 0, sizeof *pdp);
+   pdp->base.drawable = drawable;
+   pdp->base.psc = &psc->base;
 
-   if (!XF86DRICreateDrawable(psc->dpy, psc->scr, drawable, &hwDrawable)) {
-      Xfree(pdraw);
+   if (!XF86DRICreateDrawable(psc->base.dpy, psc->base.scr,
+                             drawable, &hwDrawable)) {
+      Xfree(pdp);
       return NULL;
    }
 
    /* Create a new drawable */
-   pdraw->driDrawable =
-      (*psc->legacy->createNewDrawable) (psc->__driScreen,
+   pdp->driDrawable =
+      (*psc->legacy->createNewDrawable) (psc->driScreen,
                                          config->driConfig,
                                          hwDrawable,
                                          GLX_WINDOW_BIT,
-                                         empty_attribute_list, pdraw);
+                                         empty_attribute_list, pdp);
 
-   if (!pdraw->driDrawable) {
-      XF86DRIDestroyDrawable(psc->dpy, psc->scr, drawable);
-      Xfree(pdraw);
+   if (!pdp->driDrawable) {
+      XF86DRIDestroyDrawable(psc->base.dpy, psc->base.scr, drawable);
+      Xfree(pdp);
       return NULL;
    }
 
-   pdraw->destroyDrawable = driDestroyDrawable;
+   pdp->base.destroyDrawable = driDestroyDrawable;
 
-   return pdraw;
+   return &pdp->base;
 }
 
 static int64_t
 driSwapBuffers(__GLXDRIdrawable * pdraw, int64_t unused1, int64_t unused2,
               int64_t unused3)
 {
-   (*pdraw->psc->core->swapBuffers) (pdraw->driDrawable);
+   struct dri_screen *psc = (struct dri_screen *) pdraw->psc;
+   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
+
+   (*psc->core->swapBuffers) (pdp->driDrawable);
    return 0;
 }
 
@@ -619,56 +677,189 @@ static void
 driCopySubBuffer(__GLXDRIdrawable * pdraw,
                  int x, int y, int width, int height)
 {
-   (*pdraw->psc->driCopySubBuffer->copySubBuffer) (pdraw->driDrawable,
-                                                   x, y, width, height);
+   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
+   struct dri_screen *psc = (struct dri_screen *) pdp->base.psc;
+
+   (*psc->driCopySubBuffer->copySubBuffer) (pdp->driDrawable,
+                                           x, y, width, height);
 }
 
 static void
-driDestroyScreen(__GLXscreenConfigs * psc)
+driDestroyScreen(__GLXscreenConfigs *base)
 {
+   struct dri_screen *psc = (struct dri_screen *) base;
+
    /* Free the direct rendering per screen data */
-   if (psc->__driScreen)
-      (*psc->core->destroyScreen) (psc->__driScreen);
-   psc->__driScreen = NULL;
+   if (psc->driScreen)
+      (*psc->core->destroyScreen) (psc->driScreen);
+   driDestroyConfigs(psc->driver_configs);
+   psc->driScreen = NULL;
    if (psc->driver)
       dlclose(psc->driver);
 }
 
-static const struct glx_context_vtable dri_context_vtable = {
-   NULL,
-   NULL,
+#ifdef __DRI_SWAP_BUFFER_COUNTER
+
+static int
+driDrawableGetMSC(__GLXscreenConfigs *base, __GLXDRIdrawable *pdraw,
+                  int64_t *ust, int64_t *msc, int64_t *sbc)
+{
+   struct dri_screen *psc = (struct dri_screen *) base;
+   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
+
+   if (pdp && psc->sbc && psc->msc)
+      return ( (*psc->msc->getMSC)(psc->driScreen, msc) == 0 &&
+              (*psc->sbc->getSBC)(pdp->driDrawable, sbc) == 0 && 
+              __glXGetUST(ust) == 0 );
+}
+
+static int
+driWaitForMSC(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
+              int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc)
+{
+   struct dri_screen *psc = (struct dri_screen *) pdraw->psc;
+   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
+
+   if (pdp != NULL && psc->msc != NULL) {
+      ret = (*psc->msc->waitForMSC) (pdp->driDrawable, target_msc,
+                                    divisor, remainder, msc, sbc);
+
+      /* __glXGetUST returns zero on success and non-zero on failure.
+       * This function returns True on success and False on failure.
+       */
+      return ret == 0 && __glXGetUST(ust) == 0;
+   }
+}
+
+static int
+driWaitForSBC(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust,
+              int64_t *msc, int64_t *sbc)
+{
+   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
+
+   if (pdp != NULL && psc->sbc != NULL) {
+      ret =
+         (*psc->sbc->waitForSBC) (pdp->driDrawable, target_sbc, msc, sbc);
+
+      /* __glXGetUST returns zero on success and non-zero on failure.
+       * This function returns True on success and False on failure.
+       */
+      return ((ret == 0) && (__glXGetUST(ust) == 0));
+   }
+
+   return DRI2WaitSBC(pdp->base.psc->dpy,
+                     pdp->base.xDrawable, target_sbc, ust, msc, sbc);
+}
+
+#endif
+
+static int
+driSetSwapInterval(__GLXDRIdrawable *pdraw, int interval)
+{
+   GLXContext gc = __glXGetCurrentContext();
+   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
+   struct dri_screen *psc;
+
+   if (gc->driContext) {
+      psc = (struct dri_screen *) pdraw->psc;
+
+      if (psc->swapControl != NULL && pdraw != NULL) {
+        psc->swapControl->setSwapInterval(pdp->driDrawable, interval);
+        return 0;
+      }
+   }
+
+   return GLX_BAD_CONTEXT;
+}
+
+static int
+driGetSwapInterval(__GLXDRIdrawable *pdraw)
+{
+   GLXContext gc = __glXGetCurrentContext();
+   struct dri_drawable *pdp = (struct dri_drawable *) pdraw;
+   struct dri_screen *psc;
+
+   if (gc != NULL && gc->driContext) {
+      psc = (struct dri_screen *) pdraw->psc;
+
+      if (psc->swapControl != NULL && pdraw != NULL) {
+        return psc->swapControl->getSwapInterval(pdp->driDrawable);
+      }
+   }
+
+   return 0;
+}
+
+/* Bind DRI1 specific extensions */
+static void
+driBindExtensions(struct dri_screen *psc, const __DRIextension **extensions)
+{
+   int i;
+
+   for (i = 0; extensions[i]; i++) {
+      /* No DRI2 support for swap_control at the moment, since SwapBuffers
+       * is done by the X server */
+      if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
+        psc->swapControl = (__DRIswapControlExtension *) extensions[i];
+        __glXEnableDirectExtension(&psc->base, "GLX_SGI_swap_control");
+        __glXEnableDirectExtension(&psc->base, "GLX_MESA_swap_control");
+      }
+
+      if (strcmp(extensions[i]->name, __DRI_MEDIA_STREAM_COUNTER) == 0) {
+         psc->msc = (__DRImediaStreamCounterExtension *) extensions[i];
+         __glXEnableDirectExtension(&psc->base, "GLX_SGI_video_sync");
+      }
+
+      if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
+        psc->driCopySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
+        __glXEnableDirectExtension(&psc->base, "GLX_MESA_copy_sub_buffer");
+      }
+
+      if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
+        __glXEnableDirectExtension(&psc->base, "GLX_SGI_make_current_read");
+      }
+      /* Ignore unknown extensions */
+   }
+}
+
+static const struct glx_screen_vtable dri_screen_vtable = {
+   dri_create_context
 };
 
-static __GLXDRIscreen *
-driCreateScreen(__GLXscreenConfigs * psc, int screen,
-                __GLXdisplayPrivate * priv)
+static __GLXscreenConfigs *
+driCreateScreen(int screen, __GLXdisplayPrivate *priv)
 {
-   __GLXDRIdisplayPrivate *pdp;
+   struct dri_display *pdp;
    __GLXDRIscreen *psp;
    const __DRIextension **extensions;
+   struct dri_screen *psc;
    char *driverName;
    int i;
 
-   psp = Xcalloc(1, sizeof *psp);
-   if (psp == NULL)
+   psc = Xcalloc(1, sizeof *psc);
+   if (psc == NULL)
       return NULL;
 
+   memset(psc, 0, sizeof *psc);
+   if (!glx_screen_init(&psc->base, screen, priv))
+       return NULL;
+
    if (!driGetDriverName(priv->dpy, screen, &driverName)) {
-      Xfree(psp);
+      Xfree(psc);
       return NULL;
    }
 
    psc->driver = driOpenDriver(driverName);
    Xfree(driverName);
    if (psc->driver == NULL) {
-      Xfree(psp);
+      Xfree(psc);
       return NULL;
    }
 
    extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
    if (extensions == NULL) {
       ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
-      Xfree(psp);
+      Xfree(psc);
       return NULL;
    }
 
@@ -680,34 +871,42 @@ driCreateScreen(__GLXscreenConfigs * psc, int screen,
    }
 
    if (psc->core == NULL || psc->legacy == NULL) {
-      Xfree(psp);
+      Xfree(psc);
       return NULL;
    }
 
-   pdp = (__GLXDRIdisplayPrivate *) priv->driDisplay;
-   psc->__driScreen = CallCreateNewScreen(psc->dpy, screen, psc, pdp);
-   if (psc->__driScreen == NULL) {
+   pdp = (struct dri_display *) priv->driDisplay;
+   psc->driScreen =
+      CallCreateNewScreen(psc->base.dpy, screen, psc, pdp);
+   if (psc->driScreen == NULL) {
       dlclose(psc->driver);
-      Xfree(psp);
+      Xfree(psc);
       return NULL;
    }
 
-   driBindExtensions(psc);
-   driBindCommonExtensions(psc);
+   extensions = psc->core->getExtensions(psc->driScreen);
+   driBindExtensions(psc, extensions);
 
+   psc->base.vtable = &dri_screen_vtable;
+   psp = &psc->vtable;
+   psc->base.driScreen = psp;
    if (psc->driCopySubBuffer)
       psp->copySubBuffer = driCopySubBuffer;
 
    psp->destroyScreen = driDestroyScreen;
-   psp->createContext = driCreateContext;
    psp->createDrawable = driCreateDrawable;
    psp->swapBuffers = driSwapBuffers;
-   psp->waitX = NULL;
-   psp->waitGL = NULL;
 
-   psc->direct_context_vtable = &dri_context_vtable;
+#ifdef __DRI_SWAP_BUFFER_COUNTER
+   psp->getDrawableMSC = driDrawableGetMSC;
+   psp->waitForMSC = driWaitForMSC;
+   psp->waitForSBC = driWaitForSBC;
+#endif
 
-   return psp;
+   psp->setSwapInterval = driSetSwapInterval;
+   psp->getSwapInterval = driGetSwapInterval;
+
+   return &psc->base;
 }
 
 /* Called from __glXFreeDisplayPrivate.
@@ -726,7 +925,7 @@ driDestroyDisplay(__GLXDRIdisplay * dpy)
 _X_HIDDEN __GLXDRIdisplay *
 driCreateDisplay(Display * dpy)
 {
-   __GLXDRIdisplayPrivate *pdpyp;
+   struct dri_display *pdpyp;
    int eventBase, errorBase;
    int major, minor, patch;
 
index cdb1d9f4dc3ea0a4243eb98fcace7644cd3a8e28..5f7185de4c8584932ffe212beac0fd0ffcb9b185 100644 (file)
 #include <dlfcn.h>
 #include "dri_common.h"
 
-typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
-typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
-typedef struct __GLXDRIdrawablePrivateRec __GLXDRIdrawablePrivate;
-
-struct __GLXDRIdisplayPrivateRec
+struct drisw_display
 {
    __GLXDRIdisplay base;
 };
 
-struct __GLXDRIcontextPrivateRec
+struct drisw_context
 {
-   __GLXDRIcontext base;
+   __GLXcontext base;
+   __GLXDRIcontext dri_vtable;
    __DRIcontext *driContext;
-   __GLXscreenConfigs *psc;
+
 };
 
-struct __GLXDRIdrawablePrivateRec
+struct drisw_screen
+{
+   __GLXscreenConfigs base;
+
+   __DRIscreen *driScreen;
+   __GLXDRIscreen vtable;
+   const __DRIcoreExtension *core;
+   const __DRIswrastExtension *swrast;
+   const __DRIconfig **driver_configs;
+
+   void *driver;
+};
+
+struct drisw_drawable
 {
    __GLXDRIdrawable base;
 
    GC gc;
    GC swapgc;
 
+   __DRIdrawable *driDrawable;
    XVisualInfo *visinfo;
    XImage *ximage;
 };
 
 static Bool
-XCreateDrawable(__GLXDRIdrawablePrivate * pdp,
+XCreateDrawable(struct drisw_drawable * pdp,
                 Display * dpy, XID drawable, int visualid)
 {
    XGCValues gcvalues;
@@ -94,7 +105,7 @@ XCreateDrawable(__GLXDRIdrawablePrivate * pdp,
 }
 
 static void
-XDestroyDrawable(__GLXDRIdrawablePrivate * pdp, Display * dpy, XID drawable)
+XDestroyDrawable(struct drisw_drawable * pdp, Display * dpy, XID drawable)
 {
    XDestroyImage(pdp->ximage);
    XFree(pdp->visinfo);
@@ -112,7 +123,7 @@ swrastGetDrawableInfo(__DRIdrawable * draw,
                       int *x, int *y, int *w, int *h,
                       void *loaderPrivate)
 {
-   __GLXDRIdrawablePrivate *pdp = loaderPrivate;
+   struct drisw_drawable *pdp = loaderPrivate;
    __GLXDRIdrawable *pdraw = &(pdp->base);
    Display *dpy = pdraw->psc->dpy;
    Drawable drawable;
@@ -156,7 +167,7 @@ swrastPutImage(__DRIdrawable * draw, int op,
                int x, int y, int w, int h,
                char *data, void *loaderPrivate)
 {
-   __GLXDRIdrawablePrivate *pdp = loaderPrivate;
+   struct drisw_drawable *pdp = loaderPrivate;
    __GLXDRIdrawable *pdraw = &(pdp->base);
    Display *dpy = pdraw->psc->dpy;
    Drawable drawable;
@@ -192,7 +203,7 @@ swrastGetImage(__DRIdrawable * read,
                int x, int y, int w, int h,
                char *data, void *loaderPrivate)
 {
-   __GLXDRIdrawablePrivate *prp = loaderPrivate;
+   struct drisw_drawable *prp = loaderPrivate;
    __GLXDRIdrawable *pread = &(prp->base);
    Display *dpy = pread->psc->dpy;
    Drawable readable;
@@ -229,54 +240,70 @@ static const __DRIextension *loader_extensions[] = {
  */
 
 static void
-driDestroyContext(__GLXDRIcontext * context,
-                  __GLXscreenConfigs * psc, Display * dpy)
+drisw_destroy_context(__GLXcontext *context)
 {
-   __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
-   const __DRIcoreExtension *core = pcp->psc->core;
+   struct drisw_context *pcp = (struct drisw_context *) context;
+   struct drisw_screen *psc = (struct drisw_screen *) context->psc;
+
+   if (context->xid)
+      glx_send_destroy_context(psc->base.dpy, context->xid);
 
-   (*core->destroyContext) (pcp->driContext);
+   if (context->extensions)
+      XFree((char *) context->extensions);
+
+   GarbageCollectDRIDrawables(context->psc);
+
+   (*psc->core->destroyContext) (pcp->driContext);
 
    Xfree(pcp);
 }
 
 static Bool
-driBindContext(__GLXDRIcontext * context,
-               __GLXDRIdrawable * draw, __GLXDRIdrawable * read)
+driBindContext(__GLXcontext * context,
+              __GLXDRIdrawable * draw, __GLXDRIdrawable * read)
 {
-   __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
-   const __DRIcoreExtension *core = pcp->psc->core;
+   struct drisw_context *pcp = (struct drisw_context *) context;
+   struct drisw_screen *psc = (struct drisw_screen *) pcp->base.psc;
+   struct drisw_drawable *pdr = (struct drisw_drawable *) draw;
+   struct drisw_drawable *prd = (struct drisw_drawable *) read;
 
-   return (*core->bindContext) (pcp->driContext,
-                                draw->driDrawable, read->driDrawable);
+   return (*psc->core->bindContext) (pcp->driContext,
+                                    pdr->driDrawable, prd->driDrawable);
 }
 
 static void
-driUnbindContext(__GLXDRIcontext * context)
+driUnbindContext(__GLXcontext * context)
 {
-   __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
-   const __DRIcoreExtension *core = pcp->psc->core;
+   struct drisw_context *pcp = (struct drisw_context *) context;
+   struct drisw_screen *psc = (struct drisw_screen *) pcp->base.psc;
 
-   (*core->unbindContext) (pcp->driContext);
+   (*psc->core->unbindContext) (pcp->driContext);
 }
 
-static __GLXDRIcontext *
-driCreateContext(__GLXscreenConfigs * psc,
-                 const __GLcontextModes * mode,
-                 GLXContext gc, GLXContext shareList, int renderType)
+static const struct glx_context_vtable drisw_context_vtable = {
+   drisw_destroy_context,
+   NULL,
+   NULL,
+   DRI_glXUseXFont,
+   NULL,
+   NULL,
+};
+
+static __GLXcontext *
+drisw_create_context(__GLXscreenConfigs *base,
+                    const __GLcontextModes *mode,
+                    GLXContext shareList, int renderType)
 {
-   __GLXDRIcontextPrivate *pcp, *pcp_shared;
+   struct drisw_context *pcp, *pcp_shared;
    __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
-   const __DRIcoreExtension *core;
+   struct drisw_screen *psc = (struct drisw_screen *) base;
    __DRIcontext *shared = NULL;
 
-   if (!psc || !psc->driScreen)
+   if (!psc->base.driScreen)
       return NULL;
 
-   core = psc->core;
-
    if (shareList) {
-      pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext;
+      pcp_shared = (struct drisw_context *) shareList->driContext;
       shared = pcp_shared->driContext;
    }
 
@@ -284,18 +311,24 @@ driCreateContext(__GLXscreenConfigs * psc,
    if (pcp == NULL)
       return NULL;
 
-   pcp->psc = psc;
+   memset(pcp, 0, sizeof *pcp);
+   if (!glx_context_init(&pcp->base, &psc->base, mode)) {
+      Xfree(pcp);
+      return NULL;
+   }
+
    pcp->driContext =
-      (*core->createNewContext) (psc->__driScreen,
-                                 config->driConfig, shared, pcp);
+      (*psc->core->createNewContext) (psc->driScreen,
+                                     config->driConfig, shared, pcp);
    if (pcp->driContext == NULL) {
       Xfree(pcp);
       return NULL;
    }
 
-   pcp->base.destroyContext = driDestroyContext;
-   pcp->base.bindContext = driBindContext;
-   pcp->base.unbindContext = driUnbindContext;
+   pcp->base.vtable = &drisw_context_vtable;
+   pcp->base.driContext = &pcp->dri_vtable;
+   pcp->dri_vtable.bindContext = driBindContext;
+   pcp->dri_vtable.unbindContext = driUnbindContext;
 
    return &pcp->base;
 }
@@ -303,23 +336,23 @@ driCreateContext(__GLXscreenConfigs * psc,
 static void
 driDestroyDrawable(__GLXDRIdrawable * pdraw)
 {
-   __GLXDRIdrawablePrivate *pdp = (__GLXDRIdrawablePrivate *) pdraw;
-   const __DRIcoreExtension *core = pdraw->psc->core;
+   struct drisw_drawable *pdp = (struct drisw_drawable *) pdraw;
+   struct drisw_screen *psc = (struct drisw_screen *) pdp->base.psc;
 
-   (*core->destroyDrawable) (pdraw->driDrawable);
+   (*psc->core->destroyDrawable) (pdp->driDrawable);
 
    XDestroyDrawable(pdp, pdraw->psc->dpy, pdraw->drawable);
    Xfree(pdp);
 }
 
 static __GLXDRIdrawable *
-driCreateDrawable(__GLXscreenConfigs * psc,
-                  XID xDrawable,
-                  GLXDrawable drawable, const __GLcontextModes * modes)
+driCreateDrawable(__GLXscreenConfigs *base, XID xDrawable,
+                 GLXDrawable drawable, const __GLcontextModes * modes)
 {
-   __GLXDRIdrawable *pdraw;
-   __GLXDRIdrawablePrivate *pdp;
+   struct drisw_drawable *pdp;
    __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
+   struct drisw_screen *psc = (struct drisw_screen *) base;
+
    const __DRIswrastExtension *swrast = psc->swrast;
 
    /* Old dri can't handle GLX 1.3+ drawable constructors. */
@@ -330,47 +363,53 @@ driCreateDrawable(__GLXscreenConfigs * psc,
    if (!pdp)
       return NULL;
 
-   pdraw = &(pdp->base);
-   pdraw->xDrawable = xDrawable;
-   pdraw->drawable = drawable;
-   pdraw->psc = psc;
+   memset(pdp, 0, sizeof *pdp);
+   pdp->base.xDrawable = xDrawable;
+   pdp->base.drawable = drawable;
+   pdp->base.psc = &psc->base;
 
-   XCreateDrawable(pdp, psc->dpy, xDrawable, modes->visualID);
+   XCreateDrawable(pdp, psc->base.dpy, xDrawable, modes->visualID);
 
    /* Create a new drawable */
-   pdraw->driDrawable =
-      (*swrast->createNewDrawable) (psc->__driScreen, config->driConfig, pdp);
+   pdp->driDrawable =
+      (*swrast->createNewDrawable) (psc->driScreen, config->driConfig, pdp);
 
-   if (!pdraw->driDrawable) {
-      XDestroyDrawable(pdp, psc->dpy, xDrawable);
+   if (!pdp->driDrawable) {
+      XDestroyDrawable(pdp, psc->base.dpy, xDrawable);
       Xfree(pdp);
       return NULL;
    }
 
-   pdraw->destroyDrawable = driDestroyDrawable;
+   pdp->base.destroyDrawable = driDestroyDrawable;
 
-   return pdraw;
+   return &pdp->base;
 }
 
 static int64_t
 driSwapBuffers(__GLXDRIdrawable * pdraw,
                int64_t target_msc, int64_t divisor, int64_t remainder)
 {
+   struct drisw_drawable *pdp = (struct drisw_drawable *) pdraw;
+   struct drisw_screen *psc = (struct drisw_screen *) pdp->base.psc;
+
    (void) target_msc;
    (void) divisor;
    (void) remainder;
 
-   (*pdraw->psc->core->swapBuffers) (pdraw->driDrawable);
+   (*psc->core->swapBuffers) (pdp->driDrawable);
 
    return 0;
 }
 
 static void
-driDestroyScreen(__GLXscreenConfigs * psc)
+driDestroyScreen(__GLXscreenConfigs *base)
 {
+   struct drisw_screen *psc = (struct drisw_screen *) base;
+
    /* Free the direct rendering per screen data */
-   (*psc->core->destroyScreen) (psc->__driScreen);
-   psc->__driScreen = NULL;
+   (*psc->core->destroyScreen) (psc->driScreen);
+   driDestroyConfigs(psc->driver_configs);
+   psc->driScreen = NULL;
    if (psc->driver)
       dlclose(psc->driver);
 }
@@ -389,19 +428,27 @@ driOpenSwrast(void)
    return driver;
 }
 
-static __GLXDRIscreen *
-driCreateScreen(__GLXscreenConfigs * psc, int screen,
-                __GLXdisplayPrivate * priv)
+static const struct glx_screen_vtable drisw_screen_vtable = {
+   drisw_create_context
+};
+
+static __GLXscreenConfigs *
+driCreateScreen(int screen, __GLXdisplayPrivate *priv)
 {
    __GLXDRIscreen *psp;
    const __DRIconfig **driver_configs;
    const __DRIextension **extensions;
+   struct drisw_screen *psc;
    int i;
 
-   psp = Xcalloc(1, sizeof *psp);
-   if (psp == NULL)
+   psc = Xcalloc(1, sizeof *psc);
+   if (psc == NULL)
       return NULL;
 
+   memset(psc, 0, sizeof *psc);
+   if (!glx_screen_init(&psc->base, screen, priv))
+       return NULL;
+
    psc->driver = driOpenSwrast();
    if (psc->driver == NULL)
       goto handle_error;
@@ -414,9 +461,9 @@ driCreateScreen(__GLXscreenConfigs * psc, int screen,
 
    for (i = 0; extensions[i]; i++) {
       if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
-         psc->core = (__DRIcoreExtension *) extensions[i];
+        psc->core = (__DRIcoreExtension *) extensions[i];
       if (strcmp(extensions[i]->name, __DRI_SWRAST) == 0)
-         psc->swrast = (__DRIswrastExtension *) extensions[i];
+        psc->swrast = (__DRIswrastExtension *) extensions[i];
    }
 
    if (psc->core == NULL || psc->swrast == NULL) {
@@ -424,33 +471,34 @@ driCreateScreen(__GLXscreenConfigs * psc, int screen,
       goto handle_error;
    }
 
-   psc->__driScreen =
-      psc->swrast->createNewScreen(screen,
-                                   loader_extensions, &driver_configs, psc);
-   if (psc->__driScreen == NULL) {
+   psc->driScreen =
+      psc->swrast->createNewScreen(screen, loader_extensions,
+                                  &driver_configs, psc);
+   if (psc->driScreen == NULL) {
       ErrorMessageF("failed to create dri screen\n");
       goto handle_error;
    }
 
-   driBindExtensions(psc);
-   driBindCommonExtensions(psc);
+   extensions = psc->core->getExtensions(psc->driScreen);
 
-   psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
-   psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
+   psc->base.configs =
+      driConvertConfigs(psc->core, psc->base.configs, driver_configs);
+   psc->base.visuals =
+      driConvertConfigs(psc->core, psc->base.visuals, driver_configs);
 
    psc->driver_configs = driver_configs;
 
+   psc->base.vtable = &drisw_screen_vtable;
+   psp = &psc->vtable;
+   psc->base.driScreen = psp;
    psp->destroyScreen = driDestroyScreen;
-   psp->createContext = driCreateContext;
    psp->createDrawable = driCreateDrawable;
    psp->swapBuffers = driSwapBuffers;
-   psp->waitX = NULL;
-   psp->waitGL = NULL;
 
-   return psp;
+   return &psc->base;
 
  handle_error:
-   Xfree(psp);
+   Xfree(psc);
 
    if (psc->driver)
       dlclose(psc->driver);
@@ -476,7 +524,7 @@ driDestroyDisplay(__GLXDRIdisplay * dpy)
 _X_HIDDEN __GLXDRIdisplay *
 driswCreateDisplay(Display * dpy)
 {
-   __GLXDRIdisplayPrivate *pdpyp;
+   struct drisw_display *pdpyp;
 
    pdpyp = Xmalloc(sizeof *pdpyp);
    if (pdpyp == NULL)
index b8d0f21bf0620a9387d1dfe13944251744319c1f..02809aacfa5ccef7161a50c73525573f08d7d512 100644 (file)
@@ -86,13 +86,17 @@ ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable,
                         const CARD32 * attribs, size_t num_attribs)
 {
    __GLXdisplayPrivate *priv = __glXInitialize(dpy);
+   __GLXDRIdrawable *pdraw;
    CARD32 *output;
    CARD8 opcode;
+   int i;
 
    if ((dpy == NULL) || (drawable == 0)) {
       return;
    }
 
+   pdraw = GetGLXDRIDrawable(dpy, drawable);
+
    opcode = __glXSetupForCommand(dpy);
    if (!opcode)
       return;
@@ -129,6 +133,15 @@ ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable,
    UnlockDisplay(dpy);
    SyncHandle();
 
+   for (i = 0; i < num_attribs; i++) {
+      switch(attribs[i * 2]) {
+      case GLX_EVENT_MASK:
+        /* Keep a local copy for masking out DRI2 proto events as needed */
+        pdraw->eventMask = attribs[i * 2 + 1];
+        break;
+      }
+   }
+
    return;
 }
 
@@ -178,7 +191,7 @@ CreateDRIDrawable(Display *dpy, const __GLcontextModes *fbconfig,
    __GLXDRIdrawable *pdraw;
    __GLXscreenConfigs *psc;
 
-   psc = &priv->screenConfigs[fbconfig->screen];
+   psc = priv->screenConfigs[fbconfig->screen];
    if (psc->driScreen == NULL)
       return;
 
@@ -189,7 +202,7 @@ CreateDRIDrawable(Display *dpy, const __GLcontextModes *fbconfig,
       return;
    }
 
-   if (__glxHashInsert(psc->drawHash, glxdrawable, pdraw)) {
+   if (__glxHashInsert(priv->drawHash, glxdrawable, pdraw)) {
       (*pdraw->destroyDrawable) (pdraw);
       return; /* FIXME: Check what we're supposed to do here... */
    }
@@ -201,16 +214,14 @@ CreateDRIDrawable(Display *dpy, const __GLcontextModes *fbconfig,
 static void
 DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable)
 {
-   int screen;
    __GLXdisplayPrivate *const priv = __glXInitialize(dpy);
-   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
-   __GLXscreenConfigs *psc = &priv->screenConfigs[screen];
+   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
 
    if (pdraw != NULL) {
       if (destroy_xdrawable)
-         XFreePixmap(psc->dpy, pdraw->xDrawable);
+         XFreePixmap(pdraw->psc->dpy, pdraw->xDrawable);
       (*pdraw->destroyDrawable) (pdraw);
-      __glxHashDelete(psc->drawHash, drawable);
+      __glxHashDelete(priv->drawHash, drawable);
    }
 }
 
@@ -328,7 +339,7 @@ GetDrawableAttribute(Display * dpy, GLXDrawable drawable,
 
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
          {
-            __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
+            __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
 
             if (pdraw != NULL && !pdraw->textureTarget)
                pdraw->textureTarget =
index 78c5f33d4d57089be807857d1b2c7b9527d9653c..48b5501fe9ee292fd53302055000956a618ced5d 100644 (file)
@@ -37,8 +37,6 @@
 
 #ifndef _GLX_client_h_
 #define _GLX_client_h_
-#define NEED_REPLIES
-#define NEED_EVENTS
 #include <X11/Xproto.h>
 #include <X11/Xlibint.h>
 #include <X11/extensions/extutil.h>
@@ -97,14 +95,13 @@ typedef struct _glapi_table __GLapi;
 #define containerOf(ptr, type, member)              \
     (type *)( (char *)ptr - offsetof(type,member) )
 
-extern void DRI_glXUseXFont(Font font, int first, int count, int listbase);
+extern void DRI_glXUseXFont(GLXContext CC,
+                           Font font, int first, int count, int listbase);
 
 #endif
 
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
 
-#include <GL/internal/dri_interface.h>
-
 /**
  * Display dependent methods.  This structure is initialized during the
  * \c driCreateDisplay call.
@@ -123,18 +120,16 @@ struct __GLXDRIdisplayRec
      */
    void (*destroyDisplay) (__GLXDRIdisplay * display);
 
-   __GLXDRIscreen *(*createScreen) (__GLXscreenConfigs * psc, int screen,
-                                    __GLXdisplayPrivate * priv);
+   __GLXscreenConfigs *(*createScreen)(int screen, __GLXdisplayPrivate * priv);
 };
 
 struct __GLXDRIscreenRec {
 
    void (*destroyScreen)(__GLXscreenConfigs *psc);
 
-   __GLXDRIcontext *(*createContext)(__GLXscreenConfigs *psc,
-                                    const __GLcontextModes *mode,
-                                    GLXContext gc,
-                                    GLXContext shareList, int renderType);
+   __GLXcontext *(*createContext)(__GLXscreenConfigs *psc,
+                                 const __GLcontextModes *mode,
+                                 GLXContext shareList, int renderType);
 
    __GLXDRIdrawable *(*createDrawable)(__GLXscreenConfigs *psc,
                                       XID drawable,
@@ -145,8 +140,6 @@ struct __GLXDRIscreenRec {
                          int64_t divisor, int64_t remainder);
    void (*copySubBuffer)(__GLXDRIdrawable *pdraw,
                         int x, int y, int width, int height);
-   void (*waitX)(__GLXDRIdrawable *pdraw);
-   void (*waitGL)(__GLXDRIdrawable *pdraw);
    int (*getDrawableMSC)(__GLXscreenConfigs *psc, __GLXDRIdrawable *pdraw,
                         int64_t *ust, int64_t *msc, int64_t *sbc);
    int (*waitForMSC)(__GLXDRIdrawable *pdraw, int64_t target_msc,
@@ -154,18 +147,15 @@ struct __GLXDRIscreenRec {
                     int64_t *msc, int64_t *sbc);
    int (*waitForSBC)(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust,
                     int64_t *msc, int64_t *sbc);
-   void (*setSwapInterval)(__GLXDRIdrawable *pdraw, int interval);
+   int (*setSwapInterval)(__GLXDRIdrawable *pdraw, int interval);
    int (*getSwapInterval)(__GLXDRIdrawable *pdraw);
 };
 
 struct __GLXDRIcontextRec
 {
-   void (*destroyContext) (__GLXDRIcontext * context,
-                           __GLXscreenConfigs * psc, Display * dpy);
-     Bool(*bindContext) (__GLXDRIcontext * context, __GLXDRIdrawable * pdraw,
-                         __GLXDRIdrawable * pread);
-
-   void (*unbindContext) (__GLXDRIcontext * context);
+   Bool(*bindContext) (__GLXcontext *context, __GLXDRIdrawable *pdraw,
+                      __GLXDRIdrawable *pread);
+   void (*unbindContext) (__GLXcontext *context);
 };
 
 struct __GLXDRIdrawableRec
@@ -176,8 +166,8 @@ struct __GLXDRIdrawableRec
    XID drawable;
    __GLXscreenConfigs *psc;
    GLenum textureTarget;
-   __DRIdrawable *driDrawable;
    GLenum textureFormat;        /* EXT_texture_from_pixmap support */
+   unsigned long eventMask;
 };
 
 /*
@@ -250,6 +240,11 @@ typedef struct __GLXattributeMachineRec
 } __GLXattributeMachine;
 
 struct glx_context_vtable {
+   void (*destroy)(__GLXcontext *ctx);
+   void (*wait_gl)(__GLXcontext *ctx);
+   void (*wait_x)(__GLXcontext *ctx);
+   void (*use_x_font)(__GLXcontext *ctx,
+                     Font font, int first, int count, int listBase);
    void (*bind_tex_image)(Display * dpy,
                          GLXDrawable drawable,
                          int buffer, const int *attrib_list);
@@ -257,6 +252,9 @@ struct glx_context_vtable {
    
 };
 
+extern void
+glx_send_destroy_context(Display *dpy, XID xid);
+
 /**
  * GLX state that needs to be kept on the client.  One of these records
  * exist for each context that has been made current by this client.
@@ -393,11 +391,6 @@ struct __GLXcontextRec
    GLubyte *extensions;
    /*@} */
 
-    /**
-     * Record the dpy this context was created on for later freeing
-     */
-   Display *createDpy;
-
     /**
      * Maximum small render command size.  This is the smaller of 64k and
      * the size of the above buffer.
@@ -421,7 +414,6 @@ struct __GLXcontextRec
    Bool do_destroy;
 #else
    __GLXDRIcontext *driContext;
-   __DRIcontext *__driContext;
 #endif
 #endif
 
@@ -469,6 +461,10 @@ struct __GLXcontextRec
    const struct glx_context_vtable *vtable;
 };
 
+extern Bool
+glx_context_init(__GLXcontext *gc,
+                __GLXscreenConfigs *psc, const __GLcontextModes *fbconfig);
+
 #define __glXSetError(gc,code)  \
    if (!(gc)->error) {          \
       (gc)->error = code;       \
@@ -508,8 +504,16 @@ extern void __glFreeAttributeState(__GLXcontext *);
  * One of these records exists per screen of the display.  It contains
  * a pointer to the config data for that screen (if the screen supports GL).
  */
+struct glx_screen_vtable {
+   __GLXcontext *(*create_context)(__GLXscreenConfigs *psc,
+                                  const __GLcontextModes *mode,
+                                  GLXContext shareList, int renderType);
+};
+
 struct __GLXscreenConfigsRec
 {
+   const struct glx_screen_vtable *vtable;
+
     /**
      * GLX extension string reported by the X-server.
      */
@@ -521,61 +525,16 @@ struct __GLXscreenConfigsRec
      */
    char *effectiveGLXexts;
 
-   /**
-    * Context vtable to use for direct contexts on this screen
-    */
-   const struct glx_context_vtable *direct_context_vtable;
+   __GLXdisplayPrivate *display;
 
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
     /**
      * Per screen direct rendering interface functions and data.
      */
-   __DRIscreen *__driScreen;
-   const __DRIcoreExtension *core;
-   const __DRIlegacyExtension *legacy;
-   const __DRIswrastExtension *swrast;
-   const __DRIdri2Extension *dri2;
-   __glxHashTable *drawHash;
    Display *dpy;
-   int scr, fd;
-   void *driver;
+   int scr;
 
    __GLXDRIscreen *driScreen;
-
-   const __DRIconfig **driver_configs;
-
-#ifdef __DRI_COPY_SUB_BUFFER
-   const __DRIcopySubBufferExtension *driCopySubBuffer;
-#endif
-
-#ifdef __DRI_SWAP_CONTROL
-   const __DRIswapControlExtension *swapControl;
-#endif
-
-#ifdef __DRI_ALLOCATE
-   const __DRIallocateExtension *allocate;
-#endif
-
-#ifdef __DRI_FRAME_TRACKING
-   const __DRIframeTrackingExtension *frameTracking;
-#endif
-
-#ifdef __DRI_MEDIA_STREAM_COUNTER
-   const __DRImediaStreamCounterExtension *msc;
-#endif
-
-#ifdef __DRI_TEX_BUFFER
-   const __DRItexBufferExtension *texBuffer;
-#endif
-
-#ifdef __DRI2_FLUSH
-   const __DRI2flushExtension *f;
-#endif
-
-#ifdef __DRI2_CONFIG_QUERY
-   const __DRI2configQueryExtension *config;
-#endif
-
 #endif
 
     /**
@@ -603,6 +562,10 @@ struct __GLXscreenConfigsRec
  */
 struct __GLXdisplayPrivateRec
 {
+   /* The extension protocol codes */
+   XExtCodes *codes;
+   struct __GLXdisplayPrivateRec *next;
+
     /**
      * Back pointer to the display
      */
@@ -639,9 +602,11 @@ struct __GLXdisplayPrivateRec
      * Also, per screen data which now includes the server \c GLX_EXTENSION
      * string.
      */
-   __GLXscreenConfigs *screenConfigs;
+   __GLXscreenConfigs **screenConfigs;
 
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
+   __glxHashTable *drawHash;
+
     /**
      * Per display direct rendering interface functions and data.
      */
@@ -651,6 +616,14 @@ struct __GLXdisplayPrivateRec
 #endif
 };
 
+extern int
+glx_screen_init(__GLXscreenConfigs *psc,
+               int screen, __GLXdisplayPrivate * priv);
+
+#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
+extern __GLXDRIdrawable *
+dri2GetGlxDrawableFromXDrawableId(Display *dpy, XID id);
+#endif
 
 extern GLubyte *__glXFlushRenderBuffer(__GLXcontext *, GLubyte *);
 
@@ -698,8 +671,6 @@ extern __GLXcontext *__glXcurrentContext;
 
 extern void __glXSetCurrentContextNull(void);
 
-extern void __glXFreeContext(__GLXcontext *);
-
 
 /*
 ** Global lock for all threads in this address space using the GLX
@@ -820,17 +791,23 @@ extern GLboolean __glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
                                     int32_t * denominator);
 
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
-GLboolean
-__driGetMscRateOML(__DRIdrawable * draw,
-                   int32_t * numerator, int32_t * denominator, void *private);
+extern GLboolean
+__glxGetMscRate(__GLXDRIdrawable *glxDraw,
+               int32_t * numerator, int32_t * denominator);
 
 /* So that dri2.c:DRI2WireToEvent() can access
  * glx_info->codes->first_event */
 XExtDisplayInfo *__glXFindDisplay (Display *dpy);
 
+extern void
+GarbageCollectDRIDrawables(__GLXscreenConfigs *psc);
+
 extern __GLXDRIdrawable *
-GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int *const scrn_num);
+GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable);
 
 #endif
 
+extern __GLXscreenConfigs *
+indirect_create_screen(int screen, __GLXdisplayPrivate * priv);
+
 #endif /* !__GLX_client_h__ */
index 16c4eef6ba8fdd92bc46d9d450f9617b02034750..0782b1d70f2df9dcd23de41c899ebfc0143ad06b 100644 (file)
@@ -62,7 +62,7 @@
 
 static const char __glXGLXClientVendorName[] = "Mesa Project and SGI";
 static const char __glXGLXClientVersion[] = "1.4";
-static const struct glx_context_vtable glx_indirect_context_vtable;
+static const struct glx_context_vtable indirect_context_vtable;
 
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
 
@@ -85,33 +85,34 @@ windowExistsErrorHandler(Display * dpy, XErrorEvent * xerr)
  * \param dpy    Display to destroy drawables for
  * \param screen Screen number to destroy drawables for
  */
-static void
-GarbageCollectDRIDrawables(Display * dpy, __GLXscreenConfigs * sc)
+_X_HIDDEN void
+GarbageCollectDRIDrawables(__GLXscreenConfigs * sc)
 {
    XID draw;
    __GLXDRIdrawable *pdraw;
+   __GLXdisplayPrivate *priv = sc->display;
    XWindowAttributes xwa;
    int (*oldXErrorHandler) (Display *, XErrorEvent *);
 
    /* Set no-op error handler so Xlib doesn't bail out if the windows
     * has alreay been destroyed on the server. */
-   XSync(dpy, GL_FALSE);
+   XSync(priv->dpy, GL_FALSE);
    oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler);
 
-   if (__glxHashFirst(sc->drawHash, &draw, (void *) &pdraw) == 1) {
+   if (__glxHashFirst(priv->drawHash, &draw, (void *) &pdraw) == 1) {
       do {
          windowExistsFlag = GL_TRUE;
-         XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */
+         XGetWindowAttributes(priv->dpy, draw, &xwa); /* dummy request */
          if (!windowExistsFlag) {
             /* Destroy the local drawable data, if the drawable no
                longer exists in the Xserver */
             (*pdraw->destroyDrawable) (pdraw);
-            __glxHashDelete(sc->drawHash, draw);
+            __glxHashDelete(priv->drawHash, draw);
          }
-      } while (__glxHashNext(sc->drawHash, &draw, (void *) &pdraw) == 1);
+      } while (__glxHashNext(priv->drawHash, &draw, (void *) &pdraw) == 1);
    }
 
-   XSync(dpy, GL_FALSE);
+   XSync(priv->dpy, GL_FALSE);
    XSetErrorHandler(oldXErrorHandler);
 }
 
@@ -125,28 +126,16 @@ GarbageCollectDRIDrawables(Display * dpy, __GLXscreenConfigs * sc)
  *           the drawable is not associated with a direct-rendering context.
  */
 _X_HIDDEN __GLXDRIdrawable *
-GetGLXDRIDrawable(Display * dpy, GLXDrawable drawable, int *const scrn_num)
+GetGLXDRIDrawable(Display * dpy, GLXDrawable drawable)
 {
    __GLXdisplayPrivate *priv = __glXInitialize(dpy);
    __GLXDRIdrawable *pdraw;
-   const unsigned screen_count = ScreenCount(dpy);
-   unsigned i;
-   __GLXscreenConfigs *psc;
 
    if (priv == NULL)
       return NULL;
 
-   for (i = 0; i < screen_count; i++) {
-      psc = &priv->screenConfigs[i];
-      if (psc->drawHash == NULL)
-         continue;
-
-      if (__glxHashLookup(psc->drawHash, drawable, (void *) &pdraw) == 0) {
-         if (scrn_num != NULL)
-            *scrn_num = i;
-         return pdraw;
-      }
-   }
+   if (__glxHashLookup(priv->drawHash, drawable, (void *) &pdraw) == 0)
+      return pdraw;
 
    return NULL;
 }
@@ -175,7 +164,7 @@ GetGLXScreenConfigs(Display * dpy, int scrn)
 
    return (priv
            && priv->screenConfigs !=
-           NULL) ? &priv->screenConfigs[scrn] : NULL;
+           NULL) ? priv->screenConfigs[scrn] : NULL;
 }
 
 
@@ -202,7 +191,7 @@ GetGLXPrivScreenConfig(Display * dpy, int scrn, __GLXdisplayPrivate ** ppriv,
    }
 
    /* Check to see if the GL is supported on this screen */
-   *ppsc = &((*ppriv)->screenConfigs[scrn]);
+   *ppsc = (*ppriv)->screenConfigs[scrn];
    if ((*ppsc)->configs == NULL) {
       /* No support for GL on this screen regardless of visual */
       return GLX_BAD_VISUAL;
@@ -233,7 +222,7 @@ ValidateGLXFBConfig(Display * dpy, GLXFBConfig config)
 
    if (priv != NULL) {
       for (i = 0; i < num_screens; i++) {
-         for (modes = priv->screenConfigs[i].configs; modes != NULL;
+         for (modes = priv->screenConfigs[i]->configs; modes != NULL;
               modes = modes->next) {
             if (modes == (__GLcontextModes *) config) {
                return (__GLcontextModes *) config;
@@ -245,6 +234,55 @@ ValidateGLXFBConfig(Display * dpy, GLXFBConfig config)
    return NULL;
 }
 
+#ifdef GLX_USE_APPLEGL
+
+static const struct glx_context_vtable applegl_context_vtable;
+
+static __GLcontext *
+applegl_create_context(__GLXscreenConfigs *psc,
+                       const __GLcontextModes *mode,
+                       GLXContext shareList, int renderType)
+{
+   __GLXcontext *gc;
+   int errorcode;
+   bool x11error;
+
+   /* TODO: Integrate this with apple_glx_create_context and make
+    * struct apple_glx_context inherit from __GLXcontext. */
+
+   gc = Xmalloc(sizeof *gc);
+   if (pcp == NULL)
+      return NULL;
+
+   memset(gc, 0, sizeof *gc);
+   if (!glx_context_init(&gc->base, &psc->base, mode)) {
+      Xfree(gc);
+      return NULL;
+   }
+
+   gc->vtable = &applegl_context_vtable;
+   gc->driContext = NULL;
+   gc->do_destroy = False;
+
+   /* TODO: darwin: Integrate with above to do indirect */
+   if(apple_glx_create_context(&gc->driContext, dpy, screen, fbconfig, 
+                              shareList ? shareList->driContext : NULL,
+                              &errorcode, &x11error)) {
+      __glXSendError(dpy, errorcode, 0, X_GLXCreateContext, x11error);
+      gc->vtable->destroy(gc);
+      return NULL;
+   }
+
+   gc->currentContextTag = -1;
+   gc->mode = fbconfig;
+   gc->isDirect = allowDirect;
+   gc->xid = 1; /* Just something not None, so we know when to destroy
+                * it in MakeContextCurrent. */
+
+   return gc;
+}
+#endif
+
 
 /**
  * \todo It should be possible to move the allocate of \c client_state_private
@@ -257,17 +295,16 @@ ValidateGLXFBConfig(Display * dpy, GLXFBConfig config)
  * does all the initialization (including the pixel pack / unpack).
  */
 static GLXContext
-AllocateGLXContext(Display * dpy)
+indirect_create_context(__GLXscreenConfigs *psc,
+                       const __GLcontextModes *mode,
+                       GLXContext shareList, int renderType)
 {
    GLXContext gc;
    int bufSize;
    CARD8 opcode;
    __GLXattribute *state;
 
-   if (!dpy)
-      return NULL;
-
-   opcode = __glXSetupForCommand(dpy);
+   opcode = __glXSetupForCommand(psc->dpy);
    if (!opcode) {
       return NULL;
    }
@@ -280,6 +317,9 @@ AllocateGLXContext(Display * dpy)
    }
    memset(gc, 0, sizeof(struct __GLXcontextRec));
 
+   glx_context_init(gc, psc, mode);
+   gc->isDirect = GL_FALSE;
+   gc->vtable = &indirect_context_vtable;
    state = Xmalloc(sizeof(struct __GLXattributeRec));
    if (state == NULL) {
       /* Out of memory */
@@ -297,7 +337,7 @@ AllocateGLXContext(Display * dpy)
     ** packet for the GLXRenderReq header.
     */
 
-   bufSize = (XMaxRequestSize(dpy) * 4) - sz_xGLXRenderReq;
+   bufSize = (XMaxRequestSize(psc->dpy) * 4) - sz_xGLXRenderReq;
    gc->buf = (GLubyte *) Xmalloc(bufSize);
    if (!gc->buf) {
       Xfree(gc->client_state_private);
@@ -333,7 +373,6 @@ AllocateGLXContext(Display * dpy)
    else {
       gc->limit = gc->buf + bufSize - __GLX_BUFFER_LIMIT_SIZE;
    }
-   gc->createDpy = dpy;
    gc->majorOpcode = opcode;
 
    /*
@@ -350,14 +389,47 @@ AllocateGLXContext(Display * dpy)
    }
    gc->maxSmallRenderCommandSize = bufSize;
    
-#ifdef GLX_USE_APPLEGL
-   gc->driContext = NULL;
-   gc->do_destroy = False;   
-#endif
 
    return gc;
 }
 
+struct glx_screen_vtable indirect_screen_vtable = {
+   indirect_create_context
+};
+
+_X_HIDDEN __GLXscreenConfigs *
+indirect_create_screen(int screen, __GLXdisplayPrivate * priv)
+{
+   __GLXscreenConfigs *psc;
+
+   psc = Xmalloc(sizeof *psc);
+   if (psc == NULL)
+      return NULL;
+
+   memset(psc, 0, sizeof *psc);
+   glx_screen_init(psc, screen, priv);
+   psc->vtable = &indirect_screen_vtable;
+
+   return psc;
+}
+
+
+_X_HIDDEN Bool
+glx_context_init(__GLXcontext *gc,
+                __GLXscreenConfigs *psc, const __GLcontextModes *fbconfig)
+{
+   gc->majorOpcode = __glXSetupForCommand(psc->display->dpy);
+   if (!gc->majorOpcode)
+      return GL_FALSE;
+
+   gc->screen = psc->scr;
+   gc->psc = psc;
+   gc->mode = fbconfig;
+   gc->isDirect = GL_TRUE;
+
+   return GL_TRUE;
+}
+
 
 /**
  * Create a new context.  Exactly one of \c vis and \c fbconfig should be
@@ -375,42 +447,24 @@ CreateContext(Display * dpy, int generic_id,
               Bool allowDirect,
              unsigned code, int renderType, int screen)
 {
-   GLXContext gc;
+   GLXContext gc = NULL;
    __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
-#if defined(GLX_DIRECT_RENDERING) && defined(GLX_USE_APPLEGL)
-   int errorcode;
-   bool x11error;
-#endif
-    
+
    if (dpy == NULL)
       return NULL;
 
    if (generic_id == None)
       return NULL;
 
-   gc = AllocateGLXContext(dpy);
+   gc = NULL;
+   if (allowDirect && psc->vtable->create_context)
+      gc = psc->vtable->create_context(psc, fbconfig,
+                                     shareList, renderType);
+   if (!gc)
+      gc = indirect_create_context(psc, fbconfig, shareList, renderType);
    if (!gc)
       return NULL;
 
-#ifndef GLX_USE_APPLEGL  /* TODO: darwin indirect */
-#ifdef GLX_DIRECT_RENDERING
-   if (allowDirect && psc->driScreen) {
-      gc->driContext = psc->driScreen->createContext(psc, fbconfig, gc,
-                                                    shareList, renderType);
-      if (gc->driContext != NULL) {
-        gc->screen = screen;
-        gc->psc = psc;
-        gc->mode = fbconfig;
-        gc->isDirect = GL_TRUE;
-      }
-   }
-#endif
-
-   if (gc->driContext != NULL)
-      gc->vtable = psc->direct_context_vtable;
-   else
-      gc->vtable = &glx_indirect_context_vtable;
-
    LockDisplay(dpy);
    switch (code) {
    case X_GLXCreateContext: {
@@ -474,26 +528,10 @@ CreateContext(Display * dpy, int generic_id,
 
    UnlockDisplay(dpy);
    SyncHandle();
-#endif
 
    gc->imported = GL_FALSE;
    gc->renderType = renderType;
 
-   /* TODO: darwin: Integrate with above to do indirect */
-#ifdef GLX_USE_APPLEGL
-   if(apple_glx_create_context(&gc->driContext, dpy, screen, fbconfig, 
-                               shareList ? shareList->driContext : NULL,
-                               &errorcode, &x11error)) {
-      __glXSendError(dpy, errorcode, 0, X_GLXCreateContext, x11error);
-      __glXFreeContext(gc);
-      return NULL;
-   }
-   
-   gc->currentContextTag = -1;
-   gc->mode = fbconfig;
-   gc->isDirect = allowDirect;
-#endif
-
    return gc;
 }
 
@@ -529,8 +567,28 @@ glXCreateContext(Display * dpy, XVisualInfo * vis,
 }
 
 _X_HIDDEN void
-__glXFreeContext(__GLXcontext * gc)
+glx_send_destroy_context(Display *dpy, XID xid)
 {
+   CARD8 opcode = __glXSetupForCommand(dpy);
+   xGLXDestroyContextReq *req;
+
+   LockDisplay(dpy);
+   GetReq(GLXDestroyContext, req);
+   req->reqType = opcode;
+   req->glxCode = X_GLXDestroyContext;
+   req->context = xid;
+   UnlockDisplay(dpy);
+   SyncHandle();
+}
+
+static void
+indirect_destroy_context(__GLXcontext *gc)
+{
+   if (!gc->imported && gc->xid)
+      glx_send_destroy_context(gc->psc->dpy, gc->xid);
+
+   __glXFreeVertexArrayState(gc);
+
    if (gc->vendor)
       XFree((char *) gc->vendor);
    if (gc->renderer)
@@ -543,7 +601,6 @@ __glXFreeContext(__GLXcontext * gc)
    XFree((char *) gc->buf);
    Xfree((char *) gc->client_state_private);
    XFree((char *) gc);
-
 }
 
 /*
@@ -552,81 +609,26 @@ __glXFreeContext(__GLXcontext * gc)
 static void
 DestroyContext(Display * dpy, GLXContext gc)
 {
-#ifndef GLX_USE_APPLEGL /* TODO: darwin: indirect */
-   xGLXDestroyContextReq *req;
-   GLXContextID xid;
-   CARD8 opcode;
-   GLboolean imported;
-
-   opcode = __glXSetupForCommand(dpy);
-   if (!opcode || !gc) {
+   if (!gc)
       return;
-   }
 
    __glXLock();
-   xid = gc->xid;
-   imported = gc->imported;
-   gc->xid = None;
-
    if (gc->currentDpy) {
       /* This context is bound to some thread.  According to the man page,
        * we should not actually delete the context until it's unbound.
        * Note that we set gc->xid = None above.  In MakeContextCurrent()
        * we check for that and delete the context there.
        */
+      if (!gc->imported)
+        glx_send_destroy_context(dpy, gc->xid);
+      gc->xid = None;
       __glXUnlock();
       return;
    }
+   __glXUnlock();
 
-#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
-   /* Destroy the direct rendering context */
-   if (gc->driContext) {
-      (*gc->driContext->destroyContext) (gc->driContext, gc->psc, dpy);
-      gc->driContext = NULL;
-      GarbageCollectDRIDrawables(dpy, gc->psc);
-   }
-#endif
-
-   __glXFreeVertexArrayState(gc);
-#else
-   __glXLock();
-#endif /* GLX_USE_APPLEGL */   
-
-   if (gc->currentDpy) {
-#ifdef GLX_USE_APPLEGL
-      /* 
-       * Set the Bool that indicates that we should destroy this GLX context
-       * when the context is no longer current.
-       */
-      gc->do_destroy = True;
-#endif
-      /* Have to free later cuz it's in use now */
-      __glXUnlock();
-   }
-   else {
-      /* Destroy the handle if not current to anybody */
-      __glXUnlock();
-#ifdef GLX_USE_APPLEGL
-      if(gc->driContext)
-         apple_glx_destroy_context(&gc->driContext, dpy);
-#endif
-      __glXFreeContext(gc);
-   }
-#ifndef GLX_USE_APPLEGL
-   if (!imported) {
-      /*
-       ** This dpy also created the server side part of the context.
-       ** Send the glXDestroyContext request.
-       */
-      LockDisplay(dpy);
-      GetReq(GLXDestroyContext, req);
-      req->reqType = opcode;
-      req->glxCode = X_GLXDestroyContext;
-      req->context = xid;
-      UnlockDisplay(dpy);
-      SyncHandle();
-   }
-#endif
+   if (gc->vtable->destroy)
+      gc->vtable->destroy(gc);
 }
 
 PUBLIC void
@@ -674,42 +676,14 @@ glXQueryExtension(Display * dpy, int *errorBase, int *eventBase)
    return rv;
 }
 
-/*
-** Put a barrier in the token stream that forces the GL to finish its
-** work before X can proceed.
-*/
-PUBLIC void
-glXWaitGL(void)
+static void
+indirect_wait_gl(__GLXcontext *gc)
 {
-#ifndef GLX_USE_APPLEGL
    xGLXWaitGLReq *req;
-#endif
-   GLXContext gc = __glXGetCurrentContext();
    Display *dpy = gc->currentDpy;
 
-   if (!dpy)
-      return;
-
    /* Flush any pending commands out */
    __glXFlushRenderBuffer(gc, gc->pc);
-#ifdef GLX_USE_APPLEGL
-   glFinish();
-#else
-#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
-   if (gc->driContext) {
-      int screen;
-      __GLXDRIdrawable *pdraw =
-         GetGLXDRIDrawable(dpy, gc->currentDrawable, &screen);
-
-      if (pdraw != NULL) {
-         __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
-         glFlush();
-         if (psc->driScreen->waitGL != NULL)
-            (*psc->driScreen->waitGL) (pdraw);
-      }
-      return;
-   }
-#endif
 
    /* Send the glXWaitGL request */
    LockDisplay(dpy);
@@ -719,51 +693,30 @@ glXWaitGL(void)
    req->contextTag = gc->currentContextTag;
    UnlockDisplay(dpy);
    SyncHandle();
-#endif /* GLX_USE_APPLEGL */
 }
 
 /*
-** Put a barrier in the token stream that forces X to finish its
-** work before GL can proceed.
+** Put a barrier in the token stream that forces the GL to finish its
+** work before X can proceed.
 */
 PUBLIC void
-glXWaitX(void)
+glXWaitGL(void)
 {
-#ifndef GLX_USE_APPLEGL
-   xGLXWaitXReq *req;
-#endif
    GLXContext gc = __glXGetCurrentContext();
-   Display *dpy = gc->currentDpy;
 
-   if (!dpy)
-      return;
+   if (gc && gc->vtable->use_x_font)
+      gc->vtable->wait_gl(gc);
+}
+
+static void
+indirect_wait_x(__GLXcontext *gc)
+{
+   xGLXWaitXReq *req;
+   Display *dpy = gc->currentDpy;
 
    /* Flush any pending commands out */
    __glXFlushRenderBuffer(gc, gc->pc);
 
-#ifdef GLX_USE_APPLEGL
-   apple_glx_waitx(dpy, gc->driContext);
-#else
-#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
-   if (gc->driContext) {
-      int screen;
-      __GLXDRIdrawable *pdraw =
-         GetGLXDRIDrawable(dpy, gc->currentDrawable, &screen);
-
-      if (pdraw != NULL) {
-         __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
-         if (psc->driScreen->waitX != NULL)
-            (*psc->driScreen->waitX) (pdraw);
-      }
-      else
-         XSync(dpy, False);
-      return;
-   }
-#endif
-
-   /*
-    ** Send the glXWaitX request.
-    */
    LockDisplay(dpy);
    GetReq(GLXWaitX, req);
    req->reqType = gc->majorOpcode;
@@ -771,32 +724,30 @@ glXWaitX(void)
    req->contextTag = gc->currentContextTag;
    UnlockDisplay(dpy);
    SyncHandle();
-#endif /* GLX_USE_APPLEGL */
 }
 
+/*
+** Put a barrier in the token stream that forces X to finish its
+** work before GL can proceed.
+*/
 PUBLIC void
-glXUseXFont(Font font, int first, int count, int listBase)
+glXWaitX(void)
 {
-#ifndef GLX_USE_APPLEGL
-   xGLXUseXFontReq *req;
-#endif
    GLXContext gc = __glXGetCurrentContext();
-   Display *dpy = gc->currentDpy;
 
-   if (!dpy)
-      return;
+   if (gc && gc->vtable->use_x_font)
+      gc->vtable->wait_x(gc);
+}
+
+static void
+indirect_use_x_font(__GLXcontext *gc,
+                   Font font, int first, int count, int listBase)
+{
+   xGLXUseXFontReq *req;
+   Display *dpy = gc->currentDpy;
 
    /* Flush any pending commands out */
-   (void) __glXFlushRenderBuffer(gc, gc->pc);
-#ifdef GLX_USE_APPLEGL
-   DRI_glXUseXFont(font, first, count, listBase); 
-#else
-#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
-   if (gc->driContext) {
-      DRI_glXUseXFont(font, first, count, listBase);
-      return;
-   }
-#endif
+   __glXFlushRenderBuffer(gc, gc->pc);
 
    /* Send the glXUseFont request */
    LockDisplay(dpy);
@@ -810,7 +761,46 @@ glXUseXFont(Font font, int first, int count, int listBase)
    req->listBase = listBase;
    UnlockDisplay(dpy);
    SyncHandle();
-#endif /* GLX_USE_APPLEGL */
+}
+
+#ifdef GLX_USE_APPLEGL
+
+static void
+applegl_destroy_context(__GLXcontext *gc)
+{
+   apple_glx_destroy_context(&gc->driContext, gc->currentDpy);
+}
+
+static void
+applegl_wait_gl(__GLXcontext *gc)
+{
+   glFinish();
+}
+
+static void
+applegl_wait_x(__GLXcontext *gc)
+{
+   apple_glx_waitx(gc->dpy, gc->driContext);
+}
+
+static const struct glx_context_vtable applegl_context_vtable = {
+   applegl_destroy_context,
+   applegl_wait_gl,
+   applegl_wait_x,
+   DRI_glXUseXFont,
+   NULL, /* bind_tex_image, */
+   NULL, /* release_tex_image, */
+};
+
+#endif
+
+PUBLIC void
+glXUseXFont(Font font, int first, int count, int listBase)
+{
+   GLXContext gc = __glXGetCurrentContext();
+
+   if (gc && gc->vtable->use_x_font)
+      gc->vtable->use_x_font(gc, font, first, count, listBase);
 }
 
 /************************************************************************/
@@ -992,7 +982,7 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
       __GLXscreenConfigs *psc;
       __GLcontextModes *modes;
 
-      psc = &priv->screenConfigs[vis->screen];
+      psc = priv->screenConfigs[vis->screen];
       if (psc->driScreen == NULL)
          break;
       modes = _gl_context_modes_find_visual(psc->visuals, vis->visualid);
@@ -1002,7 +992,7 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
          break;
       }
 
-      if (__glxHashInsert(psc->drawHash, req->glxpixmap, pdraw)) {
+      if (__glxHashInsert(priv->drawHash, req->glxpixmap, pdraw)) {
          (*pdraw->destroyDrawable) (pdraw);
          return None;           /* FIXME: Check what we're supposed to do here... */
       }
@@ -1042,14 +1032,12 @@ glXDestroyGLXPixmap(Display * dpy, GLXPixmap glxpixmap)
 
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
    {
-      int screen;
       __GLXdisplayPrivate *const priv = __glXInitialize(dpy);
-      __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, glxpixmap, &screen);
-      __GLXscreenConfigs *psc = &priv->screenConfigs[screen];
+      __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, glxpixmap);
 
       if (pdraw != NULL) {
          (*pdraw->destroyDrawable) (pdraw);
-         __glxHashDelete(psc->drawHash, glxpixmap);
+         __glxHashDelete(priv->drawHash, glxpixmap);
       }
    }
 #endif
@@ -1077,7 +1065,7 @@ glXSwapBuffers(Display * dpy, GLXDrawable drawable)
 #endif
 
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
-   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
+   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
 
    if (pdraw != NULL) {
       glFlush();
@@ -1690,122 +1678,103 @@ GLX_ALIAS(Display *, glXGetCurrentDisplayEXT, (void), (),
           glXGetCurrentDisplay)
 
 #ifndef GLX_USE_APPLEGL
-/**
- * Used internally by libGL to send \c xGLXQueryContextinfoExtReq requests
- * to the X-server.
- *
- * \param dpy  Display where \c ctx was created.
- * \param ctx  Context to query.
- * \returns  \c Success on success.  \c GLX_BAD_CONTEXT if \c ctx is invalid,
- *           or zero if the request failed due to internal problems (i.e.,
- *           unable to allocate temporary memory, etc.)
- *
- * \note
- * This function dynamically determines whether to use the EXT_import_context
- * version of the protocol or the GLX 1.3 version of the protocol.
- */
-static int __glXQueryContextInfo(Display * dpy, GLXContext ctx)
+PUBLIC GLXContext
+glXImportContextEXT(Display *dpy, GLXContextID contextID)
 {
    __GLXdisplayPrivate *priv = __glXInitialize(dpy);
+   __GLXscreenConfigs *psc;
    xGLXQueryContextReply reply;
    CARD8 opcode;
-   GLuint numValues;
-   int retval;
+   GLXContext ctx;
+   int propList[__GLX_MAX_CONTEXT_PROPS * 2], *pProp, nPropListBytes;
+   int i, renderType;
+   XID share;
+   __GLcontextModes *mode;
+
+   if (contextID == None || __glXIsDirect(dpy, contextID))
+      return NULL;
 
-   if (ctx == NULL) {
-      return GLX_BAD_CONTEXT;
-   }
    opcode = __glXSetupForCommand(dpy);
-   if (!opcode) {
+   if (!opcode)
       return 0;
-   }
 
    /* Send the glXQueryContextInfoEXT request */
    LockDisplay(dpy);
 
-   if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
+   if (priv->majorVersion > 1 || priv->minorVersion >= 3) {
       xGLXQueryContextReq *req;
 
       GetReq(GLXQueryContext, req);
 
       req->reqType = opcode;
       req->glxCode = X_GLXQueryContext;
-      req->context = (unsigned int) (ctx->xid);
+      req->context = contextID;
    }
    else {
       xGLXVendorPrivateReq *vpreq;
       xGLXQueryContextInfoEXTReq *req;
 
       GetReqExtra(GLXVendorPrivate,
-                  sz_xGLXQueryContextInfoEXTReq - sz_xGLXVendorPrivateReq,
-                  vpreq);
+                 sz_xGLXQueryContextInfoEXTReq - sz_xGLXVendorPrivateReq,
+                 vpreq);
       req = (xGLXQueryContextInfoEXTReq *) vpreq;
       req->reqType = opcode;
       req->glxCode = X_GLXVendorPrivateWithReply;
       req->vendorCode = X_GLXvop_QueryContextInfoEXT;
-      req->context = (unsigned int) (ctx->xid);
+      req->context = contextID;
    }
 
    _XReply(dpy, (xReply *) & reply, 0, False);
 
-   numValues = reply.n;
-   if (numValues == 0)
-      retval = Success;
-   else if (numValues > __GLX_MAX_CONTEXT_PROPS)
-      retval = 0;
-   else {
-      int *propList, *pProp;
-      int nPropListBytes;
-
-      nPropListBytes = numValues << 3;
-      propList = (int *) Xmalloc(nPropListBytes);
-      if (NULL == propList) {
-         retval = 0;
-      }
-      else {
-        unsigned i;
-
-         _XRead(dpy, (char *) propList, nPropListBytes);
-
-        /* Look up screen first so we can look up visuals/fbconfigs later */
-         pProp = propList;
-         for (i = 0; i < numValues; i++, pProp += 2)
-            if (pProp[0] == GLX_SCREEN) {
-                ctx->screen = pProp[1];
-                ctx->psc = GetGLXScreenConfigs(dpy, ctx->screen);
-            }
-
-         pProp = propList;
-         for (i = 0; i < numValues; i++) {
-            switch (*pProp++) {
-            case GLX_SHARE_CONTEXT_EXT:
-               ctx->share_xid = *pProp++;
-               break;
-            case GLX_VISUAL_ID_EXT:
-               ctx->mode =
-                  _gl_context_modes_find_visual(ctx->psc->visuals, *pProp++);
-               break;
-            case GLX_FBCONFIG_ID:
-               ctx->mode =
-                  _gl_context_modes_find_fbconfig(ctx->psc->configs,
-                                                  *pProp++);
-               break;
-            case GLX_RENDER_TYPE:
-               ctx->renderType = *pProp++;
-               break;
-            case GLX_SCREEN:
-            default:
-               pProp++;
-               continue;
-            }
-         }
-         Xfree((char *) propList);
-         retval = Success;
-      }
-   }
+   if (reply.n <= __GLX_MAX_CONTEXT_PROPS)
+      nPropListBytes = reply.n * 2 * sizeof propList[0];
+   else
+      nPropListBytes = 0;
+   _XRead(dpy, (char *) propList, nPropListBytes);
    UnlockDisplay(dpy);
    SyncHandle();
-   return retval;
+
+   /* Look up screen first so we can look up visuals/fbconfigs later */
+   psc = NULL;
+   for (i = 0, pProp = propList; i < reply.n; i++, pProp += 2)
+      if (pProp[0] == GLX_SCREEN)
+        psc = GetGLXScreenConfigs(dpy, pProp[1]);
+   if (psc == NULL)
+      return NULL;
+
+   share = None;
+   mode = NULL;
+   renderType = 0;
+   pProp = propList;
+
+   for (i = 0, pProp = propList; i < reply.n; i++, pProp += 2)
+      switch (pProp[0]) {
+      case GLX_SHARE_CONTEXT_EXT:
+        share = pProp[1];
+        break;
+      case GLX_VISUAL_ID_EXT:
+        mode = _gl_context_modes_find_visual(psc->visuals, pProp[1]);
+        break;
+      case GLX_FBCONFIG_ID:
+        mode = _gl_context_modes_find_fbconfig(psc->configs, pProp[1]);
+        break;
+      case GLX_RENDER_TYPE:
+        renderType = pProp[1];
+        break;
+      }
+
+   if (mode == NULL)
+      return NULL;
+
+   ctx = indirect_create_context(psc, mode, NULL, renderType);
+   if (ctx == NULL)
+      return NULL;
+
+   ctx->xid = contextID;
+   ctx->imported = GL_TRUE;
+   ctx->share_xid = share;
+
+   return ctx;
 }
 
 #endif
@@ -1813,38 +1782,21 @@ static int __glXQueryContextInfo(Display * dpy, GLXContext ctx)
 PUBLIC int
 glXQueryContext(Display * dpy, GLXContext ctx, int attribute, int *value)
 {
-#ifndef GLX_USE_APPLEGL
-   int retVal;
-
-   /* get the information from the server if we don't have it already */
-#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
-   if (!ctx->driContext && (ctx->mode == NULL)) {
-#else
-   if (ctx->mode == NULL) {
-#endif
-      retVal = __glXQueryContextInfo(dpy, ctx);
-      if (Success != retVal)
-         return retVal;
-   }
-#endif
-
    switch (attribute) {
-#ifndef GLX_USE_APPLEGL
       case GLX_SHARE_CONTEXT_EXT:
-      *value = (int) (ctx->share_xid);
+      *value = ctx->share_xid;
       break;
    case GLX_VISUAL_ID_EXT:
       *value = ctx->mode ? ctx->mode->visualID : None;
       break;
-#endif
    case GLX_SCREEN:
-      *value = (int) (ctx->screen);
+      *value = ctx->screen;
       break;
    case GLX_FBCONFIG_ID:
       *value = ctx->mode ? ctx->mode->fbconfigID : None;
       break;
    case GLX_RENDER_TYPE:
-      *value = (int) (ctx->renderType);
+      *value = ctx->renderType;
       break;
    default:
       return GLX_BAD_ATTRIBUTE;
@@ -1862,35 +1814,6 @@ PUBLIC GLXContextID glXGetContextIDEXT(const GLXContext ctx)
    return ctx->xid;
 }
 
-PUBLIC GLXContext
-glXImportContextEXT(Display * dpy, GLXContextID contextID)
-{
-#ifdef GLX_USE_APPLEGL
-   return NULL;
-#else
-   GLXContext ctx;
-
-   if (contextID == None) {
-      return NULL;
-   }
-   if (__glXIsDirect(dpy, contextID)) {
-      return NULL;
-   }
-
-   ctx = AllocateGLXContext(dpy);
-   if (NULL != ctx) {
-      ctx->xid = contextID;
-      ctx->imported = GL_TRUE;
-
-      if (Success != __glXQueryContextInfo(dpy, ctx)) {
-        __glXFreeContext(ctx);
-        ctx = NULL;
-      }
-   }
-   return ctx;
-#endif
-}
-
 PUBLIC void
 glXFreeContextEXT(Display * dpy, GLXContext ctx)
 {
@@ -1898,11 +1821,6 @@ glXFreeContextEXT(Display * dpy, GLXContext ctx)
 }
 
 
-
-/*
- * GLX 1.3 functions - these are just stubs for now!
- */
-
 PUBLIC GLXFBConfig *
 glXChooseFBConfig(Display * dpy, int screen,
                   const int *attribList, int *nitems)
@@ -1958,14 +1876,14 @@ glXGetFBConfigs(Display * dpy, int screen, int *nelements)
    *nelements = 0;
    if (priv && (priv->screenConfigs != NULL)
        && (screen >= 0) && (screen <= ScreenCount(dpy))
-       && (priv->screenConfigs[screen].configs != NULL)
-       && (priv->screenConfigs[screen].configs->fbconfigID
+       && (priv->screenConfigs[screen]->configs != NULL)
+       && (priv->screenConfigs[screen]->configs->fbconfigID
           != (int) GLX_DONT_CARE)) {
       unsigned num_configs = 0;
       __GLcontextModes *modes;
 
 
-      for (modes = priv->screenConfigs[screen].configs; modes != NULL;
+      for (modes = priv->screenConfigs[screen]->configs; modes != NULL;
            modes = modes->next) {
          if (modes->fbconfigID != (int) GLX_DONT_CARE) {
             num_configs++;
@@ -1977,7 +1895,7 @@ glXGetFBConfigs(Display * dpy, int screen, int *nelements)
       if (config != NULL) {
          *nelements = num_configs;
          i = 0;
-         for (modes = priv->screenConfigs[screen].configs; modes != NULL;
+         for (modes = priv->screenConfigs[screen]->configs; modes != NULL;
               modes = modes->next) {
             if (modes->fbconfigID != (int) GLX_DONT_CARE) {
                config[i] = modes;
@@ -2038,29 +1956,12 @@ __glXSwapIntervalSGI(int interval)
       return GLX_BAD_VALUE;
    }
 
-#ifdef __DRI_SWAP_CONTROL
-   if (gc->driContext) {
-      __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
-                                                           gc->screen );
-      __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy,
-                                                 gc->currentDrawable,
-                                                 NULL);
-      if (psc->swapControl != NULL && pdraw != NULL) {
-        psc->swapControl->setSwapInterval(pdraw->driDrawable, interval);
-        return 0;
-      }
-      else if (pdraw == NULL) {
-        return GLX_BAD_CONTEXT;
-      }
-   }
-#endif
    psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
 
 #ifdef GLX_DIRECT_RENDERING
    if (gc->driContext && psc->driScreen && psc->driScreen->setSwapInterval) {
-      __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy,
-                                                 gc->currentDrawable,
-                                                 NULL);
+      __GLXDRIdrawable *pdraw =
+        GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
       psc->driScreen->setSwapInterval(pdraw, interval);
       return 0;
    }
@@ -2097,34 +1998,17 @@ __glXSwapIntervalSGI(int interval)
 static int
 __glXSwapIntervalMESA(unsigned int interval)
 {
+#ifdef GLX_DIRECT_RENDERING
    GLXContext gc = __glXGetCurrentContext();
 
-#ifdef __DRI_SWAP_CONTROL
-   if (gc != NULL && gc->driContext) {
-      __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy,
-                                                          gc->screen);
-
-      if ((psc != NULL) && (psc->driScreen != NULL)) {
-         __GLXDRIdrawable *pdraw =
-            GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
-         if (psc->swapControl != NULL && pdraw != NULL) {
-            psc->swapControl->setSwapInterval(pdraw->driDrawable, interval);
-            return 0;
-         }
-      }
-   }
-#endif
-
-#ifdef GLX_DIRECT_RENDERING
    if (gc != NULL && gc->driContext) {
       __GLXscreenConfigs *psc;
 
       psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
       if (psc->driScreen && psc->driScreen->setSwapInterval) {
-         __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy,
-                                                    gc->currentDrawable, NULL);
-        psc->driScreen->setSwapInterval(pdraw, interval);
-        return 0;
+         __GLXDRIdrawable *pdraw =
+           GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
+        return psc->driScreen->setSwapInterval(pdraw, interval);
       }
    }
 #endif
@@ -2136,31 +2020,16 @@ __glXSwapIntervalMESA(unsigned int interval)
 static int
 __glXGetSwapIntervalMESA(void)
 {
-#ifdef __DRI_SWAP_CONTROL
+#ifdef GLX_DIRECT_RENDERING
    GLXContext gc = __glXGetCurrentContext();
 
-   if (gc != NULL && gc->driContext) {
-      __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy,
-                                                          gc->screen);
-
-      if ((psc != NULL) && (psc->driScreen != NULL)) {
-         __GLXDRIdrawable *pdraw =
-            GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
-         if (psc->swapControl != NULL && pdraw != NULL) {
-            return psc->swapControl->getSwapInterval(pdraw->driDrawable);
-         }
-      }
-   }
-#endif
-
-#ifdef GLX_DIRECT_RENDERING
    if (gc != NULL && gc->driContext) {
       __GLXscreenConfigs *psc;
 
       psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
       if (psc->driScreen && psc->driScreen->getSwapInterval) {
-         __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy,
-                                                    gc->currentDrawable, NULL);
+         __GLXDRIdrawable *pdraw =
+           GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
         return psc->driScreen->getSwapInterval(pdraw);
       }
    }
@@ -2170,107 +2039,6 @@ __glXGetSwapIntervalMESA(void)
 }
 
 
-/*
-** GLX_MESA_swap_frame_usage
-*/
-
-static GLint
-__glXBeginFrameTrackingMESA(Display * dpy, GLXDrawable drawable)
-{
-   int status = GLX_BAD_CONTEXT;
-#ifdef __DRI_FRAME_TRACKING
-   int screen = 0;
-   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
-   __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
-
-   if (pdraw != NULL && psc->frameTracking != NULL)
-      status = psc->frameTracking->frameTracking(pdraw->driDrawable, GL_TRUE);
-#else
-   (void) dpy;
-   (void) drawable;
-#endif
-   return status;
-}
-
-
-static GLint
-__glXEndFrameTrackingMESA(Display * dpy, GLXDrawable drawable)
-{
-   int status = GLX_BAD_CONTEXT;
-#ifdef __DRI_FRAME_TRACKING
-   int screen = 0;
-   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
-   __GLXscreenConfigs *psc = GetGLXScreenConfigs(dpy, screen);
-
-   if (pdraw != NULL && psc->frameTracking != NULL)
-      status = psc->frameTracking->frameTracking(pdraw->driDrawable,
-                                                 GL_FALSE);
-#else
-   (void) dpy;
-   (void) drawable;
-#endif
-   return status;
-}
-
-
-static GLint
-__glXGetFrameUsageMESA(Display * dpy, GLXDrawable drawable, GLfloat * usage)
-{
-   int status = GLX_BAD_CONTEXT;
-#ifdef __DRI_FRAME_TRACKING
-   int screen = 0;
-   __GLXDRIdrawable *const pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
-   __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
-
-   if (pdraw != NULL && psc->frameTracking != NULL) {
-      int64_t sbc, missedFrames;
-      float lastMissedUsage;
-
-      status = psc->frameTracking->queryFrameTracking(pdraw->driDrawable,
-                                                      &sbc,
-                                                      &missedFrames,
-                                                      &lastMissedUsage,
-                                                      usage);
-   }
-#else
-   (void) dpy;
-   (void) drawable;
-   (void) usage;
-#endif
-   return status;
-}
-
-
-static GLint
-__glXQueryFrameTrackingMESA(Display * dpy, GLXDrawable drawable,
-                            int64_t * sbc, int64_t * missedFrames,
-                            GLfloat * lastMissedUsage)
-{
-   int status = GLX_BAD_CONTEXT;
-#ifdef __DRI_FRAME_TRACKING
-   int screen = 0;
-   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
-   __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
-
-   if (pdraw != NULL && psc->frameTracking != NULL) {
-      float usage;
-
-      status = psc->frameTracking->queryFrameTracking(pdraw->driDrawable,
-                                                      sbc, missedFrames,
-                                                      lastMissedUsage,
-                                                      &usage);
-   }
-#else
-   (void) dpy;
-   (void) drawable;
-   (void) sbc;
-   (void) missedFrames;
-   (void) lastMissedUsage;
-#endif
-   return status;
-}
-
-
 /*
 ** GLX_SGI_video_sync
 */
@@ -2295,23 +2063,13 @@ __glXGetVideoSyncSGI(unsigned int *count)
 
    psc = GetGLXScreenConfigs(gc->currentDpy, gc->screen);
 #ifdef GLX_DIRECT_RENDERING
-   pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+   pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
 #endif
 
    /* FIXME: Looking at the GLX_SGI_video_sync spec in the extension registry,
     * FIXME: there should be a GLX encoding for this call.  I can find no
     * FIXME: documentation for the GLX encoding.
     */
-#ifdef __DRI_MEDIA_STREAM_COUNTER
-   if ( psc->msc && psc->driScreen ) {
-      ret = (*psc->msc->getDrawableMSC)(psc->__driScreen,
-                                       pdraw->driDrawable, &msc);
-      *count = (unsigned) msc;
-
-      return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
-   }
-#endif
-
 #ifdef GLX_DIRECT_RENDERING
    if (psc->driScreen && psc->driScreen->getDrawableMSC) {
       ret = psc->driScreen->getDrawableMSC(psc, pdraw, &ust, &msc, &sbc);
@@ -2347,16 +2105,7 @@ __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
 
    psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen);
 #ifdef GLX_DIRECT_RENDERING
-   pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
-#endif
-
-#ifdef __DRI_MEDIA_STREAM_COUNTER
-   if (psc->msc != NULL && psc->driScreen ) {
-      ret = (*psc->msc->waitForMSC)(pdraw->driDrawable, 0,
-                                   divisor, remainder, &msc, &sbc);
-      *count = (unsigned) msc;
-      return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
-   }
+   pdraw = GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable);
 #endif
 
 #ifdef GLX_DIRECT_RENDERING
@@ -2532,7 +2281,7 @@ __glXGetSyncValuesOML(Display * dpy, GLXDrawable drawable,
                       int64_t * ust, int64_t * msc, int64_t * sbc)
 {
    __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
-   int i, ret;
+   int ret;
 #ifdef GLX_DIRECT_RENDERING
    __GLXDRIdrawable *pdraw;
 #endif
@@ -2542,20 +2291,9 @@ __glXGetSyncValuesOML(Display * dpy, GLXDrawable drawable,
       return False;
 
 #ifdef GLX_DIRECT_RENDERING
-   pdraw = GetGLXDRIDrawable(dpy, drawable, &i);
-#endif
-   psc = &priv->screenConfigs[i];
-
-#if defined(__DRI_SWAP_BUFFER_COUNTER) && defined(__DRI_MEDIA_STREAM_COUNTER)
-   if (pdraw && psc->sbc && psc->msc)
-      return ( (pdraw && psc->sbc && psc->msc)
-              && ((*psc->msc->getMSC)(psc->driScreen, msc) == 0)
-              && ((*psc->sbc->getSBC)(pdraw->driDrawable, sbc) == 0)
-              && (__glXGetUST(ust) == 0) );
-#endif
-
-#ifdef GLX_DIRECT_RENDERING
-   if (pdraw && psc && psc->driScreen && psc->driScreen->getDrawableMSC) {
+   pdraw = GetGLXDRIDrawable(dpy, drawable);
+   psc = pdraw ? pdraw->psc : NULL;
+   if (pdraw && psc->driScreen->getDrawableMSC) {
       ret = psc->driScreen->getDrawableMSC(psc, pdraw, ust, msc, sbc);
       return ret;
    }
@@ -2566,17 +2304,14 @@ __glXGetSyncValuesOML(Display * dpy, GLXDrawable drawable,
 
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
 _X_HIDDEN GLboolean
-__driGetMscRateOML(__DRIdrawable * draw,
-                   int32_t * numerator, int32_t * denominator, void *private)
+__glxGetMscRate(__GLXDRIdrawable *glxDraw,
+               int32_t * numerator, int32_t * denominator)
 {
 #ifdef XF86VIDMODE
    __GLXscreenConfigs *psc;
    XF86VidModeModeLine mode_line;
    int dot_clock;
    int i;
-   __GLXDRIdrawable *glxDraw = private;
-
-   (void) draw;
 
    psc = glxDraw->psc;
    if (XF86VidModeQueryVersion(psc->dpy, &i, &i) &&
@@ -2655,12 +2390,12 @@ __glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
                    int32_t * numerator, int32_t * denominator)
 {
 #if defined( GLX_DIRECT_RENDERING ) && defined( XF86VIDMODE )
-   __GLXDRIdrawable *draw = GetGLXDRIDrawable(dpy, drawable, NULL);
+   __GLXDRIdrawable *draw = GetGLXDRIDrawable(dpy, drawable);
 
    if (draw == NULL)
       return False;
 
-   return __driGetMscRateOML(draw->driDrawable, numerator, denominator, draw);
+   return __glxGetMscRate(draw, numerator, denominator);
 #else
    (void) dpy;
    (void) drawable;
@@ -2676,11 +2411,10 @@ __glXSwapBuffersMscOML(Display * dpy, GLXDrawable drawable,
                        int64_t target_msc, int64_t divisor, int64_t remainder)
 {
    GLXContext gc = __glXGetCurrentContext();
-   int screen;
 #ifdef GLX_DIRECT_RENDERING
-   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
+   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
+   __GLXscreenConfigs *psc = pdraw ? pdraw->psc : NULL;
 #endif
-   __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
 
    if (!gc) /* no GLX for this */
       return -1;
@@ -2703,12 +2437,6 @@ __glXSwapBuffersMscOML(Display * dpy, GLXDrawable drawable,
    if (target_msc == 0 && divisor == 0 && remainder == 0)
       remainder = 1;
 
-#ifdef __DRI_SWAP_BUFFER_COUNTER
-   if (psc->counters != NULL)
-      return (*psc->sbc->swapBuffersMSC)(pdraw->driDrawable, target_msc,
-                                        divisor, remainder);
-#endif
-
 #ifdef GLX_DIRECT_RENDERING
    if (psc->driScreen && psc->driScreen->swapBuffers)
       return (*psc->driScreen->swapBuffers)(pdraw, target_msc, divisor,
@@ -2725,11 +2453,10 @@ __glXWaitForMscOML(Display * dpy, GLXDrawable drawable,
                    int64_t remainder, int64_t * ust,
                    int64_t * msc, int64_t * sbc)
 {
-   int screen;
 #ifdef GLX_DIRECT_RENDERING
-   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
+   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
 #endif
-   __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen );
+   __GLXscreenConfigs *psc = pdraw ? pdraw->psc : NULL;
    int ret;
 
 
@@ -2741,18 +2468,6 @@ __glXWaitForMscOML(Display * dpy, GLXDrawable drawable,
    if (divisor > 0 && remainder >= divisor)
       return False;
 
-#ifdef __DRI_MEDIA_STREAM_COUNTER
-   if (pdraw != NULL && psc->msc != NULL) {
-      ret = (*psc->msc->waitForMSC) (pdraw->driDrawable, target_msc,
-                                     divisor, remainder, msc, sbc);
-
-      /* __glXGetUST returns zero on success and non-zero on failure.
-       * This function returns True on success and False on failure.
-       */
-      return ((ret == 0) && (__glXGetUST(ust) == 0));
-   }
-#endif
-
 #ifdef GLX_DIRECT_RENDERING
    if (pdraw && psc->driScreen && psc->driScreen->waitForMSC) {
       ret = psc->driScreen->waitForMSC(pdraw, target_msc, divisor, remainder,
@@ -2770,11 +2485,10 @@ __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable,
                    int64_t target_sbc, int64_t * ust,
                    int64_t * msc, int64_t * sbc)
 {
-   int screen;
 #ifdef GLX_DIRECT_RENDERING
-   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
+   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
 #endif
-   __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
+   __GLXscreenConfigs *psc = pdraw ? pdraw->psc : NULL;
    int ret;
 
    /* The OML_sync_control spec says this should "generate a GLX_BAD_VALUE
@@ -2782,17 +2496,6 @@ __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable,
     */
    if (target_sbc < 0)
       return False;
-#ifdef __DRI_SWAP_BUFFER_COUNTER
-   if (pdraw != NULL && psc->sbc != NULL) {
-      ret =
-         (*psc->sbc->waitForSBC) (pdraw->driDrawable, target_sbc, msc, sbc);
-
-      /* __glXGetUST returns zero on success and non-zero on failure.
-       * This function returns True on success and False on failure.
-       */
-      return ((ret == 0) && (__glXGetUST(ust) == 0));
-   }
-#endif
 
 #ifdef GLX_DIRECT_RENDERING
    if (pdraw && psc->driScreen && psc->driScreen->waitForSBC) {
@@ -2804,72 +2507,6 @@ __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable,
    return False;
 }
 
-
-/**
- * GLX_MESA_allocate_memory
- */
-/*@{*/
-
-PUBLIC void *
-glXAllocateMemoryMESA(Display * dpy, int scrn,
-                      size_t size, float readFreq,
-                      float writeFreq, float priority)
-{
-#ifdef __DRI_ALLOCATE
-   __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, scrn);
-
-   if (psc && psc->allocate)
-      return (*psc->allocate->allocateMemory) (psc->__driScreen, size,
-                                               readFreq, writeFreq, priority);
-
-#else
-   (void) dpy;
-   (void) scrn;
-   (void) size;
-   (void) readFreq;
-   (void) writeFreq;
-   (void) priority;
-#endif /* __DRI_ALLOCATE */
-
-   return NULL;
-}
-
-
-PUBLIC void
-glXFreeMemoryMESA(Display * dpy, int scrn, void *pointer)
-{
-#ifdef __DRI_ALLOCATE
-   __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, scrn);
-
-   if (psc && psc->allocate)
-      (*psc->allocate->freeMemory) (psc->__driScreen, pointer);
-
-#else
-   (void) dpy;
-   (void) scrn;
-   (void) pointer;
-#endif /* __DRI_ALLOCATE */
-}
-
-
-PUBLIC GLuint
-glXGetMemoryOffsetMESA(Display * dpy, int scrn, const void *pointer)
-{
-#ifdef __DRI_ALLOCATE
-   __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, scrn);
-
-   if (psc && psc->allocate)
-      return (*psc->allocate->memoryOffset) (psc->__driScreen, pointer);
-
-#else
-   (void) dpy;
-   (void) scrn;
-   (void) pointer;
-#endif /* GLX_DIRECT_RENDERING */
-
-   return ~0L;
-}
-
 /*@}*/
 
 
@@ -2938,11 +2575,10 @@ __glXCopySubBufferMESA(Display * dpy, GLXDrawable drawable,
    INT32 *x_ptr, *y_ptr, *w_ptr, *h_ptr;
    CARD8 opcode;
 
-#ifdef __DRI_COPY_SUB_BUFFER
-   int screen;
-   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
+#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
+   __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable);
    if (pdraw != NULL) {
-      __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
+      __GLXscreenConfigs *psc = pdraw->psc;
       if (psc->driScreen->copySubBuffer != NULL) {
          glFlush();
          (*psc->driScreen->copySubBuffer) (pdraw, x, y, width, height);
@@ -2998,9 +2634,9 @@ __glXCopySubBufferMESA(Display * dpy, GLXDrawable drawable,
  * GLX_EXT_texture_from_pixmap
  */
 static void
-glx_indirect_bind_tex_image(Display * dpy,
-                           GLXDrawable drawable,
-                           int buffer, const int *attrib_list)
+indirect_bind_tex_image(Display * dpy,
+                       GLXDrawable drawable,
+                       int buffer, const int *attrib_list)
 {
    xGLXVendorPrivateReq *req;
    GLXContext gc = __glXGetCurrentContext();
@@ -3051,7 +2687,7 @@ glx_indirect_bind_tex_image(Display * dpy,
 }
 
 static void
-glx_indirect_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
+indirect_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
 {
    xGLXVendorPrivateReq *req;
    GLXContext gc = __glXGetCurrentContext();
@@ -3080,9 +2716,13 @@ glx_indirect_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
    SyncHandle();
 }
 
-static const struct glx_context_vtable glx_indirect_context_vtable = {
-   glx_indirect_bind_tex_image,
-   glx_indirect_release_tex_image,
+static const struct glx_context_vtable indirect_context_vtable = {
+   indirect_destroy_context,
+   indirect_wait_gl,
+   indirect_wait_x,
+   indirect_use_x_font,
+   indirect_bind_tex_image,
+   indirect_release_tex_image,
 };
 
 /*@{*/
@@ -3233,11 +2873,6 @@ static const struct name_address_pair GLX_functions[] = {
    GLX_FUNCTION2(glXBindSwapBarrierSGIX, __glXBindSwapBarrierSGIX),
    GLX_FUNCTION2(glXQueryMaxSwapBarriersSGIX, __glXQueryMaxSwapBarriersSGIX),
 
-   /*** GLX_MESA_allocate_memory ***/
-   GLX_FUNCTION(glXAllocateMemoryMESA),
-   GLX_FUNCTION(glXFreeMemoryMESA),
-   GLX_FUNCTION(glXGetMemoryOffsetMESA),
-
    /*** GLX_MESA_copy_sub_buffer ***/
    GLX_FUNCTION2(glXCopySubBufferMESA, __glXCopySubBufferMESA),
 
@@ -3250,12 +2885,6 @@ static const struct name_address_pair GLX_functions[] = {
    /*** GLX_MESA_swap_control ***/
    GLX_FUNCTION2(glXSwapIntervalMESA, __glXSwapIntervalMESA),
    GLX_FUNCTION2(glXGetSwapIntervalMESA, __glXGetSwapIntervalMESA),
-
-   /*** GLX_MESA_swap_frame_usage ***/
-   GLX_FUNCTION2(glXBeginFrameTrackingMESA, __glXBeginFrameTrackingMESA),
-   GLX_FUNCTION2(glXEndFrameTrackingMESA, __glXEndFrameTrackingMESA),
-   GLX_FUNCTION2(glXGetFrameUsageMESA, __glXGetFrameUsageMESA),
-   GLX_FUNCTION2(glXQueryFrameTrackingMESA, __glXQueryFrameTrackingMESA),
 #endif
 
    /*** GLX_ARB_get_proc_address ***/
index 691e8dfadf2ca1ceaba5eb895794220cab51ba6d..e8649b67655ff6a91fd6456c371b50233f4be227 100644 (file)
@@ -295,16 +295,16 @@ FetchDRIDrawable(Display * dpy, GLXDrawable glxDrawable, GLXContext gc)
    if (priv == NULL)
       return NULL;
 
-   psc = &priv->screenConfigs[gc->screen];
-   if (psc->drawHash == NULL)
+   psc = priv->screenConfigs[gc->screen];
+   if (priv->drawHash == NULL)
       return NULL;
 
-   if (__glxHashLookup(psc->drawHash, glxDrawable, (void *) &pdraw) == 0)
+   if (__glxHashLookup(priv->drawHash, glxDrawable, (void *) &pdraw) == 0)
       return pdraw;
 
    pdraw = psc->driScreen->createDrawable(psc, glxDrawable,
                                           glxDrawable, gc->mode);
-   if (__glxHashInsert(psc->drawHash, glxDrawable, pdraw)) {
+   if (__glxHashInsert(priv->drawHash, glxDrawable, pdraw)) {
       (*pdraw->destroyDrawable) (pdraw);
       return NULL;
    }
@@ -399,7 +399,7 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
       }
 
       bindReturnValue =
-         (gc->driContext->bindContext) (gc->driContext, pdraw, pread);
+         (gc->driContext->bindContext) (gc, pdraw, pread);
    }
    else if (!gc && oldGC && oldGC->driContext) {
       bindReturnValue = True;
@@ -441,7 +441,7 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
    }
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
    else if (oldGC->driContext && oldGC != gc) {
-      oldGC->driContext->unbindContext(oldGC->driContext);
+      oldGC->driContext->unbindContext(oldGC);
    }
 #endif
 
@@ -468,34 +468,13 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
          oldGC->currentReadable = None;
          oldGC->currentContextTag = 0;
          oldGC->thread_id = 0;
-#ifdef GLX_USE_APPLEGL
-         
-         /*
-          * At this point we should check if the context has been
-          * through glXDestroyContext, and redestroy it if so.
-          */
-         if(oldGC->do_destroy) {
-            __glXUnlock();
-            /* glXDestroyContext uses the same global lock. */
-            glXDestroyContext(dpy, oldGC);
-            __glXLock();
-#else
+
          if (oldGC->xid == None) {
             /* We are switching away from a context that was
              * previously destroyed, so we need to free the memory
              * for the old handle.
              */
-#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
-            /* Destroy the old direct rendering context */
-            if (oldGC->driContext) {
-               oldGC->driContext->destroyContext(oldGC->driContext,
-                                                 oldGC->psc,
-                                                 oldGC->createDpy);
-               oldGC->driContext = NULL;
-            }
-#endif
-            __glXFreeContext(oldGC);
-#endif /* GLX_USE_APPLEGL */
+           oldGC->vtable->destroy(oldGC);
          }
       }
       if (gc) {
index 69a7b29eb27c7a0e734846f595f66a694d317df4..4a9c9d499e786a5667522057ab0c6dc6cc3027b7 100644 (file)
@@ -68,13 +68,8 @@ _X_HIDDEN int __glXDebug = 0;
 
 /* Extension required boiler plate */
 
-static char *__glXExtensionName = GLX_EXTENSION_NAME;
-#ifdef GLX_USE_APPLEGL
-static XExtensionInfo __glXExtensionInfo_data;
-XExtensionInfo *__glXExtensionInfo = &__glXExtensionInfo_data;
-#else
-XExtensionInfo *__glXExtensionInfo = NULL;
-#endif
+static const char __glXExtensionName[] = GLX_EXTENSION_NAME;
+static __GLXdisplayPrivate *glx_displays;
 
 static /* const */ char *error_list[] = {
    "GLXBadContext",
@@ -92,21 +87,6 @@ static /* const */ char *error_list[] = {
    "GLXBadWindow",
 };
 
-static int
-__glXCloseDisplay(Display * dpy, XExtCodes * codes)
-{
-   GLXContext gc;
-
-   gc = __glXGetCurrentContext();
-   if (dpy == gc->currentDpy) {
-      __glXSetCurrentContextNull();
-      __glXFreeContext(gc);
-   }
-
-   return XextRemoveDisplay(__glXExtensionInfo, dpy);
-}
-
-
 #ifdef GLX_USE_APPLEGL
 static char *__glXErrorString(Display *dpy, int code, XExtCodes *codes, 
                               char *buf, int n);
@@ -115,28 +95,6 @@ static char *__glXErrorString(Display *dpy, int code, XExtCodes *codes,
 static
 XEXT_GENERATE_ERROR_STRING(__glXErrorString, __glXExtensionName,
                            __GLX_NUMBER_ERRORS, error_list)
-static Bool
-__glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire);
-static Status
-__glXEventToWire(Display *dpy, XEvent *event, xEvent *wire);
-
-static /* const */ XExtensionHooks __glXExtensionHooks = {
-  NULL,                   /* create_gc */
-  NULL,                   /* copy_gc */
-  NULL,                   /* flush_gc */
-  NULL,                   /* free_gc */
-  NULL,                   /* create_font */
-  NULL,                   /* free_font */
-  __glXCloseDisplay,      /* close_display */
-  __glXWireToEvent,       /* wire_to_event */
-  __glXEventToWire,       /* event_to_wire */
-  NULL,                   /* error */
-  __glXErrorString,       /* error_string */
-};
-
-XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo,
-                           __glXExtensionName, &__glXExtensionHooks,
-                           __GLX_NUMBER_EVENTS, NULL)
 
 /*
  * GLX events are a bit funky.  We don't stuff the X event code into
@@ -150,11 +108,12 @@ XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo,
 static Bool
 __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
 {
-   XExtDisplayInfo *info = __glXFindDisplay(dpy);
+   __GLXdisplayPrivate *glx_dpy = __glXInitialize(dpy);
 
-   XextCheckExtension(dpy, info, __glXExtensionName, False);
+   if (glx_dpy == NULL)
+      return False;
 
-   switch ((wire->u.u.type & 0x7f) - info->codes->first_event) {
+   switch ((wire->u.u.type & 0x7f) - glx_dpy->codes->first_event) {
    case GLX_PbufferClobber:
    {
       GLXPbufferClobberEvent *aevent = (GLXPbufferClobberEvent *)event;
@@ -209,9 +168,10 @@ __glXWireToEvent(Display *dpy, XEvent *event, xEvent *wire)
 static Status
 __glXEventToWire(Display *dpy, XEvent *event, xEvent *wire)
 {
-   XExtDisplayInfo *info = __glXFindDisplay(dpy);
+   __GLXdisplayPrivate *glx_dpy = __glXInitialize(dpy);
 
-   XextCheckExtension(dpy, info, __glXExtensionName, False);
+   if (glx_dpy == NULL)
+      return False;
 
    switch (event->type) {
    case GLX_DAMAGED:
@@ -244,9 +204,9 @@ FreeScreenConfigs(__GLXdisplayPrivate * priv)
    GLint i, screens;
 
    /* Free screen configuration information */
-   psc = priv->screenConfigs;
    screens = ScreenCount(priv->dpy);
-   for (i = 0; i < screens; i++, psc++) {
+   for (i = 0; i < screens; i++) {
+      psc = priv->screenConfigs[i];
       if (psc->configs) {
          _gl_context_modes_destroy(psc->configs);
          if (psc->effectiveGLXexts)
@@ -260,19 +220,13 @@ FreeScreenConfigs(__GLXdisplayPrivate * priv)
       Xfree((char *) psc->serverGLXexts);
 
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
-      if (psc->driver_configs) {
-         unsigned int j;
-         for (j = 0; psc->driver_configs[j]; j++)
-            free((__DRIconfig *) psc->driver_configs[j]);
-         free(psc->driver_configs);
-         psc->driver_configs = NULL;
-      }
       if (psc->driScreen) {
          psc->driScreen->destroyScreen(psc);
-         __glxHashDestroy(psc->drawHash);
-         XFree(psc->driScreen);
-         psc->driScreen = NULL;
+      } else {
+        Xfree(psc);
       }
+#else
+      Xfree(psc);
 #endif
    }
    XFree((char *) priv->screenConfigs);
@@ -284,20 +238,34 @@ FreeScreenConfigs(__GLXdisplayPrivate * priv)
 ** structure.  The caller will free the extension structure.
 */
 static int
-__glXFreeDisplayPrivate(XExtData * extension)
+__glXCloseDisplay(Display * dpy, XExtCodes * codes)
 {
-   __GLXdisplayPrivate *priv;
+   __GLXdisplayPrivate *priv, **prev;
+   GLXContext gc;
+
+   _XLockMutex(_Xglobal_lock);
+   prev = &glx_displays;
+   for (priv = glx_displays; priv; prev = &priv->next, priv = priv->next) {
+      if (priv->dpy == dpy) {
+        (*prev)->next = priv->next;
+        break;
+      }
+   }
+   _XUnlockMutex(_Xglobal_lock);
+
+   gc = __glXGetCurrentContext();
+   if (dpy == gc->currentDpy) {
+      gc->vtable->destroy(gc);
+      __glXSetCurrentContextNull();
+   }
 
-   priv = (__GLXdisplayPrivate *) extension->private_data;
    FreeScreenConfigs(priv);
-   if (priv->serverGLXvendor) {
+   if (priv->serverGLXvendor)
       Xfree((char *) priv->serverGLXvendor);
-      priv->serverGLXvendor = 0x0;      /* to protect against double free's */
-   }
-   if (priv->serverGLXversion) {
+   if (priv->serverGLXversion)
       Xfree((char *) priv->serverGLXversion);
-      priv->serverGLXversion = 0x0;     /* to protect against double free's */
-   }
+
+   __glxHashDestroy(priv->drawHash);
 
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
    /* Free the direct rendering per display data */
@@ -315,10 +283,9 @@ __glXFreeDisplayPrivate(XExtData * extension)
 #endif
 
    Xfree((char *) priv);
-   return 0;
-}
 
-/************************************************************************/
+   return 1;
+}
 
 /*
 ** Query the version of the GLX extension.  This procedure works even if
@@ -672,15 +639,15 @@ createConfigsFromProperties(Display * dpy, int nvisuals, int nprops,
 }
 
 static GLboolean
-getVisualConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
+getVisualConfigs(__GLXscreenConfigs *psc,
+                __GLXdisplayPrivate *priv, int screen)
 {
    xGLXGetVisualConfigsReq *req;
-   __GLXscreenConfigs *psc;
    xGLXGetVisualConfigsReply reply;
+   Display *dpy = priv->dpy;
 
    LockDisplay(dpy);
 
-   psc = priv->screenConfigs + screen;
    psc->visuals = NULL;
    GetReq(GLXGetVisualConfigs, req);
    req->reqType = priv->majorOpcode;
@@ -701,15 +668,14 @@ getVisualConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
 }
 
 static GLboolean
-getFBConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
+getFBConfigs(__GLXscreenConfigs *psc, __GLXdisplayPrivate *priv, int screen)
 {
    xGLXGetFBConfigsReq *fb_req;
    xGLXGetFBConfigsSGIXReq *sgi_req;
    xGLXVendorPrivateWithReplyReq *vpreq;
    xGLXGetFBConfigsReply reply;
-   __GLXscreenConfigs *psc;
+   Display *dpy = priv->dpy;
 
-   psc = priv->screenConfigs + screen;
    psc->serverGLXexts =
       __glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS);
 
@@ -748,6 +714,22 @@ getFBConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
    return psc->configs != NULL;
 }
 
+_X_HIDDEN Bool
+glx_screen_init(__GLXscreenConfigs *psc,
+               int screen, __GLXdisplayPrivate * priv)
+{
+   /* Initialize per screen dynamic client GLX extensions */
+   psc->ext_list_first_time = GL_TRUE;
+   psc->scr = screen;
+   psc->dpy = priv->dpy;
+   psc->display = priv;
+
+   getVisualConfigs(psc, priv, screen);
+   getFBConfigs(psc, priv, screen);
+
+   return GL_TRUE;
+}
+
 /*
 ** Allocate the memory for the per screen configs for each screen.
 ** If that works then fetch the per screen configs data.
@@ -762,12 +744,9 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
     ** First allocate memory for the array of per screen configs.
     */
    screens = ScreenCount(dpy);
-   psc = (__GLXscreenConfigs *) Xmalloc(screens * sizeof(__GLXscreenConfigs));
-   if (!psc) {
+   priv->screenConfigs = Xmalloc(screens * sizeof *priv->screenConfigs);
+   if (!priv->screenConfigs)
       return GL_FALSE;
-   }
-   memset(psc, 0, screens * sizeof(__GLXscreenConfigs));
-   priv->screenConfigs = psc;
 
    priv->serverGLXversion =
       __glXQueryServerString(dpy, priv->majorOpcode, 0, GLX_VERSION);
@@ -777,33 +756,18 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
    }
 
    for (i = 0; i < screens; i++, psc++) {
-      getVisualConfigs(dpy, priv, i);
-      getFBConfigs(dpy, priv, i);
-
+      psc = NULL;
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
-      psc->scr = i;
-      psc->dpy = dpy;
-      psc->drawHash = __glxHashCreate();
-      if (psc->drawHash == NULL)
-         continue;
-
-      /* Initialize per screen dynamic client GLX extensions */
-      psc->ext_list_first_time = GL_TRUE;
-
       if (priv->dri2Display)
-         psc->driScreen = (*priv->dri2Display->createScreen) (psc, i, priv);
-
-      if (psc->driScreen == NULL && priv->driDisplay)
-         psc->driScreen = (*priv->driDisplay->createScreen) (psc, i, priv);
-
-      if (psc->driScreen == NULL && priv->driswDisplay)
-         psc->driScreen = (*priv->driswDisplay->createScreen) (psc, i, priv);
-
-      if (psc->driScreen == NULL) {
-         __glxHashDestroy(psc->drawHash);
-         psc->drawHash = NULL;
-      }
+        psc = (*priv->dri2Display->createScreen) (i, priv);
+      if (psc == NULL && priv->driDisplay)
+        psc = (*priv->driDisplay->createScreen) (i, priv);
+      if (psc == NULL && priv->driswDisplay)
+        psc = (*priv->driswDisplay->createScreen) (i, priv);
 #endif
+      if (psc == NULL)
+        psc = indirect_create_screen(i, priv);
+      priv->screenConfigs[i] = psc;
    }
    SyncHandle();
    return GL_TRUE;
@@ -815,72 +779,59 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
 _X_HIDDEN __GLXdisplayPrivate *
 __glXInitialize(Display * dpy)
 {
-   XExtDisplayInfo *info = __glXFindDisplay(dpy);
-   XExtData **privList, *private, *found;
    __GLXdisplayPrivate *dpyPriv;
-   XEDataObject dataObj;
-   int major, minor;
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
    Bool glx_direct, glx_accel;
 #endif
+   int i;
 
-   /* The one and only long long lock */
-   __glXLock();
+   _XLockMutex(_Xglobal_lock);
 
-   if (!XextHasExtension(info)) {
-      /* No GLX extension supported by this server. Oh well. */
-      __glXUnlock();
-      XMissingExtension(dpy, __glXExtensionName);
-      return 0;
+   for (dpyPriv = glx_displays; dpyPriv; dpyPriv = dpyPriv->next) {
+      if (dpyPriv->dpy == dpy) {
+        _XUnlockMutex(_Xglobal_lock);
+        return dpyPriv;
+      }
    }
 
-   /* See if a display private already exists.  If so, return it */
-   dataObj.display = dpy;
-   privList = XEHeadOfExtensionList(dataObj);
-   found = XFindOnExtensionList(privList, info->codes->extension);
-   if (found) {
-      __glXUnlock();
-      return (__GLXdisplayPrivate *) found->private_data;
+   dpyPriv = Xcalloc(1, sizeof *dpyPriv);
+   if (!dpyPriv)
+      return NULL;
+
+   dpyPriv->codes = XInitExtension(dpy, __glXExtensionName);
+   if (!dpyPriv->codes) {
+      Xfree(dpyPriv);
+      _XUnlockMutex(_Xglobal_lock);
+      return NULL;
    }
 
+   dpyPriv->dpy = dpy;
+   dpyPriv->majorOpcode = dpyPriv->codes->major_opcode;
+   dpyPriv->serverGLXvendor = 0x0;
+   dpyPriv->serverGLXversion = 0x0;
+
    /* See if the versions are compatible */
-   if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor)) {
-      /* The client and server do not agree on versions.  Punt. */
-      __glXUnlock();
-      return 0;
+   if (!QueryVersion(dpy, dpyPriv->majorOpcode,
+                    &dpyPriv->majorVersion, &dpyPriv->minorVersion)) {
+      Xfree(dpyPriv);
+      _XUnlockMutex(_Xglobal_lock);
+      return NULL;
    }
 
-   /*
-    ** Allocate memory for all the pieces needed for this buffer.
-    */
-   private = (XExtData *) Xmalloc(sizeof(XExtData));
-   if (!private) {
-      __glXUnlock();
-      return 0;
+   for (i = 0; i < __GLX_NUMBER_EVENTS; i++) {
+      XESetWireToEvent(dpy, dpyPriv->codes->first_event + i, __glXWireToEvent);
+      XESetEventToWire(dpy, dpyPriv->codes->first_event + i, __glXEventToWire);
    }
-   dpyPriv = (__GLXdisplayPrivate *) Xcalloc(1, sizeof(__GLXdisplayPrivate));
-   if (!dpyPriv) {
-      __glXUnlock();
-      Xfree((char *) private);
-      return 0;
-   }
-
-   /*
-    ** Init the display private and then read in the screen config
-    ** structures from the server.
-    */
-   dpyPriv->majorOpcode = info->codes->major_opcode;
-   dpyPriv->majorVersion = major;
-   dpyPriv->minorVersion = minor;
-   dpyPriv->dpy = dpy;
 
-   dpyPriv->serverGLXvendor = 0x0;
-   dpyPriv->serverGLXversion = 0x0;
+   XESetCloseDisplay(dpy, dpyPriv->codes->extension, __glXCloseDisplay);
+   XESetErrorString (dpy, dpyPriv->codes->extension,__glXErrorString);
 
 #if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)
    glx_direct = (getenv("LIBGL_ALWAYS_INDIRECT") == NULL);
    glx_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL);
 
+   dpyPriv->drawHash = __glxHashCreate();
+
    /*
     ** Initialize the direct rendering per display data and functions.
     ** Note: This _must_ be done before calling any other DRI routines
@@ -893,32 +844,25 @@ __glXInitialize(Display * dpy)
    if (glx_direct)
       dpyPriv->driswDisplay = driswCreateDisplay(dpy);
 #endif
+
 #ifdef GLX_USE_APPLEGL
-   if (apple_init_glx(dpy) || !AllocAndFetchScreenConfigs(dpy, dpyPriv)) {
-#else
-   if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) {
+   if (apple_init_glx(dpy)) {
+      Xfree(dpyPriv);
+      return NULL;
+   }
 #endif
-      __glXUnlock();
-      Xfree((char *) dpyPriv);
-      Xfree((char *) private);
-      return 0;
+   if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) {
+      Xfree(dpyPriv);
+      return NULL;
    }
 
-   /*
-    ** Fill in the private structure.  This is the actual structure that
-    ** hangs off of the Display structure.  Our private structure is
-    ** referred to by this structure.  Got that?
-    */
-   private->number = info->codes->extension;
-   private->next = 0;
-   private->free_private = __glXFreeDisplayPrivate;
-   private->private_data = (char *) dpyPriv;
-   XAddToExtensionList(privList, private);
-
-   if (dpyPriv->majorVersion == 1 && dpyPriv->minorVersion >= 1) {
+   if (dpyPriv->majorVersion == 1 && dpyPriv->minorVersion >= 1)
       __glXClientInfo(dpy, dpyPriv->majorOpcode);
-   }
-   __glXUnlock();
+
+   dpyPriv->next = glx_displays;
+   glx_displays = dpyPriv;
+
+    _XUnlockMutex(_Xglobal_lock);
 
    return dpyPriv;
 }
index e58c296b30945283742e27cecd0001c5bd59d909..4eb6a5536ab8273ce3363fff1f2744348a6da814 100644 (file)
@@ -85,21 +85,17 @@ static const struct extension_info known_glx_extensions[] = {
    { GLX(EXT_visual_rating),           VER(0,0), Y, Y, N, N },
 #ifdef GLX_USE_APPLEGL
    { GLX(MESA_agp_offset),             VER(0,0), N, N, N, N }, /* Deprecated */
-   { GLX(MESA_allocate_memory),        VER(0,0), N, N, N, N },
    { GLX(MESA_copy_sub_buffer),        VER(0,0), N, N, N, N },
 #else
    { GLX(MESA_agp_offset),             VER(0,0), N, N, N, Y }, /* Deprecated */
-   { GLX(MESA_allocate_memory),        VER(0,0), Y, N, N, Y },
    { GLX(MESA_copy_sub_buffer),        VER(0,0), Y, N, N, N },
 #endif
    { GLX(MESA_pixmap_colormap),        VER(0,0), N, N, N, N }, /* Deprecated */
    { GLX(MESA_release_buffers),        VER(0,0), N, N, N, N }, /* Deprecated */
 #ifdef GLX_USE_APPLEGL
    { GLX(MESA_swap_control),           VER(0,0), N, N, N, N },
-   { GLX(MESA_swap_frame_usage),       VER(0,0), N, N, N, N },
 #else
    { GLX(MESA_swap_control),           VER(0,0), Y, N, N, Y },
-   { GLX(MESA_swap_frame_usage),       VER(0,0), Y, N, N, Y },
 #endif
    { GLX(NV_float_buffer),             VER(0,0), N, N, N, N },
    { GLX(NV_render_depth_texture),     VER(0,0), N, N, N, N },
index f556b1239c9109d9298c0db7e01cc0da1f00113a..4f1b6619d65583328f973bd52608aadbd1f26263 100644 (file)
@@ -41,7 +41,6 @@ enum
    EXT_visual_rating_bit,
    EXT_import_context_bit,
    MESA_agp_offset_bit,
-   MESA_allocate_memory_bit,    /* Replaces MESA_agp_offset & NV_vertex_array_range */
    MESA_copy_sub_buffer_bit,
    MESA_depth_float_bit,
    MESA_pixmap_colormap_bit,
index 797fd7a49004fff157968740d7b5ad1f6415e4ac..db3a57011005be40734667b88f448d0e690e202d 100644 (file)
@@ -212,9 +212,8 @@ isvalid(XFontStruct * fs, int which)
 }
 
 _X_HIDDEN void
-DRI_glXUseXFont(Font font, int first, int count, int listbase)
+DRI_glXUseXFont(GLXContext CC, Font font, int first, int count, int listbase)
 {
-   GLXContext CC;
    Display *dpy;
    Window win;
    Pixmap pixmap;
@@ -231,7 +230,6 @@ DRI_glXUseXFont(Font font, int first, int count, int listbase)
 
    int i;
 
-   CC = __glXGetCurrentContext();
    dpy = CC->currentDpy;
    win = CC->currentDrawable;
 
diff --git a/src/mapi/glapi/gen/ARB_geometry_shader4.xml b/src/mapi/glapi/gen/ARB_geometry_shader4.xml
new file mode 100644 (file)
index 0000000..ca9a101
--- /dev/null
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<!-- Note: no GLX protocol info yet. -->
+
+<OpenGLAPI>
+
+
+<category name="GL_ARB_geometry_shader4" number="47">
+    <enum name="GEOMETRY_SHADER_ARB"              value="0x8DD9"/>
+    <enum name="GEOMETRY_VERTICES_OUT_ARB"        value="0x8DDA"/>
+    <enum name="GEOMETRY_INPUT_TYPE_ARB"          value="0x8DDB"/>
+    <enum name="GEOMETRY_OUTPUT_TYPE_ARB"         value="0x8DDC"/>
+    <enum name="MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB"     value="0x8C29"/>
+    <enum name="MAX_GEOMETRY_VARYING_COMPONENTS_ARB"      value="0x8DDD"/>
+    <enum name="MAX_VERTEX_VARYING_COMPONENTS_ARB"        value="0x8DDE"/>
+    <enum name="MAX_VARYING_COMPONENTS"                   value="0x8B4B"/>
+    <enum name="MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB"      value="0x8DDF"/>
+    <enum name="MAX_GEOMETRY_OUTPUT_VERTICES_ARB"         value="0x8DE0"/>
+    <enum name="MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB" value="0x8DE1"/>
+    <enum name="LINES_ADJACENCY_ARB"          value="0xA"/>
+    <enum name="LINE_STRIP_ADJACENCY_ARB"     value="0xB"/>
+    <enum name="TRIANGLES_ADJACENCY_ARB"      value="0xC"/>
+    <enum name="TRIANGLE_STRIP_ADJACENCY_ARB" value="0xD"/>
+    <enum name="FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB" value="0x8DA8"/>
+    <enum name="FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB"   value="0x8DA9"/>
+    <enum name="FRAMEBUFFER_ATTACHMENT_LAYERED_ARB"   value="0x8DA7"/>
+    <enum name="FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER" value="0x8CD4"/>
+    <enum name="PROGRAM_POINT_SIZE_ARB" value="0x8642"/>
+    <function name="ProgramParameteriARB"  offset="assign">
+        <param name="program" type="GLuint"/>
+        <param name="pname" type="GLenum"/>
+        <param name="value" type="GLint"/>
+    </function>
+    <function name="FramebufferTextureARB"  offset="assign">
+        <param name="target" type="GLenum"/>
+        <param name="attachment" type="GLenum"/>
+        <param name="texture" type="GLuint"/>
+        <param name="level" type="GLint"/>
+    </function>
+    <function name="FramebufferTextureLayerARB" alias="FramebufferTextureLayer">
+        <param name="target" type="GLenum"/>
+        <param name="attachment" type="GLenum"/>
+        <param name="texture" type="GLuint"/>
+        <param name="level" type="GLint"/>
+        <param name="layer" type="GLint"/>
+    </function>
+    <function name="FramebufferTextureFaceARB"  offset="assign">
+        <param name="target" type="GLenum"/>
+        <param name="attachment" type="GLenum"/>
+        <param name="texture" type="GLuint"/>
+        <param name="level" type="GLint"/>
+        <param name="face" type="GLenum"/>
+    </function>
+</category>
+
+</OpenGLAPI>
index daa0a48ddae0ab591d8879872e0fcc7a2f8f8bd6..586c302f1800ec0de621415e2a8a1c7529b2a9b3 100644 (file)
@@ -37,7 +37,7 @@ MESA_OUTPUTS = \
 ######################################################################
 
 XORG_GLX_DIR = $(XORG_BASE)/glx
-XORG_GLAPI_DIR = $(XORG_BASE)/glx/glapi
+XORG_GLAPI_DIR = $(XORG_BASE)/glx
 
 XORG_GLAPI_FILES = \
        $(XORG_GLAPI_DIR)/glapi.h \
@@ -76,6 +76,7 @@ API_XML = \
        ARB_draw_elements_base_vertex.xml \
        ARB_draw_instanced.xml \
        ARB_framebuffer_object.xml \
+       ARB_geometry_shader4.xml \
        ARB_map_buffer_range.xml \
        ARB_seamless_cube_map.xml \
        ARB_sync.xml \
index 31df7a5f80167d85e08bbc4533a0d6260cdfc0c6..71a1a8c01326b75881f3c1915d4964ba9ccbb725 100644 (file)
 
 <xi:include href="ARB_draw_instanced.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
 
+<xi:include href="ARB_geometry_shader4.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
 
 <!-- Non-ARB extensions sorted by extension number. -->
 
index 644e085522962fff04158f745caaa476603ec8a5..0caa01030fade818e0f752583457bfd729a89061 100644 (file)
@@ -105,7 +105,8 @@ const char *_mesa_lookup_enum_by_nr( int nr )
    }
    else {
       /* this is not re-entrant safe, no big deal here */
-      sprintf(token_tmp, "0x%x", nr);
+      _mesa_snprintf(token_tmp, sizeof(token_tmp) - 1, "0x%x", nr);
+      token_tmp[sizeof(token_tmp) - 1] = '\\0';
       return token_tmp;
    }
 }
index e9f887b78f2026175fda1f6619cae4c0902136f8..c353ece567f14b76d9d567ca816487827e84d89f 100644 (file)
@@ -761,6 +761,9 @@ gl_dispatch_functions_start:
        GL_STUB(glGetAttribLocationARB, _gloffset_GetAttribLocationARB)
        GL_STUB(glDrawBuffersARB, _gloffset_DrawBuffersARB)
        GL_STUB(glRenderbufferStorageMultisample, _gloffset_RenderbufferStorageMultisample)
+       GL_STUB(glFramebufferTextureARB, _gloffset_FramebufferTextureARB)
+       GL_STUB(glFramebufferTextureFaceARB, _gloffset_FramebufferTextureFaceARB)
+       GL_STUB(glProgramParameteriARB, _gloffset_ProgramParameteriARB)
        GL_STUB(glFlushMappedBufferRange, _gloffset_FlushMappedBufferRange)
        GL_STUB(glMapBufferRange, _gloffset_MapBufferRange)
        GL_STUB(glBindVertexArray, _gloffset_BindVertexArray)
@@ -776,23 +779,30 @@ gl_dispatch_functions_start:
        GL_STUB(glDrawElementsBaseVertex, _gloffset_DrawElementsBaseVertex)
        GL_STUB(glDrawRangeElementsBaseVertex, _gloffset_DrawRangeElementsBaseVertex)
        GL_STUB(glMultiDrawElementsBaseVertex, _gloffset_MultiDrawElementsBaseVertex)
+       GL_STUB(glBindTransformFeedback, _gloffset_BindTransformFeedback)
+       GL_STUB(glDeleteTransformFeedbacks, _gloffset_DeleteTransformFeedbacks)
+       GL_STUB(glDrawTransformFeedback, _gloffset_DrawTransformFeedback)
+       GL_STUB(glGenTransformFeedbacks, _gloffset_GenTransformFeedbacks)
+       GL_STUB(glIsTransformFeedback, _gloffset_IsTransformFeedback)
+       GL_STUB(glPauseTransformFeedback, _gloffset_PauseTransformFeedback)
+       GL_STUB(glResumeTransformFeedback, _gloffset_ResumeTransformFeedback)
        GL_STUB(glPolygonOffsetEXT, _gloffset_PolygonOffsetEXT)
-       GL_STUB(gl_dispatch_stub_580, _gloffset_GetPixelTexGenParameterfvSGIS)
-       HIDDEN(gl_dispatch_stub_580)
-       GL_STUB(gl_dispatch_stub_581, _gloffset_GetPixelTexGenParameterivSGIS)
-       HIDDEN(gl_dispatch_stub_581)
-       GL_STUB(gl_dispatch_stub_582, _gloffset_PixelTexGenParameterfSGIS)
-       HIDDEN(gl_dispatch_stub_582)
-       GL_STUB(gl_dispatch_stub_583, _gloffset_PixelTexGenParameterfvSGIS)
-       HIDDEN(gl_dispatch_stub_583)
-       GL_STUB(gl_dispatch_stub_584, _gloffset_PixelTexGenParameteriSGIS)
-       HIDDEN(gl_dispatch_stub_584)
-       GL_STUB(gl_dispatch_stub_585, _gloffset_PixelTexGenParameterivSGIS)
-       HIDDEN(gl_dispatch_stub_585)
-       GL_STUB(gl_dispatch_stub_586, _gloffset_SampleMaskSGIS)
-       HIDDEN(gl_dispatch_stub_586)
-       GL_STUB(gl_dispatch_stub_587, _gloffset_SamplePatternSGIS)
-       HIDDEN(gl_dispatch_stub_587)
+       GL_STUB(gl_dispatch_stub_590, _gloffset_GetPixelTexGenParameterfvSGIS)
+       HIDDEN(gl_dispatch_stub_590)
+       GL_STUB(gl_dispatch_stub_591, _gloffset_GetPixelTexGenParameterivSGIS)
+       HIDDEN(gl_dispatch_stub_591)
+       GL_STUB(gl_dispatch_stub_592, _gloffset_PixelTexGenParameterfSGIS)
+       HIDDEN(gl_dispatch_stub_592)
+       GL_STUB(gl_dispatch_stub_593, _gloffset_PixelTexGenParameterfvSGIS)
+       HIDDEN(gl_dispatch_stub_593)
+       GL_STUB(gl_dispatch_stub_594, _gloffset_PixelTexGenParameteriSGIS)
+       HIDDEN(gl_dispatch_stub_594)
+       GL_STUB(gl_dispatch_stub_595, _gloffset_PixelTexGenParameterivSGIS)
+       HIDDEN(gl_dispatch_stub_595)
+       GL_STUB(gl_dispatch_stub_596, _gloffset_SampleMaskSGIS)
+       HIDDEN(gl_dispatch_stub_596)
+       GL_STUB(gl_dispatch_stub_597, _gloffset_SamplePatternSGIS)
+       HIDDEN(gl_dispatch_stub_597)
        GL_STUB(glColorPointerEXT, _gloffset_ColorPointerEXT)
        GL_STUB(glEdgeFlagPointerEXT, _gloffset_EdgeFlagPointerEXT)
        GL_STUB(glIndexPointerEXT, _gloffset_IndexPointerEXT)
@@ -803,10 +813,10 @@ gl_dispatch_functions_start:
        GL_STUB(glPointParameterfvEXT, _gloffset_PointParameterfvEXT)
        GL_STUB(glLockArraysEXT, _gloffset_LockArraysEXT)
        GL_STUB(glUnlockArraysEXT, _gloffset_UnlockArraysEXT)
-       GL_STUB(gl_dispatch_stub_598, _gloffset_CullParameterdvEXT)
-       HIDDEN(gl_dispatch_stub_598)
-       GL_STUB(gl_dispatch_stub_599, _gloffset_CullParameterfvEXT)
-       HIDDEN(gl_dispatch_stub_599)
+       GL_STUB(gl_dispatch_stub_608, _gloffset_CullParameterdvEXT)
+       HIDDEN(gl_dispatch_stub_608)
+       GL_STUB(gl_dispatch_stub_609, _gloffset_CullParameterfvEXT)
+       HIDDEN(gl_dispatch_stub_609)
        GL_STUB(glSecondaryColor3bEXT, _gloffset_SecondaryColor3bEXT)
        GL_STUB(glSecondaryColor3bvEXT, _gloffset_SecondaryColor3bvEXT)
        GL_STUB(glSecondaryColor3dEXT, _gloffset_SecondaryColor3dEXT)
@@ -831,8 +841,8 @@ gl_dispatch_functions_start:
        GL_STUB(glFogCoorddvEXT, _gloffset_FogCoorddvEXT)
        GL_STUB(glFogCoordfEXT, _gloffset_FogCoordfEXT)
        GL_STUB(glFogCoordfvEXT, _gloffset_FogCoordfvEXT)
-       GL_STUB(gl_dispatch_stub_624, _gloffset_PixelTexGenSGIX)
-       HIDDEN(gl_dispatch_stub_624)
+       GL_STUB(gl_dispatch_stub_634, _gloffset_PixelTexGenSGIX)
+       HIDDEN(gl_dispatch_stub_634)
        GL_STUB(glBlendFuncSeparateEXT, _gloffset_BlendFuncSeparateEXT)
        GL_STUB(glFlushVertexArrayRangeNV, _gloffset_FlushVertexArrayRangeNV)
        GL_STUB(glVertexArrayRangeNV, _gloffset_VertexArrayRangeNV)
@@ -874,24 +884,24 @@ gl_dispatch_functions_start:
        GL_STUB(glWindowPos4ivMESA, _gloffset_WindowPos4ivMESA)
        GL_STUB(glWindowPos4sMESA, _gloffset_WindowPos4sMESA)
        GL_STUB(glWindowPos4svMESA, _gloffset_WindowPos4svMESA)
-       GL_STUB(gl_dispatch_stub_666, _gloffset_MultiModeDrawArraysIBM)
-       HIDDEN(gl_dispatch_stub_666)
-       GL_STUB(gl_dispatch_stub_667, _gloffset_MultiModeDrawElementsIBM)
-       HIDDEN(gl_dispatch_stub_667)
-       GL_STUB(gl_dispatch_stub_668, _gloffset_DeleteFencesNV)
-       HIDDEN(gl_dispatch_stub_668)
-       GL_STUB(gl_dispatch_stub_669, _gloffset_FinishFenceNV)
-       HIDDEN(gl_dispatch_stub_669)
-       GL_STUB(gl_dispatch_stub_670, _gloffset_GenFencesNV)
-       HIDDEN(gl_dispatch_stub_670)
-       GL_STUB(gl_dispatch_stub_671, _gloffset_GetFenceivNV)
-       HIDDEN(gl_dispatch_stub_671)
-       GL_STUB(gl_dispatch_stub_672, _gloffset_IsFenceNV)
-       HIDDEN(gl_dispatch_stub_672)
-       GL_STUB(gl_dispatch_stub_673, _gloffset_SetFenceNV)
-       HIDDEN(gl_dispatch_stub_673)
-       GL_STUB(gl_dispatch_stub_674, _gloffset_TestFenceNV)
-       HIDDEN(gl_dispatch_stub_674)
+       GL_STUB(gl_dispatch_stub_676, _gloffset_MultiModeDrawArraysIBM)
+       HIDDEN(gl_dispatch_stub_676)
+       GL_STUB(gl_dispatch_stub_677, _gloffset_MultiModeDrawElementsIBM)
+       HIDDEN(gl_dispatch_stub_677)
+       GL_STUB(gl_dispatch_stub_678, _gloffset_DeleteFencesNV)
+       HIDDEN(gl_dispatch_stub_678)
+       GL_STUB(gl_dispatch_stub_679, _gloffset_FinishFenceNV)
+       HIDDEN(gl_dispatch_stub_679)
+       GL_STUB(gl_dispatch_stub_680, _gloffset_GenFencesNV)
+       HIDDEN(gl_dispatch_stub_680)
+       GL_STUB(gl_dispatch_stub_681, _gloffset_GetFenceivNV)
+       HIDDEN(gl_dispatch_stub_681)
+       GL_STUB(gl_dispatch_stub_682, _gloffset_IsFenceNV)
+       HIDDEN(gl_dispatch_stub_682)
+       GL_STUB(gl_dispatch_stub_683, _gloffset_SetFenceNV)
+       HIDDEN(gl_dispatch_stub_683)
+       GL_STUB(gl_dispatch_stub_684, _gloffset_TestFenceNV)
+       HIDDEN(gl_dispatch_stub_684)
        GL_STUB(glAreProgramsResidentNV, _gloffset_AreProgramsResidentNV)
        GL_STUB(glBindProgramNV, _gloffset_BindProgramNV)
        GL_STUB(glDeleteProgramsNV, _gloffset_DeleteProgramsNV)
@@ -972,26 +982,26 @@ gl_dispatch_functions_start:
        GL_STUB(glSetFragmentShaderConstantATI, _gloffset_SetFragmentShaderConstantATI)
        GL_STUB(glPointParameteriNV, _gloffset_PointParameteriNV)
        GL_STUB(glPointParameterivNV, _gloffset_PointParameterivNV)
-       GL_STUB(gl_dispatch_stub_755, _gloffset_ActiveStencilFaceEXT)
-       HIDDEN(gl_dispatch_stub_755)
-       GL_STUB(gl_dispatch_stub_756, _gloffset_BindVertexArrayAPPLE)
-       HIDDEN(gl_dispatch_stub_756)
-       GL_STUB(gl_dispatch_stub_757, _gloffset_DeleteVertexArraysAPPLE)
-       HIDDEN(gl_dispatch_stub_757)
-       GL_STUB(gl_dispatch_stub_758, _gloffset_GenVertexArraysAPPLE)
-       HIDDEN(gl_dispatch_stub_758)
-       GL_STUB(gl_dispatch_stub_759, _gloffset_IsVertexArrayAPPLE)
-       HIDDEN(gl_dispatch_stub_759)
+       GL_STUB(gl_dispatch_stub_765, _gloffset_ActiveStencilFaceEXT)
+       HIDDEN(gl_dispatch_stub_765)
+       GL_STUB(gl_dispatch_stub_766, _gloffset_BindVertexArrayAPPLE)
+       HIDDEN(gl_dispatch_stub_766)
+       GL_STUB(gl_dispatch_stub_767, _gloffset_DeleteVertexArraysAPPLE)
+       HIDDEN(gl_dispatch_stub_767)
+       GL_STUB(gl_dispatch_stub_768, _gloffset_GenVertexArraysAPPLE)
+       HIDDEN(gl_dispatch_stub_768)
+       GL_STUB(gl_dispatch_stub_769, _gloffset_IsVertexArrayAPPLE)
+       HIDDEN(gl_dispatch_stub_769)
        GL_STUB(glGetProgramNamedParameterdvNV, _gloffset_GetProgramNamedParameterdvNV)
        GL_STUB(glGetProgramNamedParameterfvNV, _gloffset_GetProgramNamedParameterfvNV)
        GL_STUB(glProgramNamedParameter4dNV, _gloffset_ProgramNamedParameter4dNV)
        GL_STUB(glProgramNamedParameter4dvNV, _gloffset_ProgramNamedParameter4dvNV)
        GL_STUB(glProgramNamedParameter4fNV, _gloffset_ProgramNamedParameter4fNV)
        GL_STUB(glProgramNamedParameter4fvNV, _gloffset_ProgramNamedParameter4fvNV)
-       GL_STUB(gl_dispatch_stub_766, _gloffset_DepthBoundsEXT)
-       HIDDEN(gl_dispatch_stub_766)
-       GL_STUB(gl_dispatch_stub_767, _gloffset_BlendEquationSeparateEXT)
-       HIDDEN(gl_dispatch_stub_767)
+       GL_STUB(gl_dispatch_stub_776, _gloffset_DepthBoundsEXT)
+       HIDDEN(gl_dispatch_stub_776)
+       GL_STUB(gl_dispatch_stub_777, _gloffset_BlendEquationSeparateEXT)
+       HIDDEN(gl_dispatch_stub_777)
        GL_STUB(glBindFramebufferEXT, _gloffset_BindFramebufferEXT)
        GL_STUB(glBindRenderbufferEXT, _gloffset_BindRenderbufferEXT)
        GL_STUB(glCheckFramebufferStatusEXT, _gloffset_CheckFramebufferStatusEXT)
@@ -1009,12 +1019,12 @@ gl_dispatch_functions_start:
        GL_STUB(glIsFramebufferEXT, _gloffset_IsFramebufferEXT)
        GL_STUB(glIsRenderbufferEXT, _gloffset_IsRenderbufferEXT)
        GL_STUB(glRenderbufferStorageEXT, _gloffset_RenderbufferStorageEXT)
-       GL_STUB(gl_dispatch_stub_785, _gloffset_BlitFramebufferEXT)
-       HIDDEN(gl_dispatch_stub_785)
-       GL_STUB(gl_dispatch_stub_786, _gloffset_BufferParameteriAPPLE)
-       HIDDEN(gl_dispatch_stub_786)
-       GL_STUB(gl_dispatch_stub_787, _gloffset_FlushMappedBufferRangeAPPLE)
-       HIDDEN(gl_dispatch_stub_787)
+       GL_STUB(gl_dispatch_stub_795, _gloffset_BlitFramebufferEXT)
+       HIDDEN(gl_dispatch_stub_795)
+       GL_STUB(gl_dispatch_stub_796, _gloffset_BufferParameteriAPPLE)
+       HIDDEN(gl_dispatch_stub_796)
+       GL_STUB(gl_dispatch_stub_797, _gloffset_FlushMappedBufferRangeAPPLE)
+       HIDDEN(gl_dispatch_stub_797)
        GL_STUB(glFramebufferTextureLayerEXT, _gloffset_FramebufferTextureLayerEXT)
        GL_STUB(glColorMaskIndexedEXT, _gloffset_ColorMaskIndexedEXT)
        GL_STUB(glDisableIndexedEXT, _gloffset_DisableIndexedEXT)
@@ -1032,23 +1042,23 @@ gl_dispatch_functions_start:
        GL_STUB(glGetTransformFeedbackVaryingEXT, _gloffset_GetTransformFeedbackVaryingEXT)
        GL_STUB(glTransformFeedbackVaryingsEXT, _gloffset_TransformFeedbackVaryingsEXT)
        GL_STUB(glProvokingVertexEXT, _gloffset_ProvokingVertexEXT)
-       GL_STUB(gl_dispatch_stub_805, _gloffset_GetTexParameterPointervAPPLE)
-       HIDDEN(gl_dispatch_stub_805)
-       GL_STUB(gl_dispatch_stub_806, _gloffset_TextureRangeAPPLE)
-       HIDDEN(gl_dispatch_stub_806)
+       GL_STUB(gl_dispatch_stub_815, _gloffset_GetTexParameterPointervAPPLE)
+       HIDDEN(gl_dispatch_stub_815)
+       GL_STUB(gl_dispatch_stub_816, _gloffset_TextureRangeAPPLE)
+       HIDDEN(gl_dispatch_stub_816)
        GL_STUB(glGetObjectParameterivAPPLE, _gloffset_GetObjectParameterivAPPLE)
        GL_STUB(glObjectPurgeableAPPLE, _gloffset_ObjectPurgeableAPPLE)
        GL_STUB(glObjectUnpurgeableAPPLE, _gloffset_ObjectUnpurgeableAPPLE)
-       GL_STUB(gl_dispatch_stub_810, _gloffset_StencilFuncSeparateATI)
-       HIDDEN(gl_dispatch_stub_810)
-       GL_STUB(gl_dispatch_stub_811, _gloffset_ProgramEnvParameters4fvEXT)
-       HIDDEN(gl_dispatch_stub_811)
-       GL_STUB(gl_dispatch_stub_812, _gloffset_ProgramLocalParameters4fvEXT)
-       HIDDEN(gl_dispatch_stub_812)
-       GL_STUB(gl_dispatch_stub_813, _gloffset_GetQueryObjecti64vEXT)
-       HIDDEN(gl_dispatch_stub_813)
-       GL_STUB(gl_dispatch_stub_814, _gloffset_GetQueryObjectui64vEXT)
-       HIDDEN(gl_dispatch_stub_814)
+       GL_STUB(gl_dispatch_stub_820, _gloffset_StencilFuncSeparateATI)
+       HIDDEN(gl_dispatch_stub_820)
+       GL_STUB(gl_dispatch_stub_821, _gloffset_ProgramEnvParameters4fvEXT)
+       HIDDEN(gl_dispatch_stub_821)
+       GL_STUB(gl_dispatch_stub_822, _gloffset_ProgramLocalParameters4fvEXT)
+       HIDDEN(gl_dispatch_stub_822)
+       GL_STUB(gl_dispatch_stub_823, _gloffset_GetQueryObjecti64vEXT)
+       HIDDEN(gl_dispatch_stub_823)
+       GL_STUB(gl_dispatch_stub_824, _gloffset_GetQueryObjectui64vEXT)
+       HIDDEN(gl_dispatch_stub_824)
        GL_STUB(glEGLImageTargetRenderbufferStorageOES, _gloffset_EGLImageTargetRenderbufferStorageOES)
        GL_STUB(glEGLImageTargetTexture2DOES, _gloffset_EGLImageTargetTexture2DOES)
        GL_STUB_ALIAS(glArrayElementEXT, glArrayElement)
index 96930162175d0f839b5637af87e1d7389b20b9a2..8cfd815a500145530eba03a63026a8519c4dca3d 100644 (file)
@@ -21247,9 +21247,9 @@ GL_PREFIX(RenderbufferStorageMultisample):
        .size   GL_PREFIX(RenderbufferStorageMultisample), .-GL_PREFIX(RenderbufferStorageMultisample)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(FlushMappedBufferRange)
-       .type   GL_PREFIX(FlushMappedBufferRange), @function
-GL_PREFIX(FlushMappedBufferRange):
+       .globl  GL_PREFIX(FramebufferTextureARB)
+       .type   GL_PREFIX(FramebufferTextureARB), @function
+GL_PREFIX(FramebufferTextureARB):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
        movq    4512(%rax), %r11
@@ -21258,7 +21258,11 @@ GL_PREFIX(FlushMappedBufferRange):
        pushq   %rdi
        pushq   %rsi
        pushq   %rdx
+       pushq   %rcx
+       pushq   %rbp
        call    _x86_64_get_dispatch@PLT
+       popq    %rbp
+       popq    %rcx
        popq    %rdx
        popq    %rsi
        popq    %rdi
@@ -21274,12 +21278,135 @@ GL_PREFIX(FlushMappedBufferRange):
        pushq   %rdi
        pushq   %rsi
        pushq   %rdx
+       pushq   %rcx
+       pushq   %rbp
        call    _glapi_get_dispatch
+       popq    %rbp
+       popq    %rcx
        popq    %rdx
        popq    %rsi
        popq    %rdi
        movq    4512(%rax), %r11
        jmp     *%r11
+#endif /* defined(GLX_USE_TLS) */
+       .size   GL_PREFIX(FramebufferTextureARB), .-GL_PREFIX(FramebufferTextureARB)
+
+       .p2align        4,,15
+       .globl  GL_PREFIX(FramebufferTextureFaceARB)
+       .type   GL_PREFIX(FramebufferTextureFaceARB), @function
+GL_PREFIX(FramebufferTextureFaceARB):
+#if defined(GLX_USE_TLS)
+       call    _x86_64_get_dispatch@PLT
+       movq    4520(%rax), %r11
+       jmp     *%r11
+#elif defined(PTHREADS)
+       pushq   %rdi
+       pushq   %rsi
+       pushq   %rdx
+       pushq   %rcx
+       pushq   %r8
+       call    _x86_64_get_dispatch@PLT
+       popq    %r8
+       popq    %rcx
+       popq    %rdx
+       popq    %rsi
+       popq    %rdi
+       movq    4520(%rax), %r11
+       jmp     *%r11
+#else
+       movq    _glapi_Dispatch(%rip), %rax
+       testq   %rax, %rax
+       je      1f
+       movq    4520(%rax), %r11
+       jmp     *%r11
+1:
+       pushq   %rdi
+       pushq   %rsi
+       pushq   %rdx
+       pushq   %rcx
+       pushq   %r8
+       call    _glapi_get_dispatch
+       popq    %r8
+       popq    %rcx
+       popq    %rdx
+       popq    %rsi
+       popq    %rdi
+       movq    4520(%rax), %r11
+       jmp     *%r11
+#endif /* defined(GLX_USE_TLS) */
+       .size   GL_PREFIX(FramebufferTextureFaceARB), .-GL_PREFIX(FramebufferTextureFaceARB)
+
+       .p2align        4,,15
+       .globl  GL_PREFIX(ProgramParameteriARB)
+       .type   GL_PREFIX(ProgramParameteriARB), @function
+GL_PREFIX(ProgramParameteriARB):
+#if defined(GLX_USE_TLS)
+       call    _x86_64_get_dispatch@PLT
+       movq    4528(%rax), %r11
+       jmp     *%r11
+#elif defined(PTHREADS)
+       pushq   %rdi
+       pushq   %rsi
+       pushq   %rdx
+       call    _x86_64_get_dispatch@PLT
+       popq    %rdx
+       popq    %rsi
+       popq    %rdi
+       movq    4528(%rax), %r11
+       jmp     *%r11
+#else
+       movq    _glapi_Dispatch(%rip), %rax
+       testq   %rax, %rax
+       je      1f
+       movq    4528(%rax), %r11
+       jmp     *%r11
+1:
+       pushq   %rdi
+       pushq   %rsi
+       pushq   %rdx
+       call    _glapi_get_dispatch
+       popq    %rdx
+       popq    %rsi
+       popq    %rdi
+       movq    4528(%rax), %r11
+       jmp     *%r11
+#endif /* defined(GLX_USE_TLS) */
+       .size   GL_PREFIX(ProgramParameteriARB), .-GL_PREFIX(ProgramParameteriARB)
+
+       .p2align        4,,15
+       .globl  GL_PREFIX(FlushMappedBufferRange)
+       .type   GL_PREFIX(FlushMappedBufferRange), @function
+GL_PREFIX(FlushMappedBufferRange):
+#if defined(GLX_USE_TLS)
+       call    _x86_64_get_dispatch@PLT
+       movq    4536(%rax), %r11
+       jmp     *%r11
+#elif defined(PTHREADS)
+       pushq   %rdi
+       pushq   %rsi
+       pushq   %rdx
+       call    _x86_64_get_dispatch@PLT
+       popq    %rdx
+       popq    %rsi
+       popq    %rdi
+       movq    4536(%rax), %r11
+       jmp     *%r11
+#else
+       movq    _glapi_Dispatch(%rip), %rax
+       testq   %rax, %rax
+       je      1f
+       movq    4536(%rax), %r11
+       jmp     *%r11
+1:
+       pushq   %rdi
+       pushq   %rsi
+       pushq   %rdx
+       call    _glapi_get_dispatch
+       popq    %rdx
+       popq    %rsi
+       popq    %rdi
+       movq    4536(%rax), %r11
+       jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(FlushMappedBufferRange), .-GL_PREFIX(FlushMappedBufferRange)
 
@@ -21289,7 +21416,7 @@ GL_PREFIX(FlushMappedBufferRange):
 GL_PREFIX(MapBufferRange):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4520(%rax), %r11
+       movq    4544(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -21303,13 +21430,13 @@ GL_PREFIX(MapBufferRange):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4520(%rax), %r11
+       movq    4544(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4520(%rax), %r11
+       movq    4544(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -21323,7 +21450,7 @@ GL_PREFIX(MapBufferRange):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4520(%rax), %r11
+       movq    4544(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(MapBufferRange), .-GL_PREFIX(MapBufferRange)
@@ -21334,25 +21461,25 @@ GL_PREFIX(MapBufferRange):
 GL_PREFIX(BindVertexArray):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4528(%rax), %r11
+       movq    4552(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    4528(%rax), %r11
+       movq    4552(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4528(%rax), %r11
+       movq    4552(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    4528(%rax), %r11
+       movq    4552(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(BindVertexArray), .-GL_PREFIX(BindVertexArray)
@@ -21363,7 +21490,7 @@ GL_PREFIX(BindVertexArray):
 GL_PREFIX(GenVertexArrays):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4536(%rax), %r11
+       movq    4560(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -21373,13 +21500,13 @@ GL_PREFIX(GenVertexArrays):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4536(%rax), %r11
+       movq    4560(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4536(%rax), %r11
+       movq    4560(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -21389,7 +21516,7 @@ GL_PREFIX(GenVertexArrays):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4536(%rax), %r11
+       movq    4560(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GenVertexArrays), .-GL_PREFIX(GenVertexArrays)
@@ -21400,7 +21527,7 @@ GL_PREFIX(GenVertexArrays):
 GL_PREFIX(CopyBufferSubData):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4544(%rax), %r11
+       movq    4568(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -21414,13 +21541,13 @@ GL_PREFIX(CopyBufferSubData):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4544(%rax), %r11
+       movq    4568(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4544(%rax), %r11
+       movq    4568(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -21434,7 +21561,7 @@ GL_PREFIX(CopyBufferSubData):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4544(%rax), %r11
+       movq    4568(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(CopyBufferSubData), .-GL_PREFIX(CopyBufferSubData)
@@ -21445,7 +21572,7 @@ GL_PREFIX(CopyBufferSubData):
 GL_PREFIX(ClientWaitSync):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4552(%rax), %r11
+       movq    4576(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -21455,13 +21582,13 @@ GL_PREFIX(ClientWaitSync):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4552(%rax), %r11
+       movq    4576(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4552(%rax), %r11
+       movq    4576(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -21471,7 +21598,7 @@ GL_PREFIX(ClientWaitSync):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4552(%rax), %r11
+       movq    4576(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(ClientWaitSync), .-GL_PREFIX(ClientWaitSync)
@@ -21482,25 +21609,25 @@ GL_PREFIX(ClientWaitSync):
 GL_PREFIX(DeleteSync):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4560(%rax), %r11
+       movq    4584(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    4560(%rax), %r11
+       movq    4584(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4560(%rax), %r11
+       movq    4584(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    4560(%rax), %r11
+       movq    4584(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(DeleteSync), .-GL_PREFIX(DeleteSync)
@@ -21511,7 +21638,7 @@ GL_PREFIX(DeleteSync):
 GL_PREFIX(FenceSync):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4568(%rax), %r11
+       movq    4592(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -21521,13 +21648,13 @@ GL_PREFIX(FenceSync):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4568(%rax), %r11
+       movq    4592(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4568(%rax), %r11
+       movq    4592(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -21537,7 +21664,7 @@ GL_PREFIX(FenceSync):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4568(%rax), %r11
+       movq    4592(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(FenceSync), .-GL_PREFIX(FenceSync)
@@ -21548,7 +21675,7 @@ GL_PREFIX(FenceSync):
 GL_PREFIX(GetInteger64v):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4576(%rax), %r11
+       movq    4600(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -21558,13 +21685,13 @@ GL_PREFIX(GetInteger64v):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4576(%rax), %r11
+       movq    4600(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4576(%rax), %r11
+       movq    4600(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -21574,7 +21701,7 @@ GL_PREFIX(GetInteger64v):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4576(%rax), %r11
+       movq    4600(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetInteger64v), .-GL_PREFIX(GetInteger64v)
@@ -21585,7 +21712,7 @@ GL_PREFIX(GetInteger64v):
 GL_PREFIX(GetSynciv):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4584(%rax), %r11
+       movq    4608(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -21599,13 +21726,13 @@ GL_PREFIX(GetSynciv):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4584(%rax), %r11
+       movq    4608(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4584(%rax), %r11
+       movq    4608(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -21619,7 +21746,7 @@ GL_PREFIX(GetSynciv):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4584(%rax), %r11
+       movq    4608(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetSynciv), .-GL_PREFIX(GetSynciv)
@@ -21630,25 +21757,25 @@ GL_PREFIX(GetSynciv):
 GL_PREFIX(IsSync):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4592(%rax), %r11
+       movq    4616(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    4592(%rax), %r11
+       movq    4616(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4592(%rax), %r11
+       movq    4616(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    4592(%rax), %r11
+       movq    4616(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(IsSync), .-GL_PREFIX(IsSync)
@@ -21659,7 +21786,7 @@ GL_PREFIX(IsSync):
 GL_PREFIX(WaitSync):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4600(%rax), %r11
+       movq    4624(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -21669,13 +21796,13 @@ GL_PREFIX(WaitSync):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4600(%rax), %r11
+       movq    4624(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4600(%rax), %r11
+       movq    4624(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -21685,7 +21812,7 @@ GL_PREFIX(WaitSync):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4600(%rax), %r11
+       movq    4624(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WaitSync), .-GL_PREFIX(WaitSync)
@@ -21696,7 +21823,7 @@ GL_PREFIX(WaitSync):
 GL_PREFIX(DrawElementsBaseVertex):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4608(%rax), %r11
+       movq    4632(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -21710,13 +21837,13 @@ GL_PREFIX(DrawElementsBaseVertex):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4608(%rax), %r11
+       movq    4632(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4608(%rax), %r11
+       movq    4632(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -21730,7 +21857,7 @@ GL_PREFIX(DrawElementsBaseVertex):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4608(%rax), %r11
+       movq    4632(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(DrawElementsBaseVertex), .-GL_PREFIX(DrawElementsBaseVertex)
@@ -21741,7 +21868,7 @@ GL_PREFIX(DrawElementsBaseVertex):
 GL_PREFIX(DrawRangeElementsBaseVertex):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4616(%rax), %r11
+       movq    4640(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -21759,13 +21886,13 @@ GL_PREFIX(DrawRangeElementsBaseVertex):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4616(%rax), %r11
+       movq    4640(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4616(%rax), %r11
+       movq    4640(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -21783,7 +21910,7 @@ GL_PREFIX(DrawRangeElementsBaseVertex):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4616(%rax), %r11
+       movq    4640(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(DrawRangeElementsBaseVertex), .-GL_PREFIX(DrawRangeElementsBaseVertex)
@@ -21794,7 +21921,7 @@ GL_PREFIX(DrawRangeElementsBaseVertex):
 GL_PREFIX(MultiDrawElementsBaseVertex):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4624(%rax), %r11
+       movq    4648(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -21812,13 +21939,13 @@ GL_PREFIX(MultiDrawElementsBaseVertex):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4624(%rax), %r11
+       movq    4648(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4624(%rax), %r11
+       movq    4648(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -21836,56 +21963,291 @@ GL_PREFIX(MultiDrawElementsBaseVertex):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4624(%rax), %r11
+       movq    4648(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(MultiDrawElementsBaseVertex), .-GL_PREFIX(MultiDrawElementsBaseVertex)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(PolygonOffsetEXT)
-       .type   GL_PREFIX(PolygonOffsetEXT), @function
-GL_PREFIX(PolygonOffsetEXT):
+       .globl  GL_PREFIX(BindTransformFeedback)
+       .type   GL_PREFIX(BindTransformFeedback), @function
+GL_PREFIX(BindTransformFeedback):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4632(%rax), %r11
+       movq    4656(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
-       subq    $24, %rsp
-       movq    %xmm0, (%rsp)
-       movq    %xmm1, 8(%rsp)
+       pushq   %rdi
+       pushq   %rsi
+       pushq   %rbp
        call    _x86_64_get_dispatch@PLT
-       movq    8(%rsp), %xmm1
-       movq    (%rsp), %xmm0
-       addq    $24, %rsp
-       movq    4632(%rax), %r11
+       popq    %rbp
+       popq    %rsi
+       popq    %rdi
+       movq    4656(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4632(%rax), %r11
+       movq    4656(%rax), %r11
        jmp     *%r11
 1:
-       subq    $24, %rsp
-       movq    %xmm0, (%rsp)
+       pushq   %rdi
+       pushq   %rsi
+       pushq   %rbp
+       call    _glapi_get_dispatch
+       popq    %rbp
+       popq    %rsi
+       popq    %rdi
+       movq    4656(%rax), %r11
+       jmp     *%r11
+#endif /* defined(GLX_USE_TLS) */
+       .size   GL_PREFIX(BindTransformFeedback), .-GL_PREFIX(BindTransformFeedback)
+
+       .p2align        4,,15
+       .globl  GL_PREFIX(DeleteTransformFeedbacks)
+       .type   GL_PREFIX(DeleteTransformFeedbacks), @function
+GL_PREFIX(DeleteTransformFeedbacks):
+#if defined(GLX_USE_TLS)
+       call    _x86_64_get_dispatch@PLT
+       movq    4664(%rax), %r11
+       jmp     *%r11
+#elif defined(PTHREADS)
+       pushq   %rdi
+       pushq   %rsi
+       pushq   %rbp
+       call    _x86_64_get_dispatch@PLT
+       popq    %rbp
+       popq    %rsi
+       popq    %rdi
+       movq    4664(%rax), %r11
+       jmp     *%r11
+#else
+       movq    _glapi_Dispatch(%rip), %rax
+       testq   %rax, %rax
+       je      1f
+       movq    4664(%rax), %r11
+       jmp     *%r11
+1:
+       pushq   %rdi
+       pushq   %rsi
+       pushq   %rbp
+       call    _glapi_get_dispatch
+       popq    %rbp
+       popq    %rsi
+       popq    %rdi
+       movq    4664(%rax), %r11
+       jmp     *%r11
+#endif /* defined(GLX_USE_TLS) */
+       .size   GL_PREFIX(DeleteTransformFeedbacks), .-GL_PREFIX(DeleteTransformFeedbacks)
+
+       .p2align        4,,15
+       .globl  GL_PREFIX(DrawTransformFeedback)
+       .type   GL_PREFIX(DrawTransformFeedback), @function
+GL_PREFIX(DrawTransformFeedback):
+#if defined(GLX_USE_TLS)
+       call    _x86_64_get_dispatch@PLT
+       movq    4672(%rax), %r11
+       jmp     *%r11
+#elif defined(PTHREADS)
+       pushq   %rdi
+       pushq   %rsi
+       pushq   %rbp
+       call    _x86_64_get_dispatch@PLT
+       popq    %rbp
+       popq    %rsi
+       popq    %rdi
+       movq    4672(%rax), %r11
+       jmp     *%r11
+#else
+       movq    _glapi_Dispatch(%rip), %rax
+       testq   %rax, %rax
+       je      1f
+       movq    4672(%rax), %r11
+       jmp     *%r11
+1:
+       pushq   %rdi
+       pushq   %rsi
+       pushq   %rbp
+       call    _glapi_get_dispatch
+       popq    %rbp
+       popq    %rsi
+       popq    %rdi
+       movq    4672(%rax), %r11
+       jmp     *%r11
+#endif /* defined(GLX_USE_TLS) */
+       .size   GL_PREFIX(DrawTransformFeedback), .-GL_PREFIX(DrawTransformFeedback)
+
+       .p2align        4,,15
+       .globl  GL_PREFIX(GenTransformFeedbacks)
+       .type   GL_PREFIX(GenTransformFeedbacks), @function
+GL_PREFIX(GenTransformFeedbacks):
+#if defined(GLX_USE_TLS)
+       call    _x86_64_get_dispatch@PLT
+       movq    4680(%rax), %r11
+       jmp     *%r11
+#elif defined(PTHREADS)
+       pushq   %rdi
+       pushq   %rsi
+       pushq   %rbp
+       call    _x86_64_get_dispatch@PLT
+       popq    %rbp
+       popq    %rsi
+       popq    %rdi
+       movq    4680(%rax), %r11
+       jmp     *%r11
+#else
+       movq    _glapi_Dispatch(%rip), %rax
+       testq   %rax, %rax
+       je      1f
+       movq    4680(%rax), %r11
+       jmp     *%r11
+1:
+       pushq   %rdi
+       pushq   %rsi
+       pushq   %rbp
+       call    _glapi_get_dispatch
+       popq    %rbp
+       popq    %rsi
+       popq    %rdi
+       movq    4680(%rax), %r11
+       jmp     *%r11
+#endif /* defined(GLX_USE_TLS) */
+       .size   GL_PREFIX(GenTransformFeedbacks), .-GL_PREFIX(GenTransformFeedbacks)
+
+       .p2align        4,,15
+       .globl  GL_PREFIX(IsTransformFeedback)
+       .type   GL_PREFIX(IsTransformFeedback), @function
+GL_PREFIX(IsTransformFeedback):
+#if defined(GLX_USE_TLS)
+       call    _x86_64_get_dispatch@PLT
+       movq    4688(%rax), %r11
+       jmp     *%r11
+#elif defined(PTHREADS)
+       pushq   %rdi
+       call    _x86_64_get_dispatch@PLT
+       popq    %rdi
+       movq    4688(%rax), %r11
+       jmp     *%r11
+#else
+       movq    _glapi_Dispatch(%rip), %rax
+       testq   %rax, %rax
+       je      1f
+       movq    4688(%rax), %r11
+       jmp     *%r11
+1:
+       pushq   %rdi
+       call    _glapi_get_dispatch
+       popq    %rdi
+       movq    4688(%rax), %r11
+       jmp     *%r11
+#endif /* defined(GLX_USE_TLS) */
+       .size   GL_PREFIX(IsTransformFeedback), .-GL_PREFIX(IsTransformFeedback)
+
+       .p2align        4,,15
+       .globl  GL_PREFIX(PauseTransformFeedback)
+       .type   GL_PREFIX(PauseTransformFeedback), @function
+GL_PREFIX(PauseTransformFeedback):
+#if defined(GLX_USE_TLS)
+       call    _x86_64_get_dispatch@PLT
+       movq    4696(%rax), %r11
+       jmp     *%r11
+#elif defined(PTHREADS)
+       pushq   %rbp
+       call    _x86_64_get_dispatch@PLT
+       popq    %rbp
+       movq    4696(%rax), %r11
+       jmp     *%r11
+#else
+       movq    _glapi_Dispatch(%rip), %rax
+       testq   %rax, %rax
+       je      1f
+       movq    4696(%rax), %r11
+       jmp     *%r11
+1:
+       pushq   %rbp
+       call    _glapi_get_dispatch
+       popq    %rbp
+       movq    4696(%rax), %r11
+       jmp     *%r11
+#endif /* defined(GLX_USE_TLS) */
+       .size   GL_PREFIX(PauseTransformFeedback), .-GL_PREFIX(PauseTransformFeedback)
+
+       .p2align        4,,15
+       .globl  GL_PREFIX(ResumeTransformFeedback)
+       .type   GL_PREFIX(ResumeTransformFeedback), @function
+GL_PREFIX(ResumeTransformFeedback):
+#if defined(GLX_USE_TLS)
+       call    _x86_64_get_dispatch@PLT
+       movq    4704(%rax), %r11
+       jmp     *%r11
+#elif defined(PTHREADS)
+       pushq   %rbp
+       call    _x86_64_get_dispatch@PLT
+       popq    %rbp
+       movq    4704(%rax), %r11
+       jmp     *%r11
+#else
+       movq    _glapi_Dispatch(%rip), %rax
+       testq   %rax, %rax
+       je      1f
+       movq    4704(%rax), %r11
+       jmp     *%r11
+1:
+       pushq   %rbp
+       call    _glapi_get_dispatch
+       popq    %rbp
+       movq    4704(%rax), %r11
+       jmp     *%r11
+#endif /* defined(GLX_USE_TLS) */
+       .size   GL_PREFIX(ResumeTransformFeedback), .-GL_PREFIX(ResumeTransformFeedback)
+
+       .p2align        4,,15
+       .globl  GL_PREFIX(PolygonOffsetEXT)
+       .type   GL_PREFIX(PolygonOffsetEXT), @function
+GL_PREFIX(PolygonOffsetEXT):
+#if defined(GLX_USE_TLS)
+       call    _x86_64_get_dispatch@PLT
+       movq    4712(%rax), %r11
+       jmp     *%r11
+#elif defined(PTHREADS)
+       subq    $24, %rsp
+       movq    %xmm0, (%rsp)
+       movq    %xmm1, 8(%rsp)
+       call    _x86_64_get_dispatch@PLT
+       movq    8(%rsp), %xmm1
+       movq    (%rsp), %xmm0
+       addq    $24, %rsp
+       movq    4712(%rax), %r11
+       jmp     *%r11
+#else
+       movq    _glapi_Dispatch(%rip), %rax
+       testq   %rax, %rax
+       je      1f
+       movq    4712(%rax), %r11
+       jmp     *%r11
+1:
+       subq    $24, %rsp
+       movq    %xmm0, (%rsp)
        movq    %xmm1, 8(%rsp)
        call    _glapi_get_dispatch
        movq    8(%rsp), %xmm1
        movq    (%rsp), %xmm0
        addq    $24, %rsp
-       movq    4632(%rax), %r11
+       movq    4712(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(PolygonOffsetEXT), .-GL_PREFIX(PolygonOffsetEXT)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_580)
-       .type   GL_PREFIX(_dispatch_stub_580), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_580))
-GL_PREFIX(_dispatch_stub_580):
+       .globl  GL_PREFIX(_dispatch_stub_590)
+       .type   GL_PREFIX(_dispatch_stub_590), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_590))
+GL_PREFIX(_dispatch_stub_590):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4640(%rax), %r11
+       movq    4720(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -21895,13 +22257,13 @@ GL_PREFIX(_dispatch_stub_580):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4640(%rax), %r11
+       movq    4720(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4640(%rax), %r11
+       movq    4720(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -21911,19 +22273,19 @@ GL_PREFIX(_dispatch_stub_580):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4640(%rax), %r11
+       movq    4720(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_580), .-GL_PREFIX(_dispatch_stub_580)
+       .size   GL_PREFIX(_dispatch_stub_590), .-GL_PREFIX(_dispatch_stub_590)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_581)
-       .type   GL_PREFIX(_dispatch_stub_581), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_581))
-GL_PREFIX(_dispatch_stub_581):
+       .globl  GL_PREFIX(_dispatch_stub_591)
+       .type   GL_PREFIX(_dispatch_stub_591), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_591))
+GL_PREFIX(_dispatch_stub_591):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4648(%rax), %r11
+       movq    4728(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -21933,13 +22295,13 @@ GL_PREFIX(_dispatch_stub_581):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4648(%rax), %r11
+       movq    4728(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4648(%rax), %r11
+       movq    4728(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -21949,19 +22311,19 @@ GL_PREFIX(_dispatch_stub_581):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4648(%rax), %r11
+       movq    4728(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_581), .-GL_PREFIX(_dispatch_stub_581)
+       .size   GL_PREFIX(_dispatch_stub_591), .-GL_PREFIX(_dispatch_stub_591)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_582)
-       .type   GL_PREFIX(_dispatch_stub_582), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_582))
-GL_PREFIX(_dispatch_stub_582):
+       .globl  GL_PREFIX(_dispatch_stub_592)
+       .type   GL_PREFIX(_dispatch_stub_592), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_592))
+GL_PREFIX(_dispatch_stub_592):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4656(%rax), %r11
+       movq    4736(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $24, %rsp
@@ -21971,13 +22333,13 @@ GL_PREFIX(_dispatch_stub_582):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $24, %rsp
-       movq    4656(%rax), %r11
+       movq    4736(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4656(%rax), %r11
+       movq    4736(%rax), %r11
        jmp     *%r11
 1:
        subq    $24, %rsp
@@ -21987,19 +22349,19 @@ GL_PREFIX(_dispatch_stub_582):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $24, %rsp
-       movq    4656(%rax), %r11
+       movq    4736(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_582), .-GL_PREFIX(_dispatch_stub_582)
+       .size   GL_PREFIX(_dispatch_stub_592), .-GL_PREFIX(_dispatch_stub_592)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_583)
-       .type   GL_PREFIX(_dispatch_stub_583), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_583))
-GL_PREFIX(_dispatch_stub_583):
+       .globl  GL_PREFIX(_dispatch_stub_593)
+       .type   GL_PREFIX(_dispatch_stub_593), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_593))
+GL_PREFIX(_dispatch_stub_593):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4664(%rax), %r11
+       movq    4744(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -22009,13 +22371,13 @@ GL_PREFIX(_dispatch_stub_583):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4664(%rax), %r11
+       movq    4744(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4664(%rax), %r11
+       movq    4744(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -22025,19 +22387,19 @@ GL_PREFIX(_dispatch_stub_583):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4664(%rax), %r11
+       movq    4744(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_583), .-GL_PREFIX(_dispatch_stub_583)
+       .size   GL_PREFIX(_dispatch_stub_593), .-GL_PREFIX(_dispatch_stub_593)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_584)
-       .type   GL_PREFIX(_dispatch_stub_584), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_584))
-GL_PREFIX(_dispatch_stub_584):
+       .globl  GL_PREFIX(_dispatch_stub_594)
+       .type   GL_PREFIX(_dispatch_stub_594), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_594))
+GL_PREFIX(_dispatch_stub_594):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4672(%rax), %r11
+       movq    4752(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -22047,13 +22409,13 @@ GL_PREFIX(_dispatch_stub_584):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4672(%rax), %r11
+       movq    4752(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4672(%rax), %r11
+       movq    4752(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -22063,19 +22425,19 @@ GL_PREFIX(_dispatch_stub_584):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4672(%rax), %r11
+       movq    4752(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_584), .-GL_PREFIX(_dispatch_stub_584)
+       .size   GL_PREFIX(_dispatch_stub_594), .-GL_PREFIX(_dispatch_stub_594)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_585)
-       .type   GL_PREFIX(_dispatch_stub_585), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_585))
-GL_PREFIX(_dispatch_stub_585):
+       .globl  GL_PREFIX(_dispatch_stub_595)
+       .type   GL_PREFIX(_dispatch_stub_595), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_595))
+GL_PREFIX(_dispatch_stub_595):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4680(%rax), %r11
+       movq    4760(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -22085,13 +22447,13 @@ GL_PREFIX(_dispatch_stub_585):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4680(%rax), %r11
+       movq    4760(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4680(%rax), %r11
+       movq    4760(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -22101,19 +22463,19 @@ GL_PREFIX(_dispatch_stub_585):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4680(%rax), %r11
+       movq    4760(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_585), .-GL_PREFIX(_dispatch_stub_585)
+       .size   GL_PREFIX(_dispatch_stub_595), .-GL_PREFIX(_dispatch_stub_595)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_586)
-       .type   GL_PREFIX(_dispatch_stub_586), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_586))
-GL_PREFIX(_dispatch_stub_586):
+       .globl  GL_PREFIX(_dispatch_stub_596)
+       .type   GL_PREFIX(_dispatch_stub_596), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_596))
+GL_PREFIX(_dispatch_stub_596):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4688(%rax), %r11
+       movq    4768(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -22123,13 +22485,13 @@ GL_PREFIX(_dispatch_stub_586):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4688(%rax), %r11
+       movq    4768(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4688(%rax), %r11
+       movq    4768(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -22139,40 +22501,40 @@ GL_PREFIX(_dispatch_stub_586):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4688(%rax), %r11
+       movq    4768(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_586), .-GL_PREFIX(_dispatch_stub_586)
+       .size   GL_PREFIX(_dispatch_stub_596), .-GL_PREFIX(_dispatch_stub_596)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_587)
-       .type   GL_PREFIX(_dispatch_stub_587), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_587))
-GL_PREFIX(_dispatch_stub_587):
+       .globl  GL_PREFIX(_dispatch_stub_597)
+       .type   GL_PREFIX(_dispatch_stub_597), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_597))
+GL_PREFIX(_dispatch_stub_597):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4696(%rax), %r11
+       movq    4776(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    4696(%rax), %r11
+       movq    4776(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4696(%rax), %r11
+       movq    4776(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    4696(%rax), %r11
+       movq    4776(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_587), .-GL_PREFIX(_dispatch_stub_587)
+       .size   GL_PREFIX(_dispatch_stub_597), .-GL_PREFIX(_dispatch_stub_597)
 
        .p2align        4,,15
        .globl  GL_PREFIX(ColorPointerEXT)
@@ -22180,7 +22542,7 @@ GL_PREFIX(_dispatch_stub_587):
 GL_PREFIX(ColorPointerEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4704(%rax), %r11
+       movq    4784(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -22194,13 +22556,13 @@ GL_PREFIX(ColorPointerEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4704(%rax), %r11
+       movq    4784(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4704(%rax), %r11
+       movq    4784(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -22214,7 +22576,7 @@ GL_PREFIX(ColorPointerEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4704(%rax), %r11
+       movq    4784(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(ColorPointerEXT), .-GL_PREFIX(ColorPointerEXT)
@@ -22225,7 +22587,7 @@ GL_PREFIX(ColorPointerEXT):
 GL_PREFIX(EdgeFlagPointerEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4712(%rax), %r11
+       movq    4792(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -22235,13 +22597,13 @@ GL_PREFIX(EdgeFlagPointerEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4712(%rax), %r11
+       movq    4792(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4712(%rax), %r11
+       movq    4792(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -22251,7 +22613,7 @@ GL_PREFIX(EdgeFlagPointerEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4712(%rax), %r11
+       movq    4792(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(EdgeFlagPointerEXT), .-GL_PREFIX(EdgeFlagPointerEXT)
@@ -22262,7 +22624,7 @@ GL_PREFIX(EdgeFlagPointerEXT):
 GL_PREFIX(IndexPointerEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4720(%rax), %r11
+       movq    4800(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -22276,13 +22638,13 @@ GL_PREFIX(IndexPointerEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4720(%rax), %r11
+       movq    4800(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4720(%rax), %r11
+       movq    4800(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -22296,7 +22658,7 @@ GL_PREFIX(IndexPointerEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4720(%rax), %r11
+       movq    4800(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(IndexPointerEXT), .-GL_PREFIX(IndexPointerEXT)
@@ -22307,7 +22669,7 @@ GL_PREFIX(IndexPointerEXT):
 GL_PREFIX(NormalPointerEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4728(%rax), %r11
+       movq    4808(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -22321,13 +22683,13 @@ GL_PREFIX(NormalPointerEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4728(%rax), %r11
+       movq    4808(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4728(%rax), %r11
+       movq    4808(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -22341,7 +22703,7 @@ GL_PREFIX(NormalPointerEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4728(%rax), %r11
+       movq    4808(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(NormalPointerEXT), .-GL_PREFIX(NormalPointerEXT)
@@ -22352,7 +22714,7 @@ GL_PREFIX(NormalPointerEXT):
 GL_PREFIX(TexCoordPointerEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4736(%rax), %r11
+       movq    4816(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -22366,13 +22728,13 @@ GL_PREFIX(TexCoordPointerEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4736(%rax), %r11
+       movq    4816(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4736(%rax), %r11
+       movq    4816(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -22386,7 +22748,7 @@ GL_PREFIX(TexCoordPointerEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4736(%rax), %r11
+       movq    4816(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(TexCoordPointerEXT), .-GL_PREFIX(TexCoordPointerEXT)
@@ -22397,7 +22759,7 @@ GL_PREFIX(TexCoordPointerEXT):
 GL_PREFIX(VertexPointerEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4744(%rax), %r11
+       movq    4824(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -22411,13 +22773,13 @@ GL_PREFIX(VertexPointerEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4744(%rax), %r11
+       movq    4824(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4744(%rax), %r11
+       movq    4824(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -22431,7 +22793,7 @@ GL_PREFIX(VertexPointerEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4744(%rax), %r11
+       movq    4824(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexPointerEXT), .-GL_PREFIX(VertexPointerEXT)
@@ -22442,7 +22804,7 @@ GL_PREFIX(VertexPointerEXT):
 GL_PREFIX(PointParameterfEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4752(%rax), %r11
+       movq    4832(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $24, %rsp
@@ -22452,13 +22814,13 @@ GL_PREFIX(PointParameterfEXT):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $24, %rsp
-       movq    4752(%rax), %r11
+       movq    4832(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4752(%rax), %r11
+       movq    4832(%rax), %r11
        jmp     *%r11
 1:
        subq    $24, %rsp
@@ -22468,7 +22830,7 @@ GL_PREFIX(PointParameterfEXT):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $24, %rsp
-       movq    4752(%rax), %r11
+       movq    4832(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(PointParameterfEXT), .-GL_PREFIX(PointParameterfEXT)
@@ -22479,7 +22841,7 @@ GL_PREFIX(PointParameterfEXT):
 GL_PREFIX(PointParameterfvEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4760(%rax), %r11
+       movq    4840(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -22489,13 +22851,13 @@ GL_PREFIX(PointParameterfvEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4760(%rax), %r11
+       movq    4840(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4760(%rax), %r11
+       movq    4840(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -22505,7 +22867,7 @@ GL_PREFIX(PointParameterfvEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4760(%rax), %r11
+       movq    4840(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(PointParameterfvEXT), .-GL_PREFIX(PointParameterfvEXT)
@@ -22516,7 +22878,7 @@ GL_PREFIX(PointParameterfvEXT):
 GL_PREFIX(LockArraysEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4768(%rax), %r11
+       movq    4848(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -22526,13 +22888,13 @@ GL_PREFIX(LockArraysEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4768(%rax), %r11
+       movq    4848(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4768(%rax), %r11
+       movq    4848(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -22542,7 +22904,7 @@ GL_PREFIX(LockArraysEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4768(%rax), %r11
+       movq    4848(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(LockArraysEXT), .-GL_PREFIX(LockArraysEXT)
@@ -22553,37 +22915,37 @@ GL_PREFIX(LockArraysEXT):
 GL_PREFIX(UnlockArraysEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4776(%rax), %r11
+       movq    4856(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rbp
        call    _x86_64_get_dispatch@PLT
        popq    %rbp
-       movq    4776(%rax), %r11
+       movq    4856(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4776(%rax), %r11
+       movq    4856(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rbp
        call    _glapi_get_dispatch
        popq    %rbp
-       movq    4776(%rax), %r11
+       movq    4856(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(UnlockArraysEXT), .-GL_PREFIX(UnlockArraysEXT)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_598)
-       .type   GL_PREFIX(_dispatch_stub_598), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_598))
-GL_PREFIX(_dispatch_stub_598):
+       .globl  GL_PREFIX(_dispatch_stub_608)
+       .type   GL_PREFIX(_dispatch_stub_608), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_608))
+GL_PREFIX(_dispatch_stub_608):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4784(%rax), %r11
+       movq    4864(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -22593,13 +22955,13 @@ GL_PREFIX(_dispatch_stub_598):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4784(%rax), %r11
+       movq    4864(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4784(%rax), %r11
+       movq    4864(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -22609,19 +22971,19 @@ GL_PREFIX(_dispatch_stub_598):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4784(%rax), %r11
+       movq    4864(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_598), .-GL_PREFIX(_dispatch_stub_598)
+       .size   GL_PREFIX(_dispatch_stub_608), .-GL_PREFIX(_dispatch_stub_608)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_599)
-       .type   GL_PREFIX(_dispatch_stub_599), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_599))
-GL_PREFIX(_dispatch_stub_599):
+       .globl  GL_PREFIX(_dispatch_stub_609)
+       .type   GL_PREFIX(_dispatch_stub_609), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_609))
+GL_PREFIX(_dispatch_stub_609):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4792(%rax), %r11
+       movq    4872(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -22631,13 +22993,13 @@ GL_PREFIX(_dispatch_stub_599):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4792(%rax), %r11
+       movq    4872(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4792(%rax), %r11
+       movq    4872(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -22647,10 +23009,10 @@ GL_PREFIX(_dispatch_stub_599):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    4792(%rax), %r11
+       movq    4872(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_599), .-GL_PREFIX(_dispatch_stub_599)
+       .size   GL_PREFIX(_dispatch_stub_609), .-GL_PREFIX(_dispatch_stub_609)
 
        .p2align        4,,15
        .globl  GL_PREFIX(SecondaryColor3bEXT)
@@ -22658,7 +23020,7 @@ GL_PREFIX(_dispatch_stub_599):
 GL_PREFIX(SecondaryColor3bEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4800(%rax), %r11
+       movq    4880(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -22668,13 +23030,13 @@ GL_PREFIX(SecondaryColor3bEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4800(%rax), %r11
+       movq    4880(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4800(%rax), %r11
+       movq    4880(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -22684,7 +23046,7 @@ GL_PREFIX(SecondaryColor3bEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4800(%rax), %r11
+       movq    4880(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(SecondaryColor3bEXT), .-GL_PREFIX(SecondaryColor3bEXT)
@@ -22695,25 +23057,25 @@ GL_PREFIX(SecondaryColor3bEXT):
 GL_PREFIX(SecondaryColor3bvEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4808(%rax), %r11
+       movq    4888(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    4808(%rax), %r11
+       movq    4888(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4808(%rax), %r11
+       movq    4888(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    4808(%rax), %r11
+       movq    4888(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(SecondaryColor3bvEXT), .-GL_PREFIX(SecondaryColor3bvEXT)
@@ -22724,7 +23086,7 @@ GL_PREFIX(SecondaryColor3bvEXT):
 GL_PREFIX(SecondaryColor3dEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4816(%rax), %r11
+       movq    4896(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $24, %rsp
@@ -22736,13 +23098,13 @@ GL_PREFIX(SecondaryColor3dEXT):
        movq    8(%rsp), %xmm1
        movq    (%rsp), %xmm0
        addq    $24, %rsp
-       movq    4816(%rax), %r11
+       movq    4896(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4816(%rax), %r11
+       movq    4896(%rax), %r11
        jmp     *%r11
 1:
        subq    $24, %rsp
@@ -22754,7 +23116,7 @@ GL_PREFIX(SecondaryColor3dEXT):
        movq    8(%rsp), %xmm1
        movq    (%rsp), %xmm0
        addq    $24, %rsp
-       movq    4816(%rax), %r11
+       movq    4896(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(SecondaryColor3dEXT), .-GL_PREFIX(SecondaryColor3dEXT)
@@ -22765,25 +23127,25 @@ GL_PREFIX(SecondaryColor3dEXT):
 GL_PREFIX(SecondaryColor3dvEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4824(%rax), %r11
+       movq    4904(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    4824(%rax), %r11
+       movq    4904(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4824(%rax), %r11
+       movq    4904(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    4824(%rax), %r11
+       movq    4904(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(SecondaryColor3dvEXT), .-GL_PREFIX(SecondaryColor3dvEXT)
@@ -22794,7 +23156,7 @@ GL_PREFIX(SecondaryColor3dvEXT):
 GL_PREFIX(SecondaryColor3fEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4832(%rax), %r11
+       movq    4912(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $24, %rsp
@@ -22806,13 +23168,13 @@ GL_PREFIX(SecondaryColor3fEXT):
        movq    8(%rsp), %xmm1
        movq    (%rsp), %xmm0
        addq    $24, %rsp
-       movq    4832(%rax), %r11
+       movq    4912(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4832(%rax), %r11
+       movq    4912(%rax), %r11
        jmp     *%r11
 1:
        subq    $24, %rsp
@@ -22824,7 +23186,7 @@ GL_PREFIX(SecondaryColor3fEXT):
        movq    8(%rsp), %xmm1
        movq    (%rsp), %xmm0
        addq    $24, %rsp
-       movq    4832(%rax), %r11
+       movq    4912(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(SecondaryColor3fEXT), .-GL_PREFIX(SecondaryColor3fEXT)
@@ -22835,25 +23197,25 @@ GL_PREFIX(SecondaryColor3fEXT):
 GL_PREFIX(SecondaryColor3fvEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4840(%rax), %r11
+       movq    4920(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    4840(%rax), %r11
+       movq    4920(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4840(%rax), %r11
+       movq    4920(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    4840(%rax), %r11
+       movq    4920(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(SecondaryColor3fvEXT), .-GL_PREFIX(SecondaryColor3fvEXT)
@@ -22864,7 +23226,7 @@ GL_PREFIX(SecondaryColor3fvEXT):
 GL_PREFIX(SecondaryColor3iEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4848(%rax), %r11
+       movq    4928(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -22874,13 +23236,13 @@ GL_PREFIX(SecondaryColor3iEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4848(%rax), %r11
+       movq    4928(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4848(%rax), %r11
+       movq    4928(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -22890,7 +23252,7 @@ GL_PREFIX(SecondaryColor3iEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4848(%rax), %r11
+       movq    4928(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(SecondaryColor3iEXT), .-GL_PREFIX(SecondaryColor3iEXT)
@@ -22901,25 +23263,25 @@ GL_PREFIX(SecondaryColor3iEXT):
 GL_PREFIX(SecondaryColor3ivEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4856(%rax), %r11
+       movq    4936(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    4856(%rax), %r11
+       movq    4936(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4856(%rax), %r11
+       movq    4936(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    4856(%rax), %r11
+       movq    4936(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(SecondaryColor3ivEXT), .-GL_PREFIX(SecondaryColor3ivEXT)
@@ -22930,7 +23292,7 @@ GL_PREFIX(SecondaryColor3ivEXT):
 GL_PREFIX(SecondaryColor3sEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4864(%rax), %r11
+       movq    4944(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -22940,13 +23302,13 @@ GL_PREFIX(SecondaryColor3sEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4864(%rax), %r11
+       movq    4944(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4864(%rax), %r11
+       movq    4944(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -22956,7 +23318,7 @@ GL_PREFIX(SecondaryColor3sEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4864(%rax), %r11
+       movq    4944(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(SecondaryColor3sEXT), .-GL_PREFIX(SecondaryColor3sEXT)
@@ -22967,25 +23329,25 @@ GL_PREFIX(SecondaryColor3sEXT):
 GL_PREFIX(SecondaryColor3svEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4872(%rax), %r11
+       movq    4952(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    4872(%rax), %r11
+       movq    4952(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4872(%rax), %r11
+       movq    4952(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    4872(%rax), %r11
+       movq    4952(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(SecondaryColor3svEXT), .-GL_PREFIX(SecondaryColor3svEXT)
@@ -22996,7 +23358,7 @@ GL_PREFIX(SecondaryColor3svEXT):
 GL_PREFIX(SecondaryColor3ubEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4880(%rax), %r11
+       movq    4960(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -23006,13 +23368,13 @@ GL_PREFIX(SecondaryColor3ubEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4880(%rax), %r11
+       movq    4960(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4880(%rax), %r11
+       movq    4960(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -23022,7 +23384,7 @@ GL_PREFIX(SecondaryColor3ubEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4880(%rax), %r11
+       movq    4960(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(SecondaryColor3ubEXT), .-GL_PREFIX(SecondaryColor3ubEXT)
@@ -23033,25 +23395,25 @@ GL_PREFIX(SecondaryColor3ubEXT):
 GL_PREFIX(SecondaryColor3ubvEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4888(%rax), %r11
+       movq    4968(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    4888(%rax), %r11
+       movq    4968(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4888(%rax), %r11
+       movq    4968(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    4888(%rax), %r11
+       movq    4968(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(SecondaryColor3ubvEXT), .-GL_PREFIX(SecondaryColor3ubvEXT)
@@ -23062,7 +23424,7 @@ GL_PREFIX(SecondaryColor3ubvEXT):
 GL_PREFIX(SecondaryColor3uiEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4896(%rax), %r11
+       movq    4976(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -23072,13 +23434,13 @@ GL_PREFIX(SecondaryColor3uiEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4896(%rax), %r11
+       movq    4976(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4896(%rax), %r11
+       movq    4976(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -23088,7 +23450,7 @@ GL_PREFIX(SecondaryColor3uiEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4896(%rax), %r11
+       movq    4976(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(SecondaryColor3uiEXT), .-GL_PREFIX(SecondaryColor3uiEXT)
@@ -23099,25 +23461,25 @@ GL_PREFIX(SecondaryColor3uiEXT):
 GL_PREFIX(SecondaryColor3uivEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4904(%rax), %r11
+       movq    4984(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    4904(%rax), %r11
+       movq    4984(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4904(%rax), %r11
+       movq    4984(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    4904(%rax), %r11
+       movq    4984(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(SecondaryColor3uivEXT), .-GL_PREFIX(SecondaryColor3uivEXT)
@@ -23128,7 +23490,7 @@ GL_PREFIX(SecondaryColor3uivEXT):
 GL_PREFIX(SecondaryColor3usEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4912(%rax), %r11
+       movq    4992(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -23138,13 +23500,13 @@ GL_PREFIX(SecondaryColor3usEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4912(%rax), %r11
+       movq    4992(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4912(%rax), %r11
+       movq    4992(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -23154,7 +23516,7 @@ GL_PREFIX(SecondaryColor3usEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4912(%rax), %r11
+       movq    4992(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(SecondaryColor3usEXT), .-GL_PREFIX(SecondaryColor3usEXT)
@@ -23165,25 +23527,25 @@ GL_PREFIX(SecondaryColor3usEXT):
 GL_PREFIX(SecondaryColor3usvEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4920(%rax), %r11
+       movq    5000(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    4920(%rax), %r11
+       movq    5000(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4920(%rax), %r11
+       movq    5000(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    4920(%rax), %r11
+       movq    5000(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(SecondaryColor3usvEXT), .-GL_PREFIX(SecondaryColor3usvEXT)
@@ -23194,7 +23556,7 @@ GL_PREFIX(SecondaryColor3usvEXT):
 GL_PREFIX(SecondaryColorPointerEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4928(%rax), %r11
+       movq    5008(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -23208,13 +23570,13 @@ GL_PREFIX(SecondaryColorPointerEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4928(%rax), %r11
+       movq    5008(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4928(%rax), %r11
+       movq    5008(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -23228,7 +23590,7 @@ GL_PREFIX(SecondaryColorPointerEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4928(%rax), %r11
+       movq    5008(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(SecondaryColorPointerEXT), .-GL_PREFIX(SecondaryColorPointerEXT)
@@ -23239,7 +23601,7 @@ GL_PREFIX(SecondaryColorPointerEXT):
 GL_PREFIX(MultiDrawArraysEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4936(%rax), %r11
+       movq    5016(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -23253,13 +23615,13 @@ GL_PREFIX(MultiDrawArraysEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4936(%rax), %r11
+       movq    5016(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4936(%rax), %r11
+       movq    5016(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -23273,7 +23635,7 @@ GL_PREFIX(MultiDrawArraysEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4936(%rax), %r11
+       movq    5016(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(MultiDrawArraysEXT), .-GL_PREFIX(MultiDrawArraysEXT)
@@ -23284,7 +23646,7 @@ GL_PREFIX(MultiDrawArraysEXT):
 GL_PREFIX(MultiDrawElementsEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4944(%rax), %r11
+       movq    5024(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -23298,13 +23660,13 @@ GL_PREFIX(MultiDrawElementsEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4944(%rax), %r11
+       movq    5024(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4944(%rax), %r11
+       movq    5024(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -23318,7 +23680,7 @@ GL_PREFIX(MultiDrawElementsEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4944(%rax), %r11
+       movq    5024(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(MultiDrawElementsEXT), .-GL_PREFIX(MultiDrawElementsEXT)
@@ -23329,7 +23691,7 @@ GL_PREFIX(MultiDrawElementsEXT):
 GL_PREFIX(FogCoordPointerEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4952(%rax), %r11
+       movq    5032(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -23339,13 +23701,13 @@ GL_PREFIX(FogCoordPointerEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4952(%rax), %r11
+       movq    5032(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4952(%rax), %r11
+       movq    5032(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -23355,7 +23717,7 @@ GL_PREFIX(FogCoordPointerEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    4952(%rax), %r11
+       movq    5032(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(FogCoordPointerEXT), .-GL_PREFIX(FogCoordPointerEXT)
@@ -23366,7 +23728,7 @@ GL_PREFIX(FogCoordPointerEXT):
 GL_PREFIX(FogCoorddEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4960(%rax), %r11
+       movq    5040(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $8, %rsp
@@ -23374,13 +23736,13 @@ GL_PREFIX(FogCoorddEXT):
        call    _x86_64_get_dispatch@PLT
        movq    (%rsp), %xmm0
        addq    $8, %rsp
-       movq    4960(%rax), %r11
+       movq    5040(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4960(%rax), %r11
+       movq    5040(%rax), %r11
        jmp     *%r11
 1:
        subq    $8, %rsp
@@ -23388,7 +23750,7 @@ GL_PREFIX(FogCoorddEXT):
        call    _glapi_get_dispatch
        movq    (%rsp), %xmm0
        addq    $8, %rsp
-       movq    4960(%rax), %r11
+       movq    5040(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(FogCoorddEXT), .-GL_PREFIX(FogCoorddEXT)
@@ -23399,25 +23761,25 @@ GL_PREFIX(FogCoorddEXT):
 GL_PREFIX(FogCoorddvEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4968(%rax), %r11
+       movq    5048(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    4968(%rax), %r11
+       movq    5048(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4968(%rax), %r11
+       movq    5048(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    4968(%rax), %r11
+       movq    5048(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(FogCoorddvEXT), .-GL_PREFIX(FogCoorddvEXT)
@@ -23428,7 +23790,7 @@ GL_PREFIX(FogCoorddvEXT):
 GL_PREFIX(FogCoordfEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4976(%rax), %r11
+       movq    5056(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $8, %rsp
@@ -23436,13 +23798,13 @@ GL_PREFIX(FogCoordfEXT):
        call    _x86_64_get_dispatch@PLT
        movq    (%rsp), %xmm0
        addq    $8, %rsp
-       movq    4976(%rax), %r11
+       movq    5056(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4976(%rax), %r11
+       movq    5056(%rax), %r11
        jmp     *%r11
 1:
        subq    $8, %rsp
@@ -23450,7 +23812,7 @@ GL_PREFIX(FogCoordfEXT):
        call    _glapi_get_dispatch
        movq    (%rsp), %xmm0
        addq    $8, %rsp
-       movq    4976(%rax), %r11
+       movq    5056(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(FogCoordfEXT), .-GL_PREFIX(FogCoordfEXT)
@@ -23461,58 +23823,58 @@ GL_PREFIX(FogCoordfEXT):
 GL_PREFIX(FogCoordfvEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4984(%rax), %r11
+       movq    5064(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    4984(%rax), %r11
+       movq    5064(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4984(%rax), %r11
+       movq    5064(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    4984(%rax), %r11
+       movq    5064(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(FogCoordfvEXT), .-GL_PREFIX(FogCoordfvEXT)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_624)
-       .type   GL_PREFIX(_dispatch_stub_624), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_624))
-GL_PREFIX(_dispatch_stub_624):
+       .globl  GL_PREFIX(_dispatch_stub_634)
+       .type   GL_PREFIX(_dispatch_stub_634), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_634))
+GL_PREFIX(_dispatch_stub_634):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    4992(%rax), %r11
+       movq    5072(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    4992(%rax), %r11
+       movq    5072(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    4992(%rax), %r11
+       movq    5072(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    4992(%rax), %r11
+       movq    5072(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_624), .-GL_PREFIX(_dispatch_stub_624)
+       .size   GL_PREFIX(_dispatch_stub_634), .-GL_PREFIX(_dispatch_stub_634)
 
        .p2align        4,,15
        .globl  GL_PREFIX(BlendFuncSeparateEXT)
@@ -23520,7 +23882,7 @@ GL_PREFIX(_dispatch_stub_624):
 GL_PREFIX(BlendFuncSeparateEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5000(%rax), %r11
+       movq    5080(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -23534,13 +23896,13 @@ GL_PREFIX(BlendFuncSeparateEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5000(%rax), %r11
+       movq    5080(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5000(%rax), %r11
+       movq    5080(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -23554,7 +23916,7 @@ GL_PREFIX(BlendFuncSeparateEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5000(%rax), %r11
+       movq    5080(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(BlendFuncSeparateEXT), .-GL_PREFIX(BlendFuncSeparateEXT)
@@ -23565,25 +23927,25 @@ GL_PREFIX(BlendFuncSeparateEXT):
 GL_PREFIX(FlushVertexArrayRangeNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5008(%rax), %r11
+       movq    5088(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rbp
        call    _x86_64_get_dispatch@PLT
        popq    %rbp
-       movq    5008(%rax), %r11
+       movq    5088(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5008(%rax), %r11
+       movq    5088(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rbp
        call    _glapi_get_dispatch
        popq    %rbp
-       movq    5008(%rax), %r11
+       movq    5088(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(FlushVertexArrayRangeNV), .-GL_PREFIX(FlushVertexArrayRangeNV)
@@ -23594,7 +23956,7 @@ GL_PREFIX(FlushVertexArrayRangeNV):
 GL_PREFIX(VertexArrayRangeNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5016(%rax), %r11
+       movq    5096(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -23604,13 +23966,13 @@ GL_PREFIX(VertexArrayRangeNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5016(%rax), %r11
+       movq    5096(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5016(%rax), %r11
+       movq    5096(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -23620,7 +23982,7 @@ GL_PREFIX(VertexArrayRangeNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5016(%rax), %r11
+       movq    5096(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexArrayRangeNV), .-GL_PREFIX(VertexArrayRangeNV)
@@ -23631,7 +23993,7 @@ GL_PREFIX(VertexArrayRangeNV):
 GL_PREFIX(CombinerInputNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5024(%rax), %r11
+       movq    5104(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -23649,13 +24011,13 @@ GL_PREFIX(CombinerInputNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5024(%rax), %r11
+       movq    5104(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5024(%rax), %r11
+       movq    5104(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -23673,7 +24035,7 @@ GL_PREFIX(CombinerInputNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5024(%rax), %r11
+       movq    5104(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(CombinerInputNV), .-GL_PREFIX(CombinerInputNV)
@@ -23684,7 +24046,7 @@ GL_PREFIX(CombinerInputNV):
 GL_PREFIX(CombinerOutputNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5032(%rax), %r11
+       movq    5112(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -23702,13 +24064,13 @@ GL_PREFIX(CombinerOutputNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5032(%rax), %r11
+       movq    5112(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5032(%rax), %r11
+       movq    5112(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -23726,7 +24088,7 @@ GL_PREFIX(CombinerOutputNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5032(%rax), %r11
+       movq    5112(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(CombinerOutputNV), .-GL_PREFIX(CombinerOutputNV)
@@ -23737,7 +24099,7 @@ GL_PREFIX(CombinerOutputNV):
 GL_PREFIX(CombinerParameterfNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5040(%rax), %r11
+       movq    5120(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $24, %rsp
@@ -23747,13 +24109,13 @@ GL_PREFIX(CombinerParameterfNV):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $24, %rsp
-       movq    5040(%rax), %r11
+       movq    5120(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5040(%rax), %r11
+       movq    5120(%rax), %r11
        jmp     *%r11
 1:
        subq    $24, %rsp
@@ -23763,7 +24125,7 @@ GL_PREFIX(CombinerParameterfNV):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $24, %rsp
-       movq    5040(%rax), %r11
+       movq    5120(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(CombinerParameterfNV), .-GL_PREFIX(CombinerParameterfNV)
@@ -23774,7 +24136,7 @@ GL_PREFIX(CombinerParameterfNV):
 GL_PREFIX(CombinerParameterfvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5048(%rax), %r11
+       movq    5128(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -23784,13 +24146,13 @@ GL_PREFIX(CombinerParameterfvNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5048(%rax), %r11
+       movq    5128(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5048(%rax), %r11
+       movq    5128(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -23800,7 +24162,7 @@ GL_PREFIX(CombinerParameterfvNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5048(%rax), %r11
+       movq    5128(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(CombinerParameterfvNV), .-GL_PREFIX(CombinerParameterfvNV)
@@ -23811,7 +24173,7 @@ GL_PREFIX(CombinerParameterfvNV):
 GL_PREFIX(CombinerParameteriNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5056(%rax), %r11
+       movq    5136(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -23821,13 +24183,13 @@ GL_PREFIX(CombinerParameteriNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5056(%rax), %r11
+       movq    5136(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5056(%rax), %r11
+       movq    5136(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -23837,7 +24199,7 @@ GL_PREFIX(CombinerParameteriNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5056(%rax), %r11
+       movq    5136(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(CombinerParameteriNV), .-GL_PREFIX(CombinerParameteriNV)
@@ -23848,7 +24210,7 @@ GL_PREFIX(CombinerParameteriNV):
 GL_PREFIX(CombinerParameterivNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5064(%rax), %r11
+       movq    5144(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -23858,13 +24220,13 @@ GL_PREFIX(CombinerParameterivNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5064(%rax), %r11
+       movq    5144(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5064(%rax), %r11
+       movq    5144(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -23874,7 +24236,7 @@ GL_PREFIX(CombinerParameterivNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5064(%rax), %r11
+       movq    5144(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(CombinerParameterivNV), .-GL_PREFIX(CombinerParameterivNV)
@@ -23885,7 +24247,7 @@ GL_PREFIX(CombinerParameterivNV):
 GL_PREFIX(FinalCombinerInputNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5072(%rax), %r11
+       movq    5152(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -23899,13 +24261,13 @@ GL_PREFIX(FinalCombinerInputNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5072(%rax), %r11
+       movq    5152(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5072(%rax), %r11
+       movq    5152(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -23919,7 +24281,7 @@ GL_PREFIX(FinalCombinerInputNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5072(%rax), %r11
+       movq    5152(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(FinalCombinerInputNV), .-GL_PREFIX(FinalCombinerInputNV)
@@ -23930,7 +24292,7 @@ GL_PREFIX(FinalCombinerInputNV):
 GL_PREFIX(GetCombinerInputParameterfvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5080(%rax), %r11
+       movq    5160(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -23944,13 +24306,13 @@ GL_PREFIX(GetCombinerInputParameterfvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5080(%rax), %r11
+       movq    5160(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5080(%rax), %r11
+       movq    5160(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -23964,7 +24326,7 @@ GL_PREFIX(GetCombinerInputParameterfvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5080(%rax), %r11
+       movq    5160(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetCombinerInputParameterfvNV), .-GL_PREFIX(GetCombinerInputParameterfvNV)
@@ -23975,7 +24337,7 @@ GL_PREFIX(GetCombinerInputParameterfvNV):
 GL_PREFIX(GetCombinerInputParameterivNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5088(%rax), %r11
+       movq    5168(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -23989,13 +24351,13 @@ GL_PREFIX(GetCombinerInputParameterivNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5088(%rax), %r11
+       movq    5168(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5088(%rax), %r11
+       movq    5168(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -24009,7 +24371,7 @@ GL_PREFIX(GetCombinerInputParameterivNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5088(%rax), %r11
+       movq    5168(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetCombinerInputParameterivNV), .-GL_PREFIX(GetCombinerInputParameterivNV)
@@ -24020,7 +24382,7 @@ GL_PREFIX(GetCombinerInputParameterivNV):
 GL_PREFIX(GetCombinerOutputParameterfvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5096(%rax), %r11
+       movq    5176(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -24034,13 +24396,13 @@ GL_PREFIX(GetCombinerOutputParameterfvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5096(%rax), %r11
+       movq    5176(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5096(%rax), %r11
+       movq    5176(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -24054,7 +24416,7 @@ GL_PREFIX(GetCombinerOutputParameterfvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5096(%rax), %r11
+       movq    5176(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetCombinerOutputParameterfvNV), .-GL_PREFIX(GetCombinerOutputParameterfvNV)
@@ -24065,7 +24427,7 @@ GL_PREFIX(GetCombinerOutputParameterfvNV):
 GL_PREFIX(GetCombinerOutputParameterivNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5104(%rax), %r11
+       movq    5184(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -24079,13 +24441,13 @@ GL_PREFIX(GetCombinerOutputParameterivNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5104(%rax), %r11
+       movq    5184(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5104(%rax), %r11
+       movq    5184(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -24099,7 +24461,7 @@ GL_PREFIX(GetCombinerOutputParameterivNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5104(%rax), %r11
+       movq    5184(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetCombinerOutputParameterivNV), .-GL_PREFIX(GetCombinerOutputParameterivNV)
@@ -24110,7 +24472,7 @@ GL_PREFIX(GetCombinerOutputParameterivNV):
 GL_PREFIX(GetFinalCombinerInputParameterfvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5112(%rax), %r11
+       movq    5192(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -24120,13 +24482,13 @@ GL_PREFIX(GetFinalCombinerInputParameterfvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5112(%rax), %r11
+       movq    5192(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5112(%rax), %r11
+       movq    5192(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -24136,7 +24498,7 @@ GL_PREFIX(GetFinalCombinerInputParameterfvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5112(%rax), %r11
+       movq    5192(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetFinalCombinerInputParameterfvNV), .-GL_PREFIX(GetFinalCombinerInputParameterfvNV)
@@ -24147,7 +24509,7 @@ GL_PREFIX(GetFinalCombinerInputParameterfvNV):
 GL_PREFIX(GetFinalCombinerInputParameterivNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5120(%rax), %r11
+       movq    5200(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -24157,13 +24519,13 @@ GL_PREFIX(GetFinalCombinerInputParameterivNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5120(%rax), %r11
+       movq    5200(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5120(%rax), %r11
+       movq    5200(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -24173,7 +24535,7 @@ GL_PREFIX(GetFinalCombinerInputParameterivNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5120(%rax), %r11
+       movq    5200(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetFinalCombinerInputParameterivNV), .-GL_PREFIX(GetFinalCombinerInputParameterivNV)
@@ -24184,25 +24546,25 @@ GL_PREFIX(GetFinalCombinerInputParameterivNV):
 GL_PREFIX(ResizeBuffersMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5128(%rax), %r11
+       movq    5208(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rbp
        call    _x86_64_get_dispatch@PLT
        popq    %rbp
-       movq    5128(%rax), %r11
+       movq    5208(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5128(%rax), %r11
+       movq    5208(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rbp
        call    _glapi_get_dispatch
        popq    %rbp
-       movq    5128(%rax), %r11
+       movq    5208(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(ResizeBuffersMESA), .-GL_PREFIX(ResizeBuffersMESA)
@@ -24213,7 +24575,7 @@ GL_PREFIX(ResizeBuffersMESA):
 GL_PREFIX(WindowPos2dMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5136(%rax), %r11
+       movq    5216(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $24, %rsp
@@ -24223,13 +24585,13 @@ GL_PREFIX(WindowPos2dMESA):
        movq    8(%rsp), %xmm1
        movq    (%rsp), %xmm0
        addq    $24, %rsp
-       movq    5136(%rax), %r11
+       movq    5216(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5136(%rax), %r11
+       movq    5216(%rax), %r11
        jmp     *%r11
 1:
        subq    $24, %rsp
@@ -24239,7 +24601,7 @@ GL_PREFIX(WindowPos2dMESA):
        movq    8(%rsp), %xmm1
        movq    (%rsp), %xmm0
        addq    $24, %rsp
-       movq    5136(%rax), %r11
+       movq    5216(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos2dMESA), .-GL_PREFIX(WindowPos2dMESA)
@@ -24250,25 +24612,25 @@ GL_PREFIX(WindowPos2dMESA):
 GL_PREFIX(WindowPos2dvMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5144(%rax), %r11
+       movq    5224(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    5144(%rax), %r11
+       movq    5224(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5144(%rax), %r11
+       movq    5224(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    5144(%rax), %r11
+       movq    5224(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos2dvMESA), .-GL_PREFIX(WindowPos2dvMESA)
@@ -24279,7 +24641,7 @@ GL_PREFIX(WindowPos2dvMESA):
 GL_PREFIX(WindowPos2fMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5152(%rax), %r11
+       movq    5232(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $24, %rsp
@@ -24289,13 +24651,13 @@ GL_PREFIX(WindowPos2fMESA):
        movq    8(%rsp), %xmm1
        movq    (%rsp), %xmm0
        addq    $24, %rsp
-       movq    5152(%rax), %r11
+       movq    5232(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5152(%rax), %r11
+       movq    5232(%rax), %r11
        jmp     *%r11
 1:
        subq    $24, %rsp
@@ -24305,7 +24667,7 @@ GL_PREFIX(WindowPos2fMESA):
        movq    8(%rsp), %xmm1
        movq    (%rsp), %xmm0
        addq    $24, %rsp
-       movq    5152(%rax), %r11
+       movq    5232(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos2fMESA), .-GL_PREFIX(WindowPos2fMESA)
@@ -24316,25 +24678,25 @@ GL_PREFIX(WindowPos2fMESA):
 GL_PREFIX(WindowPos2fvMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5160(%rax), %r11
+       movq    5240(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    5160(%rax), %r11
+       movq    5240(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5160(%rax), %r11
+       movq    5240(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    5160(%rax), %r11
+       movq    5240(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos2fvMESA), .-GL_PREFIX(WindowPos2fvMESA)
@@ -24345,7 +24707,7 @@ GL_PREFIX(WindowPos2fvMESA):
 GL_PREFIX(WindowPos2iMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5168(%rax), %r11
+       movq    5248(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -24355,13 +24717,13 @@ GL_PREFIX(WindowPos2iMESA):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5168(%rax), %r11
+       movq    5248(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5168(%rax), %r11
+       movq    5248(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -24371,7 +24733,7 @@ GL_PREFIX(WindowPos2iMESA):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5168(%rax), %r11
+       movq    5248(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos2iMESA), .-GL_PREFIX(WindowPos2iMESA)
@@ -24382,25 +24744,25 @@ GL_PREFIX(WindowPos2iMESA):
 GL_PREFIX(WindowPos2ivMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5176(%rax), %r11
+       movq    5256(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    5176(%rax), %r11
+       movq    5256(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5176(%rax), %r11
+       movq    5256(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    5176(%rax), %r11
+       movq    5256(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos2ivMESA), .-GL_PREFIX(WindowPos2ivMESA)
@@ -24411,7 +24773,7 @@ GL_PREFIX(WindowPos2ivMESA):
 GL_PREFIX(WindowPos2sMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5184(%rax), %r11
+       movq    5264(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -24421,13 +24783,13 @@ GL_PREFIX(WindowPos2sMESA):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5184(%rax), %r11
+       movq    5264(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5184(%rax), %r11
+       movq    5264(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -24437,7 +24799,7 @@ GL_PREFIX(WindowPos2sMESA):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5184(%rax), %r11
+       movq    5264(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos2sMESA), .-GL_PREFIX(WindowPos2sMESA)
@@ -24448,25 +24810,25 @@ GL_PREFIX(WindowPos2sMESA):
 GL_PREFIX(WindowPos2svMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5192(%rax), %r11
+       movq    5272(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    5192(%rax), %r11
+       movq    5272(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5192(%rax), %r11
+       movq    5272(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    5192(%rax), %r11
+       movq    5272(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos2svMESA), .-GL_PREFIX(WindowPos2svMESA)
@@ -24477,7 +24839,7 @@ GL_PREFIX(WindowPos2svMESA):
 GL_PREFIX(WindowPos3dMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5200(%rax), %r11
+       movq    5280(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $24, %rsp
@@ -24489,13 +24851,13 @@ GL_PREFIX(WindowPos3dMESA):
        movq    8(%rsp), %xmm1
        movq    (%rsp), %xmm0
        addq    $24, %rsp
-       movq    5200(%rax), %r11
+       movq    5280(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5200(%rax), %r11
+       movq    5280(%rax), %r11
        jmp     *%r11
 1:
        subq    $24, %rsp
@@ -24507,7 +24869,7 @@ GL_PREFIX(WindowPos3dMESA):
        movq    8(%rsp), %xmm1
        movq    (%rsp), %xmm0
        addq    $24, %rsp
-       movq    5200(%rax), %r11
+       movq    5280(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos3dMESA), .-GL_PREFIX(WindowPos3dMESA)
@@ -24518,25 +24880,25 @@ GL_PREFIX(WindowPos3dMESA):
 GL_PREFIX(WindowPos3dvMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5208(%rax), %r11
+       movq    5288(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    5208(%rax), %r11
+       movq    5288(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5208(%rax), %r11
+       movq    5288(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    5208(%rax), %r11
+       movq    5288(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos3dvMESA), .-GL_PREFIX(WindowPos3dvMESA)
@@ -24547,7 +24909,7 @@ GL_PREFIX(WindowPos3dvMESA):
 GL_PREFIX(WindowPos3fMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5216(%rax), %r11
+       movq    5296(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $24, %rsp
@@ -24559,13 +24921,13 @@ GL_PREFIX(WindowPos3fMESA):
        movq    8(%rsp), %xmm1
        movq    (%rsp), %xmm0
        addq    $24, %rsp
-       movq    5216(%rax), %r11
+       movq    5296(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5216(%rax), %r11
+       movq    5296(%rax), %r11
        jmp     *%r11
 1:
        subq    $24, %rsp
@@ -24577,7 +24939,7 @@ GL_PREFIX(WindowPos3fMESA):
        movq    8(%rsp), %xmm1
        movq    (%rsp), %xmm0
        addq    $24, %rsp
-       movq    5216(%rax), %r11
+       movq    5296(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos3fMESA), .-GL_PREFIX(WindowPos3fMESA)
@@ -24588,25 +24950,25 @@ GL_PREFIX(WindowPos3fMESA):
 GL_PREFIX(WindowPos3fvMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5224(%rax), %r11
+       movq    5304(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    5224(%rax), %r11
+       movq    5304(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5224(%rax), %r11
+       movq    5304(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    5224(%rax), %r11
+       movq    5304(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos3fvMESA), .-GL_PREFIX(WindowPos3fvMESA)
@@ -24617,7 +24979,7 @@ GL_PREFIX(WindowPos3fvMESA):
 GL_PREFIX(WindowPos3iMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5232(%rax), %r11
+       movq    5312(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -24627,13 +24989,13 @@ GL_PREFIX(WindowPos3iMESA):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5232(%rax), %r11
+       movq    5312(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5232(%rax), %r11
+       movq    5312(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -24643,7 +25005,7 @@ GL_PREFIX(WindowPos3iMESA):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5232(%rax), %r11
+       movq    5312(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos3iMESA), .-GL_PREFIX(WindowPos3iMESA)
@@ -24654,25 +25016,25 @@ GL_PREFIX(WindowPos3iMESA):
 GL_PREFIX(WindowPos3ivMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5240(%rax), %r11
+       movq    5320(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    5240(%rax), %r11
+       movq    5320(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5240(%rax), %r11
+       movq    5320(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    5240(%rax), %r11
+       movq    5320(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos3ivMESA), .-GL_PREFIX(WindowPos3ivMESA)
@@ -24683,7 +25045,7 @@ GL_PREFIX(WindowPos3ivMESA):
 GL_PREFIX(WindowPos3sMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5248(%rax), %r11
+       movq    5328(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -24693,13 +25055,13 @@ GL_PREFIX(WindowPos3sMESA):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5248(%rax), %r11
+       movq    5328(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5248(%rax), %r11
+       movq    5328(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -24709,7 +25071,7 @@ GL_PREFIX(WindowPos3sMESA):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5248(%rax), %r11
+       movq    5328(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos3sMESA), .-GL_PREFIX(WindowPos3sMESA)
@@ -24720,25 +25082,25 @@ GL_PREFIX(WindowPos3sMESA):
 GL_PREFIX(WindowPos3svMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5256(%rax), %r11
+       movq    5336(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    5256(%rax), %r11
+       movq    5336(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5256(%rax), %r11
+       movq    5336(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    5256(%rax), %r11
+       movq    5336(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos3svMESA), .-GL_PREFIX(WindowPos3svMESA)
@@ -24749,7 +25111,7 @@ GL_PREFIX(WindowPos3svMESA):
 GL_PREFIX(WindowPos4dMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5264(%rax), %r11
+       movq    5344(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $40, %rsp
@@ -24763,13 +25125,13 @@ GL_PREFIX(WindowPos4dMESA):
        movq    8(%rsp), %xmm1
        movq    (%rsp), %xmm0
        addq    $40, %rsp
-       movq    5264(%rax), %r11
+       movq    5344(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5264(%rax), %r11
+       movq    5344(%rax), %r11
        jmp     *%r11
 1:
        subq    $40, %rsp
@@ -24783,7 +25145,7 @@ GL_PREFIX(WindowPos4dMESA):
        movq    8(%rsp), %xmm1
        movq    (%rsp), %xmm0
        addq    $40, %rsp
-       movq    5264(%rax), %r11
+       movq    5344(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos4dMESA), .-GL_PREFIX(WindowPos4dMESA)
@@ -24794,25 +25156,25 @@ GL_PREFIX(WindowPos4dMESA):
 GL_PREFIX(WindowPos4dvMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5272(%rax), %r11
+       movq    5352(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    5272(%rax), %r11
+       movq    5352(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5272(%rax), %r11
+       movq    5352(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    5272(%rax), %r11
+       movq    5352(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos4dvMESA), .-GL_PREFIX(WindowPos4dvMESA)
@@ -24823,7 +25185,7 @@ GL_PREFIX(WindowPos4dvMESA):
 GL_PREFIX(WindowPos4fMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5280(%rax), %r11
+       movq    5360(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $40, %rsp
@@ -24837,13 +25199,13 @@ GL_PREFIX(WindowPos4fMESA):
        movq    8(%rsp), %xmm1
        movq    (%rsp), %xmm0
        addq    $40, %rsp
-       movq    5280(%rax), %r11
+       movq    5360(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5280(%rax), %r11
+       movq    5360(%rax), %r11
        jmp     *%r11
 1:
        subq    $40, %rsp
@@ -24857,7 +25219,7 @@ GL_PREFIX(WindowPos4fMESA):
        movq    8(%rsp), %xmm1
        movq    (%rsp), %xmm0
        addq    $40, %rsp
-       movq    5280(%rax), %r11
+       movq    5360(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos4fMESA), .-GL_PREFIX(WindowPos4fMESA)
@@ -24868,25 +25230,25 @@ GL_PREFIX(WindowPos4fMESA):
 GL_PREFIX(WindowPos4fvMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5288(%rax), %r11
+       movq    5368(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    5288(%rax), %r11
+       movq    5368(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5288(%rax), %r11
+       movq    5368(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    5288(%rax), %r11
+       movq    5368(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos4fvMESA), .-GL_PREFIX(WindowPos4fvMESA)
@@ -24897,7 +25259,7 @@ GL_PREFIX(WindowPos4fvMESA):
 GL_PREFIX(WindowPos4iMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5296(%rax), %r11
+       movq    5376(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -24911,13 +25273,13 @@ GL_PREFIX(WindowPos4iMESA):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5296(%rax), %r11
+       movq    5376(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5296(%rax), %r11
+       movq    5376(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -24931,7 +25293,7 @@ GL_PREFIX(WindowPos4iMESA):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5296(%rax), %r11
+       movq    5376(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos4iMESA), .-GL_PREFIX(WindowPos4iMESA)
@@ -24942,25 +25304,25 @@ GL_PREFIX(WindowPos4iMESA):
 GL_PREFIX(WindowPos4ivMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5304(%rax), %r11
+       movq    5384(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    5304(%rax), %r11
+       movq    5384(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5304(%rax), %r11
+       movq    5384(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    5304(%rax), %r11
+       movq    5384(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos4ivMESA), .-GL_PREFIX(WindowPos4ivMESA)
@@ -24971,7 +25333,7 @@ GL_PREFIX(WindowPos4ivMESA):
 GL_PREFIX(WindowPos4sMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5312(%rax), %r11
+       movq    5392(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -24985,13 +25347,13 @@ GL_PREFIX(WindowPos4sMESA):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5312(%rax), %r11
+       movq    5392(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5312(%rax), %r11
+       movq    5392(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25005,7 +25367,7 @@ GL_PREFIX(WindowPos4sMESA):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5312(%rax), %r11
+       movq    5392(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos4sMESA), .-GL_PREFIX(WindowPos4sMESA)
@@ -25016,37 +25378,37 @@ GL_PREFIX(WindowPos4sMESA):
 GL_PREFIX(WindowPos4svMESA):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5320(%rax), %r11
+       movq    5400(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    5320(%rax), %r11
+       movq    5400(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5320(%rax), %r11
+       movq    5400(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    5320(%rax), %r11
+       movq    5400(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(WindowPos4svMESA), .-GL_PREFIX(WindowPos4svMESA)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_666)
-       .type   GL_PREFIX(_dispatch_stub_666), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_666))
-GL_PREFIX(_dispatch_stub_666):
+       .globl  GL_PREFIX(_dispatch_stub_676)
+       .type   GL_PREFIX(_dispatch_stub_676), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_676))
+GL_PREFIX(_dispatch_stub_676):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5328(%rax), %r11
+       movq    5408(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25060,13 +25422,13 @@ GL_PREFIX(_dispatch_stub_666):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5328(%rax), %r11
+       movq    5408(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5328(%rax), %r11
+       movq    5408(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25080,19 +25442,19 @@ GL_PREFIX(_dispatch_stub_666):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5328(%rax), %r11
+       movq    5408(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_666), .-GL_PREFIX(_dispatch_stub_666)
+       .size   GL_PREFIX(_dispatch_stub_676), .-GL_PREFIX(_dispatch_stub_676)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_667)
-       .type   GL_PREFIX(_dispatch_stub_667), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_667))
-GL_PREFIX(_dispatch_stub_667):
+       .globl  GL_PREFIX(_dispatch_stub_677)
+       .type   GL_PREFIX(_dispatch_stub_677), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_677))
+GL_PREFIX(_dispatch_stub_677):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5336(%rax), %r11
+       movq    5416(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25110,13 +25472,13 @@ GL_PREFIX(_dispatch_stub_667):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5336(%rax), %r11
+       movq    5416(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5336(%rax), %r11
+       movq    5416(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25134,19 +25496,19 @@ GL_PREFIX(_dispatch_stub_667):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5336(%rax), %r11
+       movq    5416(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_667), .-GL_PREFIX(_dispatch_stub_667)
+       .size   GL_PREFIX(_dispatch_stub_677), .-GL_PREFIX(_dispatch_stub_677)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_668)
-       .type   GL_PREFIX(_dispatch_stub_668), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_668))
-GL_PREFIX(_dispatch_stub_668):
+       .globl  GL_PREFIX(_dispatch_stub_678)
+       .type   GL_PREFIX(_dispatch_stub_678), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_678))
+GL_PREFIX(_dispatch_stub_678):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5344(%rax), %r11
+       movq    5424(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25156,13 +25518,13 @@ GL_PREFIX(_dispatch_stub_668):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5344(%rax), %r11
+       movq    5424(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5344(%rax), %r11
+       movq    5424(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25172,49 +25534,49 @@ GL_PREFIX(_dispatch_stub_668):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5344(%rax), %r11
+       movq    5424(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_668), .-GL_PREFIX(_dispatch_stub_668)
+       .size   GL_PREFIX(_dispatch_stub_678), .-GL_PREFIX(_dispatch_stub_678)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_669)
-       .type   GL_PREFIX(_dispatch_stub_669), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_669))
-GL_PREFIX(_dispatch_stub_669):
+       .globl  GL_PREFIX(_dispatch_stub_679)
+       .type   GL_PREFIX(_dispatch_stub_679), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_679))
+GL_PREFIX(_dispatch_stub_679):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5352(%rax), %r11
+       movq    5432(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    5352(%rax), %r11
+       movq    5432(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5352(%rax), %r11
+       movq    5432(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    5352(%rax), %r11
+       movq    5432(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_669), .-GL_PREFIX(_dispatch_stub_669)
+       .size   GL_PREFIX(_dispatch_stub_679), .-GL_PREFIX(_dispatch_stub_679)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_670)
-       .type   GL_PREFIX(_dispatch_stub_670), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_670))
-GL_PREFIX(_dispatch_stub_670):
+       .globl  GL_PREFIX(_dispatch_stub_680)
+       .type   GL_PREFIX(_dispatch_stub_680), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_680))
+GL_PREFIX(_dispatch_stub_680):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5360(%rax), %r11
+       movq    5440(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25224,13 +25586,13 @@ GL_PREFIX(_dispatch_stub_670):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5360(%rax), %r11
+       movq    5440(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5360(%rax), %r11
+       movq    5440(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25240,19 +25602,19 @@ GL_PREFIX(_dispatch_stub_670):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5360(%rax), %r11
+       movq    5440(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_670), .-GL_PREFIX(_dispatch_stub_670)
+       .size   GL_PREFIX(_dispatch_stub_680), .-GL_PREFIX(_dispatch_stub_680)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_671)
-       .type   GL_PREFIX(_dispatch_stub_671), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_671))
-GL_PREFIX(_dispatch_stub_671):
+       .globl  GL_PREFIX(_dispatch_stub_681)
+       .type   GL_PREFIX(_dispatch_stub_681), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_681))
+GL_PREFIX(_dispatch_stub_681):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5368(%rax), %r11
+       movq    5448(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25262,13 +25624,13 @@ GL_PREFIX(_dispatch_stub_671):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5368(%rax), %r11
+       movq    5448(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5368(%rax), %r11
+       movq    5448(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25278,49 +25640,49 @@ GL_PREFIX(_dispatch_stub_671):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5368(%rax), %r11
+       movq    5448(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_671), .-GL_PREFIX(_dispatch_stub_671)
+       .size   GL_PREFIX(_dispatch_stub_681), .-GL_PREFIX(_dispatch_stub_681)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_672)
-       .type   GL_PREFIX(_dispatch_stub_672), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_672))
-GL_PREFIX(_dispatch_stub_672):
+       .globl  GL_PREFIX(_dispatch_stub_682)
+       .type   GL_PREFIX(_dispatch_stub_682), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_682))
+GL_PREFIX(_dispatch_stub_682):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5376(%rax), %r11
+       movq    5456(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    5376(%rax), %r11
+       movq    5456(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5376(%rax), %r11
+       movq    5456(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    5376(%rax), %r11
+       movq    5456(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_672), .-GL_PREFIX(_dispatch_stub_672)
+       .size   GL_PREFIX(_dispatch_stub_682), .-GL_PREFIX(_dispatch_stub_682)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_673)
-       .type   GL_PREFIX(_dispatch_stub_673), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_673))
-GL_PREFIX(_dispatch_stub_673):
+       .globl  GL_PREFIX(_dispatch_stub_683)
+       .type   GL_PREFIX(_dispatch_stub_683), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_683))
+GL_PREFIX(_dispatch_stub_683):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5384(%rax), %r11
+       movq    5464(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25330,13 +25692,13 @@ GL_PREFIX(_dispatch_stub_673):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5384(%rax), %r11
+       movq    5464(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5384(%rax), %r11
+       movq    5464(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25346,40 +25708,40 @@ GL_PREFIX(_dispatch_stub_673):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5384(%rax), %r11
+       movq    5464(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_673), .-GL_PREFIX(_dispatch_stub_673)
+       .size   GL_PREFIX(_dispatch_stub_683), .-GL_PREFIX(_dispatch_stub_683)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_674)
-       .type   GL_PREFIX(_dispatch_stub_674), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_674))
-GL_PREFIX(_dispatch_stub_674):
+       .globl  GL_PREFIX(_dispatch_stub_684)
+       .type   GL_PREFIX(_dispatch_stub_684), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_684))
+GL_PREFIX(_dispatch_stub_684):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5392(%rax), %r11
+       movq    5472(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    5392(%rax), %r11
+       movq    5472(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5392(%rax), %r11
+       movq    5472(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    5392(%rax), %r11
+       movq    5472(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_674), .-GL_PREFIX(_dispatch_stub_674)
+       .size   GL_PREFIX(_dispatch_stub_684), .-GL_PREFIX(_dispatch_stub_684)
 
        .p2align        4,,15
        .globl  GL_PREFIX(AreProgramsResidentNV)
@@ -25387,7 +25749,7 @@ GL_PREFIX(_dispatch_stub_674):
 GL_PREFIX(AreProgramsResidentNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5400(%rax), %r11
+       movq    5480(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25397,13 +25759,13 @@ GL_PREFIX(AreProgramsResidentNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5400(%rax), %r11
+       movq    5480(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5400(%rax), %r11
+       movq    5480(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25413,7 +25775,7 @@ GL_PREFIX(AreProgramsResidentNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5400(%rax), %r11
+       movq    5480(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(AreProgramsResidentNV), .-GL_PREFIX(AreProgramsResidentNV)
@@ -25424,7 +25786,7 @@ GL_PREFIX(AreProgramsResidentNV):
 GL_PREFIX(BindProgramNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5408(%rax), %r11
+       movq    5488(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25434,13 +25796,13 @@ GL_PREFIX(BindProgramNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5408(%rax), %r11
+       movq    5488(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5408(%rax), %r11
+       movq    5488(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25450,7 +25812,7 @@ GL_PREFIX(BindProgramNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5408(%rax), %r11
+       movq    5488(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(BindProgramNV), .-GL_PREFIX(BindProgramNV)
@@ -25461,7 +25823,7 @@ GL_PREFIX(BindProgramNV):
 GL_PREFIX(DeleteProgramsNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5416(%rax), %r11
+       movq    5496(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25471,13 +25833,13 @@ GL_PREFIX(DeleteProgramsNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5416(%rax), %r11
+       movq    5496(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5416(%rax), %r11
+       movq    5496(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25487,7 +25849,7 @@ GL_PREFIX(DeleteProgramsNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5416(%rax), %r11
+       movq    5496(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(DeleteProgramsNV), .-GL_PREFIX(DeleteProgramsNV)
@@ -25498,7 +25860,7 @@ GL_PREFIX(DeleteProgramsNV):
 GL_PREFIX(ExecuteProgramNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5424(%rax), %r11
+       movq    5504(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25508,13 +25870,13 @@ GL_PREFIX(ExecuteProgramNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5424(%rax), %r11
+       movq    5504(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5424(%rax), %r11
+       movq    5504(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25524,7 +25886,7 @@ GL_PREFIX(ExecuteProgramNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5424(%rax), %r11
+       movq    5504(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(ExecuteProgramNV), .-GL_PREFIX(ExecuteProgramNV)
@@ -25535,7 +25897,7 @@ GL_PREFIX(ExecuteProgramNV):
 GL_PREFIX(GenProgramsNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5432(%rax), %r11
+       movq    5512(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25545,13 +25907,13 @@ GL_PREFIX(GenProgramsNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5432(%rax), %r11
+       movq    5512(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5432(%rax), %r11
+       movq    5512(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25561,7 +25923,7 @@ GL_PREFIX(GenProgramsNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5432(%rax), %r11
+       movq    5512(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GenProgramsNV), .-GL_PREFIX(GenProgramsNV)
@@ -25572,7 +25934,7 @@ GL_PREFIX(GenProgramsNV):
 GL_PREFIX(GetProgramParameterdvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5440(%rax), %r11
+       movq    5520(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25586,13 +25948,13 @@ GL_PREFIX(GetProgramParameterdvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5440(%rax), %r11
+       movq    5520(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5440(%rax), %r11
+       movq    5520(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25606,7 +25968,7 @@ GL_PREFIX(GetProgramParameterdvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5440(%rax), %r11
+       movq    5520(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetProgramParameterdvNV), .-GL_PREFIX(GetProgramParameterdvNV)
@@ -25617,7 +25979,7 @@ GL_PREFIX(GetProgramParameterdvNV):
 GL_PREFIX(GetProgramParameterfvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5448(%rax), %r11
+       movq    5528(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25631,13 +25993,13 @@ GL_PREFIX(GetProgramParameterfvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5448(%rax), %r11
+       movq    5528(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5448(%rax), %r11
+       movq    5528(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25651,7 +26013,7 @@ GL_PREFIX(GetProgramParameterfvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5448(%rax), %r11
+       movq    5528(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetProgramParameterfvNV), .-GL_PREFIX(GetProgramParameterfvNV)
@@ -25662,7 +26024,7 @@ GL_PREFIX(GetProgramParameterfvNV):
 GL_PREFIX(GetProgramStringNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5456(%rax), %r11
+       movq    5536(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25672,13 +26034,13 @@ GL_PREFIX(GetProgramStringNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5456(%rax), %r11
+       movq    5536(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5456(%rax), %r11
+       movq    5536(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25688,7 +26050,7 @@ GL_PREFIX(GetProgramStringNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5456(%rax), %r11
+       movq    5536(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetProgramStringNV), .-GL_PREFIX(GetProgramStringNV)
@@ -25699,7 +26061,7 @@ GL_PREFIX(GetProgramStringNV):
 GL_PREFIX(GetProgramivNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5464(%rax), %r11
+       movq    5544(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25709,13 +26071,13 @@ GL_PREFIX(GetProgramivNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5464(%rax), %r11
+       movq    5544(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5464(%rax), %r11
+       movq    5544(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25725,7 +26087,7 @@ GL_PREFIX(GetProgramivNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5464(%rax), %r11
+       movq    5544(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetProgramivNV), .-GL_PREFIX(GetProgramivNV)
@@ -25736,7 +26098,7 @@ GL_PREFIX(GetProgramivNV):
 GL_PREFIX(GetTrackMatrixivNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5472(%rax), %r11
+       movq    5552(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25750,13 +26112,13 @@ GL_PREFIX(GetTrackMatrixivNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5472(%rax), %r11
+       movq    5552(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5472(%rax), %r11
+       movq    5552(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25770,7 +26132,7 @@ GL_PREFIX(GetTrackMatrixivNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5472(%rax), %r11
+       movq    5552(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetTrackMatrixivNV), .-GL_PREFIX(GetTrackMatrixivNV)
@@ -25781,7 +26143,7 @@ GL_PREFIX(GetTrackMatrixivNV):
 GL_PREFIX(GetVertexAttribPointervNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5480(%rax), %r11
+       movq    5560(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25791,13 +26153,13 @@ GL_PREFIX(GetVertexAttribPointervNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5480(%rax), %r11
+       movq    5560(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5480(%rax), %r11
+       movq    5560(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25807,7 +26169,7 @@ GL_PREFIX(GetVertexAttribPointervNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5480(%rax), %r11
+       movq    5560(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetVertexAttribPointervNV), .-GL_PREFIX(GetVertexAttribPointervNV)
@@ -25818,7 +26180,7 @@ GL_PREFIX(GetVertexAttribPointervNV):
 GL_PREFIX(GetVertexAttribdvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5488(%rax), %r11
+       movq    5568(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25828,13 +26190,13 @@ GL_PREFIX(GetVertexAttribdvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5488(%rax), %r11
+       movq    5568(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5488(%rax), %r11
+       movq    5568(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25844,7 +26206,7 @@ GL_PREFIX(GetVertexAttribdvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5488(%rax), %r11
+       movq    5568(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetVertexAttribdvNV), .-GL_PREFIX(GetVertexAttribdvNV)
@@ -25855,7 +26217,7 @@ GL_PREFIX(GetVertexAttribdvNV):
 GL_PREFIX(GetVertexAttribfvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5496(%rax), %r11
+       movq    5576(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25865,13 +26227,13 @@ GL_PREFIX(GetVertexAttribfvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5496(%rax), %r11
+       movq    5576(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5496(%rax), %r11
+       movq    5576(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25881,7 +26243,7 @@ GL_PREFIX(GetVertexAttribfvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5496(%rax), %r11
+       movq    5576(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetVertexAttribfvNV), .-GL_PREFIX(GetVertexAttribfvNV)
@@ -25892,7 +26254,7 @@ GL_PREFIX(GetVertexAttribfvNV):
 GL_PREFIX(GetVertexAttribivNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5504(%rax), %r11
+       movq    5584(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25902,13 +26264,13 @@ GL_PREFIX(GetVertexAttribivNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5504(%rax), %r11
+       movq    5584(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5504(%rax), %r11
+       movq    5584(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25918,7 +26280,7 @@ GL_PREFIX(GetVertexAttribivNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5504(%rax), %r11
+       movq    5584(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetVertexAttribivNV), .-GL_PREFIX(GetVertexAttribivNV)
@@ -25929,25 +26291,25 @@ GL_PREFIX(GetVertexAttribivNV):
 GL_PREFIX(IsProgramNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5512(%rax), %r11
+       movq    5592(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    5512(%rax), %r11
+       movq    5592(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5512(%rax), %r11
+       movq    5592(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    5512(%rax), %r11
+       movq    5592(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(IsProgramNV), .-GL_PREFIX(IsProgramNV)
@@ -25958,7 +26320,7 @@ GL_PREFIX(IsProgramNV):
 GL_PREFIX(LoadProgramNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5520(%rax), %r11
+       movq    5600(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -25972,13 +26334,13 @@ GL_PREFIX(LoadProgramNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5520(%rax), %r11
+       movq    5600(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5520(%rax), %r11
+       movq    5600(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -25992,7 +26354,7 @@ GL_PREFIX(LoadProgramNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5520(%rax), %r11
+       movq    5600(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(LoadProgramNV), .-GL_PREFIX(LoadProgramNV)
@@ -26003,7 +26365,7 @@ GL_PREFIX(LoadProgramNV):
 GL_PREFIX(ProgramParameters4dvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5528(%rax), %r11
+       movq    5608(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -26017,13 +26379,13 @@ GL_PREFIX(ProgramParameters4dvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5528(%rax), %r11
+       movq    5608(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5528(%rax), %r11
+       movq    5608(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -26037,7 +26399,7 @@ GL_PREFIX(ProgramParameters4dvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5528(%rax), %r11
+       movq    5608(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(ProgramParameters4dvNV), .-GL_PREFIX(ProgramParameters4dvNV)
@@ -26048,7 +26410,7 @@ GL_PREFIX(ProgramParameters4dvNV):
 GL_PREFIX(ProgramParameters4fvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5536(%rax), %r11
+       movq    5616(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -26062,13 +26424,13 @@ GL_PREFIX(ProgramParameters4fvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5536(%rax), %r11
+       movq    5616(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5536(%rax), %r11
+       movq    5616(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -26082,7 +26444,7 @@ GL_PREFIX(ProgramParameters4fvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5536(%rax), %r11
+       movq    5616(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(ProgramParameters4fvNV), .-GL_PREFIX(ProgramParameters4fvNV)
@@ -26093,7 +26455,7 @@ GL_PREFIX(ProgramParameters4fvNV):
 GL_PREFIX(RequestResidentProgramsNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5544(%rax), %r11
+       movq    5624(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -26103,13 +26465,13 @@ GL_PREFIX(RequestResidentProgramsNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5544(%rax), %r11
+       movq    5624(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5544(%rax), %r11
+       movq    5624(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -26119,7 +26481,7 @@ GL_PREFIX(RequestResidentProgramsNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5544(%rax), %r11
+       movq    5624(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(RequestResidentProgramsNV), .-GL_PREFIX(RequestResidentProgramsNV)
@@ -26130,7 +26492,7 @@ GL_PREFIX(RequestResidentProgramsNV):
 GL_PREFIX(TrackMatrixNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5552(%rax), %r11
+       movq    5632(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -26144,13 +26506,13 @@ GL_PREFIX(TrackMatrixNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5552(%rax), %r11
+       movq    5632(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5552(%rax), %r11
+       movq    5632(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -26164,7 +26526,7 @@ GL_PREFIX(TrackMatrixNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5552(%rax), %r11
+       movq    5632(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(TrackMatrixNV), .-GL_PREFIX(TrackMatrixNV)
@@ -26175,7 +26537,7 @@ GL_PREFIX(TrackMatrixNV):
 GL_PREFIX(VertexAttrib1dNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5560(%rax), %r11
+       movq    5640(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $24, %rsp
@@ -26185,13 +26547,13 @@ GL_PREFIX(VertexAttrib1dNV):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $24, %rsp
-       movq    5560(%rax), %r11
+       movq    5640(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5560(%rax), %r11
+       movq    5640(%rax), %r11
        jmp     *%r11
 1:
        subq    $24, %rsp
@@ -26201,7 +26563,7 @@ GL_PREFIX(VertexAttrib1dNV):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $24, %rsp
-       movq    5560(%rax), %r11
+       movq    5640(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib1dNV), .-GL_PREFIX(VertexAttrib1dNV)
@@ -26212,7 +26574,7 @@ GL_PREFIX(VertexAttrib1dNV):
 GL_PREFIX(VertexAttrib1dvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5568(%rax), %r11
+       movq    5648(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -26222,13 +26584,13 @@ GL_PREFIX(VertexAttrib1dvNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5568(%rax), %r11
+       movq    5648(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5568(%rax), %r11
+       movq    5648(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -26238,7 +26600,7 @@ GL_PREFIX(VertexAttrib1dvNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5568(%rax), %r11
+       movq    5648(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib1dvNV), .-GL_PREFIX(VertexAttrib1dvNV)
@@ -26249,7 +26611,7 @@ GL_PREFIX(VertexAttrib1dvNV):
 GL_PREFIX(VertexAttrib1fNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5576(%rax), %r11
+       movq    5656(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $24, %rsp
@@ -26259,13 +26621,13 @@ GL_PREFIX(VertexAttrib1fNV):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $24, %rsp
-       movq    5576(%rax), %r11
+       movq    5656(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5576(%rax), %r11
+       movq    5656(%rax), %r11
        jmp     *%r11
 1:
        subq    $24, %rsp
@@ -26275,7 +26637,7 @@ GL_PREFIX(VertexAttrib1fNV):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $24, %rsp
-       movq    5576(%rax), %r11
+       movq    5656(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib1fNV), .-GL_PREFIX(VertexAttrib1fNV)
@@ -26286,7 +26648,7 @@ GL_PREFIX(VertexAttrib1fNV):
 GL_PREFIX(VertexAttrib1fvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5584(%rax), %r11
+       movq    5664(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -26296,13 +26658,13 @@ GL_PREFIX(VertexAttrib1fvNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5584(%rax), %r11
+       movq    5664(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5584(%rax), %r11
+       movq    5664(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -26312,7 +26674,7 @@ GL_PREFIX(VertexAttrib1fvNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5584(%rax), %r11
+       movq    5664(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib1fvNV), .-GL_PREFIX(VertexAttrib1fvNV)
@@ -26323,7 +26685,7 @@ GL_PREFIX(VertexAttrib1fvNV):
 GL_PREFIX(VertexAttrib1sNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5592(%rax), %r11
+       movq    5672(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -26333,13 +26695,13 @@ GL_PREFIX(VertexAttrib1sNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5592(%rax), %r11
+       movq    5672(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5592(%rax), %r11
+       movq    5672(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -26349,7 +26711,7 @@ GL_PREFIX(VertexAttrib1sNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5592(%rax), %r11
+       movq    5672(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib1sNV), .-GL_PREFIX(VertexAttrib1sNV)
@@ -26360,7 +26722,7 @@ GL_PREFIX(VertexAttrib1sNV):
 GL_PREFIX(VertexAttrib1svNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5600(%rax), %r11
+       movq    5680(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -26370,13 +26732,13 @@ GL_PREFIX(VertexAttrib1svNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5600(%rax), %r11
+       movq    5680(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5600(%rax), %r11
+       movq    5680(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -26386,7 +26748,7 @@ GL_PREFIX(VertexAttrib1svNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5600(%rax), %r11
+       movq    5680(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib1svNV), .-GL_PREFIX(VertexAttrib1svNV)
@@ -26397,7 +26759,7 @@ GL_PREFIX(VertexAttrib1svNV):
 GL_PREFIX(VertexAttrib2dNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5608(%rax), %r11
+       movq    5688(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $24, %rsp
@@ -26409,13 +26771,13 @@ GL_PREFIX(VertexAttrib2dNV):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $24, %rsp
-       movq    5608(%rax), %r11
+       movq    5688(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5608(%rax), %r11
+       movq    5688(%rax), %r11
        jmp     *%r11
 1:
        subq    $24, %rsp
@@ -26427,7 +26789,7 @@ GL_PREFIX(VertexAttrib2dNV):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $24, %rsp
-       movq    5608(%rax), %r11
+       movq    5688(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib2dNV), .-GL_PREFIX(VertexAttrib2dNV)
@@ -26438,7 +26800,7 @@ GL_PREFIX(VertexAttrib2dNV):
 GL_PREFIX(VertexAttrib2dvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5616(%rax), %r11
+       movq    5696(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -26448,13 +26810,13 @@ GL_PREFIX(VertexAttrib2dvNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5616(%rax), %r11
+       movq    5696(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5616(%rax), %r11
+       movq    5696(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -26464,7 +26826,7 @@ GL_PREFIX(VertexAttrib2dvNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5616(%rax), %r11
+       movq    5696(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib2dvNV), .-GL_PREFIX(VertexAttrib2dvNV)
@@ -26475,7 +26837,7 @@ GL_PREFIX(VertexAttrib2dvNV):
 GL_PREFIX(VertexAttrib2fNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5624(%rax), %r11
+       movq    5704(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $24, %rsp
@@ -26487,13 +26849,13 @@ GL_PREFIX(VertexAttrib2fNV):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $24, %rsp
-       movq    5624(%rax), %r11
+       movq    5704(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5624(%rax), %r11
+       movq    5704(%rax), %r11
        jmp     *%r11
 1:
        subq    $24, %rsp
@@ -26505,7 +26867,7 @@ GL_PREFIX(VertexAttrib2fNV):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $24, %rsp
-       movq    5624(%rax), %r11
+       movq    5704(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib2fNV), .-GL_PREFIX(VertexAttrib2fNV)
@@ -26516,7 +26878,7 @@ GL_PREFIX(VertexAttrib2fNV):
 GL_PREFIX(VertexAttrib2fvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5632(%rax), %r11
+       movq    5712(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -26526,13 +26888,13 @@ GL_PREFIX(VertexAttrib2fvNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5632(%rax), %r11
+       movq    5712(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5632(%rax), %r11
+       movq    5712(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -26542,7 +26904,7 @@ GL_PREFIX(VertexAttrib2fvNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5632(%rax), %r11
+       movq    5712(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib2fvNV), .-GL_PREFIX(VertexAttrib2fvNV)
@@ -26553,7 +26915,7 @@ GL_PREFIX(VertexAttrib2fvNV):
 GL_PREFIX(VertexAttrib2sNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5640(%rax), %r11
+       movq    5720(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -26563,13 +26925,13 @@ GL_PREFIX(VertexAttrib2sNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5640(%rax), %r11
+       movq    5720(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5640(%rax), %r11
+       movq    5720(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -26579,7 +26941,7 @@ GL_PREFIX(VertexAttrib2sNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5640(%rax), %r11
+       movq    5720(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib2sNV), .-GL_PREFIX(VertexAttrib2sNV)
@@ -26590,7 +26952,7 @@ GL_PREFIX(VertexAttrib2sNV):
 GL_PREFIX(VertexAttrib2svNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5648(%rax), %r11
+       movq    5728(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -26600,13 +26962,13 @@ GL_PREFIX(VertexAttrib2svNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5648(%rax), %r11
+       movq    5728(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5648(%rax), %r11
+       movq    5728(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -26616,7 +26978,7 @@ GL_PREFIX(VertexAttrib2svNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5648(%rax), %r11
+       movq    5728(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib2svNV), .-GL_PREFIX(VertexAttrib2svNV)
@@ -26627,7 +26989,7 @@ GL_PREFIX(VertexAttrib2svNV):
 GL_PREFIX(VertexAttrib3dNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5656(%rax), %r11
+       movq    5736(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $40, %rsp
@@ -26641,13 +27003,13 @@ GL_PREFIX(VertexAttrib3dNV):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $40, %rsp
-       movq    5656(%rax), %r11
+       movq    5736(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5656(%rax), %r11
+       movq    5736(%rax), %r11
        jmp     *%r11
 1:
        subq    $40, %rsp
@@ -26661,7 +27023,7 @@ GL_PREFIX(VertexAttrib3dNV):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $40, %rsp
-       movq    5656(%rax), %r11
+       movq    5736(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib3dNV), .-GL_PREFIX(VertexAttrib3dNV)
@@ -26672,7 +27034,7 @@ GL_PREFIX(VertexAttrib3dNV):
 GL_PREFIX(VertexAttrib3dvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5664(%rax), %r11
+       movq    5744(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -26682,13 +27044,13 @@ GL_PREFIX(VertexAttrib3dvNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5664(%rax), %r11
+       movq    5744(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5664(%rax), %r11
+       movq    5744(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -26698,7 +27060,7 @@ GL_PREFIX(VertexAttrib3dvNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5664(%rax), %r11
+       movq    5744(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib3dvNV), .-GL_PREFIX(VertexAttrib3dvNV)
@@ -26709,7 +27071,7 @@ GL_PREFIX(VertexAttrib3dvNV):
 GL_PREFIX(VertexAttrib3fNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5672(%rax), %r11
+       movq    5752(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $40, %rsp
@@ -26723,13 +27085,13 @@ GL_PREFIX(VertexAttrib3fNV):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $40, %rsp
-       movq    5672(%rax), %r11
+       movq    5752(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5672(%rax), %r11
+       movq    5752(%rax), %r11
        jmp     *%r11
 1:
        subq    $40, %rsp
@@ -26743,7 +27105,7 @@ GL_PREFIX(VertexAttrib3fNV):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $40, %rsp
-       movq    5672(%rax), %r11
+       movq    5752(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib3fNV), .-GL_PREFIX(VertexAttrib3fNV)
@@ -26754,7 +27116,7 @@ GL_PREFIX(VertexAttrib3fNV):
 GL_PREFIX(VertexAttrib3fvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5680(%rax), %r11
+       movq    5760(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -26764,13 +27126,13 @@ GL_PREFIX(VertexAttrib3fvNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5680(%rax), %r11
+       movq    5760(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5680(%rax), %r11
+       movq    5760(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -26780,7 +27142,7 @@ GL_PREFIX(VertexAttrib3fvNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5680(%rax), %r11
+       movq    5760(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib3fvNV), .-GL_PREFIX(VertexAttrib3fvNV)
@@ -26791,7 +27153,7 @@ GL_PREFIX(VertexAttrib3fvNV):
 GL_PREFIX(VertexAttrib3sNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5688(%rax), %r11
+       movq    5768(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -26805,13 +27167,13 @@ GL_PREFIX(VertexAttrib3sNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5688(%rax), %r11
+       movq    5768(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5688(%rax), %r11
+       movq    5768(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -26825,7 +27187,7 @@ GL_PREFIX(VertexAttrib3sNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5688(%rax), %r11
+       movq    5768(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib3sNV), .-GL_PREFIX(VertexAttrib3sNV)
@@ -26836,7 +27198,7 @@ GL_PREFIX(VertexAttrib3sNV):
 GL_PREFIX(VertexAttrib3svNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5696(%rax), %r11
+       movq    5776(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -26846,13 +27208,13 @@ GL_PREFIX(VertexAttrib3svNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5696(%rax), %r11
+       movq    5776(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5696(%rax), %r11
+       movq    5776(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -26862,7 +27224,7 @@ GL_PREFIX(VertexAttrib3svNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5696(%rax), %r11
+       movq    5776(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib3svNV), .-GL_PREFIX(VertexAttrib3svNV)
@@ -26873,7 +27235,7 @@ GL_PREFIX(VertexAttrib3svNV):
 GL_PREFIX(VertexAttrib4dNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5704(%rax), %r11
+       movq    5784(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $40, %rsp
@@ -26889,13 +27251,13 @@ GL_PREFIX(VertexAttrib4dNV):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $40, %rsp
-       movq    5704(%rax), %r11
+       movq    5784(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5704(%rax), %r11
+       movq    5784(%rax), %r11
        jmp     *%r11
 1:
        subq    $40, %rsp
@@ -26911,7 +27273,7 @@ GL_PREFIX(VertexAttrib4dNV):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $40, %rsp
-       movq    5704(%rax), %r11
+       movq    5784(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib4dNV), .-GL_PREFIX(VertexAttrib4dNV)
@@ -26922,7 +27284,7 @@ GL_PREFIX(VertexAttrib4dNV):
 GL_PREFIX(VertexAttrib4dvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5712(%rax), %r11
+       movq    5792(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -26932,13 +27294,13 @@ GL_PREFIX(VertexAttrib4dvNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5712(%rax), %r11
+       movq    5792(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5712(%rax), %r11
+       movq    5792(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -26948,7 +27310,7 @@ GL_PREFIX(VertexAttrib4dvNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5712(%rax), %r11
+       movq    5792(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib4dvNV), .-GL_PREFIX(VertexAttrib4dvNV)
@@ -26959,7 +27321,7 @@ GL_PREFIX(VertexAttrib4dvNV):
 GL_PREFIX(VertexAttrib4fNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5720(%rax), %r11
+       movq    5800(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $40, %rsp
@@ -26975,13 +27337,13 @@ GL_PREFIX(VertexAttrib4fNV):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $40, %rsp
-       movq    5720(%rax), %r11
+       movq    5800(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5720(%rax), %r11
+       movq    5800(%rax), %r11
        jmp     *%r11
 1:
        subq    $40, %rsp
@@ -26997,7 +27359,7 @@ GL_PREFIX(VertexAttrib4fNV):
        movq    8(%rsp), %xmm0
        movq    (%rsp), %rdi
        addq    $40, %rsp
-       movq    5720(%rax), %r11
+       movq    5800(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib4fNV), .-GL_PREFIX(VertexAttrib4fNV)
@@ -27008,7 +27370,7 @@ GL_PREFIX(VertexAttrib4fNV):
 GL_PREFIX(VertexAttrib4fvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5728(%rax), %r11
+       movq    5808(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27018,13 +27380,13 @@ GL_PREFIX(VertexAttrib4fvNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5728(%rax), %r11
+       movq    5808(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5728(%rax), %r11
+       movq    5808(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27034,7 +27396,7 @@ GL_PREFIX(VertexAttrib4fvNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5728(%rax), %r11
+       movq    5808(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib4fvNV), .-GL_PREFIX(VertexAttrib4fvNV)
@@ -27045,7 +27407,7 @@ GL_PREFIX(VertexAttrib4fvNV):
 GL_PREFIX(VertexAttrib4sNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5736(%rax), %r11
+       movq    5816(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27059,13 +27421,13 @@ GL_PREFIX(VertexAttrib4sNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5736(%rax), %r11
+       movq    5816(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5736(%rax), %r11
+       movq    5816(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27079,7 +27441,7 @@ GL_PREFIX(VertexAttrib4sNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5736(%rax), %r11
+       movq    5816(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib4sNV), .-GL_PREFIX(VertexAttrib4sNV)
@@ -27090,7 +27452,7 @@ GL_PREFIX(VertexAttrib4sNV):
 GL_PREFIX(VertexAttrib4svNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5744(%rax), %r11
+       movq    5824(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27100,13 +27462,13 @@ GL_PREFIX(VertexAttrib4svNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5744(%rax), %r11
+       movq    5824(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5744(%rax), %r11
+       movq    5824(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27116,7 +27478,7 @@ GL_PREFIX(VertexAttrib4svNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5744(%rax), %r11
+       movq    5824(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib4svNV), .-GL_PREFIX(VertexAttrib4svNV)
@@ -27127,7 +27489,7 @@ GL_PREFIX(VertexAttrib4svNV):
 GL_PREFIX(VertexAttrib4ubNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5752(%rax), %r11
+       movq    5832(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27141,13 +27503,13 @@ GL_PREFIX(VertexAttrib4ubNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5752(%rax), %r11
+       movq    5832(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5752(%rax), %r11
+       movq    5832(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27161,7 +27523,7 @@ GL_PREFIX(VertexAttrib4ubNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5752(%rax), %r11
+       movq    5832(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib4ubNV), .-GL_PREFIX(VertexAttrib4ubNV)
@@ -27172,7 +27534,7 @@ GL_PREFIX(VertexAttrib4ubNV):
 GL_PREFIX(VertexAttrib4ubvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5760(%rax), %r11
+       movq    5840(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27182,13 +27544,13 @@ GL_PREFIX(VertexAttrib4ubvNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5760(%rax), %r11
+       movq    5840(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5760(%rax), %r11
+       movq    5840(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27198,7 +27560,7 @@ GL_PREFIX(VertexAttrib4ubvNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5760(%rax), %r11
+       movq    5840(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttrib4ubvNV), .-GL_PREFIX(VertexAttrib4ubvNV)
@@ -27209,7 +27571,7 @@ GL_PREFIX(VertexAttrib4ubvNV):
 GL_PREFIX(VertexAttribPointerNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5768(%rax), %r11
+       movq    5848(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27223,13 +27585,13 @@ GL_PREFIX(VertexAttribPointerNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5768(%rax), %r11
+       movq    5848(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5768(%rax), %r11
+       movq    5848(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27243,7 +27605,7 @@ GL_PREFIX(VertexAttribPointerNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5768(%rax), %r11
+       movq    5848(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttribPointerNV), .-GL_PREFIX(VertexAttribPointerNV)
@@ -27254,7 +27616,7 @@ GL_PREFIX(VertexAttribPointerNV):
 GL_PREFIX(VertexAttribs1dvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5776(%rax), %r11
+       movq    5856(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27264,13 +27626,13 @@ GL_PREFIX(VertexAttribs1dvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5776(%rax), %r11
+       movq    5856(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5776(%rax), %r11
+       movq    5856(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27280,7 +27642,7 @@ GL_PREFIX(VertexAttribs1dvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5776(%rax), %r11
+       movq    5856(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttribs1dvNV), .-GL_PREFIX(VertexAttribs1dvNV)
@@ -27291,7 +27653,7 @@ GL_PREFIX(VertexAttribs1dvNV):
 GL_PREFIX(VertexAttribs1fvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5784(%rax), %r11
+       movq    5864(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27301,13 +27663,13 @@ GL_PREFIX(VertexAttribs1fvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5784(%rax), %r11
+       movq    5864(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5784(%rax), %r11
+       movq    5864(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27317,7 +27679,7 @@ GL_PREFIX(VertexAttribs1fvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5784(%rax), %r11
+       movq    5864(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttribs1fvNV), .-GL_PREFIX(VertexAttribs1fvNV)
@@ -27328,7 +27690,7 @@ GL_PREFIX(VertexAttribs1fvNV):
 GL_PREFIX(VertexAttribs1svNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5792(%rax), %r11
+       movq    5872(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27338,13 +27700,13 @@ GL_PREFIX(VertexAttribs1svNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5792(%rax), %r11
+       movq    5872(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5792(%rax), %r11
+       movq    5872(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27354,7 +27716,7 @@ GL_PREFIX(VertexAttribs1svNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5792(%rax), %r11
+       movq    5872(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttribs1svNV), .-GL_PREFIX(VertexAttribs1svNV)
@@ -27365,7 +27727,7 @@ GL_PREFIX(VertexAttribs1svNV):
 GL_PREFIX(VertexAttribs2dvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5800(%rax), %r11
+       movq    5880(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27375,13 +27737,13 @@ GL_PREFIX(VertexAttribs2dvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5800(%rax), %r11
+       movq    5880(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5800(%rax), %r11
+       movq    5880(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27391,7 +27753,7 @@ GL_PREFIX(VertexAttribs2dvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5800(%rax), %r11
+       movq    5880(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttribs2dvNV), .-GL_PREFIX(VertexAttribs2dvNV)
@@ -27402,7 +27764,7 @@ GL_PREFIX(VertexAttribs2dvNV):
 GL_PREFIX(VertexAttribs2fvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5808(%rax), %r11
+       movq    5888(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27412,13 +27774,13 @@ GL_PREFIX(VertexAttribs2fvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5808(%rax), %r11
+       movq    5888(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5808(%rax), %r11
+       movq    5888(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27428,7 +27790,7 @@ GL_PREFIX(VertexAttribs2fvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5808(%rax), %r11
+       movq    5888(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttribs2fvNV), .-GL_PREFIX(VertexAttribs2fvNV)
@@ -27439,7 +27801,7 @@ GL_PREFIX(VertexAttribs2fvNV):
 GL_PREFIX(VertexAttribs2svNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5816(%rax), %r11
+       movq    5896(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27449,13 +27811,13 @@ GL_PREFIX(VertexAttribs2svNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5816(%rax), %r11
+       movq    5896(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5816(%rax), %r11
+       movq    5896(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27465,7 +27827,7 @@ GL_PREFIX(VertexAttribs2svNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5816(%rax), %r11
+       movq    5896(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttribs2svNV), .-GL_PREFIX(VertexAttribs2svNV)
@@ -27476,7 +27838,7 @@ GL_PREFIX(VertexAttribs2svNV):
 GL_PREFIX(VertexAttribs3dvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5824(%rax), %r11
+       movq    5904(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27486,13 +27848,13 @@ GL_PREFIX(VertexAttribs3dvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5824(%rax), %r11
+       movq    5904(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5824(%rax), %r11
+       movq    5904(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27502,7 +27864,7 @@ GL_PREFIX(VertexAttribs3dvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5824(%rax), %r11
+       movq    5904(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttribs3dvNV), .-GL_PREFIX(VertexAttribs3dvNV)
@@ -27513,7 +27875,7 @@ GL_PREFIX(VertexAttribs3dvNV):
 GL_PREFIX(VertexAttribs3fvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5832(%rax), %r11
+       movq    5912(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27523,13 +27885,13 @@ GL_PREFIX(VertexAttribs3fvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5832(%rax), %r11
+       movq    5912(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5832(%rax), %r11
+       movq    5912(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27539,7 +27901,7 @@ GL_PREFIX(VertexAttribs3fvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5832(%rax), %r11
+       movq    5912(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttribs3fvNV), .-GL_PREFIX(VertexAttribs3fvNV)
@@ -27550,7 +27912,7 @@ GL_PREFIX(VertexAttribs3fvNV):
 GL_PREFIX(VertexAttribs3svNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5840(%rax), %r11
+       movq    5920(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27560,13 +27922,13 @@ GL_PREFIX(VertexAttribs3svNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5840(%rax), %r11
+       movq    5920(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5840(%rax), %r11
+       movq    5920(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27576,7 +27938,7 @@ GL_PREFIX(VertexAttribs3svNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5840(%rax), %r11
+       movq    5920(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttribs3svNV), .-GL_PREFIX(VertexAttribs3svNV)
@@ -27587,7 +27949,7 @@ GL_PREFIX(VertexAttribs3svNV):
 GL_PREFIX(VertexAttribs4dvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5848(%rax), %r11
+       movq    5928(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27597,13 +27959,13 @@ GL_PREFIX(VertexAttribs4dvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5848(%rax), %r11
+       movq    5928(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5848(%rax), %r11
+       movq    5928(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27613,7 +27975,7 @@ GL_PREFIX(VertexAttribs4dvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5848(%rax), %r11
+       movq    5928(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttribs4dvNV), .-GL_PREFIX(VertexAttribs4dvNV)
@@ -27624,7 +27986,7 @@ GL_PREFIX(VertexAttribs4dvNV):
 GL_PREFIX(VertexAttribs4fvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5856(%rax), %r11
+       movq    5936(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27634,13 +27996,13 @@ GL_PREFIX(VertexAttribs4fvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5856(%rax), %r11
+       movq    5936(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5856(%rax), %r11
+       movq    5936(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27650,7 +28012,7 @@ GL_PREFIX(VertexAttribs4fvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5856(%rax), %r11
+       movq    5936(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttribs4fvNV), .-GL_PREFIX(VertexAttribs4fvNV)
@@ -27661,7 +28023,7 @@ GL_PREFIX(VertexAttribs4fvNV):
 GL_PREFIX(VertexAttribs4svNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5864(%rax), %r11
+       movq    5944(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27671,13 +28033,13 @@ GL_PREFIX(VertexAttribs4svNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5864(%rax), %r11
+       movq    5944(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5864(%rax), %r11
+       movq    5944(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27687,7 +28049,7 @@ GL_PREFIX(VertexAttribs4svNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5864(%rax), %r11
+       movq    5944(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttribs4svNV), .-GL_PREFIX(VertexAttribs4svNV)
@@ -27698,7 +28060,7 @@ GL_PREFIX(VertexAttribs4svNV):
 GL_PREFIX(VertexAttribs4ubvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5872(%rax), %r11
+       movq    5952(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27708,13 +28070,13 @@ GL_PREFIX(VertexAttribs4ubvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5872(%rax), %r11
+       movq    5952(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5872(%rax), %r11
+       movq    5952(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27724,7 +28086,7 @@ GL_PREFIX(VertexAttribs4ubvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5872(%rax), %r11
+       movq    5952(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(VertexAttribs4ubvNV), .-GL_PREFIX(VertexAttribs4ubvNV)
@@ -27735,7 +28097,7 @@ GL_PREFIX(VertexAttribs4ubvNV):
 GL_PREFIX(GetTexBumpParameterfvATI):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5880(%rax), %r11
+       movq    5960(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27745,13 +28107,13 @@ GL_PREFIX(GetTexBumpParameterfvATI):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5880(%rax), %r11
+       movq    5960(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5880(%rax), %r11
+       movq    5960(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27761,7 +28123,7 @@ GL_PREFIX(GetTexBumpParameterfvATI):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5880(%rax), %r11
+       movq    5960(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetTexBumpParameterfvATI), .-GL_PREFIX(GetTexBumpParameterfvATI)
@@ -27772,7 +28134,7 @@ GL_PREFIX(GetTexBumpParameterfvATI):
 GL_PREFIX(GetTexBumpParameterivATI):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5888(%rax), %r11
+       movq    5968(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27782,13 +28144,13 @@ GL_PREFIX(GetTexBumpParameterivATI):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5888(%rax), %r11
+       movq    5968(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5888(%rax), %r11
+       movq    5968(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27798,7 +28160,7 @@ GL_PREFIX(GetTexBumpParameterivATI):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5888(%rax), %r11
+       movq    5968(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetTexBumpParameterivATI), .-GL_PREFIX(GetTexBumpParameterivATI)
@@ -27809,7 +28171,7 @@ GL_PREFIX(GetTexBumpParameterivATI):
 GL_PREFIX(TexBumpParameterfvATI):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5896(%rax), %r11
+       movq    5976(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27819,13 +28181,13 @@ GL_PREFIX(TexBumpParameterfvATI):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5896(%rax), %r11
+       movq    5976(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5896(%rax), %r11
+       movq    5976(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27835,7 +28197,7 @@ GL_PREFIX(TexBumpParameterfvATI):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5896(%rax), %r11
+       movq    5976(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(TexBumpParameterfvATI), .-GL_PREFIX(TexBumpParameterfvATI)
@@ -27846,7 +28208,7 @@ GL_PREFIX(TexBumpParameterfvATI):
 GL_PREFIX(TexBumpParameterivATI):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5904(%rax), %r11
+       movq    5984(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27856,13 +28218,13 @@ GL_PREFIX(TexBumpParameterivATI):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5904(%rax), %r11
+       movq    5984(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5904(%rax), %r11
+       movq    5984(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27872,7 +28234,7 @@ GL_PREFIX(TexBumpParameterivATI):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    5904(%rax), %r11
+       movq    5984(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(TexBumpParameterivATI), .-GL_PREFIX(TexBumpParameterivATI)
@@ -27883,7 +28245,7 @@ GL_PREFIX(TexBumpParameterivATI):
 GL_PREFIX(AlphaFragmentOp1ATI):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5912(%rax), %r11
+       movq    5992(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27901,13 +28263,13 @@ GL_PREFIX(AlphaFragmentOp1ATI):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5912(%rax), %r11
+       movq    5992(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5912(%rax), %r11
+       movq    5992(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27925,7 +28287,7 @@ GL_PREFIX(AlphaFragmentOp1ATI):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5912(%rax), %r11
+       movq    5992(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(AlphaFragmentOp1ATI), .-GL_PREFIX(AlphaFragmentOp1ATI)
@@ -27936,7 +28298,7 @@ GL_PREFIX(AlphaFragmentOp1ATI):
 GL_PREFIX(AlphaFragmentOp2ATI):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5920(%rax), %r11
+       movq    6000(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -27954,13 +28316,13 @@ GL_PREFIX(AlphaFragmentOp2ATI):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5920(%rax), %r11
+       movq    6000(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5920(%rax), %r11
+       movq    6000(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -27978,7 +28340,7 @@ GL_PREFIX(AlphaFragmentOp2ATI):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5920(%rax), %r11
+       movq    6000(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(AlphaFragmentOp2ATI), .-GL_PREFIX(AlphaFragmentOp2ATI)
@@ -27989,7 +28351,7 @@ GL_PREFIX(AlphaFragmentOp2ATI):
 GL_PREFIX(AlphaFragmentOp3ATI):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5928(%rax), %r11
+       movq    6008(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -28007,13 +28369,13 @@ GL_PREFIX(AlphaFragmentOp3ATI):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5928(%rax), %r11
+       movq    6008(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5928(%rax), %r11
+       movq    6008(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -28031,7 +28393,7 @@ GL_PREFIX(AlphaFragmentOp3ATI):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5928(%rax), %r11
+       movq    6008(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(AlphaFragmentOp3ATI), .-GL_PREFIX(AlphaFragmentOp3ATI)
@@ -28042,25 +28404,25 @@ GL_PREFIX(AlphaFragmentOp3ATI):
 GL_PREFIX(BeginFragmentShaderATI):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5936(%rax), %r11
+       movq    6016(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rbp
        call    _x86_64_get_dispatch@PLT
        popq    %rbp
-       movq    5936(%rax), %r11
+       movq    6016(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5936(%rax), %r11
+       movq    6016(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rbp
        call    _glapi_get_dispatch
        popq    %rbp
-       movq    5936(%rax), %r11
+       movq    6016(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(BeginFragmentShaderATI), .-GL_PREFIX(BeginFragmentShaderATI)
@@ -28071,25 +28433,25 @@ GL_PREFIX(BeginFragmentShaderATI):
 GL_PREFIX(BindFragmentShaderATI):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5944(%rax), %r11
+       movq    6024(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    5944(%rax), %r11
+       movq    6024(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5944(%rax), %r11
+       movq    6024(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    5944(%rax), %r11
+       movq    6024(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(BindFragmentShaderATI), .-GL_PREFIX(BindFragmentShaderATI)
@@ -28100,7 +28462,7 @@ GL_PREFIX(BindFragmentShaderATI):
 GL_PREFIX(ColorFragmentOp1ATI):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5952(%rax), %r11
+       movq    6032(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -28118,13 +28480,13 @@ GL_PREFIX(ColorFragmentOp1ATI):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5952(%rax), %r11
+       movq    6032(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5952(%rax), %r11
+       movq    6032(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -28142,7 +28504,7 @@ GL_PREFIX(ColorFragmentOp1ATI):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5952(%rax), %r11
+       movq    6032(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(ColorFragmentOp1ATI), .-GL_PREFIX(ColorFragmentOp1ATI)
@@ -28153,7 +28515,7 @@ GL_PREFIX(ColorFragmentOp1ATI):
 GL_PREFIX(ColorFragmentOp2ATI):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5960(%rax), %r11
+       movq    6040(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -28171,13 +28533,13 @@ GL_PREFIX(ColorFragmentOp2ATI):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5960(%rax), %r11
+       movq    6040(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5960(%rax), %r11
+       movq    6040(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -28195,7 +28557,7 @@ GL_PREFIX(ColorFragmentOp2ATI):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5960(%rax), %r11
+       movq    6040(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(ColorFragmentOp2ATI), .-GL_PREFIX(ColorFragmentOp2ATI)
@@ -28206,7 +28568,7 @@ GL_PREFIX(ColorFragmentOp2ATI):
 GL_PREFIX(ColorFragmentOp3ATI):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5968(%rax), %r11
+       movq    6048(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -28224,13 +28586,13 @@ GL_PREFIX(ColorFragmentOp3ATI):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5968(%rax), %r11
+       movq    6048(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5968(%rax), %r11
+       movq    6048(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -28248,7 +28610,7 @@ GL_PREFIX(ColorFragmentOp3ATI):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    5968(%rax), %r11
+       movq    6048(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(ColorFragmentOp3ATI), .-GL_PREFIX(ColorFragmentOp3ATI)
@@ -28259,25 +28621,25 @@ GL_PREFIX(ColorFragmentOp3ATI):
 GL_PREFIX(DeleteFragmentShaderATI):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5976(%rax), %r11
+       movq    6056(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    5976(%rax), %r11
+       movq    6056(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5976(%rax), %r11
+       movq    6056(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    5976(%rax), %r11
+       movq    6056(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(DeleteFragmentShaderATI), .-GL_PREFIX(DeleteFragmentShaderATI)
@@ -28288,25 +28650,25 @@ GL_PREFIX(DeleteFragmentShaderATI):
 GL_PREFIX(EndFragmentShaderATI):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5984(%rax), %r11
+       movq    6064(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rbp
        call    _x86_64_get_dispatch@PLT
        popq    %rbp
-       movq    5984(%rax), %r11
+       movq    6064(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5984(%rax), %r11
+       movq    6064(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rbp
        call    _glapi_get_dispatch
        popq    %rbp
-       movq    5984(%rax), %r11
+       movq    6064(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(EndFragmentShaderATI), .-GL_PREFIX(EndFragmentShaderATI)
@@ -28317,25 +28679,25 @@ GL_PREFIX(EndFragmentShaderATI):
 GL_PREFIX(GenFragmentShadersATI):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    5992(%rax), %r11
+       movq    6072(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    5992(%rax), %r11
+       movq    6072(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    5992(%rax), %r11
+       movq    6072(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    5992(%rax), %r11
+       movq    6072(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GenFragmentShadersATI), .-GL_PREFIX(GenFragmentShadersATI)
@@ -28346,7 +28708,7 @@ GL_PREFIX(GenFragmentShadersATI):
 GL_PREFIX(PassTexCoordATI):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6000(%rax), %r11
+       movq    6080(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -28356,13 +28718,13 @@ GL_PREFIX(PassTexCoordATI):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6000(%rax), %r11
+       movq    6080(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6000(%rax), %r11
+       movq    6080(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -28372,7 +28734,7 @@ GL_PREFIX(PassTexCoordATI):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6000(%rax), %r11
+       movq    6080(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(PassTexCoordATI), .-GL_PREFIX(PassTexCoordATI)
@@ -28383,7 +28745,7 @@ GL_PREFIX(PassTexCoordATI):
 GL_PREFIX(SampleMapATI):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6008(%rax), %r11
+       movq    6088(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -28393,13 +28755,13 @@ GL_PREFIX(SampleMapATI):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6008(%rax), %r11
+       movq    6088(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6008(%rax), %r11
+       movq    6088(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -28409,7 +28771,7 @@ GL_PREFIX(SampleMapATI):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6008(%rax), %r11
+       movq    6088(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(SampleMapATI), .-GL_PREFIX(SampleMapATI)
@@ -28420,7 +28782,7 @@ GL_PREFIX(SampleMapATI):
 GL_PREFIX(SetFragmentShaderConstantATI):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6016(%rax), %r11
+       movq    6096(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -28430,13 +28792,13 @@ GL_PREFIX(SetFragmentShaderConstantATI):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6016(%rax), %r11
+       movq    6096(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6016(%rax), %r11
+       movq    6096(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -28446,7 +28808,7 @@ GL_PREFIX(SetFragmentShaderConstantATI):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6016(%rax), %r11
+       movq    6096(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(SetFragmentShaderConstantATI), .-GL_PREFIX(SetFragmentShaderConstantATI)
@@ -28457,7 +28819,7 @@ GL_PREFIX(SetFragmentShaderConstantATI):
 GL_PREFIX(PointParameteriNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6024(%rax), %r11
+       movq    6104(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -28467,13 +28829,13 @@ GL_PREFIX(PointParameteriNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6024(%rax), %r11
+       movq    6104(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6024(%rax), %r11
+       movq    6104(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -28483,7 +28845,7 @@ GL_PREFIX(PointParameteriNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6024(%rax), %r11
+       movq    6104(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(PointParameteriNV), .-GL_PREFIX(PointParameteriNV)
@@ -28494,7 +28856,7 @@ GL_PREFIX(PointParameteriNV):
 GL_PREFIX(PointParameterivNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6032(%rax), %r11
+       movq    6112(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -28504,13 +28866,13 @@ GL_PREFIX(PointParameterivNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6032(%rax), %r11
+       movq    6112(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6032(%rax), %r11
+       movq    6112(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -28520,79 +28882,79 @@ GL_PREFIX(PointParameterivNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6032(%rax), %r11
+       movq    6112(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(PointParameterivNV), .-GL_PREFIX(PointParameterivNV)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_755)
-       .type   GL_PREFIX(_dispatch_stub_755), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_755))
-GL_PREFIX(_dispatch_stub_755):
+       .globl  GL_PREFIX(_dispatch_stub_765)
+       .type   GL_PREFIX(_dispatch_stub_765), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_765))
+GL_PREFIX(_dispatch_stub_765):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6040(%rax), %r11
+       movq    6120(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    6040(%rax), %r11
+       movq    6120(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6040(%rax), %r11
+       movq    6120(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    6040(%rax), %r11
+       movq    6120(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_755), .-GL_PREFIX(_dispatch_stub_755)
+       .size   GL_PREFIX(_dispatch_stub_765), .-GL_PREFIX(_dispatch_stub_765)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_756)
-       .type   GL_PREFIX(_dispatch_stub_756), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_756))
-GL_PREFIX(_dispatch_stub_756):
+       .globl  GL_PREFIX(_dispatch_stub_766)
+       .type   GL_PREFIX(_dispatch_stub_766), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_766))
+GL_PREFIX(_dispatch_stub_766):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6048(%rax), %r11
+       movq    6128(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    6048(%rax), %r11
+       movq    6128(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6048(%rax), %r11
+       movq    6128(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    6048(%rax), %r11
+       movq    6128(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_756), .-GL_PREFIX(_dispatch_stub_756)
+       .size   GL_PREFIX(_dispatch_stub_766), .-GL_PREFIX(_dispatch_stub_766)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_757)
-       .type   GL_PREFIX(_dispatch_stub_757), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_757))
-GL_PREFIX(_dispatch_stub_757):
+       .globl  GL_PREFIX(_dispatch_stub_767)
+       .type   GL_PREFIX(_dispatch_stub_767), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_767))
+GL_PREFIX(_dispatch_stub_767):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6056(%rax), %r11
+       movq    6136(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -28602,13 +28964,13 @@ GL_PREFIX(_dispatch_stub_757):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6056(%rax), %r11
+       movq    6136(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6056(%rax), %r11
+       movq    6136(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -28618,19 +28980,19 @@ GL_PREFIX(_dispatch_stub_757):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6056(%rax), %r11
+       movq    6136(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_757), .-GL_PREFIX(_dispatch_stub_757)
+       .size   GL_PREFIX(_dispatch_stub_767), .-GL_PREFIX(_dispatch_stub_767)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_758)
-       .type   GL_PREFIX(_dispatch_stub_758), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_758))
-GL_PREFIX(_dispatch_stub_758):
+       .globl  GL_PREFIX(_dispatch_stub_768)
+       .type   GL_PREFIX(_dispatch_stub_768), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_768))
+GL_PREFIX(_dispatch_stub_768):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6064(%rax), %r11
+       movq    6144(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -28640,13 +29002,13 @@ GL_PREFIX(_dispatch_stub_758):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6064(%rax), %r11
+       movq    6144(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6064(%rax), %r11
+       movq    6144(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -28656,40 +29018,40 @@ GL_PREFIX(_dispatch_stub_758):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6064(%rax), %r11
+       movq    6144(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_758), .-GL_PREFIX(_dispatch_stub_758)
+       .size   GL_PREFIX(_dispatch_stub_768), .-GL_PREFIX(_dispatch_stub_768)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_759)
-       .type   GL_PREFIX(_dispatch_stub_759), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_759))
-GL_PREFIX(_dispatch_stub_759):
+       .globl  GL_PREFIX(_dispatch_stub_769)
+       .type   GL_PREFIX(_dispatch_stub_769), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_769))
+GL_PREFIX(_dispatch_stub_769):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6072(%rax), %r11
+       movq    6152(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    6072(%rax), %r11
+       movq    6152(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6072(%rax), %r11
+       movq    6152(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    6072(%rax), %r11
+       movq    6152(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_759), .-GL_PREFIX(_dispatch_stub_759)
+       .size   GL_PREFIX(_dispatch_stub_769), .-GL_PREFIX(_dispatch_stub_769)
 
        .p2align        4,,15
        .globl  GL_PREFIX(GetProgramNamedParameterdvNV)
@@ -28697,7 +29059,7 @@ GL_PREFIX(_dispatch_stub_759):
 GL_PREFIX(GetProgramNamedParameterdvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6080(%rax), %r11
+       movq    6160(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -28711,13 +29073,13 @@ GL_PREFIX(GetProgramNamedParameterdvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6080(%rax), %r11
+       movq    6160(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6080(%rax), %r11
+       movq    6160(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -28731,7 +29093,7 @@ GL_PREFIX(GetProgramNamedParameterdvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6080(%rax), %r11
+       movq    6160(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetProgramNamedParameterdvNV), .-GL_PREFIX(GetProgramNamedParameterdvNV)
@@ -28742,7 +29104,7 @@ GL_PREFIX(GetProgramNamedParameterdvNV):
 GL_PREFIX(GetProgramNamedParameterfvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6088(%rax), %r11
+       movq    6168(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -28756,13 +29118,13 @@ GL_PREFIX(GetProgramNamedParameterfvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6088(%rax), %r11
+       movq    6168(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6088(%rax), %r11
+       movq    6168(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -28776,7 +29138,7 @@ GL_PREFIX(GetProgramNamedParameterfvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6088(%rax), %r11
+       movq    6168(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetProgramNamedParameterfvNV), .-GL_PREFIX(GetProgramNamedParameterfvNV)
@@ -28787,7 +29149,7 @@ GL_PREFIX(GetProgramNamedParameterfvNV):
 GL_PREFIX(ProgramNamedParameter4dNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6096(%rax), %r11
+       movq    6176(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $56, %rsp
@@ -28807,13 +29169,13 @@ GL_PREFIX(ProgramNamedParameter4dNV):
        movq    8(%rsp), %rsi
        movq    (%rsp), %rdi
        addq    $56, %rsp
-       movq    6096(%rax), %r11
+       movq    6176(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6096(%rax), %r11
+       movq    6176(%rax), %r11
        jmp     *%r11
 1:
        subq    $56, %rsp
@@ -28833,7 +29195,7 @@ GL_PREFIX(ProgramNamedParameter4dNV):
        movq    8(%rsp), %rsi
        movq    (%rsp), %rdi
        addq    $56, %rsp
-       movq    6096(%rax), %r11
+       movq    6176(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(ProgramNamedParameter4dNV), .-GL_PREFIX(ProgramNamedParameter4dNV)
@@ -28844,7 +29206,7 @@ GL_PREFIX(ProgramNamedParameter4dNV):
 GL_PREFIX(ProgramNamedParameter4dvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6104(%rax), %r11
+       movq    6184(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -28858,13 +29220,13 @@ GL_PREFIX(ProgramNamedParameter4dvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6104(%rax), %r11
+       movq    6184(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6104(%rax), %r11
+       movq    6184(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -28878,7 +29240,7 @@ GL_PREFIX(ProgramNamedParameter4dvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6104(%rax), %r11
+       movq    6184(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(ProgramNamedParameter4dvNV), .-GL_PREFIX(ProgramNamedParameter4dvNV)
@@ -28889,7 +29251,7 @@ GL_PREFIX(ProgramNamedParameter4dvNV):
 GL_PREFIX(ProgramNamedParameter4fNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6112(%rax), %r11
+       movq    6192(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        subq    $56, %rsp
@@ -28909,13 +29271,13 @@ GL_PREFIX(ProgramNamedParameter4fNV):
        movq    8(%rsp), %rsi
        movq    (%rsp), %rdi
        addq    $56, %rsp
-       movq    6112(%rax), %r11
+       movq    6192(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6112(%rax), %r11
+       movq    6192(%rax), %r11
        jmp     *%r11
 1:
        subq    $56, %rsp
@@ -28935,7 +29297,7 @@ GL_PREFIX(ProgramNamedParameter4fNV):
        movq    8(%rsp), %rsi
        movq    (%rsp), %rdi
        addq    $56, %rsp
-       movq    6112(%rax), %r11
+       movq    6192(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(ProgramNamedParameter4fNV), .-GL_PREFIX(ProgramNamedParameter4fNV)
@@ -28946,7 +29308,7 @@ GL_PREFIX(ProgramNamedParameter4fNV):
 GL_PREFIX(ProgramNamedParameter4fvNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6120(%rax), %r11
+       movq    6200(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -28960,13 +29322,13 @@ GL_PREFIX(ProgramNamedParameter4fvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6120(%rax), %r11
+       movq    6200(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6120(%rax), %r11
+       movq    6200(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -28980,19 +29342,19 @@ GL_PREFIX(ProgramNamedParameter4fvNV):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6120(%rax), %r11
+       movq    6200(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(ProgramNamedParameter4fvNV), .-GL_PREFIX(ProgramNamedParameter4fvNV)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_766)
-       .type   GL_PREFIX(_dispatch_stub_766), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_766))
-GL_PREFIX(_dispatch_stub_766):
+       .globl  GL_PREFIX(_dispatch_stub_776)
+       .type   GL_PREFIX(_dispatch_stub_776), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_776))
+GL_PREFIX(_dispatch_stub_776):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6128(%rax), %r11
+       movq    6208(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29002,13 +29364,13 @@ GL_PREFIX(_dispatch_stub_766):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6128(%rax), %r11
+       movq    6208(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6128(%rax), %r11
+       movq    6208(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29018,19 +29380,19 @@ GL_PREFIX(_dispatch_stub_766):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6128(%rax), %r11
+       movq    6208(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_766), .-GL_PREFIX(_dispatch_stub_766)
+       .size   GL_PREFIX(_dispatch_stub_776), .-GL_PREFIX(_dispatch_stub_776)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_767)
-       .type   GL_PREFIX(_dispatch_stub_767), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_767))
-GL_PREFIX(_dispatch_stub_767):
+       .globl  GL_PREFIX(_dispatch_stub_777)
+       .type   GL_PREFIX(_dispatch_stub_777), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_777))
+GL_PREFIX(_dispatch_stub_777):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6136(%rax), %r11
+       movq    6216(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29040,13 +29402,13 @@ GL_PREFIX(_dispatch_stub_767):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6136(%rax), %r11
+       movq    6216(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6136(%rax), %r11
+       movq    6216(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29056,10 +29418,10 @@ GL_PREFIX(_dispatch_stub_767):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6136(%rax), %r11
+       movq    6216(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_767), .-GL_PREFIX(_dispatch_stub_767)
+       .size   GL_PREFIX(_dispatch_stub_777), .-GL_PREFIX(_dispatch_stub_777)
 
        .p2align        4,,15
        .globl  GL_PREFIX(BindFramebufferEXT)
@@ -29067,7 +29429,7 @@ GL_PREFIX(_dispatch_stub_767):
 GL_PREFIX(BindFramebufferEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6144(%rax), %r11
+       movq    6224(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29077,13 +29439,13 @@ GL_PREFIX(BindFramebufferEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6144(%rax), %r11
+       movq    6224(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6144(%rax), %r11
+       movq    6224(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29093,7 +29455,7 @@ GL_PREFIX(BindFramebufferEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6144(%rax), %r11
+       movq    6224(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(BindFramebufferEXT), .-GL_PREFIX(BindFramebufferEXT)
@@ -29104,7 +29466,7 @@ GL_PREFIX(BindFramebufferEXT):
 GL_PREFIX(BindRenderbufferEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6152(%rax), %r11
+       movq    6232(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29114,13 +29476,13 @@ GL_PREFIX(BindRenderbufferEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6152(%rax), %r11
+       movq    6232(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6152(%rax), %r11
+       movq    6232(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29130,7 +29492,7 @@ GL_PREFIX(BindRenderbufferEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6152(%rax), %r11
+       movq    6232(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(BindRenderbufferEXT), .-GL_PREFIX(BindRenderbufferEXT)
@@ -29141,25 +29503,25 @@ GL_PREFIX(BindRenderbufferEXT):
 GL_PREFIX(CheckFramebufferStatusEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6160(%rax), %r11
+       movq    6240(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    6160(%rax), %r11
+       movq    6240(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6160(%rax), %r11
+       movq    6240(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    6160(%rax), %r11
+       movq    6240(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(CheckFramebufferStatusEXT), .-GL_PREFIX(CheckFramebufferStatusEXT)
@@ -29170,7 +29532,7 @@ GL_PREFIX(CheckFramebufferStatusEXT):
 GL_PREFIX(DeleteFramebuffersEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6168(%rax), %r11
+       movq    6248(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29180,13 +29542,13 @@ GL_PREFIX(DeleteFramebuffersEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6168(%rax), %r11
+       movq    6248(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6168(%rax), %r11
+       movq    6248(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29196,7 +29558,7 @@ GL_PREFIX(DeleteFramebuffersEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6168(%rax), %r11
+       movq    6248(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(DeleteFramebuffersEXT), .-GL_PREFIX(DeleteFramebuffersEXT)
@@ -29207,7 +29569,7 @@ GL_PREFIX(DeleteFramebuffersEXT):
 GL_PREFIX(DeleteRenderbuffersEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6176(%rax), %r11
+       movq    6256(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29217,13 +29579,13 @@ GL_PREFIX(DeleteRenderbuffersEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6176(%rax), %r11
+       movq    6256(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6176(%rax), %r11
+       movq    6256(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29233,7 +29595,7 @@ GL_PREFIX(DeleteRenderbuffersEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6176(%rax), %r11
+       movq    6256(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(DeleteRenderbuffersEXT), .-GL_PREFIX(DeleteRenderbuffersEXT)
@@ -29244,7 +29606,7 @@ GL_PREFIX(DeleteRenderbuffersEXT):
 GL_PREFIX(FramebufferRenderbufferEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6184(%rax), %r11
+       movq    6264(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29258,13 +29620,13 @@ GL_PREFIX(FramebufferRenderbufferEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6184(%rax), %r11
+       movq    6264(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6184(%rax), %r11
+       movq    6264(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29278,7 +29640,7 @@ GL_PREFIX(FramebufferRenderbufferEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6184(%rax), %r11
+       movq    6264(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(FramebufferRenderbufferEXT), .-GL_PREFIX(FramebufferRenderbufferEXT)
@@ -29289,7 +29651,7 @@ GL_PREFIX(FramebufferRenderbufferEXT):
 GL_PREFIX(FramebufferTexture1DEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6192(%rax), %r11
+       movq    6272(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29303,13 +29665,13 @@ GL_PREFIX(FramebufferTexture1DEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6192(%rax), %r11
+       movq    6272(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6192(%rax), %r11
+       movq    6272(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29323,7 +29685,7 @@ GL_PREFIX(FramebufferTexture1DEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6192(%rax), %r11
+       movq    6272(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(FramebufferTexture1DEXT), .-GL_PREFIX(FramebufferTexture1DEXT)
@@ -29334,7 +29696,7 @@ GL_PREFIX(FramebufferTexture1DEXT):
 GL_PREFIX(FramebufferTexture2DEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6200(%rax), %r11
+       movq    6280(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29348,13 +29710,13 @@ GL_PREFIX(FramebufferTexture2DEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6200(%rax), %r11
+       movq    6280(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6200(%rax), %r11
+       movq    6280(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29368,7 +29730,7 @@ GL_PREFIX(FramebufferTexture2DEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6200(%rax), %r11
+       movq    6280(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(FramebufferTexture2DEXT), .-GL_PREFIX(FramebufferTexture2DEXT)
@@ -29379,7 +29741,7 @@ GL_PREFIX(FramebufferTexture2DEXT):
 GL_PREFIX(FramebufferTexture3DEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6208(%rax), %r11
+       movq    6288(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29397,13 +29759,13 @@ GL_PREFIX(FramebufferTexture3DEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6208(%rax), %r11
+       movq    6288(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6208(%rax), %r11
+       movq    6288(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29421,7 +29783,7 @@ GL_PREFIX(FramebufferTexture3DEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6208(%rax), %r11
+       movq    6288(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(FramebufferTexture3DEXT), .-GL_PREFIX(FramebufferTexture3DEXT)
@@ -29432,7 +29794,7 @@ GL_PREFIX(FramebufferTexture3DEXT):
 GL_PREFIX(GenFramebuffersEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6216(%rax), %r11
+       movq    6296(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29442,13 +29804,13 @@ GL_PREFIX(GenFramebuffersEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6216(%rax), %r11
+       movq    6296(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6216(%rax), %r11
+       movq    6296(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29458,7 +29820,7 @@ GL_PREFIX(GenFramebuffersEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6216(%rax), %r11
+       movq    6296(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GenFramebuffersEXT), .-GL_PREFIX(GenFramebuffersEXT)
@@ -29469,7 +29831,7 @@ GL_PREFIX(GenFramebuffersEXT):
 GL_PREFIX(GenRenderbuffersEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6224(%rax), %r11
+       movq    6304(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29479,13 +29841,13 @@ GL_PREFIX(GenRenderbuffersEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6224(%rax), %r11
+       movq    6304(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6224(%rax), %r11
+       movq    6304(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29495,7 +29857,7 @@ GL_PREFIX(GenRenderbuffersEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6224(%rax), %r11
+       movq    6304(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GenRenderbuffersEXT), .-GL_PREFIX(GenRenderbuffersEXT)
@@ -29506,25 +29868,25 @@ GL_PREFIX(GenRenderbuffersEXT):
 GL_PREFIX(GenerateMipmapEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6232(%rax), %r11
+       movq    6312(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    6232(%rax), %r11
+       movq    6312(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6232(%rax), %r11
+       movq    6312(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    6232(%rax), %r11
+       movq    6312(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GenerateMipmapEXT), .-GL_PREFIX(GenerateMipmapEXT)
@@ -29535,7 +29897,7 @@ GL_PREFIX(GenerateMipmapEXT):
 GL_PREFIX(GetFramebufferAttachmentParameterivEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6240(%rax), %r11
+       movq    6320(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29549,13 +29911,13 @@ GL_PREFIX(GetFramebufferAttachmentParameterivEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6240(%rax), %r11
+       movq    6320(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6240(%rax), %r11
+       movq    6320(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29569,7 +29931,7 @@ GL_PREFIX(GetFramebufferAttachmentParameterivEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6240(%rax), %r11
+       movq    6320(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetFramebufferAttachmentParameterivEXT), .-GL_PREFIX(GetFramebufferAttachmentParameterivEXT)
@@ -29580,7 +29942,7 @@ GL_PREFIX(GetFramebufferAttachmentParameterivEXT):
 GL_PREFIX(GetRenderbufferParameterivEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6248(%rax), %r11
+       movq    6328(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29590,13 +29952,13 @@ GL_PREFIX(GetRenderbufferParameterivEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6248(%rax), %r11
+       movq    6328(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6248(%rax), %r11
+       movq    6328(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29606,7 +29968,7 @@ GL_PREFIX(GetRenderbufferParameterivEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6248(%rax), %r11
+       movq    6328(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetRenderbufferParameterivEXT), .-GL_PREFIX(GetRenderbufferParameterivEXT)
@@ -29617,25 +29979,25 @@ GL_PREFIX(GetRenderbufferParameterivEXT):
 GL_PREFIX(IsFramebufferEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6256(%rax), %r11
+       movq    6336(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    6256(%rax), %r11
+       movq    6336(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6256(%rax), %r11
+       movq    6336(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    6256(%rax), %r11
+       movq    6336(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(IsFramebufferEXT), .-GL_PREFIX(IsFramebufferEXT)
@@ -29646,25 +30008,25 @@ GL_PREFIX(IsFramebufferEXT):
 GL_PREFIX(IsRenderbufferEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6264(%rax), %r11
+       movq    6344(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    6264(%rax), %r11
+       movq    6344(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6264(%rax), %r11
+       movq    6344(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    6264(%rax), %r11
+       movq    6344(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(IsRenderbufferEXT), .-GL_PREFIX(IsRenderbufferEXT)
@@ -29675,7 +30037,7 @@ GL_PREFIX(IsRenderbufferEXT):
 GL_PREFIX(RenderbufferStorageEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6272(%rax), %r11
+       movq    6352(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29689,13 +30051,13 @@ GL_PREFIX(RenderbufferStorageEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6272(%rax), %r11
+       movq    6352(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6272(%rax), %r11
+       movq    6352(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29709,19 +30071,19 @@ GL_PREFIX(RenderbufferStorageEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6272(%rax), %r11
+       movq    6352(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(RenderbufferStorageEXT), .-GL_PREFIX(RenderbufferStorageEXT)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_785)
-       .type   GL_PREFIX(_dispatch_stub_785), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_785))
-GL_PREFIX(_dispatch_stub_785):
+       .globl  GL_PREFIX(_dispatch_stub_795)
+       .type   GL_PREFIX(_dispatch_stub_795), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_795))
+GL_PREFIX(_dispatch_stub_795):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6280(%rax), %r11
+       movq    6360(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29739,13 +30101,13 @@ GL_PREFIX(_dispatch_stub_785):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6280(%rax), %r11
+       movq    6360(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6280(%rax), %r11
+       movq    6360(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29763,19 +30125,19 @@ GL_PREFIX(_dispatch_stub_785):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6280(%rax), %r11
+       movq    6360(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_785), .-GL_PREFIX(_dispatch_stub_785)
+       .size   GL_PREFIX(_dispatch_stub_795), .-GL_PREFIX(_dispatch_stub_795)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_786)
-       .type   GL_PREFIX(_dispatch_stub_786), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_786))
-GL_PREFIX(_dispatch_stub_786):
+       .globl  GL_PREFIX(_dispatch_stub_796)
+       .type   GL_PREFIX(_dispatch_stub_796), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_796))
+GL_PREFIX(_dispatch_stub_796):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6288(%rax), %r11
+       movq    6368(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29785,13 +30147,13 @@ GL_PREFIX(_dispatch_stub_786):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6288(%rax), %r11
+       movq    6368(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6288(%rax), %r11
+       movq    6368(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29801,19 +30163,19 @@ GL_PREFIX(_dispatch_stub_786):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6288(%rax), %r11
+       movq    6368(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_786), .-GL_PREFIX(_dispatch_stub_786)
+       .size   GL_PREFIX(_dispatch_stub_796), .-GL_PREFIX(_dispatch_stub_796)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_787)
-       .type   GL_PREFIX(_dispatch_stub_787), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_787))
-GL_PREFIX(_dispatch_stub_787):
+       .globl  GL_PREFIX(_dispatch_stub_797)
+       .type   GL_PREFIX(_dispatch_stub_797), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_797))
+GL_PREFIX(_dispatch_stub_797):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6296(%rax), %r11
+       movq    6376(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29823,13 +30185,13 @@ GL_PREFIX(_dispatch_stub_787):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6296(%rax), %r11
+       movq    6376(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6296(%rax), %r11
+       movq    6376(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29839,10 +30201,10 @@ GL_PREFIX(_dispatch_stub_787):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6296(%rax), %r11
+       movq    6376(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_787), .-GL_PREFIX(_dispatch_stub_787)
+       .size   GL_PREFIX(_dispatch_stub_797), .-GL_PREFIX(_dispatch_stub_797)
 
        .p2align        4,,15
        .globl  GL_PREFIX(FramebufferTextureLayerEXT)
@@ -29850,7 +30212,7 @@ GL_PREFIX(_dispatch_stub_787):
 GL_PREFIX(FramebufferTextureLayerEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6304(%rax), %r11
+       movq    6384(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29864,13 +30226,13 @@ GL_PREFIX(FramebufferTextureLayerEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6304(%rax), %r11
+       movq    6384(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6304(%rax), %r11
+       movq    6384(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29884,7 +30246,7 @@ GL_PREFIX(FramebufferTextureLayerEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6304(%rax), %r11
+       movq    6384(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(FramebufferTextureLayerEXT), .-GL_PREFIX(FramebufferTextureLayerEXT)
@@ -29895,7 +30257,7 @@ GL_PREFIX(FramebufferTextureLayerEXT):
 GL_PREFIX(ColorMaskIndexedEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6312(%rax), %r11
+       movq    6392(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29909,13 +30271,13 @@ GL_PREFIX(ColorMaskIndexedEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6312(%rax), %r11
+       movq    6392(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6312(%rax), %r11
+       movq    6392(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29929,7 +30291,7 @@ GL_PREFIX(ColorMaskIndexedEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6312(%rax), %r11
+       movq    6392(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(ColorMaskIndexedEXT), .-GL_PREFIX(ColorMaskIndexedEXT)
@@ -29940,7 +30302,7 @@ GL_PREFIX(ColorMaskIndexedEXT):
 GL_PREFIX(DisableIndexedEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6320(%rax), %r11
+       movq    6400(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29950,13 +30312,13 @@ GL_PREFIX(DisableIndexedEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6320(%rax), %r11
+       movq    6400(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6320(%rax), %r11
+       movq    6400(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -29966,7 +30328,7 @@ GL_PREFIX(DisableIndexedEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6320(%rax), %r11
+       movq    6400(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(DisableIndexedEXT), .-GL_PREFIX(DisableIndexedEXT)
@@ -29977,7 +30339,7 @@ GL_PREFIX(DisableIndexedEXT):
 GL_PREFIX(EnableIndexedEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6328(%rax), %r11
+       movq    6408(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -29987,13 +30349,13 @@ GL_PREFIX(EnableIndexedEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6328(%rax), %r11
+       movq    6408(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6328(%rax), %r11
+       movq    6408(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30003,7 +30365,7 @@ GL_PREFIX(EnableIndexedEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6328(%rax), %r11
+       movq    6408(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(EnableIndexedEXT), .-GL_PREFIX(EnableIndexedEXT)
@@ -30014,7 +30376,7 @@ GL_PREFIX(EnableIndexedEXT):
 GL_PREFIX(GetBooleanIndexedvEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6336(%rax), %r11
+       movq    6416(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30024,13 +30386,13 @@ GL_PREFIX(GetBooleanIndexedvEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6336(%rax), %r11
+       movq    6416(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6336(%rax), %r11
+       movq    6416(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30040,7 +30402,7 @@ GL_PREFIX(GetBooleanIndexedvEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6336(%rax), %r11
+       movq    6416(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetBooleanIndexedvEXT), .-GL_PREFIX(GetBooleanIndexedvEXT)
@@ -30051,7 +30413,7 @@ GL_PREFIX(GetBooleanIndexedvEXT):
 GL_PREFIX(GetIntegerIndexedvEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6344(%rax), %r11
+       movq    6424(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30061,13 +30423,13 @@ GL_PREFIX(GetIntegerIndexedvEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6344(%rax), %r11
+       movq    6424(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6344(%rax), %r11
+       movq    6424(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30077,7 +30439,7 @@ GL_PREFIX(GetIntegerIndexedvEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6344(%rax), %r11
+       movq    6424(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetIntegerIndexedvEXT), .-GL_PREFIX(GetIntegerIndexedvEXT)
@@ -30088,7 +30450,7 @@ GL_PREFIX(GetIntegerIndexedvEXT):
 GL_PREFIX(IsEnabledIndexedEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6352(%rax), %r11
+       movq    6432(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30098,13 +30460,13 @@ GL_PREFIX(IsEnabledIndexedEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6352(%rax), %r11
+       movq    6432(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6352(%rax), %r11
+       movq    6432(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30114,7 +30476,7 @@ GL_PREFIX(IsEnabledIndexedEXT):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6352(%rax), %r11
+       movq    6432(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(IsEnabledIndexedEXT), .-GL_PREFIX(IsEnabledIndexedEXT)
@@ -30125,7 +30487,7 @@ GL_PREFIX(IsEnabledIndexedEXT):
 GL_PREFIX(BeginConditionalRenderNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6360(%rax), %r11
+       movq    6440(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30135,13 +30497,13 @@ GL_PREFIX(BeginConditionalRenderNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6360(%rax), %r11
+       movq    6440(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6360(%rax), %r11
+       movq    6440(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30151,7 +30513,7 @@ GL_PREFIX(BeginConditionalRenderNV):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6360(%rax), %r11
+       movq    6440(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(BeginConditionalRenderNV), .-GL_PREFIX(BeginConditionalRenderNV)
@@ -30162,25 +30524,25 @@ GL_PREFIX(BeginConditionalRenderNV):
 GL_PREFIX(EndConditionalRenderNV):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6368(%rax), %r11
+       movq    6448(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rbp
        call    _x86_64_get_dispatch@PLT
        popq    %rbp
-       movq    6368(%rax), %r11
+       movq    6448(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6368(%rax), %r11
+       movq    6448(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rbp
        call    _glapi_get_dispatch
        popq    %rbp
-       movq    6368(%rax), %r11
+       movq    6448(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(EndConditionalRenderNV), .-GL_PREFIX(EndConditionalRenderNV)
@@ -30191,25 +30553,25 @@ GL_PREFIX(EndConditionalRenderNV):
 GL_PREFIX(BeginTransformFeedbackEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6376(%rax), %r11
+       movq    6456(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    6376(%rax), %r11
+       movq    6456(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6376(%rax), %r11
+       movq    6456(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    6376(%rax), %r11
+       movq    6456(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(BeginTransformFeedbackEXT), .-GL_PREFIX(BeginTransformFeedbackEXT)
@@ -30220,7 +30582,7 @@ GL_PREFIX(BeginTransformFeedbackEXT):
 GL_PREFIX(BindBufferBaseEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6384(%rax), %r11
+       movq    6464(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30230,13 +30592,13 @@ GL_PREFIX(BindBufferBaseEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6384(%rax), %r11
+       movq    6464(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6384(%rax), %r11
+       movq    6464(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30246,7 +30608,7 @@ GL_PREFIX(BindBufferBaseEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6384(%rax), %r11
+       movq    6464(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(BindBufferBaseEXT), .-GL_PREFIX(BindBufferBaseEXT)
@@ -30257,7 +30619,7 @@ GL_PREFIX(BindBufferBaseEXT):
 GL_PREFIX(BindBufferOffsetEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6392(%rax), %r11
+       movq    6472(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30271,13 +30633,13 @@ GL_PREFIX(BindBufferOffsetEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6392(%rax), %r11
+       movq    6472(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6392(%rax), %r11
+       movq    6472(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30291,7 +30653,7 @@ GL_PREFIX(BindBufferOffsetEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6392(%rax), %r11
+       movq    6472(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(BindBufferOffsetEXT), .-GL_PREFIX(BindBufferOffsetEXT)
@@ -30302,7 +30664,7 @@ GL_PREFIX(BindBufferOffsetEXT):
 GL_PREFIX(BindBufferRangeEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6400(%rax), %r11
+       movq    6480(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30316,13 +30678,13 @@ GL_PREFIX(BindBufferRangeEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6400(%rax), %r11
+       movq    6480(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6400(%rax), %r11
+       movq    6480(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30336,7 +30698,7 @@ GL_PREFIX(BindBufferRangeEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6400(%rax), %r11
+       movq    6480(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(BindBufferRangeEXT), .-GL_PREFIX(BindBufferRangeEXT)
@@ -30347,25 +30709,25 @@ GL_PREFIX(BindBufferRangeEXT):
 GL_PREFIX(EndTransformFeedbackEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6408(%rax), %r11
+       movq    6488(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rbp
        call    _x86_64_get_dispatch@PLT
        popq    %rbp
-       movq    6408(%rax), %r11
+       movq    6488(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6408(%rax), %r11
+       movq    6488(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rbp
        call    _glapi_get_dispatch
        popq    %rbp
-       movq    6408(%rax), %r11
+       movq    6488(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(EndTransformFeedbackEXT), .-GL_PREFIX(EndTransformFeedbackEXT)
@@ -30376,7 +30738,7 @@ GL_PREFIX(EndTransformFeedbackEXT):
 GL_PREFIX(GetTransformFeedbackVaryingEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6416(%rax), %r11
+       movq    6496(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30394,13 +30756,13 @@ GL_PREFIX(GetTransformFeedbackVaryingEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6416(%rax), %r11
+       movq    6496(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6416(%rax), %r11
+       movq    6496(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30418,7 +30780,7 @@ GL_PREFIX(GetTransformFeedbackVaryingEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6416(%rax), %r11
+       movq    6496(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetTransformFeedbackVaryingEXT), .-GL_PREFIX(GetTransformFeedbackVaryingEXT)
@@ -30429,7 +30791,7 @@ GL_PREFIX(GetTransformFeedbackVaryingEXT):
 GL_PREFIX(TransformFeedbackVaryingsEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6424(%rax), %r11
+       movq    6504(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30443,13 +30805,13 @@ GL_PREFIX(TransformFeedbackVaryingsEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6424(%rax), %r11
+       movq    6504(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6424(%rax), %r11
+       movq    6504(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30463,7 +30825,7 @@ GL_PREFIX(TransformFeedbackVaryingsEXT):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6424(%rax), %r11
+       movq    6504(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(TransformFeedbackVaryingsEXT), .-GL_PREFIX(TransformFeedbackVaryingsEXT)
@@ -30474,37 +30836,37 @@ GL_PREFIX(TransformFeedbackVaryingsEXT):
 GL_PREFIX(ProvokingVertexEXT):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6432(%rax), %r11
+       movq    6512(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
        call    _x86_64_get_dispatch@PLT
        popq    %rdi
-       movq    6432(%rax), %r11
+       movq    6512(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6432(%rax), %r11
+       movq    6512(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
        call    _glapi_get_dispatch
        popq    %rdi
-       movq    6432(%rax), %r11
+       movq    6512(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(ProvokingVertexEXT), .-GL_PREFIX(ProvokingVertexEXT)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_805)
-       .type   GL_PREFIX(_dispatch_stub_805), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_805))
-GL_PREFIX(_dispatch_stub_805):
+       .globl  GL_PREFIX(_dispatch_stub_815)
+       .type   GL_PREFIX(_dispatch_stub_815), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_815))
+GL_PREFIX(_dispatch_stub_815):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6440(%rax), %r11
+       movq    6520(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30514,13 +30876,13 @@ GL_PREFIX(_dispatch_stub_805):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6440(%rax), %r11
+       movq    6520(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6440(%rax), %r11
+       movq    6520(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30530,19 +30892,19 @@ GL_PREFIX(_dispatch_stub_805):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6440(%rax), %r11
+       movq    6520(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_805), .-GL_PREFIX(_dispatch_stub_805)
+       .size   GL_PREFIX(_dispatch_stub_815), .-GL_PREFIX(_dispatch_stub_815)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_806)
-       .type   GL_PREFIX(_dispatch_stub_806), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_806))
-GL_PREFIX(_dispatch_stub_806):
+       .globl  GL_PREFIX(_dispatch_stub_816)
+       .type   GL_PREFIX(_dispatch_stub_816), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_816))
+GL_PREFIX(_dispatch_stub_816):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6448(%rax), %r11
+       movq    6528(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30552,13 +30914,13 @@ GL_PREFIX(_dispatch_stub_806):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6448(%rax), %r11
+       movq    6528(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6448(%rax), %r11
+       movq    6528(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30568,10 +30930,10 @@ GL_PREFIX(_dispatch_stub_806):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6448(%rax), %r11
+       movq    6528(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_806), .-GL_PREFIX(_dispatch_stub_806)
+       .size   GL_PREFIX(_dispatch_stub_816), .-GL_PREFIX(_dispatch_stub_816)
 
        .p2align        4,,15
        .globl  GL_PREFIX(GetObjectParameterivAPPLE)
@@ -30579,7 +30941,7 @@ GL_PREFIX(_dispatch_stub_806):
 GL_PREFIX(GetObjectParameterivAPPLE):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6456(%rax), %r11
+       movq    6536(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30593,13 +30955,13 @@ GL_PREFIX(GetObjectParameterivAPPLE):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6456(%rax), %r11
+       movq    6536(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6456(%rax), %r11
+       movq    6536(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30613,7 +30975,7 @@ GL_PREFIX(GetObjectParameterivAPPLE):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6456(%rax), %r11
+       movq    6536(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(GetObjectParameterivAPPLE), .-GL_PREFIX(GetObjectParameterivAPPLE)
@@ -30624,7 +30986,7 @@ GL_PREFIX(GetObjectParameterivAPPLE):
 GL_PREFIX(ObjectPurgeableAPPLE):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6464(%rax), %r11
+       movq    6544(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30634,13 +30996,13 @@ GL_PREFIX(ObjectPurgeableAPPLE):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6464(%rax), %r11
+       movq    6544(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6464(%rax), %r11
+       movq    6544(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30650,7 +31012,7 @@ GL_PREFIX(ObjectPurgeableAPPLE):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6464(%rax), %r11
+       movq    6544(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(ObjectPurgeableAPPLE), .-GL_PREFIX(ObjectPurgeableAPPLE)
@@ -30661,7 +31023,7 @@ GL_PREFIX(ObjectPurgeableAPPLE):
 GL_PREFIX(ObjectUnpurgeableAPPLE):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6472(%rax), %r11
+       movq    6552(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30671,13 +31033,13 @@ GL_PREFIX(ObjectUnpurgeableAPPLE):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6472(%rax), %r11
+       movq    6552(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6472(%rax), %r11
+       movq    6552(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30687,19 +31049,19 @@ GL_PREFIX(ObjectUnpurgeableAPPLE):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6472(%rax), %r11
+       movq    6552(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(ObjectUnpurgeableAPPLE), .-GL_PREFIX(ObjectUnpurgeableAPPLE)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_810)
-       .type   GL_PREFIX(_dispatch_stub_810), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_810))
-GL_PREFIX(_dispatch_stub_810):
+       .globl  GL_PREFIX(_dispatch_stub_820)
+       .type   GL_PREFIX(_dispatch_stub_820), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_820))
+GL_PREFIX(_dispatch_stub_820):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6480(%rax), %r11
+       movq    6560(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30713,13 +31075,13 @@ GL_PREFIX(_dispatch_stub_810):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6480(%rax), %r11
+       movq    6560(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6480(%rax), %r11
+       movq    6560(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30733,19 +31095,19 @@ GL_PREFIX(_dispatch_stub_810):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6480(%rax), %r11
+       movq    6560(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_810), .-GL_PREFIX(_dispatch_stub_810)
+       .size   GL_PREFIX(_dispatch_stub_820), .-GL_PREFIX(_dispatch_stub_820)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_811)
-       .type   GL_PREFIX(_dispatch_stub_811), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_811))
-GL_PREFIX(_dispatch_stub_811):
+       .globl  GL_PREFIX(_dispatch_stub_821)
+       .type   GL_PREFIX(_dispatch_stub_821), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_821))
+GL_PREFIX(_dispatch_stub_821):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6488(%rax), %r11
+       movq    6568(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30759,13 +31121,13 @@ GL_PREFIX(_dispatch_stub_811):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6488(%rax), %r11
+       movq    6568(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6488(%rax), %r11
+       movq    6568(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30779,19 +31141,19 @@ GL_PREFIX(_dispatch_stub_811):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6488(%rax), %r11
+       movq    6568(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_811), .-GL_PREFIX(_dispatch_stub_811)
+       .size   GL_PREFIX(_dispatch_stub_821), .-GL_PREFIX(_dispatch_stub_821)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_812)
-       .type   GL_PREFIX(_dispatch_stub_812), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_812))
-GL_PREFIX(_dispatch_stub_812):
+       .globl  GL_PREFIX(_dispatch_stub_822)
+       .type   GL_PREFIX(_dispatch_stub_822), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_822))
+GL_PREFIX(_dispatch_stub_822):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6496(%rax), %r11
+       movq    6576(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30805,13 +31167,13 @@ GL_PREFIX(_dispatch_stub_812):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6496(%rax), %r11
+       movq    6576(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6496(%rax), %r11
+       movq    6576(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30825,19 +31187,19 @@ GL_PREFIX(_dispatch_stub_812):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6496(%rax), %r11
+       movq    6576(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_812), .-GL_PREFIX(_dispatch_stub_812)
+       .size   GL_PREFIX(_dispatch_stub_822), .-GL_PREFIX(_dispatch_stub_822)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_813)
-       .type   GL_PREFIX(_dispatch_stub_813), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_813))
-GL_PREFIX(_dispatch_stub_813):
+       .globl  GL_PREFIX(_dispatch_stub_823)
+       .type   GL_PREFIX(_dispatch_stub_823), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_823))
+GL_PREFIX(_dispatch_stub_823):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6504(%rax), %r11
+       movq    6584(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30847,13 +31209,13 @@ GL_PREFIX(_dispatch_stub_813):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6504(%rax), %r11
+       movq    6584(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6504(%rax), %r11
+       movq    6584(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30863,19 +31225,19 @@ GL_PREFIX(_dispatch_stub_813):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6504(%rax), %r11
+       movq    6584(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_813), .-GL_PREFIX(_dispatch_stub_813)
+       .size   GL_PREFIX(_dispatch_stub_823), .-GL_PREFIX(_dispatch_stub_823)
 
        .p2align        4,,15
-       .globl  GL_PREFIX(_dispatch_stub_814)
-       .type   GL_PREFIX(_dispatch_stub_814), @function
-       HIDDEN(GL_PREFIX(_dispatch_stub_814))
-GL_PREFIX(_dispatch_stub_814):
+       .globl  GL_PREFIX(_dispatch_stub_824)
+       .type   GL_PREFIX(_dispatch_stub_824), @function
+       HIDDEN(GL_PREFIX(_dispatch_stub_824))
+GL_PREFIX(_dispatch_stub_824):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6512(%rax), %r11
+       movq    6592(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30885,13 +31247,13 @@ GL_PREFIX(_dispatch_stub_814):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6512(%rax), %r11
+       movq    6592(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6512(%rax), %r11
+       movq    6592(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30901,10 +31263,10 @@ GL_PREFIX(_dispatch_stub_814):
        popq    %rdx
        popq    %rsi
        popq    %rdi
-       movq    6512(%rax), %r11
+       movq    6592(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
-       .size   GL_PREFIX(_dispatch_stub_814), .-GL_PREFIX(_dispatch_stub_814)
+       .size   GL_PREFIX(_dispatch_stub_824), .-GL_PREFIX(_dispatch_stub_824)
 
        .p2align        4,,15
        .globl  GL_PREFIX(EGLImageTargetRenderbufferStorageOES)
@@ -30912,7 +31274,7 @@ GL_PREFIX(_dispatch_stub_814):
 GL_PREFIX(EGLImageTargetRenderbufferStorageOES):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6520(%rax), %r11
+       movq    6600(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30922,13 +31284,13 @@ GL_PREFIX(EGLImageTargetRenderbufferStorageOES):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6520(%rax), %r11
+       movq    6600(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6520(%rax), %r11
+       movq    6600(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30938,7 +31300,7 @@ GL_PREFIX(EGLImageTargetRenderbufferStorageOES):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6520(%rax), %r11
+       movq    6600(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(EGLImageTargetRenderbufferStorageOES), .-GL_PREFIX(EGLImageTargetRenderbufferStorageOES)
@@ -30949,7 +31311,7 @@ GL_PREFIX(EGLImageTargetRenderbufferStorageOES):
 GL_PREFIX(EGLImageTargetTexture2DOES):
 #if defined(GLX_USE_TLS)
        call    _x86_64_get_dispatch@PLT
-       movq    6528(%rax), %r11
+       movq    6608(%rax), %r11
        jmp     *%r11
 #elif defined(PTHREADS)
        pushq   %rdi
@@ -30959,13 +31321,13 @@ GL_PREFIX(EGLImageTargetTexture2DOES):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6528(%rax), %r11
+       movq    6608(%rax), %r11
        jmp     *%r11
 #else
        movq    _glapi_Dispatch(%rip), %rax
        testq   %rax, %rax
        je      1f
-       movq    6528(%rax), %r11
+       movq    6608(%rax), %r11
        jmp     *%r11
 1:
        pushq   %rdi
@@ -30975,7 +31337,7 @@ GL_PREFIX(EGLImageTargetTexture2DOES):
        popq    %rbp
        popq    %rsi
        popq    %rdi
-       movq    6528(%rax), %r11
+       movq    6608(%rax), %r11
        jmp     *%r11
 #endif /* defined(GLX_USE_TLS) */
        .size   GL_PREFIX(EGLImageTargetTexture2DOES), .-GL_PREFIX(EGLImageTargetTexture2DOES)
@@ -31238,9 +31600,9 @@ GL_PREFIX(EGLImageTargetTexture2DOES):
        .globl GL_PREFIX(IsProgramARB) ; .set GL_PREFIX(IsProgramARB), GL_PREFIX(IsProgramNV)
        .globl GL_PREFIX(PointParameteri) ; .set GL_PREFIX(PointParameteri), GL_PREFIX(PointParameteriNV)
        .globl GL_PREFIX(PointParameteriv) ; .set GL_PREFIX(PointParameteriv), GL_PREFIX(PointParameterivNV)
-       .globl GL_PREFIX(DeleteVertexArrays) ; .set GL_PREFIX(DeleteVertexArrays), GL_PREFIX(_dispatch_stub_757)
-       .globl GL_PREFIX(IsVertexArray) ; .set GL_PREFIX(IsVertexArray), GL_PREFIX(_dispatch_stub_759)
-       .globl GL_PREFIX(BlendEquationSeparate) ; .set GL_PREFIX(BlendEquationSeparate), GL_PREFIX(_dispatch_stub_767)
+       .globl GL_PREFIX(DeleteVertexArrays) ; .set GL_PREFIX(DeleteVertexArrays), GL_PREFIX(_dispatch_stub_767)
+       .globl GL_PREFIX(IsVertexArray) ; .set GL_PREFIX(IsVertexArray), GL_PREFIX(_dispatch_stub_769)
+       .globl GL_PREFIX(BlendEquationSeparate) ; .set GL_PREFIX(BlendEquationSeparate), GL_PREFIX(_dispatch_stub_777)
        .globl GL_PREFIX(BindFramebuffer) ; .set GL_PREFIX(BindFramebuffer), GL_PREFIX(BindFramebufferEXT)
        .globl GL_PREFIX(BindRenderbuffer) ; .set GL_PREFIX(BindRenderbuffer), GL_PREFIX(BindRenderbufferEXT)
        .globl GL_PREFIX(CheckFramebufferStatus) ; .set GL_PREFIX(CheckFramebufferStatus), GL_PREFIX(CheckFramebufferStatusEXT)
@@ -31258,7 +31620,7 @@ GL_PREFIX(EGLImageTargetTexture2DOES):
        .globl GL_PREFIX(IsFramebuffer) ; .set GL_PREFIX(IsFramebuffer), GL_PREFIX(IsFramebufferEXT)
        .globl GL_PREFIX(IsRenderbuffer) ; .set GL_PREFIX(IsRenderbuffer), GL_PREFIX(IsRenderbufferEXT)
        .globl GL_PREFIX(RenderbufferStorage) ; .set GL_PREFIX(RenderbufferStorage), GL_PREFIX(RenderbufferStorageEXT)
-       .globl GL_PREFIX(BlitFramebuffer) ; .set GL_PREFIX(BlitFramebuffer), GL_PREFIX(_dispatch_stub_785)
+       .globl GL_PREFIX(BlitFramebuffer) ; .set GL_PREFIX(BlitFramebuffer), GL_PREFIX(_dispatch_stub_795)
        .globl GL_PREFIX(FramebufferTextureLayer) ; .set GL_PREFIX(FramebufferTextureLayer), GL_PREFIX(FramebufferTextureLayerEXT)
        .globl GL_PREFIX(BeginTransformFeedback) ; .set GL_PREFIX(BeginTransformFeedback), GL_PREFIX(BeginTransformFeedbackEXT)
        .globl GL_PREFIX(BindBufferBase) ; .set GL_PREFIX(BindBufferBase), GL_PREFIX(BindBufferBaseEXT)
index 317f595454a11095e3e4edd02e2561c982645c5b..8b764c993cbef33b160fc7b29ae9c5022a35c74a 100644 (file)
@@ -715,6 +715,9 @@ GLNAME(gl_dispatch_functions_start):
        GL_STUB(GetAttribLocationARB, _gloffset_GetAttribLocationARB, GetAttribLocationARB@8)
        GL_STUB(DrawBuffersARB, _gloffset_DrawBuffersARB, DrawBuffersARB@8)
        GL_STUB(RenderbufferStorageMultisample, _gloffset_RenderbufferStorageMultisample, RenderbufferStorageMultisample@20)
+       GL_STUB(FramebufferTextureARB, _gloffset_FramebufferTextureARB, FramebufferTextureARB@16)
+       GL_STUB(FramebufferTextureFaceARB, _gloffset_FramebufferTextureFaceARB, FramebufferTextureFaceARB@20)
+       GL_STUB(ProgramParameteriARB, _gloffset_ProgramParameteriARB, ProgramParameteriARB@12)
        GL_STUB(FlushMappedBufferRange, _gloffset_FlushMappedBufferRange, FlushMappedBufferRange@12)
        GL_STUB(MapBufferRange, _gloffset_MapBufferRange, MapBufferRange@16)
        GL_STUB(BindVertexArray, _gloffset_BindVertexArray, BindVertexArray@4)
@@ -730,23 +733,30 @@ GLNAME(gl_dispatch_functions_start):
        GL_STUB(DrawElementsBaseVertex, _gloffset_DrawElementsBaseVertex, DrawElementsBaseVertex@20)
        GL_STUB(DrawRangeElementsBaseVertex, _gloffset_DrawRangeElementsBaseVertex, DrawRangeElementsBaseVertex@28)
        GL_STUB(MultiDrawElementsBaseVertex, _gloffset_MultiDrawElementsBaseVertex, MultiDrawElementsBaseVertex@24)
+       GL_STUB(BindTransformFeedback, _gloffset_BindTransformFeedback, BindTransformFeedback@8)
+       GL_STUB(DeleteTransformFeedbacks, _gloffset_DeleteTransformFeedbacks, DeleteTransformFeedbacks@8)
+       GL_STUB(DrawTransformFeedback, _gloffset_DrawTransformFeedback, DrawTransformFeedback@8)
+       GL_STUB(GenTransformFeedbacks, _gloffset_GenTransformFeedbacks, GenTransformFeedbacks@8)
+       GL_STUB(IsTransformFeedback, _gloffset_IsTransformFeedback, IsTransformFeedback@4)
+       GL_STUB(PauseTransformFeedback, _gloffset_PauseTransformFeedback, PauseTransformFeedback@0)
+       GL_STUB(ResumeTransformFeedback, _gloffset_ResumeTransformFeedback, ResumeTransformFeedback@0)
        GL_STUB(PolygonOffsetEXT, _gloffset_PolygonOffsetEXT, PolygonOffsetEXT@8)
-       GL_STUB(_dispatch_stub_580, _gloffset_GetPixelTexGenParameterfvSGIS, _dispatch_stub_580@8)
-       HIDDEN(GL_PREFIX(_dispatch_stub_580, _dispatch_stub_580@8))
-       GL_STUB(_dispatch_stub_581, _gloffset_GetPixelTexGenParameterivSGIS, _dispatch_stub_581@8)
-       HIDDEN(GL_PREFIX(_dispatch_stub_581, _dispatch_stub_581@8))
-       GL_STUB(_dispatch_stub_582, _gloffset_PixelTexGenParameterfSGIS, _dispatch_stub_582@8)
-       HIDDEN(GL_PREFIX(_dispatch_stub_582, _dispatch_stub_582@8))
-       GL_STUB(_dispatch_stub_583, _gloffset_PixelTexGenParameterfvSGIS, _dispatch_stub_583@8)
-       HIDDEN(GL_PREFIX(_dispatch_stub_583, _dispatch_stub_583@8))
-       GL_STUB(_dispatch_stub_584, _gloffset_PixelTexGenParameteriSGIS, _dispatch_stub_584@8)
-       HIDDEN(GL_PREFIX(_dispatch_stub_584, _dispatch_stub_584@8))
-       GL_STUB(_dispatch_stub_585, _gloffset_PixelTexGenParameterivSGIS, _dispatch_stub_585@8)
-       HIDDEN(GL_PREFIX(_dispatch_stub_585, _dispatch_stub_585@8))
-       GL_STUB(_dispatch_stub_586, _gloffset_SampleMaskSGIS, _dispatch_stub_586@8)
-       HIDDEN(GL_PREFIX(_dispatch_stub_586, _dispatch_stub_586@8))
-       GL_STUB(_dispatch_stub_587, _gloffset_SamplePatternSGIS, _dispatch_stub_587@4)
-       HIDDEN(GL_PREFIX(_dispatch_stub_587, _dispatch_stub_587@4))
+       GL_STUB(_dispatch_stub_590, _gloffset_GetPixelTexGenParameterfvSGIS, _dispatch_stub_590@8)
+       HIDDEN(GL_PREFIX(_dispatch_stub_590, _dispatch_stub_590@8))
+       GL_STUB(_dispatch_stub_591, _gloffset_GetPixelTexGenParameterivSGIS, _dispatch_stub_591@8)
+       HIDDEN(GL_PREFIX(_dispatch_stub_591, _dispatch_stub_591@8))
+       GL_STUB(_dispatch_stub_592, _gloffset_PixelTexGenParameterfSGIS, _dispatch_stub_592@8)
+       HIDDEN(GL_PREFIX(_dispatch_stub_592, _dispatch_stub_592@8))
+       GL_STUB(_dispatch_stub_593, _gloffset_PixelTexGenParameterfvSGIS, _dispatch_stub_593@8)
+       HIDDEN(GL_PREFIX(_dispatch_stub_593, _dispatch_stub_593@8))
+       GL_STUB(_dispatch_stub_594, _gloffset_PixelTexGenParameteriSGIS, _dispatch_stub_594@8)
+       HIDDEN(GL_PREFIX(_dispatch_stub_594, _dispatch_stub_594@8))
+       GL_STUB(_dispatch_stub_595, _gloffset_PixelTexGenParameterivSGIS, _dispatch_stub_595@8)
+       HIDDEN(GL_PREFIX(_dispatch_stub_595, _dispatch_stub_595@8))
+       GL_STUB(_dispatch_stub_596, _gloffset_SampleMaskSGIS, _dispatch_stub_596@8)
+       HIDDEN(GL_PREFIX(_dispatch_stub_596, _dispatch_stub_596@8))
+       GL_STUB(_dispatch_stub_597, _gloffset_SamplePatternSGIS, _dispatch_stub_597@4)
+       HIDDEN(GL_PREFIX(_dispatch_stub_597, _dispatch_stub_597@4))
        GL_STUB(ColorPointerEXT, _gloffset_ColorPointerEXT, ColorPointerEXT@20)
        GL_STUB(EdgeFlagPointerEXT, _gloffset_EdgeFlagPointerEXT, EdgeFlagPointerEXT@12)
        GL_STUB(IndexPointerEXT, _gloffset_IndexPointerEXT, IndexPointerEXT@16)
@@ -757,10 +767,10 @@ GLNAME(gl_dispatch_functions_start):
        GL_STUB(PointParameterfvEXT, _gloffset_PointParameterfvEXT, PointParameterfvEXT@8)
        GL_STUB(LockArraysEXT, _gloffset_LockArraysEXT, LockArraysEXT@8)
        GL_STUB(UnlockArraysEXT, _gloffset_UnlockArraysEXT, UnlockArraysEXT@0)
-       GL_STUB(_dispatch_stub_598, _gloffset_CullParameterdvEXT, _dispatch_stub_598@8)
-       HIDDEN(GL_PREFIX(_dispatch_stub_598, _dispatch_stub_598@8))
-       GL_STUB(_dispatch_stub_599, _gloffset_CullParameterfvEXT, _dispatch_stub_599@8)
-       HIDDEN(GL_PREFIX(_dispatch_stub_599, _dispatch_stub_599@8))
+       GL_STUB(_dispatch_stub_608, _gloffset_CullParameterdvEXT, _dispatch_stub_608@8)
+       HIDDEN(GL_PREFIX(_dispatch_stub_608, _dispatch_stub_608@8))
+       GL_STUB(_dispatch_stub_609, _gloffset_CullParameterfvEXT, _dispatch_stub_609@8)
+       HIDDEN(GL_PREFIX(_dispatch_stub_609, _dispatch_stub_609@8))
        GL_STUB(SecondaryColor3bEXT, _gloffset_SecondaryColor3bEXT, SecondaryColor3bEXT@12)
        GL_STUB(SecondaryColor3bvEXT, _gloffset_SecondaryColor3bvEXT, SecondaryColor3bvEXT@4)
        GL_STUB(SecondaryColor3dEXT, _gloffset_SecondaryColor3dEXT, SecondaryColor3dEXT@24)
@@ -785,8 +795,8 @@ GLNAME(gl_dispatch_functions_start):
        GL_STUB(FogCoorddvEXT, _gloffset_FogCoorddvEXT, FogCoorddvEXT@4)
        GL_STUB(FogCoordfEXT, _gloffset_FogCoordfEXT, FogCoordfEXT@4)
        GL_STUB(FogCoordfvEXT, _gloffset_FogCoordfvEXT, FogCoordfvEXT@4)
-       GL_STUB(_dispatch_stub_624, _gloffset_PixelTexGenSGIX, _dispatch_stub_624@4)
-       HIDDEN(GL_PREFIX(_dispatch_stub_624, _dispatch_stub_624@4))
+       GL_STUB(_dispatch_stub_634, _gloffset_PixelTexGenSGIX, _dispatch_stub_634@4)
+       HIDDEN(GL_PREFIX(_dispatch_stub_634, _dispatch_stub_634@4))
        GL_STUB(BlendFuncSeparateEXT, _gloffset_BlendFuncSeparateEXT, BlendFuncSeparateEXT@16)
        GL_STUB(FlushVertexArrayRangeNV, _gloffset_FlushVertexArrayRangeNV, FlushVertexArrayRangeNV@0)
        GL_STUB(VertexArrayRangeNV, _gloffset_VertexArrayRangeNV, VertexArrayRangeNV@8)
@@ -828,24 +838,24 @@ GLNAME(gl_dispatch_functions_start):
        GL_STUB(WindowPos4ivMESA, _gloffset_WindowPos4ivMESA, WindowPos4ivMESA@4)
        GL_STUB(WindowPos4sMESA, _gloffset_WindowPos4sMESA, WindowPos4sMESA@16)
        GL_STUB(WindowPos4svMESA, _gloffset_WindowPos4svMESA, WindowPos4svMESA@4)
-       GL_STUB(_dispatch_stub_666, _gloffset_MultiModeDrawArraysIBM, _dispatch_stub_666@20)
-       HIDDEN(GL_PREFIX(_dispatch_stub_666, _dispatch_stub_666@20))
-       GL_STUB(_dispatch_stub_667, _gloffset_MultiModeDrawElementsIBM, _dispatch_stub_667@24)
-       HIDDEN(GL_PREFIX(_dispatch_stub_667, _dispatch_stub_667@24))
-       GL_STUB(_dispatch_stub_668, _gloffset_DeleteFencesNV, _dispatch_stub_668@8)
-       HIDDEN(GL_PREFIX(_dispatch_stub_668, _dispatch_stub_668@8))
-       GL_STUB(_dispatch_stub_669, _gloffset_FinishFenceNV, _dispatch_stub_669@4)
-       HIDDEN(GL_PREFIX(_dispatch_stub_669, _dispatch_stub_669@4))
-       GL_STUB(_dispatch_stub_670, _gloffset_GenFencesNV, _dispatch_stub_670@8)
-       HIDDEN(GL_PREFIX(_dispatch_stub_670, _dispatch_stub_670@8))
-       GL_STUB(_dispatch_stub_671, _gloffset_GetFenceivNV, _dispatch_stub_671@12)
-       HIDDEN(GL_PREFIX(_dispatch_stub_671, _dispatch_stub_671@12))
-       GL_STUB(_dispatch_stub_672, _gloffset_IsFenceNV, _dispatch_stub_672@4)
-       HIDDEN(GL_PREFIX(_dispatch_stub_672, _dispatch_stub_672@4))
-       GL_STUB(_dispatch_stub_673, _gloffset_SetFenceNV, _dispatch_stub_673@8)
-       HIDDEN(GL_PREFIX(_dispatch_stub_673, _dispatch_stub_673@8))
-       GL_STUB(_dispatch_stub_674, _gloffset_TestFenceNV, _dispatch_stub_674@4)
-       HIDDEN(GL_PREFIX(_dispatch_stub_674, _dispatch_stub_674@4))
+       GL_STUB(_dispatch_stub_676, _gloffset_MultiModeDrawArraysIBM, _dispatch_stub_676@20)
+       HIDDEN(GL_PREFIX(_dispatch_stub_676, _dispatch_stub_676@20))
+       GL_STUB(_dispatch_stub_677, _gloffset_MultiModeDrawElementsIBM, _dispatch_stub_677@24)
+       HIDDEN(GL_PREFIX(_dispatch_stub_677, _dispatch_stub_677@24))
+       GL_STUB(_dispatch_stub_678, _gloffset_DeleteFencesNV, _dispatch_stub_678@8)
+       HIDDEN(GL_PREFIX(_dispatch_stub_678, _dispatch_stub_678@8))
+       GL_STUB(_dispatch_stub_679, _gloffset_FinishFenceNV, _dispatch_stub_679@4)
+       HIDDEN(GL_PREFIX(_dispatch_stub_679, _dispatch_stub_679@4))
+       GL_STUB(_dispatch_stub_680, _gloffset_GenFencesNV, _dispatch_stub_680@8)
+       HIDDEN(GL_PREFIX(_dispatch_stub_680, _dispatch_stub_680@8))
+       GL_STUB(_dispatch_stub_681, _gloffset_GetFenceivNV, _dispatch_stub_681@12)
+       HIDDEN(GL_PREFIX(_dispatch_stub_681, _dispatch_stub_681@12))
+       GL_STUB(_dispatch_stub_682, _gloffset_IsFenceNV, _dispatch_stub_682@4)
+       HIDDEN(GL_PREFIX(_dispatch_stub_682, _dispatch_stub_682@4))
+       GL_STUB(_dispatch_stub_683, _gloffset_SetFenceNV, _dispatch_stub_683@8)
+       HIDDEN(GL_PREFIX(_dispatch_stub_683, _dispatch_stub_683@8))
+       GL_STUB(_dispatch_stub_684, _gloffset_TestFenceNV, _dispatch_stub_684@4)
+       HIDDEN(GL_PREFIX(_dispatch_stub_684, _dispatch_stub_684@4))
        GL_STUB(AreProgramsResidentNV, _gloffset_AreProgramsResidentNV, AreProgramsResidentNV@12)
        GL_STUB(BindProgramNV, _gloffset_BindProgramNV, BindProgramNV@8)
        GL_STUB(DeleteProgramsNV, _gloffset_DeleteProgramsNV, DeleteProgramsNV@8)
@@ -926,26 +936,26 @@ GLNAME(gl_dispatch_functions_start):
        GL_STUB(SetFragmentShaderConstantATI, _gloffset_SetFragmentShaderConstantATI, SetFragmentShaderConstantATI@8)
        GL_STUB(PointParameteriNV, _gloffset_PointParameteriNV, PointParameteriNV@8)
        GL_STUB(PointParameterivNV, _gloffset_PointParameterivNV, PointParameterivNV@8)
-       GL_STUB(_dispatch_stub_755, _gloffset_ActiveStencilFaceEXT, _dispatch_stub_755@4)
-       HIDDEN(GL_PREFIX(_dispatch_stub_755, _dispatch_stub_755@4))
-       GL_STUB(_dispatch_stub_756, _gloffset_BindVertexArrayAPPLE, _dispatch_stub_756@4)
-       HIDDEN(GL_PREFIX(_dispatch_stub_756, _dispatch_stub_756@4))
-       GL_STUB(_dispatch_stub_757, _gloffset_DeleteVertexArraysAPPLE, _dispatch_stub_757@8)
-       HIDDEN(GL_PREFIX(_dispatch_stub_757, _dispatch_stub_757@8))
-       GL_STUB(_dispatch_stub_758, _gloffset_GenVertexArraysAPPLE, _dispatch_stub_758@8)
-       HIDDEN(GL_PREFIX(_dispatch_stub_758, _dispatch_stub_758@8))
-       GL_STUB(_dispatch_stub_759, _gloffset_IsVertexArrayAPPLE, _dispatch_stub_759@4)
-       HIDDEN(GL_PREFIX(_dispatch_stub_759, _dispatch_stub_759@4))
+       GL_STUB(_dispatch_stub_765, _gloffset_ActiveStencilFaceEXT, _dispatch_stub_765@4)
+       HIDDEN(GL_PREFIX(_dispatch_stub_765, _dispatch_stub_765@4))
+       GL_STUB(_dispatch_stub_766, _gloffset_BindVertexArrayAPPLE, _dispatch_stub_766@4)
+       HIDDEN(GL_PREFIX(_dispatch_stub_766, _dispatch_stub_766@4))
+       GL_STUB(_dispatch_stub_767, _gloffset_DeleteVertexArraysAPPLE, _dispatch_stub_767@8)
+       HIDDEN(GL_PREFIX(_dispatch_stub_767, _dispatch_stub_767@8))
+       GL_STUB(_dispatch_stub_768, _gloffset_GenVertexArraysAPPLE, _dispatch_stub_768@8)
+       HIDDEN(GL_PREFIX(_dispatch_stub_768, _dispatch_stub_768@8))
+       GL_STUB(_dispatch_stub_769, _gloffset_IsVertexArrayAPPLE, _dispatch_stub_769@4)
+       HIDDEN(GL_PREFIX(_dispatch_stub_769, _dispatch_stub_769@4))
        GL_STUB(GetProgramNamedParameterdvNV, _gloffset_GetProgramNamedParameterdvNV, GetProgramNamedParameterdvNV@16)
        GL_STUB(GetProgramNamedParameterfvNV, _gloffset_GetProgramNamedParameterfvNV, GetProgramNamedParameterfvNV@16)
        GL_STUB(ProgramNamedParameter4dNV, _gloffset_ProgramNamedParameter4dNV, ProgramNamedParameter4dNV@44)
        GL_STUB(ProgramNamedParameter4dvNV, _gloffset_ProgramNamedParameter4dvNV, ProgramNamedParameter4dvNV@16)
        GL_STUB(ProgramNamedParameter4fNV, _gloffset_ProgramNamedParameter4fNV, ProgramNamedParameter4fNV@28)
        GL_STUB(ProgramNamedParameter4fvNV, _gloffset_ProgramNamedParameter4fvNV, ProgramNamedParameter4fvNV@16)
-       GL_STUB(_dispatch_stub_766, _gloffset_DepthBoundsEXT, _dispatch_stub_766@16)
-       HIDDEN(GL_PREFIX(_dispatch_stub_766, _dispatch_stub_766@16))
-       GL_STUB(_dispatch_stub_767, _gloffset_BlendEquationSeparateEXT, _dispatch_stub_767@8)
-       HIDDEN(GL_PREFIX(_dispatch_stub_767, _dispatch_stub_767@8))
+       GL_STUB(_dispatch_stub_776, _gloffset_DepthBoundsEXT, _dispatch_stub_776@16)
+       HIDDEN(GL_PREFIX(_dispatch_stub_776, _dispatch_stub_776@16))
+       GL_STUB(_dispatch_stub_777, _gloffset_BlendEquationSeparateEXT, _dispatch_stub_777@8)
+       HIDDEN(GL_PREFIX(_dispatch_stub_777, _dispatch_stub_777@8))
        GL_STUB(BindFramebufferEXT, _gloffset_BindFramebufferEXT, BindFramebufferEXT@8)
        GL_STUB(BindRenderbufferEXT, _gloffset_BindRenderbufferEXT, BindRenderbufferEXT@8)
        GL_STUB(CheckFramebufferStatusEXT, _gloffset_CheckFramebufferStatusEXT, CheckFramebufferStatusEXT@4)
@@ -963,12 +973,12 @@ GLNAME(gl_dispatch_functions_start):
        GL_STUB(IsFramebufferEXT, _gloffset_IsFramebufferEXT, IsFramebufferEXT@4)
        GL_STUB(IsRenderbufferEXT, _gloffset_IsRenderbufferEXT, IsRenderbufferEXT@4)
        GL_STUB(RenderbufferStorageEXT, _gloffset_RenderbufferStorageEXT, RenderbufferStorageEXT@16)
-       GL_STUB(_dispatch_stub_785, _gloffset_BlitFramebufferEXT, _dispatch_stub_785@40)
-       HIDDEN(GL_PREFIX(_dispatch_stub_785, _dispatch_stub_785@40))
-       GL_STUB(_dispatch_stub_786, _gloffset_BufferParameteriAPPLE, _dispatch_stub_786@12)
-       HIDDEN(GL_PREFIX(_dispatch_stub_786, _dispatch_stub_786@12))
-       GL_STUB(_dispatch_stub_787, _gloffset_FlushMappedBufferRangeAPPLE, _dispatch_stub_787@12)
-       HIDDEN(GL_PREFIX(_dispatch_stub_787, _dispatch_stub_787@12))
+       GL_STUB(_dispatch_stub_795, _gloffset_BlitFramebufferEXT, _dispatch_stub_795@40)
+       HIDDEN(GL_PREFIX(_dispatch_stub_795, _dispatch_stub_795@40))
+       GL_STUB(_dispatch_stub_796, _gloffset_BufferParameteriAPPLE, _dispatch_stub_796@12)
+       HIDDEN(GL_PREFIX(_dispatch_stub_796, _dispatch_stub_796@12))
+       GL_STUB(_dispatch_stub_797, _gloffset_FlushMappedBufferRangeAPPLE, _dispatch_stub_797@12)
+       HIDDEN(GL_PREFIX(_dispatch_stub_797, _dispatch_stub_797@12))
        GL_STUB(FramebufferTextureLayerEXT, _gloffset_FramebufferTextureLayerEXT, FramebufferTextureLayerEXT@20)
        GL_STUB(ColorMaskIndexedEXT, _gloffset_ColorMaskIndexedEXT, ColorMaskIndexedEXT@20)
        GL_STUB(DisableIndexedEXT, _gloffset_DisableIndexedEXT, DisableIndexedEXT@8)
@@ -986,23 +996,23 @@ GLNAME(gl_dispatch_functions_start):
        GL_STUB(GetTransformFeedbackVaryingEXT, _gloffset_GetTransformFeedbackVaryingEXT, GetTransformFeedbackVaryingEXT@28)
        GL_STUB(TransformFeedbackVaryingsEXT, _gloffset_TransformFeedbackVaryingsEXT, TransformFeedbackVaryingsEXT@16)
        GL_STUB(ProvokingVertexEXT, _gloffset_ProvokingVertexEXT, ProvokingVertexEXT@4)
-       GL_STUB(_dispatch_stub_805, _gloffset_GetTexParameterPointervAPPLE, _dispatch_stub_805@12)
-       HIDDEN(GL_PREFIX(_dispatch_stub_805, _dispatch_stub_805@12))
-       GL_STUB(_dispatch_stub_806, _gloffset_TextureRangeAPPLE, _dispatch_stub_806@12)
-       HIDDEN(GL_PREFIX(_dispatch_stub_806, _dispatch_stub_806@12))
+       GL_STUB(_dispatch_stub_815, _gloffset_GetTexParameterPointervAPPLE, _dispatch_stub_815@12)
+       HIDDEN(GL_PREFIX(_dispatch_stub_815, _dispatch_stub_815@12))
+       GL_STUB(_dispatch_stub_816, _gloffset_TextureRangeAPPLE, _dispatch_stub_816@12)
+       HIDDEN(GL_PREFIX(_dispatch_stub_816, _dispatch_stub_816@12))
        GL_STUB(GetObjectParameterivAPPLE, _gloffset_GetObjectParameterivAPPLE, GetObjectParameterivAPPLE@16)
        GL_STUB(ObjectPurgeableAPPLE, _gloffset_ObjectPurgeableAPPLE, ObjectPurgeableAPPLE@12)
        GL_STUB(ObjectUnpurgeableAPPLE, _gloffset_ObjectUnpurgeableAPPLE, ObjectUnpurgeableAPPLE@12)
-       GL_STUB(_dispatch_stub_810, _gloffset_StencilFuncSeparateATI, _dispatch_stub_810@16)
-       HIDDEN(GL_PREFIX(_dispatch_stub_810, _dispatch_stub_810@16))
-       GL_STUB(_dispatch_stub_811, _gloffset_ProgramEnvParameters4fvEXT, _dispatch_stub_811@16)
-       HIDDEN(GL_PREFIX(_dispatch_stub_811, _dispatch_stub_811@16))
-       GL_STUB(_dispatch_stub_812, _gloffset_ProgramLocalParameters4fvEXT, _dispatch_stub_812@16)
-       HIDDEN(GL_PREFIX(_dispatch_stub_812, _dispatch_stub_812@16))
-       GL_STUB(_dispatch_stub_813, _gloffset_GetQueryObjecti64vEXT, _dispatch_stub_813@12)
-       HIDDEN(GL_PREFIX(_dispatch_stub_813, _dispatch_stub_813@12))
-       GL_STUB(_dispatch_stub_814, _gloffset_GetQueryObjectui64vEXT, _dispatch_stub_814@12)
-       HIDDEN(GL_PREFIX(_dispatch_stub_814, _dispatch_stub_814@12))
+       GL_STUB(_dispatch_stub_820, _gloffset_StencilFuncSeparateATI, _dispatch_stub_820@16)
+       HIDDEN(GL_PREFIX(_dispatch_stub_820, _dispatch_stub_820@16))
+       GL_STUB(_dispatch_stub_821, _gloffset_ProgramEnvParameters4fvEXT, _dispatch_stub_821@16)
+       HIDDEN(GL_PREFIX(_dispatch_stub_821, _dispatch_stub_821@16))
+       GL_STUB(_dispatch_stub_822, _gloffset_ProgramLocalParameters4fvEXT, _dispatch_stub_822@16)
+       HIDDEN(GL_PREFIX(_dispatch_stub_822, _dispatch_stub_822@16))
+       GL_STUB(_dispatch_stub_823, _gloffset_GetQueryObjecti64vEXT, _dispatch_stub_823@12)
+       HIDDEN(GL_PREFIX(_dispatch_stub_823, _dispatch_stub_823@12))
+       GL_STUB(_dispatch_stub_824, _gloffset_GetQueryObjectui64vEXT, _dispatch_stub_824@12)
+       HIDDEN(GL_PREFIX(_dispatch_stub_824, _dispatch_stub_824@12))
        GL_STUB(EGLImageTargetRenderbufferStorageOES, _gloffset_EGLImageTargetRenderbufferStorageOES, EGLImageTargetRenderbufferStorageOES@8)
        GL_STUB(EGLImageTargetTexture2DOES, _gloffset_EGLImageTargetTexture2DOES, EGLImageTargetTexture2DOES@8)
        GL_STUB_ALIAS(ArrayElementEXT, _gloffset_ArrayElement, ArrayElementEXT@4, ArrayElement, ArrayElement@4)
@@ -1263,9 +1273,9 @@ GLNAME(gl_dispatch_functions_start):
        GL_STUB_ALIAS(IsProgramARB, _gloffset_IsProgramNV, IsProgramARB@4, IsProgramNV, IsProgramNV@4)
        GL_STUB_ALIAS(PointParameteri, _gloffset_PointParameteriNV, PointParameteri@8, PointParameteriNV, PointParameteriNV@8)
        GL_STUB_ALIAS(PointParameteriv, _gloffset_PointParameterivNV, PointParameteriv@8, PointParameterivNV, PointParameterivNV@8)
-       GL_STUB_ALIAS(DeleteVertexArrays, _gloffset_DeleteVertexArraysAPPLE, DeleteVertexArrays@8, _dispatch_stub_757, _dispatch_stub_757@8)
-       GL_STUB_ALIAS(IsVertexArray, _gloffset_IsVertexArrayAPPLE, IsVertexArray@4, _dispatch_stub_759, _dispatch_stub_759@4)
-       GL_STUB_ALIAS(BlendEquationSeparate, _gloffset_BlendEquationSeparateEXT, BlendEquationSeparate@8, _dispatch_stub_767, _dispatch_stub_767@8)
+       GL_STUB_ALIAS(DeleteVertexArrays, _gloffset_DeleteVertexArraysAPPLE, DeleteVertexArrays@8, _dispatch_stub_767, _dispatch_stub_767@8)
+       GL_STUB_ALIAS(IsVertexArray, _gloffset_IsVertexArrayAPPLE, IsVertexArray@4, _dispatch_stub_769, _dispatch_stub_769@4)
+       GL_STUB_ALIAS(BlendEquationSeparate, _gloffset_BlendEquationSeparateEXT, BlendEquationSeparate@8, _dispatch_stub_777, _dispatch_stub_777@8)
        GL_STUB_ALIAS(BindFramebuffer, _gloffset_BindFramebufferEXT, BindFramebuffer@8, BindFramebufferEXT, BindFramebufferEXT@8)
        GL_STUB_ALIAS(BindRenderbuffer, _gloffset_BindRenderbufferEXT, BindRenderbuffer@8, BindRenderbufferEXT, BindRenderbufferEXT@8)
        GL_STUB_ALIAS(CheckFramebufferStatus, _gloffset_CheckFramebufferStatusEXT, CheckFramebufferStatus@4, CheckFramebufferStatusEXT, CheckFramebufferStatusEXT@4)
@@ -1283,7 +1293,7 @@ GLNAME(gl_dispatch_functions_start):
        GL_STUB_ALIAS(IsFramebuffer, _gloffset_IsFramebufferEXT, IsFramebuffer@4, IsFramebufferEXT, IsFramebufferEXT@4)
        GL_STUB_ALIAS(IsRenderbuffer, _gloffset_IsRenderbufferEXT, IsRenderbuffer@4, IsRenderbufferEXT, IsRenderbufferEXT@4)
        GL_STUB_ALIAS(RenderbufferStorage, _gloffset_RenderbufferStorageEXT, RenderbufferStorage@16, RenderbufferStorageEXT, RenderbufferStorageEXT@16)
-       GL_STUB_ALIAS(BlitFramebuffer, _gloffset_BlitFramebufferEXT, BlitFramebuffer@40, _dispatch_stub_785, _dispatch_stub_785@40)
+       GL_STUB_ALIAS(BlitFramebuffer, _gloffset_BlitFramebufferEXT, BlitFramebuffer@40, _dispatch_stub_795, _dispatch_stub_795@40)
        GL_STUB_ALIAS(FramebufferTextureLayer, _gloffset_FramebufferTextureLayerEXT, FramebufferTextureLayer@20, FramebufferTextureLayerEXT, FramebufferTextureLayerEXT@20)
        GL_STUB_ALIAS(BeginTransformFeedback, _gloffset_BeginTransformFeedbackEXT, BeginTransformFeedback@4, BeginTransformFeedbackEXT, BeginTransformFeedbackEXT@4)
        GL_STUB_ALIAS(BindBufferBase, _gloffset_BindBufferBaseEXT, BindBufferBase@12, BindBufferBaseEXT, BindBufferBaseEXT@12)
index f66876fe8d292b9892c6921cd492597e4363ef47..f8a68ee302c5372488ecd25e570b4e13dae5799c 100644 (file)
 #define CALL_RenderbufferStorageMultisample(disp, parameters) (*((disp)->RenderbufferStorageMultisample)) parameters
 #define GET_RenderbufferStorageMultisample(disp) ((disp)->RenderbufferStorageMultisample)
 #define SET_RenderbufferStorageMultisample(disp, fn) ((disp)->RenderbufferStorageMultisample = fn)
+#define CALL_FramebufferTextureARB(disp, parameters) (*((disp)->FramebufferTextureARB)) parameters
+#define GET_FramebufferTextureARB(disp) ((disp)->FramebufferTextureARB)
+#define SET_FramebufferTextureARB(disp, fn) ((disp)->FramebufferTextureARB = fn)
+#define CALL_FramebufferTextureFaceARB(disp, parameters) (*((disp)->FramebufferTextureFaceARB)) parameters
+#define GET_FramebufferTextureFaceARB(disp) ((disp)->FramebufferTextureFaceARB)
+#define SET_FramebufferTextureFaceARB(disp, fn) ((disp)->FramebufferTextureFaceARB = fn)
+#define CALL_ProgramParameteriARB(disp, parameters) (*((disp)->ProgramParameteriARB)) parameters
+#define GET_ProgramParameteriARB(disp) ((disp)->ProgramParameteriARB)
+#define SET_ProgramParameteriARB(disp, fn) ((disp)->ProgramParameteriARB = fn)
 #define CALL_FlushMappedBufferRange(disp, parameters) (*((disp)->FlushMappedBufferRange)) parameters
 #define GET_FlushMappedBufferRange(disp) ((disp)->FlushMappedBufferRange)
 #define SET_FlushMappedBufferRange(disp, fn) ((disp)->FlushMappedBufferRange = fn)
 #define CALL_MultiDrawElementsBaseVertex(disp, parameters) (*((disp)->MultiDrawElementsBaseVertex)) parameters
 #define GET_MultiDrawElementsBaseVertex(disp) ((disp)->MultiDrawElementsBaseVertex)
 #define SET_MultiDrawElementsBaseVertex(disp, fn) ((disp)->MultiDrawElementsBaseVertex = fn)
+#define CALL_BindTransformFeedback(disp, parameters) (*((disp)->BindTransformFeedback)) parameters
+#define GET_BindTransformFeedback(disp) ((disp)->BindTransformFeedback)
+#define SET_BindTransformFeedback(disp, fn) ((disp)->BindTransformFeedback = fn)
+#define CALL_DeleteTransformFeedbacks(disp, parameters) (*((disp)->DeleteTransformFeedbacks)) parameters
+#define GET_DeleteTransformFeedbacks(disp) ((disp)->DeleteTransformFeedbacks)
+#define SET_DeleteTransformFeedbacks(disp, fn) ((disp)->DeleteTransformFeedbacks = fn)
+#define CALL_DrawTransformFeedback(disp, parameters) (*((disp)->DrawTransformFeedback)) parameters
+#define GET_DrawTransformFeedback(disp) ((disp)->DrawTransformFeedback)
+#define SET_DrawTransformFeedback(disp, fn) ((disp)->DrawTransformFeedback = fn)
+#define CALL_GenTransformFeedbacks(disp, parameters) (*((disp)->GenTransformFeedbacks)) parameters
+#define GET_GenTransformFeedbacks(disp) ((disp)->GenTransformFeedbacks)
+#define SET_GenTransformFeedbacks(disp, fn) ((disp)->GenTransformFeedbacks = fn)
+#define CALL_IsTransformFeedback(disp, parameters) (*((disp)->IsTransformFeedback)) parameters
+#define GET_IsTransformFeedback(disp) ((disp)->IsTransformFeedback)
+#define SET_IsTransformFeedback(disp, fn) ((disp)->IsTransformFeedback = fn)
+#define CALL_PauseTransformFeedback(disp, parameters) (*((disp)->PauseTransformFeedback)) parameters
+#define GET_PauseTransformFeedback(disp) ((disp)->PauseTransformFeedback)
+#define SET_PauseTransformFeedback(disp, fn) ((disp)->PauseTransformFeedback = fn)
+#define CALL_ResumeTransformFeedback(disp, parameters) (*((disp)->ResumeTransformFeedback)) parameters
+#define GET_ResumeTransformFeedback(disp) ((disp)->ResumeTransformFeedback)
+#define SET_ResumeTransformFeedback(disp, fn) ((disp)->ResumeTransformFeedback = fn)
 #define CALL_PolygonOffsetEXT(disp, parameters) (*((disp)->PolygonOffsetEXT)) parameters
 #define GET_PolygonOffsetEXT(disp) ((disp)->PolygonOffsetEXT)
 #define SET_PolygonOffsetEXT(disp, fn) ((disp)->PolygonOffsetEXT = fn)
 
 #else
 
-#define driDispatchRemapTable_size 409
+#define driDispatchRemapTable_size 419
 extern int driDispatchRemapTable[ driDispatchRemapTable_size ];
 
 #define AttachShader_remap_index 0
@@ -2674,259 +2704,269 @@ extern int driDispatchRemapTable[ driDispatchRemapTable_size ];
 #define GetAttribLocationARB_remap_index 153
 #define DrawBuffersARB_remap_index 154
 #define RenderbufferStorageMultisample_remap_index 155
-#define FlushMappedBufferRange_remap_index 156
-#define MapBufferRange_remap_index 157
-#define BindVertexArray_remap_index 158
-#define GenVertexArrays_remap_index 159
-#define CopyBufferSubData_remap_index 160
-#define ClientWaitSync_remap_index 161
-#define DeleteSync_remap_index 162
-#define FenceSync_remap_index 163
-#define GetInteger64v_remap_index 164
-#define GetSynciv_remap_index 165
-#define IsSync_remap_index 166
-#define WaitSync_remap_index 167
-#define DrawElementsBaseVertex_remap_index 168
-#define DrawRangeElementsBaseVertex_remap_index 169
-#define MultiDrawElementsBaseVertex_remap_index 170
-#define PolygonOffsetEXT_remap_index 171
-#define GetPixelTexGenParameterfvSGIS_remap_index 172
-#define GetPixelTexGenParameterivSGIS_remap_index 173
-#define PixelTexGenParameterfSGIS_remap_index 174
-#define PixelTexGenParameterfvSGIS_remap_index 175
-#define PixelTexGenParameteriSGIS_remap_index 176
-#define PixelTexGenParameterivSGIS_remap_index 177
-#define SampleMaskSGIS_remap_index 178
-#define SamplePatternSGIS_remap_index 179
-#define ColorPointerEXT_remap_index 180
-#define EdgeFlagPointerEXT_remap_index 181
-#define IndexPointerEXT_remap_index 182
-#define NormalPointerEXT_remap_index 183
-#define TexCoordPointerEXT_remap_index 184
-#define VertexPointerEXT_remap_index 185
-#define PointParameterfEXT_remap_index 186
-#define PointParameterfvEXT_remap_index 187
-#define LockArraysEXT_remap_index 188
-#define UnlockArraysEXT_remap_index 189
-#define CullParameterdvEXT_remap_index 190
-#define CullParameterfvEXT_remap_index 191
-#define SecondaryColor3bEXT_remap_index 192
-#define SecondaryColor3bvEXT_remap_index 193
-#define SecondaryColor3dEXT_remap_index 194
-#define SecondaryColor3dvEXT_remap_index 195
-#define SecondaryColor3fEXT_remap_index 196
-#define SecondaryColor3fvEXT_remap_index 197
-#define SecondaryColor3iEXT_remap_index 198
-#define SecondaryColor3ivEXT_remap_index 199
-#define SecondaryColor3sEXT_remap_index 200
-#define SecondaryColor3svEXT_remap_index 201
-#define SecondaryColor3ubEXT_remap_index 202
-#define SecondaryColor3ubvEXT_remap_index 203
-#define SecondaryColor3uiEXT_remap_index 204
-#define SecondaryColor3uivEXT_remap_index 205
-#define SecondaryColor3usEXT_remap_index 206
-#define SecondaryColor3usvEXT_remap_index 207
-#define SecondaryColorPointerEXT_remap_index 208
-#define MultiDrawArraysEXT_remap_index 209
-#define MultiDrawElementsEXT_remap_index 210
-#define FogCoordPointerEXT_remap_index 211
-#define FogCoorddEXT_remap_index 212
-#define FogCoorddvEXT_remap_index 213
-#define FogCoordfEXT_remap_index 214
-#define FogCoordfvEXT_remap_index 215
-#define PixelTexGenSGIX_remap_index 216
-#define BlendFuncSeparateEXT_remap_index 217
-#define FlushVertexArrayRangeNV_remap_index 218
-#define VertexArrayRangeNV_remap_index 219
-#define CombinerInputNV_remap_index 220
-#define CombinerOutputNV_remap_index 221
-#define CombinerParameterfNV_remap_index 222
-#define CombinerParameterfvNV_remap_index 223
-#define CombinerParameteriNV_remap_index 224
-#define CombinerParameterivNV_remap_index 225
-#define FinalCombinerInputNV_remap_index 226
-#define GetCombinerInputParameterfvNV_remap_index 227
-#define GetCombinerInputParameterivNV_remap_index 228
-#define GetCombinerOutputParameterfvNV_remap_index 229
-#define GetCombinerOutputParameterivNV_remap_index 230
-#define GetFinalCombinerInputParameterfvNV_remap_index 231
-#define GetFinalCombinerInputParameterivNV_remap_index 232
-#define ResizeBuffersMESA_remap_index 233
-#define WindowPos2dMESA_remap_index 234
-#define WindowPos2dvMESA_remap_index 235
-#define WindowPos2fMESA_remap_index 236
-#define WindowPos2fvMESA_remap_index 237
-#define WindowPos2iMESA_remap_index 238
-#define WindowPos2ivMESA_remap_index 239
-#define WindowPos2sMESA_remap_index 240
-#define WindowPos2svMESA_remap_index 241
-#define WindowPos3dMESA_remap_index 242
-#define WindowPos3dvMESA_remap_index 243
-#define WindowPos3fMESA_remap_index 244
-#define WindowPos3fvMESA_remap_index 245
-#define WindowPos3iMESA_remap_index 246
-#define WindowPos3ivMESA_remap_index 247
-#define WindowPos3sMESA_remap_index 248
-#define WindowPos3svMESA_remap_index 249
-#define WindowPos4dMESA_remap_index 250
-#define WindowPos4dvMESA_remap_index 251
-#define WindowPos4fMESA_remap_index 252
-#define WindowPos4fvMESA_remap_index 253
-#define WindowPos4iMESA_remap_index 254
-#define WindowPos4ivMESA_remap_index 255
-#define WindowPos4sMESA_remap_index 256
-#define WindowPos4svMESA_remap_index 257
-#define MultiModeDrawArraysIBM_remap_index 258
-#define MultiModeDrawElementsIBM_remap_index 259
-#define DeleteFencesNV_remap_index 260
-#define FinishFenceNV_remap_index 261
-#define GenFencesNV_remap_index 262
-#define GetFenceivNV_remap_index 263
-#define IsFenceNV_remap_index 264
-#define SetFenceNV_remap_index 265
-#define TestFenceNV_remap_index 266
-#define AreProgramsResidentNV_remap_index 267
-#define BindProgramNV_remap_index 268
-#define DeleteProgramsNV_remap_index 269
-#define ExecuteProgramNV_remap_index 270
-#define GenProgramsNV_remap_index 271
-#define GetProgramParameterdvNV_remap_index 272
-#define GetProgramParameterfvNV_remap_index 273
-#define GetProgramStringNV_remap_index 274
-#define GetProgramivNV_remap_index 275
-#define GetTrackMatrixivNV_remap_index 276
-#define GetVertexAttribPointervNV_remap_index 277
-#define GetVertexAttribdvNV_remap_index 278
-#define GetVertexAttribfvNV_remap_index 279
-#define GetVertexAttribivNV_remap_index 280
-#define IsProgramNV_remap_index 281
-#define LoadProgramNV_remap_index 282
-#define ProgramParameters4dvNV_remap_index 283
-#define ProgramParameters4fvNV_remap_index 284
-#define RequestResidentProgramsNV_remap_index 285
-#define TrackMatrixNV_remap_index 286
-#define VertexAttrib1dNV_remap_index 287
-#define VertexAttrib1dvNV_remap_index 288
-#define VertexAttrib1fNV_remap_index 289
-#define VertexAttrib1fvNV_remap_index 290
-#define VertexAttrib1sNV_remap_index 291
-#define VertexAttrib1svNV_remap_index 292
-#define VertexAttrib2dNV_remap_index 293
-#define VertexAttrib2dvNV_remap_index 294
-#define VertexAttrib2fNV_remap_index 295
-#define VertexAttrib2fvNV_remap_index 296
-#define VertexAttrib2sNV_remap_index 297
-#define VertexAttrib2svNV_remap_index 298
-#define VertexAttrib3dNV_remap_index 299
-#define VertexAttrib3dvNV_remap_index 300
-#define VertexAttrib3fNV_remap_index 301
-#define VertexAttrib3fvNV_remap_index 302
-#define VertexAttrib3sNV_remap_index 303
-#define VertexAttrib3svNV_remap_index 304
-#define VertexAttrib4dNV_remap_index 305
-#define VertexAttrib4dvNV_remap_index 306
-#define VertexAttrib4fNV_remap_index 307
-#define VertexAttrib4fvNV_remap_index 308
-#define VertexAttrib4sNV_remap_index 309
-#define VertexAttrib4svNV_remap_index 310
-#define VertexAttrib4ubNV_remap_index 311
-#define VertexAttrib4ubvNV_remap_index 312
-#define VertexAttribPointerNV_remap_index 313
-#define VertexAttribs1dvNV_remap_index 314
-#define VertexAttribs1fvNV_remap_index 315
-#define VertexAttribs1svNV_remap_index 316
-#define VertexAttribs2dvNV_remap_index 317
-#define VertexAttribs2fvNV_remap_index 318
-#define VertexAttribs2svNV_remap_index 319
-#define VertexAttribs3dvNV_remap_index 320
-#define VertexAttribs3fvNV_remap_index 321
-#define VertexAttribs3svNV_remap_index 322
-#define VertexAttribs4dvNV_remap_index 323
-#define VertexAttribs4fvNV_remap_index 324
-#define VertexAttribs4svNV_remap_index 325
-#define VertexAttribs4ubvNV_remap_index 326
-#define GetTexBumpParameterfvATI_remap_index 327
-#define GetTexBumpParameterivATI_remap_index 328
-#define TexBumpParameterfvATI_remap_index 329
-#define TexBumpParameterivATI_remap_index 330
-#define AlphaFragmentOp1ATI_remap_index 331
-#define AlphaFragmentOp2ATI_remap_index 332
-#define AlphaFragmentOp3ATI_remap_index 333
-#define BeginFragmentShaderATI_remap_index 334
-#define BindFragmentShaderATI_remap_index 335
-#define ColorFragmentOp1ATI_remap_index 336
-#define ColorFragmentOp2ATI_remap_index 337
-#define ColorFragmentOp3ATI_remap_index 338
-#define DeleteFragmentShaderATI_remap_index 339
-#define EndFragmentShaderATI_remap_index 340
-#define GenFragmentShadersATI_remap_index 341
-#define PassTexCoordATI_remap_index 342
-#define SampleMapATI_remap_index 343
-#define SetFragmentShaderConstantATI_remap_index 344
-#define PointParameteriNV_remap_index 345
-#define PointParameterivNV_remap_index 346
-#define ActiveStencilFaceEXT_remap_index 347
-#define BindVertexArrayAPPLE_remap_index 348
-#define DeleteVertexArraysAPPLE_remap_index 349
-#define GenVertexArraysAPPLE_remap_index 350
-#define IsVertexArrayAPPLE_remap_index 351
-#define GetProgramNamedParameterdvNV_remap_index 352
-#define GetProgramNamedParameterfvNV_remap_index 353
-#define ProgramNamedParameter4dNV_remap_index 354
-#define ProgramNamedParameter4dvNV_remap_index 355
-#define ProgramNamedParameter4fNV_remap_index 356
-#define ProgramNamedParameter4fvNV_remap_index 357
-#define DepthBoundsEXT_remap_index 358
-#define BlendEquationSeparateEXT_remap_index 359
-#define BindFramebufferEXT_remap_index 360
-#define BindRenderbufferEXT_remap_index 361
-#define CheckFramebufferStatusEXT_remap_index 362
-#define DeleteFramebuffersEXT_remap_index 363
-#define DeleteRenderbuffersEXT_remap_index 364
-#define FramebufferRenderbufferEXT_remap_index 365
-#define FramebufferTexture1DEXT_remap_index 366
-#define FramebufferTexture2DEXT_remap_index 367
-#define FramebufferTexture3DEXT_remap_index 368
-#define GenFramebuffersEXT_remap_index 369
-#define GenRenderbuffersEXT_remap_index 370
-#define GenerateMipmapEXT_remap_index 371
-#define GetFramebufferAttachmentParameterivEXT_remap_index 372
-#define GetRenderbufferParameterivEXT_remap_index 373
-#define IsFramebufferEXT_remap_index 374
-#define IsRenderbufferEXT_remap_index 375
-#define RenderbufferStorageEXT_remap_index 376
-#define BlitFramebufferEXT_remap_index 377
-#define BufferParameteriAPPLE_remap_index 378
-#define FlushMappedBufferRangeAPPLE_remap_index 379
-#define FramebufferTextureLayerEXT_remap_index 380
-#define ColorMaskIndexedEXT_remap_index 381
-#define DisableIndexedEXT_remap_index 382
-#define EnableIndexedEXT_remap_index 383
-#define GetBooleanIndexedvEXT_remap_index 384
-#define GetIntegerIndexedvEXT_remap_index 385
-#define IsEnabledIndexedEXT_remap_index 386
-#define BeginConditionalRenderNV_remap_index 387
-#define EndConditionalRenderNV_remap_index 388
-#define BeginTransformFeedbackEXT_remap_index 389
-#define BindBufferBaseEXT_remap_index 390
-#define BindBufferOffsetEXT_remap_index 391
-#define BindBufferRangeEXT_remap_index 392
-#define EndTransformFeedbackEXT_remap_index 393
-#define GetTransformFeedbackVaryingEXT_remap_index 394
-#define TransformFeedbackVaryingsEXT_remap_index 395
-#define ProvokingVertexEXT_remap_index 396
-#define GetTexParameterPointervAPPLE_remap_index 397
-#define TextureRangeAPPLE_remap_index 398
-#define GetObjectParameterivAPPLE_remap_index 399
-#define ObjectPurgeableAPPLE_remap_index 400
-#define ObjectUnpurgeableAPPLE_remap_index 401
-#define StencilFuncSeparateATI_remap_index 402
-#define ProgramEnvParameters4fvEXT_remap_index 403
-#define ProgramLocalParameters4fvEXT_remap_index 404
-#define GetQueryObjecti64vEXT_remap_index 405
-#define GetQueryObjectui64vEXT_remap_index 406
-#define EGLImageTargetRenderbufferStorageOES_remap_index 407
-#define EGLImageTargetTexture2DOES_remap_index 408
+#define FramebufferTextureARB_remap_index 156
+#define FramebufferTextureFaceARB_remap_index 157
+#define ProgramParameteriARB_remap_index 158
+#define FlushMappedBufferRange_remap_index 159
+#define MapBufferRange_remap_index 160
+#define BindVertexArray_remap_index 161
+#define GenVertexArrays_remap_index 162
+#define CopyBufferSubData_remap_index 163
+#define ClientWaitSync_remap_index 164
+#define DeleteSync_remap_index 165
+#define FenceSync_remap_index 166
+#define GetInteger64v_remap_index 167
+#define GetSynciv_remap_index 168
+#define IsSync_remap_index 169
+#define WaitSync_remap_index 170
+#define DrawElementsBaseVertex_remap_index 171
+#define DrawRangeElementsBaseVertex_remap_index 172
+#define MultiDrawElementsBaseVertex_remap_index 173
+#define BindTransformFeedback_remap_index 174
+#define DeleteTransformFeedbacks_remap_index 175
+#define DrawTransformFeedback_remap_index 176
+#define GenTransformFeedbacks_remap_index 177
+#define IsTransformFeedback_remap_index 178
+#define PauseTransformFeedback_remap_index 179
+#define ResumeTransformFeedback_remap_index 180
+#define PolygonOffsetEXT_remap_index 181
+#define GetPixelTexGenParameterfvSGIS_remap_index 182
+#define GetPixelTexGenParameterivSGIS_remap_index 183
+#define PixelTexGenParameterfSGIS_remap_index 184
+#define PixelTexGenParameterfvSGIS_remap_index 185
+#define PixelTexGenParameteriSGIS_remap_index 186
+#define PixelTexGenParameterivSGIS_remap_index 187
+#define SampleMaskSGIS_remap_index 188
+#define SamplePatternSGIS_remap_index 189
+#define ColorPointerEXT_remap_index 190
+#define EdgeFlagPointerEXT_remap_index 191
+#define IndexPointerEXT_remap_index 192
+#define NormalPointerEXT_remap_index 193
+#define TexCoordPointerEXT_remap_index 194
+#define VertexPointerEXT_remap_index 195
+#define PointParameterfEXT_remap_index 196
+#define PointParameterfvEXT_remap_index 197
+#define LockArraysEXT_remap_index 198
+#define UnlockArraysEXT_remap_index 199
+#define CullParameterdvEXT_remap_index 200
+#define CullParameterfvEXT_remap_index 201
+#define SecondaryColor3bEXT_remap_index 202
+#define SecondaryColor3bvEXT_remap_index 203
+#define SecondaryColor3dEXT_remap_index 204
+#define SecondaryColor3dvEXT_remap_index 205
+#define SecondaryColor3fEXT_remap_index 206
+#define SecondaryColor3fvEXT_remap_index 207
+#define SecondaryColor3iEXT_remap_index 208
+#define SecondaryColor3ivEXT_remap_index 209
+#define SecondaryColor3sEXT_remap_index 210
+#define SecondaryColor3svEXT_remap_index 211
+#define SecondaryColor3ubEXT_remap_index 212
+#define SecondaryColor3ubvEXT_remap_index 213
+#define SecondaryColor3uiEXT_remap_index 214
+#define SecondaryColor3uivEXT_remap_index 215
+#define SecondaryColor3usEXT_remap_index 216
+#define SecondaryColor3usvEXT_remap_index 217
+#define SecondaryColorPointerEXT_remap_index 218
+#define MultiDrawArraysEXT_remap_index 219
+#define MultiDrawElementsEXT_remap_index 220
+#define FogCoordPointerEXT_remap_index 221
+#define FogCoorddEXT_remap_index 222
+#define FogCoorddvEXT_remap_index 223
+#define FogCoordfEXT_remap_index 224
+#define FogCoordfvEXT_remap_index 225
+#define PixelTexGenSGIX_remap_index 226
+#define BlendFuncSeparateEXT_remap_index 227
+#define FlushVertexArrayRangeNV_remap_index 228
+#define VertexArrayRangeNV_remap_index 229
+#define CombinerInputNV_remap_index 230
+#define CombinerOutputNV_remap_index 231
+#define CombinerParameterfNV_remap_index 232
+#define CombinerParameterfvNV_remap_index 233
+#define CombinerParameteriNV_remap_index 234
+#define CombinerParameterivNV_remap_index 235
+#define FinalCombinerInputNV_remap_index 236
+#define GetCombinerInputParameterfvNV_remap_index 237
+#define GetCombinerInputParameterivNV_remap_index 238
+#define GetCombinerOutputParameterfvNV_remap_index 239
+#define GetCombinerOutputParameterivNV_remap_index 240
+#define GetFinalCombinerInputParameterfvNV_remap_index 241
+#define GetFinalCombinerInputParameterivNV_remap_index 242
+#define ResizeBuffersMESA_remap_index 243
+#define WindowPos2dMESA_remap_index 244
+#define WindowPos2dvMESA_remap_index 245
+#define WindowPos2fMESA_remap_index 246
+#define WindowPos2fvMESA_remap_index 247
+#define WindowPos2iMESA_remap_index 248
+#define WindowPos2ivMESA_remap_index 249
+#define WindowPos2sMESA_remap_index 250
+#define WindowPos2svMESA_remap_index 251
+#define WindowPos3dMESA_remap_index 252
+#define WindowPos3dvMESA_remap_index 253
+#define WindowPos3fMESA_remap_index 254
+#define WindowPos3fvMESA_remap_index 255
+#define WindowPos3iMESA_remap_index 256
+#define WindowPos3ivMESA_remap_index 257
+#define WindowPos3sMESA_remap_index 258
+#define WindowPos3svMESA_remap_index 259
+#define WindowPos4dMESA_remap_index 260
+#define WindowPos4dvMESA_remap_index 261
+#define WindowPos4fMESA_remap_index 262
+#define WindowPos4fvMESA_remap_index 263
+#define WindowPos4iMESA_remap_index 264
+#define WindowPos4ivMESA_remap_index 265
+#define WindowPos4sMESA_remap_index 266
+#define WindowPos4svMESA_remap_index 267
+#define MultiModeDrawArraysIBM_remap_index 268
+#define MultiModeDrawElementsIBM_remap_index 269
+#define DeleteFencesNV_remap_index 270
+#define FinishFenceNV_remap_index 271
+#define GenFencesNV_remap_index 272
+#define GetFenceivNV_remap_index 273
+#define IsFenceNV_remap_index 274
+#define SetFenceNV_remap_index 275
+#define TestFenceNV_remap_index 276
+#define AreProgramsResidentNV_remap_index 277
+#define BindProgramNV_remap_index 278
+#define DeleteProgramsNV_remap_index 279
+#define ExecuteProgramNV_remap_index 280
+#define GenProgramsNV_remap_index 281
+#define GetProgramParameterdvNV_remap_index 282
+#define GetProgramParameterfvNV_remap_index 283
+#define GetProgramStringNV_remap_index 284
+#define GetProgramivNV_remap_index 285
+#define GetTrackMatrixivNV_remap_index 286
+#define GetVertexAttribPointervNV_remap_index 287
+#define GetVertexAttribdvNV_remap_index 288
+#define GetVertexAttribfvNV_remap_index 289
+#define GetVertexAttribivNV_remap_index 290
+#define IsProgramNV_remap_index 291
+#define LoadProgramNV_remap_index 292
+#define ProgramParameters4dvNV_remap_index 293
+#define ProgramParameters4fvNV_remap_index 294
+#define RequestResidentProgramsNV_remap_index 295
+#define TrackMatrixNV_remap_index 296
+#define VertexAttrib1dNV_remap_index 297
+#define VertexAttrib1dvNV_remap_index 298
+#define VertexAttrib1fNV_remap_index 299
+#define VertexAttrib1fvNV_remap_index 300
+#define VertexAttrib1sNV_remap_index 301
+#define VertexAttrib1svNV_remap_index 302
+#define VertexAttrib2dNV_remap_index 303
+#define VertexAttrib2dvNV_remap_index 304
+#define VertexAttrib2fNV_remap_index 305
+#define VertexAttrib2fvNV_remap_index 306
+#define VertexAttrib2sNV_remap_index 307
+#define VertexAttrib2svNV_remap_index 308
+#define VertexAttrib3dNV_remap_index 309
+#define VertexAttrib3dvNV_remap_index 310
+#define VertexAttrib3fNV_remap_index 311
+#define VertexAttrib3fvNV_remap_index 312
+#define VertexAttrib3sNV_remap_index 313
+#define VertexAttrib3svNV_remap_index 314
+#define VertexAttrib4dNV_remap_index 315
+#define VertexAttrib4dvNV_remap_index 316
+#define VertexAttrib4fNV_remap_index 317
+#define VertexAttrib4fvNV_remap_index 318
+#define VertexAttrib4sNV_remap_index 319
+#define VertexAttrib4svNV_remap_index 320
+#define VertexAttrib4ubNV_remap_index 321
+#define VertexAttrib4ubvNV_remap_index 322
+#define VertexAttribPointerNV_remap_index 323
+#define VertexAttribs1dvNV_remap_index 324
+#define VertexAttribs1fvNV_remap_index 325
+#define VertexAttribs1svNV_remap_index 326
+#define VertexAttribs2dvNV_remap_index 327
+#define VertexAttribs2fvNV_remap_index 328
+#define VertexAttribs2svNV_remap_index 329
+#define VertexAttribs3dvNV_remap_index 330
+#define VertexAttribs3fvNV_remap_index 331
+#define VertexAttribs3svNV_remap_index 332
+#define VertexAttribs4dvNV_remap_index 333
+#define VertexAttribs4fvNV_remap_index 334
+#define VertexAttribs4svNV_remap_index 335
+#define VertexAttribs4ubvNV_remap_index 336
+#define GetTexBumpParameterfvATI_remap_index 337
+#define GetTexBumpParameterivATI_remap_index 338
+#define TexBumpParameterfvATI_remap_index 339
+#define TexBumpParameterivATI_remap_index 340
+#define AlphaFragmentOp1ATI_remap_index 341
+#define AlphaFragmentOp2ATI_remap_index 342
+#define AlphaFragmentOp3ATI_remap_index 343
+#define BeginFragmentShaderATI_remap_index 344
+#define BindFragmentShaderATI_remap_index 345
+#define ColorFragmentOp1ATI_remap_index 346
+#define ColorFragmentOp2ATI_remap_index 347
+#define ColorFragmentOp3ATI_remap_index 348
+#define DeleteFragmentShaderATI_remap_index 349
+#define EndFragmentShaderATI_remap_index 350
+#define GenFragmentShadersATI_remap_index 351
+#define PassTexCoordATI_remap_index 352
+#define SampleMapATI_remap_index 353
+#define SetFragmentShaderConstantATI_remap_index 354
+#define PointParameteriNV_remap_index 355
+#define PointParameterivNV_remap_index 356
+#define ActiveStencilFaceEXT_remap_index 357
+#define BindVertexArrayAPPLE_remap_index 358
+#define DeleteVertexArraysAPPLE_remap_index 359
+#define GenVertexArraysAPPLE_remap_index 360
+#define IsVertexArrayAPPLE_remap_index 361
+#define GetProgramNamedParameterdvNV_remap_index 362
+#define GetProgramNamedParameterfvNV_remap_index 363
+#define ProgramNamedParameter4dNV_remap_index 364
+#define ProgramNamedParameter4dvNV_remap_index 365
+#define ProgramNamedParameter4fNV_remap_index 366
+#define ProgramNamedParameter4fvNV_remap_index 367
+#define DepthBoundsEXT_remap_index 368
+#define BlendEquationSeparateEXT_remap_index 369
+#define BindFramebufferEXT_remap_index 370
+#define BindRenderbufferEXT_remap_index 371
+#define CheckFramebufferStatusEXT_remap_index 372
+#define DeleteFramebuffersEXT_remap_index 373
+#define DeleteRenderbuffersEXT_remap_index 374
+#define FramebufferRenderbufferEXT_remap_index 375
+#define FramebufferTexture1DEXT_remap_index 376
+#define FramebufferTexture2DEXT_remap_index 377
+#define FramebufferTexture3DEXT_remap_index 378
+#define GenFramebuffersEXT_remap_index 379
+#define GenRenderbuffersEXT_remap_index 380
+#define GenerateMipmapEXT_remap_index 381
+#define GetFramebufferAttachmentParameterivEXT_remap_index 382
+#define GetRenderbufferParameterivEXT_remap_index 383
+#define IsFramebufferEXT_remap_index 384
+#define IsRenderbufferEXT_remap_index 385
+#define RenderbufferStorageEXT_remap_index 386
+#define BlitFramebufferEXT_remap_index 387
+#define BufferParameteriAPPLE_remap_index 388
+#define FlushMappedBufferRangeAPPLE_remap_index 389
+#define FramebufferTextureLayerEXT_remap_index 390
+#define ColorMaskIndexedEXT_remap_index 391
+#define DisableIndexedEXT_remap_index 392
+#define EnableIndexedEXT_remap_index 393
+#define GetBooleanIndexedvEXT_remap_index 394
+#define GetIntegerIndexedvEXT_remap_index 395
+#define IsEnabledIndexedEXT_remap_index 396
+#define BeginConditionalRenderNV_remap_index 397
+#define EndConditionalRenderNV_remap_index 398
+#define BeginTransformFeedbackEXT_remap_index 399
+#define BindBufferBaseEXT_remap_index 400
+#define BindBufferOffsetEXT_remap_index 401
+#define BindBufferRangeEXT_remap_index 402
+#define EndTransformFeedbackEXT_remap_index 403
+#define GetTransformFeedbackVaryingEXT_remap_index 404
+#define TransformFeedbackVaryingsEXT_remap_index 405
+#define ProvokingVertexEXT_remap_index 406
+#define GetTexParameterPointervAPPLE_remap_index 407
+#define TextureRangeAPPLE_remap_index 408
+#define GetObjectParameterivAPPLE_remap_index 409
+#define ObjectPurgeableAPPLE_remap_index 410
+#define ObjectUnpurgeableAPPLE_remap_index 411
+#define StencilFuncSeparateATI_remap_index 412
+#define ProgramEnvParameters4fvEXT_remap_index 413
+#define ProgramLocalParameters4fvEXT_remap_index 414
+#define GetQueryObjecti64vEXT_remap_index 415
+#define GetQueryObjectui64vEXT_remap_index 416
+#define EGLImageTargetRenderbufferStorageOES_remap_index 417
+#define EGLImageTargetTexture2DOES_remap_index 418
 
 #define CALL_AttachShader(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLuint, GLuint)), driDispatchRemapTable[AttachShader_remap_index], parameters)
 #define GET_AttachShader(disp) GET_by_offset(disp, driDispatchRemapTable[AttachShader_remap_index])
@@ -3396,6 +3436,15 @@ extern int driDispatchRemapTable[ driDispatchRemapTable_size ];
 #define CALL_RenderbufferStorageMultisample(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLsizei, GLenum, GLsizei, GLsizei)), driDispatchRemapTable[RenderbufferStorageMultisample_remap_index], parameters)
 #define GET_RenderbufferStorageMultisample(disp) GET_by_offset(disp, driDispatchRemapTable[RenderbufferStorageMultisample_remap_index])
 #define SET_RenderbufferStorageMultisample(disp, fn) SET_by_offset(disp, driDispatchRemapTable[RenderbufferStorageMultisample_remap_index], fn)
+#define CALL_FramebufferTextureARB(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLenum, GLuint, GLint)), driDispatchRemapTable[FramebufferTextureARB_remap_index], parameters)
+#define GET_FramebufferTextureARB(disp) GET_by_offset(disp, driDispatchRemapTable[FramebufferTextureARB_remap_index])
+#define SET_FramebufferTextureARB(disp, fn) SET_by_offset(disp, driDispatchRemapTable[FramebufferTextureARB_remap_index], fn)
+#define CALL_FramebufferTextureFaceARB(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLenum, GLuint, GLint, GLenum)), driDispatchRemapTable[FramebufferTextureFaceARB_remap_index], parameters)
+#define GET_FramebufferTextureFaceARB(disp) GET_by_offset(disp, driDispatchRemapTable[FramebufferTextureFaceARB_remap_index])
+#define SET_FramebufferTextureFaceARB(disp, fn) SET_by_offset(disp, driDispatchRemapTable[FramebufferTextureFaceARB_remap_index], fn)
+#define CALL_ProgramParameteriARB(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLuint, GLenum, GLint)), driDispatchRemapTable[ProgramParameteriARB_remap_index], parameters)
+#define GET_ProgramParameteriARB(disp) GET_by_offset(disp, driDispatchRemapTable[ProgramParameteriARB_remap_index])
+#define SET_ProgramParameteriARB(disp, fn) SET_by_offset(disp, driDispatchRemapTable[ProgramParameteriARB_remap_index], fn)
 #define CALL_FlushMappedBufferRange(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLintptr, GLsizeiptr)), driDispatchRemapTable[FlushMappedBufferRange_remap_index], parameters)
 #define GET_FlushMappedBufferRange(disp) GET_by_offset(disp, driDispatchRemapTable[FlushMappedBufferRange_remap_index])
 #define SET_FlushMappedBufferRange(disp, fn) SET_by_offset(disp, driDispatchRemapTable[FlushMappedBufferRange_remap_index], fn)
@@ -3441,6 +3490,27 @@ extern int driDispatchRemapTable[ driDispatchRemapTable_size ];
 #define CALL_MultiDrawElementsBaseVertex(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, const GLsizei *, GLenum, const GLvoid **, GLsizei, const GLint *)), driDispatchRemapTable[MultiDrawElementsBaseVertex_remap_index], parameters)
 #define GET_MultiDrawElementsBaseVertex(disp) GET_by_offset(disp, driDispatchRemapTable[MultiDrawElementsBaseVertex_remap_index])
 #define SET_MultiDrawElementsBaseVertex(disp, fn) SET_by_offset(disp, driDispatchRemapTable[MultiDrawElementsBaseVertex_remap_index], fn)
+#define CALL_BindTransformFeedback(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLuint)), driDispatchRemapTable[BindTransformFeedback_remap_index], parameters)
+#define GET_BindTransformFeedback(disp) GET_by_offset(disp, driDispatchRemapTable[BindTransformFeedback_remap_index])
+#define SET_BindTransformFeedback(disp, fn) SET_by_offset(disp, driDispatchRemapTable[BindTransformFeedback_remap_index], fn)
+#define CALL_DeleteTransformFeedbacks(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLsizei, const GLuint *)), driDispatchRemapTable[DeleteTransformFeedbacks_remap_index], parameters)
+#define GET_DeleteTransformFeedbacks(disp) GET_by_offset(disp, driDispatchRemapTable[DeleteTransformFeedbacks_remap_index])
+#define SET_DeleteTransformFeedbacks(disp, fn) SET_by_offset(disp, driDispatchRemapTable[DeleteTransformFeedbacks_remap_index], fn)
+#define CALL_DrawTransformFeedback(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLuint)), driDispatchRemapTable[DrawTransformFeedback_remap_index], parameters)
+#define GET_DrawTransformFeedback(disp) GET_by_offset(disp, driDispatchRemapTable[DrawTransformFeedback_remap_index])
+#define SET_DrawTransformFeedback(disp, fn) SET_by_offset(disp, driDispatchRemapTable[DrawTransformFeedback_remap_index], fn)
+#define CALL_GenTransformFeedbacks(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLsizei, GLuint *)), driDispatchRemapTable[GenTransformFeedbacks_remap_index], parameters)
+#define GET_GenTransformFeedbacks(disp) GET_by_offset(disp, driDispatchRemapTable[GenTransformFeedbacks_remap_index])
+#define SET_GenTransformFeedbacks(disp, fn) SET_by_offset(disp, driDispatchRemapTable[GenTransformFeedbacks_remap_index], fn)
+#define CALL_IsTransformFeedback(disp, parameters) CALL_by_offset(disp, (GLboolean (GLAPIENTRYP)(GLuint)), driDispatchRemapTable[IsTransformFeedback_remap_index], parameters)
+#define GET_IsTransformFeedback(disp) GET_by_offset(disp, driDispatchRemapTable[IsTransformFeedback_remap_index])
+#define SET_IsTransformFeedback(disp, fn) SET_by_offset(disp, driDispatchRemapTable[IsTransformFeedback_remap_index], fn)
+#define CALL_PauseTransformFeedback(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(void)), driDispatchRemapTable[PauseTransformFeedback_remap_index], parameters)
+#define GET_PauseTransformFeedback(disp) GET_by_offset(disp, driDispatchRemapTable[PauseTransformFeedback_remap_index])
+#define SET_PauseTransformFeedback(disp, fn) SET_by_offset(disp, driDispatchRemapTable[PauseTransformFeedback_remap_index], fn)
+#define CALL_ResumeTransformFeedback(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(void)), driDispatchRemapTable[ResumeTransformFeedback_remap_index], parameters)
+#define GET_ResumeTransformFeedback(disp) GET_by_offset(disp, driDispatchRemapTable[ResumeTransformFeedback_remap_index])
+#define SET_ResumeTransformFeedback(disp, fn) SET_by_offset(disp, driDispatchRemapTable[ResumeTransformFeedback_remap_index], fn)
 #define CALL_PolygonOffsetEXT(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLfloat, GLfloat)), driDispatchRemapTable[PolygonOffsetEXT_remap_index], parameters)
 #define GET_PolygonOffsetEXT(disp) GET_by_offset(disp, driDispatchRemapTable[PolygonOffsetEXT_remap_index])
 #define SET_PolygonOffsetEXT(disp, fn) SET_by_offset(disp, driDispatchRemapTable[PolygonOffsetEXT_remap_index], fn)
index a8133b40737ff1a567cd7bc2ac09bf9e949e0496..a790d87322e15f472a957581c03269550b22f8fd 100644 (file)
 #define _gloffset_GetAttribLocationARB 561
 #define _gloffset_DrawBuffersARB 562
 #define _gloffset_RenderbufferStorageMultisample 563
-#define _gloffset_FlushMappedBufferRange 564
-#define _gloffset_MapBufferRange 565
-#define _gloffset_BindVertexArray 566
-#define _gloffset_GenVertexArrays 567
-#define _gloffset_CopyBufferSubData 568
-#define _gloffset_ClientWaitSync 569
-#define _gloffset_DeleteSync 570
-#define _gloffset_FenceSync 571
-#define _gloffset_GetInteger64v 572
-#define _gloffset_GetSynciv 573
-#define _gloffset_IsSync 574
-#define _gloffset_WaitSync 575
-#define _gloffset_DrawElementsBaseVertex 576
-#define _gloffset_DrawRangeElementsBaseVertex 577
-#define _gloffset_MultiDrawElementsBaseVertex 578
-#define _gloffset_PolygonOffsetEXT 579
-#define _gloffset_GetPixelTexGenParameterfvSGIS 580
-#define _gloffset_GetPixelTexGenParameterivSGIS 581
-#define _gloffset_PixelTexGenParameterfSGIS 582
-#define _gloffset_PixelTexGenParameterfvSGIS 583
-#define _gloffset_PixelTexGenParameteriSGIS 584
-#define _gloffset_PixelTexGenParameterivSGIS 585
-#define _gloffset_SampleMaskSGIS 586
-#define _gloffset_SamplePatternSGIS 587
-#define _gloffset_ColorPointerEXT 588
-#define _gloffset_EdgeFlagPointerEXT 589
-#define _gloffset_IndexPointerEXT 590
-#define _gloffset_NormalPointerEXT 591
-#define _gloffset_TexCoordPointerEXT 592
-#define _gloffset_VertexPointerEXT 593
-#define _gloffset_PointParameterfEXT 594
-#define _gloffset_PointParameterfvEXT 595
-#define _gloffset_LockArraysEXT 596
-#define _gloffset_UnlockArraysEXT 597
-#define _gloffset_CullParameterdvEXT 598
-#define _gloffset_CullParameterfvEXT 599
-#define _gloffset_SecondaryColor3bEXT 600
-#define _gloffset_SecondaryColor3bvEXT 601
-#define _gloffset_SecondaryColor3dEXT 602
-#define _gloffset_SecondaryColor3dvEXT 603
-#define _gloffset_SecondaryColor3fEXT 604
-#define _gloffset_SecondaryColor3fvEXT 605
-#define _gloffset_SecondaryColor3iEXT 606
-#define _gloffset_SecondaryColor3ivEXT 607
-#define _gloffset_SecondaryColor3sEXT 608
-#define _gloffset_SecondaryColor3svEXT 609
-#define _gloffset_SecondaryColor3ubEXT 610
-#define _gloffset_SecondaryColor3ubvEXT 611
-#define _gloffset_SecondaryColor3uiEXT 612
-#define _gloffset_SecondaryColor3uivEXT 613
-#define _gloffset_SecondaryColor3usEXT 614
-#define _gloffset_SecondaryColor3usvEXT 615
-#define _gloffset_SecondaryColorPointerEXT 616
-#define _gloffset_MultiDrawArraysEXT 617
-#define _gloffset_MultiDrawElementsEXT 618
-#define _gloffset_FogCoordPointerEXT 619
-#define _gloffset_FogCoorddEXT 620
-#define _gloffset_FogCoorddvEXT 621
-#define _gloffset_FogCoordfEXT 622
-#define _gloffset_FogCoordfvEXT 623
-#define _gloffset_PixelTexGenSGIX 624
-#define _gloffset_BlendFuncSeparateEXT 625
-#define _gloffset_FlushVertexArrayRangeNV 626
-#define _gloffset_VertexArrayRangeNV 627
-#define _gloffset_CombinerInputNV 628
-#define _gloffset_CombinerOutputNV 629
-#define _gloffset_CombinerParameterfNV 630
-#define _gloffset_CombinerParameterfvNV 631
-#define _gloffset_CombinerParameteriNV 632
-#define _gloffset_CombinerParameterivNV 633
-#define _gloffset_FinalCombinerInputNV 634
-#define _gloffset_GetCombinerInputParameterfvNV 635
-#define _gloffset_GetCombinerInputParameterivNV 636
-#define _gloffset_GetCombinerOutputParameterfvNV 637
-#define _gloffset_GetCombinerOutputParameterivNV 638
-#define _gloffset_GetFinalCombinerInputParameterfvNV 639
-#define _gloffset_GetFinalCombinerInputParameterivNV 640
-#define _gloffset_ResizeBuffersMESA 641
-#define _gloffset_WindowPos2dMESA 642
-#define _gloffset_WindowPos2dvMESA 643
-#define _gloffset_WindowPos2fMESA 644
-#define _gloffset_WindowPos2fvMESA 645
-#define _gloffset_WindowPos2iMESA 646
-#define _gloffset_WindowPos2ivMESA 647
-#define _gloffset_WindowPos2sMESA 648
-#define _gloffset_WindowPos2svMESA 649
-#define _gloffset_WindowPos3dMESA 650
-#define _gloffset_WindowPos3dvMESA 651
-#define _gloffset_WindowPos3fMESA 652
-#define _gloffset_WindowPos3fvMESA 653
-#define _gloffset_WindowPos3iMESA 654
-#define _gloffset_WindowPos3ivMESA 655
-#define _gloffset_WindowPos3sMESA 656
-#define _gloffset_WindowPos3svMESA 657
-#define _gloffset_WindowPos4dMESA 658
-#define _gloffset_WindowPos4dvMESA 659
-#define _gloffset_WindowPos4fMESA 660
-#define _gloffset_WindowPos4fvMESA 661
-#define _gloffset_WindowPos4iMESA 662
-#define _gloffset_WindowPos4ivMESA 663
-#define _gloffset_WindowPos4sMESA 664
-#define _gloffset_WindowPos4svMESA 665
-#define _gloffset_MultiModeDrawArraysIBM 666
-#define _gloffset_MultiModeDrawElementsIBM 667
-#define _gloffset_DeleteFencesNV 668
-#define _gloffset_FinishFenceNV 669
-#define _gloffset_GenFencesNV 670
-#define _gloffset_GetFenceivNV 671
-#define _gloffset_IsFenceNV 672
-#define _gloffset_SetFenceNV 673
-#define _gloffset_TestFenceNV 674
-#define _gloffset_AreProgramsResidentNV 675
-#define _gloffset_BindProgramNV 676
-#define _gloffset_DeleteProgramsNV 677
-#define _gloffset_ExecuteProgramNV 678
-#define _gloffset_GenProgramsNV 679
-#define _gloffset_GetProgramParameterdvNV 680
-#define _gloffset_GetProgramParameterfvNV 681
-#define _gloffset_GetProgramStringNV 682
-#define _gloffset_GetProgramivNV 683
-#define _gloffset_GetTrackMatrixivNV 684
-#define _gloffset_GetVertexAttribPointervNV 685
-#define _gloffset_GetVertexAttribdvNV 686
-#define _gloffset_GetVertexAttribfvNV 687
-#define _gloffset_GetVertexAttribivNV 688
-#define _gloffset_IsProgramNV 689
-#define _gloffset_LoadProgramNV 690
-#define _gloffset_ProgramParameters4dvNV 691
-#define _gloffset_ProgramParameters4fvNV 692
-#define _gloffset_RequestResidentProgramsNV 693
-#define _gloffset_TrackMatrixNV 694
-#define _gloffset_VertexAttrib1dNV 695
-#define _gloffset_VertexAttrib1dvNV 696
-#define _gloffset_VertexAttrib1fNV 697
-#define _gloffset_VertexAttrib1fvNV 698
-#define _gloffset_VertexAttrib1sNV 699
-#define _gloffset_VertexAttrib1svNV 700
-#define _gloffset_VertexAttrib2dNV 701
-#define _gloffset_VertexAttrib2dvNV 702
-#define _gloffset_VertexAttrib2fNV 703
-#define _gloffset_VertexAttrib2fvNV 704
-#define _gloffset_VertexAttrib2sNV 705
-#define _gloffset_VertexAttrib2svNV 706
-#define _gloffset_VertexAttrib3dNV 707
-#define _gloffset_VertexAttrib3dvNV 708
-#define _gloffset_VertexAttrib3fNV 709
-#define _gloffset_VertexAttrib3fvNV 710
-#define _gloffset_VertexAttrib3sNV 711
-#define _gloffset_VertexAttrib3svNV 712
-#define _gloffset_VertexAttrib4dNV 713
-#define _gloffset_VertexAttrib4dvNV 714
-#define _gloffset_VertexAttrib4fNV 715
-#define _gloffset_VertexAttrib4fvNV 716
-#define _gloffset_VertexAttrib4sNV 717
-#define _gloffset_VertexAttrib4svNV 718
-#define _gloffset_VertexAttrib4ubNV 719
-#define _gloffset_VertexAttrib4ubvNV 720
-#define _gloffset_VertexAttribPointerNV 721
-#define _gloffset_VertexAttribs1dvNV 722
-#define _gloffset_VertexAttribs1fvNV 723
-#define _gloffset_VertexAttribs1svNV 724
-#define _gloffset_VertexAttribs2dvNV 725
-#define _gloffset_VertexAttribs2fvNV 726
-#define _gloffset_VertexAttribs2svNV 727
-#define _gloffset_VertexAttribs3dvNV 728
-#define _gloffset_VertexAttribs3fvNV 729
-#define _gloffset_VertexAttribs3svNV 730
-#define _gloffset_VertexAttribs4dvNV 731
-#define _gloffset_VertexAttribs4fvNV 732
-#define _gloffset_VertexAttribs4svNV 733
-#define _gloffset_VertexAttribs4ubvNV 734
-#define _gloffset_GetTexBumpParameterfvATI 735
-#define _gloffset_GetTexBumpParameterivATI 736
-#define _gloffset_TexBumpParameterfvATI 737
-#define _gloffset_TexBumpParameterivATI 738
-#define _gloffset_AlphaFragmentOp1ATI 739
-#define _gloffset_AlphaFragmentOp2ATI 740
-#define _gloffset_AlphaFragmentOp3ATI 741
-#define _gloffset_BeginFragmentShaderATI 742
-#define _gloffset_BindFragmentShaderATI 743
-#define _gloffset_ColorFragmentOp1ATI 744
-#define _gloffset_ColorFragmentOp2ATI 745
-#define _gloffset_ColorFragmentOp3ATI 746
-#define _gloffset_DeleteFragmentShaderATI 747
-#define _gloffset_EndFragmentShaderATI 748
-#define _gloffset_GenFragmentShadersATI 749
-#define _gloffset_PassTexCoordATI 750
-#define _gloffset_SampleMapATI 751
-#define _gloffset_SetFragmentShaderConstantATI 752
-#define _gloffset_PointParameteriNV 753
-#define _gloffset_PointParameterivNV 754
-#define _gloffset_ActiveStencilFaceEXT 755
-#define _gloffset_BindVertexArrayAPPLE 756
-#define _gloffset_DeleteVertexArraysAPPLE 757
-#define _gloffset_GenVertexArraysAPPLE 758
-#define _gloffset_IsVertexArrayAPPLE 759
-#define _gloffset_GetProgramNamedParameterdvNV 760
-#define _gloffset_GetProgramNamedParameterfvNV 761
-#define _gloffset_ProgramNamedParameter4dNV 762
-#define _gloffset_ProgramNamedParameter4dvNV 763
-#define _gloffset_ProgramNamedParameter4fNV 764
-#define _gloffset_ProgramNamedParameter4fvNV 765
-#define _gloffset_DepthBoundsEXT 766
-#define _gloffset_BlendEquationSeparateEXT 767
-#define _gloffset_BindFramebufferEXT 768
-#define _gloffset_BindRenderbufferEXT 769
-#define _gloffset_CheckFramebufferStatusEXT 770
-#define _gloffset_DeleteFramebuffersEXT 771
-#define _gloffset_DeleteRenderbuffersEXT 772
-#define _gloffset_FramebufferRenderbufferEXT 773
-#define _gloffset_FramebufferTexture1DEXT 774
-#define _gloffset_FramebufferTexture2DEXT 775
-#define _gloffset_FramebufferTexture3DEXT 776
-#define _gloffset_GenFramebuffersEXT 777
-#define _gloffset_GenRenderbuffersEXT 778
-#define _gloffset_GenerateMipmapEXT 779
-#define _gloffset_GetFramebufferAttachmentParameterivEXT 780
-#define _gloffset_GetRenderbufferParameterivEXT 781
-#define _gloffset_IsFramebufferEXT 782
-#define _gloffset_IsRenderbufferEXT 783
-#define _gloffset_RenderbufferStorageEXT 784
-#define _gloffset_BlitFramebufferEXT 785
-#define _gloffset_BufferParameteriAPPLE 786
-#define _gloffset_FlushMappedBufferRangeAPPLE 787
-#define _gloffset_FramebufferTextureLayerEXT 788
-#define _gloffset_ColorMaskIndexedEXT 789
-#define _gloffset_DisableIndexedEXT 790
-#define _gloffset_EnableIndexedEXT 791
-#define _gloffset_GetBooleanIndexedvEXT 792
-#define _gloffset_GetIntegerIndexedvEXT 793
-#define _gloffset_IsEnabledIndexedEXT 794
-#define _gloffset_BeginConditionalRenderNV 795
-#define _gloffset_EndConditionalRenderNV 796
-#define _gloffset_BeginTransformFeedbackEXT 797
-#define _gloffset_BindBufferBaseEXT 798
-#define _gloffset_BindBufferOffsetEXT 799
-#define _gloffset_BindBufferRangeEXT 800
-#define _gloffset_EndTransformFeedbackEXT 801
-#define _gloffset_GetTransformFeedbackVaryingEXT 802
-#define _gloffset_TransformFeedbackVaryingsEXT 803
-#define _gloffset_ProvokingVertexEXT 804
-#define _gloffset_GetTexParameterPointervAPPLE 805
-#define _gloffset_TextureRangeAPPLE 806
-#define _gloffset_GetObjectParameterivAPPLE 807
-#define _gloffset_ObjectPurgeableAPPLE 808
-#define _gloffset_ObjectUnpurgeableAPPLE 809
-#define _gloffset_StencilFuncSeparateATI 810
-#define _gloffset_ProgramEnvParameters4fvEXT 811
-#define _gloffset_ProgramLocalParameters4fvEXT 812
-#define _gloffset_GetQueryObjecti64vEXT 813
-#define _gloffset_GetQueryObjectui64vEXT 814
-#define _gloffset_EGLImageTargetRenderbufferStorageOES 815
-#define _gloffset_EGLImageTargetTexture2DOES 816
-#define _gloffset_FIRST_DYNAMIC 817
+#define _gloffset_FramebufferTextureARB 564
+#define _gloffset_FramebufferTextureFaceARB 565
+#define _gloffset_ProgramParameteriARB 566
+#define _gloffset_FlushMappedBufferRange 567
+#define _gloffset_MapBufferRange 568
+#define _gloffset_BindVertexArray 569
+#define _gloffset_GenVertexArrays 570
+#define _gloffset_CopyBufferSubData 571
+#define _gloffset_ClientWaitSync 572
+#define _gloffset_DeleteSync 573
+#define _gloffset_FenceSync 574
+#define _gloffset_GetInteger64v 575
+#define _gloffset_GetSynciv 576
+#define _gloffset_IsSync 577
+#define _gloffset_WaitSync 578
+#define _gloffset_DrawElementsBaseVertex 579
+#define _gloffset_DrawRangeElementsBaseVertex 580
+#define _gloffset_MultiDrawElementsBaseVertex 581
+#define _gloffset_BindTransformFeedback 582
+#define _gloffset_DeleteTransformFeedbacks 583
+#define _gloffset_DrawTransformFeedback 584
+#define _gloffset_GenTransformFeedbacks 585
+#define _gloffset_IsTransformFeedback 586
+#define _gloffset_PauseTransformFeedback 587
+#define _gloffset_ResumeTransformFeedback 588
+#define _gloffset_PolygonOffsetEXT 589
+#define _gloffset_GetPixelTexGenParameterfvSGIS 590
+#define _gloffset_GetPixelTexGenParameterivSGIS 591
+#define _gloffset_PixelTexGenParameterfSGIS 592
+#define _gloffset_PixelTexGenParameterfvSGIS 593
+#define _gloffset_PixelTexGenParameteriSGIS 594
+#define _gloffset_PixelTexGenParameterivSGIS 595
+#define _gloffset_SampleMaskSGIS 596
+#define _gloffset_SamplePatternSGIS 597
+#define _gloffset_ColorPointerEXT 598
+#define _gloffset_EdgeFlagPointerEXT 599
+#define _gloffset_IndexPointerEXT 600
+#define _gloffset_NormalPointerEXT 601
+#define _gloffset_TexCoordPointerEXT 602
+#define _gloffset_VertexPointerEXT 603
+#define _gloffset_PointParameterfEXT 604
+#define _gloffset_PointParameterfvEXT 605
+#define _gloffset_LockArraysEXT 606
+#define _gloffset_UnlockArraysEXT 607
+#define _gloffset_CullParameterdvEXT 608
+#define _gloffset_CullParameterfvEXT 609
+#define _gloffset_SecondaryColor3bEXT 610
+#define _gloffset_SecondaryColor3bvEXT 611
+#define _gloffset_SecondaryColor3dEXT 612
+#define _gloffset_SecondaryColor3dvEXT 613
+#define _gloffset_SecondaryColor3fEXT 614
+#define _gloffset_SecondaryColor3fvEXT 615
+#define _gloffset_SecondaryColor3iEXT 616
+#define _gloffset_SecondaryColor3ivEXT 617
+#define _gloffset_SecondaryColor3sEXT 618
+#define _gloffset_SecondaryColor3svEXT 619
+#define _gloffset_SecondaryColor3ubEXT 620
+#define _gloffset_SecondaryColor3ubvEXT 621
+#define _gloffset_SecondaryColor3uiEXT 622
+#define _gloffset_SecondaryColor3uivEXT 623
+#define _gloffset_SecondaryColor3usEXT 624
+#define _gloffset_SecondaryColor3usvEXT 625
+#define _gloffset_SecondaryColorPointerEXT 626
+#define _gloffset_MultiDrawArraysEXT 627
+#define _gloffset_MultiDrawElementsEXT 628
+#define _gloffset_FogCoordPointerEXT 629
+#define _gloffset_FogCoorddEXT 630
+#define _gloffset_FogCoorddvEXT 631
+#define _gloffset_FogCoordfEXT 632
+#define _gloffset_FogCoordfvEXT 633
+#define _gloffset_PixelTexGenSGIX 634
+#define _gloffset_BlendFuncSeparateEXT 635
+#define _gloffset_FlushVertexArrayRangeNV 636
+#define _gloffset_VertexArrayRangeNV 637
+#define _gloffset_CombinerInputNV 638
+#define _gloffset_CombinerOutputNV 639
+#define _gloffset_CombinerParameterfNV 640
+#define _gloffset_CombinerParameterfvNV 641
+#define _gloffset_CombinerParameteriNV 642
+#define _gloffset_CombinerParameterivNV 643
+#define _gloffset_FinalCombinerInputNV 644
+#define _gloffset_GetCombinerInputParameterfvNV 645
+#define _gloffset_GetCombinerInputParameterivNV 646
+#define _gloffset_GetCombinerOutputParameterfvNV 647
+#define _gloffset_GetCombinerOutputParameterivNV 648
+#define _gloffset_GetFinalCombinerInputParameterfvNV 649
+#define _gloffset_GetFinalCombinerInputParameterivNV 650
+#define _gloffset_ResizeBuffersMESA 651
+#define _gloffset_WindowPos2dMESA 652
+#define _gloffset_WindowPos2dvMESA 653
+#define _gloffset_WindowPos2fMESA 654
+#define _gloffset_WindowPos2fvMESA 655
+#define _gloffset_WindowPos2iMESA 656
+#define _gloffset_WindowPos2ivMESA 657
+#define _gloffset_WindowPos2sMESA 658
+#define _gloffset_WindowPos2svMESA 659
+#define _gloffset_WindowPos3dMESA 660
+#define _gloffset_WindowPos3dvMESA 661
+#define _gloffset_WindowPos3fMESA 662
+#define _gloffset_WindowPos3fvMESA 663
+#define _gloffset_WindowPos3iMESA 664
+#define _gloffset_WindowPos3ivMESA 665
+#define _gloffset_WindowPos3sMESA 666
+#define _gloffset_WindowPos3svMESA 667
+#define _gloffset_WindowPos4dMESA 668
+#define _gloffset_WindowPos4dvMESA 669
+#define _gloffset_WindowPos4fMESA 670
+#define _gloffset_WindowPos4fvMESA 671
+#define _gloffset_WindowPos4iMESA 672
+#define _gloffset_WindowPos4ivMESA 673
+#define _gloffset_WindowPos4sMESA 674
+#define _gloffset_WindowPos4svMESA 675
+#define _gloffset_MultiModeDrawArraysIBM 676
+#define _gloffset_MultiModeDrawElementsIBM 677
+#define _gloffset_DeleteFencesNV 678
+#define _gloffset_FinishFenceNV 679
+#define _gloffset_GenFencesNV 680
+#define _gloffset_GetFenceivNV 681
+#define _gloffset_IsFenceNV 682
+#define _gloffset_SetFenceNV 683
+#define _gloffset_TestFenceNV 684
+#define _gloffset_AreProgramsResidentNV 685
+#define _gloffset_BindProgramNV 686
+#define _gloffset_DeleteProgramsNV 687
+#define _gloffset_ExecuteProgramNV 688
+#define _gloffset_GenProgramsNV 689
+#define _gloffset_GetProgramParameterdvNV 690
+#define _gloffset_GetProgramParameterfvNV 691
+#define _gloffset_GetProgramStringNV 692
+#define _gloffset_GetProgramivNV 693
+#define _gloffset_GetTrackMatrixivNV 694
+#define _gloffset_GetVertexAttribPointervNV 695
+#define _gloffset_GetVertexAttribdvNV 696
+#define _gloffset_GetVertexAttribfvNV 697
+#define _gloffset_GetVertexAttribivNV 698
+#define _gloffset_IsProgramNV 699
+#define _gloffset_LoadProgramNV 700
+#define _gloffset_ProgramParameters4dvNV 701
+#define _gloffset_ProgramParameters4fvNV 702
+#define _gloffset_RequestResidentProgramsNV 703
+#define _gloffset_TrackMatrixNV 704
+#define _gloffset_VertexAttrib1dNV 705
+#define _gloffset_VertexAttrib1dvNV 706
+#define _gloffset_VertexAttrib1fNV 707
+#define _gloffset_VertexAttrib1fvNV 708
+#define _gloffset_VertexAttrib1sNV 709
+#define _gloffset_VertexAttrib1svNV 710
+#define _gloffset_VertexAttrib2dNV 711
+#define _gloffset_VertexAttrib2dvNV 712
+#define _gloffset_VertexAttrib2fNV 713
+#define _gloffset_VertexAttrib2fvNV 714
+#define _gloffset_VertexAttrib2sNV 715
+#define _gloffset_VertexAttrib2svNV 716
+#define _gloffset_VertexAttrib3dNV 717
+#define _gloffset_VertexAttrib3dvNV 718
+#define _gloffset_VertexAttrib3fNV 719
+#define _gloffset_VertexAttrib3fvNV 720
+#define _gloffset_VertexAttrib3sNV 721
+#define _gloffset_VertexAttrib3svNV 722
+#define _gloffset_VertexAttrib4dNV 723
+#define _gloffset_VertexAttrib4dvNV 724
+#define _gloffset_VertexAttrib4fNV 725
+#define _gloffset_VertexAttrib4fvNV 726
+#define _gloffset_VertexAttrib4sNV 727
+#define _gloffset_VertexAttrib4svNV 728
+#define _gloffset_VertexAttrib4ubNV 729
+#define _gloffset_VertexAttrib4ubvNV 730
+#define _gloffset_VertexAttribPointerNV 731
+#define _gloffset_VertexAttribs1dvNV 732
+#define _gloffset_VertexAttribs1fvNV 733
+#define _gloffset_VertexAttribs1svNV 734
+#define _gloffset_VertexAttribs2dvNV 735
+#define _gloffset_VertexAttribs2fvNV 736
+#define _gloffset_VertexAttribs2svNV 737
+#define _gloffset_VertexAttribs3dvNV 738
+#define _gloffset_VertexAttribs3fvNV 739
+#define _gloffset_VertexAttribs3svNV 740
+#define _gloffset_VertexAttribs4dvNV 741
+#define _gloffset_VertexAttribs4fvNV 742
+#define _gloffset_VertexAttribs4svNV 743
+#define _gloffset_VertexAttribs4ubvNV 744
+#define _gloffset_GetTexBumpParameterfvATI 745
+#define _gloffset_GetTexBumpParameterivATI 746
+#define _gloffset_TexBumpParameterfvATI 747
+#define _gloffset_TexBumpParameterivATI 748
+#define _gloffset_AlphaFragmentOp1ATI 749
+#define _gloffset_AlphaFragmentOp2ATI 750
+#define _gloffset_AlphaFragmentOp3ATI 751
+#define _gloffset_BeginFragmentShaderATI 752
+#define _gloffset_BindFragmentShaderATI 753
+#define _gloffset_ColorFragmentOp1ATI 754
+#define _gloffset_ColorFragmentOp2ATI 755
+#define _gloffset_ColorFragmentOp3ATI 756
+#define _gloffset_DeleteFragmentShaderATI 757
+#define _gloffset_EndFragmentShaderATI 758
+#define _gloffset_GenFragmentShadersATI 759
+#define _gloffset_PassTexCoordATI 760
+#define _gloffset_SampleMapATI 761
+#define _gloffset_SetFragmentShaderConstantATI 762
+#define _gloffset_PointParameteriNV 763
+#define _gloffset_PointParameterivNV 764
+#define _gloffset_ActiveStencilFaceEXT 765
+#define _gloffset_BindVertexArrayAPPLE 766
+#define _gloffset_DeleteVertexArraysAPPLE 767
+#define _gloffset_GenVertexArraysAPPLE 768
+#define _gloffset_IsVertexArrayAPPLE 769
+#define _gloffset_GetProgramNamedParameterdvNV 770
+#define _gloffset_GetProgramNamedParameterfvNV 771
+#define _gloffset_ProgramNamedParameter4dNV 772
+#define _gloffset_ProgramNamedParameter4dvNV 773
+#define _gloffset_ProgramNamedParameter4fNV 774
+#define _gloffset_ProgramNamedParameter4fvNV 775
+#define _gloffset_DepthBoundsEXT 776
+#define _gloffset_BlendEquationSeparateEXT 777
+#define _gloffset_BindFramebufferEXT 778
+#define _gloffset_BindRenderbufferEXT 779
+#define _gloffset_CheckFramebufferStatusEXT 780
+#define _gloffset_DeleteFramebuffersEXT 781
+#define _gloffset_DeleteRenderbuffersEXT 782
+#define _gloffset_FramebufferRenderbufferEXT 783
+#define _gloffset_FramebufferTexture1DEXT 784
+#define _gloffset_FramebufferTexture2DEXT 785
+#define _gloffset_FramebufferTexture3DEXT 786
+#define _gloffset_GenFramebuffersEXT 787
+#define _gloffset_GenRenderbuffersEXT 788
+#define _gloffset_GenerateMipmapEXT 789
+#define _gloffset_GetFramebufferAttachmentParameterivEXT 790
+#define _gloffset_GetRenderbufferParameterivEXT 791
+#define _gloffset_IsFramebufferEXT 792
+#define _gloffset_IsRenderbufferEXT 793
+#define _gloffset_RenderbufferStorageEXT 794
+#define _gloffset_BlitFramebufferEXT 795
+#define _gloffset_BufferParameteriAPPLE 796
+#define _gloffset_FlushMappedBufferRangeAPPLE 797
+#define _gloffset_FramebufferTextureLayerEXT 798
+#define _gloffset_ColorMaskIndexedEXT 799
+#define _gloffset_DisableIndexedEXT 800
+#define _gloffset_EnableIndexedEXT 801
+#define _gloffset_GetBooleanIndexedvEXT 802
+#define _gloffset_GetIntegerIndexedvEXT 803
+#define _gloffset_IsEnabledIndexedEXT 804
+#define _gloffset_BeginConditionalRenderNV 805
+#define _gloffset_EndConditionalRenderNV 806
+#define _gloffset_BeginTransformFeedbackEXT 807
+#define _gloffset_BindBufferBaseEXT 808
+#define _gloffset_BindBufferOffsetEXT 809
+#define _gloffset_BindBufferRangeEXT 810
+#define _gloffset_EndTransformFeedbackEXT 811
+#define _gloffset_GetTransformFeedbackVaryingEXT 812
+#define _gloffset_TransformFeedbackVaryingsEXT 813
+#define _gloffset_ProvokingVertexEXT 814
+#define _gloffset_GetTexParameterPointervAPPLE 815
+#define _gloffset_TextureRangeAPPLE 816
+#define _gloffset_GetObjectParameterivAPPLE 817
+#define _gloffset_ObjectPurgeableAPPLE 818
+#define _gloffset_ObjectUnpurgeableAPPLE 819
+#define _gloffset_StencilFuncSeparateATI 820
+#define _gloffset_ProgramEnvParameters4fvEXT 821
+#define _gloffset_ProgramLocalParameters4fvEXT 822
+#define _gloffset_GetQueryObjecti64vEXT 823
+#define _gloffset_GetQueryObjectui64vEXT 824
+#define _gloffset_EGLImageTargetRenderbufferStorageOES 825
+#define _gloffset_EGLImageTargetTexture2DOES 826
+#define _gloffset_FIRST_DYNAMIC 827
 
 #else
 
 #define _gloffset_GetAttribLocationARB driDispatchRemapTable[GetAttribLocationARB_remap_index]
 #define _gloffset_DrawBuffersARB driDispatchRemapTable[DrawBuffersARB_remap_index]
 #define _gloffset_RenderbufferStorageMultisample driDispatchRemapTable[RenderbufferStorageMultisample_remap_index]
+#define _gloffset_FramebufferTextureARB driDispatchRemapTable[FramebufferTextureARB_remap_index]
+#define _gloffset_FramebufferTextureFaceARB driDispatchRemapTable[FramebufferTextureFaceARB_remap_index]
+#define _gloffset_ProgramParameteriARB driDispatchRemapTable[ProgramParameteriARB_remap_index]
 #define _gloffset_FlushMappedBufferRange driDispatchRemapTable[FlushMappedBufferRange_remap_index]
 #define _gloffset_MapBufferRange driDispatchRemapTable[MapBufferRange_remap_index]
 #define _gloffset_BindVertexArray driDispatchRemapTable[BindVertexArray_remap_index]
 #define _gloffset_DrawElementsBaseVertex driDispatchRemapTable[DrawElementsBaseVertex_remap_index]
 #define _gloffset_DrawRangeElementsBaseVertex driDispatchRemapTable[DrawRangeElementsBaseVertex_remap_index]
 #define _gloffset_MultiDrawElementsBaseVertex driDispatchRemapTable[MultiDrawElementsBaseVertex_remap_index]
+#define _gloffset_BindTransformFeedback driDispatchRemapTable[BindTransformFeedback_remap_index]
+#define _gloffset_DeleteTransformFeedbacks driDispatchRemapTable[DeleteTransformFeedbacks_remap_index]
+#define _gloffset_DrawTransformFeedback driDispatchRemapTable[DrawTransformFeedback_remap_index]
+#define _gloffset_GenTransformFeedbacks driDispatchRemapTable[GenTransformFeedbacks_remap_index]
+#define _gloffset_IsTransformFeedback driDispatchRemapTable[IsTransformFeedback_remap_index]
+#define _gloffset_PauseTransformFeedback driDispatchRemapTable[PauseTransformFeedback_remap_index]
+#define _gloffset_ResumeTransformFeedback driDispatchRemapTable[ResumeTransformFeedback_remap_index]
 #define _gloffset_PolygonOffsetEXT driDispatchRemapTable[PolygonOffsetEXT_remap_index]
 #define _gloffset_GetPixelTexGenParameterfvSGIS driDispatchRemapTable[GetPixelTexGenParameterfvSGIS_remap_index]
 #define _gloffset_GetPixelTexGenParameterivSGIS driDispatchRemapTable[GetPixelTexGenParameterivSGIS_remap_index]
index faf274f2704ae39ae57d2688f928f7eb34ae3e12..7da958981a846bd5b7861a02908db4411332e8a0 100644 (file)
@@ -604,259 +604,269 @@ struct _glapi_table
    GLint (GLAPIENTRYP GetAttribLocationARB)(GLhandleARB program, const GLcharARB * name); /* 561 */
    void (GLAPIENTRYP DrawBuffersARB)(GLsizei n, const GLenum * bufs); /* 562 */
    void (GLAPIENTRYP RenderbufferStorageMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); /* 563 */
-   void (GLAPIENTRYP FlushMappedBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length); /* 564 */
-   GLvoid * (GLAPIENTRYP MapBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); /* 565 */
-   void (GLAPIENTRYP BindVertexArray)(GLuint array); /* 566 */
-   void (GLAPIENTRYP GenVertexArrays)(GLsizei n, GLuint * arrays); /* 567 */
-   void (GLAPIENTRYP CopyBufferSubData)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); /* 568 */
-   GLenum (GLAPIENTRYP ClientWaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout); /* 569 */
-   void (GLAPIENTRYP DeleteSync)(GLsync sync); /* 570 */
-   GLsync (GLAPIENTRYP FenceSync)(GLenum condition, GLbitfield flags); /* 571 */
-   void (GLAPIENTRYP GetInteger64v)(GLenum pname, GLint64 * params); /* 572 */
-   void (GLAPIENTRYP GetSynciv)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei * length, GLint * values); /* 573 */
-   GLboolean (GLAPIENTRYP IsSync)(GLsync sync); /* 574 */
-   void (GLAPIENTRYP WaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout); /* 575 */
-   void (GLAPIENTRYP DrawElementsBaseVertex)(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices, GLint basevertex); /* 576 */
-   void (GLAPIENTRYP DrawRangeElementsBaseVertex)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid * indices, GLint basevertex); /* 577 */
-   void (GLAPIENTRYP MultiDrawElementsBaseVertex)(GLenum mode, const GLsizei * count, GLenum type, const GLvoid ** indices, GLsizei primcount, const GLint * basevertex); /* 578 */
-   void (GLAPIENTRYP PolygonOffsetEXT)(GLfloat factor, GLfloat bias); /* 579 */
-   void (GLAPIENTRYP GetPixelTexGenParameterfvSGIS)(GLenum pname, GLfloat * params); /* 580 */
-   void (GLAPIENTRYP GetPixelTexGenParameterivSGIS)(GLenum pname, GLint * params); /* 581 */
-   void (GLAPIENTRYP PixelTexGenParameterfSGIS)(GLenum pname, GLfloat param); /* 582 */
-   void (GLAPIENTRYP PixelTexGenParameterfvSGIS)(GLenum pname, const GLfloat * params); /* 583 */
-   void (GLAPIENTRYP PixelTexGenParameteriSGIS)(GLenum pname, GLint param); /* 584 */
-   void (GLAPIENTRYP PixelTexGenParameterivSGIS)(GLenum pname, const GLint * params); /* 585 */
-   void (GLAPIENTRYP SampleMaskSGIS)(GLclampf value, GLboolean invert); /* 586 */
-   void (GLAPIENTRYP SamplePatternSGIS)(GLenum pattern); /* 587 */
-   void (GLAPIENTRYP ColorPointerEXT)(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 588 */
-   void (GLAPIENTRYP EdgeFlagPointerEXT)(GLsizei stride, GLsizei count, const GLboolean * pointer); /* 589 */
-   void (GLAPIENTRYP IndexPointerEXT)(GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 590 */
-   void (GLAPIENTRYP NormalPointerEXT)(GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 591 */
-   void (GLAPIENTRYP TexCoordPointerEXT)(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 592 */
-   void (GLAPIENTRYP VertexPointerEXT)(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 593 */
-   void (GLAPIENTRYP PointParameterfEXT)(GLenum pname, GLfloat param); /* 594 */
-   void (GLAPIENTRYP PointParameterfvEXT)(GLenum pname, const GLfloat * params); /* 595 */
-   void (GLAPIENTRYP LockArraysEXT)(GLint first, GLsizei count); /* 596 */
-   void (GLAPIENTRYP UnlockArraysEXT)(void); /* 597 */
-   void (GLAPIENTRYP CullParameterdvEXT)(GLenum pname, GLdouble * params); /* 598 */
-   void (GLAPIENTRYP CullParameterfvEXT)(GLenum pname, GLfloat * params); /* 599 */
-   void (GLAPIENTRYP SecondaryColor3bEXT)(GLbyte red, GLbyte green, GLbyte blue); /* 600 */
-   void (GLAPIENTRYP SecondaryColor3bvEXT)(const GLbyte * v); /* 601 */
-   void (GLAPIENTRYP SecondaryColor3dEXT)(GLdouble red, GLdouble green, GLdouble blue); /* 602 */
-   void (GLAPIENTRYP SecondaryColor3dvEXT)(const GLdouble * v); /* 603 */
-   void (GLAPIENTRYP SecondaryColor3fEXT)(GLfloat red, GLfloat green, GLfloat blue); /* 604 */
-   void (GLAPIENTRYP SecondaryColor3fvEXT)(const GLfloat * v); /* 605 */
-   void (GLAPIENTRYP SecondaryColor3iEXT)(GLint red, GLint green, GLint blue); /* 606 */
-   void (GLAPIENTRYP SecondaryColor3ivEXT)(const GLint * v); /* 607 */
-   void (GLAPIENTRYP SecondaryColor3sEXT)(GLshort red, GLshort green, GLshort blue); /* 608 */
-   void (GLAPIENTRYP SecondaryColor3svEXT)(const GLshort * v); /* 609 */
-   void (GLAPIENTRYP SecondaryColor3ubEXT)(GLubyte red, GLubyte green, GLubyte blue); /* 610 */
-   void (GLAPIENTRYP SecondaryColor3ubvEXT)(const GLubyte * v); /* 611 */
-   void (GLAPIENTRYP SecondaryColor3uiEXT)(GLuint red, GLuint green, GLuint blue); /* 612 */
-   void (GLAPIENTRYP SecondaryColor3uivEXT)(const GLuint * v); /* 613 */
-   void (GLAPIENTRYP SecondaryColor3usEXT)(GLushort red, GLushort green, GLushort blue); /* 614 */
-   void (GLAPIENTRYP SecondaryColor3usvEXT)(const GLushort * v); /* 615 */
-   void (GLAPIENTRYP SecondaryColorPointerEXT)(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); /* 616 */
-   void (GLAPIENTRYP MultiDrawArraysEXT)(GLenum mode, GLint * first, GLsizei * count, GLsizei primcount); /* 617 */
-   void (GLAPIENTRYP MultiDrawElementsEXT)(GLenum mode, const GLsizei * count, GLenum type, const GLvoid ** indices, GLsizei primcount); /* 618 */
-   void (GLAPIENTRYP FogCoordPointerEXT)(GLenum type, GLsizei stride, const GLvoid * pointer); /* 619 */
-   void (GLAPIENTRYP FogCoorddEXT)(GLdouble coord); /* 620 */
-   void (GLAPIENTRYP FogCoorddvEXT)(const GLdouble * coord); /* 621 */
-   void (GLAPIENTRYP FogCoordfEXT)(GLfloat coord); /* 622 */
-   void (GLAPIENTRYP FogCoordfvEXT)(const GLfloat * coord); /* 623 */
-   void (GLAPIENTRYP PixelTexGenSGIX)(GLenum mode); /* 624 */
-   void (GLAPIENTRYP BlendFuncSeparateEXT)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); /* 625 */
-   void (GLAPIENTRYP FlushVertexArrayRangeNV)(void); /* 626 */
-   void (GLAPIENTRYP VertexArrayRangeNV)(GLsizei length, const GLvoid * pointer); /* 627 */
-   void (GLAPIENTRYP CombinerInputNV)(GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); /* 628 */
-   void (GLAPIENTRYP CombinerOutputNV)(GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); /* 629 */
-   void (GLAPIENTRYP CombinerParameterfNV)(GLenum pname, GLfloat param); /* 630 */
-   void (GLAPIENTRYP CombinerParameterfvNV)(GLenum pname, const GLfloat * params); /* 631 */
-   void (GLAPIENTRYP CombinerParameteriNV)(GLenum pname, GLint param); /* 632 */
-   void (GLAPIENTRYP CombinerParameterivNV)(GLenum pname, const GLint * params); /* 633 */
-   void (GLAPIENTRYP FinalCombinerInputNV)(GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); /* 634 */
-   void (GLAPIENTRYP GetCombinerInputParameterfvNV)(GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat * params); /* 635 */
-   void (GLAPIENTRYP GetCombinerInputParameterivNV)(GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint * params); /* 636 */
-   void (GLAPIENTRYP GetCombinerOutputParameterfvNV)(GLenum stage, GLenum portion, GLenum pname, GLfloat * params); /* 637 */
-   void (GLAPIENTRYP GetCombinerOutputParameterivNV)(GLenum stage, GLenum portion, GLenum pname, GLint * params); /* 638 */
-   void (GLAPIENTRYP GetFinalCombinerInputParameterfvNV)(GLenum variable, GLenum pname, GLfloat * params); /* 639 */
-   void (GLAPIENTRYP GetFinalCombinerInputParameterivNV)(GLenum variable, GLenum pname, GLint * params); /* 640 */
-   void (GLAPIENTRYP ResizeBuffersMESA)(void); /* 641 */
-   void (GLAPIENTRYP WindowPos2dMESA)(GLdouble x, GLdouble y); /* 642 */
-   void (GLAPIENTRYP WindowPos2dvMESA)(const GLdouble * v); /* 643 */
-   void (GLAPIENTRYP WindowPos2fMESA)(GLfloat x, GLfloat y); /* 644 */
-   void (GLAPIENTRYP WindowPos2fvMESA)(const GLfloat * v); /* 645 */
-   void (GLAPIENTRYP WindowPos2iMESA)(GLint x, GLint y); /* 646 */
-   void (GLAPIENTRYP WindowPos2ivMESA)(const GLint * v); /* 647 */
-   void (GLAPIENTRYP WindowPos2sMESA)(GLshort x, GLshort y); /* 648 */
-   void (GLAPIENTRYP WindowPos2svMESA)(const GLshort * v); /* 649 */
-   void (GLAPIENTRYP WindowPos3dMESA)(GLdouble x, GLdouble y, GLdouble z); /* 650 */
-   void (GLAPIENTRYP WindowPos3dvMESA)(const GLdouble * v); /* 651 */
-   void (GLAPIENTRYP WindowPos3fMESA)(GLfloat x, GLfloat y, GLfloat z); /* 652 */
-   void (GLAPIENTRYP WindowPos3fvMESA)(const GLfloat * v); /* 653 */
-   void (GLAPIENTRYP WindowPos3iMESA)(GLint x, GLint y, GLint z); /* 654 */
-   void (GLAPIENTRYP WindowPos3ivMESA)(const GLint * v); /* 655 */
-   void (GLAPIENTRYP WindowPos3sMESA)(GLshort x, GLshort y, GLshort z); /* 656 */
-   void (GLAPIENTRYP WindowPos3svMESA)(const GLshort * v); /* 657 */
-   void (GLAPIENTRYP WindowPos4dMESA)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); /* 658 */
-   void (GLAPIENTRYP WindowPos4dvMESA)(const GLdouble * v); /* 659 */
-   void (GLAPIENTRYP WindowPos4fMESA)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); /* 660 */
-   void (GLAPIENTRYP WindowPos4fvMESA)(const GLfloat * v); /* 661 */
-   void (GLAPIENTRYP WindowPos4iMESA)(GLint x, GLint y, GLint z, GLint w); /* 662 */
-   void (GLAPIENTRYP WindowPos4ivMESA)(const GLint * v); /* 663 */
-   void (GLAPIENTRYP WindowPos4sMESA)(GLshort x, GLshort y, GLshort z, GLshort w); /* 664 */
-   void (GLAPIENTRYP WindowPos4svMESA)(const GLshort * v); /* 665 */
-   void (GLAPIENTRYP MultiModeDrawArraysIBM)(const GLenum * mode, const GLint * first, const GLsizei * count, GLsizei primcount, GLint modestride); /* 666 */
-   void (GLAPIENTRYP MultiModeDrawElementsIBM)(const GLenum * mode, const GLsizei * count, GLenum type, const GLvoid * const * indices, GLsizei primcount, GLint modestride); /* 667 */
-   void (GLAPIENTRYP DeleteFencesNV)(GLsizei n, const GLuint * fences); /* 668 */
-   void (GLAPIENTRYP FinishFenceNV)(GLuint fence); /* 669 */
-   void (GLAPIENTRYP GenFencesNV)(GLsizei n, GLuint * fences); /* 670 */
-   void (GLAPIENTRYP GetFenceivNV)(GLuint fence, GLenum pname, GLint * params); /* 671 */
-   GLboolean (GLAPIENTRYP IsFenceNV)(GLuint fence); /* 672 */
-   void (GLAPIENTRYP SetFenceNV)(GLuint fence, GLenum condition); /* 673 */
-   GLboolean (GLAPIENTRYP TestFenceNV)(GLuint fence); /* 674 */
-   GLboolean (GLAPIENTRYP AreProgramsResidentNV)(GLsizei n, const GLuint * ids, GLboolean * residences); /* 675 */
-   void (GLAPIENTRYP BindProgramNV)(GLenum target, GLuint program); /* 676 */
-   void (GLAPIENTRYP DeleteProgramsNV)(GLsizei n, const GLuint * programs); /* 677 */
-   void (GLAPIENTRYP ExecuteProgramNV)(GLenum target, GLuint id, const GLfloat * params); /* 678 */
-   void (GLAPIENTRYP GenProgramsNV)(GLsizei n, GLuint * programs); /* 679 */
-   void (GLAPIENTRYP GetProgramParameterdvNV)(GLenum target, GLuint index, GLenum pname, GLdouble * params); /* 680 */
-   void (GLAPIENTRYP GetProgramParameterfvNV)(GLenum target, GLuint index, GLenum pname, GLfloat * params); /* 681 */
-   void (GLAPIENTRYP GetProgramStringNV)(GLuint id, GLenum pname, GLubyte * program); /* 682 */
-   void (GLAPIENTRYP GetProgramivNV)(GLuint id, GLenum pname, GLint * params); /* 683 */
-   void (GLAPIENTRYP GetTrackMatrixivNV)(GLenum target, GLuint address, GLenum pname, GLint * params); /* 684 */
-   void (GLAPIENTRYP GetVertexAttribPointervNV)(GLuint index, GLenum pname, GLvoid ** pointer); /* 685 */
-   void (GLAPIENTRYP GetVertexAttribdvNV)(GLuint index, GLenum pname, GLdouble * params); /* 686 */
-   void (GLAPIENTRYP GetVertexAttribfvNV)(GLuint index, GLenum pname, GLfloat * params); /* 687 */
-   void (GLAPIENTRYP GetVertexAttribivNV)(GLuint index, GLenum pname, GLint * params); /* 688 */
-   GLboolean (GLAPIENTRYP IsProgramNV)(GLuint program); /* 689 */
-   void (GLAPIENTRYP LoadProgramNV)(GLenum target, GLuint id, GLsizei len, const GLubyte * program); /* 690 */
-   void (GLAPIENTRYP ProgramParameters4dvNV)(GLenum target, GLuint index, GLuint num, const GLdouble * params); /* 691 */
-   void (GLAPIENTRYP ProgramParameters4fvNV)(GLenum target, GLuint index, GLuint num, const GLfloat * params); /* 692 */
-   void (GLAPIENTRYP RequestResidentProgramsNV)(GLsizei n, const GLuint * ids); /* 693 */
-   void (GLAPIENTRYP TrackMatrixNV)(GLenum target, GLuint address, GLenum matrix, GLenum transform); /* 694 */
-   void (GLAPIENTRYP VertexAttrib1dNV)(GLuint index, GLdouble x); /* 695 */
-   void (GLAPIENTRYP VertexAttrib1dvNV)(GLuint index, const GLdouble * v); /* 696 */
-   void (GLAPIENTRYP VertexAttrib1fNV)(GLuint index, GLfloat x); /* 697 */
-   void (GLAPIENTRYP VertexAttrib1fvNV)(GLuint index, const GLfloat * v); /* 698 */
-   void (GLAPIENTRYP VertexAttrib1sNV)(GLuint index, GLshort x); /* 699 */
-   void (GLAPIENTRYP VertexAttrib1svNV)(GLuint index, const GLshort * v); /* 700 */
-   void (GLAPIENTRYP VertexAttrib2dNV)(GLuint index, GLdouble x, GLdouble y); /* 701 */
-   void (GLAPIENTRYP VertexAttrib2dvNV)(GLuint index, const GLdouble * v); /* 702 */
-   void (GLAPIENTRYP VertexAttrib2fNV)(GLuint index, GLfloat x, GLfloat y); /* 703 */
-   void (GLAPIENTRYP VertexAttrib2fvNV)(GLuint index, const GLfloat * v); /* 704 */
-   void (GLAPIENTRYP VertexAttrib2sNV)(GLuint index, GLshort x, GLshort y); /* 705 */
-   void (GLAPIENTRYP VertexAttrib2svNV)(GLuint index, const GLshort * v); /* 706 */
-   void (GLAPIENTRYP VertexAttrib3dNV)(GLuint index, GLdouble x, GLdouble y, GLdouble z); /* 707 */
-   void (GLAPIENTRYP VertexAttrib3dvNV)(GLuint index, const GLdouble * v); /* 708 */
-   void (GLAPIENTRYP VertexAttrib3fNV)(GLuint index, GLfloat x, GLfloat y, GLfloat z); /* 709 */
-   void (GLAPIENTRYP VertexAttrib3fvNV)(GLuint index, const GLfloat * v); /* 710 */
-   void (GLAPIENTRYP VertexAttrib3sNV)(GLuint index, GLshort x, GLshort y, GLshort z); /* 711 */
-   void (GLAPIENTRYP VertexAttrib3svNV)(GLuint index, const GLshort * v); /* 712 */
-   void (GLAPIENTRYP VertexAttrib4dNV)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); /* 713 */
-   void (GLAPIENTRYP VertexAttrib4dvNV)(GLuint index, const GLdouble * v); /* 714 */
-   void (GLAPIENTRYP VertexAttrib4fNV)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); /* 715 */
-   void (GLAPIENTRYP VertexAttrib4fvNV)(GLuint index, const GLfloat * v); /* 716 */
-   void (GLAPIENTRYP VertexAttrib4sNV)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); /* 717 */
-   void (GLAPIENTRYP VertexAttrib4svNV)(GLuint index, const GLshort * v); /* 718 */
-   void (GLAPIENTRYP VertexAttrib4ubNV)(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); /* 719 */
-   void (GLAPIENTRYP VertexAttrib4ubvNV)(GLuint index, const GLubyte * v); /* 720 */
-   void (GLAPIENTRYP VertexAttribPointerNV)(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); /* 721 */
-   void (GLAPIENTRYP VertexAttribs1dvNV)(GLuint index, GLsizei n, const GLdouble * v); /* 722 */
-   void (GLAPIENTRYP VertexAttribs1fvNV)(GLuint index, GLsizei n, const GLfloat * v); /* 723 */
-   void (GLAPIENTRYP VertexAttribs1svNV)(GLuint index, GLsizei n, const GLshort * v); /* 724 */
-   void (GLAPIENTRYP VertexAttribs2dvNV)(GLuint index, GLsizei n, const GLdouble * v); /* 725 */
-   void (GLAPIENTRYP VertexAttribs2fvNV)(GLuint index, GLsizei n, const GLfloat * v); /* 726 */
-   void (GLAPIENTRYP VertexAttribs2svNV)(GLuint index, GLsizei n, const GLshort * v); /* 727 */
-   void (GLAPIENTRYP VertexAttribs3dvNV)(GLuint index, GLsizei n, const GLdouble * v); /* 728 */
-   void (GLAPIENTRYP VertexAttribs3fvNV)(GLuint index, GLsizei n, const GLfloat * v); /* 729 */
-   void (GLAPIENTRYP VertexAttribs3svNV)(GLuint index, GLsizei n, const GLshort * v); /* 730 */
-   void (GLAPIENTRYP VertexAttribs4dvNV)(GLuint index, GLsizei n, const GLdouble * v); /* 731 */
-   void (GLAPIENTRYP VertexAttribs4fvNV)(GLuint index, GLsizei n, const GLfloat * v); /* 732 */
-   void (GLAPIENTRYP VertexAttribs4svNV)(GLuint index, GLsizei n, const GLshort * v); /* 733 */
-   void (GLAPIENTRYP VertexAttribs4ubvNV)(GLuint index, GLsizei n, const GLubyte * v); /* 734 */
-   void (GLAPIENTRYP GetTexBumpParameterfvATI)(GLenum pname, GLfloat * param); /* 735 */
-   void (GLAPIENTRYP GetTexBumpParameterivATI)(GLenum pname, GLint * param); /* 736 */
-   void (GLAPIENTRYP TexBumpParameterfvATI)(GLenum pname, const GLfloat * param); /* 737 */
-   void (GLAPIENTRYP TexBumpParameterivATI)(GLenum pname, const GLint * param); /* 738 */
-   void (GLAPIENTRYP AlphaFragmentOp1ATI)(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); /* 739 */
-   void (GLAPIENTRYP AlphaFragmentOp2ATI)(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); /* 740 */
-   void (GLAPIENTRYP AlphaFragmentOp3ATI)(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); /* 741 */
-   void (GLAPIENTRYP BeginFragmentShaderATI)(void); /* 742 */
-   void (GLAPIENTRYP BindFragmentShaderATI)(GLuint id); /* 743 */
-   void (GLAPIENTRYP ColorFragmentOp1ATI)(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); /* 744 */
-   void (GLAPIENTRYP ColorFragmentOp2ATI)(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); /* 745 */
-   void (GLAPIENTRYP ColorFragmentOp3ATI)(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); /* 746 */
-   void (GLAPIENTRYP DeleteFragmentShaderATI)(GLuint id); /* 747 */
-   void (GLAPIENTRYP EndFragmentShaderATI)(void); /* 748 */
-   GLuint (GLAPIENTRYP GenFragmentShadersATI)(GLuint range); /* 749 */
-   void (GLAPIENTRYP PassTexCoordATI)(GLuint dst, GLuint coord, GLenum swizzle); /* 750 */
-   void (GLAPIENTRYP SampleMapATI)(GLuint dst, GLuint interp, GLenum swizzle); /* 751 */
-   void (GLAPIENTRYP SetFragmentShaderConstantATI)(GLuint dst, const GLfloat * value); /* 752 */
-   void (GLAPIENTRYP PointParameteriNV)(GLenum pname, GLint param); /* 753 */
-   void (GLAPIENTRYP PointParameterivNV)(GLenum pname, const GLint * params); /* 754 */
-   void (GLAPIENTRYP ActiveStencilFaceEXT)(GLenum face); /* 755 */
-   void (GLAPIENTRYP BindVertexArrayAPPLE)(GLuint array); /* 756 */
-   void (GLAPIENTRYP DeleteVertexArraysAPPLE)(GLsizei n, const GLuint * arrays); /* 757 */
-   void (GLAPIENTRYP GenVertexArraysAPPLE)(GLsizei n, GLuint * arrays); /* 758 */
-   GLboolean (GLAPIENTRYP IsVertexArrayAPPLE)(GLuint array); /* 759 */
-   void (GLAPIENTRYP GetProgramNamedParameterdvNV)(GLuint id, GLsizei len, const GLubyte * name, GLdouble * params); /* 760 */
-   void (GLAPIENTRYP GetProgramNamedParameterfvNV)(GLuint id, GLsizei len, const GLubyte * name, GLfloat * params); /* 761 */
-   void (GLAPIENTRYP ProgramNamedParameter4dNV)(GLuint id, GLsizei len, const GLubyte * name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); /* 762 */
-   void (GLAPIENTRYP ProgramNamedParameter4dvNV)(GLuint id, GLsizei len, const GLubyte * name, const GLdouble * v); /* 763 */
-   void (GLAPIENTRYP ProgramNamedParameter4fNV)(GLuint id, GLsizei len, const GLubyte * name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); /* 764 */
-   void (GLAPIENTRYP ProgramNamedParameter4fvNV)(GLuint id, GLsizei len, const GLubyte * name, const GLfloat * v); /* 765 */
-   void (GLAPIENTRYP DepthBoundsEXT)(GLclampd zmin, GLclampd zmax); /* 766 */
-   void (GLAPIENTRYP BlendEquationSeparateEXT)(GLenum modeRGB, GLenum modeA); /* 767 */
-   void (GLAPIENTRYP BindFramebufferEXT)(GLenum target, GLuint framebuffer); /* 768 */
-   void (GLAPIENTRYP BindRenderbufferEXT)(GLenum target, GLuint renderbuffer); /* 769 */
-   GLenum (GLAPIENTRYP CheckFramebufferStatusEXT)(GLenum target); /* 770 */
-   void (GLAPIENTRYP DeleteFramebuffersEXT)(GLsizei n, const GLuint * framebuffers); /* 771 */
-   void (GLAPIENTRYP DeleteRenderbuffersEXT)(GLsizei n, const GLuint * renderbuffers); /* 772 */
-   void (GLAPIENTRYP FramebufferRenderbufferEXT)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); /* 773 */
-   void (GLAPIENTRYP FramebufferTexture1DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); /* 774 */
-   void (GLAPIENTRYP FramebufferTexture2DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); /* 775 */
-   void (GLAPIENTRYP FramebufferTexture3DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); /* 776 */
-   void (GLAPIENTRYP GenFramebuffersEXT)(GLsizei n, GLuint * framebuffers); /* 777 */
-   void (GLAPIENTRYP GenRenderbuffersEXT)(GLsizei n, GLuint * renderbuffers); /* 778 */
-   void (GLAPIENTRYP GenerateMipmapEXT)(GLenum target); /* 779 */
-   void (GLAPIENTRYP GetFramebufferAttachmentParameterivEXT)(GLenum target, GLenum attachment, GLenum pname, GLint * params); /* 780 */
-   void (GLAPIENTRYP GetRenderbufferParameterivEXT)(GLenum target, GLenum pname, GLint * params); /* 781 */
-   GLboolean (GLAPIENTRYP IsFramebufferEXT)(GLuint framebuffer); /* 782 */
-   GLboolean (GLAPIENTRYP IsRenderbufferEXT)(GLuint renderbuffer); /* 783 */
-   void (GLAPIENTRYP RenderbufferStorageEXT)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); /* 784 */
-   void (GLAPIENTRYP BlitFramebufferEXT)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); /* 785 */
-   void (GLAPIENTRYP BufferParameteriAPPLE)(GLenum target, GLenum pname, GLint param); /* 786 */
-   void (GLAPIENTRYP FlushMappedBufferRangeAPPLE)(GLenum target, GLintptr offset, GLsizeiptr size); /* 787 */
-   void (GLAPIENTRYP FramebufferTextureLayerEXT)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); /* 788 */
-   void (GLAPIENTRYP ColorMaskIndexedEXT)(GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a); /* 789 */
-   void (GLAPIENTRYP DisableIndexedEXT)(GLenum target, GLuint index); /* 790 */
-   void (GLAPIENTRYP EnableIndexedEXT)(GLenum target, GLuint index); /* 791 */
-   void (GLAPIENTRYP GetBooleanIndexedvEXT)(GLenum value, GLuint index, GLboolean * data); /* 792 */
-   void (GLAPIENTRYP GetIntegerIndexedvEXT)(GLenum value, GLuint index, GLint * data); /* 793 */
-   GLboolean (GLAPIENTRYP IsEnabledIndexedEXT)(GLenum target, GLuint index); /* 794 */
-   void (GLAPIENTRYP BeginConditionalRenderNV)(GLuint query, GLenum mode); /* 795 */
-   void (GLAPIENTRYP EndConditionalRenderNV)(void); /* 796 */
-   void (GLAPIENTRYP BeginTransformFeedbackEXT)(GLenum mode); /* 797 */
-   void (GLAPIENTRYP BindBufferBaseEXT)(GLenum target, GLuint index, GLuint buffer); /* 798 */
-   void (GLAPIENTRYP BindBufferOffsetEXT)(GLenum target, GLuint index, GLuint buffer, GLintptr offset); /* 799 */
-   void (GLAPIENTRYP BindBufferRangeEXT)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); /* 800 */
-   void (GLAPIENTRYP EndTransformFeedbackEXT)(void); /* 801 */
-   void (GLAPIENTRYP GetTransformFeedbackVaryingEXT)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name); /* 802 */
-   void (GLAPIENTRYP TransformFeedbackVaryingsEXT)(GLuint program, GLsizei count, const char ** varyings, GLenum bufferMode); /* 803 */
-   void (GLAPIENTRYP ProvokingVertexEXT)(GLenum mode); /* 804 */
-   void (GLAPIENTRYP GetTexParameterPointervAPPLE)(GLenum target, GLenum pname, GLvoid ** params); /* 805 */
-   void (GLAPIENTRYP TextureRangeAPPLE)(GLenum target, GLsizei length, GLvoid * pointer); /* 806 */
-   void (GLAPIENTRYP GetObjectParameterivAPPLE)(GLenum objectType, GLuint name, GLenum pname, GLint * value); /* 807 */
-   GLenum (GLAPIENTRYP ObjectPurgeableAPPLE)(GLenum objectType, GLuint name, GLenum option); /* 808 */
-   GLenum (GLAPIENTRYP ObjectUnpurgeableAPPLE)(GLenum objectType, GLuint name, GLenum option); /* 809 */
-   void (GLAPIENTRYP StencilFuncSeparateATI)(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); /* 810 */
-   void (GLAPIENTRYP ProgramEnvParameters4fvEXT)(GLenum target, GLuint index, GLsizei count, const GLfloat * params); /* 811 */
-   void (GLAPIENTRYP ProgramLocalParameters4fvEXT)(GLenum target, GLuint index, GLsizei count, const GLfloat * params); /* 812 */
-   void (GLAPIENTRYP GetQueryObjecti64vEXT)(GLuint id, GLenum pname, GLint64EXT * params); /* 813 */
-   void (GLAPIENTRYP GetQueryObjectui64vEXT)(GLuint id, GLenum pname, GLuint64EXT * params); /* 814 */
-   void (GLAPIENTRYP EGLImageTargetRenderbufferStorageOES)(GLenum target, GLvoid * writeOffset); /* 815 */
-   void (GLAPIENTRYP EGLImageTargetTexture2DOES)(GLenum target, GLvoid * writeOffset); /* 816 */
+   void (GLAPIENTRYP FramebufferTextureARB)(GLenum target, GLenum attachment, GLuint texture, GLint level); /* 564 */
+   void (GLAPIENTRYP FramebufferTextureFaceARB)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); /* 565 */
+   void (GLAPIENTRYP ProgramParameteriARB)(GLuint program, GLenum pname, GLint value); /* 566 */
+   void (GLAPIENTRYP FlushMappedBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length); /* 567 */
+   GLvoid * (GLAPIENTRYP MapBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); /* 568 */
+   void (GLAPIENTRYP BindVertexArray)(GLuint array); /* 569 */
+   void (GLAPIENTRYP GenVertexArrays)(GLsizei n, GLuint * arrays); /* 570 */
+   void (GLAPIENTRYP CopyBufferSubData)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); /* 571 */
+   GLenum (GLAPIENTRYP ClientWaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout); /* 572 */
+   void (GLAPIENTRYP DeleteSync)(GLsync sync); /* 573 */
+   GLsync (GLAPIENTRYP FenceSync)(GLenum condition, GLbitfield flags); /* 574 */
+   void (GLAPIENTRYP GetInteger64v)(GLenum pname, GLint64 * params); /* 575 */
+   void (GLAPIENTRYP GetSynciv)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei * length, GLint * values); /* 576 */
+   GLboolean (GLAPIENTRYP IsSync)(GLsync sync); /* 577 */
+   void (GLAPIENTRYP WaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout); /* 578 */
+   void (GLAPIENTRYP DrawElementsBaseVertex)(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices, GLint basevertex); /* 579 */
+   void (GLAPIENTRYP DrawRangeElementsBaseVertex)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid * indices, GLint basevertex); /* 580 */
+   void (GLAPIENTRYP MultiDrawElementsBaseVertex)(GLenum mode, const GLsizei * count, GLenum type, const GLvoid ** indices, GLsizei primcount, const GLint * basevertex); /* 581 */
+   void (GLAPIENTRYP BindTransformFeedback)(GLenum target, GLuint id); /* 582 */
+   void (GLAPIENTRYP DeleteTransformFeedbacks)(GLsizei n, const GLuint * ids); /* 583 */
+   void (GLAPIENTRYP DrawTransformFeedback)(GLenum mode, GLuint id); /* 584 */
+   void (GLAPIENTRYP GenTransformFeedbacks)(GLsizei n, GLuint * ids); /* 585 */
+   GLboolean (GLAPIENTRYP IsTransformFeedback)(GLuint id); /* 586 */
+   void (GLAPIENTRYP PauseTransformFeedback)(void); /* 587 */
+   void (GLAPIENTRYP ResumeTransformFeedback)(void); /* 588 */
+   void (GLAPIENTRYP PolygonOffsetEXT)(GLfloat factor, GLfloat bias); /* 589 */
+   void (GLAPIENTRYP GetPixelTexGenParameterfvSGIS)(GLenum pname, GLfloat * params); /* 590 */
+   void (GLAPIENTRYP GetPixelTexGenParameterivSGIS)(GLenum pname, GLint * params); /* 591 */
+   void (GLAPIENTRYP PixelTexGenParameterfSGIS)(GLenum pname, GLfloat param); /* 592 */
+   void (GLAPIENTRYP PixelTexGenParameterfvSGIS)(GLenum pname, const GLfloat * params); /* 593 */
+   void (GLAPIENTRYP PixelTexGenParameteriSGIS)(GLenum pname, GLint param); /* 594 */
+   void (GLAPIENTRYP PixelTexGenParameterivSGIS)(GLenum pname, const GLint * params); /* 595 */
+   void (GLAPIENTRYP SampleMaskSGIS)(GLclampf value, GLboolean invert); /* 596 */
+   void (GLAPIENTRYP SamplePatternSGIS)(GLenum pattern); /* 597 */
+   void (GLAPIENTRYP ColorPointerEXT)(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 598 */
+   void (GLAPIENTRYP EdgeFlagPointerEXT)(GLsizei stride, GLsizei count, const GLboolean * pointer); /* 599 */
+   void (GLAPIENTRYP IndexPointerEXT)(GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 600 */
+   void (GLAPIENTRYP NormalPointerEXT)(GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 601 */
+   void (GLAPIENTRYP TexCoordPointerEXT)(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 602 */
+   void (GLAPIENTRYP VertexPointerEXT)(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 603 */
+   void (GLAPIENTRYP PointParameterfEXT)(GLenum pname, GLfloat param); /* 604 */
+   void (GLAPIENTRYP PointParameterfvEXT)(GLenum pname, const GLfloat * params); /* 605 */
+   void (GLAPIENTRYP LockArraysEXT)(GLint first, GLsizei count); /* 606 */
+   void (GLAPIENTRYP UnlockArraysEXT)(void); /* 607 */
+   void (GLAPIENTRYP CullParameterdvEXT)(GLenum pname, GLdouble * params); /* 608 */
+   void (GLAPIENTRYP CullParameterfvEXT)(GLenum pname, GLfloat * params); /* 609 */
+   void (GLAPIENTRYP SecondaryColor3bEXT)(GLbyte red, GLbyte green, GLbyte blue); /* 610 */
+   void (GLAPIENTRYP SecondaryColor3bvEXT)(const GLbyte * v); /* 611 */
+   void (GLAPIENTRYP SecondaryColor3dEXT)(GLdouble red, GLdouble green, GLdouble blue); /* 612 */
+   void (GLAPIENTRYP SecondaryColor3dvEXT)(const GLdouble * v); /* 613 */
+   void (GLAPIENTRYP SecondaryColor3fEXT)(GLfloat red, GLfloat green, GLfloat blue); /* 614 */
+   void (GLAPIENTRYP SecondaryColor3fvEXT)(const GLfloat * v); /* 615 */
+   void (GLAPIENTRYP SecondaryColor3iEXT)(GLint red, GLint green, GLint blue); /* 616 */
+   void (GLAPIENTRYP SecondaryColor3ivEXT)(const GLint * v); /* 617 */
+   void (GLAPIENTRYP SecondaryColor3sEXT)(GLshort red, GLshort green, GLshort blue); /* 618 */
+   void (GLAPIENTRYP SecondaryColor3svEXT)(const GLshort * v); /* 619 */
+   void (GLAPIENTRYP SecondaryColor3ubEXT)(GLubyte red, GLubyte green, GLubyte blue); /* 620 */
+   void (GLAPIENTRYP SecondaryColor3ubvEXT)(const GLubyte * v); /* 621 */
+   void (GLAPIENTRYP SecondaryColor3uiEXT)(GLuint red, GLuint green, GLuint blue); /* 622 */
+   void (GLAPIENTRYP SecondaryColor3uivEXT)(const GLuint * v); /* 623 */
+   void (GLAPIENTRYP SecondaryColor3usEXT)(GLushort red, GLushort green, GLushort blue); /* 624 */
+   void (GLAPIENTRYP SecondaryColor3usvEXT)(const GLushort * v); /* 625 */
+   void (GLAPIENTRYP SecondaryColorPointerEXT)(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); /* 626 */
+   void (GLAPIENTRYP MultiDrawArraysEXT)(GLenum mode, GLint * first, GLsizei * count, GLsizei primcount); /* 627 */
+   void (GLAPIENTRYP MultiDrawElementsEXT)(GLenum mode, const GLsizei * count, GLenum type, const GLvoid ** indices, GLsizei primcount); /* 628 */
+   void (GLAPIENTRYP FogCoordPointerEXT)(GLenum type, GLsizei stride, const GLvoid * pointer); /* 629 */
+   void (GLAPIENTRYP FogCoorddEXT)(GLdouble coord); /* 630 */
+   void (GLAPIENTRYP FogCoorddvEXT)(const GLdouble * coord); /* 631 */
+   void (GLAPIENTRYP FogCoordfEXT)(GLfloat coord); /* 632 */
+   void (GLAPIENTRYP FogCoordfvEXT)(const GLfloat * coord); /* 633 */
+   void (GLAPIENTRYP PixelTexGenSGIX)(GLenum mode); /* 634 */
+   void (GLAPIENTRYP BlendFuncSeparateEXT)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); /* 635 */
+   void (GLAPIENTRYP FlushVertexArrayRangeNV)(void); /* 636 */
+   void (GLAPIENTRYP VertexArrayRangeNV)(GLsizei length, const GLvoid * pointer); /* 637 */
+   void (GLAPIENTRYP CombinerInputNV)(GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); /* 638 */
+   void (GLAPIENTRYP CombinerOutputNV)(GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); /* 639 */
+   void (GLAPIENTRYP CombinerParameterfNV)(GLenum pname, GLfloat param); /* 640 */
+   void (GLAPIENTRYP CombinerParameterfvNV)(GLenum pname, const GLfloat * params); /* 641 */
+   void (GLAPIENTRYP CombinerParameteriNV)(GLenum pname, GLint param); /* 642 */
+   void (GLAPIENTRYP CombinerParameterivNV)(GLenum pname, const GLint * params); /* 643 */
+   void (GLAPIENTRYP FinalCombinerInputNV)(GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); /* 644 */
+   void (GLAPIENTRYP GetCombinerInputParameterfvNV)(GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat * params); /* 645 */
+   void (GLAPIENTRYP GetCombinerInputParameterivNV)(GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint * params); /* 646 */
+   void (GLAPIENTRYP GetCombinerOutputParameterfvNV)(GLenum stage, GLenum portion, GLenum pname, GLfloat * params); /* 647 */
+   void (GLAPIENTRYP GetCombinerOutputParameterivNV)(GLenum stage, GLenum portion, GLenum pname, GLint * params); /* 648 */
+   void (GLAPIENTRYP GetFinalCombinerInputParameterfvNV)(GLenum variable, GLenum pname, GLfloat * params); /* 649 */
+   void (GLAPIENTRYP GetFinalCombinerInputParameterivNV)(GLenum variable, GLenum pname, GLint * params); /* 650 */
+   void (GLAPIENTRYP ResizeBuffersMESA)(void); /* 651 */
+   void (GLAPIENTRYP WindowPos2dMESA)(GLdouble x, GLdouble y); /* 652 */
+   void (GLAPIENTRYP WindowPos2dvMESA)(const GLdouble * v); /* 653 */
+   void (GLAPIENTRYP WindowPos2fMESA)(GLfloat x, GLfloat y); /* 654 */
+   void (GLAPIENTRYP WindowPos2fvMESA)(const GLfloat * v); /* 655 */
+   void (GLAPIENTRYP WindowPos2iMESA)(GLint x, GLint y); /* 656 */
+   void (GLAPIENTRYP WindowPos2ivMESA)(const GLint * v); /* 657 */
+   void (GLAPIENTRYP WindowPos2sMESA)(GLshort x, GLshort y); /* 658 */
+   void (GLAPIENTRYP WindowPos2svMESA)(const GLshort * v); /* 659 */
+   void (GLAPIENTRYP WindowPos3dMESA)(GLdouble x, GLdouble y, GLdouble z); /* 660 */
+   void (GLAPIENTRYP WindowPos3dvMESA)(const GLdouble * v); /* 661 */
+   void (GLAPIENTRYP WindowPos3fMESA)(GLfloat x, GLfloat y, GLfloat z); /* 662 */
+   void (GLAPIENTRYP WindowPos3fvMESA)(const GLfloat * v); /* 663 */
+   void (GLAPIENTRYP WindowPos3iMESA)(GLint x, GLint y, GLint z); /* 664 */
+   void (GLAPIENTRYP WindowPos3ivMESA)(const GLint * v); /* 665 */
+   void (GLAPIENTRYP WindowPos3sMESA)(GLshort x, GLshort y, GLshort z); /* 666 */
+   void (GLAPIENTRYP WindowPos3svMESA)(const GLshort * v); /* 667 */
+   void (GLAPIENTRYP WindowPos4dMESA)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); /* 668 */
+   void (GLAPIENTRYP WindowPos4dvMESA)(const GLdouble * v); /* 669 */
+   void (GLAPIENTRYP WindowPos4fMESA)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); /* 670 */
+   void (GLAPIENTRYP WindowPos4fvMESA)(const GLfloat * v); /* 671 */
+   void (GLAPIENTRYP WindowPos4iMESA)(GLint x, GLint y, GLint z, GLint w); /* 672 */
+   void (GLAPIENTRYP WindowPos4ivMESA)(const GLint * v); /* 673 */
+   void (GLAPIENTRYP WindowPos4sMESA)(GLshort x, GLshort y, GLshort z, GLshort w); /* 674 */
+   void (GLAPIENTRYP WindowPos4svMESA)(const GLshort * v); /* 675 */
+   void (GLAPIENTRYP MultiModeDrawArraysIBM)(const GLenum * mode, const GLint * first, const GLsizei * count, GLsizei primcount, GLint modestride); /* 676 */
+   void (GLAPIENTRYP MultiModeDrawElementsIBM)(const GLenum * mode, const GLsizei * count, GLenum type, const GLvoid * const * indices, GLsizei primcount, GLint modestride); /* 677 */
+   void (GLAPIENTRYP DeleteFencesNV)(GLsizei n, const GLuint * fences); /* 678 */
+   void (GLAPIENTRYP FinishFenceNV)(GLuint fence); /* 679 */
+   void (GLAPIENTRYP GenFencesNV)(GLsizei n, GLuint * fences); /* 680 */
+   void (GLAPIENTRYP GetFenceivNV)(GLuint fence, GLenum pname, GLint * params); /* 681 */
+   GLboolean (GLAPIENTRYP IsFenceNV)(GLuint fence); /* 682 */
+   void (GLAPIENTRYP SetFenceNV)(GLuint fence, GLenum condition); /* 683 */
+   GLboolean (GLAPIENTRYP TestFenceNV)(GLuint fence); /* 684 */
+   GLboolean (GLAPIENTRYP AreProgramsResidentNV)(GLsizei n, const GLuint * ids, GLboolean * residences); /* 685 */
+   void (GLAPIENTRYP BindProgramNV)(GLenum target, GLuint program); /* 686 */
+   void (GLAPIENTRYP DeleteProgramsNV)(GLsizei n, const GLuint * programs); /* 687 */
+   void (GLAPIENTRYP ExecuteProgramNV)(GLenum target, GLuint id, const GLfloat * params); /* 688 */
+   void (GLAPIENTRYP GenProgramsNV)(GLsizei n, GLuint * programs); /* 689 */
+   void (GLAPIENTRYP GetProgramParameterdvNV)(GLenum target, GLuint index, GLenum pname, GLdouble * params); /* 690 */
+   void (GLAPIENTRYP GetProgramParameterfvNV)(GLenum target, GLuint index, GLenum pname, GLfloat * params); /* 691 */
+   void (GLAPIENTRYP GetProgramStringNV)(GLuint id, GLenum pname, GLubyte * program); /* 692 */
+   void (GLAPIENTRYP GetProgramivNV)(GLuint id, GLenum pname, GLint * params); /* 693 */
+   void (GLAPIENTRYP GetTrackMatrixivNV)(GLenum target, GLuint address, GLenum pname, GLint * params); /* 694 */
+   void (GLAPIENTRYP GetVertexAttribPointervNV)(GLuint index, GLenum pname, GLvoid ** pointer); /* 695 */
+   void (GLAPIENTRYP GetVertexAttribdvNV)(GLuint index, GLenum pname, GLdouble * params); /* 696 */
+   void (GLAPIENTRYP GetVertexAttribfvNV)(GLuint index, GLenum pname, GLfloat * params); /* 697 */
+   void (GLAPIENTRYP GetVertexAttribivNV)(GLuint index, GLenum pname, GLint * params); /* 698 */
+   GLboolean (GLAPIENTRYP IsProgramNV)(GLuint program); /* 699 */
+   void (GLAPIENTRYP LoadProgramNV)(GLenum target, GLuint id, GLsizei len, const GLubyte * program); /* 700 */
+   void (GLAPIENTRYP ProgramParameters4dvNV)(GLenum target, GLuint index, GLuint num, const GLdouble * params); /* 701 */
+   void (GLAPIENTRYP ProgramParameters4fvNV)(GLenum target, GLuint index, GLuint num, const GLfloat * params); /* 702 */
+   void (GLAPIENTRYP RequestResidentProgramsNV)(GLsizei n, const GLuint * ids); /* 703 */
+   void (GLAPIENTRYP TrackMatrixNV)(GLenum target, GLuint address, GLenum matrix, GLenum transform); /* 704 */
+   void (GLAPIENTRYP VertexAttrib1dNV)(GLuint index, GLdouble x); /* 705 */
+   void (GLAPIENTRYP VertexAttrib1dvNV)(GLuint index, const GLdouble * v); /* 706 */
+   void (GLAPIENTRYP VertexAttrib1fNV)(GLuint index, GLfloat x); /* 707 */
+   void (GLAPIENTRYP VertexAttrib1fvNV)(GLuint index, const GLfloat * v); /* 708 */
+   void (GLAPIENTRYP VertexAttrib1sNV)(GLuint index, GLshort x); /* 709 */
+   void (GLAPIENTRYP VertexAttrib1svNV)(GLuint index, const GLshort * v); /* 710 */
+   void (GLAPIENTRYP VertexAttrib2dNV)(GLuint index, GLdouble x, GLdouble y); /* 711 */
+   void (GLAPIENTRYP VertexAttrib2dvNV)(GLuint index, const GLdouble * v); /* 712 */
+   void (GLAPIENTRYP VertexAttrib2fNV)(GLuint index, GLfloat x, GLfloat y); /* 713 */
+   void (GLAPIENTRYP VertexAttrib2fvNV)(GLuint index, const GLfloat * v); /* 714 */
+   void (GLAPIENTRYP VertexAttrib2sNV)(GLuint index, GLshort x, GLshort y); /* 715 */
+   void (GLAPIENTRYP VertexAttrib2svNV)(GLuint index, const GLshort * v); /* 716 */
+   void (GLAPIENTRYP VertexAttrib3dNV)(GLuint index, GLdouble x, GLdouble y, GLdouble z); /* 717 */
+   void (GLAPIENTRYP VertexAttrib3dvNV)(GLuint index, const GLdouble * v); /* 718 */
+   void (GLAPIENTRYP VertexAttrib3fNV)(GLuint index, GLfloat x, GLfloat y, GLfloat z); /* 719 */
+   void (GLAPIENTRYP VertexAttrib3fvNV)(GLuint index, const GLfloat * v); /* 720 */
+   void (GLAPIENTRYP VertexAttrib3sNV)(GLuint index, GLshort x, GLshort y, GLshort z); /* 721 */
+   void (GLAPIENTRYP VertexAttrib3svNV)(GLuint index, const GLshort * v); /* 722 */
+   void (GLAPIENTRYP VertexAttrib4dNV)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); /* 723 */
+   void (GLAPIENTRYP VertexAttrib4dvNV)(GLuint index, const GLdouble * v); /* 724 */
+   void (GLAPIENTRYP VertexAttrib4fNV)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); /* 725 */
+   void (GLAPIENTRYP VertexAttrib4fvNV)(GLuint index, const GLfloat * v); /* 726 */
+   void (GLAPIENTRYP VertexAttrib4sNV)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); /* 727 */
+   void (GLAPIENTRYP VertexAttrib4svNV)(GLuint index, const GLshort * v); /* 728 */
+   void (GLAPIENTRYP VertexAttrib4ubNV)(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); /* 729 */
+   void (GLAPIENTRYP VertexAttrib4ubvNV)(GLuint index, const GLubyte * v); /* 730 */
+   void (GLAPIENTRYP VertexAttribPointerNV)(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); /* 731 */
+   void (GLAPIENTRYP VertexAttribs1dvNV)(GLuint index, GLsizei n, const GLdouble * v); /* 732 */
+   void (GLAPIENTRYP VertexAttribs1fvNV)(GLuint index, GLsizei n, const GLfloat * v); /* 733 */
+   void (GLAPIENTRYP VertexAttribs1svNV)(GLuint index, GLsizei n, const GLshort * v); /* 734 */
+   void (GLAPIENTRYP VertexAttribs2dvNV)(GLuint index, GLsizei n, const GLdouble * v); /* 735 */
+   void (GLAPIENTRYP VertexAttribs2fvNV)(GLuint index, GLsizei n, const GLfloat * v); /* 736 */
+   void (GLAPIENTRYP VertexAttribs2svNV)(GLuint index, GLsizei n, const GLshort * v); /* 737 */
+   void (GLAPIENTRYP VertexAttribs3dvNV)(GLuint index, GLsizei n, const GLdouble * v); /* 738 */
+   void (GLAPIENTRYP VertexAttribs3fvNV)(GLuint index, GLsizei n, const GLfloat * v); /* 739 */
+   void (GLAPIENTRYP VertexAttribs3svNV)(GLuint index, GLsizei n, const GLshort * v); /* 740 */
+   void (GLAPIENTRYP VertexAttribs4dvNV)(GLuint index, GLsizei n, const GLdouble * v); /* 741 */
+   void (GLAPIENTRYP VertexAttribs4fvNV)(GLuint index, GLsizei n, const GLfloat * v); /* 742 */
+   void (GLAPIENTRYP VertexAttribs4svNV)(GLuint index, GLsizei n, const GLshort * v); /* 743 */
+   void (GLAPIENTRYP VertexAttribs4ubvNV)(GLuint index, GLsizei n, const GLubyte * v); /* 744 */
+   void (GLAPIENTRYP GetTexBumpParameterfvATI)(GLenum pname, GLfloat * param); /* 745 */
+   void (GLAPIENTRYP GetTexBumpParameterivATI)(GLenum pname, GLint * param); /* 746 */
+   void (GLAPIENTRYP TexBumpParameterfvATI)(GLenum pname, const GLfloat * param); /* 747 */
+   void (GLAPIENTRYP TexBumpParameterivATI)(GLenum pname, const GLint * param); /* 748 */
+   void (GLAPIENTRYP AlphaFragmentOp1ATI)(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); /* 749 */
+   void (GLAPIENTRYP AlphaFragmentOp2ATI)(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); /* 750 */
+   void (GLAPIENTRYP AlphaFragmentOp3ATI)(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); /* 751 */
+   void (GLAPIENTRYP BeginFragmentShaderATI)(void); /* 752 */
+   void (GLAPIENTRYP BindFragmentShaderATI)(GLuint id); /* 753 */
+   void (GLAPIENTRYP ColorFragmentOp1ATI)(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); /* 754 */
+   void (GLAPIENTRYP ColorFragmentOp2ATI)(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); /* 755 */
+   void (GLAPIENTRYP ColorFragmentOp3ATI)(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); /* 756 */
+   void (GLAPIENTRYP DeleteFragmentShaderATI)(GLuint id); /* 757 */
+   void (GLAPIENTRYP EndFragmentShaderATI)(void); /* 758 */
+   GLuint (GLAPIENTRYP GenFragmentShadersATI)(GLuint range); /* 759 */
+   void (GLAPIENTRYP PassTexCoordATI)(GLuint dst, GLuint coord, GLenum swizzle); /* 760 */
+   void (GLAPIENTRYP SampleMapATI)(GLuint dst, GLuint interp, GLenum swizzle); /* 761 */
+   void (GLAPIENTRYP SetFragmentShaderConstantATI)(GLuint dst, const GLfloat * value); /* 762 */
+   void (GLAPIENTRYP PointParameteriNV)(GLenum pname, GLint param); /* 763 */
+   void (GLAPIENTRYP PointParameterivNV)(GLenum pname, const GLint * params); /* 764 */
+   void (GLAPIENTRYP ActiveStencilFaceEXT)(GLenum face); /* 765 */
+   void (GLAPIENTRYP BindVertexArrayAPPLE)(GLuint array); /* 766 */
+   void (GLAPIENTRYP DeleteVertexArraysAPPLE)(GLsizei n, const GLuint * arrays); /* 767 */
+   void (GLAPIENTRYP GenVertexArraysAPPLE)(GLsizei n, GLuint * arrays); /* 768 */
+   GLboolean (GLAPIENTRYP IsVertexArrayAPPLE)(GLuint array); /* 769 */
+   void (GLAPIENTRYP GetProgramNamedParameterdvNV)(GLuint id, GLsizei len, const GLubyte * name, GLdouble * params); /* 770 */
+   void (GLAPIENTRYP GetProgramNamedParameterfvNV)(GLuint id, GLsizei len, const GLubyte * name, GLfloat * params); /* 771 */
+   void (GLAPIENTRYP ProgramNamedParameter4dNV)(GLuint id, GLsizei len, const GLubyte * name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); /* 772 */
+   void (GLAPIENTRYP ProgramNamedParameter4dvNV)(GLuint id, GLsizei len, const GLubyte * name, const GLdouble * v); /* 773 */
+   void (GLAPIENTRYP ProgramNamedParameter4fNV)(GLuint id, GLsizei len, const GLubyte * name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); /* 774 */
+   void (GLAPIENTRYP ProgramNamedParameter4fvNV)(GLuint id, GLsizei len, const GLubyte * name, const GLfloat * v); /* 775 */
+   void (GLAPIENTRYP DepthBoundsEXT)(GLclampd zmin, GLclampd zmax); /* 776 */
+   void (GLAPIENTRYP BlendEquationSeparateEXT)(GLenum modeRGB, GLenum modeA); /* 777 */
+   void (GLAPIENTRYP BindFramebufferEXT)(GLenum target, GLuint framebuffer); /* 778 */
+   void (GLAPIENTRYP BindRenderbufferEXT)(GLenum target, GLuint renderbuffer); /* 779 */
+   GLenum (GLAPIENTRYP CheckFramebufferStatusEXT)(GLenum target); /* 780 */
+   void (GLAPIENTRYP DeleteFramebuffersEXT)(GLsizei n, const GLuint * framebuffers); /* 781 */
+   void (GLAPIENTRYP DeleteRenderbuffersEXT)(GLsizei n, const GLuint * renderbuffers); /* 782 */
+   void (GLAPIENTRYP FramebufferRenderbufferEXT)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); /* 783 */
+   void (GLAPIENTRYP FramebufferTexture1DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); /* 784 */
+   void (GLAPIENTRYP FramebufferTexture2DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); /* 785 */
+   void (GLAPIENTRYP FramebufferTexture3DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); /* 786 */
+   void (GLAPIENTRYP GenFramebuffersEXT)(GLsizei n, GLuint * framebuffers); /* 787 */
+   void (GLAPIENTRYP GenRenderbuffersEXT)(GLsizei n, GLuint * renderbuffers); /* 788 */
+   void (GLAPIENTRYP GenerateMipmapEXT)(GLenum target); /* 789 */
+   void (GLAPIENTRYP GetFramebufferAttachmentParameterivEXT)(GLenum target, GLenum attachment, GLenum pname, GLint * params); /* 790 */
+   void (GLAPIENTRYP GetRenderbufferParameterivEXT)(GLenum target, GLenum pname, GLint * params); /* 791 */
+   GLboolean (GLAPIENTRYP IsFramebufferEXT)(GLuint framebuffer); /* 792 */
+   GLboolean (GLAPIENTRYP IsRenderbufferEXT)(GLuint renderbuffer); /* 793 */
+   void (GLAPIENTRYP RenderbufferStorageEXT)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); /* 794 */
+   void (GLAPIENTRYP BlitFramebufferEXT)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); /* 795 */
+   void (GLAPIENTRYP BufferParameteriAPPLE)(GLenum target, GLenum pname, GLint param); /* 796 */
+   void (GLAPIENTRYP FlushMappedBufferRangeAPPLE)(GLenum target, GLintptr offset, GLsizeiptr size); /* 797 */
+   void (GLAPIENTRYP FramebufferTextureLayerEXT)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); /* 798 */
+   void (GLAPIENTRYP ColorMaskIndexedEXT)(GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a); /* 799 */
+   void (GLAPIENTRYP DisableIndexedEXT)(GLenum target, GLuint index); /* 800 */
+   void (GLAPIENTRYP EnableIndexedEXT)(GLenum target, GLuint index); /* 801 */
+   void (GLAPIENTRYP GetBooleanIndexedvEXT)(GLenum value, GLuint index, GLboolean * data); /* 802 */
+   void (GLAPIENTRYP GetIntegerIndexedvEXT)(GLenum value, GLuint index, GLint * data); /* 803 */
+   GLboolean (GLAPIENTRYP IsEnabledIndexedEXT)(GLenum target, GLuint index); /* 804 */
+   void (GLAPIENTRYP BeginConditionalRenderNV)(GLuint query, GLenum mode); /* 805 */
+   void (GLAPIENTRYP EndConditionalRenderNV)(void); /* 806 */
+   void (GLAPIENTRYP BeginTransformFeedbackEXT)(GLenum mode); /* 807 */
+   void (GLAPIENTRYP BindBufferBaseEXT)(GLenum target, GLuint index, GLuint buffer); /* 808 */
+   void (GLAPIENTRYP BindBufferOffsetEXT)(GLenum target, GLuint index, GLuint buffer, GLintptr offset); /* 809 */
+   void (GLAPIENTRYP BindBufferRangeEXT)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); /* 810 */
+   void (GLAPIENTRYP EndTransformFeedbackEXT)(void); /* 811 */
+   void (GLAPIENTRYP GetTransformFeedbackVaryingEXT)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name); /* 812 */
+   void (GLAPIENTRYP TransformFeedbackVaryingsEXT)(GLuint program, GLsizei count, const char ** varyings, GLenum bufferMode); /* 813 */
+   void (GLAPIENTRYP ProvokingVertexEXT)(GLenum mode); /* 814 */
+   void (GLAPIENTRYP GetTexParameterPointervAPPLE)(GLenum target, GLenum pname, GLvoid ** params); /* 815 */
+   void (GLAPIENTRYP TextureRangeAPPLE)(GLenum target, GLsizei length, GLvoid * pointer); /* 816 */
+   void (GLAPIENTRYP GetObjectParameterivAPPLE)(GLenum objectType, GLuint name, GLenum pname, GLint * value); /* 817 */
+   GLenum (GLAPIENTRYP ObjectPurgeableAPPLE)(GLenum objectType, GLuint name, GLenum option); /* 818 */
+   GLenum (GLAPIENTRYP ObjectUnpurgeableAPPLE)(GLenum objectType, GLuint name, GLenum option); /* 819 */
+   void (GLAPIENTRYP StencilFuncSeparateATI)(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); /* 820 */
+   void (GLAPIENTRYP ProgramEnvParameters4fvEXT)(GLenum target, GLuint index, GLsizei count, const GLfloat * params); /* 821 */
+   void (GLAPIENTRYP ProgramLocalParameters4fvEXT)(GLenum target, GLuint index, GLsizei count, const GLfloat * params); /* 822 */
+   void (GLAPIENTRYP GetQueryObjecti64vEXT)(GLuint id, GLenum pname, GLint64EXT * params); /* 823 */
+   void (GLAPIENTRYP GetQueryObjectui64vEXT)(GLuint id, GLenum pname, GLuint64EXT * params); /* 824 */
+   void (GLAPIENTRYP EGLImageTargetRenderbufferStorageOES)(GLenum target, GLvoid * writeOffset); /* 825 */
+   void (GLAPIENTRYP EGLImageTargetTexture2DOES)(GLenum target, GLvoid * writeOffset); /* 826 */
 };
 
 #endif /* !defined( _GLAPI_TABLE_H_ ) */
index 92835b9afc2341f5ca2ee0d7c323de76bd91e55b..f27f6ab22bc64a8f63fb27a9aaba514b8744a1ce 100644 (file)
@@ -27,7 +27,7 @@
  */
 
 
-#  if (defined(__GNUC__) && !defined(__MINGW32__)) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) && defined(__ELF__)
+#  if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) && defined(__ELF__)
 #    define HIDDEN  __attribute__((visibility("hidden")))
 #  else
 #    define HIDDEN
@@ -3882,6 +3882,21 @@ KEYWORD1 void KEYWORD2 NAME(RenderbufferStorageMultisampleEXT)(GLenum target, GL
    DISPATCH(RenderbufferStorageMultisample, (target, samples, internalformat, width, height), (F, "glRenderbufferStorageMultisampleEXT(0x%x, %d, 0x%x, %d, %d);\n", target, samples, internalformat, width, height));
 }
 
+KEYWORD1 void KEYWORD2 NAME(FramebufferTextureARB)(GLenum target, GLenum attachment, GLuint texture, GLint level)
+{
+   DISPATCH(FramebufferTextureARB, (target, attachment, texture, level), (F, "glFramebufferTextureARB(0x%x, 0x%x, %d, %d);\n", target, attachment, texture, level));
+}
+
+KEYWORD1 void KEYWORD2 NAME(FramebufferTextureFaceARB)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face)
+{
+   DISPATCH(FramebufferTextureFaceARB, (target, attachment, texture, level, face), (F, "glFramebufferTextureFaceARB(0x%x, 0x%x, %d, %d, 0x%x);\n", target, attachment, texture, level, face));
+}
+
+KEYWORD1 void KEYWORD2 NAME(ProgramParameteriARB)(GLuint program, GLenum pname, GLint value)
+{
+   DISPATCH(ProgramParameteriARB, (program, pname, value), (F, "glProgramParameteriARB(%d, 0x%x, %d);\n", program, pname, value));
+}
+
 KEYWORD1 void KEYWORD2 NAME(FlushMappedBufferRange)(GLenum target, GLintptr offset, GLsizeiptr length)
 {
    DISPATCH(FlushMappedBufferRange, (target, offset, length), (F, "glFlushMappedBufferRange(0x%x, %d, %d);\n", target, offset, length));
@@ -3957,63 +3972,98 @@ KEYWORD1 void KEYWORD2 NAME(MultiDrawElementsBaseVertex)(GLenum mode, const GLsi
    DISPATCH(MultiDrawElementsBaseVertex, (mode, count, type, indices, primcount, basevertex), (F, "glMultiDrawElementsBaseVertex(0x%x, %p, 0x%x, %p, %d, %p);\n", mode, (const void *) count, type, (const void *) indices, primcount, (const void *) basevertex));
 }
 
+KEYWORD1 void KEYWORD2 NAME(BindTransformFeedback)(GLenum target, GLuint id)
+{
+   DISPATCH(BindTransformFeedback, (target, id), (F, "glBindTransformFeedback(0x%x, %d);\n", target, id));
+}
+
+KEYWORD1 void KEYWORD2 NAME(DeleteTransformFeedbacks)(GLsizei n, const GLuint * ids)
+{
+   DISPATCH(DeleteTransformFeedbacks, (n, ids), (F, "glDeleteTransformFeedbacks(%d, %p);\n", n, (const void *) ids));
+}
+
+KEYWORD1 void KEYWORD2 NAME(DrawTransformFeedback)(GLenum mode, GLuint id)
+{
+   DISPATCH(DrawTransformFeedback, (mode, id), (F, "glDrawTransformFeedback(0x%x, %d);\n", mode, id));
+}
+
+KEYWORD1 void KEYWORD2 NAME(GenTransformFeedbacks)(GLsizei n, GLuint * ids)
+{
+   DISPATCH(GenTransformFeedbacks, (n, ids), (F, "glGenTransformFeedbacks(%d, %p);\n", n, (const void *) ids));
+}
+
+KEYWORD1 GLboolean KEYWORD2 NAME(IsTransformFeedback)(GLuint id)
+{
+   RETURN_DISPATCH(IsTransformFeedback, (id), (F, "glIsTransformFeedback(%d);\n", id));
+}
+
+KEYWORD1 void KEYWORD2 NAME(PauseTransformFeedback)(void)
+{
+   DISPATCH(PauseTransformFeedback, (), (F, "glPauseTransformFeedback();\n"));
+}
+
+KEYWORD1 void KEYWORD2 NAME(ResumeTransformFeedback)(void)
+{
+   DISPATCH(ResumeTransformFeedback, (), (F, "glResumeTransformFeedback();\n"));
+}
+
 KEYWORD1 void KEYWORD2 NAME(PolygonOffsetEXT)(GLfloat factor, GLfloat bias)
 {
    DISPATCH(PolygonOffsetEXT, (factor, bias), (F, "glPolygonOffsetEXT(%f, %f);\n", factor, bias));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_580)(GLenum pname, GLfloat * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_590)(GLenum pname, GLfloat * params);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_580)(GLenum pname, GLfloat * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_590)(GLenum pname, GLfloat * params)
 {
    DISPATCH(GetPixelTexGenParameterfvSGIS, (pname, params), (F, "glGetPixelTexGenParameterfvSGIS(0x%x, %p);\n", pname, (const void *) params));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_581)(GLenum pname, GLint * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_591)(GLenum pname, GLint * params);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_581)(GLenum pname, GLint * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_591)(GLenum pname, GLint * params)
 {
    DISPATCH(GetPixelTexGenParameterivSGIS, (pname, params), (F, "glGetPixelTexGenParameterivSGIS(0x%x, %p);\n", pname, (const void *) params));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_582)(GLenum pname, GLfloat param);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_592)(GLenum pname, GLfloat param);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_582)(GLenum pname, GLfloat param)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_592)(GLenum pname, GLfloat param)
 {
    DISPATCH(PixelTexGenParameterfSGIS, (pname, param), (F, "glPixelTexGenParameterfSGIS(0x%x, %f);\n", pname, param));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_583)(GLenum pname, const GLfloat * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_593)(GLenum pname, const GLfloat * params);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_583)(GLenum pname, const GLfloat * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_593)(GLenum pname, const GLfloat * params)
 {
    DISPATCH(PixelTexGenParameterfvSGIS, (pname, params), (F, "glPixelTexGenParameterfvSGIS(0x%x, %p);\n", pname, (const void *) params));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_584)(GLenum pname, GLint param);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_594)(GLenum pname, GLint param);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_584)(GLenum pname, GLint param)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_594)(GLenum pname, GLint param)
 {
    DISPATCH(PixelTexGenParameteriSGIS, (pname, param), (F, "glPixelTexGenParameteriSGIS(0x%x, %d);\n", pname, param));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_585)(GLenum pname, const GLint * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_595)(GLenum pname, const GLint * params);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_585)(GLenum pname, const GLint * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_595)(GLenum pname, const GLint * params)
 {
    DISPATCH(PixelTexGenParameterivSGIS, (pname, params), (F, "glPixelTexGenParameterivSGIS(0x%x, %p);\n", pname, (const void *) params));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_586)(GLclampf value, GLboolean invert);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_596)(GLclampf value, GLboolean invert);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_586)(GLclampf value, GLboolean invert)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_596)(GLclampf value, GLboolean invert)
 {
    DISPATCH(SampleMaskSGIS, (value, invert), (F, "glSampleMaskSGIS(%f, %d);\n", value, invert));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_587)(GLenum pattern);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_597)(GLenum pattern);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_587)(GLenum pattern)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_597)(GLenum pattern)
 {
    DISPATCH(SamplePatternSGIS, (pattern), (F, "glSamplePatternSGIS(0x%x);\n", pattern));
 }
@@ -4063,9 +4113,9 @@ KEYWORD1 void KEYWORD2 NAME(PointParameterfEXT)(GLenum pname, GLfloat param)
    DISPATCH(PointParameterfEXT, (pname, param), (F, "glPointParameterfEXT(0x%x, %f);\n", pname, param));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_594)(GLenum pname, GLfloat param);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_604)(GLenum pname, GLfloat param);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_594)(GLenum pname, GLfloat param)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_604)(GLenum pname, GLfloat param)
 {
    DISPATCH(PointParameterfEXT, (pname, param), (F, "glPointParameterfSGIS(0x%x, %f);\n", pname, param));
 }
@@ -4085,9 +4135,9 @@ KEYWORD1 void KEYWORD2 NAME(PointParameterfvEXT)(GLenum pname, const GLfloat * p
    DISPATCH(PointParameterfvEXT, (pname, params), (F, "glPointParameterfvEXT(0x%x, %p);\n", pname, (const void *) params));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_595)(GLenum pname, const GLfloat * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_605)(GLenum pname, const GLfloat * params);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_595)(GLenum pname, const GLfloat * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_605)(GLenum pname, const GLfloat * params)
 {
    DISPATCH(PointParameterfvEXT, (pname, params), (F, "glPointParameterfvSGIS(0x%x, %p);\n", pname, (const void *) params));
 }
@@ -4102,16 +4152,16 @@ KEYWORD1 void KEYWORD2 NAME(UnlockArraysEXT)(void)
    DISPATCH(UnlockArraysEXT, (), (F, "glUnlockArraysEXT();\n"));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_598)(GLenum pname, GLdouble * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_608)(GLenum pname, GLdouble * params);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_598)(GLenum pname, GLdouble * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_608)(GLenum pname, GLdouble * params)
 {
    DISPATCH(CullParameterdvEXT, (pname, params), (F, "glCullParameterdvEXT(0x%x, %p);\n", pname, (const void *) params));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_599)(GLenum pname, GLfloat * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_609)(GLenum pname, GLfloat * params);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_599)(GLenum pname, GLfloat * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_609)(GLenum pname, GLfloat * params)
 {
    DISPATCH(CullParameterfvEXT, (pname, params), (F, "glCullParameterfvEXT(0x%x, %p);\n", pname, (const void *) params));
 }
@@ -4356,9 +4406,9 @@ KEYWORD1 void KEYWORD2 NAME(FogCoordfvEXT)(const GLfloat * coord)
    DISPATCH(FogCoordfvEXT, (coord), (F, "glFogCoordfvEXT(%p);\n", (const void *) coord));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_624)(GLenum mode);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_634)(GLenum mode);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_624)(GLenum mode)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_634)(GLenum mode)
 {
    DISPATCH(PixelTexGenSGIX, (mode), (F, "glPixelTexGenSGIX(0x%x);\n", mode));
 }
@@ -4373,9 +4423,9 @@ KEYWORD1 void KEYWORD2 NAME(BlendFuncSeparateEXT)(GLenum sfactorRGB, GLenum dfac
    DISPATCH(BlendFuncSeparateEXT, (sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha), (F, "glBlendFuncSeparateEXT(0x%x, 0x%x, 0x%x, 0x%x);\n", sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_625)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_635)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_625)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_635)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha)
 {
    DISPATCH(BlendFuncSeparateEXT, (sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha), (F, "glBlendFuncSeparateINGR(0x%x, 0x%x, 0x%x, 0x%x);\n", sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha));
 }
@@ -4740,65 +4790,65 @@ KEYWORD1 void KEYWORD2 NAME(WindowPos4svMESA)(const GLshort * v)
    DISPATCH(WindowPos4svMESA, (v), (F, "glWindowPos4svMESA(%p);\n", (const void *) v));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_666)(const GLenum * mode, const GLint * first, const GLsizei * count, GLsizei primcount, GLint modestride);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_676)(const GLenum * mode, const GLint * first, const GLsizei * count, GLsizei primcount, GLint modestride);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_666)(const GLenum * mode, const GLint * first, const GLsizei * count, GLsizei primcount, GLint modestride)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_676)(const GLenum * mode, const GLint * first, const GLsizei * count, GLsizei primcount, GLint modestride)
 {
    DISPATCH(MultiModeDrawArraysIBM, (mode, first, count, primcount, modestride), (F, "glMultiModeDrawArraysIBM(%p, %p, %p, %d, %d);\n", (const void *) mode, (const void *) first, (const void *) count, primcount, modestride));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_667)(const GLenum * mode, const GLsizei * count, GLenum type, const GLvoid * const * indices, GLsizei primcount, GLint modestride);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_677)(const GLenum * mode, const GLsizei * count, GLenum type, const GLvoid * const * indices, GLsizei primcount, GLint modestride);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_667)(const GLenum * mode, const GLsizei * count, GLenum type, const GLvoid * const * indices, GLsizei primcount, GLint modestride)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_677)(const GLenum * mode, const GLsizei * count, GLenum type, const GLvoid * const * indices, GLsizei primcount, GLint modestride)
 {
    DISPATCH(MultiModeDrawElementsIBM, (mode, count, type, indices, primcount, modestride), (F, "glMultiModeDrawElementsIBM(%p, %p, 0x%x, %p, %d, %d);\n", (const void *) mode, (const void *) count, type, (const void *) indices, primcount, modestride));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_668)(GLsizei n, const GLuint * fences);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_678)(GLsizei n, const GLuint * fences);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_668)(GLsizei n, const GLuint * fences)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_678)(GLsizei n, const GLuint * fences)
 {
    DISPATCH(DeleteFencesNV, (n, fences), (F, "glDeleteFencesNV(%d, %p);\n", n, (const void *) fences));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_669)(GLuint fence);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_679)(GLuint fence);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_669)(GLuint fence)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_679)(GLuint fence)
 {
    DISPATCH(FinishFenceNV, (fence), (F, "glFinishFenceNV(%d);\n", fence));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_670)(GLsizei n, GLuint * fences);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_680)(GLsizei n, GLuint * fences);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_670)(GLsizei n, GLuint * fences)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_680)(GLsizei n, GLuint * fences)
 {
    DISPATCH(GenFencesNV, (n, fences), (F, "glGenFencesNV(%d, %p);\n", n, (const void *) fences));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_671)(GLuint fence, GLenum pname, GLint * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_681)(GLuint fence, GLenum pname, GLint * params);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_671)(GLuint fence, GLenum pname, GLint * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_681)(GLuint fence, GLenum pname, GLint * params)
 {
    DISPATCH(GetFenceivNV, (fence, pname, params), (F, "glGetFenceivNV(%d, 0x%x, %p);\n", fence, pname, (const void *) params));
 }
 
-KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_672)(GLuint fence);
+KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_682)(GLuint fence);
 
-KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_672)(GLuint fence)
+KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_682)(GLuint fence)
 {
    RETURN_DISPATCH(IsFenceNV, (fence), (F, "glIsFenceNV(%d);\n", fence));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_673)(GLuint fence, GLenum condition);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_683)(GLuint fence, GLenum condition);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_673)(GLuint fence, GLenum condition)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_683)(GLuint fence, GLenum condition)
 {
    DISPATCH(SetFenceNV, (fence, condition), (F, "glSetFenceNV(%d, 0x%x);\n", fence, condition));
 }
 
-KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_674)(GLuint fence);
+KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_684)(GLuint fence);
 
-KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_674)(GLuint fence)
+KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_684)(GLuint fence)
 {
    RETURN_DISPATCH(TestFenceNV, (fence), (F, "glTestFenceNV(%d);\n", fence));
 }
@@ -5243,16 +5293,16 @@ KEYWORD1 void KEYWORD2 NAME(PointParameterivNV)(GLenum pname, const GLint * para
    DISPATCH(PointParameterivNV, (pname, params), (F, "glPointParameterivNV(0x%x, %p);\n", pname, (const void *) params));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_755)(GLenum face);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_765)(GLenum face);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_755)(GLenum face)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_765)(GLenum face)
 {
    DISPATCH(ActiveStencilFaceEXT, (face), (F, "glActiveStencilFaceEXT(0x%x);\n", face));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_756)(GLuint array);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_766)(GLuint array);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_756)(GLuint array)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_766)(GLuint array)
 {
    DISPATCH(BindVertexArrayAPPLE, (array), (F, "glBindVertexArrayAPPLE(%d);\n", array));
 }
@@ -5262,16 +5312,16 @@ KEYWORD1 void KEYWORD2 NAME(DeleteVertexArrays)(GLsizei n, const GLuint * arrays
    DISPATCH(DeleteVertexArraysAPPLE, (n, arrays), (F, "glDeleteVertexArrays(%d, %p);\n", n, (const void *) arrays));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_757)(GLsizei n, const GLuint * arrays);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_767)(GLsizei n, const GLuint * arrays);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_757)(GLsizei n, const GLuint * arrays)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_767)(GLsizei n, const GLuint * arrays)
 {
    DISPATCH(DeleteVertexArraysAPPLE, (n, arrays), (F, "glDeleteVertexArraysAPPLE(%d, %p);\n", n, (const void *) arrays));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_758)(GLsizei n, GLuint * arrays);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_768)(GLsizei n, GLuint * arrays);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_758)(GLsizei n, GLuint * arrays)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_768)(GLsizei n, GLuint * arrays)
 {
    DISPATCH(GenVertexArraysAPPLE, (n, arrays), (F, "glGenVertexArraysAPPLE(%d, %p);\n", n, (const void *) arrays));
 }
@@ -5281,9 +5331,9 @@ KEYWORD1 GLboolean KEYWORD2 NAME(IsVertexArray)(GLuint array)
    RETURN_DISPATCH(IsVertexArrayAPPLE, (array), (F, "glIsVertexArray(%d);\n", array));
 }
 
-KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_759)(GLuint array);
+KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_769)(GLuint array);
 
-KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_759)(GLuint array)
+KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_769)(GLuint array)
 {
    RETURN_DISPATCH(IsVertexArrayAPPLE, (array), (F, "glIsVertexArrayAPPLE(%d);\n", array));
 }
@@ -5318,9 +5368,9 @@ KEYWORD1 void KEYWORD2 NAME(ProgramNamedParameter4fvNV)(GLuint id, GLsizei len,
    DISPATCH(ProgramNamedParameter4fvNV, (id, len, name, v), (F, "glProgramNamedParameter4fvNV(%d, %d, %p, %p);\n", id, len, (const void *) name, (const void *) v));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_766)(GLclampd zmin, GLclampd zmax);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_776)(GLclampd zmin, GLclampd zmax);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_766)(GLclampd zmin, GLclampd zmax)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_776)(GLclampd zmin, GLclampd zmax)
 {
    DISPATCH(DepthBoundsEXT, (zmin, zmax), (F, "glDepthBoundsEXT(%f, %f);\n", zmin, zmax));
 }
@@ -5330,9 +5380,9 @@ KEYWORD1 void KEYWORD2 NAME(BlendEquationSeparate)(GLenum modeRGB, GLenum modeA)
    DISPATCH(BlendEquationSeparateEXT, (modeRGB, modeA), (F, "glBlendEquationSeparate(0x%x, 0x%x);\n", modeRGB, modeA));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_767)(GLenum modeRGB, GLenum modeA);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_777)(GLenum modeRGB, GLenum modeA);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_767)(GLenum modeRGB, GLenum modeA)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_777)(GLenum modeRGB, GLenum modeA)
 {
    DISPATCH(BlendEquationSeparateEXT, (modeRGB, modeA), (F, "glBlendEquationSeparateEXT(0x%x, 0x%x);\n", modeRGB, modeA));
 }
@@ -5512,23 +5562,23 @@ KEYWORD1 void KEYWORD2 NAME(BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint src
    DISPATCH(BlitFramebufferEXT, (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter), (F, "glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d, %d, 0x%x);\n", srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_785)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_795)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_785)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_795)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
 {
    DISPATCH(BlitFramebufferEXT, (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter), (F, "glBlitFramebufferEXT(%d, %d, %d, %d, %d, %d, %d, %d, %d, 0x%x);\n", srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_786)(GLenum target, GLenum pname, GLint param);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_796)(GLenum target, GLenum pname, GLint param);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_786)(GLenum target, GLenum pname, GLint param)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_796)(GLenum target, GLenum pname, GLint param)
 {
    DISPATCH(BufferParameteriAPPLE, (target, pname, param), (F, "glBufferParameteriAPPLE(0x%x, 0x%x, %d);\n", target, pname, param));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_787)(GLenum target, GLintptr offset, GLsizeiptr size);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_797)(GLenum target, GLintptr offset, GLsizeiptr size);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_787)(GLenum target, GLintptr offset, GLsizeiptr size)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_797)(GLenum target, GLintptr offset, GLsizeiptr size)
 {
    DISPATCH(FlushMappedBufferRangeAPPLE, (target, offset, size), (F, "glFlushMappedBufferRangeAPPLE(0x%x, %d, %d);\n", target, offset, size));
 }
@@ -5658,16 +5708,16 @@ KEYWORD1 void KEYWORD2 NAME(ProvokingVertex)(GLenum mode)
    DISPATCH(ProvokingVertexEXT, (mode), (F, "glProvokingVertex(0x%x);\n", mode));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_805)(GLenum target, GLenum pname, GLvoid ** params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_815)(GLenum target, GLenum pname, GLvoid ** params);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_805)(GLenum target, GLenum pname, GLvoid ** params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_815)(GLenum target, GLenum pname, GLvoid ** params)
 {
    DISPATCH(GetTexParameterPointervAPPLE, (target, pname, params), (F, "glGetTexParameterPointervAPPLE(0x%x, 0x%x, %p);\n", target, pname, (const void *) params));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_806)(GLenum target, GLsizei length, GLvoid * pointer);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_816)(GLenum target, GLsizei length, GLvoid * pointer);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_806)(GLenum target, GLsizei length, GLvoid * pointer)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_816)(GLenum target, GLsizei length, GLvoid * pointer)
 {
    DISPATCH(TextureRangeAPPLE, (target, length, pointer), (F, "glTextureRangeAPPLE(0x%x, %d, %p);\n", target, length, (const void *) pointer));
 }
@@ -5687,37 +5737,37 @@ KEYWORD1 GLenum KEYWORD2 NAME(ObjectUnpurgeableAPPLE)(GLenum objectType, GLuint
    RETURN_DISPATCH(ObjectUnpurgeableAPPLE, (objectType, name, option), (F, "glObjectUnpurgeableAPPLE(0x%x, %d, 0x%x);\n", objectType, name, option));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_810)(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_820)(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_810)(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_820)(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask)
 {
    DISPATCH(StencilFuncSeparateATI, (frontfunc, backfunc, ref, mask), (F, "glStencilFuncSeparateATI(0x%x, 0x%x, %d, %d);\n", frontfunc, backfunc, ref, mask));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_811)(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_821)(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_811)(GLenum target, GLuint index, GLsizei count, const GLfloat * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_821)(GLenum target, GLuint index, GLsizei count, const GLfloat * params)
 {
    DISPATCH(ProgramEnvParameters4fvEXT, (target, index, count, params), (F, "glProgramEnvParameters4fvEXT(0x%x, %d, %d, %p);\n", target, index, count, (const void *) params));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_812)(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_822)(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_812)(GLenum target, GLuint index, GLsizei count, const GLfloat * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_822)(GLenum target, GLuint index, GLsizei count, const GLfloat * params)
 {
    DISPATCH(ProgramLocalParameters4fvEXT, (target, index, count, params), (F, "glProgramLocalParameters4fvEXT(0x%x, %d, %d, %p);\n", target, index, count, (const void *) params));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_813)(GLuint id, GLenum pname, GLint64EXT * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_823)(GLuint id, GLenum pname, GLint64EXT * params);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_813)(GLuint id, GLenum pname, GLint64EXT * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_823)(GLuint id, GLenum pname, GLint64EXT * params)
 {
    DISPATCH(GetQueryObjecti64vEXT, (id, pname, params), (F, "glGetQueryObjecti64vEXT(%d, 0x%x, %p);\n", id, pname, (const void *) params));
 }
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_814)(GLuint id, GLenum pname, GLuint64EXT * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_824)(GLuint id, GLenum pname, GLuint64EXT * params);
 
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_814)(GLuint id, GLenum pname, GLuint64EXT * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_824)(GLuint id, GLenum pname, GLuint64EXT * params)
 {
    DISPATCH(GetQueryObjectui64vEXT, (id, pname, params), (F, "glGetQueryObjectui64vEXT(%d, 0x%x, %p);\n", id, pname, (const void *) params));
 }
@@ -6449,6 +6499,9 @@ _glapi_proc DISPATCH_TABLE_NAME[] = {
    TABLE_ENTRY(GetAttribLocationARB),
    TABLE_ENTRY(DrawBuffersARB),
    TABLE_ENTRY(RenderbufferStorageMultisample),
+   TABLE_ENTRY(FramebufferTextureARB),
+   TABLE_ENTRY(FramebufferTextureFaceARB),
+   TABLE_ENTRY(ProgramParameteriARB),
    TABLE_ENTRY(FlushMappedBufferRange),
    TABLE_ENTRY(MapBufferRange),
    TABLE_ENTRY(BindVertexArray),
@@ -6464,15 +6517,22 @@ _glapi_proc DISPATCH_TABLE_NAME[] = {
    TABLE_ENTRY(DrawElementsBaseVertex),
    TABLE_ENTRY(DrawRangeElementsBaseVertex),
    TABLE_ENTRY(MultiDrawElementsBaseVertex),
+   TABLE_ENTRY(BindTransformFeedback),
+   TABLE_ENTRY(DeleteTransformFeedbacks),
+   TABLE_ENTRY(DrawTransformFeedback),
+   TABLE_ENTRY(GenTransformFeedbacks),
+   TABLE_ENTRY(IsTransformFeedback),
+   TABLE_ENTRY(PauseTransformFeedback),
+   TABLE_ENTRY(ResumeTransformFeedback),
    TABLE_ENTRY(PolygonOffsetEXT),
-   TABLE_ENTRY(_dispatch_stub_580),
-   TABLE_ENTRY(_dispatch_stub_581),
-   TABLE_ENTRY(_dispatch_stub_582),
-   TABLE_ENTRY(_dispatch_stub_583),
-   TABLE_ENTRY(_dispatch_stub_584),
-   TABLE_ENTRY(_dispatch_stub_585),
-   TABLE_ENTRY(_dispatch_stub_586),
-   TABLE_ENTRY(_dispatch_stub_587),
+   TABLE_ENTRY(_dispatch_stub_590),
+   TABLE_ENTRY(_dispatch_stub_591),
+   TABLE_ENTRY(_dispatch_stub_592),
+   TABLE_ENTRY(_dispatch_stub_593),
+   TABLE_ENTRY(_dispatch_stub_594),
+   TABLE_ENTRY(_dispatch_stub_595),
+   TABLE_ENTRY(_dispatch_stub_596),
+   TABLE_ENTRY(_dispatch_stub_597),
    TABLE_ENTRY(ColorPointerEXT),
    TABLE_ENTRY(EdgeFlagPointerEXT),
    TABLE_ENTRY(IndexPointerEXT),
@@ -6483,8 +6543,8 @@ _glapi_proc DISPATCH_TABLE_NAME[] = {
    TABLE_ENTRY(PointParameterfvEXT),
    TABLE_ENTRY(LockArraysEXT),
    TABLE_ENTRY(UnlockArraysEXT),
-   TABLE_ENTRY(_dispatch_stub_598),
-   TABLE_ENTRY(_dispatch_stub_599),
+   TABLE_ENTRY(_dispatch_stub_608),
+   TABLE_ENTRY(_dispatch_stub_609),
    TABLE_ENTRY(SecondaryColor3bEXT),
    TABLE_ENTRY(SecondaryColor3bvEXT),
    TABLE_ENTRY(SecondaryColor3dEXT),
@@ -6509,7 +6569,7 @@ _glapi_proc DISPATCH_TABLE_NAME[] = {
    TABLE_ENTRY(FogCoorddvEXT),
    TABLE_ENTRY(FogCoordfEXT),
    TABLE_ENTRY(FogCoordfvEXT),
-   TABLE_ENTRY(_dispatch_stub_624),
+   TABLE_ENTRY(_dispatch_stub_634),
    TABLE_ENTRY(BlendFuncSeparateEXT),
    TABLE_ENTRY(FlushVertexArrayRangeNV),
    TABLE_ENTRY(VertexArrayRangeNV),
@@ -6551,15 +6611,15 @@ _glapi_proc DISPATCH_TABLE_NAME[] = {
    TABLE_ENTRY(WindowPos4ivMESA),
    TABLE_ENTRY(WindowPos4sMESA),
    TABLE_ENTRY(WindowPos4svMESA),
-   TABLE_ENTRY(_dispatch_stub_666),
-   TABLE_ENTRY(_dispatch_stub_667),
-   TABLE_ENTRY(_dispatch_stub_668),
-   TABLE_ENTRY(_dispatch_stub_669),
-   TABLE_ENTRY(_dispatch_stub_670),
-   TABLE_ENTRY(_dispatch_stub_671),
-   TABLE_ENTRY(_dispatch_stub_672),
-   TABLE_ENTRY(_dispatch_stub_673),
-   TABLE_ENTRY(_dispatch_stub_674),
+   TABLE_ENTRY(_dispatch_stub_676),
+   TABLE_ENTRY(_dispatch_stub_677),
+   TABLE_ENTRY(_dispatch_stub_678),
+   TABLE_ENTRY(_dispatch_stub_679),
+   TABLE_ENTRY(_dispatch_stub_680),
+   TABLE_ENTRY(_dispatch_stub_681),
+   TABLE_ENTRY(_dispatch_stub_682),
+   TABLE_ENTRY(_dispatch_stub_683),
+   TABLE_ENTRY(_dispatch_stub_684),
    TABLE_ENTRY(AreProgramsResidentNV),
    TABLE_ENTRY(BindProgramNV),
    TABLE_ENTRY(DeleteProgramsNV),
@@ -6640,19 +6700,19 @@ _glapi_proc DISPATCH_TABLE_NAME[] = {
    TABLE_ENTRY(SetFragmentShaderConstantATI),
    TABLE_ENTRY(PointParameteriNV),
    TABLE_ENTRY(PointParameterivNV),
-   TABLE_ENTRY(_dispatch_stub_755),
-   TABLE_ENTRY(_dispatch_stub_756),
-   TABLE_ENTRY(_dispatch_stub_757),
-   TABLE_ENTRY(_dispatch_stub_758),
-   TABLE_ENTRY(_dispatch_stub_759),
+   TABLE_ENTRY(_dispatch_stub_765),
+   TABLE_ENTRY(_dispatch_stub_766),
+   TABLE_ENTRY(_dispatch_stub_767),
+   TABLE_ENTRY(_dispatch_stub_768),
+   TABLE_ENTRY(_dispatch_stub_769),
    TABLE_ENTRY(GetProgramNamedParameterdvNV),
    TABLE_ENTRY(GetProgramNamedParameterfvNV),
    TABLE_ENTRY(ProgramNamedParameter4dNV),
    TABLE_ENTRY(ProgramNamedParameter4dvNV),
    TABLE_ENTRY(ProgramNamedParameter4fNV),
    TABLE_ENTRY(ProgramNamedParameter4fvNV),
-   TABLE_ENTRY(_dispatch_stub_766),
-   TABLE_ENTRY(_dispatch_stub_767),
+   TABLE_ENTRY(_dispatch_stub_776),
+   TABLE_ENTRY(_dispatch_stub_777),
    TABLE_ENTRY(BindFramebufferEXT),
    TABLE_ENTRY(BindRenderbufferEXT),
    TABLE_ENTRY(CheckFramebufferStatusEXT),
@@ -6670,9 +6730,9 @@ _glapi_proc DISPATCH_TABLE_NAME[] = {
    TABLE_ENTRY(IsFramebufferEXT),
    TABLE_ENTRY(IsRenderbufferEXT),
    TABLE_ENTRY(RenderbufferStorageEXT),
-   TABLE_ENTRY(_dispatch_stub_785),
-   TABLE_ENTRY(_dispatch_stub_786),
-   TABLE_ENTRY(_dispatch_stub_787),
+   TABLE_ENTRY(_dispatch_stub_795),
+   TABLE_ENTRY(_dispatch_stub_796),
+   TABLE_ENTRY(_dispatch_stub_797),
    TABLE_ENTRY(FramebufferTextureLayerEXT),
    TABLE_ENTRY(ColorMaskIndexedEXT),
    TABLE_ENTRY(DisableIndexedEXT),
@@ -6690,16 +6750,16 @@ _glapi_proc DISPATCH_TABLE_NAME[] = {
    TABLE_ENTRY(GetTransformFeedbackVaryingEXT),
    TABLE_ENTRY(TransformFeedbackVaryingsEXT),
    TABLE_ENTRY(ProvokingVertexEXT),
-   TABLE_ENTRY(_dispatch_stub_805),
-   TABLE_ENTRY(_dispatch_stub_806),
+   TABLE_ENTRY(_dispatch_stub_815),
+   TABLE_ENTRY(_dispatch_stub_816),
    TABLE_ENTRY(GetObjectParameterivAPPLE),
    TABLE_ENTRY(ObjectPurgeableAPPLE),
    TABLE_ENTRY(ObjectUnpurgeableAPPLE),
-   TABLE_ENTRY(_dispatch_stub_810),
-   TABLE_ENTRY(_dispatch_stub_811),
-   TABLE_ENTRY(_dispatch_stub_812),
-   TABLE_ENTRY(_dispatch_stub_813),
-   TABLE_ENTRY(_dispatch_stub_814),
+   TABLE_ENTRY(_dispatch_stub_820),
+   TABLE_ENTRY(_dispatch_stub_821),
+   TABLE_ENTRY(_dispatch_stub_822),
+   TABLE_ENTRY(_dispatch_stub_823),
+   TABLE_ENTRY(_dispatch_stub_824),
    TABLE_ENTRY(EGLImageTargetRenderbufferStorageOES),
    TABLE_ENTRY(EGLImageTargetTexture2DOES),
    /* A whole bunch of no-op functions.  These might be called
@@ -7006,10 +7066,10 @@ _glapi_proc UNUSED_TABLE_NAME[] = {
    TABLE_ENTRY(RenderbufferStorageMultisampleEXT),
    TABLE_ENTRY(PointParameterf),
    TABLE_ENTRY(PointParameterfARB),
-   TABLE_ENTRY(_dispatch_stub_594),
+   TABLE_ENTRY(_dispatch_stub_604),
    TABLE_ENTRY(PointParameterfv),
    TABLE_ENTRY(PointParameterfvARB),
-   TABLE_ENTRY(_dispatch_stub_595),
+   TABLE_ENTRY(_dispatch_stub_605),
    TABLE_ENTRY(SecondaryColor3b),
    TABLE_ENTRY(SecondaryColor3bv),
    TABLE_ENTRY(SecondaryColor3d),
@@ -7035,7 +7095,7 @@ _glapi_proc UNUSED_TABLE_NAME[] = {
    TABLE_ENTRY(FogCoordf),
    TABLE_ENTRY(FogCoordfv),
    TABLE_ENTRY(BlendFuncSeparate),
-   TABLE_ENTRY(_dispatch_stub_625),
+   TABLE_ENTRY(_dispatch_stub_635),
    TABLE_ENTRY(WindowPos2d),
    TABLE_ENTRY(WindowPos2dARB),
    TABLE_ENTRY(WindowPos2dv),
index 8eb04ee67814ddbbd4153a1ef72e33a7a231f687..0ddcf4bad0cc534f71f8ff3908c4fa4c7bcf60df 100644 (file)
@@ -616,6 +616,9 @@ static const char gl_string_table[] =
     "glGetAttribLocationARB\0"
     "glDrawBuffersARB\0"
     "glRenderbufferStorageMultisample\0"
+    "glFramebufferTextureARB\0"
+    "glFramebufferTextureFaceARB\0"
+    "glProgramParameteriARB\0"
     "glFlushMappedBufferRange\0"
     "glMapBufferRange\0"
     "glBindVertexArray\0"
@@ -631,6 +634,13 @@ static const char gl_string_table[] =
     "glDrawElementsBaseVertex\0"
     "glDrawRangeElementsBaseVertex\0"
     "glMultiDrawElementsBaseVertex\0"
+    "glBindTransformFeedback\0"
+    "glDeleteTransformFeedbacks\0"
+    "glDrawTransformFeedback\0"
+    "glGenTransformFeedbacks\0"
+    "glIsTransformFeedback\0"
+    "glPauseTransformFeedback\0"
+    "glResumeTransformFeedback\0"
     "glPolygonOffsetEXT\0"
     "glGetPixelTexGenParameterfvSGIS\0"
     "glGetPixelTexGenParameterivSGIS\0"
@@ -1198,43 +1208,43 @@ static const char gl_string_table[] =
 #define gl_dispatch_stub_364 mgl_dispatch_stub_364
 #define gl_dispatch_stub_365 mgl_dispatch_stub_365
 #define gl_dispatch_stub_366 mgl_dispatch_stub_366
-#define gl_dispatch_stub_580 mgl_dispatch_stub_580
-#define gl_dispatch_stub_581 mgl_dispatch_stub_581
-#define gl_dispatch_stub_582 mgl_dispatch_stub_582
-#define gl_dispatch_stub_583 mgl_dispatch_stub_583
-#define gl_dispatch_stub_584 mgl_dispatch_stub_584
-#define gl_dispatch_stub_585 mgl_dispatch_stub_585
-#define gl_dispatch_stub_586 mgl_dispatch_stub_586
-#define gl_dispatch_stub_587 mgl_dispatch_stub_587
-#define gl_dispatch_stub_598 mgl_dispatch_stub_598
-#define gl_dispatch_stub_599 mgl_dispatch_stub_599
-#define gl_dispatch_stub_624 mgl_dispatch_stub_624
-#define gl_dispatch_stub_666 mgl_dispatch_stub_666
-#define gl_dispatch_stub_667 mgl_dispatch_stub_667
-#define gl_dispatch_stub_668 mgl_dispatch_stub_668
-#define gl_dispatch_stub_669 mgl_dispatch_stub_669
-#define gl_dispatch_stub_670 mgl_dispatch_stub_670
-#define gl_dispatch_stub_671 mgl_dispatch_stub_671
-#define gl_dispatch_stub_672 mgl_dispatch_stub_672
-#define gl_dispatch_stub_673 mgl_dispatch_stub_673
-#define gl_dispatch_stub_674 mgl_dispatch_stub_674
-#define gl_dispatch_stub_755 mgl_dispatch_stub_755
-#define gl_dispatch_stub_756 mgl_dispatch_stub_756
-#define gl_dispatch_stub_757 mgl_dispatch_stub_757
-#define gl_dispatch_stub_758 mgl_dispatch_stub_758
-#define gl_dispatch_stub_759 mgl_dispatch_stub_759
+#define gl_dispatch_stub_590 mgl_dispatch_stub_590
+#define gl_dispatch_stub_591 mgl_dispatch_stub_591
+#define gl_dispatch_stub_592 mgl_dispatch_stub_592
+#define gl_dispatch_stub_593 mgl_dispatch_stub_593
+#define gl_dispatch_stub_594 mgl_dispatch_stub_594
+#define gl_dispatch_stub_595 mgl_dispatch_stub_595
+#define gl_dispatch_stub_596 mgl_dispatch_stub_596
+#define gl_dispatch_stub_597 mgl_dispatch_stub_597
+#define gl_dispatch_stub_608 mgl_dispatch_stub_608
+#define gl_dispatch_stub_609 mgl_dispatch_stub_609
+#define gl_dispatch_stub_634 mgl_dispatch_stub_634
+#define gl_dispatch_stub_676 mgl_dispatch_stub_676
+#define gl_dispatch_stub_677 mgl_dispatch_stub_677
+#define gl_dispatch_stub_678 mgl_dispatch_stub_678
+#define gl_dispatch_stub_679 mgl_dispatch_stub_679
+#define gl_dispatch_stub_680 mgl_dispatch_stub_680
+#define gl_dispatch_stub_681 mgl_dispatch_stub_681
+#define gl_dispatch_stub_682 mgl_dispatch_stub_682
+#define gl_dispatch_stub_683 mgl_dispatch_stub_683
+#define gl_dispatch_stub_684 mgl_dispatch_stub_684
+#define gl_dispatch_stub_765 mgl_dispatch_stub_765
 #define gl_dispatch_stub_766 mgl_dispatch_stub_766
 #define gl_dispatch_stub_767 mgl_dispatch_stub_767
-#define gl_dispatch_stub_785 mgl_dispatch_stub_785
-#define gl_dispatch_stub_786 mgl_dispatch_stub_786
-#define gl_dispatch_stub_787 mgl_dispatch_stub_787
-#define gl_dispatch_stub_805 mgl_dispatch_stub_805
-#define gl_dispatch_stub_806 mgl_dispatch_stub_806
-#define gl_dispatch_stub_810 mgl_dispatch_stub_810
-#define gl_dispatch_stub_811 mgl_dispatch_stub_811
-#define gl_dispatch_stub_812 mgl_dispatch_stub_812
-#define gl_dispatch_stub_813 mgl_dispatch_stub_813
-#define gl_dispatch_stub_814 mgl_dispatch_stub_814
+#define gl_dispatch_stub_768 mgl_dispatch_stub_768
+#define gl_dispatch_stub_769 mgl_dispatch_stub_769
+#define gl_dispatch_stub_776 mgl_dispatch_stub_776
+#define gl_dispatch_stub_777 mgl_dispatch_stub_777
+#define gl_dispatch_stub_795 mgl_dispatch_stub_795
+#define gl_dispatch_stub_796 mgl_dispatch_stub_796
+#define gl_dispatch_stub_797 mgl_dispatch_stub_797
+#define gl_dispatch_stub_815 mgl_dispatch_stub_815
+#define gl_dispatch_stub_816 mgl_dispatch_stub_816
+#define gl_dispatch_stub_820 mgl_dispatch_stub_820
+#define gl_dispatch_stub_821 mgl_dispatch_stub_821
+#define gl_dispatch_stub_822 mgl_dispatch_stub_822
+#define gl_dispatch_stub_823 mgl_dispatch_stub_823
+#define gl_dispatch_stub_824 mgl_dispatch_stub_824
 #endif /* USE_MGL_NAMESPACE */
 
 
@@ -1252,43 +1262,43 @@ void GLAPIENTRY gl_dispatch_stub_363(GLenum target, GLenum pname, GLint * params
 void GLAPIENTRY gl_dispatch_stub_364(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values);
 void GLAPIENTRY gl_dispatch_stub_365(GLenum target, GLenum pname, GLfloat * params);
 void GLAPIENTRY gl_dispatch_stub_366(GLenum target, GLenum pname, GLint * params);
-void GLAPIENTRY gl_dispatch_stub_580(GLenum pname, GLfloat * params);
-void GLAPIENTRY gl_dispatch_stub_581(GLenum pname, GLint * params);
-void GLAPIENTRY gl_dispatch_stub_582(GLenum pname, GLfloat param);
-void GLAPIENTRY gl_dispatch_stub_583(GLenum pname, const GLfloat * params);
-void GLAPIENTRY gl_dispatch_stub_584(GLenum pname, GLint param);
-void GLAPIENTRY gl_dispatch_stub_585(GLenum pname, const GLint * params);
-void GLAPIENTRY gl_dispatch_stub_586(GLclampf value, GLboolean invert);
-void GLAPIENTRY gl_dispatch_stub_587(GLenum pattern);
-void GLAPIENTRY gl_dispatch_stub_598(GLenum pname, GLdouble * params);
-void GLAPIENTRY gl_dispatch_stub_599(GLenum pname, GLfloat * params);
-void GLAPIENTRY gl_dispatch_stub_624(GLenum mode);
-void GLAPIENTRY gl_dispatch_stub_666(const GLenum * mode, const GLint * first, const GLsizei * count, GLsizei primcount, GLint modestride);
-void GLAPIENTRY gl_dispatch_stub_667(const GLenum * mode, const GLsizei * count, GLenum type, const GLvoid * const * indices, GLsizei primcount, GLint modestride);
-void GLAPIENTRY gl_dispatch_stub_668(GLsizei n, const GLuint * fences);
-void GLAPIENTRY gl_dispatch_stub_669(GLuint fence);
-void GLAPIENTRY gl_dispatch_stub_670(GLsizei n, GLuint * fences);
-void GLAPIENTRY gl_dispatch_stub_671(GLuint fence, GLenum pname, GLint * params);
-GLboolean GLAPIENTRY gl_dispatch_stub_672(GLuint fence);
-void GLAPIENTRY gl_dispatch_stub_673(GLuint fence, GLenum condition);
-GLboolean GLAPIENTRY gl_dispatch_stub_674(GLuint fence);
-void GLAPIENTRY gl_dispatch_stub_755(GLenum face);
-void GLAPIENTRY gl_dispatch_stub_756(GLuint array);
-void GLAPIENTRY gl_dispatch_stub_757(GLsizei n, const GLuint * arrays);
-void GLAPIENTRY gl_dispatch_stub_758(GLsizei n, GLuint * arrays);
-GLboolean GLAPIENTRY gl_dispatch_stub_759(GLuint array);
-void GLAPIENTRY gl_dispatch_stub_766(GLclampd zmin, GLclampd zmax);
-void GLAPIENTRY gl_dispatch_stub_767(GLenum modeRGB, GLenum modeA);
-void GLAPIENTRY gl_dispatch_stub_785(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
-void GLAPIENTRY gl_dispatch_stub_786(GLenum target, GLenum pname, GLint param);
-void GLAPIENTRY gl_dispatch_stub_787(GLenum target, GLintptr offset, GLsizeiptr size);
-void GLAPIENTRY gl_dispatch_stub_805(GLenum target, GLenum pname, GLvoid ** params);
-void GLAPIENTRY gl_dispatch_stub_806(GLenum target, GLsizei length, GLvoid * pointer);
-void GLAPIENTRY gl_dispatch_stub_810(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
-void GLAPIENTRY gl_dispatch_stub_811(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
-void GLAPIENTRY gl_dispatch_stub_812(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
-void GLAPIENTRY gl_dispatch_stub_813(GLuint id, GLenum pname, GLint64EXT * params);
-void GLAPIENTRY gl_dispatch_stub_814(GLuint id, GLenum pname, GLuint64EXT * params);
+void GLAPIENTRY gl_dispatch_stub_590(GLenum pname, GLfloat * params);
+void GLAPIENTRY gl_dispatch_stub_591(GLenum pname, GLint * params);
+void GLAPIENTRY gl_dispatch_stub_592(GLenum pname, GLfloat param);
+void GLAPIENTRY gl_dispatch_stub_593(GLenum pname, const GLfloat * params);
+void GLAPIENTRY gl_dispatch_stub_594(GLenum pname, GLint param);
+void GLAPIENTRY gl_dispatch_stub_595(GLenum pname, const GLint * params);
+void GLAPIENTRY gl_dispatch_stub_596(GLclampf value, GLboolean invert);
+void GLAPIENTRY gl_dispatch_stub_597(GLenum pattern);
+void GLAPIENTRY gl_dispatch_stub_608(GLenum pname, GLdouble * params);
+void GLAPIENTRY gl_dispatch_stub_609(GLenum pname, GLfloat * params);
+void GLAPIENTRY gl_dispatch_stub_634(GLenum mode);
+void GLAPIENTRY gl_dispatch_stub_676(const GLenum * mode, const GLint * first, const GLsizei * count, GLsizei primcount, GLint modestride);
+void GLAPIENTRY gl_dispatch_stub_677(const GLenum * mode, const GLsizei * count, GLenum type, const GLvoid * const * indices, GLsizei primcount, GLint modestride);
+void GLAPIENTRY gl_dispatch_stub_678(GLsizei n, const GLuint * fences);
+void GLAPIENTRY gl_dispatch_stub_679(GLuint fence);
+void GLAPIENTRY gl_dispatch_stub_680(GLsizei n, GLuint * fences);
+void GLAPIENTRY gl_dispatch_stub_681(GLuint fence, GLenum pname, GLint * params);
+GLboolean GLAPIENTRY gl_dispatch_stub_682(GLuint fence);
+void GLAPIENTRY gl_dispatch_stub_683(GLuint fence, GLenum condition);
+GLboolean GLAPIENTRY gl_dispatch_stub_684(GLuint fence);
+void GLAPIENTRY gl_dispatch_stub_765(GLenum face);
+void GLAPIENTRY gl_dispatch_stub_766(GLuint array);
+void GLAPIENTRY gl_dispatch_stub_767(GLsizei n, const GLuint * arrays);
+void GLAPIENTRY gl_dispatch_stub_768(GLsizei n, GLuint * arrays);
+GLboolean GLAPIENTRY gl_dispatch_stub_769(GLuint array);
+void GLAPIENTRY gl_dispatch_stub_776(GLclampd zmin, GLclampd zmax);
+void GLAPIENTRY gl_dispatch_stub_777(GLenum modeRGB, GLenum modeA);
+void GLAPIENTRY gl_dispatch_stub_795(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+void GLAPIENTRY gl_dispatch_stub_796(GLenum target, GLenum pname, GLint param);
+void GLAPIENTRY gl_dispatch_stub_797(GLenum target, GLintptr offset, GLsizeiptr size);
+void GLAPIENTRY gl_dispatch_stub_815(GLenum target, GLenum pname, GLvoid ** params);
+void GLAPIENTRY gl_dispatch_stub_816(GLenum target, GLsizei length, GLvoid * pointer);
+void GLAPIENTRY gl_dispatch_stub_820(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+void GLAPIENTRY gl_dispatch_stub_821(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
+void GLAPIENTRY gl_dispatch_stub_822(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
+void GLAPIENTRY gl_dispatch_stub_823(GLuint id, GLenum pname, GLint64EXT * params);
+void GLAPIENTRY gl_dispatch_stub_824(GLuint id, GLenum pname, GLuint64EXT * params);
 #endif /* defined(NEED_FUNCTION_POINTER) || defined(GLX_INDIRECT_RENDERING) */
 
 static const glprocs_table_t static_functions[] = {
@@ -1856,571 +1866,581 @@ static const glprocs_table_t static_functions[] = {
     NAME_FUNC_OFFSET( 8957, glGetAttribLocationARB, glGetAttribLocationARB, NULL, _gloffset_GetAttribLocationARB),
     NAME_FUNC_OFFSET( 8980, glDrawBuffersARB, glDrawBuffersARB, NULL, _gloffset_DrawBuffersARB),
     NAME_FUNC_OFFSET( 8997, glRenderbufferStorageMultisample, glRenderbufferStorageMultisample, NULL, _gloffset_RenderbufferStorageMultisample),
-    NAME_FUNC_OFFSET( 9030, glFlushMappedBufferRange, glFlushMappedBufferRange, NULL, _gloffset_FlushMappedBufferRange),
-    NAME_FUNC_OFFSET( 9055, glMapBufferRange, glMapBufferRange, NULL, _gloffset_MapBufferRange),
-    NAME_FUNC_OFFSET( 9072, glBindVertexArray, glBindVertexArray, NULL, _gloffset_BindVertexArray),
-    NAME_FUNC_OFFSET( 9090, glGenVertexArrays, glGenVertexArrays, NULL, _gloffset_GenVertexArrays),
-    NAME_FUNC_OFFSET( 9108, glCopyBufferSubData, glCopyBufferSubData, NULL, _gloffset_CopyBufferSubData),
-    NAME_FUNC_OFFSET( 9128, glClientWaitSync, glClientWaitSync, NULL, _gloffset_ClientWaitSync),
-    NAME_FUNC_OFFSET( 9145, glDeleteSync, glDeleteSync, NULL, _gloffset_DeleteSync),
-    NAME_FUNC_OFFSET( 9158, glFenceSync, glFenceSync, NULL, _gloffset_FenceSync),
-    NAME_FUNC_OFFSET( 9170, glGetInteger64v, glGetInteger64v, NULL, _gloffset_GetInteger64v),
-    NAME_FUNC_OFFSET( 9186, glGetSynciv, glGetSynciv, NULL, _gloffset_GetSynciv),
-    NAME_FUNC_OFFSET( 9198, glIsSync, glIsSync, NULL, _gloffset_IsSync),
-    NAME_FUNC_OFFSET( 9207, glWaitSync, glWaitSync, NULL, _gloffset_WaitSync),
-    NAME_FUNC_OFFSET( 9218, glDrawElementsBaseVertex, glDrawElementsBaseVertex, NULL, _gloffset_DrawElementsBaseVertex),
-    NAME_FUNC_OFFSET( 9243, glDrawRangeElementsBaseVertex, glDrawRangeElementsBaseVertex, NULL, _gloffset_DrawRangeElementsBaseVertex),
-    NAME_FUNC_OFFSET( 9273, glMultiDrawElementsBaseVertex, glMultiDrawElementsBaseVertex, NULL, _gloffset_MultiDrawElementsBaseVertex),
-    NAME_FUNC_OFFSET( 9303, glPolygonOffsetEXT, glPolygonOffsetEXT, NULL, _gloffset_PolygonOffsetEXT),
-    NAME_FUNC_OFFSET( 9322, gl_dispatch_stub_580, gl_dispatch_stub_580, NULL, _gloffset_GetPixelTexGenParameterfvSGIS),
-    NAME_FUNC_OFFSET( 9354, gl_dispatch_stub_581, gl_dispatch_stub_581, NULL, _gloffset_GetPixelTexGenParameterivSGIS),
-    NAME_FUNC_OFFSET( 9386, gl_dispatch_stub_582, gl_dispatch_stub_582, NULL, _gloffset_PixelTexGenParameterfSGIS),
-    NAME_FUNC_OFFSET( 9414, gl_dispatch_stub_583, gl_dispatch_stub_583, NULL, _gloffset_PixelTexGenParameterfvSGIS),
-    NAME_FUNC_OFFSET( 9443, gl_dispatch_stub_584, gl_dispatch_stub_584, NULL, _gloffset_PixelTexGenParameteriSGIS),
-    NAME_FUNC_OFFSET( 9471, gl_dispatch_stub_585, gl_dispatch_stub_585, NULL, _gloffset_PixelTexGenParameterivSGIS),
-    NAME_FUNC_OFFSET( 9500, gl_dispatch_stub_586, gl_dispatch_stub_586, NULL, _gloffset_SampleMaskSGIS),
-    NAME_FUNC_OFFSET( 9517, gl_dispatch_stub_587, gl_dispatch_stub_587, NULL, _gloffset_SamplePatternSGIS),
-    NAME_FUNC_OFFSET( 9537, glColorPointerEXT, glColorPointerEXT, NULL, _gloffset_ColorPointerEXT),
-    NAME_FUNC_OFFSET( 9555, glEdgeFlagPointerEXT, glEdgeFlagPointerEXT, NULL, _gloffset_EdgeFlagPointerEXT),
-    NAME_FUNC_OFFSET( 9576, glIndexPointerEXT, glIndexPointerEXT, NULL, _gloffset_IndexPointerEXT),
-    NAME_FUNC_OFFSET( 9594, glNormalPointerEXT, glNormalPointerEXT, NULL, _gloffset_NormalPointerEXT),
-    NAME_FUNC_OFFSET( 9613, glTexCoordPointerEXT, glTexCoordPointerEXT, NULL, _gloffset_TexCoordPointerEXT),
-    NAME_FUNC_OFFSET( 9634, glVertexPointerEXT, glVertexPointerEXT, NULL, _gloffset_VertexPointerEXT),
-    NAME_FUNC_OFFSET( 9653, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
-    NAME_FUNC_OFFSET( 9674, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
-    NAME_FUNC_OFFSET( 9696, glLockArraysEXT, glLockArraysEXT, NULL, _gloffset_LockArraysEXT),
-    NAME_FUNC_OFFSET( 9712, glUnlockArraysEXT, glUnlockArraysEXT, NULL, _gloffset_UnlockArraysEXT),
-    NAME_FUNC_OFFSET( 9730, gl_dispatch_stub_598, gl_dispatch_stub_598, NULL, _gloffset_CullParameterdvEXT),
-    NAME_FUNC_OFFSET( 9751, gl_dispatch_stub_599, gl_dispatch_stub_599, NULL, _gloffset_CullParameterfvEXT),
-    NAME_FUNC_OFFSET( 9772, glSecondaryColor3bEXT, glSecondaryColor3bEXT, NULL, _gloffset_SecondaryColor3bEXT),
-    NAME_FUNC_OFFSET( 9794, glSecondaryColor3bvEXT, glSecondaryColor3bvEXT, NULL, _gloffset_SecondaryColor3bvEXT),
-    NAME_FUNC_OFFSET( 9817, glSecondaryColor3dEXT, glSecondaryColor3dEXT, NULL, _gloffset_SecondaryColor3dEXT),
-    NAME_FUNC_OFFSET( 9839, glSecondaryColor3dvEXT, glSecondaryColor3dvEXT, NULL, _gloffset_SecondaryColor3dvEXT),
-    NAME_FUNC_OFFSET( 9862, glSecondaryColor3fEXT, glSecondaryColor3fEXT, NULL, _gloffset_SecondaryColor3fEXT),
-    NAME_FUNC_OFFSET( 9884, glSecondaryColor3fvEXT, glSecondaryColor3fvEXT, NULL, _gloffset_SecondaryColor3fvEXT),
-    NAME_FUNC_OFFSET( 9907, glSecondaryColor3iEXT, glSecondaryColor3iEXT, NULL, _gloffset_SecondaryColor3iEXT),
-    NAME_FUNC_OFFSET( 9929, glSecondaryColor3ivEXT, glSecondaryColor3ivEXT, NULL, _gloffset_SecondaryColor3ivEXT),
-    NAME_FUNC_OFFSET( 9952, glSecondaryColor3sEXT, glSecondaryColor3sEXT, NULL, _gloffset_SecondaryColor3sEXT),
-    NAME_FUNC_OFFSET( 9974, glSecondaryColor3svEXT, glSecondaryColor3svEXT, NULL, _gloffset_SecondaryColor3svEXT),
-    NAME_FUNC_OFFSET( 9997, glSecondaryColor3ubEXT, glSecondaryColor3ubEXT, NULL, _gloffset_SecondaryColor3ubEXT),
-    NAME_FUNC_OFFSET(10020, glSecondaryColor3ubvEXT, glSecondaryColor3ubvEXT, NULL, _gloffset_SecondaryColor3ubvEXT),
-    NAME_FUNC_OFFSET(10044, glSecondaryColor3uiEXT, glSecondaryColor3uiEXT, NULL, _gloffset_SecondaryColor3uiEXT),
-    NAME_FUNC_OFFSET(10067, glSecondaryColor3uivEXT, glSecondaryColor3uivEXT, NULL, _gloffset_SecondaryColor3uivEXT),
-    NAME_FUNC_OFFSET(10091, glSecondaryColor3usEXT, glSecondaryColor3usEXT, NULL, _gloffset_SecondaryColor3usEXT),
-    NAME_FUNC_OFFSET(10114, glSecondaryColor3usvEXT, glSecondaryColor3usvEXT, NULL, _gloffset_SecondaryColor3usvEXT),
-    NAME_FUNC_OFFSET(10138, glSecondaryColorPointerEXT, glSecondaryColorPointerEXT, NULL, _gloffset_SecondaryColorPointerEXT),
-    NAME_FUNC_OFFSET(10165, glMultiDrawArraysEXT, glMultiDrawArraysEXT, NULL, _gloffset_MultiDrawArraysEXT),
-    NAME_FUNC_OFFSET(10186, glMultiDrawElementsEXT, glMultiDrawElementsEXT, NULL, _gloffset_MultiDrawElementsEXT),
-    NAME_FUNC_OFFSET(10209, glFogCoordPointerEXT, glFogCoordPointerEXT, NULL, _gloffset_FogCoordPointerEXT),
-    NAME_FUNC_OFFSET(10230, glFogCoorddEXT, glFogCoorddEXT, NULL, _gloffset_FogCoorddEXT),
-    NAME_FUNC_OFFSET(10245, glFogCoorddvEXT, glFogCoorddvEXT, NULL, _gloffset_FogCoorddvEXT),
-    NAME_FUNC_OFFSET(10261, glFogCoordfEXT, glFogCoordfEXT, NULL, _gloffset_FogCoordfEXT),
-    NAME_FUNC_OFFSET(10276, glFogCoordfvEXT, glFogCoordfvEXT, NULL, _gloffset_FogCoordfvEXT),
-    NAME_FUNC_OFFSET(10292, gl_dispatch_stub_624, gl_dispatch_stub_624, NULL, _gloffset_PixelTexGenSGIX),
-    NAME_FUNC_OFFSET(10310, glBlendFuncSeparateEXT, glBlendFuncSeparateEXT, NULL, _gloffset_BlendFuncSeparateEXT),
-    NAME_FUNC_OFFSET(10333, glFlushVertexArrayRangeNV, glFlushVertexArrayRangeNV, NULL, _gloffset_FlushVertexArrayRangeNV),
-    NAME_FUNC_OFFSET(10359, glVertexArrayRangeNV, glVertexArrayRangeNV, NULL, _gloffset_VertexArrayRangeNV),
-    NAME_FUNC_OFFSET(10380, glCombinerInputNV, glCombinerInputNV, NULL, _gloffset_CombinerInputNV),
-    NAME_FUNC_OFFSET(10398, glCombinerOutputNV, glCombinerOutputNV, NULL, _gloffset_CombinerOutputNV),
-    NAME_FUNC_OFFSET(10417, glCombinerParameterfNV, glCombinerParameterfNV, NULL, _gloffset_CombinerParameterfNV),
-    NAME_FUNC_OFFSET(10440, glCombinerParameterfvNV, glCombinerParameterfvNV, NULL, _gloffset_CombinerParameterfvNV),
-    NAME_FUNC_OFFSET(10464, glCombinerParameteriNV, glCombinerParameteriNV, NULL, _gloffset_CombinerParameteriNV),
-    NAME_FUNC_OFFSET(10487, glCombinerParameterivNV, glCombinerParameterivNV, NULL, _gloffset_CombinerParameterivNV),
-    NAME_FUNC_OFFSET(10511, glFinalCombinerInputNV, glFinalCombinerInputNV, NULL, _gloffset_FinalCombinerInputNV),
-    NAME_FUNC_OFFSET(10534, glGetCombinerInputParameterfvNV, glGetCombinerInputParameterfvNV, NULL, _gloffset_GetCombinerInputParameterfvNV),
-    NAME_FUNC_OFFSET(10566, glGetCombinerInputParameterivNV, glGetCombinerInputParameterivNV, NULL, _gloffset_GetCombinerInputParameterivNV),
-    NAME_FUNC_OFFSET(10598, glGetCombinerOutputParameterfvNV, glGetCombinerOutputParameterfvNV, NULL, _gloffset_GetCombinerOutputParameterfvNV),
-    NAME_FUNC_OFFSET(10631, glGetCombinerOutputParameterivNV, glGetCombinerOutputParameterivNV, NULL, _gloffset_GetCombinerOutputParameterivNV),
-    NAME_FUNC_OFFSET(10664, glGetFinalCombinerInputParameterfvNV, glGetFinalCombinerInputParameterfvNV, NULL, _gloffset_GetFinalCombinerInputParameterfvNV),
-    NAME_FUNC_OFFSET(10701, glGetFinalCombinerInputParameterivNV, glGetFinalCombinerInputParameterivNV, NULL, _gloffset_GetFinalCombinerInputParameterivNV),
-    NAME_FUNC_OFFSET(10738, glResizeBuffersMESA, glResizeBuffersMESA, NULL, _gloffset_ResizeBuffersMESA),
-    NAME_FUNC_OFFSET(10758, glWindowPos2dMESA, glWindowPos2dMESA, NULL, _gloffset_WindowPos2dMESA),
-    NAME_FUNC_OFFSET(10776, glWindowPos2dvMESA, glWindowPos2dvMESA, NULL, _gloffset_WindowPos2dvMESA),
-    NAME_FUNC_OFFSET(10795, glWindowPos2fMESA, glWindowPos2fMESA, NULL, _gloffset_WindowPos2fMESA),
-    NAME_FUNC_OFFSET(10813, glWindowPos2fvMESA, glWindowPos2fvMESA, NULL, _gloffset_WindowPos2fvMESA),
-    NAME_FUNC_OFFSET(10832, glWindowPos2iMESA, glWindowPos2iMESA, NULL, _gloffset_WindowPos2iMESA),
-    NAME_FUNC_OFFSET(10850, glWindowPos2ivMESA, glWindowPos2ivMESA, NULL, _gloffset_WindowPos2ivMESA),
-    NAME_FUNC_OFFSET(10869, glWindowPos2sMESA, glWindowPos2sMESA, NULL, _gloffset_WindowPos2sMESA),
-    NAME_FUNC_OFFSET(10887, glWindowPos2svMESA, glWindowPos2svMESA, NULL, _gloffset_WindowPos2svMESA),
-    NAME_FUNC_OFFSET(10906, glWindowPos3dMESA, glWindowPos3dMESA, NULL, _gloffset_WindowPos3dMESA),
-    NAME_FUNC_OFFSET(10924, glWindowPos3dvMESA, glWindowPos3dvMESA, NULL, _gloffset_WindowPos3dvMESA),
-    NAME_FUNC_OFFSET(10943, glWindowPos3fMESA, glWindowPos3fMESA, NULL, _gloffset_WindowPos3fMESA),
-    NAME_FUNC_OFFSET(10961, glWindowPos3fvMESA, glWindowPos3fvMESA, NULL, _gloffset_WindowPos3fvMESA),
-    NAME_FUNC_OFFSET(10980, glWindowPos3iMESA, glWindowPos3iMESA, NULL, _gloffset_WindowPos3iMESA),
-    NAME_FUNC_OFFSET(10998, glWindowPos3ivMESA, glWindowPos3ivMESA, NULL, _gloffset_WindowPos3ivMESA),
-    NAME_FUNC_OFFSET(11017, glWindowPos3sMESA, glWindowPos3sMESA, NULL, _gloffset_WindowPos3sMESA),
-    NAME_FUNC_OFFSET(11035, glWindowPos3svMESA, glWindowPos3svMESA, NULL, _gloffset_WindowPos3svMESA),
-    NAME_FUNC_OFFSET(11054, glWindowPos4dMESA, glWindowPos4dMESA, NULL, _gloffset_WindowPos4dMESA),
-    NAME_FUNC_OFFSET(11072, glWindowPos4dvMESA, glWindowPos4dvMESA, NULL, _gloffset_WindowPos4dvMESA),
-    NAME_FUNC_OFFSET(11091, glWindowPos4fMESA, glWindowPos4fMESA, NULL, _gloffset_WindowPos4fMESA),
-    NAME_FUNC_OFFSET(11109, glWindowPos4fvMESA, glWindowPos4fvMESA, NULL, _gloffset_WindowPos4fvMESA),
-    NAME_FUNC_OFFSET(11128, glWindowPos4iMESA, glWindowPos4iMESA, NULL, _gloffset_WindowPos4iMESA),
-    NAME_FUNC_OFFSET(11146, glWindowPos4ivMESA, glWindowPos4ivMESA, NULL, _gloffset_WindowPos4ivMESA),
-    NAME_FUNC_OFFSET(11165, glWindowPos4sMESA, glWindowPos4sMESA, NULL, _gloffset_WindowPos4sMESA),
-    NAME_FUNC_OFFSET(11183, glWindowPos4svMESA, glWindowPos4svMESA, NULL, _gloffset_WindowPos4svMESA),
-    NAME_FUNC_OFFSET(11202, gl_dispatch_stub_666, gl_dispatch_stub_666, NULL, _gloffset_MultiModeDrawArraysIBM),
-    NAME_FUNC_OFFSET(11227, gl_dispatch_stub_667, gl_dispatch_stub_667, NULL, _gloffset_MultiModeDrawElementsIBM),
-    NAME_FUNC_OFFSET(11254, gl_dispatch_stub_668, gl_dispatch_stub_668, NULL, _gloffset_DeleteFencesNV),
-    NAME_FUNC_OFFSET(11271, gl_dispatch_stub_669, gl_dispatch_stub_669, NULL, _gloffset_FinishFenceNV),
-    NAME_FUNC_OFFSET(11287, gl_dispatch_stub_670, gl_dispatch_stub_670, NULL, _gloffset_GenFencesNV),
-    NAME_FUNC_OFFSET(11301, gl_dispatch_stub_671, gl_dispatch_stub_671, NULL, _gloffset_GetFenceivNV),
-    NAME_FUNC_OFFSET(11316, gl_dispatch_stub_672, gl_dispatch_stub_672, NULL, _gloffset_IsFenceNV),
-    NAME_FUNC_OFFSET(11328, gl_dispatch_stub_673, gl_dispatch_stub_673, NULL, _gloffset_SetFenceNV),
-    NAME_FUNC_OFFSET(11341, gl_dispatch_stub_674, gl_dispatch_stub_674, NULL, _gloffset_TestFenceNV),
-    NAME_FUNC_OFFSET(11355, glAreProgramsResidentNV, glAreProgramsResidentNV, NULL, _gloffset_AreProgramsResidentNV),
-    NAME_FUNC_OFFSET(11379, glBindProgramNV, glBindProgramNV, NULL, _gloffset_BindProgramNV),
-    NAME_FUNC_OFFSET(11395, glDeleteProgramsNV, glDeleteProgramsNV, NULL, _gloffset_DeleteProgramsNV),
-    NAME_FUNC_OFFSET(11414, glExecuteProgramNV, glExecuteProgramNV, NULL, _gloffset_ExecuteProgramNV),
-    NAME_FUNC_OFFSET(11433, glGenProgramsNV, glGenProgramsNV, NULL, _gloffset_GenProgramsNV),
-    NAME_FUNC_OFFSET(11449, glGetProgramParameterdvNV, glGetProgramParameterdvNV, NULL, _gloffset_GetProgramParameterdvNV),
-    NAME_FUNC_OFFSET(11475, glGetProgramParameterfvNV, glGetProgramParameterfvNV, NULL, _gloffset_GetProgramParameterfvNV),
-    NAME_FUNC_OFFSET(11501, glGetProgramStringNV, glGetProgramStringNV, NULL, _gloffset_GetProgramStringNV),
-    NAME_FUNC_OFFSET(11522, glGetProgramivNV, glGetProgramivNV, NULL, _gloffset_GetProgramivNV),
-    NAME_FUNC_OFFSET(11539, glGetTrackMatrixivNV, glGetTrackMatrixivNV, NULL, _gloffset_GetTrackMatrixivNV),
-    NAME_FUNC_OFFSET(11560, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV),
-    NAME_FUNC_OFFSET(11588, glGetVertexAttribdvNV, glGetVertexAttribdvNV, NULL, _gloffset_GetVertexAttribdvNV),
-    NAME_FUNC_OFFSET(11610, glGetVertexAttribfvNV, glGetVertexAttribfvNV, NULL, _gloffset_GetVertexAttribfvNV),
-    NAME_FUNC_OFFSET(11632, glGetVertexAttribivNV, glGetVertexAttribivNV, NULL, _gloffset_GetVertexAttribivNV),
-    NAME_FUNC_OFFSET(11654, glIsProgramNV, glIsProgramNV, NULL, _gloffset_IsProgramNV),
-    NAME_FUNC_OFFSET(11668, glLoadProgramNV, glLoadProgramNV, NULL, _gloffset_LoadProgramNV),
-    NAME_FUNC_OFFSET(11684, glProgramParameters4dvNV, glProgramParameters4dvNV, NULL, _gloffset_ProgramParameters4dvNV),
-    NAME_FUNC_OFFSET(11709, glProgramParameters4fvNV, glProgramParameters4fvNV, NULL, _gloffset_ProgramParameters4fvNV),
-    NAME_FUNC_OFFSET(11734, glRequestResidentProgramsNV, glRequestResidentProgramsNV, NULL, _gloffset_RequestResidentProgramsNV),
-    NAME_FUNC_OFFSET(11762, glTrackMatrixNV, glTrackMatrixNV, NULL, _gloffset_TrackMatrixNV),
-    NAME_FUNC_OFFSET(11778, glVertexAttrib1dNV, glVertexAttrib1dNV, NULL, _gloffset_VertexAttrib1dNV),
-    NAME_FUNC_OFFSET(11797, glVertexAttrib1dvNV, glVertexAttrib1dvNV, NULL, _gloffset_VertexAttrib1dvNV),
-    NAME_FUNC_OFFSET(11817, glVertexAttrib1fNV, glVertexAttrib1fNV, NULL, _gloffset_VertexAttrib1fNV),
-    NAME_FUNC_OFFSET(11836, glVertexAttrib1fvNV, glVertexAttrib1fvNV, NULL, _gloffset_VertexAttrib1fvNV),
-    NAME_FUNC_OFFSET(11856, glVertexAttrib1sNV, glVertexAttrib1sNV, NULL, _gloffset_VertexAttrib1sNV),
-    NAME_FUNC_OFFSET(11875, glVertexAttrib1svNV, glVertexAttrib1svNV, NULL, _gloffset_VertexAttrib1svNV),
-    NAME_FUNC_OFFSET(11895, glVertexAttrib2dNV, glVertexAttrib2dNV, NULL, _gloffset_VertexAttrib2dNV),
-    NAME_FUNC_OFFSET(11914, glVertexAttrib2dvNV, glVertexAttrib2dvNV, NULL, _gloffset_VertexAttrib2dvNV),
-    NAME_FUNC_OFFSET(11934, glVertexAttrib2fNV, glVertexAttrib2fNV, NULL, _gloffset_VertexAttrib2fNV),
-    NAME_FUNC_OFFSET(11953, glVertexAttrib2fvNV, glVertexAttrib2fvNV, NULL, _gloffset_VertexAttrib2fvNV),
-    NAME_FUNC_OFFSET(11973, glVertexAttrib2sNV, glVertexAttrib2sNV, NULL, _gloffset_VertexAttrib2sNV),
-    NAME_FUNC_OFFSET(11992, glVertexAttrib2svNV, glVertexAttrib2svNV, NULL, _gloffset_VertexAttrib2svNV),
-    NAME_FUNC_OFFSET(12012, glVertexAttrib3dNV, glVertexAttrib3dNV, NULL, _gloffset_VertexAttrib3dNV),
-    NAME_FUNC_OFFSET(12031, glVertexAttrib3dvNV, glVertexAttrib3dvNV, NULL, _gloffset_VertexAttrib3dvNV),
-    NAME_FUNC_OFFSET(12051, glVertexAttrib3fNV, glVertexAttrib3fNV, NULL, _gloffset_VertexAttrib3fNV),
-    NAME_FUNC_OFFSET(12070, glVertexAttrib3fvNV, glVertexAttrib3fvNV, NULL, _gloffset_VertexAttrib3fvNV),
-    NAME_FUNC_OFFSET(12090, glVertexAttrib3sNV, glVertexAttrib3sNV, NULL, _gloffset_VertexAttrib3sNV),
-    NAME_FUNC_OFFSET(12109, glVertexAttrib3svNV, glVertexAttrib3svNV, NULL, _gloffset_VertexAttrib3svNV),
-    NAME_FUNC_OFFSET(12129, glVertexAttrib4dNV, glVertexAttrib4dNV, NULL, _gloffset_VertexAttrib4dNV),
-    NAME_FUNC_OFFSET(12148, glVertexAttrib4dvNV, glVertexAttrib4dvNV, NULL, _gloffset_VertexAttrib4dvNV),
-    NAME_FUNC_OFFSET(12168, glVertexAttrib4fNV, glVertexAttrib4fNV, NULL, _gloffset_VertexAttrib4fNV),
-    NAME_FUNC_OFFSET(12187, glVertexAttrib4fvNV, glVertexAttrib4fvNV, NULL, _gloffset_VertexAttrib4fvNV),
-    NAME_FUNC_OFFSET(12207, glVertexAttrib4sNV, glVertexAttrib4sNV, NULL, _gloffset_VertexAttrib4sNV),
-    NAME_FUNC_OFFSET(12226, glVertexAttrib4svNV, glVertexAttrib4svNV, NULL, _gloffset_VertexAttrib4svNV),
-    NAME_FUNC_OFFSET(12246, glVertexAttrib4ubNV, glVertexAttrib4ubNV, NULL, _gloffset_VertexAttrib4ubNV),
-    NAME_FUNC_OFFSET(12266, glVertexAttrib4ubvNV, glVertexAttrib4ubvNV, NULL, _gloffset_VertexAttrib4ubvNV),
-    NAME_FUNC_OFFSET(12287, glVertexAttribPointerNV, glVertexAttribPointerNV, NULL, _gloffset_VertexAttribPointerNV),
-    NAME_FUNC_OFFSET(12311, glVertexAttribs1dvNV, glVertexAttribs1dvNV, NULL, _gloffset_VertexAttribs1dvNV),
-    NAME_FUNC_OFFSET(12332, glVertexAttribs1fvNV, glVertexAttribs1fvNV, NULL, _gloffset_VertexAttribs1fvNV),
-    NAME_FUNC_OFFSET(12353, glVertexAttribs1svNV, glVertexAttribs1svNV, NULL, _gloffset_VertexAttribs1svNV),
-    NAME_FUNC_OFFSET(12374, glVertexAttribs2dvNV, glVertexAttribs2dvNV, NULL, _gloffset_VertexAttribs2dvNV),
-    NAME_FUNC_OFFSET(12395, glVertexAttribs2fvNV, glVertexAttribs2fvNV, NULL, _gloffset_VertexAttribs2fvNV),
-    NAME_FUNC_OFFSET(12416, glVertexAttribs2svNV, glVertexAttribs2svNV, NULL, _gloffset_VertexAttribs2svNV),
-    NAME_FUNC_OFFSET(12437, glVertexAttribs3dvNV, glVertexAttribs3dvNV, NULL, _gloffset_VertexAttribs3dvNV),
-    NAME_FUNC_OFFSET(12458, glVertexAttribs3fvNV, glVertexAttribs3fvNV, NULL, _gloffset_VertexAttribs3fvNV),
-    NAME_FUNC_OFFSET(12479, glVertexAttribs3svNV, glVertexAttribs3svNV, NULL, _gloffset_VertexAttribs3svNV),
-    NAME_FUNC_OFFSET(12500, glVertexAttribs4dvNV, glVertexAttribs4dvNV, NULL, _gloffset_VertexAttribs4dvNV),
-    NAME_FUNC_OFFSET(12521, glVertexAttribs4fvNV, glVertexAttribs4fvNV, NULL, _gloffset_VertexAttribs4fvNV),
-    NAME_FUNC_OFFSET(12542, glVertexAttribs4svNV, glVertexAttribs4svNV, NULL, _gloffset_VertexAttribs4svNV),
-    NAME_FUNC_OFFSET(12563, glVertexAttribs4ubvNV, glVertexAttribs4ubvNV, NULL, _gloffset_VertexAttribs4ubvNV),
-    NAME_FUNC_OFFSET(12585, glGetTexBumpParameterfvATI, glGetTexBumpParameterfvATI, NULL, _gloffset_GetTexBumpParameterfvATI),
-    NAME_FUNC_OFFSET(12612, glGetTexBumpParameterivATI, glGetTexBumpParameterivATI, NULL, _gloffset_GetTexBumpParameterivATI),
-    NAME_FUNC_OFFSET(12639, glTexBumpParameterfvATI, glTexBumpParameterfvATI, NULL, _gloffset_TexBumpParameterfvATI),
-    NAME_FUNC_OFFSET(12663, glTexBumpParameterivATI, glTexBumpParameterivATI, NULL, _gloffset_TexBumpParameterivATI),
-    NAME_FUNC_OFFSET(12687, glAlphaFragmentOp1ATI, glAlphaFragmentOp1ATI, NULL, _gloffset_AlphaFragmentOp1ATI),
-    NAME_FUNC_OFFSET(12709, glAlphaFragmentOp2ATI, glAlphaFragmentOp2ATI, NULL, _gloffset_AlphaFragmentOp2ATI),
-    NAME_FUNC_OFFSET(12731, glAlphaFragmentOp3ATI, glAlphaFragmentOp3ATI, NULL, _gloffset_AlphaFragmentOp3ATI),
-    NAME_FUNC_OFFSET(12753, glBeginFragmentShaderATI, glBeginFragmentShaderATI, NULL, _gloffset_BeginFragmentShaderATI),
-    NAME_FUNC_OFFSET(12778, glBindFragmentShaderATI, glBindFragmentShaderATI, NULL, _gloffset_BindFragmentShaderATI),
-    NAME_FUNC_OFFSET(12802, glColorFragmentOp1ATI, glColorFragmentOp1ATI, NULL, _gloffset_ColorFragmentOp1ATI),
-    NAME_FUNC_OFFSET(12824, glColorFragmentOp2ATI, glColorFragmentOp2ATI, NULL, _gloffset_ColorFragmentOp2ATI),
-    NAME_FUNC_OFFSET(12846, glColorFragmentOp3ATI, glColorFragmentOp3ATI, NULL, _gloffset_ColorFragmentOp3ATI),
-    NAME_FUNC_OFFSET(12868, glDeleteFragmentShaderATI, glDeleteFragmentShaderATI, NULL, _gloffset_DeleteFragmentShaderATI),
-    NAME_FUNC_OFFSET(12894, glEndFragmentShaderATI, glEndFragmentShaderATI, NULL, _gloffset_EndFragmentShaderATI),
-    NAME_FUNC_OFFSET(12917, glGenFragmentShadersATI, glGenFragmentShadersATI, NULL, _gloffset_GenFragmentShadersATI),
-    NAME_FUNC_OFFSET(12941, glPassTexCoordATI, glPassTexCoordATI, NULL, _gloffset_PassTexCoordATI),
-    NAME_FUNC_OFFSET(12959, glSampleMapATI, glSampleMapATI, NULL, _gloffset_SampleMapATI),
-    NAME_FUNC_OFFSET(12974, glSetFragmentShaderConstantATI, glSetFragmentShaderConstantATI, NULL, _gloffset_SetFragmentShaderConstantATI),
-    NAME_FUNC_OFFSET(13005, glPointParameteriNV, glPointParameteriNV, NULL, _gloffset_PointParameteriNV),
-    NAME_FUNC_OFFSET(13025, glPointParameterivNV, glPointParameterivNV, NULL, _gloffset_PointParameterivNV),
-    NAME_FUNC_OFFSET(13046, gl_dispatch_stub_755, gl_dispatch_stub_755, NULL, _gloffset_ActiveStencilFaceEXT),
-    NAME_FUNC_OFFSET(13069, gl_dispatch_stub_756, gl_dispatch_stub_756, NULL, _gloffset_BindVertexArrayAPPLE),
-    NAME_FUNC_OFFSET(13092, gl_dispatch_stub_757, gl_dispatch_stub_757, NULL, _gloffset_DeleteVertexArraysAPPLE),
-    NAME_FUNC_OFFSET(13118, gl_dispatch_stub_758, gl_dispatch_stub_758, NULL, _gloffset_GenVertexArraysAPPLE),
-    NAME_FUNC_OFFSET(13141, gl_dispatch_stub_759, gl_dispatch_stub_759, NULL, _gloffset_IsVertexArrayAPPLE),
-    NAME_FUNC_OFFSET(13162, glGetProgramNamedParameterdvNV, glGetProgramNamedParameterdvNV, NULL, _gloffset_GetProgramNamedParameterdvNV),
-    NAME_FUNC_OFFSET(13193, glGetProgramNamedParameterfvNV, glGetProgramNamedParameterfvNV, NULL, _gloffset_GetProgramNamedParameterfvNV),
-    NAME_FUNC_OFFSET(13224, glProgramNamedParameter4dNV, glProgramNamedParameter4dNV, NULL, _gloffset_ProgramNamedParameter4dNV),
-    NAME_FUNC_OFFSET(13252, glProgramNamedParameter4dvNV, glProgramNamedParameter4dvNV, NULL, _gloffset_ProgramNamedParameter4dvNV),
-    NAME_FUNC_OFFSET(13281, glProgramNamedParameter4fNV, glProgramNamedParameter4fNV, NULL, _gloffset_ProgramNamedParameter4fNV),
-    NAME_FUNC_OFFSET(13309, glProgramNamedParameter4fvNV, glProgramNamedParameter4fvNV, NULL, _gloffset_ProgramNamedParameter4fvNV),
-    NAME_FUNC_OFFSET(13338, gl_dispatch_stub_766, gl_dispatch_stub_766, NULL, _gloffset_DepthBoundsEXT),
-    NAME_FUNC_OFFSET(13355, gl_dispatch_stub_767, gl_dispatch_stub_767, NULL, _gloffset_BlendEquationSeparateEXT),
-    NAME_FUNC_OFFSET(13382, glBindFramebufferEXT, glBindFramebufferEXT, NULL, _gloffset_BindFramebufferEXT),
-    NAME_FUNC_OFFSET(13403, glBindRenderbufferEXT, glBindRenderbufferEXT, NULL, _gloffset_BindRenderbufferEXT),
-    NAME_FUNC_OFFSET(13425, glCheckFramebufferStatusEXT, glCheckFramebufferStatusEXT, NULL, _gloffset_CheckFramebufferStatusEXT),
-    NAME_FUNC_OFFSET(13453, glDeleteFramebuffersEXT, glDeleteFramebuffersEXT, NULL, _gloffset_DeleteFramebuffersEXT),
-    NAME_FUNC_OFFSET(13477, glDeleteRenderbuffersEXT, glDeleteRenderbuffersEXT, NULL, _gloffset_DeleteRenderbuffersEXT),
-    NAME_FUNC_OFFSET(13502, glFramebufferRenderbufferEXT, glFramebufferRenderbufferEXT, NULL, _gloffset_FramebufferRenderbufferEXT),
-    NAME_FUNC_OFFSET(13531, glFramebufferTexture1DEXT, glFramebufferTexture1DEXT, NULL, _gloffset_FramebufferTexture1DEXT),
-    NAME_FUNC_OFFSET(13557, glFramebufferTexture2DEXT, glFramebufferTexture2DEXT, NULL, _gloffset_FramebufferTexture2DEXT),
-    NAME_FUNC_OFFSET(13583, glFramebufferTexture3DEXT, glFramebufferTexture3DEXT, NULL, _gloffset_FramebufferTexture3DEXT),
-    NAME_FUNC_OFFSET(13609, glGenFramebuffersEXT, glGenFramebuffersEXT, NULL, _gloffset_GenFramebuffersEXT),
-    NAME_FUNC_OFFSET(13630, glGenRenderbuffersEXT, glGenRenderbuffersEXT, NULL, _gloffset_GenRenderbuffersEXT),
-    NAME_FUNC_OFFSET(13652, glGenerateMipmapEXT, glGenerateMipmapEXT, NULL, _gloffset_GenerateMipmapEXT),
-    NAME_FUNC_OFFSET(13672, glGetFramebufferAttachmentParameterivEXT, glGetFramebufferAttachmentParameterivEXT, NULL, _gloffset_GetFramebufferAttachmentParameterivEXT),
-    NAME_FUNC_OFFSET(13713, glGetRenderbufferParameterivEXT, glGetRenderbufferParameterivEXT, NULL, _gloffset_GetRenderbufferParameterivEXT),
-    NAME_FUNC_OFFSET(13745, glIsFramebufferEXT, glIsFramebufferEXT, NULL, _gloffset_IsFramebufferEXT),
-    NAME_FUNC_OFFSET(13764, glIsRenderbufferEXT, glIsRenderbufferEXT, NULL, _gloffset_IsRenderbufferEXT),
-    NAME_FUNC_OFFSET(13784, glRenderbufferStorageEXT, glRenderbufferStorageEXT, NULL, _gloffset_RenderbufferStorageEXT),
-    NAME_FUNC_OFFSET(13809, gl_dispatch_stub_785, gl_dispatch_stub_785, NULL, _gloffset_BlitFramebufferEXT),
-    NAME_FUNC_OFFSET(13830, gl_dispatch_stub_786, gl_dispatch_stub_786, NULL, _gloffset_BufferParameteriAPPLE),
-    NAME_FUNC_OFFSET(13854, gl_dispatch_stub_787, gl_dispatch_stub_787, NULL, _gloffset_FlushMappedBufferRangeAPPLE),
-    NAME_FUNC_OFFSET(13884, glFramebufferTextureLayerEXT, glFramebufferTextureLayerEXT, NULL, _gloffset_FramebufferTextureLayerEXT),
-    NAME_FUNC_OFFSET(13913, glColorMaskIndexedEXT, glColorMaskIndexedEXT, NULL, _gloffset_ColorMaskIndexedEXT),
-    NAME_FUNC_OFFSET(13935, glDisableIndexedEXT, glDisableIndexedEXT, NULL, _gloffset_DisableIndexedEXT),
-    NAME_FUNC_OFFSET(13955, glEnableIndexedEXT, glEnableIndexedEXT, NULL, _gloffset_EnableIndexedEXT),
-    NAME_FUNC_OFFSET(13974, glGetBooleanIndexedvEXT, glGetBooleanIndexedvEXT, NULL, _gloffset_GetBooleanIndexedvEXT),
-    NAME_FUNC_OFFSET(13998, glGetIntegerIndexedvEXT, glGetIntegerIndexedvEXT, NULL, _gloffset_GetIntegerIndexedvEXT),
-    NAME_FUNC_OFFSET(14022, glIsEnabledIndexedEXT, glIsEnabledIndexedEXT, NULL, _gloffset_IsEnabledIndexedEXT),
-    NAME_FUNC_OFFSET(14044, glBeginConditionalRenderNV, glBeginConditionalRenderNV, NULL, _gloffset_BeginConditionalRenderNV),
-    NAME_FUNC_OFFSET(14071, glEndConditionalRenderNV, glEndConditionalRenderNV, NULL, _gloffset_EndConditionalRenderNV),
-    NAME_FUNC_OFFSET(14096, glBeginTransformFeedbackEXT, glBeginTransformFeedbackEXT, NULL, _gloffset_BeginTransformFeedbackEXT),
-    NAME_FUNC_OFFSET(14124, glBindBufferBaseEXT, glBindBufferBaseEXT, NULL, _gloffset_BindBufferBaseEXT),
-    NAME_FUNC_OFFSET(14144, glBindBufferOffsetEXT, glBindBufferOffsetEXT, NULL, _gloffset_BindBufferOffsetEXT),
-    NAME_FUNC_OFFSET(14166, glBindBufferRangeEXT, glBindBufferRangeEXT, NULL, _gloffset_BindBufferRangeEXT),
-    NAME_FUNC_OFFSET(14187, glEndTransformFeedbackEXT, glEndTransformFeedbackEXT, NULL, _gloffset_EndTransformFeedbackEXT),
-    NAME_FUNC_OFFSET(14213, glGetTransformFeedbackVaryingEXT, glGetTransformFeedbackVaryingEXT, NULL, _gloffset_GetTransformFeedbackVaryingEXT),
-    NAME_FUNC_OFFSET(14246, glTransformFeedbackVaryingsEXT, glTransformFeedbackVaryingsEXT, NULL, _gloffset_TransformFeedbackVaryingsEXT),
-    NAME_FUNC_OFFSET(14277, glProvokingVertexEXT, glProvokingVertexEXT, NULL, _gloffset_ProvokingVertexEXT),
-    NAME_FUNC_OFFSET(14298, gl_dispatch_stub_805, gl_dispatch_stub_805, NULL, _gloffset_GetTexParameterPointervAPPLE),
-    NAME_FUNC_OFFSET(14329, gl_dispatch_stub_806, gl_dispatch_stub_806, NULL, _gloffset_TextureRangeAPPLE),
-    NAME_FUNC_OFFSET(14349, glGetObjectParameterivAPPLE, glGetObjectParameterivAPPLE, NULL, _gloffset_GetObjectParameterivAPPLE),
-    NAME_FUNC_OFFSET(14377, glObjectPurgeableAPPLE, glObjectPurgeableAPPLE, NULL, _gloffset_ObjectPurgeableAPPLE),
-    NAME_FUNC_OFFSET(14400, glObjectUnpurgeableAPPLE, glObjectUnpurgeableAPPLE, NULL, _gloffset_ObjectUnpurgeableAPPLE),
-    NAME_FUNC_OFFSET(14425, gl_dispatch_stub_810, gl_dispatch_stub_810, NULL, _gloffset_StencilFuncSeparateATI),
-    NAME_FUNC_OFFSET(14450, gl_dispatch_stub_811, gl_dispatch_stub_811, NULL, _gloffset_ProgramEnvParameters4fvEXT),
-    NAME_FUNC_OFFSET(14479, gl_dispatch_stub_812, gl_dispatch_stub_812, NULL, _gloffset_ProgramLocalParameters4fvEXT),
-    NAME_FUNC_OFFSET(14510, gl_dispatch_stub_813, gl_dispatch_stub_813, NULL, _gloffset_GetQueryObjecti64vEXT),
-    NAME_FUNC_OFFSET(14534, gl_dispatch_stub_814, gl_dispatch_stub_814, NULL, _gloffset_GetQueryObjectui64vEXT),
-    NAME_FUNC_OFFSET(14559, glEGLImageTargetRenderbufferStorageOES, glEGLImageTargetRenderbufferStorageOES, NULL, _gloffset_EGLImageTargetRenderbufferStorageOES),
-    NAME_FUNC_OFFSET(14598, glEGLImageTargetTexture2DOES, glEGLImageTargetTexture2DOES, NULL, _gloffset_EGLImageTargetTexture2DOES),
-    NAME_FUNC_OFFSET(14627, glArrayElement, glArrayElement, NULL, _gloffset_ArrayElement),
-    NAME_FUNC_OFFSET(14645, glBindTexture, glBindTexture, NULL, _gloffset_BindTexture),
-    NAME_FUNC_OFFSET(14662, glDrawArrays, glDrawArrays, NULL, _gloffset_DrawArrays),
-    NAME_FUNC_OFFSET(14678, glAreTexturesResident, glAreTexturesResidentEXT, glAreTexturesResidentEXT, _gloffset_AreTexturesResident),
-    NAME_FUNC_OFFSET(14703, glCopyTexImage1D, glCopyTexImage1D, NULL, _gloffset_CopyTexImage1D),
-    NAME_FUNC_OFFSET(14723, glCopyTexImage2D, glCopyTexImage2D, NULL, _gloffset_CopyTexImage2D),
-    NAME_FUNC_OFFSET(14743, glCopyTexSubImage1D, glCopyTexSubImage1D, NULL, _gloffset_CopyTexSubImage1D),
-    NAME_FUNC_OFFSET(14766, glCopyTexSubImage2D, glCopyTexSubImage2D, NULL, _gloffset_CopyTexSubImage2D),
-    NAME_FUNC_OFFSET(14789, glDeleteTextures, glDeleteTexturesEXT, glDeleteTexturesEXT, _gloffset_DeleteTextures),
-    NAME_FUNC_OFFSET(14809, glGenTextures, glGenTexturesEXT, glGenTexturesEXT, _gloffset_GenTextures),
-    NAME_FUNC_OFFSET(14826, glGetPointerv, glGetPointerv, NULL, _gloffset_GetPointerv),
-    NAME_FUNC_OFFSET(14843, glIsTexture, glIsTextureEXT, glIsTextureEXT, _gloffset_IsTexture),
-    NAME_FUNC_OFFSET(14858, glPrioritizeTextures, glPrioritizeTextures, NULL, _gloffset_PrioritizeTextures),
-    NAME_FUNC_OFFSET(14882, glTexSubImage1D, glTexSubImage1D, NULL, _gloffset_TexSubImage1D),
-    NAME_FUNC_OFFSET(14901, glTexSubImage2D, glTexSubImage2D, NULL, _gloffset_TexSubImage2D),
-    NAME_FUNC_OFFSET(14920, glBlendColor, glBlendColor, NULL, _gloffset_BlendColor),
-    NAME_FUNC_OFFSET(14936, glBlendEquation, glBlendEquation, NULL, _gloffset_BlendEquation),
-    NAME_FUNC_OFFSET(14955, glDrawRangeElements, glDrawRangeElements, NULL, _gloffset_DrawRangeElements),
-    NAME_FUNC_OFFSET(14978, glColorTable, glColorTable, NULL, _gloffset_ColorTable),
-    NAME_FUNC_OFFSET(14994, glColorTable, glColorTable, NULL, _gloffset_ColorTable),
-    NAME_FUNC_OFFSET(15010, glColorTableParameterfv, glColorTableParameterfv, NULL, _gloffset_ColorTableParameterfv),
-    NAME_FUNC_OFFSET(15037, glColorTableParameteriv, glColorTableParameteriv, NULL, _gloffset_ColorTableParameteriv),
-    NAME_FUNC_OFFSET(15064, glCopyColorTable, glCopyColorTable, NULL, _gloffset_CopyColorTable),
-    NAME_FUNC_OFFSET(15084, glGetColorTable, glGetColorTableEXT, glGetColorTableEXT, _gloffset_GetColorTable),
-    NAME_FUNC_OFFSET(15103, glGetColorTable, glGetColorTableEXT, glGetColorTableEXT, _gloffset_GetColorTable),
-    NAME_FUNC_OFFSET(15122, glGetColorTableParameterfv, glGetColorTableParameterfvEXT, glGetColorTableParameterfvEXT, _gloffset_GetColorTableParameterfv),
-    NAME_FUNC_OFFSET(15152, glGetColorTableParameterfv, glGetColorTableParameterfvEXT, glGetColorTableParameterfvEXT, _gloffset_GetColorTableParameterfv),
-    NAME_FUNC_OFFSET(15182, glGetColorTableParameteriv, glGetColorTableParameterivEXT, glGetColorTableParameterivEXT, _gloffset_GetColorTableParameteriv),
-    NAME_FUNC_OFFSET(15212, glGetColorTableParameteriv, glGetColorTableParameterivEXT, glGetColorTableParameterivEXT, _gloffset_GetColorTableParameteriv),
-    NAME_FUNC_OFFSET(15242, glColorSubTable, glColorSubTable, NULL, _gloffset_ColorSubTable),
-    NAME_FUNC_OFFSET(15261, glCopyColorSubTable, glCopyColorSubTable, NULL, _gloffset_CopyColorSubTable),
-    NAME_FUNC_OFFSET(15284, glConvolutionFilter1D, glConvolutionFilter1D, NULL, _gloffset_ConvolutionFilter1D),
-    NAME_FUNC_OFFSET(15309, glConvolutionFilter2D, glConvolutionFilter2D, NULL, _gloffset_ConvolutionFilter2D),
-    NAME_FUNC_OFFSET(15334, glConvolutionParameterf, glConvolutionParameterf, NULL, _gloffset_ConvolutionParameterf),
-    NAME_FUNC_OFFSET(15361, glConvolutionParameterfv, glConvolutionParameterfv, NULL, _gloffset_ConvolutionParameterfv),
-    NAME_FUNC_OFFSET(15389, glConvolutionParameteri, glConvolutionParameteri, NULL, _gloffset_ConvolutionParameteri),
-    NAME_FUNC_OFFSET(15416, glConvolutionParameteriv, glConvolutionParameteriv, NULL, _gloffset_ConvolutionParameteriv),
-    NAME_FUNC_OFFSET(15444, glCopyConvolutionFilter1D, glCopyConvolutionFilter1D, NULL, _gloffset_CopyConvolutionFilter1D),
-    NAME_FUNC_OFFSET(15473, glCopyConvolutionFilter2D, glCopyConvolutionFilter2D, NULL, _gloffset_CopyConvolutionFilter2D),
-    NAME_FUNC_OFFSET(15502, glGetConvolutionFilter, gl_dispatch_stub_356, gl_dispatch_stub_356, _gloffset_GetConvolutionFilter),
-    NAME_FUNC_OFFSET(15528, glGetConvolutionParameterfv, gl_dispatch_stub_357, gl_dispatch_stub_357, _gloffset_GetConvolutionParameterfv),
-    NAME_FUNC_OFFSET(15559, glGetConvolutionParameteriv, gl_dispatch_stub_358, gl_dispatch_stub_358, _gloffset_GetConvolutionParameteriv),
-    NAME_FUNC_OFFSET(15590, glGetSeparableFilter, gl_dispatch_stub_359, gl_dispatch_stub_359, _gloffset_GetSeparableFilter),
-    NAME_FUNC_OFFSET(15614, glSeparableFilter2D, glSeparableFilter2D, NULL, _gloffset_SeparableFilter2D),
-    NAME_FUNC_OFFSET(15637, glGetHistogram, gl_dispatch_stub_361, gl_dispatch_stub_361, _gloffset_GetHistogram),
-    NAME_FUNC_OFFSET(15655, glGetHistogramParameterfv, gl_dispatch_stub_362, gl_dispatch_stub_362, _gloffset_GetHistogramParameterfv),
-    NAME_FUNC_OFFSET(15684, glGetHistogramParameteriv, gl_dispatch_stub_363, gl_dispatch_stub_363, _gloffset_GetHistogramParameteriv),
-    NAME_FUNC_OFFSET(15713, glGetMinmax, gl_dispatch_stub_364, gl_dispatch_stub_364, _gloffset_GetMinmax),
-    NAME_FUNC_OFFSET(15728, glGetMinmaxParameterfv, gl_dispatch_stub_365, gl_dispatch_stub_365, _gloffset_GetMinmaxParameterfv),
-    NAME_FUNC_OFFSET(15754, glGetMinmaxParameteriv, gl_dispatch_stub_366, gl_dispatch_stub_366, _gloffset_GetMinmaxParameteriv),
-    NAME_FUNC_OFFSET(15780, glHistogram, glHistogram, NULL, _gloffset_Histogram),
-    NAME_FUNC_OFFSET(15795, glMinmax, glMinmax, NULL, _gloffset_Minmax),
-    NAME_FUNC_OFFSET(15807, glResetHistogram, glResetHistogram, NULL, _gloffset_ResetHistogram),
-    NAME_FUNC_OFFSET(15827, glResetMinmax, glResetMinmax, NULL, _gloffset_ResetMinmax),
-    NAME_FUNC_OFFSET(15844, glTexImage3D, glTexImage3D, NULL, _gloffset_TexImage3D),
-    NAME_FUNC_OFFSET(15860, glTexSubImage3D, glTexSubImage3D, NULL, _gloffset_TexSubImage3D),
-    NAME_FUNC_OFFSET(15879, glCopyTexSubImage3D, glCopyTexSubImage3D, NULL, _gloffset_CopyTexSubImage3D),
-    NAME_FUNC_OFFSET(15902, glActiveTextureARB, glActiveTextureARB, NULL, _gloffset_ActiveTextureARB),
-    NAME_FUNC_OFFSET(15918, glClientActiveTextureARB, glClientActiveTextureARB, NULL, _gloffset_ClientActiveTextureARB),
-    NAME_FUNC_OFFSET(15940, glMultiTexCoord1dARB, glMultiTexCoord1dARB, NULL, _gloffset_MultiTexCoord1dARB),
-    NAME_FUNC_OFFSET(15958, glMultiTexCoord1dvARB, glMultiTexCoord1dvARB, NULL, _gloffset_MultiTexCoord1dvARB),
-    NAME_FUNC_OFFSET(15977, glMultiTexCoord1fARB, glMultiTexCoord1fARB, NULL, _gloffset_MultiTexCoord1fARB),
-    NAME_FUNC_OFFSET(15995, glMultiTexCoord1fvARB, glMultiTexCoord1fvARB, NULL, _gloffset_MultiTexCoord1fvARB),
-    NAME_FUNC_OFFSET(16014, glMultiTexCoord1iARB, glMultiTexCoord1iARB, NULL, _gloffset_MultiTexCoord1iARB),
-    NAME_FUNC_OFFSET(16032, glMultiTexCoord1ivARB, glMultiTexCoord1ivARB, NULL, _gloffset_MultiTexCoord1ivARB),
-    NAME_FUNC_OFFSET(16051, glMultiTexCoord1sARB, glMultiTexCoord1sARB, NULL, _gloffset_MultiTexCoord1sARB),
-    NAME_FUNC_OFFSET(16069, glMultiTexCoord1svARB, glMultiTexCoord1svARB, NULL, _gloffset_MultiTexCoord1svARB),
-    NAME_FUNC_OFFSET(16088, glMultiTexCoord2dARB, glMultiTexCoord2dARB, NULL, _gloffset_MultiTexCoord2dARB),
-    NAME_FUNC_OFFSET(16106, glMultiTexCoord2dvARB, glMultiTexCoord2dvARB, NULL, _gloffset_MultiTexCoord2dvARB),
-    NAME_FUNC_OFFSET(16125, glMultiTexCoord2fARB, glMultiTexCoord2fARB, NULL, _gloffset_MultiTexCoord2fARB),
-    NAME_FUNC_OFFSET(16143, glMultiTexCoord2fvARB, glMultiTexCoord2fvARB, NULL, _gloffset_MultiTexCoord2fvARB),
-    NAME_FUNC_OFFSET(16162, glMultiTexCoord2iARB, glMultiTexCoord2iARB, NULL, _gloffset_MultiTexCoord2iARB),
-    NAME_FUNC_OFFSET(16180, glMultiTexCoord2ivARB, glMultiTexCoord2ivARB, NULL, _gloffset_MultiTexCoord2ivARB),
-    NAME_FUNC_OFFSET(16199, glMultiTexCoord2sARB, glMultiTexCoord2sARB, NULL, _gloffset_MultiTexCoord2sARB),
-    NAME_FUNC_OFFSET(16217, glMultiTexCoord2svARB, glMultiTexCoord2svARB, NULL, _gloffset_MultiTexCoord2svARB),
-    NAME_FUNC_OFFSET(16236, glMultiTexCoord3dARB, glMultiTexCoord3dARB, NULL, _gloffset_MultiTexCoord3dARB),
-    NAME_FUNC_OFFSET(16254, glMultiTexCoord3dvARB, glMultiTexCoord3dvARB, NULL, _gloffset_MultiTexCoord3dvARB),
-    NAME_FUNC_OFFSET(16273, glMultiTexCoord3fARB, glMultiTexCoord3fARB, NULL, _gloffset_MultiTexCoord3fARB),
-    NAME_FUNC_OFFSET(16291, glMultiTexCoord3fvARB, glMultiTexCoord3fvARB, NULL, _gloffset_MultiTexCoord3fvARB),
-    NAME_FUNC_OFFSET(16310, glMultiTexCoord3iARB, glMultiTexCoord3iARB, NULL, _gloffset_MultiTexCoord3iARB),
-    NAME_FUNC_OFFSET(16328, glMultiTexCoord3ivARB, glMultiTexCoord3ivARB, NULL, _gloffset_MultiTexCoord3ivARB),
-    NAME_FUNC_OFFSET(16347, glMultiTexCoord3sARB, glMultiTexCoord3sARB, NULL, _gloffset_MultiTexCoord3sARB),
-    NAME_FUNC_OFFSET(16365, glMultiTexCoord3svARB, glMultiTexCoord3svARB, NULL, _gloffset_MultiTexCoord3svARB),
-    NAME_FUNC_OFFSET(16384, glMultiTexCoord4dARB, glMultiTexCoord4dARB, NULL, _gloffset_MultiTexCoord4dARB),
-    NAME_FUNC_OFFSET(16402, glMultiTexCoord4dvARB, glMultiTexCoord4dvARB, NULL, _gloffset_MultiTexCoord4dvARB),
-    NAME_FUNC_OFFSET(16421, glMultiTexCoord4fARB, glMultiTexCoord4fARB, NULL, _gloffset_MultiTexCoord4fARB),
-    NAME_FUNC_OFFSET(16439, glMultiTexCoord4fvARB, glMultiTexCoord4fvARB, NULL, _gloffset_MultiTexCoord4fvARB),
-    NAME_FUNC_OFFSET(16458, glMultiTexCoord4iARB, glMultiTexCoord4iARB, NULL, _gloffset_MultiTexCoord4iARB),
-    NAME_FUNC_OFFSET(16476, glMultiTexCoord4ivARB, glMultiTexCoord4ivARB, NULL, _gloffset_MultiTexCoord4ivARB),
-    NAME_FUNC_OFFSET(16495, glMultiTexCoord4sARB, glMultiTexCoord4sARB, NULL, _gloffset_MultiTexCoord4sARB),
-    NAME_FUNC_OFFSET(16513, glMultiTexCoord4svARB, glMultiTexCoord4svARB, NULL, _gloffset_MultiTexCoord4svARB),
-    NAME_FUNC_OFFSET(16532, glStencilOpSeparate, glStencilOpSeparate, NULL, _gloffset_StencilOpSeparate),
-    NAME_FUNC_OFFSET(16555, glDrawArraysInstanced, glDrawArraysInstanced, NULL, _gloffset_DrawArraysInstanced),
-    NAME_FUNC_OFFSET(16580, glDrawArraysInstanced, glDrawArraysInstanced, NULL, _gloffset_DrawArraysInstanced),
-    NAME_FUNC_OFFSET(16605, glDrawElementsInstanced, glDrawElementsInstanced, NULL, _gloffset_DrawElementsInstanced),
-    NAME_FUNC_OFFSET(16632, glDrawElementsInstanced, glDrawElementsInstanced, NULL, _gloffset_DrawElementsInstanced),
-    NAME_FUNC_OFFSET(16659, glLoadTransposeMatrixdARB, glLoadTransposeMatrixdARB, NULL, _gloffset_LoadTransposeMatrixdARB),
-    NAME_FUNC_OFFSET(16682, glLoadTransposeMatrixfARB, glLoadTransposeMatrixfARB, NULL, _gloffset_LoadTransposeMatrixfARB),
-    NAME_FUNC_OFFSET(16705, glMultTransposeMatrixdARB, glMultTransposeMatrixdARB, NULL, _gloffset_MultTransposeMatrixdARB),
-    NAME_FUNC_OFFSET(16728, glMultTransposeMatrixfARB, glMultTransposeMatrixfARB, NULL, _gloffset_MultTransposeMatrixfARB),
-    NAME_FUNC_OFFSET(16751, glSampleCoverageARB, glSampleCoverageARB, NULL, _gloffset_SampleCoverageARB),
-    NAME_FUNC_OFFSET(16768, glCompressedTexImage1DARB, glCompressedTexImage1DARB, NULL, _gloffset_CompressedTexImage1DARB),
-    NAME_FUNC_OFFSET(16791, glCompressedTexImage2DARB, glCompressedTexImage2DARB, NULL, _gloffset_CompressedTexImage2DARB),
-    NAME_FUNC_OFFSET(16814, glCompressedTexImage3DARB, glCompressedTexImage3DARB, NULL, _gloffset_CompressedTexImage3DARB),
-    NAME_FUNC_OFFSET(16837, glCompressedTexSubImage1DARB, glCompressedTexSubImage1DARB, NULL, _gloffset_CompressedTexSubImage1DARB),
-    NAME_FUNC_OFFSET(16863, glCompressedTexSubImage2DARB, glCompressedTexSubImage2DARB, NULL, _gloffset_CompressedTexSubImage2DARB),
-    NAME_FUNC_OFFSET(16889, glCompressedTexSubImage3DARB, glCompressedTexSubImage3DARB, NULL, _gloffset_CompressedTexSubImage3DARB),
-    NAME_FUNC_OFFSET(16915, glGetCompressedTexImageARB, glGetCompressedTexImageARB, NULL, _gloffset_GetCompressedTexImageARB),
-    NAME_FUNC_OFFSET(16939, glDisableVertexAttribArrayARB, glDisableVertexAttribArrayARB, NULL, _gloffset_DisableVertexAttribArrayARB),
-    NAME_FUNC_OFFSET(16966, glEnableVertexAttribArrayARB, glEnableVertexAttribArrayARB, NULL, _gloffset_EnableVertexAttribArrayARB),
-    NAME_FUNC_OFFSET(16992, glGetVertexAttribdvARB, glGetVertexAttribdvARB, NULL, _gloffset_GetVertexAttribdvARB),
-    NAME_FUNC_OFFSET(17012, glGetVertexAttribfvARB, glGetVertexAttribfvARB, NULL, _gloffset_GetVertexAttribfvARB),
-    NAME_FUNC_OFFSET(17032, glGetVertexAttribivARB, glGetVertexAttribivARB, NULL, _gloffset_GetVertexAttribivARB),
-    NAME_FUNC_OFFSET(17052, glProgramEnvParameter4dARB, glProgramEnvParameter4dARB, NULL, _gloffset_ProgramEnvParameter4dARB),
-    NAME_FUNC_OFFSET(17075, glProgramEnvParameter4dvARB, glProgramEnvParameter4dvARB, NULL, _gloffset_ProgramEnvParameter4dvARB),
-    NAME_FUNC_OFFSET(17099, glProgramEnvParameter4fARB, glProgramEnvParameter4fARB, NULL, _gloffset_ProgramEnvParameter4fARB),
-    NAME_FUNC_OFFSET(17122, glProgramEnvParameter4fvARB, glProgramEnvParameter4fvARB, NULL, _gloffset_ProgramEnvParameter4fvARB),
-    NAME_FUNC_OFFSET(17146, glVertexAttrib1dARB, glVertexAttrib1dARB, NULL, _gloffset_VertexAttrib1dARB),
-    NAME_FUNC_OFFSET(17163, glVertexAttrib1dvARB, glVertexAttrib1dvARB, NULL, _gloffset_VertexAttrib1dvARB),
-    NAME_FUNC_OFFSET(17181, glVertexAttrib1fARB, glVertexAttrib1fARB, NULL, _gloffset_VertexAttrib1fARB),
-    NAME_FUNC_OFFSET(17198, glVertexAttrib1fvARB, glVertexAttrib1fvARB, NULL, _gloffset_VertexAttrib1fvARB),
-    NAME_FUNC_OFFSET(17216, glVertexAttrib1sARB, glVertexAttrib1sARB, NULL, _gloffset_VertexAttrib1sARB),
-    NAME_FUNC_OFFSET(17233, glVertexAttrib1svARB, glVertexAttrib1svARB, NULL, _gloffset_VertexAttrib1svARB),
-    NAME_FUNC_OFFSET(17251, glVertexAttrib2dARB, glVertexAttrib2dARB, NULL, _gloffset_VertexAttrib2dARB),
-    NAME_FUNC_OFFSET(17268, glVertexAttrib2dvARB, glVertexAttrib2dvARB, NULL, _gloffset_VertexAttrib2dvARB),
-    NAME_FUNC_OFFSET(17286, glVertexAttrib2fARB, glVertexAttrib2fARB, NULL, _gloffset_VertexAttrib2fARB),
-    NAME_FUNC_OFFSET(17303, glVertexAttrib2fvARB, glVertexAttrib2fvARB, NULL, _gloffset_VertexAttrib2fvARB),
-    NAME_FUNC_OFFSET(17321, glVertexAttrib2sARB, glVertexAttrib2sARB, NULL, _gloffset_VertexAttrib2sARB),
-    NAME_FUNC_OFFSET(17338, glVertexAttrib2svARB, glVertexAttrib2svARB, NULL, _gloffset_VertexAttrib2svARB),
-    NAME_FUNC_OFFSET(17356, glVertexAttrib3dARB, glVertexAttrib3dARB, NULL, _gloffset_VertexAttrib3dARB),
-    NAME_FUNC_OFFSET(17373, glVertexAttrib3dvARB, glVertexAttrib3dvARB, NULL, _gloffset_VertexAttrib3dvARB),
-    NAME_FUNC_OFFSET(17391, glVertexAttrib3fARB, glVertexAttrib3fARB, NULL, _gloffset_VertexAttrib3fARB),
-    NAME_FUNC_OFFSET(17408, glVertexAttrib3fvARB, glVertexAttrib3fvARB, NULL, _gloffset_VertexAttrib3fvARB),
-    NAME_FUNC_OFFSET(17426, glVertexAttrib3sARB, glVertexAttrib3sARB, NULL, _gloffset_VertexAttrib3sARB),
-    NAME_FUNC_OFFSET(17443, glVertexAttrib3svARB, glVertexAttrib3svARB, NULL, _gloffset_VertexAttrib3svARB),
-    NAME_FUNC_OFFSET(17461, glVertexAttrib4NbvARB, glVertexAttrib4NbvARB, NULL, _gloffset_VertexAttrib4NbvARB),
-    NAME_FUNC_OFFSET(17480, glVertexAttrib4NivARB, glVertexAttrib4NivARB, NULL, _gloffset_VertexAttrib4NivARB),
-    NAME_FUNC_OFFSET(17499, glVertexAttrib4NsvARB, glVertexAttrib4NsvARB, NULL, _gloffset_VertexAttrib4NsvARB),
-    NAME_FUNC_OFFSET(17518, glVertexAttrib4NubARB, glVertexAttrib4NubARB, NULL, _gloffset_VertexAttrib4NubARB),
-    NAME_FUNC_OFFSET(17537, glVertexAttrib4NubvARB, glVertexAttrib4NubvARB, NULL, _gloffset_VertexAttrib4NubvARB),
-    NAME_FUNC_OFFSET(17557, glVertexAttrib4NuivARB, glVertexAttrib4NuivARB, NULL, _gloffset_VertexAttrib4NuivARB),
-    NAME_FUNC_OFFSET(17577, glVertexAttrib4NusvARB, glVertexAttrib4NusvARB, NULL, _gloffset_VertexAttrib4NusvARB),
-    NAME_FUNC_OFFSET(17597, glVertexAttrib4bvARB, glVertexAttrib4bvARB, NULL, _gloffset_VertexAttrib4bvARB),
-    NAME_FUNC_OFFSET(17615, glVertexAttrib4dARB, glVertexAttrib4dARB, NULL, _gloffset_VertexAttrib4dARB),
-    NAME_FUNC_OFFSET(17632, glVertexAttrib4dvARB, glVertexAttrib4dvARB, NULL, _gloffset_VertexAttrib4dvARB),
-    NAME_FUNC_OFFSET(17650, glVertexAttrib4fARB, glVertexAttrib4fARB, NULL, _gloffset_VertexAttrib4fARB),
-    NAME_FUNC_OFFSET(17667, glVertexAttrib4fvARB, glVertexAttrib4fvARB, NULL, _gloffset_VertexAttrib4fvARB),
-    NAME_FUNC_OFFSET(17685, glVertexAttrib4ivARB, glVertexAttrib4ivARB, NULL, _gloffset_VertexAttrib4ivARB),
-    NAME_FUNC_OFFSET(17703, glVertexAttrib4sARB, glVertexAttrib4sARB, NULL, _gloffset_VertexAttrib4sARB),
-    NAME_FUNC_OFFSET(17720, glVertexAttrib4svARB, glVertexAttrib4svARB, NULL, _gloffset_VertexAttrib4svARB),
-    NAME_FUNC_OFFSET(17738, glVertexAttrib4ubvARB, glVertexAttrib4ubvARB, NULL, _gloffset_VertexAttrib4ubvARB),
-    NAME_FUNC_OFFSET(17757, glVertexAttrib4uivARB, glVertexAttrib4uivARB, NULL, _gloffset_VertexAttrib4uivARB),
-    NAME_FUNC_OFFSET(17776, glVertexAttrib4usvARB, glVertexAttrib4usvARB, NULL, _gloffset_VertexAttrib4usvARB),
-    NAME_FUNC_OFFSET(17795, glVertexAttribPointerARB, glVertexAttribPointerARB, NULL, _gloffset_VertexAttribPointerARB),
-    NAME_FUNC_OFFSET(17817, glBindBufferARB, glBindBufferARB, NULL, _gloffset_BindBufferARB),
-    NAME_FUNC_OFFSET(17830, glBufferDataARB, glBufferDataARB, NULL, _gloffset_BufferDataARB),
-    NAME_FUNC_OFFSET(17843, glBufferSubDataARB, glBufferSubDataARB, NULL, _gloffset_BufferSubDataARB),
-    NAME_FUNC_OFFSET(17859, glDeleteBuffersARB, glDeleteBuffersARB, NULL, _gloffset_DeleteBuffersARB),
-    NAME_FUNC_OFFSET(17875, glGenBuffersARB, glGenBuffersARB, NULL, _gloffset_GenBuffersARB),
-    NAME_FUNC_OFFSET(17888, glGetBufferParameterivARB, glGetBufferParameterivARB, NULL, _gloffset_GetBufferParameterivARB),
-    NAME_FUNC_OFFSET(17911, glGetBufferPointervARB, glGetBufferPointervARB, NULL, _gloffset_GetBufferPointervARB),
-    NAME_FUNC_OFFSET(17931, glGetBufferSubDataARB, glGetBufferSubDataARB, NULL, _gloffset_GetBufferSubDataARB),
-    NAME_FUNC_OFFSET(17950, glIsBufferARB, glIsBufferARB, NULL, _gloffset_IsBufferARB),
-    NAME_FUNC_OFFSET(17961, glMapBufferARB, glMapBufferARB, NULL, _gloffset_MapBufferARB),
-    NAME_FUNC_OFFSET(17973, glUnmapBufferARB, glUnmapBufferARB, NULL, _gloffset_UnmapBufferARB),
-    NAME_FUNC_OFFSET(17987, glBeginQueryARB, glBeginQueryARB, NULL, _gloffset_BeginQueryARB),
-    NAME_FUNC_OFFSET(18000, glDeleteQueriesARB, glDeleteQueriesARB, NULL, _gloffset_DeleteQueriesARB),
-    NAME_FUNC_OFFSET(18016, glEndQueryARB, glEndQueryARB, NULL, _gloffset_EndQueryARB),
-    NAME_FUNC_OFFSET(18027, glGenQueriesARB, glGenQueriesARB, NULL, _gloffset_GenQueriesARB),
-    NAME_FUNC_OFFSET(18040, glGetQueryObjectivARB, glGetQueryObjectivARB, NULL, _gloffset_GetQueryObjectivARB),
-    NAME_FUNC_OFFSET(18059, glGetQueryObjectuivARB, glGetQueryObjectuivARB, NULL, _gloffset_GetQueryObjectuivARB),
-    NAME_FUNC_OFFSET(18079, glGetQueryivARB, glGetQueryivARB, NULL, _gloffset_GetQueryivARB),
-    NAME_FUNC_OFFSET(18092, glIsQueryARB, glIsQueryARB, NULL, _gloffset_IsQueryARB),
-    NAME_FUNC_OFFSET(18102, glCompileShaderARB, glCompileShaderARB, NULL, _gloffset_CompileShaderARB),
-    NAME_FUNC_OFFSET(18118, glGetActiveUniformARB, glGetActiveUniformARB, NULL, _gloffset_GetActiveUniformARB),
-    NAME_FUNC_OFFSET(18137, glGetShaderSourceARB, glGetShaderSourceARB, NULL, _gloffset_GetShaderSourceARB),
-    NAME_FUNC_OFFSET(18155, glGetUniformLocationARB, glGetUniformLocationARB, NULL, _gloffset_GetUniformLocationARB),
-    NAME_FUNC_OFFSET(18176, glGetUniformfvARB, glGetUniformfvARB, NULL, _gloffset_GetUniformfvARB),
-    NAME_FUNC_OFFSET(18191, glGetUniformivARB, glGetUniformivARB, NULL, _gloffset_GetUniformivARB),
-    NAME_FUNC_OFFSET(18206, glLinkProgramARB, glLinkProgramARB, NULL, _gloffset_LinkProgramARB),
-    NAME_FUNC_OFFSET(18220, glShaderSourceARB, glShaderSourceARB, NULL, _gloffset_ShaderSourceARB),
-    NAME_FUNC_OFFSET(18235, glUniform1fARB, glUniform1fARB, NULL, _gloffset_Uniform1fARB),
-    NAME_FUNC_OFFSET(18247, glUniform1fvARB, glUniform1fvARB, NULL, _gloffset_Uniform1fvARB),
-    NAME_FUNC_OFFSET(18260, glUniform1iARB, glUniform1iARB, NULL, _gloffset_Uniform1iARB),
-    NAME_FUNC_OFFSET(18272, glUniform1ivARB, glUniform1ivARB, NULL, _gloffset_Uniform1ivARB),
-    NAME_FUNC_OFFSET(18285, glUniform2fARB, glUniform2fARB, NULL, _gloffset_Uniform2fARB),
-    NAME_FUNC_OFFSET(18297, glUniform2fvARB, glUniform2fvARB, NULL, _gloffset_Uniform2fvARB),
-    NAME_FUNC_OFFSET(18310, glUniform2iARB, glUniform2iARB, NULL, _gloffset_Uniform2iARB),
-    NAME_FUNC_OFFSET(18322, glUniform2ivARB, glUniform2ivARB, NULL, _gloffset_Uniform2ivARB),
-    NAME_FUNC_OFFSET(18335, glUniform3fARB, glUniform3fARB, NULL, _gloffset_Uniform3fARB),
-    NAME_FUNC_OFFSET(18347, glUniform3fvARB, glUniform3fvARB, NULL, _gloffset_Uniform3fvARB),
-    NAME_FUNC_OFFSET(18360, glUniform3iARB, glUniform3iARB, NULL, _gloffset_Uniform3iARB),
-    NAME_FUNC_OFFSET(18372, glUniform3ivARB, glUniform3ivARB, NULL, _gloffset_Uniform3ivARB),
-    NAME_FUNC_OFFSET(18385, glUniform4fARB, glUniform4fARB, NULL, _gloffset_Uniform4fARB),
-    NAME_FUNC_OFFSET(18397, glUniform4fvARB, glUniform4fvARB, NULL, _gloffset_Uniform4fvARB),
-    NAME_FUNC_OFFSET(18410, glUniform4iARB, glUniform4iARB, NULL, _gloffset_Uniform4iARB),
-    NAME_FUNC_OFFSET(18422, glUniform4ivARB, glUniform4ivARB, NULL, _gloffset_Uniform4ivARB),
-    NAME_FUNC_OFFSET(18435, glUniformMatrix2fvARB, glUniformMatrix2fvARB, NULL, _gloffset_UniformMatrix2fvARB),
-    NAME_FUNC_OFFSET(18454, glUniformMatrix3fvARB, glUniformMatrix3fvARB, NULL, _gloffset_UniformMatrix3fvARB),
-    NAME_FUNC_OFFSET(18473, glUniformMatrix4fvARB, glUniformMatrix4fvARB, NULL, _gloffset_UniformMatrix4fvARB),
-    NAME_FUNC_OFFSET(18492, glUseProgramObjectARB, glUseProgramObjectARB, NULL, _gloffset_UseProgramObjectARB),
-    NAME_FUNC_OFFSET(18505, glValidateProgramARB, glValidateProgramARB, NULL, _gloffset_ValidateProgramARB),
-    NAME_FUNC_OFFSET(18523, glBindAttribLocationARB, glBindAttribLocationARB, NULL, _gloffset_BindAttribLocationARB),
-    NAME_FUNC_OFFSET(18544, glGetActiveAttribARB, glGetActiveAttribARB, NULL, _gloffset_GetActiveAttribARB),
-    NAME_FUNC_OFFSET(18562, glGetAttribLocationARB, glGetAttribLocationARB, NULL, _gloffset_GetAttribLocationARB),
-    NAME_FUNC_OFFSET(18582, glDrawBuffersARB, glDrawBuffersARB, NULL, _gloffset_DrawBuffersARB),
-    NAME_FUNC_OFFSET(18596, glDrawBuffersARB, glDrawBuffersARB, NULL, _gloffset_DrawBuffersARB),
-    NAME_FUNC_OFFSET(18613, glRenderbufferStorageMultisample, glRenderbufferStorageMultisample, NULL, _gloffset_RenderbufferStorageMultisample),
-    NAME_FUNC_OFFSET(18649, gl_dispatch_stub_586, gl_dispatch_stub_586, NULL, _gloffset_SampleMaskSGIS),
-    NAME_FUNC_OFFSET(18665, gl_dispatch_stub_587, gl_dispatch_stub_587, NULL, _gloffset_SamplePatternSGIS),
-    NAME_FUNC_OFFSET(18684, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
-    NAME_FUNC_OFFSET(18702, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
-    NAME_FUNC_OFFSET(18723, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
-    NAME_FUNC_OFFSET(18745, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
-    NAME_FUNC_OFFSET(18764, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
-    NAME_FUNC_OFFSET(18786, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
-    NAME_FUNC_OFFSET(18809, glSecondaryColor3bEXT, glSecondaryColor3bEXT, NULL, _gloffset_SecondaryColor3bEXT),
-    NAME_FUNC_OFFSET(18828, glSecondaryColor3bvEXT, glSecondaryColor3bvEXT, NULL, _gloffset_SecondaryColor3bvEXT),
-    NAME_FUNC_OFFSET(18848, glSecondaryColor3dEXT, glSecondaryColor3dEXT, NULL, _gloffset_SecondaryColor3dEXT),
-    NAME_FUNC_OFFSET(18867, glSecondaryColor3dvEXT, glSecondaryColor3dvEXT, NULL, _gloffset_SecondaryColor3dvEXT),
-    NAME_FUNC_OFFSET(18887, glSecondaryColor3fEXT, glSecondaryColor3fEXT, NULL, _gloffset_SecondaryColor3fEXT),
-    NAME_FUNC_OFFSET(18906, glSecondaryColor3fvEXT, glSecondaryColor3fvEXT, NULL, _gloffset_SecondaryColor3fvEXT),
-    NAME_FUNC_OFFSET(18926, glSecondaryColor3iEXT, glSecondaryColor3iEXT, NULL, _gloffset_SecondaryColor3iEXT),
-    NAME_FUNC_OFFSET(18945, glSecondaryColor3ivEXT, glSecondaryColor3ivEXT, NULL, _gloffset_SecondaryColor3ivEXT),
-    NAME_FUNC_OFFSET(18965, glSecondaryColor3sEXT, glSecondaryColor3sEXT, NULL, _gloffset_SecondaryColor3sEXT),
-    NAME_FUNC_OFFSET(18984, glSecondaryColor3svEXT, glSecondaryColor3svEXT, NULL, _gloffset_SecondaryColor3svEXT),
-    NAME_FUNC_OFFSET(19004, glSecondaryColor3ubEXT, glSecondaryColor3ubEXT, NULL, _gloffset_SecondaryColor3ubEXT),
-    NAME_FUNC_OFFSET(19024, glSecondaryColor3ubvEXT, glSecondaryColor3ubvEXT, NULL, _gloffset_SecondaryColor3ubvEXT),
-    NAME_FUNC_OFFSET(19045, glSecondaryColor3uiEXT, glSecondaryColor3uiEXT, NULL, _gloffset_SecondaryColor3uiEXT),
-    NAME_FUNC_OFFSET(19065, glSecondaryColor3uivEXT, glSecondaryColor3uivEXT, NULL, _gloffset_SecondaryColor3uivEXT),
-    NAME_FUNC_OFFSET(19086, glSecondaryColor3usEXT, glSecondaryColor3usEXT, NULL, _gloffset_SecondaryColor3usEXT),
-    NAME_FUNC_OFFSET(19106, glSecondaryColor3usvEXT, glSecondaryColor3usvEXT, NULL, _gloffset_SecondaryColor3usvEXT),
-    NAME_FUNC_OFFSET(19127, glSecondaryColorPointerEXT, glSecondaryColorPointerEXT, NULL, _gloffset_SecondaryColorPointerEXT),
-    NAME_FUNC_OFFSET(19151, glMultiDrawArraysEXT, glMultiDrawArraysEXT, NULL, _gloffset_MultiDrawArraysEXT),
-    NAME_FUNC_OFFSET(19169, glMultiDrawElementsEXT, glMultiDrawElementsEXT, NULL, _gloffset_MultiDrawElementsEXT),
-    NAME_FUNC_OFFSET(19189, glFogCoordPointerEXT, glFogCoordPointerEXT, NULL, _gloffset_FogCoordPointerEXT),
-    NAME_FUNC_OFFSET(19207, glFogCoorddEXT, glFogCoorddEXT, NULL, _gloffset_FogCoorddEXT),
-    NAME_FUNC_OFFSET(19219, glFogCoorddvEXT, glFogCoorddvEXT, NULL, _gloffset_FogCoorddvEXT),
-    NAME_FUNC_OFFSET(19232, glFogCoordfEXT, glFogCoordfEXT, NULL, _gloffset_FogCoordfEXT),
-    NAME_FUNC_OFFSET(19244, glFogCoordfvEXT, glFogCoordfvEXT, NULL, _gloffset_FogCoordfvEXT),
-    NAME_FUNC_OFFSET(19257, glBlendFuncSeparateEXT, glBlendFuncSeparateEXT, NULL, _gloffset_BlendFuncSeparateEXT),
-    NAME_FUNC_OFFSET(19277, glBlendFuncSeparateEXT, glBlendFuncSeparateEXT, NULL, _gloffset_BlendFuncSeparateEXT),
-    NAME_FUNC_OFFSET(19301, glWindowPos2dMESA, glWindowPos2dMESA, NULL, _gloffset_WindowPos2dMESA),
-    NAME_FUNC_OFFSET(19315, glWindowPos2dMESA, glWindowPos2dMESA, NULL, _gloffset_WindowPos2dMESA),
-    NAME_FUNC_OFFSET(19332, glWindowPos2dvMESA, glWindowPos2dvMESA, NULL, _gloffset_WindowPos2dvMESA),
-    NAME_FUNC_OFFSET(19347, glWindowPos2dvMESA, glWindowPos2dvMESA, NULL, _gloffset_WindowPos2dvMESA),
-    NAME_FUNC_OFFSET(19365, glWindowPos2fMESA, glWindowPos2fMESA, NULL, _gloffset_WindowPos2fMESA),
-    NAME_FUNC_OFFSET(19379, glWindowPos2fMESA, glWindowPos2fMESA, NULL, _gloffset_WindowPos2fMESA),
-    NAME_FUNC_OFFSET(19396, glWindowPos2fvMESA, glWindowPos2fvMESA, NULL, _gloffset_WindowPos2fvMESA),
-    NAME_FUNC_OFFSET(19411, glWindowPos2fvMESA, glWindowPos2fvMESA, NULL, _gloffset_WindowPos2fvMESA),
-    NAME_FUNC_OFFSET(19429, glWindowPos2iMESA, glWindowPos2iMESA, NULL, _gloffset_WindowPos2iMESA),
-    NAME_FUNC_OFFSET(19443, glWindowPos2iMESA, glWindowPos2iMESA, NULL, _gloffset_WindowPos2iMESA),
-    NAME_FUNC_OFFSET(19460, glWindowPos2ivMESA, glWindowPos2ivMESA, NULL, _gloffset_WindowPos2ivMESA),
-    NAME_FUNC_OFFSET(19475, glWindowPos2ivMESA, glWindowPos2ivMESA, NULL, _gloffset_WindowPos2ivMESA),
-    NAME_FUNC_OFFSET(19493, glWindowPos2sMESA, glWindowPos2sMESA, NULL, _gloffset_WindowPos2sMESA),
-    NAME_FUNC_OFFSET(19507, glWindowPos2sMESA, glWindowPos2sMESA, NULL, _gloffset_WindowPos2sMESA),
-    NAME_FUNC_OFFSET(19524, glWindowPos2svMESA, glWindowPos2svMESA, NULL, _gloffset_WindowPos2svMESA),
-    NAME_FUNC_OFFSET(19539, glWindowPos2svMESA, glWindowPos2svMESA, NULL, _gloffset_WindowPos2svMESA),
-    NAME_FUNC_OFFSET(19557, glWindowPos3dMESA, glWindowPos3dMESA, NULL, _gloffset_WindowPos3dMESA),
-    NAME_FUNC_OFFSET(19571, glWindowPos3dMESA, glWindowPos3dMESA, NULL, _gloffset_WindowPos3dMESA),
-    NAME_FUNC_OFFSET(19588, glWindowPos3dvMESA, glWindowPos3dvMESA, NULL, _gloffset_WindowPos3dvMESA),
-    NAME_FUNC_OFFSET(19603, glWindowPos3dvMESA, glWindowPos3dvMESA, NULL, _gloffset_WindowPos3dvMESA),
-    NAME_FUNC_OFFSET(19621, glWindowPos3fMESA, glWindowPos3fMESA, NULL, _gloffset_WindowPos3fMESA),
-    NAME_FUNC_OFFSET(19635, glWindowPos3fMESA, glWindowPos3fMESA, NULL, _gloffset_WindowPos3fMESA),
-    NAME_FUNC_OFFSET(19652, glWindowPos3fvMESA, glWindowPos3fvMESA, NULL, _gloffset_WindowPos3fvMESA),
-    NAME_FUNC_OFFSET(19667, glWindowPos3fvMESA, glWindowPos3fvMESA, NULL, _gloffset_WindowPos3fvMESA),
-    NAME_FUNC_OFFSET(19685, glWindowPos3iMESA, glWindowPos3iMESA, NULL, _gloffset_WindowPos3iMESA),
-    NAME_FUNC_OFFSET(19699, glWindowPos3iMESA, glWindowPos3iMESA, NULL, _gloffset_WindowPos3iMESA),
-    NAME_FUNC_OFFSET(19716, glWindowPos3ivMESA, glWindowPos3ivMESA, NULL, _gloffset_WindowPos3ivMESA),
-    NAME_FUNC_OFFSET(19731, glWindowPos3ivMESA, glWindowPos3ivMESA, NULL, _gloffset_WindowPos3ivMESA),
-    NAME_FUNC_OFFSET(19749, glWindowPos3sMESA, glWindowPos3sMESA, NULL, _gloffset_WindowPos3sMESA),
-    NAME_FUNC_OFFSET(19763, glWindowPos3sMESA, glWindowPos3sMESA, NULL, _gloffset_WindowPos3sMESA),
-    NAME_FUNC_OFFSET(19780, glWindowPos3svMESA, glWindowPos3svMESA, NULL, _gloffset_WindowPos3svMESA),
-    NAME_FUNC_OFFSET(19795, glWindowPos3svMESA, glWindowPos3svMESA, NULL, _gloffset_WindowPos3svMESA),
-    NAME_FUNC_OFFSET(19813, glBindProgramNV, glBindProgramNV, NULL, _gloffset_BindProgramNV),
-    NAME_FUNC_OFFSET(19830, glDeleteProgramsNV, glDeleteProgramsNV, NULL, _gloffset_DeleteProgramsNV),
-    NAME_FUNC_OFFSET(19850, glGenProgramsNV, glGenProgramsNV, NULL, _gloffset_GenProgramsNV),
-    NAME_FUNC_OFFSET(19867, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV),
-    NAME_FUNC_OFFSET(19893, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV),
-    NAME_FUNC_OFFSET(19922, glIsProgramNV, glIsProgramNV, NULL, _gloffset_IsProgramNV),
-    NAME_FUNC_OFFSET(19937, glPointParameteriNV, glPointParameteriNV, NULL, _gloffset_PointParameteriNV),
-    NAME_FUNC_OFFSET(19955, glPointParameterivNV, glPointParameterivNV, NULL, _gloffset_PointParameterivNV),
-    NAME_FUNC_OFFSET(19974, gl_dispatch_stub_757, gl_dispatch_stub_757, NULL, _gloffset_DeleteVertexArraysAPPLE),
-    NAME_FUNC_OFFSET(19995, gl_dispatch_stub_759, gl_dispatch_stub_759, NULL, _gloffset_IsVertexArrayAPPLE),
-    NAME_FUNC_OFFSET(20011, gl_dispatch_stub_767, gl_dispatch_stub_767, NULL, _gloffset_BlendEquationSeparateEXT),
-    NAME_FUNC_OFFSET(20035, gl_dispatch_stub_767, gl_dispatch_stub_767, NULL, _gloffset_BlendEquationSeparateEXT),
-    NAME_FUNC_OFFSET(20062, glBindFramebufferEXT, glBindFramebufferEXT, NULL, _gloffset_BindFramebufferEXT),
-    NAME_FUNC_OFFSET(20080, glBindRenderbufferEXT, glBindRenderbufferEXT, NULL, _gloffset_BindRenderbufferEXT),
-    NAME_FUNC_OFFSET(20099, glCheckFramebufferStatusEXT, glCheckFramebufferStatusEXT, NULL, _gloffset_CheckFramebufferStatusEXT),
-    NAME_FUNC_OFFSET(20124, glDeleteFramebuffersEXT, glDeleteFramebuffersEXT, NULL, _gloffset_DeleteFramebuffersEXT),
-    NAME_FUNC_OFFSET(20145, glDeleteRenderbuffersEXT, glDeleteRenderbuffersEXT, NULL, _gloffset_DeleteRenderbuffersEXT),
-    NAME_FUNC_OFFSET(20167, glFramebufferRenderbufferEXT, glFramebufferRenderbufferEXT, NULL, _gloffset_FramebufferRenderbufferEXT),
-    NAME_FUNC_OFFSET(20193, glFramebufferTexture1DEXT, glFramebufferTexture1DEXT, NULL, _gloffset_FramebufferTexture1DEXT),
-    NAME_FUNC_OFFSET(20216, glFramebufferTexture2DEXT, glFramebufferTexture2DEXT, NULL, _gloffset_FramebufferTexture2DEXT),
-    NAME_FUNC_OFFSET(20239, glFramebufferTexture3DEXT, glFramebufferTexture3DEXT, NULL, _gloffset_FramebufferTexture3DEXT),
-    NAME_FUNC_OFFSET(20262, glGenFramebuffersEXT, glGenFramebuffersEXT, NULL, _gloffset_GenFramebuffersEXT),
-    NAME_FUNC_OFFSET(20280, glGenRenderbuffersEXT, glGenRenderbuffersEXT, NULL, _gloffset_GenRenderbuffersEXT),
-    NAME_FUNC_OFFSET(20299, glGenerateMipmapEXT, glGenerateMipmapEXT, NULL, _gloffset_GenerateMipmapEXT),
-    NAME_FUNC_OFFSET(20316, glGetFramebufferAttachmentParameterivEXT, glGetFramebufferAttachmentParameterivEXT, NULL, _gloffset_GetFramebufferAttachmentParameterivEXT),
-    NAME_FUNC_OFFSET(20354, glGetRenderbufferParameterivEXT, glGetRenderbufferParameterivEXT, NULL, _gloffset_GetRenderbufferParameterivEXT),
-    NAME_FUNC_OFFSET(20383, glIsFramebufferEXT, glIsFramebufferEXT, NULL, _gloffset_IsFramebufferEXT),
-    NAME_FUNC_OFFSET(20399, glIsRenderbufferEXT, glIsRenderbufferEXT, NULL, _gloffset_IsRenderbufferEXT),
-    NAME_FUNC_OFFSET(20416, glRenderbufferStorageEXT, glRenderbufferStorageEXT, NULL, _gloffset_RenderbufferStorageEXT),
-    NAME_FUNC_OFFSET(20438, gl_dispatch_stub_785, gl_dispatch_stub_785, NULL, _gloffset_BlitFramebufferEXT),
-    NAME_FUNC_OFFSET(20456, glFramebufferTextureLayerEXT, glFramebufferTextureLayerEXT, NULL, _gloffset_FramebufferTextureLayerEXT),
-    NAME_FUNC_OFFSET(20482, glBeginTransformFeedbackEXT, glBeginTransformFeedbackEXT, NULL, _gloffset_BeginTransformFeedbackEXT),
-    NAME_FUNC_OFFSET(20507, glBindBufferBaseEXT, glBindBufferBaseEXT, NULL, _gloffset_BindBufferBaseEXT),
-    NAME_FUNC_OFFSET(20524, glBindBufferRangeEXT, glBindBufferRangeEXT, NULL, _gloffset_BindBufferRangeEXT),
-    NAME_FUNC_OFFSET(20542, glEndTransformFeedbackEXT, glEndTransformFeedbackEXT, NULL, _gloffset_EndTransformFeedbackEXT),
-    NAME_FUNC_OFFSET(20565, glGetTransformFeedbackVaryingEXT, glGetTransformFeedbackVaryingEXT, NULL, _gloffset_GetTransformFeedbackVaryingEXT),
-    NAME_FUNC_OFFSET(20595, glTransformFeedbackVaryingsEXT, glTransformFeedbackVaryingsEXT, NULL, _gloffset_TransformFeedbackVaryingsEXT),
-    NAME_FUNC_OFFSET(20623, glProvokingVertexEXT, glProvokingVertexEXT, NULL, _gloffset_ProvokingVertexEXT),
+    NAME_FUNC_OFFSET( 9030, glFramebufferTextureARB, glFramebufferTextureARB, NULL, _gloffset_FramebufferTextureARB),
+    NAME_FUNC_OFFSET( 9054, glFramebufferTextureFaceARB, glFramebufferTextureFaceARB, NULL, _gloffset_FramebufferTextureFaceARB),
+    NAME_FUNC_OFFSET( 9082, glProgramParameteriARB, glProgramParameteriARB, NULL, _gloffset_ProgramParameteriARB),
+    NAME_FUNC_OFFSET( 9105, glFlushMappedBufferRange, glFlushMappedBufferRange, NULL, _gloffset_FlushMappedBufferRange),
+    NAME_FUNC_OFFSET( 9130, glMapBufferRange, glMapBufferRange, NULL, _gloffset_MapBufferRange),
+    NAME_FUNC_OFFSET( 9147, glBindVertexArray, glBindVertexArray, NULL, _gloffset_BindVertexArray),
+    NAME_FUNC_OFFSET( 9165, glGenVertexArrays, glGenVertexArrays, NULL, _gloffset_GenVertexArrays),
+    NAME_FUNC_OFFSET( 9183, glCopyBufferSubData, glCopyBufferSubData, NULL, _gloffset_CopyBufferSubData),
+    NAME_FUNC_OFFSET( 9203, glClientWaitSync, glClientWaitSync, NULL, _gloffset_ClientWaitSync),
+    NAME_FUNC_OFFSET( 9220, glDeleteSync, glDeleteSync, NULL, _gloffset_DeleteSync),
+    NAME_FUNC_OFFSET( 9233, glFenceSync, glFenceSync, NULL, _gloffset_FenceSync),
+    NAME_FUNC_OFFSET( 9245, glGetInteger64v, glGetInteger64v, NULL, _gloffset_GetInteger64v),
+    NAME_FUNC_OFFSET( 9261, glGetSynciv, glGetSynciv, NULL, _gloffset_GetSynciv),
+    NAME_FUNC_OFFSET( 9273, glIsSync, glIsSync, NULL, _gloffset_IsSync),
+    NAME_FUNC_OFFSET( 9282, glWaitSync, glWaitSync, NULL, _gloffset_WaitSync),
+    NAME_FUNC_OFFSET( 9293, glDrawElementsBaseVertex, glDrawElementsBaseVertex, NULL, _gloffset_DrawElementsBaseVertex),
+    NAME_FUNC_OFFSET( 9318, glDrawRangeElementsBaseVertex, glDrawRangeElementsBaseVertex, NULL, _gloffset_DrawRangeElementsBaseVertex),
+    NAME_FUNC_OFFSET( 9348, glMultiDrawElementsBaseVertex, glMultiDrawElementsBaseVertex, NULL, _gloffset_MultiDrawElementsBaseVertex),
+    NAME_FUNC_OFFSET( 9378, glBindTransformFeedback, glBindTransformFeedback, NULL, _gloffset_BindTransformFeedback),
+    NAME_FUNC_OFFSET( 9402, glDeleteTransformFeedbacks, glDeleteTransformFeedbacks, NULL, _gloffset_DeleteTransformFeedbacks),
+    NAME_FUNC_OFFSET( 9429, glDrawTransformFeedback, glDrawTransformFeedback, NULL, _gloffset_DrawTransformFeedback),
+    NAME_FUNC_OFFSET( 9453, glGenTransformFeedbacks, glGenTransformFeedbacks, NULL, _gloffset_GenTransformFeedbacks),
+    NAME_FUNC_OFFSET( 9477, glIsTransformFeedback, glIsTransformFeedback, NULL, _gloffset_IsTransformFeedback),
+    NAME_FUNC_OFFSET( 9499, glPauseTransformFeedback, glPauseTransformFeedback, NULL, _gloffset_PauseTransformFeedback),
+    NAME_FUNC_OFFSET( 9524, glResumeTransformFeedback, glResumeTransformFeedback, NULL, _gloffset_ResumeTransformFeedback),
+    NAME_FUNC_OFFSET( 9550, glPolygonOffsetEXT, glPolygonOffsetEXT, NULL, _gloffset_PolygonOffsetEXT),
+    NAME_FUNC_OFFSET( 9569, gl_dispatch_stub_590, gl_dispatch_stub_590, NULL, _gloffset_GetPixelTexGenParameterfvSGIS),
+    NAME_FUNC_OFFSET( 9601, gl_dispatch_stub_591, gl_dispatch_stub_591, NULL, _gloffset_GetPixelTexGenParameterivSGIS),
+    NAME_FUNC_OFFSET( 9633, gl_dispatch_stub_592, gl_dispatch_stub_592, NULL, _gloffset_PixelTexGenParameterfSGIS),
+    NAME_FUNC_OFFSET( 9661, gl_dispatch_stub_593, gl_dispatch_stub_593, NULL, _gloffset_PixelTexGenParameterfvSGIS),
+    NAME_FUNC_OFFSET( 9690, gl_dispatch_stub_594, gl_dispatch_stub_594, NULL, _gloffset_PixelTexGenParameteriSGIS),
+    NAME_FUNC_OFFSET( 9718, gl_dispatch_stub_595, gl_dispatch_stub_595, NULL, _gloffset_PixelTexGenParameterivSGIS),
+    NAME_FUNC_OFFSET( 9747, gl_dispatch_stub_596, gl_dispatch_stub_596, NULL, _gloffset_SampleMaskSGIS),
+    NAME_FUNC_OFFSET( 9764, gl_dispatch_stub_597, gl_dispatch_stub_597, NULL, _gloffset_SamplePatternSGIS),
+    NAME_FUNC_OFFSET( 9784, glColorPointerEXT, glColorPointerEXT, NULL, _gloffset_ColorPointerEXT),
+    NAME_FUNC_OFFSET( 9802, glEdgeFlagPointerEXT, glEdgeFlagPointerEXT, NULL, _gloffset_EdgeFlagPointerEXT),
+    NAME_FUNC_OFFSET( 9823, glIndexPointerEXT, glIndexPointerEXT, NULL, _gloffset_IndexPointerEXT),
+    NAME_FUNC_OFFSET( 9841, glNormalPointerEXT, glNormalPointerEXT, NULL, _gloffset_NormalPointerEXT),
+    NAME_FUNC_OFFSET( 9860, glTexCoordPointerEXT, glTexCoordPointerEXT, NULL, _gloffset_TexCoordPointerEXT),
+    NAME_FUNC_OFFSET( 9881, glVertexPointerEXT, glVertexPointerEXT, NULL, _gloffset_VertexPointerEXT),
+    NAME_FUNC_OFFSET( 9900, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
+    NAME_FUNC_OFFSET( 9921, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
+    NAME_FUNC_OFFSET( 9943, glLockArraysEXT, glLockArraysEXT, NULL, _gloffset_LockArraysEXT),
+    NAME_FUNC_OFFSET( 9959, glUnlockArraysEXT, glUnlockArraysEXT, NULL, _gloffset_UnlockArraysEXT),
+    NAME_FUNC_OFFSET( 9977, gl_dispatch_stub_608, gl_dispatch_stub_608, NULL, _gloffset_CullParameterdvEXT),
+    NAME_FUNC_OFFSET( 9998, gl_dispatch_stub_609, gl_dispatch_stub_609, NULL, _gloffset_CullParameterfvEXT),
+    NAME_FUNC_OFFSET(10019, glSecondaryColor3bEXT, glSecondaryColor3bEXT, NULL, _gloffset_SecondaryColor3bEXT),
+    NAME_FUNC_OFFSET(10041, glSecondaryColor3bvEXT, glSecondaryColor3bvEXT, NULL, _gloffset_SecondaryColor3bvEXT),
+    NAME_FUNC_OFFSET(10064, glSecondaryColor3dEXT, glSecondaryColor3dEXT, NULL, _gloffset_SecondaryColor3dEXT),
+    NAME_FUNC_OFFSET(10086, glSecondaryColor3dvEXT, glSecondaryColor3dvEXT, NULL, _gloffset_SecondaryColor3dvEXT),
+    NAME_FUNC_OFFSET(10109, glSecondaryColor3fEXT, glSecondaryColor3fEXT, NULL, _gloffset_SecondaryColor3fEXT),
+    NAME_FUNC_OFFSET(10131, glSecondaryColor3fvEXT, glSecondaryColor3fvEXT, NULL, _gloffset_SecondaryColor3fvEXT),
+    NAME_FUNC_OFFSET(10154, glSecondaryColor3iEXT, glSecondaryColor3iEXT, NULL, _gloffset_SecondaryColor3iEXT),
+    NAME_FUNC_OFFSET(10176, glSecondaryColor3ivEXT, glSecondaryColor3ivEXT, NULL, _gloffset_SecondaryColor3ivEXT),
+    NAME_FUNC_OFFSET(10199, glSecondaryColor3sEXT, glSecondaryColor3sEXT, NULL, _gloffset_SecondaryColor3sEXT),
+    NAME_FUNC_OFFSET(10221, glSecondaryColor3svEXT, glSecondaryColor3svEXT, NULL, _gloffset_SecondaryColor3svEXT),
+    NAME_FUNC_OFFSET(10244, glSecondaryColor3ubEXT, glSecondaryColor3ubEXT, NULL, _gloffset_SecondaryColor3ubEXT),
+    NAME_FUNC_OFFSET(10267, glSecondaryColor3ubvEXT, glSecondaryColor3ubvEXT, NULL, _gloffset_SecondaryColor3ubvEXT),
+    NAME_FUNC_OFFSET(10291, glSecondaryColor3uiEXT, glSecondaryColor3uiEXT, NULL, _gloffset_SecondaryColor3uiEXT),
+    NAME_FUNC_OFFSET(10314, glSecondaryColor3uivEXT, glSecondaryColor3uivEXT, NULL, _gloffset_SecondaryColor3uivEXT),
+    NAME_FUNC_OFFSET(10338, glSecondaryColor3usEXT, glSecondaryColor3usEXT, NULL, _gloffset_SecondaryColor3usEXT),
+    NAME_FUNC_OFFSET(10361, glSecondaryColor3usvEXT, glSecondaryColor3usvEXT, NULL, _gloffset_SecondaryColor3usvEXT),
+    NAME_FUNC_OFFSET(10385, glSecondaryColorPointerEXT, glSecondaryColorPointerEXT, NULL, _gloffset_SecondaryColorPointerEXT),
+    NAME_FUNC_OFFSET(10412, glMultiDrawArraysEXT, glMultiDrawArraysEXT, NULL, _gloffset_MultiDrawArraysEXT),
+    NAME_FUNC_OFFSET(10433, glMultiDrawElementsEXT, glMultiDrawElementsEXT, NULL, _gloffset_MultiDrawElementsEXT),
+    NAME_FUNC_OFFSET(10456, glFogCoordPointerEXT, glFogCoordPointerEXT, NULL, _gloffset_FogCoordPointerEXT),
+    NAME_FUNC_OFFSET(10477, glFogCoorddEXT, glFogCoorddEXT, NULL, _gloffset_FogCoorddEXT),
+    NAME_FUNC_OFFSET(10492, glFogCoorddvEXT, glFogCoorddvEXT, NULL, _gloffset_FogCoorddvEXT),
+    NAME_FUNC_OFFSET(10508, glFogCoordfEXT, glFogCoordfEXT, NULL, _gloffset_FogCoordfEXT),
+    NAME_FUNC_OFFSET(10523, glFogCoordfvEXT, glFogCoordfvEXT, NULL, _gloffset_FogCoordfvEXT),
+    NAME_FUNC_OFFSET(10539, gl_dispatch_stub_634, gl_dispatch_stub_634, NULL, _gloffset_PixelTexGenSGIX),
+    NAME_FUNC_OFFSET(10557, glBlendFuncSeparateEXT, glBlendFuncSeparateEXT, NULL, _gloffset_BlendFuncSeparateEXT),
+    NAME_FUNC_OFFSET(10580, glFlushVertexArrayRangeNV, glFlushVertexArrayRangeNV, NULL, _gloffset_FlushVertexArrayRangeNV),
+    NAME_FUNC_OFFSET(10606, glVertexArrayRangeNV, glVertexArrayRangeNV, NULL, _gloffset_VertexArrayRangeNV),
+    NAME_FUNC_OFFSET(10627, glCombinerInputNV, glCombinerInputNV, NULL, _gloffset_CombinerInputNV),
+    NAME_FUNC_OFFSET(10645, glCombinerOutputNV, glCombinerOutputNV, NULL, _gloffset_CombinerOutputNV),
+    NAME_FUNC_OFFSET(10664, glCombinerParameterfNV, glCombinerParameterfNV, NULL, _gloffset_CombinerParameterfNV),
+    NAME_FUNC_OFFSET(10687, glCombinerParameterfvNV, glCombinerParameterfvNV, NULL, _gloffset_CombinerParameterfvNV),
+    NAME_FUNC_OFFSET(10711, glCombinerParameteriNV, glCombinerParameteriNV, NULL, _gloffset_CombinerParameteriNV),
+    NAME_FUNC_OFFSET(10734, glCombinerParameterivNV, glCombinerParameterivNV, NULL, _gloffset_CombinerParameterivNV),
+    NAME_FUNC_OFFSET(10758, glFinalCombinerInputNV, glFinalCombinerInputNV, NULL, _gloffset_FinalCombinerInputNV),
+    NAME_FUNC_OFFSET(10781, glGetCombinerInputParameterfvNV, glGetCombinerInputParameterfvNV, NULL, _gloffset_GetCombinerInputParameterfvNV),
+    NAME_FUNC_OFFSET(10813, glGetCombinerInputParameterivNV, glGetCombinerInputParameterivNV, NULL, _gloffset_GetCombinerInputParameterivNV),
+    NAME_FUNC_OFFSET(10845, glGetCombinerOutputParameterfvNV, glGetCombinerOutputParameterfvNV, NULL, _gloffset_GetCombinerOutputParameterfvNV),
+    NAME_FUNC_OFFSET(10878, glGetCombinerOutputParameterivNV, glGetCombinerOutputParameterivNV, NULL, _gloffset_GetCombinerOutputParameterivNV),
+    NAME_FUNC_OFFSET(10911, glGetFinalCombinerInputParameterfvNV, glGetFinalCombinerInputParameterfvNV, NULL, _gloffset_GetFinalCombinerInputParameterfvNV),
+    NAME_FUNC_OFFSET(10948, glGetFinalCombinerInputParameterivNV, glGetFinalCombinerInputParameterivNV, NULL, _gloffset_GetFinalCombinerInputParameterivNV),
+    NAME_FUNC_OFFSET(10985, glResizeBuffersMESA, glResizeBuffersMESA, NULL, _gloffset_ResizeBuffersMESA),
+    NAME_FUNC_OFFSET(11005, glWindowPos2dMESA, glWindowPos2dMESA, NULL, _gloffset_WindowPos2dMESA),
+    NAME_FUNC_OFFSET(11023, glWindowPos2dvMESA, glWindowPos2dvMESA, NULL, _gloffset_WindowPos2dvMESA),
+    NAME_FUNC_OFFSET(11042, glWindowPos2fMESA, glWindowPos2fMESA, NULL, _gloffset_WindowPos2fMESA),
+    NAME_FUNC_OFFSET(11060, glWindowPos2fvMESA, glWindowPos2fvMESA, NULL, _gloffset_WindowPos2fvMESA),
+    NAME_FUNC_OFFSET(11079, glWindowPos2iMESA, glWindowPos2iMESA, NULL, _gloffset_WindowPos2iMESA),
+    NAME_FUNC_OFFSET(11097, glWindowPos2ivMESA, glWindowPos2ivMESA, NULL, _gloffset_WindowPos2ivMESA),
+    NAME_FUNC_OFFSET(11116, glWindowPos2sMESA, glWindowPos2sMESA, NULL, _gloffset_WindowPos2sMESA),
+    NAME_FUNC_OFFSET(11134, glWindowPos2svMESA, glWindowPos2svMESA, NULL, _gloffset_WindowPos2svMESA),
+    NAME_FUNC_OFFSET(11153, glWindowPos3dMESA, glWindowPos3dMESA, NULL, _gloffset_WindowPos3dMESA),
+    NAME_FUNC_OFFSET(11171, glWindowPos3dvMESA, glWindowPos3dvMESA, NULL, _gloffset_WindowPos3dvMESA),
+    NAME_FUNC_OFFSET(11190, glWindowPos3fMESA, glWindowPos3fMESA, NULL, _gloffset_WindowPos3fMESA),
+    NAME_FUNC_OFFSET(11208, glWindowPos3fvMESA, glWindowPos3fvMESA, NULL, _gloffset_WindowPos3fvMESA),
+    NAME_FUNC_OFFSET(11227, glWindowPos3iMESA, glWindowPos3iMESA, NULL, _gloffset_WindowPos3iMESA),
+    NAME_FUNC_OFFSET(11245, glWindowPos3ivMESA, glWindowPos3ivMESA, NULL, _gloffset_WindowPos3ivMESA),
+    NAME_FUNC_OFFSET(11264, glWindowPos3sMESA, glWindowPos3sMESA, NULL, _gloffset_WindowPos3sMESA),
+    NAME_FUNC_OFFSET(11282, glWindowPos3svMESA, glWindowPos3svMESA, NULL, _gloffset_WindowPos3svMESA),
+    NAME_FUNC_OFFSET(11301, glWindowPos4dMESA, glWindowPos4dMESA, NULL, _gloffset_WindowPos4dMESA),
+    NAME_FUNC_OFFSET(11319, glWindowPos4dvMESA, glWindowPos4dvMESA, NULL, _gloffset_WindowPos4dvMESA),
+    NAME_FUNC_OFFSET(11338, glWindowPos4fMESA, glWindowPos4fMESA, NULL, _gloffset_WindowPos4fMESA),
+    NAME_FUNC_OFFSET(11356, glWindowPos4fvMESA, glWindowPos4fvMESA, NULL, _gloffset_WindowPos4fvMESA),
+    NAME_FUNC_OFFSET(11375, glWindowPos4iMESA, glWindowPos4iMESA, NULL, _gloffset_WindowPos4iMESA),
+    NAME_FUNC_OFFSET(11393, glWindowPos4ivMESA, glWindowPos4ivMESA, NULL, _gloffset_WindowPos4ivMESA),
+    NAME_FUNC_OFFSET(11412, glWindowPos4sMESA, glWindowPos4sMESA, NULL, _gloffset_WindowPos4sMESA),
+    NAME_FUNC_OFFSET(11430, glWindowPos4svMESA, glWindowPos4svMESA, NULL, _gloffset_WindowPos4svMESA),
+    NAME_FUNC_OFFSET(11449, gl_dispatch_stub_676, gl_dispatch_stub_676, NULL, _gloffset_MultiModeDrawArraysIBM),
+    NAME_FUNC_OFFSET(11474, gl_dispatch_stub_677, gl_dispatch_stub_677, NULL, _gloffset_MultiModeDrawElementsIBM),
+    NAME_FUNC_OFFSET(11501, gl_dispatch_stub_678, gl_dispatch_stub_678, NULL, _gloffset_DeleteFencesNV),
+    NAME_FUNC_OFFSET(11518, gl_dispatch_stub_679, gl_dispatch_stub_679, NULL, _gloffset_FinishFenceNV),
+    NAME_FUNC_OFFSET(11534, gl_dispatch_stub_680, gl_dispatch_stub_680, NULL, _gloffset_GenFencesNV),
+    NAME_FUNC_OFFSET(11548, gl_dispatch_stub_681, gl_dispatch_stub_681, NULL, _gloffset_GetFenceivNV),
+    NAME_FUNC_OFFSET(11563, gl_dispatch_stub_682, gl_dispatch_stub_682, NULL, _gloffset_IsFenceNV),
+    NAME_FUNC_OFFSET(11575, gl_dispatch_stub_683, gl_dispatch_stub_683, NULL, _gloffset_SetFenceNV),
+    NAME_FUNC_OFFSET(11588, gl_dispatch_stub_684, gl_dispatch_stub_684, NULL, _gloffset_TestFenceNV),
+    NAME_FUNC_OFFSET(11602, glAreProgramsResidentNV, glAreProgramsResidentNV, NULL, _gloffset_AreProgramsResidentNV),
+    NAME_FUNC_OFFSET(11626, glBindProgramNV, glBindProgramNV, NULL, _gloffset_BindProgramNV),
+    NAME_FUNC_OFFSET(11642, glDeleteProgramsNV, glDeleteProgramsNV, NULL, _gloffset_DeleteProgramsNV),
+    NAME_FUNC_OFFSET(11661, glExecuteProgramNV, glExecuteProgramNV, NULL, _gloffset_ExecuteProgramNV),
+    NAME_FUNC_OFFSET(11680, glGenProgramsNV, glGenProgramsNV, NULL, _gloffset_GenProgramsNV),
+    NAME_FUNC_OFFSET(11696, glGetProgramParameterdvNV, glGetProgramParameterdvNV, NULL, _gloffset_GetProgramParameterdvNV),
+    NAME_FUNC_OFFSET(11722, glGetProgramParameterfvNV, glGetProgramParameterfvNV, NULL, _gloffset_GetProgramParameterfvNV),
+    NAME_FUNC_OFFSET(11748, glGetProgramStringNV, glGetProgramStringNV, NULL, _gloffset_GetProgramStringNV),
+    NAME_FUNC_OFFSET(11769, glGetProgramivNV, glGetProgramivNV, NULL, _gloffset_GetProgramivNV),
+    NAME_FUNC_OFFSET(11786, glGetTrackMatrixivNV, glGetTrackMatrixivNV, NULL, _gloffset_GetTrackMatrixivNV),
+    NAME_FUNC_OFFSET(11807, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV),
+    NAME_FUNC_OFFSET(11835, glGetVertexAttribdvNV, glGetVertexAttribdvNV, NULL, _gloffset_GetVertexAttribdvNV),
+    NAME_FUNC_OFFSET(11857, glGetVertexAttribfvNV, glGetVertexAttribfvNV, NULL, _gloffset_GetVertexAttribfvNV),
+    NAME_FUNC_OFFSET(11879, glGetVertexAttribivNV, glGetVertexAttribivNV, NULL, _gloffset_GetVertexAttribivNV),
+    NAME_FUNC_OFFSET(11901, glIsProgramNV, glIsProgramNV, NULL, _gloffset_IsProgramNV),
+    NAME_FUNC_OFFSET(11915, glLoadProgramNV, glLoadProgramNV, NULL, _gloffset_LoadProgramNV),
+    NAME_FUNC_OFFSET(11931, glProgramParameters4dvNV, glProgramParameters4dvNV, NULL, _gloffset_ProgramParameters4dvNV),
+    NAME_FUNC_OFFSET(11956, glProgramParameters4fvNV, glProgramParameters4fvNV, NULL, _gloffset_ProgramParameters4fvNV),
+    NAME_FUNC_OFFSET(11981, glRequestResidentProgramsNV, glRequestResidentProgramsNV, NULL, _gloffset_RequestResidentProgramsNV),
+    NAME_FUNC_OFFSET(12009, glTrackMatrixNV, glTrackMatrixNV, NULL, _gloffset_TrackMatrixNV),
+    NAME_FUNC_OFFSET(12025, glVertexAttrib1dNV, glVertexAttrib1dNV, NULL, _gloffset_VertexAttrib1dNV),
+    NAME_FUNC_OFFSET(12044, glVertexAttrib1dvNV, glVertexAttrib1dvNV, NULL, _gloffset_VertexAttrib1dvNV),
+    NAME_FUNC_OFFSET(12064, glVertexAttrib1fNV, glVertexAttrib1fNV, NULL, _gloffset_VertexAttrib1fNV),
+    NAME_FUNC_OFFSET(12083, glVertexAttrib1fvNV, glVertexAttrib1fvNV, NULL, _gloffset_VertexAttrib1fvNV),
+    NAME_FUNC_OFFSET(12103, glVertexAttrib1sNV, glVertexAttrib1sNV, NULL, _gloffset_VertexAttrib1sNV),
+    NAME_FUNC_OFFSET(12122, glVertexAttrib1svNV, glVertexAttrib1svNV, NULL, _gloffset_VertexAttrib1svNV),
+    NAME_FUNC_OFFSET(12142, glVertexAttrib2dNV, glVertexAttrib2dNV, NULL, _gloffset_VertexAttrib2dNV),
+    NAME_FUNC_OFFSET(12161, glVertexAttrib2dvNV, glVertexAttrib2dvNV, NULL, _gloffset_VertexAttrib2dvNV),
+    NAME_FUNC_OFFSET(12181, glVertexAttrib2fNV, glVertexAttrib2fNV, NULL, _gloffset_VertexAttrib2fNV),
+    NAME_FUNC_OFFSET(12200, glVertexAttrib2fvNV, glVertexAttrib2fvNV, NULL, _gloffset_VertexAttrib2fvNV),
+    NAME_FUNC_OFFSET(12220, glVertexAttrib2sNV, glVertexAttrib2sNV, NULL, _gloffset_VertexAttrib2sNV),
+    NAME_FUNC_OFFSET(12239, glVertexAttrib2svNV, glVertexAttrib2svNV, NULL, _gloffset_VertexAttrib2svNV),
+    NAME_FUNC_OFFSET(12259, glVertexAttrib3dNV, glVertexAttrib3dNV, NULL, _gloffset_VertexAttrib3dNV),
+    NAME_FUNC_OFFSET(12278, glVertexAttrib3dvNV, glVertexAttrib3dvNV, NULL, _gloffset_VertexAttrib3dvNV),
+    NAME_FUNC_OFFSET(12298, glVertexAttrib3fNV, glVertexAttrib3fNV, NULL, _gloffset_VertexAttrib3fNV),
+    NAME_FUNC_OFFSET(12317, glVertexAttrib3fvNV, glVertexAttrib3fvNV, NULL, _gloffset_VertexAttrib3fvNV),
+    NAME_FUNC_OFFSET(12337, glVertexAttrib3sNV, glVertexAttrib3sNV, NULL, _gloffset_VertexAttrib3sNV),
+    NAME_FUNC_OFFSET(12356, glVertexAttrib3svNV, glVertexAttrib3svNV, NULL, _gloffset_VertexAttrib3svNV),
+    NAME_FUNC_OFFSET(12376, glVertexAttrib4dNV, glVertexAttrib4dNV, NULL, _gloffset_VertexAttrib4dNV),
+    NAME_FUNC_OFFSET(12395, glVertexAttrib4dvNV, glVertexAttrib4dvNV, NULL, _gloffset_VertexAttrib4dvNV),
+    NAME_FUNC_OFFSET(12415, glVertexAttrib4fNV, glVertexAttrib4fNV, NULL, _gloffset_VertexAttrib4fNV),
+    NAME_FUNC_OFFSET(12434, glVertexAttrib4fvNV, glVertexAttrib4fvNV, NULL, _gloffset_VertexAttrib4fvNV),
+    NAME_FUNC_OFFSET(12454, glVertexAttrib4sNV, glVertexAttrib4sNV, NULL, _gloffset_VertexAttrib4sNV),
+    NAME_FUNC_OFFSET(12473, glVertexAttrib4svNV, glVertexAttrib4svNV, NULL, _gloffset_VertexAttrib4svNV),
+    NAME_FUNC_OFFSET(12493, glVertexAttrib4ubNV, glVertexAttrib4ubNV, NULL, _gloffset_VertexAttrib4ubNV),
+    NAME_FUNC_OFFSET(12513, glVertexAttrib4ubvNV, glVertexAttrib4ubvNV, NULL, _gloffset_VertexAttrib4ubvNV),
+    NAME_FUNC_OFFSET(12534, glVertexAttribPointerNV, glVertexAttribPointerNV, NULL, _gloffset_VertexAttribPointerNV),
+    NAME_FUNC_OFFSET(12558, glVertexAttribs1dvNV, glVertexAttribs1dvNV, NULL, _gloffset_VertexAttribs1dvNV),
+    NAME_FUNC_OFFSET(12579, glVertexAttribs1fvNV, glVertexAttribs1fvNV, NULL, _gloffset_VertexAttribs1fvNV),
+    NAME_FUNC_OFFSET(12600, glVertexAttribs1svNV, glVertexAttribs1svNV, NULL, _gloffset_VertexAttribs1svNV),
+    NAME_FUNC_OFFSET(12621, glVertexAttribs2dvNV, glVertexAttribs2dvNV, NULL, _gloffset_VertexAttribs2dvNV),
+    NAME_FUNC_OFFSET(12642, glVertexAttribs2fvNV, glVertexAttribs2fvNV, NULL, _gloffset_VertexAttribs2fvNV),
+    NAME_FUNC_OFFSET(12663, glVertexAttribs2svNV, glVertexAttribs2svNV, NULL, _gloffset_VertexAttribs2svNV),
+    NAME_FUNC_OFFSET(12684, glVertexAttribs3dvNV, glVertexAttribs3dvNV, NULL, _gloffset_VertexAttribs3dvNV),
+    NAME_FUNC_OFFSET(12705, glVertexAttribs3fvNV, glVertexAttribs3fvNV, NULL, _gloffset_VertexAttribs3fvNV),
+    NAME_FUNC_OFFSET(12726, glVertexAttribs3svNV, glVertexAttribs3svNV, NULL, _gloffset_VertexAttribs3svNV),
+    NAME_FUNC_OFFSET(12747, glVertexAttribs4dvNV, glVertexAttribs4dvNV, NULL, _gloffset_VertexAttribs4dvNV),
+    NAME_FUNC_OFFSET(12768, glVertexAttribs4fvNV, glVertexAttribs4fvNV, NULL, _gloffset_VertexAttribs4fvNV),
+    NAME_FUNC_OFFSET(12789, glVertexAttribs4svNV, glVertexAttribs4svNV, NULL, _gloffset_VertexAttribs4svNV),
+    NAME_FUNC_OFFSET(12810, glVertexAttribs4ubvNV, glVertexAttribs4ubvNV, NULL, _gloffset_VertexAttribs4ubvNV),
+    NAME_FUNC_OFFSET(12832, glGetTexBumpParameterfvATI, glGetTexBumpParameterfvATI, NULL, _gloffset_GetTexBumpParameterfvATI),
+    NAME_FUNC_OFFSET(12859, glGetTexBumpParameterivATI, glGetTexBumpParameterivATI, NULL, _gloffset_GetTexBumpParameterivATI),
+    NAME_FUNC_OFFSET(12886, glTexBumpParameterfvATI, glTexBumpParameterfvATI, NULL, _gloffset_TexBumpParameterfvATI),
+    NAME_FUNC_OFFSET(12910, glTexBumpParameterivATI, glTexBumpParameterivATI, NULL, _gloffset_TexBumpParameterivATI),
+    NAME_FUNC_OFFSET(12934, glAlphaFragmentOp1ATI, glAlphaFragmentOp1ATI, NULL, _gloffset_AlphaFragmentOp1ATI),
+    NAME_FUNC_OFFSET(12956, glAlphaFragmentOp2ATI, glAlphaFragmentOp2ATI, NULL, _gloffset_AlphaFragmentOp2ATI),
+    NAME_FUNC_OFFSET(12978, glAlphaFragmentOp3ATI, glAlphaFragmentOp3ATI, NULL, _gloffset_AlphaFragmentOp3ATI),
+    NAME_FUNC_OFFSET(13000, glBeginFragmentShaderATI, glBeginFragmentShaderATI, NULL, _gloffset_BeginFragmentShaderATI),
+    NAME_FUNC_OFFSET(13025, glBindFragmentShaderATI, glBindFragmentShaderATI, NULL, _gloffset_BindFragmentShaderATI),
+    NAME_FUNC_OFFSET(13049, glColorFragmentOp1ATI, glColorFragmentOp1ATI, NULL, _gloffset_ColorFragmentOp1ATI),
+    NAME_FUNC_OFFSET(13071, glColorFragmentOp2ATI, glColorFragmentOp2ATI, NULL, _gloffset_ColorFragmentOp2ATI),
+    NAME_FUNC_OFFSET(13093, glColorFragmentOp3ATI, glColorFragmentOp3ATI, NULL, _gloffset_ColorFragmentOp3ATI),
+    NAME_FUNC_OFFSET(13115, glDeleteFragmentShaderATI, glDeleteFragmentShaderATI, NULL, _gloffset_DeleteFragmentShaderATI),
+    NAME_FUNC_OFFSET(13141, glEndFragmentShaderATI, glEndFragmentShaderATI, NULL, _gloffset_EndFragmentShaderATI),
+    NAME_FUNC_OFFSET(13164, glGenFragmentShadersATI, glGenFragmentShadersATI, NULL, _gloffset_GenFragmentShadersATI),
+    NAME_FUNC_OFFSET(13188, glPassTexCoordATI, glPassTexCoordATI, NULL, _gloffset_PassTexCoordATI),
+    NAME_FUNC_OFFSET(13206, glSampleMapATI, glSampleMapATI, NULL, _gloffset_SampleMapATI),
+    NAME_FUNC_OFFSET(13221, glSetFragmentShaderConstantATI, glSetFragmentShaderConstantATI, NULL, _gloffset_SetFragmentShaderConstantATI),
+    NAME_FUNC_OFFSET(13252, glPointParameteriNV, glPointParameteriNV, NULL, _gloffset_PointParameteriNV),
+    NAME_FUNC_OFFSET(13272, glPointParameterivNV, glPointParameterivNV, NULL, _gloffset_PointParameterivNV),
+    NAME_FUNC_OFFSET(13293, gl_dispatch_stub_765, gl_dispatch_stub_765, NULL, _gloffset_ActiveStencilFaceEXT),
+    NAME_FUNC_OFFSET(13316, gl_dispatch_stub_766, gl_dispatch_stub_766, NULL, _gloffset_BindVertexArrayAPPLE),
+    NAME_FUNC_OFFSET(13339, gl_dispatch_stub_767, gl_dispatch_stub_767, NULL, _gloffset_DeleteVertexArraysAPPLE),
+    NAME_FUNC_OFFSET(13365, gl_dispatch_stub_768, gl_dispatch_stub_768, NULL, _gloffset_GenVertexArraysAPPLE),
+    NAME_FUNC_OFFSET(13388, gl_dispatch_stub_769, gl_dispatch_stub_769, NULL, _gloffset_IsVertexArrayAPPLE),
+    NAME_FUNC_OFFSET(13409, glGetProgramNamedParameterdvNV, glGetProgramNamedParameterdvNV, NULL, _gloffset_GetProgramNamedParameterdvNV),
+    NAME_FUNC_OFFSET(13440, glGetProgramNamedParameterfvNV, glGetProgramNamedParameterfvNV, NULL, _gloffset_GetProgramNamedParameterfvNV),
+    NAME_FUNC_OFFSET(13471, glProgramNamedParameter4dNV, glProgramNamedParameter4dNV, NULL, _gloffset_ProgramNamedParameter4dNV),
+    NAME_FUNC_OFFSET(13499, glProgramNamedParameter4dvNV, glProgramNamedParameter4dvNV, NULL, _gloffset_ProgramNamedParameter4dvNV),
+    NAME_FUNC_OFFSET(13528, glProgramNamedParameter4fNV, glProgramNamedParameter4fNV, NULL, _gloffset_ProgramNamedParameter4fNV),
+    NAME_FUNC_OFFSET(13556, glProgramNamedParameter4fvNV, glProgramNamedParameter4fvNV, NULL, _gloffset_ProgramNamedParameter4fvNV),
+    NAME_FUNC_OFFSET(13585, gl_dispatch_stub_776, gl_dispatch_stub_776, NULL, _gloffset_DepthBoundsEXT),
+    NAME_FUNC_OFFSET(13602, gl_dispatch_stub_777, gl_dispatch_stub_777, NULL, _gloffset_BlendEquationSeparateEXT),
+    NAME_FUNC_OFFSET(13629, glBindFramebufferEXT, glBindFramebufferEXT, NULL, _gloffset_BindFramebufferEXT),
+    NAME_FUNC_OFFSET(13650, glBindRenderbufferEXT, glBindRenderbufferEXT, NULL, _gloffset_BindRenderbufferEXT),
+    NAME_FUNC_OFFSET(13672, glCheckFramebufferStatusEXT, glCheckFramebufferStatusEXT, NULL, _gloffset_CheckFramebufferStatusEXT),
+    NAME_FUNC_OFFSET(13700, glDeleteFramebuffersEXT, glDeleteFramebuffersEXT, NULL, _gloffset_DeleteFramebuffersEXT),
+    NAME_FUNC_OFFSET(13724, glDeleteRenderbuffersEXT, glDeleteRenderbuffersEXT, NULL, _gloffset_DeleteRenderbuffersEXT),
+    NAME_FUNC_OFFSET(13749, glFramebufferRenderbufferEXT, glFramebufferRenderbufferEXT, NULL, _gloffset_FramebufferRenderbufferEXT),
+    NAME_FUNC_OFFSET(13778, glFramebufferTexture1DEXT, glFramebufferTexture1DEXT, NULL, _gloffset_FramebufferTexture1DEXT),
+    NAME_FUNC_OFFSET(13804, glFramebufferTexture2DEXT, glFramebufferTexture2DEXT, NULL, _gloffset_FramebufferTexture2DEXT),
+    NAME_FUNC_OFFSET(13830, glFramebufferTexture3DEXT, glFramebufferTexture3DEXT, NULL, _gloffset_FramebufferTexture3DEXT),
+    NAME_FUNC_OFFSET(13856, glGenFramebuffersEXT, glGenFramebuffersEXT, NULL, _gloffset_GenFramebuffersEXT),
+    NAME_FUNC_OFFSET(13877, glGenRenderbuffersEXT, glGenRenderbuffersEXT, NULL, _gloffset_GenRenderbuffersEXT),
+    NAME_FUNC_OFFSET(13899, glGenerateMipmapEXT, glGenerateMipmapEXT, NULL, _gloffset_GenerateMipmapEXT),
+    NAME_FUNC_OFFSET(13919, glGetFramebufferAttachmentParameterivEXT, glGetFramebufferAttachmentParameterivEXT, NULL, _gloffset_GetFramebufferAttachmentParameterivEXT),
+    NAME_FUNC_OFFSET(13960, glGetRenderbufferParameterivEXT, glGetRenderbufferParameterivEXT, NULL, _gloffset_GetRenderbufferParameterivEXT),
+    NAME_FUNC_OFFSET(13992, glIsFramebufferEXT, glIsFramebufferEXT, NULL, _gloffset_IsFramebufferEXT),
+    NAME_FUNC_OFFSET(14011, glIsRenderbufferEXT, glIsRenderbufferEXT, NULL, _gloffset_IsRenderbufferEXT),
+    NAME_FUNC_OFFSET(14031, glRenderbufferStorageEXT, glRenderbufferStorageEXT, NULL, _gloffset_RenderbufferStorageEXT),
+    NAME_FUNC_OFFSET(14056, gl_dispatch_stub_795, gl_dispatch_stub_795, NULL, _gloffset_BlitFramebufferEXT),
+    NAME_FUNC_OFFSET(14077, gl_dispatch_stub_796, gl_dispatch_stub_796, NULL, _gloffset_BufferParameteriAPPLE),
+    NAME_FUNC_OFFSET(14101, gl_dispatch_stub_797, gl_dispatch_stub_797, NULL, _gloffset_FlushMappedBufferRangeAPPLE),
+    NAME_FUNC_OFFSET(14131, glFramebufferTextureLayerEXT, glFramebufferTextureLayerEXT, NULL, _gloffset_FramebufferTextureLayerEXT),
+    NAME_FUNC_OFFSET(14160, glColorMaskIndexedEXT, glColorMaskIndexedEXT, NULL, _gloffset_ColorMaskIndexedEXT),
+    NAME_FUNC_OFFSET(14182, glDisableIndexedEXT, glDisableIndexedEXT, NULL, _gloffset_DisableIndexedEXT),
+    NAME_FUNC_OFFSET(14202, glEnableIndexedEXT, glEnableIndexedEXT, NULL, _gloffset_EnableIndexedEXT),
+    NAME_FUNC_OFFSET(14221, glGetBooleanIndexedvEXT, glGetBooleanIndexedvEXT, NULL, _gloffset_GetBooleanIndexedvEXT),
+    NAME_FUNC_OFFSET(14245, glGetIntegerIndexedvEXT, glGetIntegerIndexedvEXT, NULL, _gloffset_GetIntegerIndexedvEXT),
+    NAME_FUNC_OFFSET(14269, glIsEnabledIndexedEXT, glIsEnabledIndexedEXT, NULL, _gloffset_IsEnabledIndexedEXT),
+    NAME_FUNC_OFFSET(14291, glBeginConditionalRenderNV, glBeginConditionalRenderNV, NULL, _gloffset_BeginConditionalRenderNV),
+    NAME_FUNC_OFFSET(14318, glEndConditionalRenderNV, glEndConditionalRenderNV, NULL, _gloffset_EndConditionalRenderNV),
+    NAME_FUNC_OFFSET(14343, glBeginTransformFeedbackEXT, glBeginTransformFeedbackEXT, NULL, _gloffset_BeginTransformFeedbackEXT),
+    NAME_FUNC_OFFSET(14371, glBindBufferBaseEXT, glBindBufferBaseEXT, NULL, _gloffset_BindBufferBaseEXT),
+    NAME_FUNC_OFFSET(14391, glBindBufferOffsetEXT, glBindBufferOffsetEXT, NULL, _gloffset_BindBufferOffsetEXT),
+    NAME_FUNC_OFFSET(14413, glBindBufferRangeEXT, glBindBufferRangeEXT, NULL, _gloffset_BindBufferRangeEXT),
+    NAME_FUNC_OFFSET(14434, glEndTransformFeedbackEXT, glEndTransformFeedbackEXT, NULL, _gloffset_EndTransformFeedbackEXT),
+    NAME_FUNC_OFFSET(14460, glGetTransformFeedbackVaryingEXT, glGetTransformFeedbackVaryingEXT, NULL, _gloffset_GetTransformFeedbackVaryingEXT),
+    NAME_FUNC_OFFSET(14493, glTransformFeedbackVaryingsEXT, glTransformFeedbackVaryingsEXT, NULL, _gloffset_TransformFeedbackVaryingsEXT),
+    NAME_FUNC_OFFSET(14524, glProvokingVertexEXT, glProvokingVertexEXT, NULL, _gloffset_ProvokingVertexEXT),
+    NAME_FUNC_OFFSET(14545, gl_dispatch_stub_815, gl_dispatch_stub_815, NULL, _gloffset_GetTexParameterPointervAPPLE),
+    NAME_FUNC_OFFSET(14576, gl_dispatch_stub_816, gl_dispatch_stub_816, NULL, _gloffset_TextureRangeAPPLE),
+    NAME_FUNC_OFFSET(14596, glGetObjectParameterivAPPLE, glGetObjectParameterivAPPLE, NULL, _gloffset_GetObjectParameterivAPPLE),
+    NAME_FUNC_OFFSET(14624, glObjectPurgeableAPPLE, glObjectPurgeableAPPLE, NULL, _gloffset_ObjectPurgeableAPPLE),
+    NAME_FUNC_OFFSET(14647, glObjectUnpurgeableAPPLE, glObjectUnpurgeableAPPLE, NULL, _gloffset_ObjectUnpurgeableAPPLE),
+    NAME_FUNC_OFFSET(14672, gl_dispatch_stub_820, gl_dispatch_stub_820, NULL, _gloffset_StencilFuncSeparateATI),
+    NAME_FUNC_OFFSET(14697, gl_dispatch_stub_821, gl_dispatch_stub_821, NULL, _gloffset_ProgramEnvParameters4fvEXT),
+    NAME_FUNC_OFFSET(14726, gl_dispatch_stub_822, gl_dispatch_stub_822, NULL, _gloffset_ProgramLocalParameters4fvEXT),
+    NAME_FUNC_OFFSET(14757, gl_dispatch_stub_823, gl_dispatch_stub_823, NULL, _gloffset_GetQueryObjecti64vEXT),
+    NAME_FUNC_OFFSET(14781, gl_dispatch_stub_824, gl_dispatch_stub_824, NULL, _gloffset_GetQueryObjectui64vEXT),
+    NAME_FUNC_OFFSET(14806, glEGLImageTargetRenderbufferStorageOES, glEGLImageTargetRenderbufferStorageOES, NULL, _gloffset_EGLImageTargetRenderbufferStorageOES),
+    NAME_FUNC_OFFSET(14845, glEGLImageTargetTexture2DOES, glEGLImageTargetTexture2DOES, NULL, _gloffset_EGLImageTargetTexture2DOES),
+    NAME_FUNC_OFFSET(14874, glArrayElement, glArrayElement, NULL, _gloffset_ArrayElement),
+    NAME_FUNC_OFFSET(14892, glBindTexture, glBindTexture, NULL, _gloffset_BindTexture),
+    NAME_FUNC_OFFSET(14909, glDrawArrays, glDrawArrays, NULL, _gloffset_DrawArrays),
+    NAME_FUNC_OFFSET(14925, glAreTexturesResident, glAreTexturesResidentEXT, glAreTexturesResidentEXT, _gloffset_AreTexturesResident),
+    NAME_FUNC_OFFSET(14950, glCopyTexImage1D, glCopyTexImage1D, NULL, _gloffset_CopyTexImage1D),
+    NAME_FUNC_OFFSET(14970, glCopyTexImage2D, glCopyTexImage2D, NULL, _gloffset_CopyTexImage2D),
+    NAME_FUNC_OFFSET(14990, glCopyTexSubImage1D, glCopyTexSubImage1D, NULL, _gloffset_CopyTexSubImage1D),
+    NAME_FUNC_OFFSET(15013, glCopyTexSubImage2D, glCopyTexSubImage2D, NULL, _gloffset_CopyTexSubImage2D),
+    NAME_FUNC_OFFSET(15036, glDeleteTextures, glDeleteTexturesEXT, glDeleteTexturesEXT, _gloffset_DeleteTextures),
+    NAME_FUNC_OFFSET(15056, glGenTextures, glGenTexturesEXT, glGenTexturesEXT, _gloffset_GenTextures),
+    NAME_FUNC_OFFSET(15073, glGetPointerv, glGetPointerv, NULL, _gloffset_GetPointerv),
+    NAME_FUNC_OFFSET(15090, glIsTexture, glIsTextureEXT, glIsTextureEXT, _gloffset_IsTexture),
+    NAME_FUNC_OFFSET(15105, glPrioritizeTextures, glPrioritizeTextures, NULL, _gloffset_PrioritizeTextures),
+    NAME_FUNC_OFFSET(15129, glTexSubImage1D, glTexSubImage1D, NULL, _gloffset_TexSubImage1D),
+    NAME_FUNC_OFFSET(15148, glTexSubImage2D, glTexSubImage2D, NULL, _gloffset_TexSubImage2D),
+    NAME_FUNC_OFFSET(15167, glBlendColor, glBlendColor, NULL, _gloffset_BlendColor),
+    NAME_FUNC_OFFSET(15183, glBlendEquation, glBlendEquation, NULL, _gloffset_BlendEquation),
+    NAME_FUNC_OFFSET(15202, glDrawRangeElements, glDrawRangeElements, NULL, _gloffset_DrawRangeElements),
+    NAME_FUNC_OFFSET(15225, glColorTable, glColorTable, NULL, _gloffset_ColorTable),
+    NAME_FUNC_OFFSET(15241, glColorTable, glColorTable, NULL, _gloffset_ColorTable),
+    NAME_FUNC_OFFSET(15257, glColorTableParameterfv, glColorTableParameterfv, NULL, _gloffset_ColorTableParameterfv),
+    NAME_FUNC_OFFSET(15284, glColorTableParameteriv, glColorTableParameteriv, NULL, _gloffset_ColorTableParameteriv),
+    NAME_FUNC_OFFSET(15311, glCopyColorTable, glCopyColorTable, NULL, _gloffset_CopyColorTable),
+    NAME_FUNC_OFFSET(15331, glGetColorTable, glGetColorTableEXT, glGetColorTableEXT, _gloffset_GetColorTable),
+    NAME_FUNC_OFFSET(15350, glGetColorTable, glGetColorTableEXT, glGetColorTableEXT, _gloffset_GetColorTable),
+    NAME_FUNC_OFFSET(15369, glGetColorTableParameterfv, glGetColorTableParameterfvEXT, glGetColorTableParameterfvEXT, _gloffset_GetColorTableParameterfv),
+    NAME_FUNC_OFFSET(15399, glGetColorTableParameterfv, glGetColorTableParameterfvEXT, glGetColorTableParameterfvEXT, _gloffset_GetColorTableParameterfv),
+    NAME_FUNC_OFFSET(15429, glGetColorTableParameteriv, glGetColorTableParameterivEXT, glGetColorTableParameterivEXT, _gloffset_GetColorTableParameteriv),
+    NAME_FUNC_OFFSET(15459, glGetColorTableParameteriv, glGetColorTableParameterivEXT, glGetColorTableParameterivEXT, _gloffset_GetColorTableParameteriv),
+    NAME_FUNC_OFFSET(15489, glColorSubTable, glColorSubTable, NULL, _gloffset_ColorSubTable),
+    NAME_FUNC_OFFSET(15508, glCopyColorSubTable, glCopyColorSubTable, NULL, _gloffset_CopyColorSubTable),
+    NAME_FUNC_OFFSET(15531, glConvolutionFilter1D, glConvolutionFilter1D, NULL, _gloffset_ConvolutionFilter1D),
+    NAME_FUNC_OFFSET(15556, glConvolutionFilter2D, glConvolutionFilter2D, NULL, _gloffset_ConvolutionFilter2D),
+    NAME_FUNC_OFFSET(15581, glConvolutionParameterf, glConvolutionParameterf, NULL, _gloffset_ConvolutionParameterf),
+    NAME_FUNC_OFFSET(15608, glConvolutionParameterfv, glConvolutionParameterfv, NULL, _gloffset_ConvolutionParameterfv),
+    NAME_FUNC_OFFSET(15636, glConvolutionParameteri, glConvolutionParameteri, NULL, _gloffset_ConvolutionParameteri),
+    NAME_FUNC_OFFSET(15663, glConvolutionParameteriv, glConvolutionParameteriv, NULL, _gloffset_ConvolutionParameteriv),
+    NAME_FUNC_OFFSET(15691, glCopyConvolutionFilter1D, glCopyConvolutionFilter1D, NULL, _gloffset_CopyConvolutionFilter1D),
+    NAME_FUNC_OFFSET(15720, glCopyConvolutionFilter2D, glCopyConvolutionFilter2D, NULL, _gloffset_CopyConvolutionFilter2D),
+    NAME_FUNC_OFFSET(15749, glGetConvolutionFilter, gl_dispatch_stub_356, gl_dispatch_stub_356, _gloffset_GetConvolutionFilter),
+    NAME_FUNC_OFFSET(15775, glGetConvolutionParameterfv, gl_dispatch_stub_357, gl_dispatch_stub_357, _gloffset_GetConvolutionParameterfv),
+    NAME_FUNC_OFFSET(15806, glGetConvolutionParameteriv, gl_dispatch_stub_358, gl_dispatch_stub_358, _gloffset_GetConvolutionParameteriv),
+    NAME_FUNC_OFFSET(15837, glGetSeparableFilter, gl_dispatch_stub_359, gl_dispatch_stub_359, _gloffset_GetSeparableFilter),
+    NAME_FUNC_OFFSET(15861, glSeparableFilter2D, glSeparableFilter2D, NULL, _gloffset_SeparableFilter2D),
+    NAME_FUNC_OFFSET(15884, glGetHistogram, gl_dispatch_stub_361, gl_dispatch_stub_361, _gloffset_GetHistogram),
+    NAME_FUNC_OFFSET(15902, glGetHistogramParameterfv, gl_dispatch_stub_362, gl_dispatch_stub_362, _gloffset_GetHistogramParameterfv),
+    NAME_FUNC_OFFSET(15931, glGetHistogramParameteriv, gl_dispatch_stub_363, gl_dispatch_stub_363, _gloffset_GetHistogramParameteriv),
+    NAME_FUNC_OFFSET(15960, glGetMinmax, gl_dispatch_stub_364, gl_dispatch_stub_364, _gloffset_GetMinmax),
+    NAME_FUNC_OFFSET(15975, glGetMinmaxParameterfv, gl_dispatch_stub_365, gl_dispatch_stub_365, _gloffset_GetMinmaxParameterfv),
+    NAME_FUNC_OFFSET(16001, glGetMinmaxParameteriv, gl_dispatch_stub_366, gl_dispatch_stub_366, _gloffset_GetMinmaxParameteriv),
+    NAME_FUNC_OFFSET(16027, glHistogram, glHistogram, NULL, _gloffset_Histogram),
+    NAME_FUNC_OFFSET(16042, glMinmax, glMinmax, NULL, _gloffset_Minmax),
+    NAME_FUNC_OFFSET(16054, glResetHistogram, glResetHistogram, NULL, _gloffset_ResetHistogram),
+    NAME_FUNC_OFFSET(16074, glResetMinmax, glResetMinmax, NULL, _gloffset_ResetMinmax),
+    NAME_FUNC_OFFSET(16091, glTexImage3D, glTexImage3D, NULL, _gloffset_TexImage3D),
+    NAME_FUNC_OFFSET(16107, glTexSubImage3D, glTexSubImage3D, NULL, _gloffset_TexSubImage3D),
+    NAME_FUNC_OFFSET(16126, glCopyTexSubImage3D, glCopyTexSubImage3D, NULL, _gloffset_CopyTexSubImage3D),
+    NAME_FUNC_OFFSET(16149, glActiveTextureARB, glActiveTextureARB, NULL, _gloffset_ActiveTextureARB),
+    NAME_FUNC_OFFSET(16165, glClientActiveTextureARB, glClientActiveTextureARB, NULL, _gloffset_ClientActiveTextureARB),
+    NAME_FUNC_OFFSET(16187, glMultiTexCoord1dARB, glMultiTexCoord1dARB, NULL, _gloffset_MultiTexCoord1dARB),
+    NAME_FUNC_OFFSET(16205, glMultiTexCoord1dvARB, glMultiTexCoord1dvARB, NULL, _gloffset_MultiTexCoord1dvARB),
+    NAME_FUNC_OFFSET(16224, glMultiTexCoord1fARB, glMultiTexCoord1fARB, NULL, _gloffset_MultiTexCoord1fARB),
+    NAME_FUNC_OFFSET(16242, glMultiTexCoord1fvARB, glMultiTexCoord1fvARB, NULL, _gloffset_MultiTexCoord1fvARB),
+    NAME_FUNC_OFFSET(16261, glMultiTexCoord1iARB, glMultiTexCoord1iARB, NULL, _gloffset_MultiTexCoord1iARB),
+    NAME_FUNC_OFFSET(16279, glMultiTexCoord1ivARB, glMultiTexCoord1ivARB, NULL, _gloffset_MultiTexCoord1ivARB),
+    NAME_FUNC_OFFSET(16298, glMultiTexCoord1sARB, glMultiTexCoord1sARB, NULL, _gloffset_MultiTexCoord1sARB),
+    NAME_FUNC_OFFSET(16316, glMultiTexCoord1svARB, glMultiTexCoord1svARB, NULL, _gloffset_MultiTexCoord1svARB),
+    NAME_FUNC_OFFSET(16335, glMultiTexCoord2dARB, glMultiTexCoord2dARB, NULL, _gloffset_MultiTexCoord2dARB),
+    NAME_FUNC_OFFSET(16353, glMultiTexCoord2dvARB, glMultiTexCoord2dvARB, NULL, _gloffset_MultiTexCoord2dvARB),
+    NAME_FUNC_OFFSET(16372, glMultiTexCoord2fARB, glMultiTexCoord2fARB, NULL, _gloffset_MultiTexCoord2fARB),
+    NAME_FUNC_OFFSET(16390, glMultiTexCoord2fvARB, glMultiTexCoord2fvARB, NULL, _gloffset_MultiTexCoord2fvARB),
+    NAME_FUNC_OFFSET(16409, glMultiTexCoord2iARB, glMultiTexCoord2iARB, NULL, _gloffset_MultiTexCoord2iARB),
+    NAME_FUNC_OFFSET(16427, glMultiTexCoord2ivARB, glMultiTexCoord2ivARB, NULL, _gloffset_MultiTexCoord2ivARB),
+    NAME_FUNC_OFFSET(16446, glMultiTexCoord2sARB, glMultiTexCoord2sARB, NULL, _gloffset_MultiTexCoord2sARB),
+    NAME_FUNC_OFFSET(16464, glMultiTexCoord2svARB, glMultiTexCoord2svARB, NULL, _gloffset_MultiTexCoord2svARB),
+    NAME_FUNC_OFFSET(16483, glMultiTexCoord3dARB, glMultiTexCoord3dARB, NULL, _gloffset_MultiTexCoord3dARB),
+    NAME_FUNC_OFFSET(16501, glMultiTexCoord3dvARB, glMultiTexCoord3dvARB, NULL, _gloffset_MultiTexCoord3dvARB),
+    NAME_FUNC_OFFSET(16520, glMultiTexCoord3fARB, glMultiTexCoord3fARB, NULL, _gloffset_MultiTexCoord3fARB),
+    NAME_FUNC_OFFSET(16538, glMultiTexCoord3fvARB, glMultiTexCoord3fvARB, NULL, _gloffset_MultiTexCoord3fvARB),
+    NAME_FUNC_OFFSET(16557, glMultiTexCoord3iARB, glMultiTexCoord3iARB, NULL, _gloffset_MultiTexCoord3iARB),
+    NAME_FUNC_OFFSET(16575, glMultiTexCoord3ivARB, glMultiTexCoord3ivARB, NULL, _gloffset_MultiTexCoord3ivARB),
+    NAME_FUNC_OFFSET(16594, glMultiTexCoord3sARB, glMultiTexCoord3sARB, NULL, _gloffset_MultiTexCoord3sARB),
+    NAME_FUNC_OFFSET(16612, glMultiTexCoord3svARB, glMultiTexCoord3svARB, NULL, _gloffset_MultiTexCoord3svARB),
+    NAME_FUNC_OFFSET(16631, glMultiTexCoord4dARB, glMultiTexCoord4dARB, NULL, _gloffset_MultiTexCoord4dARB),
+    NAME_FUNC_OFFSET(16649, glMultiTexCoord4dvARB, glMultiTexCoord4dvARB, NULL, _gloffset_MultiTexCoord4dvARB),
+    NAME_FUNC_OFFSET(16668, glMultiTexCoord4fARB, glMultiTexCoord4fARB, NULL, _gloffset_MultiTexCoord4fARB),
+    NAME_FUNC_OFFSET(16686, glMultiTexCoord4fvARB, glMultiTexCoord4fvARB, NULL, _gloffset_MultiTexCoord4fvARB),
+    NAME_FUNC_OFFSET(16705, glMultiTexCoord4iARB, glMultiTexCoord4iARB, NULL, _gloffset_MultiTexCoord4iARB),
+    NAME_FUNC_OFFSET(16723, glMultiTexCoord4ivARB, glMultiTexCoord4ivARB, NULL, _gloffset_MultiTexCoord4ivARB),
+    NAME_FUNC_OFFSET(16742, glMultiTexCoord4sARB, glMultiTexCoord4sARB, NULL, _gloffset_MultiTexCoord4sARB),
+    NAME_FUNC_OFFSET(16760, glMultiTexCoord4svARB, glMultiTexCoord4svARB, NULL, _gloffset_MultiTexCoord4svARB),
+    NAME_FUNC_OFFSET(16779, glStencilOpSeparate, glStencilOpSeparate, NULL, _gloffset_StencilOpSeparate),
+    NAME_FUNC_OFFSET(16802, glDrawArraysInstanced, glDrawArraysInstanced, NULL, _gloffset_DrawArraysInstanced),
+    NAME_FUNC_OFFSET(16827, glDrawArraysInstanced, glDrawArraysInstanced, NULL, _gloffset_DrawArraysInstanced),
+    NAME_FUNC_OFFSET(16852, glDrawElementsInstanced, glDrawElementsInstanced, NULL, _gloffset_DrawElementsInstanced),
+    NAME_FUNC_OFFSET(16879, glDrawElementsInstanced, glDrawElementsInstanced, NULL, _gloffset_DrawElementsInstanced),
+    NAME_FUNC_OFFSET(16906, glLoadTransposeMatrixdARB, glLoadTransposeMatrixdARB, NULL, _gloffset_LoadTransposeMatrixdARB),
+    NAME_FUNC_OFFSET(16929, glLoadTransposeMatrixfARB, glLoadTransposeMatrixfARB, NULL, _gloffset_LoadTransposeMatrixfARB),
+    NAME_FUNC_OFFSET(16952, glMultTransposeMatrixdARB, glMultTransposeMatrixdARB, NULL, _gloffset_MultTransposeMatrixdARB),
+    NAME_FUNC_OFFSET(16975, glMultTransposeMatrixfARB, glMultTransposeMatrixfARB, NULL, _gloffset_MultTransposeMatrixfARB),
+    NAME_FUNC_OFFSET(16998, glSampleCoverageARB, glSampleCoverageARB, NULL, _gloffset_SampleCoverageARB),
+    NAME_FUNC_OFFSET(17015, glCompressedTexImage1DARB, glCompressedTexImage1DARB, NULL, _gloffset_CompressedTexImage1DARB),
+    NAME_FUNC_OFFSET(17038, glCompressedTexImage2DARB, glCompressedTexImage2DARB, NULL, _gloffset_CompressedTexImage2DARB),
+    NAME_FUNC_OFFSET(17061, glCompressedTexImage3DARB, glCompressedTexImage3DARB, NULL, _gloffset_CompressedTexImage3DARB),
+    NAME_FUNC_OFFSET(17084, glCompressedTexSubImage1DARB, glCompressedTexSubImage1DARB, NULL, _gloffset_CompressedTexSubImage1DARB),
+    NAME_FUNC_OFFSET(17110, glCompressedTexSubImage2DARB, glCompressedTexSubImage2DARB, NULL, _gloffset_CompressedTexSubImage2DARB),
+    NAME_FUNC_OFFSET(17136, glCompressedTexSubImage3DARB, glCompressedTexSubImage3DARB, NULL, _gloffset_CompressedTexSubImage3DARB),
+    NAME_FUNC_OFFSET(17162, glGetCompressedTexImageARB, glGetCompressedTexImageARB, NULL, _gloffset_GetCompressedTexImageARB),
+    NAME_FUNC_OFFSET(17186, glDisableVertexAttribArrayARB, glDisableVertexAttribArrayARB, NULL, _gloffset_DisableVertexAttribArrayARB),
+    NAME_FUNC_OFFSET(17213, glEnableVertexAttribArrayARB, glEnableVertexAttribArrayARB, NULL, _gloffset_EnableVertexAttribArrayARB),
+    NAME_FUNC_OFFSET(17239, glGetVertexAttribdvARB, glGetVertexAttribdvARB, NULL, _gloffset_GetVertexAttribdvARB),
+    NAME_FUNC_OFFSET(17259, glGetVertexAttribfvARB, glGetVertexAttribfvARB, NULL, _gloffset_GetVertexAttribfvARB),
+    NAME_FUNC_OFFSET(17279, glGetVertexAttribivARB, glGetVertexAttribivARB, NULL, _gloffset_GetVertexAttribivARB),
+    NAME_FUNC_OFFSET(17299, glProgramEnvParameter4dARB, glProgramEnvParameter4dARB, NULL, _gloffset_ProgramEnvParameter4dARB),
+    NAME_FUNC_OFFSET(17322, glProgramEnvParameter4dvARB, glProgramEnvParameter4dvARB, NULL, _gloffset_ProgramEnvParameter4dvARB),
+    NAME_FUNC_OFFSET(17346, glProgramEnvParameter4fARB, glProgramEnvParameter4fARB, NULL, _gloffset_ProgramEnvParameter4fARB),
+    NAME_FUNC_OFFSET(17369, glProgramEnvParameter4fvARB, glProgramEnvParameter4fvARB, NULL, _gloffset_ProgramEnvParameter4fvARB),
+    NAME_FUNC_OFFSET(17393, glVertexAttrib1dARB, glVertexAttrib1dARB, NULL, _gloffset_VertexAttrib1dARB),
+    NAME_FUNC_OFFSET(17410, glVertexAttrib1dvARB, glVertexAttrib1dvARB, NULL, _gloffset_VertexAttrib1dvARB),
+    NAME_FUNC_OFFSET(17428, glVertexAttrib1fARB, glVertexAttrib1fARB, NULL, _gloffset_VertexAttrib1fARB),
+    NAME_FUNC_OFFSET(17445, glVertexAttrib1fvARB, glVertexAttrib1fvARB, NULL, _gloffset_VertexAttrib1fvARB),
+    NAME_FUNC_OFFSET(17463, glVertexAttrib1sARB, glVertexAttrib1sARB, NULL, _gloffset_VertexAttrib1sARB),
+    NAME_FUNC_OFFSET(17480, glVertexAttrib1svARB, glVertexAttrib1svARB, NULL, _gloffset_VertexAttrib1svARB),
+    NAME_FUNC_OFFSET(17498, glVertexAttrib2dARB, glVertexAttrib2dARB, NULL, _gloffset_VertexAttrib2dARB),
+    NAME_FUNC_OFFSET(17515, glVertexAttrib2dvARB, glVertexAttrib2dvARB, NULL, _gloffset_VertexAttrib2dvARB),
+    NAME_FUNC_OFFSET(17533, glVertexAttrib2fARB, glVertexAttrib2fARB, NULL, _gloffset_VertexAttrib2fARB),
+    NAME_FUNC_OFFSET(17550, glVertexAttrib2fvARB, glVertexAttrib2fvARB, NULL, _gloffset_VertexAttrib2fvARB),
+    NAME_FUNC_OFFSET(17568, glVertexAttrib2sARB, glVertexAttrib2sARB, NULL, _gloffset_VertexAttrib2sARB),
+    NAME_FUNC_OFFSET(17585, glVertexAttrib2svARB, glVertexAttrib2svARB, NULL, _gloffset_VertexAttrib2svARB),
+    NAME_FUNC_OFFSET(17603, glVertexAttrib3dARB, glVertexAttrib3dARB, NULL, _gloffset_VertexAttrib3dARB),
+    NAME_FUNC_OFFSET(17620, glVertexAttrib3dvARB, glVertexAttrib3dvARB, NULL, _gloffset_VertexAttrib3dvARB),
+    NAME_FUNC_OFFSET(17638, glVertexAttrib3fARB, glVertexAttrib3fARB, NULL, _gloffset_VertexAttrib3fARB),
+    NAME_FUNC_OFFSET(17655, glVertexAttrib3fvARB, glVertexAttrib3fvARB, NULL, _gloffset_VertexAttrib3fvARB),
+    NAME_FUNC_OFFSET(17673, glVertexAttrib3sARB, glVertexAttrib3sARB, NULL, _gloffset_VertexAttrib3sARB),
+    NAME_FUNC_OFFSET(17690, glVertexAttrib3svARB, glVertexAttrib3svARB, NULL, _gloffset_VertexAttrib3svARB),
+    NAME_FUNC_OFFSET(17708, glVertexAttrib4NbvARB, glVertexAttrib4NbvARB, NULL, _gloffset_VertexAttrib4NbvARB),
+    NAME_FUNC_OFFSET(17727, glVertexAttrib4NivARB, glVertexAttrib4NivARB, NULL, _gloffset_VertexAttrib4NivARB),
+    NAME_FUNC_OFFSET(17746, glVertexAttrib4NsvARB, glVertexAttrib4NsvARB, NULL, _gloffset_VertexAttrib4NsvARB),
+    NAME_FUNC_OFFSET(17765, glVertexAttrib4NubARB, glVertexAttrib4NubARB, NULL, _gloffset_VertexAttrib4NubARB),
+    NAME_FUNC_OFFSET(17784, glVertexAttrib4NubvARB, glVertexAttrib4NubvARB, NULL, _gloffset_VertexAttrib4NubvARB),
+    NAME_FUNC_OFFSET(17804, glVertexAttrib4NuivARB, glVertexAttrib4NuivARB, NULL, _gloffset_VertexAttrib4NuivARB),
+    NAME_FUNC_OFFSET(17824, glVertexAttrib4NusvARB, glVertexAttrib4NusvARB, NULL, _gloffset_VertexAttrib4NusvARB),
+    NAME_FUNC_OFFSET(17844, glVertexAttrib4bvARB, glVertexAttrib4bvARB, NULL, _gloffset_VertexAttrib4bvARB),
+    NAME_FUNC_OFFSET(17862, glVertexAttrib4dARB, glVertexAttrib4dARB, NULL, _gloffset_VertexAttrib4dARB),
+    NAME_FUNC_OFFSET(17879, glVertexAttrib4dvARB, glVertexAttrib4dvARB, NULL, _gloffset_VertexAttrib4dvARB),
+    NAME_FUNC_OFFSET(17897, glVertexAttrib4fARB, glVertexAttrib4fARB, NULL, _gloffset_VertexAttrib4fARB),
+    NAME_FUNC_OFFSET(17914, glVertexAttrib4fvARB, glVertexAttrib4fvARB, NULL, _gloffset_VertexAttrib4fvARB),
+    NAME_FUNC_OFFSET(17932, glVertexAttrib4ivARB, glVertexAttrib4ivARB, NULL, _gloffset_VertexAttrib4ivARB),
+    NAME_FUNC_OFFSET(17950, glVertexAttrib4sARB, glVertexAttrib4sARB, NULL, _gloffset_VertexAttrib4sARB),
+    NAME_FUNC_OFFSET(17967, glVertexAttrib4svARB, glVertexAttrib4svARB, NULL, _gloffset_VertexAttrib4svARB),
+    NAME_FUNC_OFFSET(17985, glVertexAttrib4ubvARB, glVertexAttrib4ubvARB, NULL, _gloffset_VertexAttrib4ubvARB),
+    NAME_FUNC_OFFSET(18004, glVertexAttrib4uivARB, glVertexAttrib4uivARB, NULL, _gloffset_VertexAttrib4uivARB),
+    NAME_FUNC_OFFSET(18023, glVertexAttrib4usvARB, glVertexAttrib4usvARB, NULL, _gloffset_VertexAttrib4usvARB),
+    NAME_FUNC_OFFSET(18042, glVertexAttribPointerARB, glVertexAttribPointerARB, NULL, _gloffset_VertexAttribPointerARB),
+    NAME_FUNC_OFFSET(18064, glBindBufferARB, glBindBufferARB, NULL, _gloffset_BindBufferARB),
+    NAME_FUNC_OFFSET(18077, glBufferDataARB, glBufferDataARB, NULL, _gloffset_BufferDataARB),
+    NAME_FUNC_OFFSET(18090, glBufferSubDataARB, glBufferSubDataARB, NULL, _gloffset_BufferSubDataARB),
+    NAME_FUNC_OFFSET(18106, glDeleteBuffersARB, glDeleteBuffersARB, NULL, _gloffset_DeleteBuffersARB),
+    NAME_FUNC_OFFSET(18122, glGenBuffersARB, glGenBuffersARB, NULL, _gloffset_GenBuffersARB),
+    NAME_FUNC_OFFSET(18135, glGetBufferParameterivARB, glGetBufferParameterivARB, NULL, _gloffset_GetBufferParameterivARB),
+    NAME_FUNC_OFFSET(18158, glGetBufferPointervARB, glGetBufferPointervARB, NULL, _gloffset_GetBufferPointervARB),
+    NAME_FUNC_OFFSET(18178, glGetBufferSubDataARB, glGetBufferSubDataARB, NULL, _gloffset_GetBufferSubDataARB),
+    NAME_FUNC_OFFSET(18197, glIsBufferARB, glIsBufferARB, NULL, _gloffset_IsBufferARB),
+    NAME_FUNC_OFFSET(18208, glMapBufferARB, glMapBufferARB, NULL, _gloffset_MapBufferARB),
+    NAME_FUNC_OFFSET(18220, glUnmapBufferARB, glUnmapBufferARB, NULL, _gloffset_UnmapBufferARB),
+    NAME_FUNC_OFFSET(18234, glBeginQueryARB, glBeginQueryARB, NULL, _gloffset_BeginQueryARB),
+    NAME_FUNC_OFFSET(18247, glDeleteQueriesARB, glDeleteQueriesARB, NULL, _gloffset_DeleteQueriesARB),
+    NAME_FUNC_OFFSET(18263, glEndQueryARB, glEndQueryARB, NULL, _gloffset_EndQueryARB),
+    NAME_FUNC_OFFSET(18274, glGenQueriesARB, glGenQueriesARB, NULL, _gloffset_GenQueriesARB),
+    NAME_FUNC_OFFSET(18287, glGetQueryObjectivARB, glGetQueryObjectivARB, NULL, _gloffset_GetQueryObjectivARB),
+    NAME_FUNC_OFFSET(18306, glGetQueryObjectuivARB, glGetQueryObjectuivARB, NULL, _gloffset_GetQueryObjectuivARB),
+    NAME_FUNC_OFFSET(18326, glGetQueryivARB, glGetQueryivARB, NULL, _gloffset_GetQueryivARB),
+    NAME_FUNC_OFFSET(18339, glIsQueryARB, glIsQueryARB, NULL, _gloffset_IsQueryARB),
+    NAME_FUNC_OFFSET(18349, glCompileShaderARB, glCompileShaderARB, NULL, _gloffset_CompileShaderARB),
+    NAME_FUNC_OFFSET(18365, glGetActiveUniformARB, glGetActiveUniformARB, NULL, _gloffset_GetActiveUniformARB),
+    NAME_FUNC_OFFSET(18384, glGetShaderSourceARB, glGetShaderSourceARB, NULL, _gloffset_GetShaderSourceARB),
+    NAME_FUNC_OFFSET(18402, glGetUniformLocationARB, glGetUniformLocationARB, NULL, _gloffset_GetUniformLocationARB),
+    NAME_FUNC_OFFSET(18423, glGetUniformfvARB, glGetUniformfvARB, NULL, _gloffset_GetUniformfvARB),
+    NAME_FUNC_OFFSET(18438, glGetUniformivARB, glGetUniformivARB, NULL, _gloffset_GetUniformivARB),
+    NAME_FUNC_OFFSET(18453, glLinkProgramARB, glLinkProgramARB, NULL, _gloffset_LinkProgramARB),
+    NAME_FUNC_OFFSET(18467, glShaderSourceARB, glShaderSourceARB, NULL, _gloffset_ShaderSourceARB),
+    NAME_FUNC_OFFSET(18482, glUniform1fARB, glUniform1fARB, NULL, _gloffset_Uniform1fARB),
+    NAME_FUNC_OFFSET(18494, glUniform1fvARB, glUniform1fvARB, NULL, _gloffset_Uniform1fvARB),
+    NAME_FUNC_OFFSET(18507, glUniform1iARB, glUniform1iARB, NULL, _gloffset_Uniform1iARB),
+    NAME_FUNC_OFFSET(18519, glUniform1ivARB, glUniform1ivARB, NULL, _gloffset_Uniform1ivARB),
+    NAME_FUNC_OFFSET(18532, glUniform2fARB, glUniform2fARB, NULL, _gloffset_Uniform2fARB),
+    NAME_FUNC_OFFSET(18544, glUniform2fvARB, glUniform2fvARB, NULL, _gloffset_Uniform2fvARB),
+    NAME_FUNC_OFFSET(18557, glUniform2iARB, glUniform2iARB, NULL, _gloffset_Uniform2iARB),
+    NAME_FUNC_OFFSET(18569, glUniform2ivARB, glUniform2ivARB, NULL, _gloffset_Uniform2ivARB),
+    NAME_FUNC_OFFSET(18582, glUniform3fARB, glUniform3fARB, NULL, _gloffset_Uniform3fARB),
+    NAME_FUNC_OFFSET(18594, glUniform3fvARB, glUniform3fvARB, NULL, _gloffset_Uniform3fvARB),
+    NAME_FUNC_OFFSET(18607, glUniform3iARB, glUniform3iARB, NULL, _gloffset_Uniform3iARB),
+    NAME_FUNC_OFFSET(18619, glUniform3ivARB, glUniform3ivARB, NULL, _gloffset_Uniform3ivARB),
+    NAME_FUNC_OFFSET(18632, glUniform4fARB, glUniform4fARB, NULL, _gloffset_Uniform4fARB),
+    NAME_FUNC_OFFSET(18644, glUniform4fvARB, glUniform4fvARB, NULL, _gloffset_Uniform4fvARB),
+    NAME_FUNC_OFFSET(18657, glUniform4iARB, glUniform4iARB, NULL, _gloffset_Uniform4iARB),
+    NAME_FUNC_OFFSET(18669, glUniform4ivARB, glUniform4ivARB, NULL, _gloffset_Uniform4ivARB),
+    NAME_FUNC_OFFSET(18682, glUniformMatrix2fvARB, glUniformMatrix2fvARB, NULL, _gloffset_UniformMatrix2fvARB),
+    NAME_FUNC_OFFSET(18701, glUniformMatrix3fvARB, glUniformMatrix3fvARB, NULL, _gloffset_UniformMatrix3fvARB),
+    NAME_FUNC_OFFSET(18720, glUniformMatrix4fvARB, glUniformMatrix4fvARB, NULL, _gloffset_UniformMatrix4fvARB),
+    NAME_FUNC_OFFSET(18739, glUseProgramObjectARB, glUseProgramObjectARB, NULL, _gloffset_UseProgramObjectARB),
+    NAME_FUNC_OFFSET(18752, glValidateProgramARB, glValidateProgramARB, NULL, _gloffset_ValidateProgramARB),
+    NAME_FUNC_OFFSET(18770, glBindAttribLocationARB, glBindAttribLocationARB, NULL, _gloffset_BindAttribLocationARB),
+    NAME_FUNC_OFFSET(18791, glGetActiveAttribARB, glGetActiveAttribARB, NULL, _gloffset_GetActiveAttribARB),
+    NAME_FUNC_OFFSET(18809, glGetAttribLocationARB, glGetAttribLocationARB, NULL, _gloffset_GetAttribLocationARB),
+    NAME_FUNC_OFFSET(18829, glDrawBuffersARB, glDrawBuffersARB, NULL, _gloffset_DrawBuffersARB),
+    NAME_FUNC_OFFSET(18843, glDrawBuffersARB, glDrawBuffersARB, NULL, _gloffset_DrawBuffersARB),
+    NAME_FUNC_OFFSET(18860, glRenderbufferStorageMultisample, glRenderbufferStorageMultisample, NULL, _gloffset_RenderbufferStorageMultisample),
+    NAME_FUNC_OFFSET(18896, gl_dispatch_stub_596, gl_dispatch_stub_596, NULL, _gloffset_SampleMaskSGIS),
+    NAME_FUNC_OFFSET(18912, gl_dispatch_stub_597, gl_dispatch_stub_597, NULL, _gloffset_SamplePatternSGIS),
+    NAME_FUNC_OFFSET(18931, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
+    NAME_FUNC_OFFSET(18949, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
+    NAME_FUNC_OFFSET(18970, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
+    NAME_FUNC_OFFSET(18992, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
+    NAME_FUNC_OFFSET(19011, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
+    NAME_FUNC_OFFSET(19033, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
+    NAME_FUNC_OFFSET(19056, glSecondaryColor3bEXT, glSecondaryColor3bEXT, NULL, _gloffset_SecondaryColor3bEXT),
+    NAME_FUNC_OFFSET(19075, glSecondaryColor3bvEXT, glSecondaryColor3bvEXT, NULL, _gloffset_SecondaryColor3bvEXT),
+    NAME_FUNC_OFFSET(19095, glSecondaryColor3dEXT, glSecondaryColor3dEXT, NULL, _gloffset_SecondaryColor3dEXT),
+    NAME_FUNC_OFFSET(19114, glSecondaryColor3dvEXT, glSecondaryColor3dvEXT, NULL, _gloffset_SecondaryColor3dvEXT),
+    NAME_FUNC_OFFSET(19134, glSecondaryColor3fEXT, glSecondaryColor3fEXT, NULL, _gloffset_SecondaryColor3fEXT),
+    NAME_FUNC_OFFSET(19153, glSecondaryColor3fvEXT, glSecondaryColor3fvEXT, NULL, _gloffset_SecondaryColor3fvEXT),
+    NAME_FUNC_OFFSET(19173, glSecondaryColor3iEXT, glSecondaryColor3iEXT, NULL, _gloffset_SecondaryColor3iEXT),
+    NAME_FUNC_OFFSET(19192, glSecondaryColor3ivEXT, glSecondaryColor3ivEXT, NULL, _gloffset_SecondaryColor3ivEXT),
+    NAME_FUNC_OFFSET(19212, glSecondaryColor3sEXT, glSecondaryColor3sEXT, NULL, _gloffset_SecondaryColor3sEXT),
+    NAME_FUNC_OFFSET(19231, glSecondaryColor3svEXT, glSecondaryColor3svEXT, NULL, _gloffset_SecondaryColor3svEXT),
+    NAME_FUNC_OFFSET(19251, glSecondaryColor3ubEXT, glSecondaryColor3ubEXT, NULL, _gloffset_SecondaryColor3ubEXT),
+    NAME_FUNC_OFFSET(19271, glSecondaryColor3ubvEXT, glSecondaryColor3ubvEXT, NULL, _gloffset_SecondaryColor3ubvEXT),
+    NAME_FUNC_OFFSET(19292, glSecondaryColor3uiEXT, glSecondaryColor3uiEXT, NULL, _gloffset_SecondaryColor3uiEXT),
+    NAME_FUNC_OFFSET(19312, glSecondaryColor3uivEXT, glSecondaryColor3uivEXT, NULL, _gloffset_SecondaryColor3uivEXT),
+    NAME_FUNC_OFFSET(19333, glSecondaryColor3usEXT, glSecondaryColor3usEXT, NULL, _gloffset_SecondaryColor3usEXT),
+    NAME_FUNC_OFFSET(19353, glSecondaryColor3usvEXT, glSecondaryColor3usvEXT, NULL, _gloffset_SecondaryColor3usvEXT),
+    NAME_FUNC_OFFSET(19374, glSecondaryColorPointerEXT, glSecondaryColorPointerEXT, NULL, _gloffset_SecondaryColorPointerEXT),
+    NAME_FUNC_OFFSET(19398, glMultiDrawArraysEXT, glMultiDrawArraysEXT, NULL, _gloffset_MultiDrawArraysEXT),
+    NAME_FUNC_OFFSET(19416, glMultiDrawElementsEXT, glMultiDrawElementsEXT, NULL, _gloffset_MultiDrawElementsEXT),
+    NAME_FUNC_OFFSET(19436, glFogCoordPointerEXT, glFogCoordPointerEXT, NULL, _gloffset_FogCoordPointerEXT),
+    NAME_FUNC_OFFSET(19454, glFogCoorddEXT, glFogCoorddEXT, NULL, _gloffset_FogCoorddEXT),
+    NAME_FUNC_OFFSET(19466, glFogCoorddvEXT, glFogCoorddvEXT, NULL, _gloffset_FogCoorddvEXT),
+    NAME_FUNC_OFFSET(19479, glFogCoordfEXT, glFogCoordfEXT, NULL, _gloffset_FogCoordfEXT),
+    NAME_FUNC_OFFSET(19491, glFogCoordfvEXT, glFogCoordfvEXT, NULL, _gloffset_FogCoordfvEXT),
+    NAME_FUNC_OFFSET(19504, glBlendFuncSeparateEXT, glBlendFuncSeparateEXT, NULL, _gloffset_BlendFuncSeparateEXT),
+    NAME_FUNC_OFFSET(19524, glBlendFuncSeparateEXT, glBlendFuncSeparateEXT, NULL, _gloffset_BlendFuncSeparateEXT),
+    NAME_FUNC_OFFSET(19548, glWindowPos2dMESA, glWindowPos2dMESA, NULL, _gloffset_WindowPos2dMESA),
+    NAME_FUNC_OFFSET(19562, glWindowPos2dMESA, glWindowPos2dMESA, NULL, _gloffset_WindowPos2dMESA),
+    NAME_FUNC_OFFSET(19579, glWindowPos2dvMESA, glWindowPos2dvMESA, NULL, _gloffset_WindowPos2dvMESA),
+    NAME_FUNC_OFFSET(19594, glWindowPos2dvMESA, glWindowPos2dvMESA, NULL, _gloffset_WindowPos2dvMESA),
+    NAME_FUNC_OFFSET(19612, glWindowPos2fMESA, glWindowPos2fMESA, NULL, _gloffset_WindowPos2fMESA),
+    NAME_FUNC_OFFSET(19626, glWindowPos2fMESA, glWindowPos2fMESA, NULL, _gloffset_WindowPos2fMESA),
+    NAME_FUNC_OFFSET(19643, glWindowPos2fvMESA, glWindowPos2fvMESA, NULL, _gloffset_WindowPos2fvMESA),
+    NAME_FUNC_OFFSET(19658, glWindowPos2fvMESA, glWindowPos2fvMESA, NULL, _gloffset_WindowPos2fvMESA),
+    NAME_FUNC_OFFSET(19676, glWindowPos2iMESA, glWindowPos2iMESA, NULL, _gloffset_WindowPos2iMESA),
+    NAME_FUNC_OFFSET(19690, glWindowPos2iMESA, glWindowPos2iMESA, NULL, _gloffset_WindowPos2iMESA),
+    NAME_FUNC_OFFSET(19707, glWindowPos2ivMESA, glWindowPos2ivMESA, NULL, _gloffset_WindowPos2ivMESA),
+    NAME_FUNC_OFFSET(19722, glWindowPos2ivMESA, glWindowPos2ivMESA, NULL, _gloffset_WindowPos2ivMESA),
+    NAME_FUNC_OFFSET(19740, glWindowPos2sMESA, glWindowPos2sMESA, NULL, _gloffset_WindowPos2sMESA),
+    NAME_FUNC_OFFSET(19754, glWindowPos2sMESA, glWindowPos2sMESA, NULL, _gloffset_WindowPos2sMESA),
+    NAME_FUNC_OFFSET(19771, glWindowPos2svMESA, glWindowPos2svMESA, NULL, _gloffset_WindowPos2svMESA),
+    NAME_FUNC_OFFSET(19786, glWindowPos2svMESA, glWindowPos2svMESA, NULL, _gloffset_WindowPos2svMESA),
+    NAME_FUNC_OFFSET(19804, glWindowPos3dMESA, glWindowPos3dMESA, NULL, _gloffset_WindowPos3dMESA),
+    NAME_FUNC_OFFSET(19818, glWindowPos3dMESA, glWindowPos3dMESA, NULL, _gloffset_WindowPos3dMESA),
+    NAME_FUNC_OFFSET(19835, glWindowPos3dvMESA, glWindowPos3dvMESA, NULL, _gloffset_WindowPos3dvMESA),
+    NAME_FUNC_OFFSET(19850, glWindowPos3dvMESA, glWindowPos3dvMESA, NULL, _gloffset_WindowPos3dvMESA),
+    NAME_FUNC_OFFSET(19868, glWindowPos3fMESA, glWindowPos3fMESA, NULL, _gloffset_WindowPos3fMESA),
+    NAME_FUNC_OFFSET(19882, glWindowPos3fMESA, glWindowPos3fMESA, NULL, _gloffset_WindowPos3fMESA),
+    NAME_FUNC_OFFSET(19899, glWindowPos3fvMESA, glWindowPos3fvMESA, NULL, _gloffset_WindowPos3fvMESA),
+    NAME_FUNC_OFFSET(19914, glWindowPos3fvMESA, glWindowPos3fvMESA, NULL, _gloffset_WindowPos3fvMESA),
+    NAME_FUNC_OFFSET(19932, glWindowPos3iMESA, glWindowPos3iMESA, NULL, _gloffset_WindowPos3iMESA),
+    NAME_FUNC_OFFSET(19946, glWindowPos3iMESA, glWindowPos3iMESA, NULL, _gloffset_WindowPos3iMESA),
+    NAME_FUNC_OFFSET(19963, glWindowPos3ivMESA, glWindowPos3ivMESA, NULL, _gloffset_WindowPos3ivMESA),
+    NAME_FUNC_OFFSET(19978, glWindowPos3ivMESA, glWindowPos3ivMESA, NULL, _gloffset_WindowPos3ivMESA),
+    NAME_FUNC_OFFSET(19996, glWindowPos3sMESA, glWindowPos3sMESA, NULL, _gloffset_WindowPos3sMESA),
+    NAME_FUNC_OFFSET(20010, glWindowPos3sMESA, glWindowPos3sMESA, NULL, _gloffset_WindowPos3sMESA),
+    NAME_FUNC_OFFSET(20027, glWindowPos3svMESA, glWindowPos3svMESA, NULL, _gloffset_WindowPos3svMESA),
+    NAME_FUNC_OFFSET(20042, glWindowPos3svMESA, glWindowPos3svMESA, NULL, _gloffset_WindowPos3svMESA),
+    NAME_FUNC_OFFSET(20060, glBindProgramNV, glBindProgramNV, NULL, _gloffset_BindProgramNV),
+    NAME_FUNC_OFFSET(20077, glDeleteProgramsNV, glDeleteProgramsNV, NULL, _gloffset_DeleteProgramsNV),
+    NAME_FUNC_OFFSET(20097, glGenProgramsNV, glGenProgramsNV, NULL, _gloffset_GenProgramsNV),
+    NAME_FUNC_OFFSET(20114, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV),
+    NAME_FUNC_OFFSET(20140, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV),
+    NAME_FUNC_OFFSET(20169, glIsProgramNV, glIsProgramNV, NULL, _gloffset_IsProgramNV),
+    NAME_FUNC_OFFSET(20184, glPointParameteriNV, glPointParameteriNV, NULL, _gloffset_PointParameteriNV),
+    NAME_FUNC_OFFSET(20202, glPointParameterivNV, glPointParameterivNV, NULL, _gloffset_PointParameterivNV),
+    NAME_FUNC_OFFSET(20221, gl_dispatch_stub_767, gl_dispatch_stub_767, NULL, _gloffset_DeleteVertexArraysAPPLE),
+    NAME_FUNC_OFFSET(20242, gl_dispatch_stub_769, gl_dispatch_stub_769, NULL, _gloffset_IsVertexArrayAPPLE),
+    NAME_FUNC_OFFSET(20258, gl_dispatch_stub_777, gl_dispatch_stub_777, NULL, _gloffset_BlendEquationSeparateEXT),
+    NAME_FUNC_OFFSET(20282, gl_dispatch_stub_777, gl_dispatch_stub_777, NULL, _gloffset_BlendEquationSeparateEXT),
+    NAME_FUNC_OFFSET(20309, glBindFramebufferEXT, glBindFramebufferEXT, NULL, _gloffset_BindFramebufferEXT),
+    NAME_FUNC_OFFSET(20327, glBindRenderbufferEXT, glBindRenderbufferEXT, NULL, _gloffset_BindRenderbufferEXT),
+    NAME_FUNC_OFFSET(20346, glCheckFramebufferStatusEXT, glCheckFramebufferStatusEXT, NULL, _gloffset_CheckFramebufferStatusEXT),
+    NAME_FUNC_OFFSET(20371, glDeleteFramebuffersEXT, glDeleteFramebuffersEXT, NULL, _gloffset_DeleteFramebuffersEXT),
+    NAME_FUNC_OFFSET(20392, glDeleteRenderbuffersEXT, glDeleteRenderbuffersEXT, NULL, _gloffset_DeleteRenderbuffersEXT),
+    NAME_FUNC_OFFSET(20414, glFramebufferRenderbufferEXT, glFramebufferRenderbufferEXT, NULL, _gloffset_FramebufferRenderbufferEXT),
+    NAME_FUNC_OFFSET(20440, glFramebufferTexture1DEXT, glFramebufferTexture1DEXT, NULL, _gloffset_FramebufferTexture1DEXT),
+    NAME_FUNC_OFFSET(20463, glFramebufferTexture2DEXT, glFramebufferTexture2DEXT, NULL, _gloffset_FramebufferTexture2DEXT),
+    NAME_FUNC_OFFSET(20486, glFramebufferTexture3DEXT, glFramebufferTexture3DEXT, NULL, _gloffset_FramebufferTexture3DEXT),
+    NAME_FUNC_OFFSET(20509, glGenFramebuffersEXT, glGenFramebuffersEXT, NULL, _gloffset_GenFramebuffersEXT),
+    NAME_FUNC_OFFSET(20527, glGenRenderbuffersEXT, glGenRenderbuffersEXT, NULL, _gloffset_GenRenderbuffersEXT),
+    NAME_FUNC_OFFSET(20546, glGenerateMipmapEXT, glGenerateMipmapEXT, NULL, _gloffset_GenerateMipmapEXT),
+    NAME_FUNC_OFFSET(20563, glGetFramebufferAttachmentParameterivEXT, glGetFramebufferAttachmentParameterivEXT, NULL, _gloffset_GetFramebufferAttachmentParameterivEXT),
+    NAME_FUNC_OFFSET(20601, glGetRenderbufferParameterivEXT, glGetRenderbufferParameterivEXT, NULL, _gloffset_GetRenderbufferParameterivEXT),
+    NAME_FUNC_OFFSET(20630, glIsFramebufferEXT, glIsFramebufferEXT, NULL, _gloffset_IsFramebufferEXT),
+    NAME_FUNC_OFFSET(20646, glIsRenderbufferEXT, glIsRenderbufferEXT, NULL, _gloffset_IsRenderbufferEXT),
+    NAME_FUNC_OFFSET(20663, glRenderbufferStorageEXT, glRenderbufferStorageEXT, NULL, _gloffset_RenderbufferStorageEXT),
+    NAME_FUNC_OFFSET(20685, gl_dispatch_stub_795, gl_dispatch_stub_795, NULL, _gloffset_BlitFramebufferEXT),
+    NAME_FUNC_OFFSET(20703, glFramebufferTextureLayerEXT, glFramebufferTextureLayerEXT, NULL, _gloffset_FramebufferTextureLayerEXT),
+    NAME_FUNC_OFFSET(20729, glBeginTransformFeedbackEXT, glBeginTransformFeedbackEXT, NULL, _gloffset_BeginTransformFeedbackEXT),
+    NAME_FUNC_OFFSET(20754, glBindBufferBaseEXT, glBindBufferBaseEXT, NULL, _gloffset_BindBufferBaseEXT),
+    NAME_FUNC_OFFSET(20771, glBindBufferRangeEXT, glBindBufferRangeEXT, NULL, _gloffset_BindBufferRangeEXT),
+    NAME_FUNC_OFFSET(20789, glEndTransformFeedbackEXT, glEndTransformFeedbackEXT, NULL, _gloffset_EndTransformFeedbackEXT),
+    NAME_FUNC_OFFSET(20812, glGetTransformFeedbackVaryingEXT, glGetTransformFeedbackVaryingEXT, NULL, _gloffset_GetTransformFeedbackVaryingEXT),
+    NAME_FUNC_OFFSET(20842, glTransformFeedbackVaryingsEXT, glTransformFeedbackVaryingsEXT, NULL, _gloffset_TransformFeedbackVaryingsEXT),
+    NAME_FUNC_OFFSET(20870, glProvokingVertexEXT, glProvokingVertexEXT, NULL, _gloffset_ProvokingVertexEXT),
     NAME_FUNC_OFFSET(-1, NULL, NULL, NULL, 0)
 };
 
index e2eeb16c9a4f6589b42bb48b32da698170f7e0c1..f97720093c8f2b14cbd32929f87793e33d0462dc 100644 (file)
@@ -20,6 +20,13 @@ MESA_CPPFLAGS := $(API_DEFINES)
 ES1_CPPFLAGS := -DFEATURE_ES1=1
 ES2_CPPFLAGS := -DFEATURE_ES2=1
 
+ifeq ($(MESA_LLVM),1)
+MESA_CPPFLAGS += $(LLVM_CFLAGS)
+ES1_CPPFLAGS += $(LLVM_CFLAGS)
+ES2_CPPFLAGS += $(LLVM_CFLAGS)
+endif
+
+
 include sources.mak
 
 # adjust object dirs
index b90384d04a705396e09fac123fbb5174c5c50c3e..fc0ff28d697c0c17232384c92a64514f86f5540e 100644 (file)
@@ -216,8 +216,8 @@ clean:
        -$(call UNLINK,main/*.o)
        -$(call UNLINK,math/*.o)
        -$(call UNLINK,vbo/*.o)
-       -$(call UNLINK,shader/*.o)
-       -$(call UNLINK,shader/slang/*.o)
+       -$(call UNLINK,program/*.o)
+       -$(call UNLINK,slang/*.o)
        -$(call UNLINK,sparc/*.o)
        -$(call UNLINK,ppc/*.o)
        -$(call UNLINK,swrast/*.o)
index 34b7f4e8b7cf78469282e16b36aac30ed28f1560..79e9b4553b7bfa02849c49126fbaa2c508d2da7e 100644 (file)
@@ -31,6 +31,8 @@ if env['platform'] != 'winddk':
                'main/api_noop.c',
                'main/api_validate.c',
                'main/accum.c',
+               'main/arbprogram.c',
+               'main/atifragshader.c',
                'main/attrib.c',
                'main/arrayobj.c',
                'main/blend.c',
@@ -73,6 +75,7 @@ if env['platform'] != 'winddk':
                'main/mipmap.c',
                'main/mm.c',
                'main/multisample.c',
+               'main/nvprogram.c',
                'main/pixel.c',
                'main/pixelstore.c',
                'main/points.c',
@@ -83,7 +86,8 @@ if env['platform'] != 'winddk':
                'main/remap.c',
                'main/renderbuffer.c',
                'main/scissor.c',
-               'main/shaders.c',
+               'main/shaderapi.c',
+               'main/shaderobj.c',
                'main/shared.c',
                'main/state.c',
                'main/stencil.c',
@@ -104,6 +108,7 @@ if env['platform'] != 'winddk':
                'main/texstate.c',
                'main/texstore.c',
                'main/transformfeedback.c',
+               'main/uniforms.c',
                'main/varray.c',
                'main/version.c',
                'main/viewport.c',
@@ -192,63 +197,58 @@ if env['platform'] != 'winddk':
                'state_tracker/st_texture.c',
        ]
        
-       shader_sources = [
-               'shader/arbprogparse.c',
-               'shader/arbprogram.c',
-               'shader/atifragshader.c',
-               'shader/hash_table.c',
-               'shader/lex.yy.c',
-               'shader/nvfragparse.c',
-               'shader/nvprogram.c',
-               'shader/nvvertparse.c',
-               'shader/program.c',
-               'shader/program_parse.tab.c',
-               'shader/program_parse_extra.c',
-               'shader/prog_cache.c',
-               'shader/prog_execute.c',
-               'shader/prog_instruction.c',
-               'shader/prog_noise.c',
-               'shader/prog_optimize.c',
-               'shader/prog_parameter.c',
-               'shader/prog_parameter_layout.c',
-               'shader/prog_print.c',
-               'shader/prog_statevars.c',
-               'shader/prog_uniform.c',
-               'shader/programopt.c',
-               'shader/symbol_table.c',
-               'shader/shader_api.c',
-               'shader/uniforms.c',
+       program_sources = [
+               'program/arbprogparse.c',
+               'program/hash_table.c',
+               'program/lex.yy.c',
+               'program/nvfragparse.c',
+               'program/nvvertparse.c',
+               'program/program.c',
+               'program/program_parse.tab.c',
+               'program/program_parse_extra.c',
+               'program/prog_cache.c',
+               'program/prog_execute.c',
+               'program/prog_instruction.c',
+               'program/prog_noise.c',
+               'program/prog_optimize.c',
+               'program/prog_parameter.c',
+               'program/prog_parameter_layout.c',
+               'program/prog_print.c',
+               'program/prog_statevars.c',
+               'program/prog_uniform.c',
+               'program/programopt.c',
+               'program/symbol_table.c',
        ]
        
        slang_sources = [
-               'shader/slang/slang_builtin.c',
-               'shader/slang/slang_codegen.c',
-               'shader/slang/slang_compile.c',
-               'shader/slang/slang_compile_function.c',
-               'shader/slang/slang_compile_operation.c',
-               'shader/slang/slang_compile_struct.c',
-               'shader/slang/slang_compile_variable.c',
-               'shader/slang/slang_emit.c',
-               'shader/slang/slang_ir.c',
-               'shader/slang/slang_label.c',
-               'shader/slang/slang_link.c',
-               'shader/slang/slang_log.c',
-               'shader/slang/slang_mem.c',
-               'shader/slang/slang_print.c',
-               'shader/slang/slang_simplify.c',
-               'shader/slang/slang_storage.c',
-               'shader/slang/slang_typeinfo.c',
-               'shader/slang/slang_vartable.c',
-               'shader/slang/slang_utility.c',
+               'slang/slang_builtin.c',
+               'slang/slang_codegen.c',
+               'slang/slang_compile.c',
+               'slang/slang_compile_function.c',
+               'slang/slang_compile_operation.c',
+               'slang/slang_compile_struct.c',
+               'slang/slang_compile_variable.c',
+               'slang/slang_emit.c',
+               'slang/slang_ir.c',
+               'slang/slang_label.c',
+               'slang/slang_link.c',
+               'slang/slang_log.c',
+               'slang/slang_mem.c',
+               'slang/slang_print.c',
+               'slang/slang_simplify.c',
+               'slang/slang_storage.c',
+               'slang/slang_typeinfo.c',
+               'slang/slang_vartable.c',
+               'slang/slang_utility.c',
        ]
        
        mesa_sources = (
                main_sources +
                math_sources +
+               program_sources +
                vbo_sources +
                vf_sources +
                statetracker_sources +
-               shader_sources +
                slang_sources
        )
 
@@ -327,7 +327,7 @@ if env['platform'] != 'winddk':
                # build dir) to the include path  
                env.Append(CPPPATH = [matypes[0].dir])
 
-       SConscript('shader/slang/library/SConscript')
+       SConscript('slang/library/SConscript')
 
        #
        # Libraries
index ca5eb5c7552e24ed5fb8529fda0744bf6ad8844b..227710fb025818d4b72c767dc6767792f02f151f 100644 (file)
@@ -31,6 +31,7 @@
 #include "main/mipmap.h"
 #include "main/queryobj.h"
 #include "main/renderbuffer.h"
+#include "main/shaderobj.h"
 #include "main/texcompress.h"
 #include "main/texformat.h"
 #include "main/texgetimage.h"
@@ -51,8 +52,7 @@
 #include "main/transformfeedback.h"
 #endif
 
-#include "shader/program.h"
-#include "shader/shader_api.h"
+#include "program/program.h"
 #include "tnl/tnl.h"
 #include "swrast/swrast.h"
 
@@ -208,6 +208,8 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
    driver->DeleteArrayObject = _mesa_delete_array_object;
    driver->BindArrayObject = NULL;
 
+   _mesa_init_shader_object_functions(driver);
+
 #if FEATURE_EXT_transform_feedback
    _mesa_init_transform_feedback_functions(driver);
 #endif
@@ -231,10 +233,6 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
    driver->EndList = NULL;
    driver->BeginCallList = NULL;
    driver->EndCallList = NULL;
-
-
-   /* XXX temporary here */
-   _mesa_init_glsl_driver_functions(driver);
 }
 
 
index 35255833821bb1255a7c241ce00e9cfd43a98015..dc6e7120c63e3fdb628079295d375837866c4469 100644 (file)
@@ -34,6 +34,7 @@
 #include "main/glheader.h"
 #include "main/mtypes.h"
 #include "main/imports.h"
+#include "main/arbprogram.h"
 #include "main/arrayobj.h"
 #include "main/blend.h"
 #include "main/bufferobj.h"
@@ -51,7 +52,7 @@
 #include "main/polygon.h"
 #include "main/readpix.h"
 #include "main/scissor.h"
-#include "main/shaders.h"
+#include "main/shaderapi.h"
 #include "main/state.h"
 #include "main/stencil.h"
 #include "main/texobj.h"
@@ -61,8 +62,7 @@
 #include "main/texstate.h"
 #include "main/varray.h"
 #include "main/viewport.h"
-#include "shader/program.h"
-#include "shader/arbprogram.h"
+#include "program/program.h"
 #include "swrast/swrast.h"
 #include "drivers/common/meta.h"
 
@@ -2570,12 +2570,6 @@ copy_tex_image(GLcontext *ctx, GLuint dims, GLenum target, GLint level,
       return;
    }
 
-   if (texImage->TexFormat == MESA_FORMAT_NONE)
-      texImage->TexFormat = ctx->Driver.ChooseTextureFormat(ctx,
-                                                            internalFormat,
-                                                            format,
-                                                            type);
-
    _mesa_unlock_texture(ctx, texObj); /* need to unlock first */
 
    /*
@@ -2604,6 +2598,9 @@ copy_tex_image(GLcontext *ctx, GLuint dims, GLenum target, GLint level,
                               postConvWidth, postConvHeight, 1,
                               border, internalFormat);
 
+   _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
+                               internalFormat, GL_NONE, GL_NONE);
+
    /*
     * Store texture data (with pixel transfer ops)
     */
index dfb7d64040942b99ac83e61e36136f4bd5a531d7..86e59a8e51c027c13454959e08f3dc6afd2f22a6 100644 (file)
@@ -26,6 +26,7 @@
  *
  **************************************************************************/
 
+#include "main/arbprogram.h"
 #include "main/arrayobj.h"
 #include "main/bufferobj.h"
 #include "main/enable.h"
@@ -33,8 +34,7 @@
 #include "main/texstate.h"
 #include "main/varray.h"
 #include "main/viewport.h"
-#include "shader/arbprogram.h"
-#include "shader/program.h"
+#include "program/program.h"
 #include "dri_metaops.h"
 
 void
index 18b9035248f7c735273587ef367e34af504c3d1a..dce84ef0deb37e2c6f48f795542f0cece88fa1f0 100644 (file)
@@ -927,41 +927,6 @@ const __DRI2configQueryExtension dri2ConfigQueryExtension = {
    dri2ConfigQueryf,
 };
 
-static int
-driFrameTracking(__DRIdrawable *drawable, GLboolean enable)
-{
-    return GLX_BAD_CONTEXT;
-}
-
-static int
-driQueryFrameTracking(__DRIdrawable *dpriv,
-                     int64_t * sbc, int64_t * missedFrames,
-                     float * lastMissedUsage, float * usage)
-{
-   __DRIswapInfo   sInfo;
-   int             status;
-   int64_t         ust;
-   __DRIscreen *psp = dpriv->driScreenPriv;
-
-   status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo );
-   if ( status == 0 ) {
-      *sbc = sInfo.swap_count;
-      *missedFrames = sInfo.swap_missed_count;
-      *lastMissedUsage = sInfo.swap_missed_usage;
-
-      (*psp->systemTime->getUST)( & ust );
-      *usage = driCalculateSwapUsage( dpriv, sInfo.swap_ust, ust );
-   }
-
-   return status;
-}
-
-const __DRIframeTrackingExtension driFrameTrackingExtension = {
-    { __DRI_FRAME_TRACKING, __DRI_FRAME_TRACKING_VERSION },
-    driFrameTracking,
-    driQueryFrameTracking    
-};
-
 /**
  * Calculate amount of swap interval used between GLX buffer swaps.
  * 
index e4c590b13224bfde7c170428ad1ab64b647ca14b..bc647ff8130f6f74d39034715f682c0c7eb9240d 100644 (file)
@@ -70,7 +70,6 @@ extern const __DRIdri2Extension driDRI2Extension;
 extern const __DRIextension driReadDrawableExtension;
 extern const __DRIcopySubBufferExtension driCopySubBufferExtension;
 extern const __DRIswapControlExtension driSwapControlExtension;
-extern const __DRIframeTrackingExtension driFrameTrackingExtension;
 extern const __DRImediaStreamCounterExtension driMediaStreamCounterExtension;
 extern const __DRI2configQueryExtension dri2ConfigQueryExtension;
 
index e60157f37772a9d4d0c91aad2d3f5b83c485eb64..f1505dc5e73a532d66086cdb26ac5c1cfdbeddc9 100644 (file)
 #include "main/macros.h"
 #include "main/enums.h"
 
-#include "shader/prog_instruction.h"
-#include "shader/prog_parameter.h"
-#include "shader/program.h"
-#include "shader/programopt.h"
-#include "shader/prog_print.h"
+#include "program/prog_instruction.h"
+#include "program/prog_parameter.h"
+#include "program/program.h"
+#include "program/programopt.h"
+#include "program/prog_print.h"
 
 #include "tnl/tnl.h"
 #include "tnl/t_context.h"
index 228ee3f3be16dff936502647ea588ca1f706de16..a1e9dae9154a84e203bf6a728d5f2101cf2e1bbd 100644 (file)
@@ -55,6 +55,7 @@ static void compile_clip_prog( struct brw_context *brw,
    GLuint program_size;
    GLuint delta;
    GLuint i;
+   GLuint header_regs;
 
    memset(&c, 0, sizeof(c));
    
@@ -72,22 +73,28 @@ static void compile_clip_prog( struct brw_context *brw,
    c.header_position_offset = ATTR_SIZE;
 
    if (intel->gen == 5)
-       delta = 3 * REG_SIZE;
+      header_regs = 3;
    else
-       delta = REG_SIZE;
+      header_regs = 1;
 
-   for (i = 0; i < VERT_RESULT_MAX; i++)
+   delta = header_regs * REG_SIZE;
+
+   for (i = 0; i < VERT_RESULT_MAX; i++) {
       if (c.key.attrs & BITFIELD64_BIT(i)) {
         c.offset[i] = delta;
         delta += ATTR_SIZE;
+
+        c.idx_to_attr[c.nr_attrs] = i;
+        c.nr_attrs++;
       }
+   }
 
-   c.nr_attrs = brw_count_bits(c.key.attrs);
-   
-   if (intel->gen == 5)
-       c.nr_regs = (c.nr_attrs + 1) / 2 + 3;  /* are vertices packed, or reg-aligned? */
-   else
-       c.nr_regs = (c.nr_attrs + 1) / 2 + 1;  /* are vertices packed, or reg-aligned? */
+   /* The vertex attributes start at a URB row-aligned offset after
+    * the 8-20 dword vertex header, and continue for a URB row-aligned
+    * length.  nr_regs determines the urb_read_length from the start
+    * of the header to the end of the vertex data.
+    */
+   c.nr_regs = header_regs + (c.nr_attrs + 1) / 2;
 
    c.nr_bytes = c.nr_regs * REG_SIZE;
 
index 68222c6c278ff84d6fbdaaee2989ae731a5f2824..3a8cd7bf39010b794cbb9e25899ffcc202597819 100644 (file)
@@ -115,7 +115,10 @@ struct brw_clip_compile {
    GLboolean need_direction;
 
    GLuint header_position_offset;
-   GLuint offset[VERT_ATTRIB_MAX];
+   /** Mapping from VERT_RESULT_* to offset within the VUE. */
+   GLuint offset[VERT_RESULT_MAX];
+   /** Mapping from attribute index to VERT_RESULT_* */
+   GLuint idx_to_attr[VERT_RESULT_MAX];
 };
 
 #define ATTR_SIZE  (4*4)
index ceb62a311626800f9b57533edb98ae6cf245f1bf..4b9117bb0b17eac143fcaaadee7b487644f6209b 100644 (file)
@@ -32,7 +32,7 @@
 #include "main/glheader.h"
 #include "main/macros.h"
 #include "main/enums.h"
-#include "shader/program.h"
+#include "program/program.h"
 
 #include "intel_batchbuffer.h"
 
index 7f47634dca80cb893d1ea3580a2125304fbebac2..b994a32bc3baf0ee3ef07c3b366d7fb141921fbd 100644 (file)
@@ -32,7 +32,7 @@
 #include "main/glheader.h"
 #include "main/macros.h"
 #include "main/enums.h"
-#include "shader/program.h"
+#include "program/program.h"
 
 #include "intel_batchbuffer.h"
 
index 916a99ea004e5871c63a3f2cbc3aa4bf9aa73b94..cb58d1da9fef3709c1965e46397a2c5869828387 100644 (file)
@@ -32,7 +32,7 @@
 #include "main/glheader.h"
 #include "main/macros.h"
 #include "main/enums.h"
-#include "shader/program.h"
+#include "program/program.h"
 
 #include "intel_batchbuffer.h"
 
@@ -76,10 +76,7 @@ void brw_clip_tri_alloc_regs( struct brw_clip_compile *c,
 
    if (c->nr_attrs & 1) {
       for (j = 0; j < 3; j++) {
-        GLuint delta = c->nr_attrs*16 + 32;
-
-         if (intel->gen == 5)
-             delta = c->nr_attrs * 16 + 32 * 3;
+        GLuint delta = c->offset[c->idx_to_attr[c->nr_attrs - 1]] + ATTR_SIZE;
 
         brw_MOV(&c->func, byte_offset(c->reg.vertex[j], delta), brw_imm_f(0));
       }
index f36d22fdbf8b9ce0eae5e18e99ec86caed96cc4e..afd93f8be0b4ce08a4db1747b07f1b8d470dede1 100644 (file)
@@ -32,7 +32,7 @@
 #include "main/glheader.h"
 #include "main/macros.h"
 #include "main/enums.h"
-#include "shader/program.h"
+#include "program/program.h"
 
 #include "intel_batchbuffer.h"
 
index 2148bc8244a70539e4a3a7011f5916b75881d239..d2ac1235e46fa6a3f88288a699093013b54480b5 100644 (file)
@@ -33,7 +33,7 @@
 #include "main/glheader.h"
 #include "main/macros.h"
 #include "main/enums.h"
-#include "shader/program.h"
+#include "program/program.h"
 
 #include "intel_batchbuffer.h"
 
@@ -134,7 +134,6 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,
                             GLboolean force_edgeflag)
 {
    struct brw_compile *p = &c->func;
-   struct intel_context *intel = &p->brw->intel;
    struct brw_reg tmp = get_tmp(c);
    GLuint i;
 
@@ -149,12 +148,9 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,
    /* Iterate over each attribute (could be done in pairs?)
     */
    for (i = 0; i < c->nr_attrs; i++) {
-      GLuint delta = i*16 + 32;
+      GLuint delta = c->offset[c->idx_to_attr[i]];
 
-      if (intel->gen == 5)
-          delta = i * 16 + 32 * 3;
-
-      if (delta == c->offset[VERT_RESULT_EDGE]) {
+      if (c->idx_to_attr[i] == VERT_RESULT_EDGE) {
         if (force_edgeflag) 
            brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(1));
         else
@@ -183,10 +179,7 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,
    }
 
    if (i & 1) {
-      GLuint delta = i*16 + 32;
-
-      if (intel->gen == 5)
-          delta = i * 16 + 32 * 3;
+      GLuint delta = c->offset[c->idx_to_attr[c->nr_attrs - 1]] + ATTR_SIZE;
 
       brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(0));
    }
@@ -199,11 +192,6 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,
    brw_clip_project_vertex(c, dest_ptr );
 }
 
-
-
-
-#define MAX_MRF 16
-
 void brw_clip_emit_vue(struct brw_clip_compile *c, 
                       struct brw_indirect vert,
                       GLboolean allocate,
index d13b9ae298bcfbb67b1649f5ffa1352d0cc2d356..6d064b822e51dba97e315ab0b3cb36ff164e7322 100644 (file)
@@ -34,7 +34,6 @@
 #include "main/api_noop.h"
 #include "main/macros.h"
 #include "main/simple_list.h"
-
 #include "brw_context.h"
 #include "brw_defines.h"
 #include "brw_draw.h"
index 6c0b79f7241c36121ad3932def084ef3d6b9bff4..8196d8ca625242e4decfb22efda98ed9eed26f0a 100644 (file)
@@ -35,9 +35,9 @@
 #include "main/context.h"
 #include "main/macros.h"
 #include "main/enums.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_print.h"
-#include "shader/prog_statevars.h"
+#include "program/prog_parameter.h"
+#include "program/prog_print.h"
+#include "program/prog_statevars.h"
 #include "intel_batchbuffer.h"
 #include "intel_regions.h"
 #include "brw_context.h"
index 39bf5b63fc2a6cdd4962e4c5bd6c8a2bce6c7b83..f7a68cead7c731029458b67be03fbd8658aa9f88 100644 (file)
 #define BRW_MASK_ENABLE   0
 #define BRW_MASK_DISABLE  1
 
+/* Sandybridge is WECtrl (Write enable control) */
+#define BRW_WE_NORMAL          0
+#define BRW_WE_KILL_PRED       1
+
 #define BRW_OPCODE_MOV        1
 #define BRW_OPCODE_SEL        2
 #define BRW_OPCODE_NOT        4
 #define BRW_ARF_NOTIFICATION_COUNT    0x90
 #define BRW_ARF_IP                    0xA0
 
+#define BRW_MRF_COMPR4                 (1 << 7)
+
 #define BRW_AMASK   0
 #define BRW_IMASK   1
 #define BRW_LMASK   2
 #define BRW_POLYGON_FACING_BACK       1
 
 #define BRW_MESSAGE_TARGET_NULL               0
-#define BRW_MESSAGE_TARGET_MATH               1
+#define BRW_MESSAGE_TARGET_MATH               1 /* reserved on GEN6 */
 #define BRW_MESSAGE_TARGET_SAMPLER            2
 #define BRW_MESSAGE_TARGET_GATEWAY            3
-#define BRW_MESSAGE_TARGET_DATAPORT_READ      4
-#define BRW_MESSAGE_TARGET_DATAPORT_WRITE     5
+#define BRW_MESSAGE_TARGET_DATAPORT_READ      4 /* sampler cache on GEN6 */
+#define BRW_MESSAGE_TARGET_DATAPORT_WRITE     5 /* render cache on Gen6 */
 #define BRW_MESSAGE_TARGET_URB                6
 #define BRW_MESSAGE_TARGET_THREAD_SPAWNER     7
+#define BRW_MESSAGE_TARGET_CONST_CACHE       9 /* GEN6 */
 
 #define BRW_SAMPLER_RETURN_FORMAT_FLOAT32     0
 #define BRW_SAMPLER_RETURN_FORMAT_UINT32      2
 #define BRW_DATAPORT_DWORD_SCATTERED_BLOCK_8DWORDS   2
 #define BRW_DATAPORT_DWORD_SCATTERED_BLOCK_16DWORDS  3
 
+/* This one stays the same across generations. */
 #define BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ          0
+/* GEN4 */
 #define BRW_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ     1
-#define BRW_DATAPORT_READ_MESSAGE_DWORD_BLOCK_READ          2
+#define BRW_DATAPORT_READ_MESSAGE_MEDIA_BLOCK_READ          2
 #define BRW_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ      3
+/* G45, GEN5 */
+#define G45_DATAPORT_READ_MESSAGE_RENDER_UNORM_READ        1
+#define G45_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ     2
+#define G45_DATAPORT_READ_MESSAGE_AVC_LOOP_FILTER_READ     3
+#define G45_DATAPORT_READ_MESSAGE_MEDIA_BLOCK_READ          4
+#define G45_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ      6
+/* GEN6 */
+#define GEN6_DATAPORT_READ_MESSAGE_RENDER_UNORM_READ       1
+#define GEN6_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ     2
+#define GEN6_DATAPORT_READ_MESSAGE_MEDIA_BLOCK_READ          4
+#define GEN6_DATAPORT_READ_MESSAGE_OWORD_UNALIGN_BLOCK_READ  5
+#define GEN6_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ      6
 
 #define BRW_DATAPORT_READ_TARGET_DATA_CACHE      0
 #define BRW_DATAPORT_READ_TARGET_RENDER_CACHE    1
 #define BRW_DATAPORT_WRITE_MESSAGE_STREAMED_VERTEX_BUFFER_WRITE     5
 #define BRW_DATAPORT_WRITE_MESSAGE_FLUSH_RENDER_CACHE               7
 
+/* GEN6 */
+#define BRW_DATAPORT_WRITE_MESSAGE_DWORD_ATOMIC_WRITE_GEN6             7
+#define BRW_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE_GEN6              8
+#define BRW_DATAPORT_WRITE_MESSAGE_OWORD_DUAL_BLOCK_WRITE_GEN6         9
+#define BRW_DATAPORT_WRITE_MESSAGE_MEDIA_BLOCK_WRITE_GEN6              10
+#define BRW_DATAPORT_WRITE_MESSAGE_DWORLD_SCATTERED_WRITE_GEN6         11
+#define BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE_GEN6            12
+#define BRW_DATAPORT_WRITE_MESSAGE_STREAMED_VB_WRITE_GEN6              13
+#define BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_UNORM_WRITE_GEN6      14
+
 #define BRW_MATH_FUNCTION_INV                              1
 #define BRW_MATH_FUNCTION_LOG                              2
 #define BRW_MATH_FUNCTION_EXP                              3
index ff12daf497d296dbce6e8a00152de90446a12680..d23071453619b6de13e3f2444d24e8d282eda859 100644 (file)
@@ -598,7 +598,7 @@ static int src_da16 (FILE *file,
        format (file, ".%d", _subreg_nr);
     string (file, "<");
     err |= control (file, "vert stride", vert_stride, _vert_stride, NULL);
-    string (file, ",1,1>");
+    string (file, ",4,1>");
     err |= control (file, "src da16 reg type", reg_encoding, _reg_type, NULL);
     /*
      * Three kinds of swizzle display:
@@ -836,10 +836,12 @@ int brw_disasm (FILE *file, struct brw_instruction *inst, int gen)
     if (inst->header.opcode == BRW_OPCODE_SEND) {
        int target;
 
-       if (gen >= 5)
-          target = inst->bits2.send_gen5.sfid;
+       if (gen >= 6)
+           target = inst->header.destreg__conditionalmod;
+       else if (gen == 5)
+           target = inst->bits2.send_gen5.sfid;
        else
-          target = inst->bits3.generic.msg_target;
+           target = inst->bits3.generic.msg_target;
 
        newline (file);
        pad (file, 16);
@@ -868,13 +870,44 @@ int brw_disasm (FILE *file, struct brw_instruction *inst, int gen)
                            inst->bits3.sampler.return_format, NULL);
            string (file, ")");
            break;
+       case BRW_MESSAGE_TARGET_DATAPORT_READ:
+           if (gen >= 6) {
+               format (file, " (%d, %d, %d, %d, %d, %d)",
+                       inst->bits3.dp_render_cache.binding_table_index,
+                       inst->bits3.dp_render_cache.msg_control,
+                       inst->bits3.dp_render_cache.msg_type,
+                       inst->bits3.dp_render_cache.send_commit_msg,
+                       inst->bits3.dp_render_cache.msg_length,
+                       inst->bits3.dp_render_cache.response_length);
+           } else if (gen >= 5) {
+               format (file, " (%d, %d, %d)",
+                       inst->bits3.dp_read_gen5.binding_table_index,
+                       inst->bits3.dp_read_gen5.msg_control,
+                       inst->bits3.dp_read_gen5.msg_type);
+           } else {
+               format (file, " (%d, %d, %d)",
+                       inst->bits3.dp_read.binding_table_index,
+                       inst->bits3.dp_read.msg_control,
+                       inst->bits3.dp_read.msg_type);
+           }
+           break;
        case BRW_MESSAGE_TARGET_DATAPORT_WRITE:
-           format (file, " (%d, %d, %d, %d)",
-                   inst->bits3.dp_write.binding_table_index,
-                   (inst->bits3.dp_write.pixel_scoreboard_clear << 3) |
-                   inst->bits3.dp_write.msg_control,
-                   inst->bits3.dp_write.msg_type,
-                   inst->bits3.dp_write.send_commit_msg);
+           if (gen >= 6) {
+               format (file, " (%d, %d, %d, %d, %d, %d)",
+                       inst->bits3.dp_render_cache.binding_table_index,
+                       inst->bits3.dp_render_cache.msg_control,
+                       inst->bits3.dp_render_cache.msg_type,
+                       inst->bits3.dp_render_cache.send_commit_msg,
+                       inst->bits3.dp_render_cache.msg_length,
+                       inst->bits3.dp_render_cache.response_length);
+           } else {
+               format (file, " (%d, %d, %d, %d)",
+                       inst->bits3.dp_write.binding_table_index,
+                       (inst->bits3.dp_write.pixel_scoreboard_clear << 3) |
+                       inst->bits3.dp_write.msg_control,
+                       inst->bits3.dp_write.msg_type,
+                       inst->bits3.dp_write.send_commit_msg);
+           }
            break;
        case BRW_MESSAGE_TARGET_URB:
            if (gen >= 5) {
@@ -900,15 +933,22 @@ int brw_disasm (FILE *file, struct brw_instruction *inst, int gen)
        case BRW_MESSAGE_TARGET_THREAD_SPAWNER:
            break;
        default:
-           format (file, "unsupported target %d", inst->bits3.generic.msg_target);
+           format (file, "unsupported target %d", target);
            break;
        }
        if (space)
            string (file, " ");
-       format (file, "mlen %d",
-               inst->bits3.generic.msg_length);
-       format (file, " rlen %d",
-               inst->bits3.generic.response_length);
+       if (gen >= 5) {
+          format (file, "mlen %d",
+                  inst->bits3.generic_gen5.msg_length);
+          format (file, " rlen %d",
+                  inst->bits3.generic_gen5.response_length);
+       } else {
+          format (file, "mlen %d",
+                  inst->bits3.generic.msg_length);
+          format (file, " rlen %d",
+                  inst->bits3.generic.response_length);
+       }
     }
     pad (file, 64);
     if (inst->header.opcode != BRW_OPCODE_NOP) {
index 3a32ad26c12aa1f3b7181028796cdb5ff9d94544..ffdddd0a38875fb00fb9db2b2817ad8491380777 100644 (file)
@@ -35,7 +35,7 @@
 
 #include "brw_structs.h"
 #include "brw_defines.h"
-#include "shader/prog_instruction.h"
+#include "program/prog_instruction.h"
 
 #define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
 #define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3)
@@ -520,6 +520,20 @@ static INLINE struct brw_reg brw_acc_reg( void )
                       0);
 }
 
+static INLINE struct brw_reg brw_notification_1_reg(void)
+{
+
+   return brw_reg(BRW_ARCHITECTURE_REGISTER_FILE,
+                 BRW_ARF_NOTIFICATION_COUNT,
+                 1,
+                 BRW_REGISTER_TYPE_UD,
+                 BRW_VERTICAL_STRIDE_0,
+                 BRW_WIDTH_1,
+                 BRW_HORIZONTAL_STRIDE_0,
+                 BRW_SWIZZLE_XXXX,
+                 WRITEMASK_X);
+}
+
 
 static INLINE struct brw_reg brw_flag_reg( void )
 {
@@ -877,12 +891,15 @@ void brw_dp_READ_4( struct brw_compile *p,
 
 void brw_dp_READ_4_vs( struct brw_compile *p,
                        struct brw_reg dest,
-                       GLuint oword,
-                       GLboolean relAddr,
-                       struct brw_reg addrReg,
                        GLuint location,
                        GLuint bind_table_index );
 
+void brw_dp_READ_4_vs_relative(struct brw_compile *p,
+                              struct brw_reg dest,
+                              struct brw_reg addrReg,
+                              GLuint offset,
+                              GLuint bind_table_index);
+
 void brw_dp_WRITE_16( struct brw_compile *p,
                      struct brw_reg src,
                      GLuint scratch_offset );
@@ -919,6 +936,8 @@ void brw_land_fwd_jump(struct brw_compile *p,
 
 void brw_NOP(struct brw_compile *p);
 
+void brw_WAIT(struct brw_compile *p);
+
 /* Special case: there is never a destination, execution size will be
  * taken from src0:
  */
@@ -965,5 +984,7 @@ void brw_set_src1( struct brw_instruction *insn,
 
 /* brw_optimize.c */
 void brw_optimize(struct brw_compile *p);
+void brw_remove_duplicate_mrf_moves(struct brw_compile *p);
+void brw_remove_grf_to_mrf_moves(struct brw_compile *p);
 
 #endif
index 34dfe10cb930f429a280ed4b8b0c7868bccbc3ef..0d5d17f501d45692b5b0672fc267114548dd9bd7 100644 (file)
@@ -364,7 +364,8 @@ static void brw_set_dp_write_message( struct brw_context *brw,
                                      GLuint msg_length,
                                      GLuint pixel_scoreboard_clear,
                                      GLuint response_length,
-                                     GLuint end_of_thread )
+                                     GLuint end_of_thread,
+                                     GLuint send_commit_msg)
 {
    struct intel_context *intel = &brw->intel;
    brw_set_src1(insn, brw_imm_d(0));
@@ -374,7 +375,7 @@ static void brw_set_dp_write_message( struct brw_context *brw,
        insn->bits3.dp_write_gen5.msg_control = msg_control;
        insn->bits3.dp_write_gen5.pixel_scoreboard_clear = pixel_scoreboard_clear;
        insn->bits3.dp_write_gen5.msg_type = msg_type;
-       insn->bits3.dp_write_gen5.send_commit_msg = 0;
+       insn->bits3.dp_write_gen5.send_commit_msg = send_commit_msg;
        insn->bits3.dp_write_gen5.header_present = 1;
        insn->bits3.dp_write_gen5.response_length = response_length;
        insn->bits3.dp_write_gen5.msg_length = msg_length;
@@ -386,7 +387,7 @@ static void brw_set_dp_write_message( struct brw_context *brw,
        insn->bits3.dp_write.msg_control = msg_control;
        insn->bits3.dp_write.pixel_scoreboard_clear = pixel_scoreboard_clear;
        insn->bits3.dp_write.msg_type = msg_type;
-       insn->bits3.dp_write.send_commit_msg = 0;
+       insn->bits3.dp_write.send_commit_msg = send_commit_msg;
        insn->bits3.dp_write.response_length = response_length;
        insn->bits3.dp_write.msg_length = msg_length;
        insn->bits3.dp_write.msg_target = BRW_MESSAGE_TARGET_DATAPORT_WRITE;
@@ -906,6 +907,20 @@ void brw_CMP(struct brw_compile *p,
    }
 }
 
+/* Issue 'wait' instruction for n1, host could program MMIO
+   to wake up thread. */
+void brw_WAIT (struct brw_compile *p)
+{
+   struct brw_instruction *insn = next_insn(p, BRW_OPCODE_WAIT);
+   struct brw_reg src = brw_notification_1_reg();
+
+   brw_set_dest(insn, src);
+   brw_set_src0(insn, src);
+   brw_set_src1(insn, brw_null_reg());
+   insn->header.execution_size = 0; /* must */
+   insn->header.predicate_control = 0;
+   insn->header.compression_control = 0;
+}
 
 
 /***********************************************************************
@@ -1040,6 +1055,7 @@ void brw_dp_WRITE_16( struct brw_compile *p,
                      struct brw_reg src,
                      GLuint scratch_offset )
 {
+   struct intel_context *intel = &p->brw->intel;
    GLuint msg_reg_nr = 1;
    {
       brw_push_insn_state(p);
@@ -1056,13 +1072,32 @@ void brw_dp_WRITE_16( struct brw_compile *p,
 
    {
       GLuint msg_length = 3;
-      struct brw_reg dest = retype(brw_null_reg(), BRW_REGISTER_TYPE_UW);
+      struct brw_reg dest;
       struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
-   
+      int send_commit_msg;
+
       insn->header.predicate_control = 0; /* XXX */
       insn->header.compression_control = BRW_COMPRESSION_NONE; 
       insn->header.destreg__conditionalmod = msg_reg_nr;
-  
+
+      /* Until gen6, writes followed by reads from the same location
+       * are not guaranteed to be ordered unless write_commit is set.
+       * If set, then a no-op write is issued to the destination
+       * register to set a dependency, and a read from the destination
+       * can be used to ensure the ordering.
+       *
+       * For gen6, only writes between different threads need ordering
+       * protection.  Our use of DP writes is all about register
+       * spilling within a thread.
+       */
+      if (intel->gen >= 6) {
+        dest = retype(vec16(brw_null_reg()), BRW_REGISTER_TYPE_UW);
+        send_commit_msg = 0;
+      } else {
+        dest = brw_uw16_grf(0, 0);
+        send_commit_msg = 1;
+      }
+
       brw_set_dest(insn, dest);
       brw_set_src0(insn, src);
 
@@ -1073,8 +1108,9 @@ void brw_dp_WRITE_16( struct brw_compile *p,
                               BRW_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE, /* msg_type */
                               msg_length,
                               0, /* pixel scoreboard */
-                              0, /* response_length */
-                              0); /* eot */
+                              send_commit_msg, /* response_length */
+                              0, /* eot */
+                              send_commit_msg);
    }
 }
 
@@ -1115,7 +1151,7 @@ void brw_dp_READ_16( struct brw_compile *p,
       brw_set_dp_read_message(p->brw,
                              insn,
                              255, /* binding table index (255=stateless) */
-                             3,  /* msg_control (3 means 4 Owords) */
+                             BRW_DATAPORT_OWORD_BLOCK_4_OWORDS,
                              BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */
                              1, /* target cache (render/scratch) */
                              1, /* msg_length */
@@ -1190,68 +1226,107 @@ void brw_dp_READ_4( struct brw_compile *p,
  */
 void brw_dp_READ_4_vs(struct brw_compile *p,
                       struct brw_reg dest,
-                      GLuint oword,
-                      GLboolean relAddr,
-                      struct brw_reg addrReg,
                       GLuint location,
                       GLuint bind_table_index)
 {
+   struct brw_instruction *insn;
    GLuint msg_reg_nr = 1;
+   struct brw_reg b;
 
-   assert(oword < 2);
    /*
    printf("vs const read msg, location %u, msg_reg_nr %d\n",
           location, msg_reg_nr);
    */
 
    /* Setup MRF[1] with location/offset into const buffer */
-   {
-      struct brw_reg b;
+   brw_push_insn_state(p);
+   brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+   brw_set_mask_control(p, BRW_MASK_DISABLE);
+   brw_set_predicate_control(p, BRW_PREDICATE_NONE);
 
-      brw_push_insn_state(p);
-      brw_set_compression_control(p, BRW_COMPRESSION_NONE);
-      brw_set_mask_control(p, BRW_MASK_DISABLE);
-      brw_set_predicate_control(p, BRW_PREDICATE_NONE);
-      /*brw_set_access_mode(p, BRW_ALIGN_16);*/
+   /* XXX I think we're setting all the dwords of MRF[1] to 'location'.
+    * when the docs say only dword[2] should be set.  Hmmm.  But it works.
+    */
+   b = brw_message_reg(msg_reg_nr);
+   b = retype(b, BRW_REGISTER_TYPE_UD);
+   /*b = get_element_ud(b, 2);*/
+   brw_MOV(p, b, brw_imm_ud(location));
 
-      /* XXX I think we're setting all the dwords of MRF[1] to 'location'.
-       * when the docs say only dword[2] should be set.  Hmmm.  But it works.
-       */
-      b = brw_message_reg(msg_reg_nr);
-      b = retype(b, BRW_REGISTER_TYPE_UD);
-      /*b = get_element_ud(b, 2);*/
-      if (relAddr) {
-         brw_ADD(p, b, addrReg, brw_imm_ud(location));
-      }
-      else {
-         brw_MOV(p, b, brw_imm_ud(location));
-      }
+   brw_pop_insn_state(p);
 
-      brw_pop_insn_state(p);
-   }
+   insn = next_insn(p, BRW_OPCODE_SEND);
 
-   {
-      struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
-   
-      insn->header.predicate_control = BRW_PREDICATE_NONE;
-      insn->header.compression_control = BRW_COMPRESSION_NONE; 
-      insn->header.destreg__conditionalmod = msg_reg_nr;
-      insn->header.mask_control = BRW_MASK_DISABLE;
-      /*insn->header.access_mode = BRW_ALIGN_16;*/
-  
-      brw_set_dest(insn, dest);
-      brw_set_src0(insn, brw_null_reg());
+   insn->header.predicate_control = BRW_PREDICATE_NONE;
+   insn->header.compression_control = BRW_COMPRESSION_NONE;
+   insn->header.destreg__conditionalmod = msg_reg_nr;
+   insn->header.mask_control = BRW_MASK_DISABLE;
 
-      brw_set_dp_read_message(p->brw,
-                             insn,
-                             bind_table_index,
-                             oword,  /* 0 = lower Oword, 1 = upper Oword */
-                             BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */
-                             0, /* source cache = data cache */
-                             1, /* msg_length */
-                             1, /* response_length (1 Oword) */
-                             0); /* eot */
-   }
+   brw_set_dest(insn, dest);
+   brw_set_src0(insn, brw_null_reg());
+
+   brw_set_dp_read_message(p->brw,
+                          insn,
+                          bind_table_index,
+                          0,
+                          BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */
+                          0, /* source cache = data cache */
+                          1, /* msg_length */
+                          1, /* response_length (1 Oword) */
+                          0); /* eot */
+}
+
+/**
+ * Read a float[4] constant per vertex from VS constant buffer, with
+ * relative addressing.
+ */
+void brw_dp_READ_4_vs_relative(struct brw_compile *p,
+                              struct brw_reg dest,
+                              struct brw_reg addr_reg,
+                              GLuint offset,
+                              GLuint bind_table_index)
+{
+   struct intel_context *intel = &p->brw->intel;
+   int msg_type;
+
+   /* Setup MRF[1] with offset into const buffer */
+   brw_push_insn_state(p);
+   brw_set_compression_control(p, BRW_COMPRESSION_NONE);
+   brw_set_mask_control(p, BRW_MASK_DISABLE);
+   brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+
+   /* M1.0 is block offset 0, M1.4 is block offset 1, all other
+    * fields ignored.
+    */
+   brw_ADD(p, retype(brw_message_reg(1), BRW_REGISTER_TYPE_UD),
+          addr_reg, brw_imm_d(offset));
+   brw_pop_insn_state(p);
+
+   struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
+
+   insn->header.predicate_control = BRW_PREDICATE_NONE;
+   insn->header.compression_control = BRW_COMPRESSION_NONE;
+   insn->header.destreg__conditionalmod = 0;
+   insn->header.mask_control = BRW_MASK_DISABLE;
+
+   brw_set_dest(insn, dest);
+   brw_set_src0(insn, brw_vec8_grf(0, 0));
+
+   if (intel->gen == 6)
+      msg_type = GEN6_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ;
+   else if (intel->gen == 5 || intel->is_g4x)
+      msg_type = G45_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ;
+   else
+      msg_type = BRW_DATAPORT_READ_MESSAGE_OWORD_DUAL_BLOCK_READ;
+
+   brw_set_dp_read_message(p->brw,
+                          insn,
+                          bind_table_index,
+                          BRW_DATAPORT_OWORD_DUAL_BLOCK_1OWORD,
+                          msg_type,
+                          0, /* source cache = data cache */
+                          2, /* msg_length */
+                          1, /* response_length */
+                          0); /* eot */
 }
 
 
@@ -1281,7 +1356,8 @@ void brw_fb_WRITE(struct brw_compile *p,
                            msg_length,
                            1,  /* pixel scoreboard */
                            response_length, 
-                           eot);
+                           eot,
+                           0 /* send_commit_msg */);
 }
 
 
index 99a6f6be113aa935e2fc822528d27ed9ac85dbc5..a01d5576f8cd93291a35e336f096c8613df2749e 100644 (file)
@@ -34,7 +34,7 @@
 #include "main/macros.h"
 #include "main/enums.h"
 
-#include "shader/program.h"
+#include "program/program.h"
 #include "intel_batchbuffer.h"
 
 #include "brw_defines.h"
index e79b3ddea3502d9b8e798a9955efa8d3d51ff76d..8aa6fb6cc6fb2534e2a3a97966829c22691cd696 100644 (file)
  */
 
 #include "main/macros.h"
-#include "shader/program.h"
-#include "shader/prog_print.h"
+#include "program/program.h"
+#include "program/prog_print.h"
 #include "brw_context.h"
 #include "brw_defines.h"
 #include "brw_eu.h"
 
+static const struct {
+    char    *name;
+    int            nsrc;
+    int            ndst;
+    GLboolean is_arith;
+} inst_opcode[128] = {
+    [BRW_OPCODE_MOV] = { .name = "mov", .nsrc = 1, .ndst = 1, .is_arith = 1 },
+    [BRW_OPCODE_FRC] = { .name = "frc", .nsrc = 1, .ndst = 1, .is_arith = 1 },
+    [BRW_OPCODE_RNDU] = { .name = "rndu", .nsrc = 1, .ndst = 1, .is_arith = 1 },
+    [BRW_OPCODE_RNDD] = { .name = "rndd", .nsrc = 1, .ndst = 1, .is_arith = 1 },
+    [BRW_OPCODE_RNDE] = { .name = "rnde", .nsrc = 1, .ndst = 1, .is_arith = 1 },
+    [BRW_OPCODE_RNDZ] = { .name = "rndz", .nsrc = 1, .ndst = 1, .is_arith = 1 },
+    [BRW_OPCODE_NOT] = { .name = "not", .nsrc = 1, .ndst = 1, .is_arith = 1 },
+    [BRW_OPCODE_LZD] = { .name = "lzd", .nsrc = 1, .ndst = 1 },
+
+    [BRW_OPCODE_MUL] = { .name = "mul", .nsrc = 2, .ndst = 1, .is_arith = 1 },
+    [BRW_OPCODE_MAC] = { .name = "mac", .nsrc = 2, .ndst = 1, .is_arith = 1 },
+    [BRW_OPCODE_MACH] = { .name = "mach", .nsrc = 2, .ndst = 1, .is_arith = 1 },
+    [BRW_OPCODE_LINE] = { .name = "line", .nsrc = 2, .ndst = 1, .is_arith = 1 },
+    [BRW_OPCODE_PLN] = { .name = "pln", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_SAD2] = { .name = "sad2", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_SADA2] = { .name = "sada2", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_DP4] = { .name = "dp4", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_DPH] = { .name = "dph", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_DP3] = { .name = "dp3", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_DP2] = { .name = "dp2", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_MATH] = { .name = "math", .nsrc = 2, .ndst = 1 },
+
+    [BRW_OPCODE_AVG] = { .name = "avg", .nsrc = 2, .ndst = 1, .is_arith = 1 },
+    [BRW_OPCODE_ADD] = { .name = "add", .nsrc = 2, .ndst = 1, .is_arith = 1 },
+    [BRW_OPCODE_SEL] = { .name = "sel", .nsrc = 2, .ndst = 1, .is_arith = 1 },
+    [BRW_OPCODE_AND] = { .name = "and", .nsrc = 2, .ndst = 1, .is_arith = 1 },
+    [BRW_OPCODE_OR] = { .name = "or", .nsrc = 2, .ndst = 1, .is_arith = 1 },
+    [BRW_OPCODE_XOR] = { .name = "xor", .nsrc = 2, .ndst = 1, .is_arith = 1 },
+    [BRW_OPCODE_SHR] = { .name = "shr", .nsrc = 2, .ndst = 1, .is_arith = 1 },
+    [BRW_OPCODE_SHL] = { .name = "shl", .nsrc = 2, .ndst = 1, .is_arith = 1 },
+    [BRW_OPCODE_ASR] = { .name = "asr", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_CMP] = { .name = "cmp", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_CMPN] = { .name = "cmpn", .nsrc = 2, .ndst = 1 },
+
+    [BRW_OPCODE_SEND] = { .name = "send", .nsrc = 1, .ndst = 1 },
+    [BRW_OPCODE_NOP] = { .name = "nop", .nsrc = 0, .ndst = 0 },
+    [BRW_OPCODE_JMPI] = { .name = "jmpi", .nsrc = 1, .ndst = 0 },
+    [BRW_OPCODE_IF] = { .name = "if", .nsrc = 2, .ndst = 0 },
+    [BRW_OPCODE_IFF] = { .name = "iff", .nsrc = 2, .ndst = 1 },
+    [BRW_OPCODE_WHILE] = { .name = "while", .nsrc = 2, .ndst = 0 },
+    [BRW_OPCODE_ELSE] = { .name = "else", .nsrc = 2, .ndst = 0 },
+    [BRW_OPCODE_BREAK] = { .name = "break", .nsrc = 2, .ndst = 0 },
+    [BRW_OPCODE_CONTINUE] = { .name = "cont", .nsrc = 1, .ndst = 0 },
+    [BRW_OPCODE_HALT] = { .name = "halt", .nsrc = 1, .ndst = 0 },
+    [BRW_OPCODE_MSAVE] = { .name = "msave", .nsrc = 1, .ndst = 1 },
+    [BRW_OPCODE_PUSH] = { .name = "push", .nsrc = 1, .ndst = 1 },
+    [BRW_OPCODE_MRESTORE] = { .name = "mrest", .nsrc = 1, .ndst = 1 },
+    [BRW_OPCODE_POP] = { .name = "pop", .nsrc = 2, .ndst = 0 },
+    [BRW_OPCODE_WAIT] = { .name = "wait", .nsrc = 1, .ndst = 0 },
+    [BRW_OPCODE_DO] = { .name = "do", .nsrc = 0, .ndst = 0 },
+    [BRW_OPCODE_ENDIF] = { .name = "endif", .nsrc = 2, .ndst = 0 },
+};
+
+static INLINE
+GLboolean brw_is_arithmetic_inst(const struct brw_instruction *inst)
+{
+   return inst_opcode[inst->header.opcode].is_arith;
+}
+
+static const GLuint inst_stride[7] = {
+    [0] = 0,
+    [1] = 1,
+    [2] = 2,
+    [3] = 4,
+    [4] = 8,
+    [5] = 16,
+    [6] = 32
+};
+
+static const GLuint inst_type_size[8] = {
+    [BRW_REGISTER_TYPE_UD] = 4,
+    [BRW_REGISTER_TYPE_D] = 4,
+    [BRW_REGISTER_TYPE_UW] = 2,
+    [BRW_REGISTER_TYPE_W] = 2,
+    [BRW_REGISTER_TYPE_UB] = 1,
+    [BRW_REGISTER_TYPE_B] = 1,
+    [BRW_REGISTER_TYPE_F] = 4
+};
+
+static INLINE GLboolean
+brw_is_grf_written(const struct brw_instruction *inst,
+                   int reg_index, int size,
+                   int gen)
+{
+   if (inst_opcode[inst->header.opcode].ndst == 0)
+      return GL_FALSE;
+
+   if (inst->bits1.da1.dest_address_mode != BRW_ADDRESS_DIRECT)
+      if (inst->bits1.ia1.dest_reg_file == BRW_GENERAL_REGISTER_FILE)
+         return GL_TRUE;
+
+   if (inst->bits1.da1.dest_reg_file != BRW_GENERAL_REGISTER_FILE)
+      return GL_FALSE;
+
+   const int reg_start = reg_index * REG_SIZE;
+   const int reg_end = reg_start + size;
+
+   const int type_size = inst_type_size[inst->bits1.da1.dest_reg_type];
+   const int write_start = inst->bits1.da1.dest_reg_nr*REG_SIZE
+                         + inst->bits1.da1.dest_subreg_nr;
+   int length, write_end;
+
+   /* SEND is specific */
+   if (inst->header.opcode == BRW_OPCODE_SEND) {
+      if (gen >= 5)
+         length = inst->bits3.generic_gen5.response_length*REG_SIZE;
+      else 
+         length = inst->bits3.generic.response_length*REG_SIZE;
+   }
+   else {
+      length = 1 << inst->header.execution_size;
+      length *= type_size;
+      length *= inst->bits1.da1.dest_horiz_stride;
+   }
+
+   /* If the two intervals intersect, we overwrite the register */
+   write_end = write_start + length;
+   const int left = MAX2(write_start, reg_start);
+   const int right = MIN2(write_end, reg_end);
+
+   return left < right;
+}
+
+/* Specific path for message register since we need to handle the compr4 case */
+static INLINE GLboolean
+brw_is_mrf_written(const struct brw_instruction *inst, int reg_index, int size)
+{
+   if (inst_opcode[inst->header.opcode].ndst == 0)
+      return GL_FALSE;
+
+   if (inst->bits1.da1.dest_address_mode != BRW_ADDRESS_DIRECT)
+      if (inst->bits1.ia1.dest_reg_file == BRW_MESSAGE_REGISTER_FILE)
+         return GL_TRUE;
+
+   if (inst->bits1.da1.dest_reg_file != BRW_MESSAGE_REGISTER_FILE)
+      return GL_FALSE;
+
+   const int reg_start = reg_index * REG_SIZE;
+   const int reg_end = reg_start + size;
+
+   const int mrf_index = inst->bits1.da1.dest_reg_nr & 0x0f;
+   const int is_compr4 = inst->bits1.da1.dest_reg_nr & BRW_MRF_COMPR4;
+   const int type_size = inst_type_size[inst->bits1.da1.dest_reg_type];
+
+   /* We use compr4 with a size != 16 elements. Strange, we conservatively
+    * consider that we are writing the register.
+    */
+   if (is_compr4 && inst->header.execution_size != BRW_EXECUTE_16)
+      return GL_TRUE;
+
+   GLboolean is_written = GL_FALSE;
+
+   /* Here we write mrf_{i} and mrf_{i+4}. So we read two times 8 elements */
+   if (is_compr4) {
+      const int length = 8 * type_size * inst->bits1.da1.dest_horiz_stride;
+
+      /* First 8-way register */
+      const int write_start0 = mrf_index*REG_SIZE
+                             + inst->bits1.da1.dest_subreg_nr;
+      const int write_end0 = write_start0 + length;
+
+      /* Second 8-way register */
+      const int write_start1 = (mrf_index+4)*REG_SIZE
+                             + inst->bits1.da1.dest_subreg_nr;
+      const int write_end1 = write_start1 + length;
+
+      /* If the two intervals intersect, we overwrite the register */
+      const int left0 = MAX2(write_start0, reg_start);
+      const int right0 = MIN2(write_end0, reg_end);
+      const int left1 = MAX2(write_start1, reg_start);
+      const int right1 = MIN2(write_end1, reg_end);
+
+      is_written = left0 < right0 || left1 < right1;
+   }
+   else {
+      int length;
+      length = 1 << inst->header.execution_size;
+      length *= type_size;
+      length *= inst->bits1.da1.dest_horiz_stride;
+
+      /* If the two intervals intersect, we write into the register */
+      const int write_start = inst->bits1.da1.dest_reg_nr*REG_SIZE
+                            + inst->bits1.da1.dest_subreg_nr;
+      const int write_end = write_start + length;
+      const int left = MAX2(write_start, reg_start);
+      const int right = MIN2(write_end, reg_end);;
+
+      is_written = left < right;
+   }
+
+   /* SEND may perform an implicit mov to a mrf register */
+   if (is_written == GL_FALSE &&
+       inst->header.opcode == BRW_OPCODE_SEND &&
+       inst->bits1.da1.src0_reg_file != 0) {
+
+      const int mrf_start = inst->header.destreg__conditionalmod;
+      const int write_start = mrf_start * REG_SIZE;
+      const int write_end = write_start + REG_SIZE;
+      const int left = MAX2(write_start, reg_start);
+      const int right = MIN2(write_end, reg_end);;
+      is_written = left < right;
+   }
+
+   return is_written;
+}
+
+static INLINE GLboolean
+brw_is_mrf_read(const struct brw_instruction *inst,
+                int reg_index, int size, int gen)
+{
+   if (inst->header.opcode != BRW_OPCODE_SEND)
+      return GL_FALSE;
+   if (inst->bits2.da1.src0_address_mode != BRW_ADDRESS_DIRECT)
+      return GL_TRUE;
+
+   const int reg_start = reg_index*REG_SIZE;
+   const int reg_end = reg_start + size;
+
+   int length, read_start, read_end;
+   if (gen >= 5)
+      length = inst->bits3.generic_gen5.msg_length*REG_SIZE;
+   else 
+      length = inst->bits3.generic.msg_length*REG_SIZE;
+
+   /* Look if SEND uses an implicit mov. In that case, we read one less register
+    * (but we write it)
+    */
+   if (inst->bits1.da1.src0_reg_file != 0)
+      read_start = inst->header.destreg__conditionalmod;
+   else {
+      length--;
+      read_start = inst->header.destreg__conditionalmod + 1;
+   }
+   read_start *= REG_SIZE;
+   read_end = read_start + length;
+
+   const int left = MAX2(read_start, reg_start);
+   const int right = MIN2(read_end, reg_end);
+
+   return left < right;
+}
+
+static INLINE GLboolean
+brw_is_grf_read(const struct brw_instruction *inst, int reg_index, int size)
+{
+   int i, j;
+   if (inst_opcode[inst->header.opcode].nsrc == 0)
+      return GL_FALSE;
+
+   /* Look at first source. We must take into account register regions to
+    * monitor carefully the read. Note that we are a bit too conservative here
+    * since we do not take into account the fact that some complete registers
+    * may be skipped
+    */
+   if (inst_opcode[inst->header.opcode].nsrc >= 1) {
+
+      if (inst->bits2.da1.src0_address_mode != BRW_ADDRESS_DIRECT)
+         if (inst->bits1.ia1.src0_reg_file == BRW_GENERAL_REGISTER_FILE)
+            return GL_TRUE;
+      if (inst->bits1.da1.src0_reg_file != BRW_GENERAL_REGISTER_FILE)
+         return GL_FALSE;
+
+      const int reg_start = reg_index*REG_SIZE;
+      const int reg_end = reg_start + size;
+
+      /* See if at least one of this element intersects the interval */
+      const int type_size = inst_type_size[inst->bits1.da1.src0_reg_type];
+      const int elem_num = 1 << inst->header.execution_size;
+      const int width = 1 << inst->bits2.da1.src0_width;
+      const int row_num = elem_num >> inst->bits2.da1.src0_width;
+      const int hs = type_size*inst_stride[inst->bits2.da1.src0_horiz_stride];
+      const int vs = type_size*inst_stride[inst->bits2.da1.src0_vert_stride];
+      int row_start = inst->bits2.da1.src0_reg_nr*REG_SIZE
+                    + inst->bits2.da1.src0_subreg_nr;
+      for (j = 0; j < row_num; ++j) {
+         int write_start = row_start;
+         for (i = 0; i < width; ++i) {
+            const int write_end = write_start + type_size;
+            const int left = write_start > reg_start ? write_start : reg_start;
+            const int right = write_end < reg_end ? write_end : reg_end;
+            if (left < right)
+               return GL_TRUE;
+            write_start += hs;
+         }
+         row_start += vs;
+      }
+   }
+
+   /* Second src register */
+   if (inst_opcode[inst->header.opcode].nsrc >= 2) {
+
+      if (inst->bits3.da1.src1_address_mode != BRW_ADDRESS_DIRECT)
+         if (inst->bits1.ia1.src1_reg_file == BRW_GENERAL_REGISTER_FILE)
+            return GL_TRUE;
+      if (inst->bits1.da1.src1_reg_file != BRW_GENERAL_REGISTER_FILE)
+         return GL_FALSE;
+
+      const int reg_start = reg_index*REG_SIZE;
+      const int reg_end = reg_start + size;
+
+      /* See if at least one of this element intersects the interval */
+      const int type_size = inst_type_size[inst->bits1.da1.src1_reg_type];
+      const int elem_num = 1 << inst->header.execution_size;
+      const int width = 1 << inst->bits3.da1.src1_width;
+      const int row_num = elem_num >> inst->bits3.da1.src1_width;
+      const int hs = type_size*inst_stride[inst->bits3.da1.src1_horiz_stride];
+      const int vs = type_size*inst_stride[inst->bits3.da1.src1_vert_stride];
+      int row_start = inst->bits3.da1.src1_reg_nr*REG_SIZE
+                    + inst->bits3.da1.src1_subreg_nr;
+      for (j = 0; j < row_num; ++j) {
+         int write_start = row_start;
+         for (i = 0; i < width; ++i) {
+            const int write_end = write_start + type_size;
+            const int left = write_start > reg_start ? write_start : reg_start;
+            const int right = write_end < reg_end ? write_end : reg_end;
+            if (left < right)
+               return GL_TRUE;
+            write_start += hs;
+         }
+         row_start += vs;
+      }
+   }
+
+   return GL_FALSE;
+}
+
+static INLINE GLboolean
+brw_is_control_done(const struct brw_instruction *mov) {
+   return
+       mov->header.dependency_control != 0 ||
+       mov->header.thread_control != 0 ||
+       mov->header.mask_control != 0 ||
+       mov->header.saturate != 0 ||
+       mov->header.debug_control != 0;
+}
+
+static INLINE GLboolean
+brw_is_predicated(const struct brw_instruction *mov) {
+   return mov->header.predicate_control != 0;
+}
+
+static INLINE GLboolean
+brw_is_grf_to_mrf_mov(const struct brw_instruction *mov,
+                      int *mrf_index,
+                      int *grf_index,
+                      GLboolean *is_compr4)
+{
+   if (brw_is_predicated(mov) ||
+       brw_is_control_done(mov) ||
+       mov->header.debug_control != 0)
+      return GL_FALSE;
+
+   if (mov->bits1.da1.dest_address_mode != BRW_ADDRESS_DIRECT ||
+       mov->bits1.da1.dest_reg_file != BRW_MESSAGE_REGISTER_FILE ||
+       mov->bits1.da1.dest_reg_type != BRW_REGISTER_TYPE_F ||
+       mov->bits1.da1.dest_horiz_stride != BRW_HORIZONTAL_STRIDE_1 ||
+       mov->bits1.da1.dest_subreg_nr != 0)
+      return GL_FALSE;
+
+   if (mov->bits2.da1.src0_address_mode != BRW_ADDRESS_DIRECT ||
+       mov->bits1.da1.src0_reg_file != BRW_GENERAL_REGISTER_FILE ||
+       mov->bits1.da1.src0_reg_type != BRW_REGISTER_TYPE_F ||
+       mov->bits2.da1.src0_width != BRW_WIDTH_8 ||
+       mov->bits2.da1.src0_horiz_stride != BRW_HORIZONTAL_STRIDE_1 ||
+       mov->bits2.da1.src0_vert_stride != BRW_VERTICAL_STRIDE_8 ||
+       mov->bits2.da1.src0_subreg_nr != 0 ||
+       mov->bits2.da1.src0_abs != 0 ||
+       mov->bits2.da1.src0_negate != 0)
+      return GL_FALSE;
+
+   *grf_index = mov->bits2.da1.src0_reg_nr;
+   *mrf_index = mov->bits1.da1.dest_reg_nr & 0x0f;
+   *is_compr4 = (mov->bits1.da1.dest_reg_nr & BRW_MRF_COMPR4) != 0;
+   return GL_TRUE;
+}
+
+static INLINE GLboolean
+brw_is_grf_straight_write(const struct brw_instruction *inst, int grf_index)
+{
+   /* remark: no problem to predicate a SEL instruction */
+   if ((!brw_is_predicated(inst) || inst->header.opcode == BRW_OPCODE_SEL) &&
+       brw_is_control_done(inst) == GL_FALSE &&
+       inst->header.execution_size == 4 &&
+       inst->header.access_mode == BRW_ALIGN_1 &&
+       inst->bits1.da1.dest_address_mode == BRW_ADDRESS_DIRECT &&
+       inst->bits1.da1.dest_reg_file == BRW_GENERAL_REGISTER_FILE &&
+       inst->bits1.da1.dest_reg_type == BRW_REGISTER_TYPE_F &&
+       inst->bits1.da1.dest_horiz_stride == BRW_HORIZONTAL_STRIDE_1 &&
+       inst->bits1.da1.dest_reg_nr == grf_index &&
+       inst->bits1.da1.dest_subreg_nr == 0 &&
+       brw_is_arithmetic_inst(inst))
+      return GL_TRUE;
+
+   return GL_FALSE;
+}
+
+static INLINE GLboolean
+brw_inst_are_equal(const struct brw_instruction *src0,
+                   const struct brw_instruction *src1)
+{
+   const GLuint *field0 = (GLuint *) src0;
+   const GLuint *field1 = (GLuint *) src1;
+   return field0[0] == field1[0] &&
+          field0[1] == field1[1] &&
+          field0[2] == field1[2] &&
+          field0[3] == field1[3];
+}
+
+static INLINE void
+brw_inst_copy(struct brw_instruction *dst,
+              const struct brw_instruction *src)
+{
+   GLuint *field_dst = (GLuint *) dst;
+   const GLuint *field_src = (GLuint *) src;
+   field_dst[0] = field_src[0];
+   field_dst[1] = field_src[1];
+   field_dst[2] = field_src[2];
+   field_dst[3] = field_src[3];
+}
+
+static void brw_remove_inst(struct brw_compile *p, const GLboolean *removeInst)
+{
+   int i, nr_insn = 0, to = 0, from = 0;
+
+   for (from = 0; from < p->nr_insn; ++from) {
+      if (removeInst[from])
+         continue;
+      if(to != from)
+         brw_inst_copy(p->store + to, p->store + from);
+      to++;
+   }
+
+   for (i = 0; i < p->nr_insn; ++i)
+      if (removeInst[i] == GL_FALSE)
+         nr_insn++;
+   p->nr_insn = nr_insn;
+}
+
+/* The gen code emitter generates a lot of duplications in the
+ * grf-to-mrf moves, for example when texture sampling with the same
+ * coordinates from multiple textures..  Here, we monitor same mov
+ * grf-to-mrf instrutions and remove repeated ones where the operands
+ * and dst ahven't changed in between.
+ */
+void brw_remove_duplicate_mrf_moves(struct brw_compile *p)
+{
+   const int gen = p->brw->intel.gen;
+   int i, j;
+
+   GLboolean *removeInst = calloc(sizeof(GLboolean), p->nr_insn);
+   for (i = 0; i < p->nr_insn; i++) {
+      if (removeInst[i])
+         continue;
+
+      const struct brw_instruction *mov = p->store + i;
+      int mrf_index, grf_index;
+      GLboolean is_compr4;
+
+      /* Only consider _straight_ grf-to-mrf moves */
+      if (!brw_is_grf_to_mrf_mov(mov, &mrf_index, &grf_index, &is_compr4))
+         continue;
+
+      const int mrf_index0 = mrf_index;
+      const int mrf_index1 = is_compr4 ? mrf_index0+4 : mrf_index0+1;
+      const int simd16_size = 2 * REG_SIZE;
+
+      for (j = i + 1; j < p->nr_insn; j++) {
+         const struct brw_instruction *inst = p->store + j;
+
+         if (brw_inst_are_equal(mov, inst)) {
+            removeInst[j] = GL_TRUE;
+            continue;
+         }
+
+         if (brw_is_grf_written(inst, grf_index, simd16_size, gen) ||
+             brw_is_mrf_written(inst, mrf_index0, REG_SIZE) ||
+             brw_is_mrf_written(inst, mrf_index1, REG_SIZE))
+            break;
+      }
+   }
+
+   brw_remove_inst(p, removeInst);
+   free(removeInst);
+}
+
+/* Replace moves to MRFs where the value moved is the result of a
+ * normal arithmetic operation with computation right into the MRF.
+ */
+void brw_remove_grf_to_mrf_moves(struct brw_compile *p)
+{
+   int i, j, prev;
+   struct brw_context *brw = p->brw;
+   const int gen = brw->intel.gen;
+   const int simd16_size = 2*REG_SIZE;
+
+   GLboolean *removeInst = calloc(sizeof(GLboolean), p->nr_insn);
+   assert(removeInst);
+
+   for (i = 0; i < p->nr_insn; i++) {
+      if (removeInst[i])
+         continue;
+
+      struct brw_instruction *grf_inst = NULL;
+      const struct brw_instruction *mov = p->store + i;
+      int mrf_index, grf_index;
+      GLboolean is_compr4;
+
+      /* Only consider _straight_ grf-to-mrf moves */
+      if (!brw_is_grf_to_mrf_mov(mov, &mrf_index, &grf_index, &is_compr4))
+         continue;
+
+      /* Using comp4 enables a stride of 4 for this instruction */
+      const int mrf_index0 = mrf_index;
+      const int mrf_index1 = is_compr4 ? mrf_index+4 : mrf_index+1;
+
+      /* Look where the register has been set */
+      prev = i;
+      GLboolean potential_remove = GL_FALSE;
+      while (prev--) {
+
+         /* If _one_ instruction writes the grf, we try to remove the mov */
+         struct brw_instruction *inst = p->store + prev;
+         if (brw_is_grf_straight_write(inst, grf_index)) {
+            potential_remove = GL_TRUE;
+            grf_inst = inst;
+            break;
+         }
+
+      }
+
+      if (potential_remove == GL_FALSE)
+         continue;
+      removeInst[i] = GL_TRUE;
+
+      /* Monitor first the section of code between the grf computation and the
+       * mov. Here we cannot read or write both mrf and grf register
+       */
+      for (j = prev + 1; j < i; ++j) {
+         struct brw_instruction *inst = p->store + j;
+         if (removeInst[j])
+            continue;
+         if (brw_is_grf_written(inst, grf_index, simd16_size, gen)   ||
+             brw_is_grf_read(inst, grf_index, simd16_size)           ||
+             brw_is_mrf_written(inst, mrf_index0, REG_SIZE)   ||
+             brw_is_mrf_written(inst, mrf_index1, REG_SIZE)   ||
+             brw_is_mrf_read(inst, mrf_index0, REG_SIZE, gen) ||
+             brw_is_mrf_read(inst, mrf_index1, REG_SIZE, gen)) {
+            removeInst[i] = GL_FALSE;
+            break;
+         }
+      }
+
+      /* After the mov, we can read or write the mrf. If the grf is overwritten,
+       * we are done
+       */
+      for (j = i + 1; j < p->nr_insn; ++j) {
+         struct brw_instruction *inst = p->store + j;
+         if (removeInst[j])
+            continue;
+
+         if (brw_is_grf_read(inst, grf_index, simd16_size)) {
+            removeInst[i] = GL_FALSE;
+            break;
+         }
+
+         if (brw_is_grf_straight_write(inst, grf_index))
+            break;
+      }
+
+      /* Note that with the top down traversal, we can safely pacth the mov
+       * instruction
+       */
+      if (removeInst[i]) {
+         grf_inst->bits1.da1.dest_reg_file = mov->bits1.da1.dest_reg_file;
+         grf_inst->bits1.da1.dest_reg_nr = mov->bits1.da1.dest_reg_nr;
+      }
+   }
+
+   brw_remove_inst(p, removeInst);
+   free(removeInst);
+}
+
 static GLboolean
 is_single_channel_dp4(struct brw_instruction *insn)
 {
index bd560acdadf69192d97b78ea30f7f63a5bbeb3e1..4b08d2599bc0b1c49546856366f437a6dc80cb15 100644 (file)
   
 #include "main/imports.h"
 #include "main/enums.h"
-#include "shader/prog_parameter.h"
-#include "shader/program.h"
-#include "shader/programopt.h"
-#include "shader/shader_api.h"
+#include "main/shaderobj.h"
+#include "program/prog_parameter.h"
+#include "program/program.h"
+#include "program/programopt.h"
 #include "tnl/tnl.h"
 
 #include "brw_context.h"
@@ -174,9 +174,36 @@ static GLboolean brwProgramStringNotify( GLcontext *ctx,
         shader_error(ctx, prog,
                      "i965 driver doesn't yet support uninlined function "
                      "calls.  Move to using a single return statement at "
-                     "the end of the function to work around it.");
+                     "the end of the function to work around it.\n");
         return GL_FALSE;
       }
+      if (prog->Instructions[i].DstReg.RelAddr &&
+         prog->Instructions[i].DstReg.File == PROGRAM_INPUT) {
+        shader_error(ctx, prog,
+                     "Variable indexing of shader inputs unsupported\n");
+        return GL_FALSE;
+      }
+      if (prog->Instructions[i].DstReg.RelAddr &&
+         prog->Instructions[i].DstReg.File == PROGRAM_OUTPUT) {
+        shader_error(ctx, prog,
+                     "Variable indexing of shader outputs unsupported\n");
+        return GL_FALSE;
+      }
+      if (target == GL_FRAGMENT_PROGRAM_ARB) {
+        if ((prog->Instructions[i].DstReg.RelAddr &&
+             prog->Instructions[i].DstReg.File == PROGRAM_TEMPORARY) ||
+            (prog->Instructions[i].SrcReg[0].RelAddr &&
+             prog->Instructions[i].SrcReg[0].File == PROGRAM_TEMPORARY) ||
+            (prog->Instructions[i].SrcReg[1].RelAddr &&
+             prog->Instructions[i].SrcReg[1].File == PROGRAM_TEMPORARY) ||
+            (prog->Instructions[i].SrcReg[2].RelAddr &&
+             prog->Instructions[i].SrcReg[2].File == PROGRAM_TEMPORARY)) {
+           shader_error(ctx, prog,
+                        "Variable indexing of variable arrays in the FS "
+                        "unsupported\n");
+           return GL_FALSE;
+        }
+      }
    }
 
    return GL_TRUE;
index a0680a56f2c80ae11cbc2856c2d03e385bbb2008..e525c730d3f4310fa57e243d1a8f961f5b91b433 100644 (file)
@@ -34,7 +34,7 @@
 #define BRW_SF_H
 
 
-#include "shader/program.h"
+#include "program/program.h"
 #include "brw_context.h"
 #include "brw_eu.h"
 
index e290ca92f60fc488a46d300f91d4adecd8b28410..914f275cc67c9f500d9e467b2161c75002a95da5 100644 (file)
@@ -130,7 +130,7 @@ struct brw_sf_unit_key {
    unsigned scissor:1;
    unsigned line_smooth:1;
    unsigned point_sprite:1;
-   unsigned point_attenuated:1;
+   unsigned use_vs_point_size:1;
    unsigned render_to_fbo:1;
    float line_width;
    float point_size;
@@ -164,7 +164,8 @@ sf_unit_populate_key(struct brw_context *brw, struct brw_sf_unit_key *key)
 
    key->point_sprite = ctx->Point.PointSprite;
    key->point_size = CLAMP(ctx->Point.Size, ctx->Point.MinSize, ctx->Point.MaxSize);
-   key->point_attenuated = ctx->Point._Attenuated;
+   key->use_vs_point_size = (ctx->VertexProgram.PointSizeEnabled ||
+                            ctx->Point._Attenuated);
 
    /* _NEW_LIGHT */
    key->pv_first = (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION);
@@ -296,7 +297,7 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,
    /* _NEW_POINT */
    sf.sf7.sprite_point = key->point_sprite;
    sf.sf7.point_size = CLAMP(rint(key->point_size), 1, 255) * (1<<3);
-   sf.sf7.use_point_size_state = !key->point_attenuated;
+   sf.sf7.use_point_size_state = !key->use_vs_point_size;
    sf.sf7.aa_line_distance_mode = 0;
 
    /* might be BRW_NEW_PRIMITIVE if we have to adjust pv for polygons:
index 2a7fa5b69978a234f7a59b96f405da6782bf11cf..2fde42a70607750c2b1302d6e7dfcf70088482df 100644 (file)
@@ -1657,8 +1657,36 @@ struct brw_instruction
         GLuint end_of_thread:1;
       } dp_write_gen5;
 
+      /* Sandybridge DP for sample cache, constant cache, render cache */
       struct {
-        GLuint pad:16;
+        GLuint binding_table_index:8;
+        GLuint msg_control:5;
+        GLuint msg_type:3;
+        GLuint pad0:3;
+        GLuint header_present:1;
+        GLuint response_length:5;
+        GLuint msg_length:4;
+        GLuint pad1:2;
+        GLuint end_of_thread:1;
+      } dp_sampler_const_cache;
+
+      struct {
+        GLuint binding_table_index:8;
+        GLuint msg_control:3;
+        GLuint slot_group_select:1;
+        GLuint pixel_scoreboard_clear:1;
+        GLuint msg_type:4;
+        GLuint send_commit_msg:1;
+        GLuint pad0:1;
+        GLuint header_present:1;
+        GLuint response_length:5;
+        GLuint msg_length:4;
+        GLuint pad1:2;
+        GLuint end_of_thread:1;
+      } dp_render_cache;
+
+      struct {
+        GLuint function_control:16;
         GLuint response_length:4;
         GLuint msg_length:4;
         GLuint msg_target:4;
@@ -1666,8 +1694,9 @@ struct brw_instruction
         GLuint end_of_thread:1;
       } generic;
 
+      /* Of this struct, only end_of_thread is not present for gen6. */
       struct {
-        GLuint pad:19;
+        GLuint function_control:19;
         GLuint header_present:1;
         GLuint response_length:5;
         GLuint msg_length:4;
index bba9249d1b43d43b0a1e50750693e2f45760c425..1db2a210d454b57c332c45e2dd09694e6ccf9964 100644 (file)
@@ -31,7 +31,7 @@
          
 
 #include "main/mtypes.h"
-#include "shader/prog_parameter.h"
+#include "program/prog_parameter.h"
 #include "brw_util.h"
 #include "brw_defines.h"
 
index 3c12f11ea78e9fb4cdabf573e3705b5547c73509..9a832af9a9702d739ab729c43d0f428fc118e032 100644 (file)
@@ -34,8 +34,8 @@
 #include "brw_vs.h"
 #include "brw_util.h"
 #include "brw_state.h"
-#include "shader/prog_print.h"
-#include "shader/prog_parameter.h"
+#include "program/prog_print.h"
+#include "program/prog_parameter.h"
 
 
 
index 6493744f3eb486a17f2473c659a1dc7bfc95427c..9338a6b7dbfe988fbe26e4baf61e2aae2c762bd7 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "brw_context.h"
 #include "brw_eu.h"
-#include "shader/program.h"
+#include "program/program.h"
 
 
 struct brw_vs_prog_key {
index 128987d78a6688204605967d6270ecf176e0b9e2..c1d6525e9b7f8944f43d7b6464d97041217d65d5 100644 (file)
@@ -31,9 +31,9 @@
             
 
 #include "main/macros.h"
-#include "shader/program.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_print.h"
+#include "program/program.h"
+#include "program/prog_parameter.h"
+#include "program/prog_print.h"
 #include "brw_context.h"
 #include "brw_vs.h"
 
@@ -44,6 +44,7 @@ static GLboolean
 brw_vs_arg_can_be_immediate(enum prog_opcode opcode, int arg)
 {
    int opcode_array[] = {
+      [OPCODE_MOV] = 1,
       [OPCODE_ADD] = 2,
       [OPCODE_CMP] = 3,
       [OPCODE_DP3] = 2,
@@ -218,7 +219,7 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
    c->first_overflow_output = 0;
 
    if (intel->gen >= 6)
-      mrf = 6;
+      mrf = 4;
    else if (intel->gen == 5)
       mrf = 8;
    else
@@ -238,12 +239,25 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
            mrf++;              /* just a placeholder?  XXX fix later stages & remove this */
         }
         else {
-            if (mrf < 16) {
+           /* Two restrictions on our compute-to-MRF here.  The
+            * message length for all SEND messages is restricted to
+            * [1,15], so we can't use mrf 15, as that means a length
+            * of 16.
+            *
+            * Additionally, URB writes are aligned to URB rows, so we
+            * need to put an even number of registers of URB data in
+            * each URB write so that the later write is aligned.  A
+            * message length of 15 means 1 message header reg plus 14
+            * regs of URB data.
+            *
+            * For attributes beyond the compute-to-MRF, we compute to
+            * GRFs and they will be written in the second URB_WRITE.
+            */
+            if (mrf < 15) {
                c->regs[PROGRAM_OUTPUT][i] = brw_message_reg(mrf);
                mrf++;
             }
             else {
-               /* too many vertex results to fit in MRF, use GRF for overflow */
                if (!c->first_overflow_output)
                   c->first_overflow_output = i;
                c->regs[PROGRAM_OUTPUT][i] = brw_vec8_grf(reg, 0);
@@ -318,8 +332,11 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
     */
    attributes_in_vue = MAX2(c->nr_outputs, c->nr_inputs);
 
+   /* See emit_vertex_write() for where the VUE's overhead on top of the
+    * attributes comes from.
+    */
    if (intel->gen >= 6)
-      c->prog_data.urb_entry_size = (attributes_in_vue + 4 + 7) / 8;
+      c->prog_data.urb_entry_size = (attributes_in_vue + 2 + 7) / 8;
    else if (intel->gen == 5)
       c->prog_data.urb_entry_size = (attributes_in_vue + 6 + 3) / 4;
    else
@@ -869,8 +886,6 @@ get_constant(struct brw_vs_compile *c,
    assert(argIndex < 3);
 
    if (c->current_const[argIndex].index != src->Index) {
-      struct brw_reg addrReg = c->regs[PROGRAM_ADDRESS][0];
-
       /* Keep track of the last constant loaded in this slot, for reuse. */
       c->current_const[argIndex].index = src->Index;
 
@@ -881,9 +896,6 @@ get_constant(struct brw_vs_compile *c,
       /* need to fetch the constant now */
       brw_dp_READ_4_vs(p,
                        const_reg,                     /* writeback dest */
-                       0,                             /* oword */
-                       0,                             /* relative indexing? */
-                       addrReg,                       /* address register */
                        16 * src->Index,               /* byte offset */
                        SURF_INDEX_VERT_CONST_BUFFER   /* binding table index */
                        );
@@ -904,8 +916,8 @@ get_reladdr_constant(struct brw_vs_compile *c,
    const struct prog_src_register *src = &inst->SrcReg[argIndex];
    struct brw_compile *p = &c->func;
    struct brw_reg const_reg = c->current_const[argIndex].reg;
-   struct brw_reg const2_reg;
    struct brw_reg addrReg = c->regs[PROGRAM_ADDRESS][0];
+   struct brw_reg byte_addr_reg = get_tmp(c);
 
    assert(argIndex < 3);
 
@@ -917,37 +929,15 @@ get_reladdr_constant(struct brw_vs_compile *c,
          src->Index, argIndex, c->current_const[argIndex].reg.nr);
 #endif
 
+   brw_MUL(p, byte_addr_reg, addrReg, brw_imm_ud(16));
+
    /* fetch the first vec4 */
-   brw_dp_READ_4_vs(p,
-                   const_reg,                     /* writeback dest */
-                   0,                             /* oword */
-                   1,                             /* relative indexing? */
-                   addrReg,                       /* address register */
-                   16 * src->Index,               /* byte offset */
-                   SURF_INDEX_VERT_CONST_BUFFER   /* binding table index */
-                   );
-   /* second vec4 */
-   const2_reg = get_tmp(c);
-
-   /* use upper half of address reg for second read */
-   addrReg = stride(addrReg, 0, 4, 0);
-   addrReg.subnr = 16;
-
-   brw_dp_READ_4_vs(p,
-                   const2_reg,              /* writeback dest */
-                   1,                       /* oword */
-                   1,                       /* relative indexing? */
-                   addrReg,                 /* address register */
-                   16 * src->Index,         /* byte offset */
-                   SURF_INDEX_VERT_CONST_BUFFER
-                   );
-
-   /* merge the two Owords into the constant register */
-   /* const_reg[7..4] = const2_reg[7..4] */
-   brw_MOV(p,
-          suboffset(stride(const_reg, 0, 4, 1), 4),
-          suboffset(stride(const2_reg, 0, 4, 1), 4));
-   release_tmp(c, const2_reg);
+   brw_dp_READ_4_vs_relative(p,
+                            const_reg,                     /* writeback dest */
+                            byte_addr_reg,                 /* address register */
+                            16 * src->Index,               /* byte offset */
+                            SURF_INDEX_VERT_CONST_BUFFER   /* binding table index */
+                            );
 
    return const_reg;
 }
@@ -993,36 +983,71 @@ static struct brw_reg get_reg( struct brw_vs_compile *c,
  */
 static struct brw_reg deref( struct brw_vs_compile *c,
                             struct brw_reg arg,
-                            GLint offset)
+                            GLint offset,
+                            GLuint reg_size )
 {
    struct brw_compile *p = &c->func;
-   struct brw_reg tmp = vec4(get_tmp(c));
+   struct brw_reg tmp = get_tmp(c);
    struct brw_reg addr_reg = c->regs[PROGRAM_ADDRESS][0];
-   struct brw_reg vp_address = retype(vec1(addr_reg), BRW_REGISTER_TYPE_UW);
-   GLuint byte_offset = arg.nr * 32 + arg.subnr + offset * 16;
+   struct brw_reg vp_address = retype(vec1(addr_reg), BRW_REGISTER_TYPE_D);
+   GLuint byte_offset = arg.nr * 32 + arg.subnr + offset * reg_size;
    struct brw_reg indirect = brw_vec4_indirect(0,0);
+   struct brw_reg acc = retype(vec1(get_tmp(c)), BRW_REGISTER_TYPE_UW);
+
+   /* Set the vertical stride on the register access so that the first
+    * 4 components come from a0.0 and the second 4 from a0.1.
+    */
+   indirect.vstride = BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL;
 
    {
       brw_push_insn_state(p);
       brw_set_access_mode(p, BRW_ALIGN_1);
 
-      /* This is pretty clunky - load the address register twice and
-       * fetch each 4-dword value in turn.  There must be a way to do
-       * this in a single pass, but I couldn't get it to work.
-       */
-      brw_ADD(p, brw_address_reg(0), vp_address, brw_imm_d(byte_offset));
-      brw_MOV(p, tmp, indirect);
+      brw_MUL(p, acc, vp_address, brw_imm_uw(reg_size));
+      brw_ADD(p, brw_address_reg(0), acc, brw_imm_uw(byte_offset));
+
+      brw_MUL(p, acc, suboffset(vp_address, 4), brw_imm_uw(reg_size));
+      brw_ADD(p, brw_address_reg(1), acc, brw_imm_uw(byte_offset));
 
-      brw_ADD(p, brw_address_reg(0), suboffset(vp_address, 8), brw_imm_d(byte_offset));
-      brw_MOV(p, suboffset(tmp, 4), indirect);
+      brw_MOV(p, tmp, indirect);
 
       brw_pop_insn_state(p);
    }
-   
+
    /* NOTE: tmp not released */
-   return vec8(tmp);
+   return tmp;
 }
 
+static void
+move_to_reladdr_dst(struct brw_vs_compile *c,
+                   const struct prog_instruction *inst,
+                   struct brw_reg val)
+{
+   struct brw_compile *p = &c->func;
+   int reg_size = 32;
+   struct brw_reg addr_reg = c->regs[PROGRAM_ADDRESS][0];
+   struct brw_reg vp_address = retype(vec1(addr_reg), BRW_REGISTER_TYPE_D);
+   struct brw_reg temp_base = c->regs[inst->DstReg.File][0];
+   GLuint byte_offset = temp_base.nr * 32 + temp_base.subnr;
+   struct brw_reg indirect = brw_vec4_indirect(0,0);
+   struct brw_reg acc = retype(vec1(get_tmp(c)), BRW_REGISTER_TYPE_UW);
+
+   byte_offset += inst->DstReg.Index * reg_size;
+
+   brw_push_insn_state(p);
+   brw_set_access_mode(p, BRW_ALIGN_1);
+
+   brw_MUL(p, acc, vp_address, brw_imm_uw(reg_size));
+   brw_ADD(p, brw_address_reg(0), acc, brw_imm_uw(byte_offset));
+   brw_MOV(p, indirect, val);
+
+   brw_MUL(p, acc, suboffset(vp_address, 4), brw_imm_uw(reg_size));
+   brw_ADD(p, brw_address_reg(0), acc,
+          brw_imm_uw(byte_offset + reg_size / 2));
+   brw_MOV(p, indirect, suboffset(val, 4));
+
+   brw_pop_insn_state(p);
+}
 
 /**
  * Get brw reg corresponding to the instruction's [argIndex] src reg.
@@ -1091,7 +1116,7 @@ get_src_reg( struct brw_vs_compile *c,
    case PROGRAM_INPUT:
    case PROGRAM_OUTPUT:
       if (relAddr) {
-         return deref(c, c->regs[file][0], index);
+         return deref(c, c->regs[file][0], index, 32);
       }
       else {
          assert(c->regs[file][index].nr != 0);
@@ -1113,7 +1138,7 @@ get_src_reg( struct brw_vs_compile *c,
            return get_constant(c, inst, argIndex);
       }
       else if (relAddr) {
-         return deref(c, c->regs[PROGRAM_STATE_VAR][0], index);
+         return deref(c, c->regs[PROGRAM_STATE_VAR][0], index, 16);
       }
       else {
          assert(c->regs[PROGRAM_STATE_VAR][index].nr != 0);
@@ -1134,26 +1159,6 @@ get_src_reg( struct brw_vs_compile *c,
    }
 }
 
-
-static void emit_arl( struct brw_vs_compile *c,
-                     struct brw_reg dst,
-                     struct brw_reg arg0 )
-{
-   struct brw_compile *p = &c->func;
-   struct brw_reg tmp = dst;
-   GLboolean need_tmp = (dst.file != BRW_GENERAL_REGISTER_FILE);
-   
-   if (need_tmp) 
-      tmp = get_tmp(c);
-
-   brw_RNDD(p, tmp, arg0);               /* tmp = round(arg0) */
-   brw_MUL(p, dst, tmp, brw_imm_d(16));  /* dst = tmp * 16 */
-
-   if (need_tmp)
-      release_tmp(c, tmp);
-}
-
-
 /**
  * Return the brw reg for the given instruction's src argument.
  * Will return mangled results for SWZ op.  The emit_swz() function
@@ -1198,8 +1203,17 @@ static struct brw_reg get_dst( struct brw_vs_compile *c,
    switch (dst.File) {
    case PROGRAM_TEMPORARY:
    case PROGRAM_OUTPUT:
-      assert(c->regs[dst.File][dst.Index].nr != 0);
-      reg = c->regs[dst.File][dst.Index];
+      /* register-indirect addressing is only 1x1, not VxH, for
+       * destination regs.  So, for RelAddr we'll return a temporary
+       * for the dest and do a move of the result to the RelAddr
+       * register after the instruction emit.
+       */
+      if (dst.RelAddr) {
+        reg = get_tmp(c);
+      } else {
+        assert(c->regs[dst.File][dst.Index].nr != 0);
+        reg = c->regs[dst.File][dst.Index];
+      }
       break;
    case PROGRAM_ADDRESS:
       assert(dst.Index == 0);
@@ -1298,7 +1312,6 @@ static void emit_vertex_write( struct brw_vs_compile *c)
    struct brw_compile *p = &c->func;
    struct brw_context *brw = p->brw;
    struct intel_context *intel = &brw->intel;
-   struct brw_reg m0 = brw_message_reg(0);
    struct brw_reg pos = c->regs[PROGRAM_OUTPUT][VERT_RESULT_HPOS];
    struct brw_reg ndc;
    int eot;
@@ -1381,16 +1394,19 @@ static void emit_vertex_write( struct brw_vs_compile *c)
     */
    brw_set_access_mode(p, BRW_ALIGN_1);
 
+   /* The VUE layout is documented in Volume 2a. */
    if (intel->gen >= 6) {
-      /* There are 16 DWs (D0-D15) in VUE header on Sandybridge:
+      /* There are 8 or 16 DWs (D0-D15) in VUE header on Sandybridge:
        * dword 0-3 (m1) of the header is indices, point width, clip flags.
        * dword 4-7 (m2) is the 4D space position
-       * dword 8-15 (m3,m4) of the vertex header is the user clip distance.
-       * m5 is the first vertex data we fill, which is the vertex position.
+       * dword 8-15 (m3,m4) of the vertex header is the user clip distance if
+       * enabled.  We don't use it, so skip it.
+       * m3 is the first vertex element data we fill, which is the vertex
+       * position.
        */
-      brw_MOV(p, offset(m0, 2), pos);
-      brw_MOV(p, offset(m0, 5), pos);
-      len_vertex_header = 4;
+      brw_MOV(p, brw_message_reg(2), pos);
+      brw_MOV(p, brw_message_reg(3), pos);
+      len_vertex_header = 2;
    } else if (intel->gen == 5) {
       /* There are 20 DWs (D0-D19) in VUE header on Ironlake:
        * dword 0-3 (m1) of the header is indices, point width, clip flags.
@@ -1400,9 +1416,9 @@ static void emit_vertex_write( struct brw_vs_compile *c)
        * m6 is a pad so that the vertex element data is aligned
        * m7 is the first vertex data we fill, which is the vertex position.
        */
-      brw_MOV(p, offset(m0, 2), ndc);
-      brw_MOV(p, offset(m0, 3), pos);
-      brw_MOV(p, offset(m0, 7), pos);
+      brw_MOV(p, brw_message_reg(2), ndc);
+      brw_MOV(p, brw_message_reg(3), pos);
+      brw_MOV(p, brw_message_reg(7), pos);
       len_vertex_header = 6;
    } else {
       /* There are 8 dwords in VUE header pre-Ironlake:
@@ -1412,8 +1428,8 @@ static void emit_vertex_write( struct brw_vs_compile *c)
        * dword 8-11 (m3) is the first vertex data, which we always have be the
        * vertex position.
        */
-      brw_MOV(p, offset(m0, 2), ndc);
-      brw_MOV(p, offset(m0, 3), pos);
+      brw_MOV(p, brw_message_reg(2), ndc);
+      brw_MOV(p, brw_message_reg(3), pos);
       len_vertex_header = 2;
    }
 
@@ -1437,29 +1453,26 @@ static void emit_vertex_write( struct brw_vs_compile *c)
        * Move the overflowed attributes from the GRF to the MRF and
        * issue another brw_urb_WRITE().
        */
-      /* XXX I'm not 100% sure about which MRF regs to use here.  Starting
-       * at mrf[4] atm...
-       */
-      GLuint i, mrf = 0;
+      GLuint i, mrf = 1;
       for (i = c->first_overflow_output; i < VERT_RESULT_MAX; i++) {
          if (c->prog_data.outputs_written & BITFIELD64_BIT(i)) {
             /* move from GRF to MRF */
-            brw_MOV(p, brw_message_reg(4+mrf), c->regs[PROGRAM_OUTPUT][i]);
+            brw_MOV(p, brw_message_reg(mrf), c->regs[PROGRAM_OUTPUT][i]);
             mrf++;
          }
       }
 
       brw_urb_WRITE(p,
                     brw_null_reg(), /* dest */
-                    4,              /* starting mrf reg nr */
+                    0,              /* starting mrf reg nr */
                     c->r0,          /* src */
                     0,              /* allocate */
                     1,              /* used */
-                    mrf+1,          /* msg len */
+                    mrf,            /* msg len */
                     0,              /* response len */
                     1,              /* eot */
                     1,              /* writes complete */
-                    BRW_MAX_MRF-1,  /* urb destination offset */
+                    14 / 2,  /* urb destination offset */
                     BRW_URB_SWIZZLE_INTERLEAVE);
    }
 }
@@ -1665,7 +1678,7 @@ void brw_vs_emit(struct brw_vs_compile *c )
         emit_math1(c, BRW_MATH_FUNCTION_EXP, dst, args[0], BRW_MATH_PRECISION_FULL);
         break;
       case OPCODE_ARL:
-        emit_arl(c, dst, args[0]);
+        brw_RNDD(p, dst, args[0]);
         break;
       case OPCODE_FLR:
         brw_RNDD(p, dst, args[0]);
@@ -1890,6 +1903,14 @@ void brw_vs_emit(struct brw_vs_compile *c )
          }
       }
 
+      if (inst->DstReg.RelAddr && inst->DstReg.File == PROGRAM_TEMPORARY) {
+        /* We don't do RelAddr of PROGRAM_OUTPUT yet, because of the
+         * compute-to-mrf and the fact that we are allocating
+         * registers for only the used PROGRAM_OUTPUTs.
+         */
+        move_to_reladdr_dst(c, inst, dst);
+      }
+
       release_tmps(c);
    }
 
index be9e415cb0744e711940dbcfbd34b441b0fe018e..0250a68d292d66aefd0cd800ba752d53c1c2ecc3 100644 (file)
@@ -31,7 +31,7 @@
 
 #include "main/mtypes.h"
 #include "main/texstore.h"
-#include "shader/prog_parameter.h"
+#include "program/prog_parameter.h"
 
 #include "brw_context.h"
 #include "brw_state.h"
index 197b87543453cd28c2442bfe5b8ddefd3c104879..40f51c21c951e76f9d17b9470a6227dfc4368af9 100644 (file)
@@ -34,7 +34,7 @@
 #define BRW_WM_H
 
 
-#include "shader/prog_instruction.h"
+#include "program/prog_instruction.h"
 #include "brw_context.h"
 #include "brw_eu.h"
 
index a90a2d3cf255870c6174bc3fb1b6bf68dcd74b42..0c625a4cd028fd7a85d5af7c6053f866688d89ed 100644 (file)
@@ -1326,7 +1326,7 @@ void emit_fb_write(struct brw_wm_compile *c,
          * + 1 for the second half we get destination + 4.
          */
         brw_MOV(p,
-                brw_message_reg(nr + channel + (1 << 7)),
+                brw_message_reg(nr + channel + BRW_MRF_COMPR4),
                 arg0[channel]);
       } else {
         /*  mov (8) m2.0<1>:ud   r28.0<8;8,1>:ud  { Align1 } */
@@ -1763,12 +1763,20 @@ void brw_wm_emit( struct brw_wm_compile *c )
                      inst->dst[i]->spill_slot);
    }
 
+   /* Only properly tested on ILK */
+   if (p->brw->intel.gen == 5) {
+     brw_remove_duplicate_mrf_moves(p);
+     if (c->dispatch_width == 16)
+       brw_remove_grf_to_mrf_moves(p);
+   }
+
    if (INTEL_DEBUG & DEBUG_WM) {
       int i;
 
-      printf("wm-native:\n");
-      for (i = 0; i < p->nr_insn; i++)
+     printf("wm-native:\n");
+     for (i = 0; i < p->nr_insn; i++)
         brw_disasm(stderr, &p->store[i], p->brw->intel.gen);
       printf("\n");
    }
 }
+
index d73c391582402abe45074bc6d46b4d8c168063bf..0bef874b88752f847e64dccc200de6b87529c9ef 100644 (file)
@@ -37,9 +37,9 @@
 #include "brw_wm.h"
 #include "brw_util.h"
 
-#include "shader/prog_parameter.h"
-#include "shader/prog_print.h"
-#include "shader/prog_statevars.h"
+#include "program/prog_parameter.h"
+#include "program/prog_print.h"
+#include "program/prog_statevars.h"
 
 
 /** An invalid texture target */
index 57be08a8d1d1f97e608de1a666e9341697415c7c..2dd346d6dd1f3675f9345dae352c594e1e717e67 100644 (file)
@@ -1,7 +1,7 @@
 #include "main/macros.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_print.h"
-#include "shader/prog_optimize.h"
+#include "program/prog_parameter.h"
+#include "program/prog_print.h"
+#include "program/prog_optimize.h"
 #include "brw_context.h"
 #include "brw_eu.h"
 #include "brw_wm.h"
index 60bd92ed223267737746c2be2904d2dbee8ef223..05de85a957e1dc79cde45247324f8848ade08453 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "brw_context.h"
 #include "brw_wm.h"
-#include "shader/prog_parameter.h"
+#include "program/prog_parameter.h"
 
 
 
index 1789b21451d3118b311b67f3eedcd4a70cfb1539..c1cf4db1caeba957d7a1f010861d60a0c727f376 100644 (file)
@@ -222,7 +222,7 @@ wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key,
       drm_intel_bo_emit_reloc(bo, offsetof(struct brw_wm_unit_state, thread2),
                              brw->wm.scratch_bo,
                              wm.thread2.per_thread_scratch_space,
-                             0, 0);
+                             I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER);
    }
 
    /* Emit sampler state relocation */
index 77898dbbe72cc68d2bb23064ef7e96af6957f168..17b016b569b9b266261fa08739d0a099f5c67f5a 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "main/mtypes.h"
 #include "main/texstore.h"
-#include "shader/prog_parameter.h"
+#include "program/prog_parameter.h"
 
 #include "intel_mipmap_tree.h"
 #include "intel_batchbuffer.h"
index 51940efb44355616a38ec9442030a55f846ddc7a..6820ca3abf40cc2396b0fb85ed9828f6f85a085d 100644 (file)
@@ -69,7 +69,7 @@ upload_sf_state(struct brw_context *brw)
    dw1 =
       num_outputs << GEN6_SF_NUM_OUTPUTS_SHIFT |
       (num_inputs + 1) / 2 << GEN6_SF_URB_ENTRY_READ_LENGTH_SHIFT |
-      3 << GEN6_SF_URB_ENTRY_READ_OFFSET_SHIFT;
+      1 << GEN6_SF_URB_ENTRY_READ_OFFSET_SHIFT;
    dw2 = GEN6_SF_VIEWPORT_TRANSFORM_ENABLE |
       GEN6_SF_STATISTICS_ENABLE;
    dw3 = 0;
index 5916a139946f9ab8350b683ce0ba6c6898968fa2..4080a9dedfd50e0a2659d0ab4d89ba68800bbfc0 100644 (file)
@@ -29,8 +29,8 @@
 #include "brw_state.h"
 #include "brw_defines.h"
 #include "brw_util.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_statevars.h"
+#include "program/prog_parameter.h"
+#include "program/prog_statevars.h"
 #include "intel_batchbuffer.h"
 
 static void
index ed1a72f03bae4f1544a3c60c4ab80671400a50ad..863c85449d9adc04061ef17fbb64ee01316f0e21 100644 (file)
@@ -29,8 +29,8 @@
 #include "brw_state.h"
 #include "brw_defines.h"
 #include "brw_util.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_statevars.h"
+#include "program/prog_parameter.h"
+#include "program/prog_statevars.h"
 #include "intel_batchbuffer.h"
 
 static void
index 698445c52680c5b36184c71f2822ac893e75ba62..ff741fc39ab28bbba863cea01f65ed980e74015f 100644 (file)
@@ -102,7 +102,7 @@ do_flush_locked(struct intel_batchbuffer *batch, GLuint used)
    if (INTEL_DEBUG & DEBUG_BATCH) {
       drm_intel_bo_map(batch->buf, GL_FALSE);
       intel_decode(batch->buf->virtual, used / 4, batch->buf->offset,
-                  intel->intelScreen->deviceID);
+                  intel->intelScreen->deviceID, GL_TRUE);
       drm_intel_bo_unmap(batch->buf);
 
       if (intel->vtbl.debug_batch != NULL)
index cd614c59e557fcaabee0194083837dd43ca08afb..72a74322ee553b03ae92dcf320cfcefc2489f476 100644 (file)
                                 devid == PCI_CHIP_I946_GZ || \
                                 IS_G4X(devid))
 
+/* Compat macro for intel_decode.c */
+#define IS_IRONLAKE(devid)     IS_GEN5(devid)
+
 #define IS_GEN6(devid)         (devid == PCI_CHIP_SANDYBRIDGE || \
                                 devid == PCI_CHIP_SANDYBRIDGE_M)
 
index 650010ac9ca70b2198bbae5f7e809ea3aac5a615..25b4131594f77980db4149706b3553e9b1bd005d 100644 (file)
@@ -1,48 +1,21 @@
-/* -*- c-basic-offset: 4 -*- */
-/*
- * Copyright Â© 2007 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION 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:
- *    Eric Anholt <eric@anholt.net>
- *
- */
-
-/** @file intel_decode.c
- * This file contains code to print out batchbuffer contents in a
- * human-readable format.
- *
- * The current version only supports i915 packets, and only pretty-prints a
- * subset of them.  The intention is for it to make just a best attempt to
- * decode, but never crash in the process.
- */
-
+#include <stdint.h>
 #include <stdio.h>
 #include <stdarg.h>
 #include <string.h>
-#include <inttypes.h>
 
 #include "intel_decode.h"
 #include "intel_chipset.h"
 
+static FILE *out;
+static uint32_t saved_s2 = 0, saved_s4 = 0;
+static char saved_s2_set = 0, saved_s4_set = 0;
+static uint32_t head_offset = 0xffffffff; /* undefined */
+static uint32_t tail_offset = 0xffffffff; /* undefined */
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(A) (sizeof(A)/sizeof(A[0]))
+#endif
+
 #define BUFFER_FAIL(_count, _len, _name) do {                  \
     fprintf(out, "Buffer size too small in %s (%d < %d)\n",    \
            (_name), (_count), (_len));                         \
@@ -50,9 +23,6 @@
     return count;                                              \
 } while (0)
 
-static FILE *out;
-static uint32_t saved_s2 = 0, saved_s4 = 0;
-static char saved_s2_set = 0, saved_s4_set = 0;
 
 static float
 int_as_float(uint32_t intval)
@@ -71,15 +41,24 @@ instr_out(uint32_t *data, uint32_t hw_offset, unsigned int index,
          char *fmt, ...)
 {
     va_list va;
-
-    fprintf(out, "0x%08x: 0x%08x:%s ", hw_offset + index * 4, data[index],
-           index == 0 ? "" : "  ");
+    char *parseinfo;
+    uint32_t offset = hw_offset + index * 4;
+
+    if (offset == head_offset)
+       parseinfo = "HEAD";
+    else if (offset == tail_offset)
+       parseinfo = "TAIL";
+    else
+       parseinfo = "    ";
+
+    fprintf(out, "0x%08x: %s 0x%08x: %s", offset, parseinfo,
+           data[index],
+           index == 0 ? "" : "   ");
     va_start(va, fmt);
     vfprintf(out, fmt, va);
     va_end(va);
 }
 
-
 static int
 decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures)
 {
@@ -94,10 +73,11 @@ decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures)
     } opcodes_mi[] = {
        { 0x08, 0, 1, 1, "MI_ARB_ON_OFF" },
        { 0x0a, 0, 1, 1, "MI_BATCH_BUFFER_END" },
+       { 0x30, 0x3f, 3, 3, "MI_BATCH_BUFFER" },
        { 0x31, 0x3f, 2, 2, "MI_BATCH_BUFFER_START" },
        { 0x14, 0x3f, 3, 3, "MI_DISPLAY_BUFFER_INFO" },
        { 0x04, 0, 1, 1, "MI_FLUSH" },
-       { 0x22, 0, 3, 3, "MI_LOAD_REGISTER_IMM" },
+       { 0x22, 0x1f, 3, 3, "MI_LOAD_REGISTER_IMM" },
        { 0x13, 0x3f, 2, 2, "MI_LOAD_SCAN_LINES_EXCL" },
        { 0x12, 0x3f, 2, 2, "MI_LOAD_SCAN_LINES_INCL" },
        { 0x00, 0, 1, 1, "MI_NOOP" },
@@ -111,6 +91,11 @@ decode_mi(uint32_t *data, int count, uint32_t hw_offset, int *failures)
        { 0x03, 0, 1, 1, "MI_WAIT_FOR_EVENT" },
     };
 
+    switch ((data[0] & 0x1f800000) >> 23) {
+    case 0x0a:
+       instr_out(data, hw_offset, 0, "MI_BATCH_BUFFER_END\n");
+       return -1;
+    }
 
     for (opcode = 0; opcode < sizeof(opcodes_mi) / sizeof(opcodes_mi[0]);
         opcode++) {
@@ -305,9 +290,13 @@ decode_2d(uint32_t *data, int count, uint32_t hw_offset, int *failures)
 static int
 decode_3d_1c(uint32_t *data, int count, uint32_t hw_offset, int *failures)
 {
-    switch ((data[0] & 0x00f80000) >> 19) {
+    uint32_t opcode;
+
+    opcode = (data[0] & 0x00f80000) >> 19;
+
+    switch (opcode) {
     case 0x11:
-       instr_out(data, hw_offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISALBE\n");
+       instr_out(data, hw_offset, 0, "3DSTATE_DEPTH_SUBRECTANGLE_DISABLE\n");
        return 1;
     case 0x10:
        instr_out(data, hw_offset, 0, "3DSTATE_SCISSOR_ENABLE\n");
@@ -323,7 +312,8 @@ decode_3d_1c(uint32_t *data, int count, uint32_t hw_offset, int *failures)
        return 1;
     }
 
-    instr_out(data, hw_offset, 0, "3D UNKNOWN\n");
+    instr_out(data, hw_offset, 0, "3D UNKNOWN: 3d_1c opcode = 0x%x\n",
+             opcode);
     (*failures)++;
     return 1;
 }
@@ -381,7 +371,7 @@ i915_get_instruction_dst(uint32_t *data, int i, char *dstname, int do_mask)
        sprintf(dstname, "oD%s%s",  dstmask, sat);
        break;
     case 6:
-       if (dst_nr > 2)
+       if (dst_nr > 3)
            fprintf(out, "bad destination reg U%d\n", dst_nr);
        sprintf(dstname, "U%d%s%s", dst_nr, dstmask, sat);
        break;
@@ -452,7 +442,7 @@ i915_get_instruction_src_name(uint32_t src_type, uint32_t src_nr, char *name)
        break;
     case 6:
        sprintf(name, "U%d", src_nr);
-       if (src_nr > 2)
+       if (src_nr > 3)
            fprintf(out, "bad src reg %s\n", name);
        break;
     default:
@@ -797,10 +787,14 @@ i915_decode_instruction(uint32_t *data, uint32_t hw_offset,
 }
 
 static int
-decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i830)
+decode_3d_1d(uint32_t *data, int count,
+            uint32_t hw_offset,
+            uint32_t devid,
+            int *failures)
 {
-    unsigned int len, i, c, opcode, word, map, sampler, instr;
+    unsigned int len, i, c, idx, word, map, sampler, instr;
     char *format;
+    uint32_t opcode;
 
     struct {
        uint32_t opcode;
@@ -811,7 +805,7 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i
     } opcodes_3d_1d[] = {
        { 0x8e, 0, 3, 3, "3DSTATE_BUFFER_INFO" },
        { 0x86, 0, 4, 4, "3DSTATE_CHROMA_KEY" },
-       { 0x9c, 0, 1, 1, "3DSTATE_CLEAR_PARAMETERS" },
+       { 0x9c, 0, 7, 7, "3DSTATE_CLEAR_PARAMETERS" },
        { 0x88, 0, 2, 2, "3DSTATE_CONSTANT_BLEND_COLOR" },
        { 0x99, 0, 2, 2, "3DSTATE_DEFAULT_DIFFUSE" },
        { 0x9a, 0, 2, 2, "3DSTATE_DEFAULT_SPECULAR" },
@@ -819,7 +813,6 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i
        { 0x97, 0, 2, 2, "3DSTATE_DEPTH_OFFSET_SCALE" },
        { 0x85, 0, 2, 2, "3DSTATE_DEST_BUFFER_VARIABLES" },
        { 0x80, 0, 5, 5, "3DSTATE_DRAWING_RECTANGLE" },
-       { 0x8e, 0, 3, 3, "3DSTATE_BUFFER_INFO" },
        { 0x9d, 0, 65, 65, "3DSTATE_FILTER_COEFFICIENTS_4X4" },
        { 0x9e, 0, 4, 4, "3DSTATE_MONO_FILTER" },
        { 0x89, 0, 4, 4, "3DSTATE_FOG_MODE" },
@@ -831,9 +824,11 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i
        { 0x8d, 1, 3, 3, "3DSTATE_W_STATE_I830" },
        { 0x01, 1, 2, 2, "3DSTATE_COLOR_FACTOR_I830" },
        { 0x02, 1, 2, 2, "3DSTATE_MAP_COORD_SETBIND_I830" },
-    };
+    }, *opcode_3d_1d;
+
+    opcode = (data[0] & 0x00ff0000) >> 16;
 
-    switch ((data[0] & 0x00ff0000) >> 16) {
+    switch (opcode) {
     case 0x07:
        /* This instruction is unusual.  A 0 length means just 1 DWORD instead of
         * 2.  The 0 length is specified in one place to be unsupported, but
@@ -888,26 +883,56 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i
        instr_out(data, hw_offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_1\n");
        len = (data[0] & 0x0000000f) + 2;
        i = 1;
-       for (word = 0; word <= 7; word++) {
+       for (word = 0; word <= 8; word++) {
            if (data[0] & (1 << (4 + word))) {
                if (i >= count)
                    BUFFER_FAIL(count, len, "3DSTATE_LOAD_STATE_IMMEDIATE_1");
 
                /* save vertex state for decode */
-               if (word == 2) {
-                   saved_s2_set = 1;
-                   saved_s2 = data[i];
-               }
-               if (word == 4) {
-                   saved_s4_set = 1;
-                   saved_s4 = data[i];
+               if (IS_9XX(devid)) {
+                   if (word == 2) {
+                       saved_s2_set = 1;
+                       saved_s2 = data[i];
+                   }
+                   if (word == 4) {
+                       saved_s4_set = 1;
+                       saved_s4 = data[i];
+                   }
                }
 
                instr_out(data, hw_offset, i++, "S%d\n", word);
            }
        }
        if (len != i) {
-           fprintf(out, "Bad count in 3DSTATE_LOAD_INDIRECT\n");
+           fprintf(out, "Bad count in 3DSTATE_LOAD_STATE_IMMEDIATE_1\n");
+           (*failures)++;
+       }
+       return len;
+    case 0x03:
+       instr_out(data, hw_offset, 0, "3DSTATE_LOAD_STATE_IMMEDIATE_2\n");
+       len = (data[0] & 0x0000000f) + 2;
+       i = 1;
+       for (word = 6; word <= 14; word++) {
+           if (data[0] & (1 << word)) {
+               if (i >= count)
+                   BUFFER_FAIL(count, len, "3DSTATE_LOAD_STATE_IMMEDIATE_2");
+
+               if (word == 6)
+                   instr_out(data, hw_offset, i++, "TBCF\n");
+               else if (word >= 7 && word <= 10) {
+                   instr_out(data, hw_offset, i++, "TB%dC\n", word - 7);
+                   instr_out(data, hw_offset, i++, "TB%dA\n", word - 7);
+               } else if (word >= 11 && word <= 14) {
+                   instr_out(data, hw_offset, i++, "TM%dS0\n", word - 11);
+                   instr_out(data, hw_offset, i++, "TM%dS1\n", word - 11);
+                   instr_out(data, hw_offset, i++, "TM%dS2\n", word - 11);
+                   instr_out(data, hw_offset, i++, "TM%dS3\n", word - 11);
+                   instr_out(data, hw_offset, i++, "TM%dS4\n", word - 11);
+               }
+           }
+       }
+       if (len != i) {
+           fprintf(out, "Bad count in 3DSTATE_LOAD_STATE_IMMEDIATE_2\n");
            (*failures)++;
        }
        return len;
@@ -919,11 +944,28 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i
        i = 2;
        for (map = 0; map <= 15; map++) {
            if (data[1] & (1 << map)) {
+               int width, height, pitch, dword;
+               const char *tiling;
+
                if (i + 3 >= count)
                    BUFFER_FAIL(count, len, "3DSTATE_MAP_STATE");
+
                instr_out(data, hw_offset, i++, "map %d MS2\n", map);
-               instr_out(data, hw_offset, i++, "map %d MS3\n", map);
-               instr_out(data, hw_offset, i++, "map %d MS4\n", map);
+
+               dword = data[i];
+               width = ((dword >> 10) & ((1 << 11) - 1))+1;
+               height = ((dword >> 21) & ((1 << 11) - 1))+1;
+
+               tiling = "none";
+               if (dword & (1 << 2))
+                       tiling = "fenced";
+               else if (dword & (1 << 1))
+                       tiling = dword & (1 << 0) ? "Y" : "X";
+               instr_out(data, hw_offset, i++, "map %d MS3 [width=%d, height=%d, tiling=%s]\n", map, width, height, tiling);
+
+               dword = data[i];
+               pitch = 4*(((dword >> 21) & ((1 << 11) - 1))+1);
+               instr_out(data, hw_offset, i++, "map %d MS4 [pitch=%d]\n", map, pitch);
            }
        }
        if (len != i) {
@@ -979,8 +1021,8 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i
        }
        return len;
     case 0x01:
-       if (i830)
-           break;
+       if (!IS_9XX(devid))
+               break;
        instr_out(data, hw_offset, 0, "3DSTATE_SAMPLER_STATE\n");
        instr_out(data, hw_offset, 1, "mask\n");
        len = (data[0] & 0x0000003f) + 2;
@@ -1031,32 +1073,61 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i
                  format,
                  (data[1] & (1 << 31)) ? "en" : "dis");
        return len;
+
+    case 0x8e:
+       {
+           const char *name, *tiling;
+
+           len = (data[0] & 0x0000000f) + 2;
+           if (len != 3)
+               fprintf(out, "Bad count in 3DSTATE_BUFFER_INFO\n");
+           if (count < 3)
+               BUFFER_FAIL(count, len, "3DSTATE_BUFFER_INFO");
+
+           switch((data[1] >> 24) & 0x7) {
+           case 0x3: name = "color"; break;
+           case 0x7: name = "depth"; break;
+           default: name = "unknown"; break;
+           }
+
+           tiling = "none";
+           if (data[1] & (1 << 23))
+               tiling = "fenced";
+           else if (data[1] & (1 << 22))
+               tiling = data[1] & (1 << 21) ? "Y" : "X";
+
+           instr_out(data, hw_offset, 0, "3DSTATE_BUFFER_INFO\n");
+           instr_out(data, hw_offset, 1, "%s, tiling = %s, pitch=%d\n", name, tiling, data[1]&0xffff);
+
+           instr_out(data, hw_offset, 2, "address\n");
+           return len;
+       }
     }
 
-    for (opcode = 0; opcode < sizeof(opcodes_3d_1d) / sizeof(opcodes_3d_1d[0]);
-        opcode++)
+    for (idx = 0; idx < ARRAY_SIZE(opcodes_3d_1d); idx++)
     {
-       if (opcodes_3d_1d[opcode].i830_only && !i830)
+       opcode_3d_1d = &opcodes_3d_1d[idx];
+       if (opcode_3d_1d->i830_only && IS_9XX(devid))
            continue;
 
-       if (((data[0] & 0x00ff0000) >> 16) == opcodes_3d_1d[opcode].opcode) {
+       if (((data[0] & 0x00ff0000) >> 16) == opcode_3d_1d->opcode) {
            len = 1;
 
-           instr_out(data, hw_offset, 0, "%s\n", opcodes_3d_1d[opcode].name);
-           if (opcodes_3d_1d[opcode].max_len > 1) {
+           instr_out(data, hw_offset, 0, "%s\n", opcode_3d_1d->name);
+           if (opcode_3d_1d->max_len > 1) {
                len = (data[0] & 0x0000ffff) + 2;
-               if (len < opcodes_3d_1d[opcode].min_len ||
-                   len > opcodes_3d_1d[opcode].max_len)
+               if (len < opcode_3d_1d->min_len ||
+                   len > opcode_3d_1d->max_len)
                {
                    fprintf(out, "Bad count in %s\n",
-                           opcodes_3d_1d[opcode].name);
+                           opcode_3d_1d->name);
                    (*failures)++;
                }
            }
 
            for (i = 1; i < len; i++) {
                if (i >= count)
-                   BUFFER_FAIL(count, len,  opcodes_3d_1d[opcode].name);
+                   BUFFER_FAIL(count, len,  opcode_3d_1d->name);
                instr_out(data, hw_offset, i, "dword %d\n", i);
            }
 
@@ -1064,7 +1135,7 @@ decode_3d_1d(uint32_t *data, int count, uint32_t hw_offset, int *failures, int i
        }
     }
 
-    instr_out(data, hw_offset, 0, "3D UNKNOWN\n");
+    instr_out(data, hw_offset, 0, "3D UNKNOWN: 3d_1d opcode = 0x%x\n", opcode);
     (*failures)++;
     return 1;
 }
@@ -1074,8 +1145,10 @@ decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset,
                    int *failures)
 {
     char immediate = (data[0] & (1 << 23)) == 0;
-    unsigned int len, i;
+    unsigned int len, i, ret;
     char *primtype;
+    int original_s2 = saved_s2;
+    int original_s4 = saved_s4;
 
     switch ((data[0] >> 18) & 0xf) {
     case 0x0: primtype = "TRILIST"; break;
@@ -1088,7 +1161,7 @@ decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset,
     case 0x7: primtype = "RECTLIST"; break;
     case 0x8: primtype = "POINTLIST"; break;
     case 0x9: primtype = "DIB"; break;
-    case 0xa: primtype = "CLEAR_RECT"; break;
+    case 0xa: primtype = "CLEAR_RECT"; saved_s4 = 3 << 6; saved_s2 = ~0; break;
     default: primtype = "unknown"; break;
     }
 
@@ -1192,6 +1265,8 @@ decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset,
                vertex++;
            }
        }
+
+       ret = len;
     } else {
        /* indirect vertices */
        len = data[0] & 0x0000ffff; /* index count */
@@ -1209,13 +1284,15 @@ decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset,
                    if ((data[i] & 0xffff) == 0xffff) {
                        instr_out(data, hw_offset, i,
                                  "            indices: (terminator)\n");
-                       return i;
+                       ret = i;
+                       goto out;
                    } else if ((data[i] >> 16) == 0xffff) {
                        instr_out(data, hw_offset, i,
                                  "            indices: 0x%04x, "
                                  "(terminator)\n",
                                  data[i] & 0xffff);
-                       return i;
+                       ret = i;
+                       goto out;
                    } else {
                        instr_out(data, hw_offset, i,
                                  "            indices: 0x%04x, 0x%04x\n",
@@ -1225,7 +1302,8 @@ decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset,
                fprintf(out,
                        "3DPRIMITIVE: no terminator found in index buffer\n");
                (*failures)++;
-               return count;
+               ret = count;
+               goto out;
            } else {
                /* fixed size vertex index buffer */
                for (i = 0; i < len; i += 2) {
@@ -1240,7 +1318,8 @@ decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset,
                    }
                }
            }
-           return (len + 1) / 2 + 1;
+           ret = (len + 1) / 2 + 1;
+           goto out;
        } else {
            /* sequential vertex access */
            if (count < 2)
@@ -1249,17 +1328,22 @@ decode_3d_primitive(uint32_t *data, int count, uint32_t hw_offset,
                      "3DPRIMITIVE sequential indirect %s, %d starting from "
                      "%d\n", primtype, len, data[1] & 0xffff);
            instr_out(data, hw_offset, 1, "           start\n");
-           return 2;
+           ret = 2;
+           goto out;
        }
     }
 
-    return len;
+out:
+    saved_s2 = original_s2;
+    saved_s4 = original_s4;
+    return ret;
 }
 
 static int
-decode_3d(uint32_t *data, int count, uint32_t hw_offset, int *failures)
+decode_3d(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid, int *failures)
 {
-    unsigned int opcode;
+    uint32_t opcode;
+    unsigned int idx;
 
     struct {
        uint32_t opcode;
@@ -1276,42 +1360,44 @@ decode_3d(uint32_t *data, int count, uint32_t hw_offset, int *failures)
        { 0x0d, 1, 1, "3DSTATE_MODES_4" },
        { 0x0c, 1, 1, "3DSTATE_MODES_5" },
        { 0x07, 1, 1, "3DSTATE_RASTERIZATION_RULES" },
-    };
+    }, *opcode_3d;
+
+    opcode = (data[0] & 0x1f000000) >> 24;
 
-    switch ((data[0] & 0x1f000000) >> 24) {
+    switch (opcode) {
     case 0x1f:
        return decode_3d_primitive(data, count, hw_offset, failures);
     case 0x1d:
-       return decode_3d_1d(data, count, hw_offset, failures, 0);
+       return decode_3d_1d(data, count, hw_offset, devid, failures);
     case 0x1c:
        return decode_3d_1c(data, count, hw_offset, failures);
     }
 
-    for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]);
-        opcode++) {
-       if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) {
+    for (idx = 0; idx < ARRAY_SIZE(opcodes_3d); idx++) {
+       opcode_3d = &opcodes_3d[idx];
+       if (opcode == opcode_3d->opcode) {
            unsigned int len = 1, i;
 
-           instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name);
-           if (opcodes_3d[opcode].max_len > 1) {
+           instr_out(data, hw_offset, 0, "%s\n", opcode_3d->name);
+           if (opcode_3d->max_len > 1) {
                len = (data[0] & 0xff) + 2;
-               if (len < opcodes_3d[opcode].min_len ||
-                   len > opcodes_3d[opcode].max_len)
+               if (len < opcode_3d->min_len ||
+                   len > opcode_3d->max_len)
                {
-                   fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name);
+                   fprintf(out, "Bad count in %s\n", opcode_3d->name);
                }
            }
 
            for (i = 1; i < len; i++) {
                if (i >= count)
-                   BUFFER_FAIL(count, len, opcodes_3d[opcode].name);
+                   BUFFER_FAIL(count, len, opcode_3d->name);
                instr_out(data, hw_offset, i, "dword %d\n", i);
            }
            return len;
        }
     }
 
-    instr_out(data, hw_offset, 0, "3D UNKNOWN\n");
+    instr_out(data, hw_offset, 0, "3D UNKNOWN: 3d opcode = 0x%x\n", opcode);
     (*failures)++;
     return 1;
 }
@@ -1403,11 +1489,86 @@ get_965_prim_type(uint32_t data)
 }
 
 static int
-decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures)
+i965_decode_urb_fence(uint32_t *data, uint32_t hw_offset, int len, int count,
+                     int *failures)
 {
-    unsigned int opcode, len;
-    int i;
-    char *desc1;
+       uint32_t vs_fence, clip_fence, gs_fence, sf_fence, vfe_fence, cs_fence;
+
+       if (len != 3)
+           fprintf(out, "Bad count in URB_FENCE\n");
+       if (count < 3)
+           BUFFER_FAIL(count, len, "URB_FENCE");
+
+       vs_fence = data[1] & 0x3ff;
+       gs_fence = (data[1] >> 10) & 0x3ff;
+       clip_fence = (data[1] >> 20) & 0x3ff;
+       sf_fence = data[2] & 0x3ff;
+       vfe_fence = (data[2] >> 10) & 0x3ff;
+       cs_fence = (data[2] >> 20) & 0x7ff;
+
+       instr_out(data, hw_offset, 0, "URB_FENCE: %s%s%s%s%s%s\n",
+                       (data[0] >> 13) & 1 ? "cs " : "",
+                       (data[0] >> 12) & 1 ? "vfe " : "",
+                       (data[0] >> 11) & 1 ? "sf " : "",
+                       (data[0] >> 10) & 1 ? "clip " : "",
+                       (data[0] >> 9)  & 1 ? "gs " : "",
+                       (data[0] >> 8)  & 1 ? "vs " : "");
+       instr_out(data, hw_offset, 1,
+                 "vs fence: %d, clip_fence: %d, gs_fence: %d\n",
+                 vs_fence, clip_fence, gs_fence);
+       instr_out(data, hw_offset, 2,
+                 "sf fence: %d, vfe_fence: %d, cs_fence: %d\n",
+                 sf_fence, vfe_fence, cs_fence);
+       if (gs_fence < vs_fence)
+           fprintf(out, "gs fence < vs fence!\n");
+       if (clip_fence < gs_fence)
+           fprintf(out, "clip fence < gs fence!\n");
+       if (sf_fence < clip_fence)
+           fprintf(out, "sf fence < clip fence!\n");
+       if (cs_fence < sf_fence)
+           fprintf(out, "cs fence < sf fence!\n");
+
+       return len;
+}
+
+static void
+state_base_out(uint32_t *data, uint32_t hw_offset, unsigned int index,
+              char *name)
+{
+    if (data[index] & 1) {
+       instr_out(data, hw_offset, index, "%s state base address 0x%08x\n",
+                 name, data[index] & ~1);
+    } else {
+       instr_out(data, hw_offset, index, "%s state base not updated\n",
+                 name);
+    }
+}
+
+static void
+state_max_out(uint32_t *data, uint32_t hw_offset, unsigned int index,
+             char *name)
+{
+    if (data[index] & 1) {
+       if (data[index] == 1) {
+           instr_out(data, hw_offset, index,
+                     "%s state upper bound disabled\n", name);
+       } else {
+           instr_out(data, hw_offset, index, "%s state upper bound 0x%08x\n",
+                     name, data[index] & ~1);
+       }
+    } else {
+       instr_out(data, hw_offset, index, "%s state upper bound not updated\n",
+                 name);
+    }
+}
+
+static int
+decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid, int *failures)
+{
+    uint32_t opcode;
+    unsigned int idx, len;
+    int i, sba_len;
+    char *desc1 = NULL;
 
     struct {
        uint32_t opcode;
@@ -1436,57 +1597,78 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures)
        { 0x7907, 33, 33, "3DSTATE_POLY_STIPPLE_PATTERN" },
        { 0x7908, 3, 3, "3DSTATE_LINE_STIPPLE" },
        { 0x7909, 2, 2, "3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP" },
+       { 0x7909, 2, 2, "3DSTATE_CLEAR_PARAMS" },
        { 0x790a, 3, 3, "3DSTATE_AA_LINE_PARAMETERS" },
+       { 0x790b, 4, 4, "3DSTATE_GS_SVB_INDEX" },
+       { 0x790d, 3, 3, "3DSTATE_MULTISAMPLE" },
        { 0x7b00, 6, 6, "3DPRIMITIVE" },
+       { 0x7802, 4, 4, "3DSTATE_SAMPLER_STATE_POINTERS" },
+       { 0x7805, 3, 3, "3DSTATE_URB" },
        { 0x780e, 4, 4, "3DSTATE_CC_STATE_POINTERS" },
        { 0x7810, 6, 6, "3DSTATE_VS_STATE" },
-       { 0x7811, 6, 6, "3DSTATE_GS_STATE" },
+       { 0x7811, 7, 7, "3DSTATE_GS_STATE" },
+       { 0x7812, 4, 4, "3DSTATE_CLIP_STATE" },
+       { 0x7813, 20, 20, "3DSTATE_SF_STATE" },
+       { 0x7814, 9, 9, "3DSTATE_WM_STATE" },
        { 0x7812, 4, 4, "3DSTATE_CLIP_STATE" },
        { 0x7815, 5, 5, "3DSTATE_CONSTANT_VS_STATE" },
        { 0x7816, 5, 5, "3DSTATE_CONSTANT_GS_STATE" },
-    };
+       { 0x7817, 5, 5, "3DSTATE_CONSTANT_PS_STATE" },
+       { 0x7818, 2, 2, "3DSTATE_SAMPLE_MASK" },
+   }, *opcode_3d;
 
     len = (data[0] & 0x0000ffff) + 2;
 
-    switch ((data[0] & 0xffff0000) >> 16) {
+    opcode = (data[0] & 0xffff0000) >> 16;
+    switch (opcode) {
+    case 0x6000:
+       len = (data[0] & 0x000000ff) + 2;
+       return i965_decode_urb_fence(data, hw_offset, len, count, failures);
+    case 0x6001:
+       instr_out(data, hw_offset, 0, "CS_URB_STATE\n");
+       instr_out(data, hw_offset, 1, "entry_size: %d [%d bytes], n_entries: %d\n",
+                       (data[1] >> 4) & 0x1f,
+                       (((data[1] >> 4) & 0x1f) + 1) * 64,
+                       data[1] & 0x7);
+       return len;
+    case 0x6002:
+       len = (data[0] & 0x000000ff) + 2;
+       instr_out(data, hw_offset, 0, "CONSTANT_BUFFER: %s\n",
+                       (data[0] >> 8) & 1 ? "valid" : "invalid");
+       instr_out(data, hw_offset, 1, "offset: 0x%08x, length: %d bytes\n",
+                       data[1] & ~0x3f, ((data[1] & 0x3f) + 1) * 64);
+       return len;
     case 0x6101:
-       if (len != 6)
+       if (IS_GEN6(devid))
+           sba_len = 10;
+       else if (IS_IRONLAKE(devid))
+           sba_len = 8;
+       else
+           sba_len = 6;
+       if (len != sba_len)
            fprintf(out, "Bad count in STATE_BASE_ADDRESS\n");
-       if (count < 6)
+       if (len != sba_len)
            BUFFER_FAIL(count, len, "STATE_BASE_ADDRESS");
 
+       i = 0;
        instr_out(data, hw_offset, 0,
                  "STATE_BASE_ADDRESS\n");
-
-       if (data[1] & 1) {
-           instr_out(data, hw_offset, 1, "General state at 0x%08x\n",
-                     data[1] & ~1);
-       } else
-           instr_out(data, hw_offset, 1, "General state not updated\n");
-
-       if (data[2] & 1) {
-           instr_out(data, hw_offset, 2, "Surface state at 0x%08x\n",
-                     data[2] & ~1);
-       } else
-           instr_out(data, hw_offset, 2, "Surface state not updated\n");
-
-       if (data[3] & 1) {
-           instr_out(data, hw_offset, 3, "Indirect state at 0x%08x\n",
-                     data[3] & ~1);
-       } else
-           instr_out(data, hw_offset, 3, "Indirect state not updated\n");
-
-       if (data[4] & 1) {
-           instr_out(data, hw_offset, 4, "General state upper bound 0x%08x\n",
-                     data[4] & ~1);
-       } else
-           instr_out(data, hw_offset, 4, "General state not updated\n");
-
-       if (data[5] & 1) {
-           instr_out(data, hw_offset, 5, "Indirect state upper bound 0x%08x\n",
-                     data[5] & ~1);
-       } else
-           instr_out(data, hw_offset, 5, "Indirect state not updated\n");
+       i++;
+
+       state_base_out(data, hw_offset, i++, "general");
+       state_base_out(data, hw_offset, i++, "surface");
+       if (IS_GEN6(devid))
+           state_base_out(data, hw_offset, i++, "dynamic");
+       state_base_out(data, hw_offset, i++, "indirect");
+       if (IS_IRONLAKE(devid) || IS_GEN6(devid))
+           state_base_out(data, hw_offset, i++, "instruction");
+
+       state_max_out(data, hw_offset, i++, "general");
+       if (IS_GEN6(devid))
+           state_max_out(data, hw_offset, i++, "dynamic");
+       state_max_out(data, hw_offset, i++, "indirect");
+       if (IS_IRONLAKE(devid) || IS_GEN6(devid))
+           state_max_out(data, hw_offset, i++, "instruction");
 
        return len;
     case 0x7800:
@@ -1505,18 +1687,33 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures)
        instr_out(data, hw_offset, 6, "CC state\n");
        return len;
     case 0x7801:
-       if (len != 6)
+       len = (data[0] & 0x000000ff) + 2;
+       if (len != 6 && len != 4)
            fprintf(out, "Bad count in 3DSTATE_BINDING_TABLE_POINTERS\n");
-       if (count < 6)
-           BUFFER_FAIL(count, len, "3DSTATE_BINDING_TABLE_POINTERS");
+       if (len == 6) {
+           if (count < 6)
+               BUFFER_FAIL(count, len, "3DSTATE_BINDING_TABLE_POINTERS");
+           instr_out(data, hw_offset, 0,
+                     "3DSTATE_BINDING_TABLE_POINTERS\n");
+           instr_out(data, hw_offset, 1, "VS binding table\n");
+           instr_out(data, hw_offset, 2, "GS binding table\n");
+           instr_out(data, hw_offset, 3, "Clip binding table\n");
+           instr_out(data, hw_offset, 4, "SF binding table\n");
+           instr_out(data, hw_offset, 5, "WM binding table\n");
+       } else {
+           if (count < 4)
+               BUFFER_FAIL(count, len, "3DSTATE_BINDING_TABLE_POINTERS");
 
-       instr_out(data, hw_offset, 0,
-                 "3DSTATE_BINDING_TABLE_POINTERS\n");
-       instr_out(data, hw_offset, 1, "VS binding table\n");
-       instr_out(data, hw_offset, 2, "GS binding table\n");
-       instr_out(data, hw_offset, 3, "Clip binding table\n");
-       instr_out(data, hw_offset, 4, "SF binding table\n");
-       instr_out(data, hw_offset, 5, "WM binding table\n");
+           instr_out(data, hw_offset, 0,
+                     "3DSTATE_BINDING_TABLE_POINTERS: VS mod %d, "
+                     "GS mod %d, PS mod %d\n",
+                     (data[0] & (1 << 8)) != 0,
+                     (data[0] & (1 << 9)) != 0,
+                     (data[0] & (1 << 10)) != 0);
+           instr_out(data, hw_offset, 1, "VS binding table\n");
+           instr_out(data, hw_offset, 2, "GS binding table\n");
+           instr_out(data, hw_offset, 3, "WM binding table\n");
+       }
 
        return len;
 
@@ -1567,6 +1764,18 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures)
        }
        return len;
 
+    case 0x780d:
+       len = (data[0] & 0xff) + 2;
+       if (len != 4)
+           fprintf(out, "Bad count in 3DSTATE_VIEWPORT_STATE_POINTERS\n");
+       if (count < len)
+           BUFFER_FAIL(count, len, "3DSTATE_VIEWPORT_STATE_POINTERS");
+       instr_out(data, hw_offset, 0, "3DSTATE_VIEWPORT_STATE_POINTERS\n");
+       instr_out(data, hw_offset, 1, "clip\n");
+       instr_out(data, hw_offset, 2, "sf\n");
+       instr_out(data, hw_offset, 3, "cc\n");
+       return len;
+
     case 0x780a:
        len = (data[0] & 0xff) + 2;
        if (len != 3)
@@ -1616,10 +1825,10 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures)
                  ((data[3] & 0x0007ffc0) >> 6) + 1,
                  ((data[3] & 0xfff80000) >> 19) + 1);
        instr_out(data, hw_offset, 4, "volume depth\n");
-       if (len == 6)
+       if (len >= 6)
            instr_out(data, hw_offset, 5, "\n");
-       if (len == 7)
-           instr_out(data, hw_offset, 6, "render target view extent\n");
+       if (len >= 7)
+           instr_out(data, hw_offset, 6, "render target view extent\n");
 
        return len;
 
@@ -1638,12 +1847,11 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures)
        }
        instr_out(data, hw_offset, 0,
                  "PIPE_CONTROL: %s, %sdepth stall, %sRC write flush, "
-                 "%sinst flush, %stexture flush\n",
+                 "%sinst flush\n",
                  desc1,
                  data[0] & (1 << 13) ? "" : "no ",
                  data[0] & (1 << 12) ? "" : "no ",
-                 data[0] & (1 << 11) ? "" : "no ",
-                 data[0] & (1 << 9) ? "" : "no ");
+                 data[0] & (1 << 11) ? "" : "no ");
        instr_out(data, hw_offset, 1, "destination address\n");
        instr_out(data, hw_offset, 2, "immediate dword low\n");
        instr_out(data, hw_offset, 3, "immediate dword high\n");
@@ -1668,40 +1876,41 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures)
        return len;
     }
 
-    for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]);
-        opcode++) {
-       if ((data[0] & 0xffff0000) >> 16 == opcodes_3d[opcode].opcode) {
+    for (idx = 0; idx < ARRAY_SIZE(opcodes_3d); idx++) {
+       opcode_3d = &opcodes_3d[idx];
+       if ((data[0] & 0xffff0000) >> 16 == opcode_3d->opcode) {
            unsigned int i;
            len = 1;
 
-           instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name);
-           if (opcodes_3d[opcode].max_len > 1) {
+           instr_out(data, hw_offset, 0, "%s\n", opcode_3d->name);
+           if (opcode_3d->max_len > 1) {
                len = (data[0] & 0xff) + 2;
-               if (len < opcodes_3d[opcode].min_len ||
-                   len > opcodes_3d[opcode].max_len)
+               if (len < opcode_3d->min_len ||
+                   len > opcode_3d->max_len)
                {
-                   fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name);
+                   fprintf(out, "Bad count in %s\n", opcode_3d->name);
                }
            }
 
            for (i = 1; i < len; i++) {
                if (i >= count)
-                   BUFFER_FAIL(count, len, opcodes_3d[opcode].name);
+                   BUFFER_FAIL(count, len, opcode_3d->name);
                instr_out(data, hw_offset, i, "dword %d\n", i);
            }
            return len;
        }
     }
 
-    instr_out(data, hw_offset, 0, "3D UNKNOWN\n");
+    instr_out(data, hw_offset, 0, "3D UNKNOWN: 3d_965 opcode = 0x%x\n", opcode);
     (*failures)++;
     return 1;
 }
 
 static int
-decode_3d_i830(uint32_t *data, int count, uint32_t hw_offset, int *failures)
+decode_3d_i830(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid, int *failures)
 {
-    unsigned int opcode;
+    unsigned int idx;
+    uint32_t opcode;
 
     struct {
        uint32_t opcode;
@@ -1725,42 +1934,44 @@ decode_3d_i830(uint32_t *data, int count, uint32_t hw_offset, int *failures)
        { 0x0f, 1, 1, "3DSTATE_MODES_2" },
        { 0x15, 1, 1, "3DSTATE_FOG_COLOR" },
        { 0x16, 1, 1, "3DSTATE_MODES_4" },
-    };
+    }, *opcode_3d;
 
-    switch ((data[0] & 0x1f000000) >> 24) {
+    opcode = (data[0] & 0x1f000000) >> 24;
+
+    switch (opcode) {
     case 0x1f:
        return decode_3d_primitive(data, count, hw_offset, failures);
     case 0x1d:
-       return decode_3d_1d(data, count, hw_offset, failures, 1);
+       return decode_3d_1d(data, count, hw_offset, devid, failures);
     case 0x1c:
        return decode_3d_1c(data, count, hw_offset, failures);
     }
 
-    for (opcode = 0; opcode < sizeof(opcodes_3d) / sizeof(opcodes_3d[0]);
-        opcode++) {
-       if ((data[0] & 0x1f000000) >> 24 == opcodes_3d[opcode].opcode) {
+    for (idx = 0; idx < ARRAY_SIZE(opcodes_3d); idx++) {
+       opcode_3d = &opcodes_3d[idx];
+       if ((data[0] & 0x1f000000) >> 24 == opcode_3d->opcode) {
            unsigned int len = 1, i;
 
-           instr_out(data, hw_offset, 0, "%s\n", opcodes_3d[opcode].name);
-           if (opcodes_3d[opcode].max_len > 1) {
+           instr_out(data, hw_offset, 0, "%s\n", opcode_3d->name);
+           if (opcode_3d->max_len > 1) {
                len = (data[0] & 0xff) + 2;
-               if (len < opcodes_3d[opcode].min_len ||
-                   len > opcodes_3d[opcode].max_len)
+               if (len < opcode_3d->min_len ||
+                   len > opcode_3d->max_len)
                {
-                   fprintf(out, "Bad count in %s\n", opcodes_3d[opcode].name);
+                   fprintf(out, "Bad count in %s\n", opcode_3d->name);
                }
            }
 
            for (i = 1; i < len; i++) {
                if (i >= count)
-                   BUFFER_FAIL(count, len, opcodes_3d[opcode].name);
+                   BUFFER_FAIL(count, len, opcode_3d->name);
                instr_out(data, hw_offset, i, "dword %d\n", i);
            }
            return len;
        }
     }
 
-    instr_out(data, hw_offset, 0, "3D UNKNOWN\n");
+    instr_out(data, hw_offset, 0, "3D UNKNOWN: 3d_i830 opcode = 0x%x\n", opcode);
     (*failures)++;
     return 1;
 }
@@ -1773,18 +1984,37 @@ decode_3d_i830(uint32_t *data, int count, uint32_t hw_offset, int *failures)
  * \param hw_offset hardware address for the buffer
  */
 int
-intel_decode(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid)
+intel_decode(uint32_t *data, int count,
+            uint32_t hw_offset,
+            uint32_t devid,
+            uint32_t ignore_end_of_batchbuffer)
 {
+    int ret;
     int index = 0;
     int failures = 0;
 
-    out = stderr;
+    out = stdout;
 
     while (index < count) {
        switch ((data[index] & 0xe0000000) >> 29) {
        case 0x0:
-           index += decode_mi(data + index, count - index,
+           ret = decode_mi(data + index, count - index,
                               hw_offset + index * 4, &failures);
+
+           /* If MI_BATCHBUFFER_END happened, then dump the rest of the
+            * output in case we some day want it in debugging, but don't
+            * decode it since it'll just confuse in the common case.
+            */
+           if (ret == -1) {
+               if (ignore_end_of_batchbuffer) {
+                   index++;
+               } else {
+                   for (index = index + 1; index < count; index++) {
+                       instr_out(data, hw_offset, index, "\n");
+                   }
+               }
+           } else
+               index += ret;
            break;
        case 0x2:
            index += decode_2d(data + index, count - index,
@@ -1793,13 +2023,16 @@ intel_decode(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid)
        case 0x3:
            if (IS_965(devid)) {
                index += decode_3d_965(data + index, count - index,
-                                      hw_offset + index * 4, &failures);
+                                      hw_offset + index * 4,
+                                      devid, &failures);
            } else if (IS_9XX(devid)) {
                index += decode_3d(data + index, count - index,
-                                  hw_offset + index * 4, &failures);
+                                  hw_offset + index * 4,
+                                  devid, &failures);
            } else {
                index += decode_3d_i830(data + index, count - index,
-                                       hw_offset + index * 4, &failures);
+                                       hw_offset + index * 4,
+                                       devid, &failures);
            }
            break;
        default:
@@ -1820,3 +2053,8 @@ void intel_decode_context_reset(void)
     saved_s4_set = 1;
 }
 
+void intel_decode_context_set_head_tail(uint32_t head, uint32_t tail)
+{
+       head_offset = head;
+       tail_offset = tail;
+}
index c50644a46b5e85e3ad452c890a70372896415e17..a13b075cef835b69265333ee6ed332b65fc1cd54 100644 (file)
@@ -25,5 +25,7 @@
  *
  */
 
-int intel_decode(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid);
+int intel_decode(uint32_t *data, int count, uint32_t hw_offset, uint32_t devid,
+                uint32_t ignore_end_of_batchbuffer);
+void intel_decode_context_set_head_tail(uint32_t head, uint32_t tail);
 void intel_decode_context_reset(void);
index 076fee89bdd0ff6eaee649e5f2e0d204fe042cd6..0e2fe893fed35d3835c7424881da115ff78f2919 100644 (file)
@@ -26,6 +26,7 @@
  **************************************************************************/
 
 #include "main/glheader.h"
+#include "main/arbprogram.h"
 #include "main/enums.h"
 #include "main/image.h"
 #include "main/colormac.h"
@@ -44,7 +45,6 @@
 #include "main/attrib.h"
 #include "main/enable.h"
 #include "main/viewport.h"
-#include "shader/arbprogram.h"
 #include "swrast/swrast.h"
 
 #include "intel_screen.h"
index 4bd6dee6c0e7caaa971ac7b752e57c8fd5c73982..239e8bc8fd09bf014675f186fbca124cb1e033e3 100644 (file)
@@ -256,7 +256,6 @@ mach64CreateScreen( __DRIscreen *sPriv )
    mach64Screen->driScreen = sPriv;
 
    i = 0;
-   mach64Screen->extensions[i++] = &driFrameTrackingExtension.base;
    if ( mach64Screen->irq != 0 ) {
       mach64Screen->extensions[i++] = &driSwapControlExtension.base;
       mach64Screen->extensions[i++] = &driMediaStreamCounterExtension.base;
index 31007ccb1dacf14e40bd628ed6e13add00e9696d..3a31dfb44a3fb87f19b4577022acea6cf0d976a8 100644 (file)
@@ -182,7 +182,6 @@ mgaFillInModes( __DRIscreen *psp,
 const __DRIextension *mgaScreenExtensions[] = {
     &driReadDrawableExtension,
     &driSwapControlExtension.base,
-    &driFrameTrackingExtension.base,
     &driMediaStreamCounterExtension.base,
     NULL
 };
index 2d91802823650ef972af7e1ec966aed974d7f035..7626a159d6a968ab141ada5f0792c448404947fb 100644 (file)
@@ -221,7 +221,6 @@ r128CreateScreen( __DRIscreen *sPriv )
    r128Screen->driScreen = sPriv;
 
    i = 0;
-   r128Screen->extensions[i++] = &driFrameTrackingExtension.base;
    if ( r128Screen->irq != 0 ) {
        r128Screen->extensions[i++] = &driSwapControlExtension.base;
        r128Screen->extensions[i++] = &driMediaStreamCounterExtension.base;
index 4d773feaaa86e6c67cb0de121fb6fa3b8a17531d..9ad25f7f46391671a584a05a4d3ae5fcaa68c9b5 100644 (file)
@@ -42,6 +42,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/context.h"
 #include "main/enums.h"
 #include "main/colormac.h"
+#include "main/macros.h"
 #include "swrast/swrast.h"
 #include "vbo/vbo.h"
 #include "tnl/tnl.h"
index 4ec4be9a47b188c59d349a9d20981b96f527e8e1..b5a19b510af49c0923a7d138c60113e45b3fbdba 100644 (file)
@@ -44,6 +44,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/texobj.h"
 #include "main/imports.h"
 #include "main/texobj.h"
+#include "main/macros.h"
 
 #include "xmlpool.h"
 
index 85c1b7bdd19426bcdb5072abe15373a0b77874d2..2a9268dd3438929f85f8665806ebff953c866697 100644 (file)
  **************************************************************************/
 
 #include "main/glheader.h"
+#include "main/atifragshader.h"
 #include "main/macros.h"
 #include "main/enums.h"
 #include "tnl/t_context.h"
-#include "shader/atifragshader.h"
-#include "shader/program.h"
+#include "program/program.h"
 #include "r200_context.h"
 #include "r200_ioctl.h"
 #include "r200_tex.h"
index b72f69b7f4585166101716ed322f2edba7abd6b0..df73de5394a6c8db308a73da2247aec5cf3df1ae 100644 (file)
@@ -253,113 +253,6 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask )
    }
 }
 
-/* This version of AllocateMemoryMESA allocates only GART memory, and
- * only does so after the point at which the driver has been
- * initialized.
- *
- * Theoretically a valid context isn't required.  However, in this
- * implementation, it is, as I'm using the hardware lock to protect
- * the kernel data structures, and the current context to get the
- * device fd.
- */
-void *r200AllocateMemoryMESA(__DRIscreen *screen, GLsizei size,
-                            GLfloat readfreq, GLfloat writefreq,
-                            GLfloat priority)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   r200ContextPtr rmesa;
-   int region_offset;
-   drm_radeon_mem_alloc_t alloc;
-   int ret;
-
-   if (R200_DEBUG & RADEON_IOCTL)
-      fprintf(stderr, "%s sz %d %f/%f/%f\n", __FUNCTION__, size, readfreq,
-             writefreq, priority);
-
-   if (!ctx || !(rmesa = R200_CONTEXT(ctx)) || !rmesa->radeon.radeonScreen->gartTextures.map)
-      return NULL;
-
-   if (getenv("R200_NO_ALLOC"))
-      return NULL;
-
-   alloc.region = RADEON_MEM_REGION_GART;
-   alloc.alignment = 0;
-   alloc.size = size;
-   alloc.region_offset = &region_offset;
-
-   ret = drmCommandWriteRead( rmesa->radeon.radeonScreen->driScreen->fd,
-                             DRM_RADEON_ALLOC,
-                             &alloc, sizeof(alloc));
-
-   if (ret) {
-      fprintf(stderr, "%s: DRM_RADEON_ALLOC ret %d\n", __FUNCTION__, ret);
-      return NULL;
-   }
-
-   {
-      char *region_start = (char *)rmesa->radeon.radeonScreen->gartTextures.map;
-      return (void *)(region_start + region_offset);
-   }
-}
-
-
-/* Called via glXFreeMemoryMESA() */
-void r200FreeMemoryMESA(__DRIscreen *screen, GLvoid *pointer)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   r200ContextPtr rmesa;
-   ptrdiff_t region_offset;
-   drm_radeon_mem_free_t memfree;
-   int ret;
-
-   if (R200_DEBUG & RADEON_IOCTL)
-      fprintf(stderr, "%s %p\n", __FUNCTION__, pointer);
-
-   if (!ctx || !(rmesa = R200_CONTEXT(ctx)) || !rmesa->radeon.radeonScreen->gartTextures.map) {
-      fprintf(stderr, "%s: no context\n", __FUNCTION__);
-      return;
-   }
-
-   region_offset = (char *)pointer - (char *)rmesa->radeon.radeonScreen->gartTextures.map;
-
-   if (region_offset < 0 ||
-       region_offset > rmesa->radeon.radeonScreen->gartTextures.size) {
-      fprintf(stderr, "offset %d outside range 0..%d\n", region_offset,
-             rmesa->radeon.radeonScreen->gartTextures.size);
-      return;
-   }
-
-   memfree.region = RADEON_MEM_REGION_GART;
-   memfree.region_offset = region_offset;
-
-   ret = drmCommandWrite( rmesa->radeon.radeonScreen->driScreen->fd,
-                         DRM_RADEON_FREE,
-                         &memfree, sizeof(memfree));
-
-   if (ret)
-      fprintf(stderr, "%s: DRM_RADEON_FREE ret %d\n", __FUNCTION__, ret);
-}
-
-/* Called via glXGetMemoryOffsetMESA() */
-GLuint r200GetMemoryOffsetMESA(__DRIscreen *screen, const GLvoid *pointer)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   r200ContextPtr rmesa;
-   GLuint card_offset;
-
-   if (!ctx || !(rmesa = R200_CONTEXT(ctx)) ) {
-      fprintf(stderr, "%s: no context\n", __FUNCTION__);
-      return ~0;
-   }
-
-   if (!r200IsGartMemory( rmesa, pointer, 0 ))
-      return ~0;
-
-   card_offset = r200GartOffsetFromVirtual( rmesa, pointer );
-
-   return card_offset - rmesa->radeon.radeonScreen->gart_base;
-}
-
 GLboolean r200IsGartMemory( r200ContextPtr rmesa, const GLvoid *pointer,
                           GLint size )
 {
index 8d51aefa0420ec71c8811cd16c1f0aab56cdd1b9..c5dca89bc760212c43e8dcce67c6b037b21f5666 100644 (file)
@@ -64,11 +64,6 @@ extern void r200EmitAOS(r200ContextPtr rmesa, GLuint nr, GLuint offset);
 
 extern void r200InitIoctlFuncs( struct dd_function_table *functions );
 
-extern void *r200AllocateMemoryMESA( __DRIscreen *screen, GLsizei size, GLfloat readfreq,
-                                  GLfloat writefreq, GLfloat priority );
-extern void r200FreeMemoryMESA( __DRIscreen *screen, GLvoid *pointer );
-extern GLuint r200GetMemoryOffsetMESA( __DRIscreen *screen, const GLvoid *pointer );
-
 extern GLboolean r200IsGartMemory( r200ContextPtr rmesa, const GLvoid *pointer,
                                   GLint size );
 
index 12f869d96f84643bd2bddb41078a8c34884e5b7f..5d268319f3f76cddcbfcd92b8154f7f891940eaa 100644 (file)
@@ -33,11 +33,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/glheader.h"
 #include "main/macros.h"
 #include "main/enums.h"
-#include "shader/program.h"
-#include "shader/prog_instruction.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_statevars.h"
-#include "shader/programopt.h"
+#include "program/program.h"
+#include "program/prog_instruction.h"
+#include "program/prog_parameter.h"
+#include "program/prog_statevars.h"
+#include "program/programopt.h"
 #include "tnl/tnl.h"
 
 #include "r200_context.h"
index ff3801dc676e7e107539028dcfdc5f5d91c4875d..3167d49bcae7a5acc5e4e4c12e0df717478e5b03 100644 (file)
@@ -23,6 +23,7 @@ C_SOURCES = \
                radeon_dataflow_deadcode.c \
                radeon_dataflow_swizzles.c \
                radeon_optimize.c \
+               radeon_rename_regs.c \
                r3xx_fragprog.c \
                r300_fragprog.c \
                r300_fragprog_swizzle.c \
index 50d9cdb7f2d1039ce127a9b97b25837191d06b38..c6f47a6f8a4940e8d8245114fa83d1e2aacc0fd1 100755 (executable)
@@ -22,6 +22,7 @@ r300compiler = env.ConvenienceLibrary(
         'radeon_pair_schedule.c',
         'radeon_pair_regalloc.c',
         'radeon_optimize.c',
+        'radeon_rename_regs.c',
         'radeon_emulate_branches.c',
         'radeon_emulate_loops.c',
         'radeon_dataflow.c',
index 38312658d65ae6595be964b926346eb68d2f051e..a326ee4c4faa03cead6d410be386790c8c9ae2d6 100644 (file)
@@ -29,6 +29,7 @@
 #include "radeon_emulate_loops.h"
 #include "radeon_program_alu.h"
 #include "radeon_program_tex.h"
+#include "radeon_rename_regs.h"
 #include "r300_fragprog.h"
 #include "r300_fragprog_swizzle.h"
 #include "r500_fragprog.h"
@@ -97,25 +98,27 @@ static void debug_program_log(struct r300_fragment_program_compiler* c, const ch
 
 void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
 {
+       struct emulate_loop_state loop_state;
+
        rewrite_depth_out(c);
 
+       /* This transformation needs to be done before any of the IF
+        * instructions are modified. */
+       radeonTransformKILP(&c->Base);
+
        debug_program_log(c, "before compilation");
 
-       /* XXX Ideally this should be done only for r3xx, but since
-        * we don't have branching support for r5xx, we use the emulation
-        * on all chipsets. */
-       
-       if(c->Base.is_r500){
-               rc_emulate_loops(&c->Base, R500_PFS_MAX_INST);
+       if (c->Base.is_r500){
+               r500_transform_unroll_loops(&c->Base, &loop_state);     
+               debug_program_log(c, "after r500 transform loops");
        }
        else{
-               rc_emulate_loops(&c->Base, R300_PFS_MAX_ALU_INST);
+               rc_transform_unroll_loops(&c->Base, &loop_state);
+               debug_program_log(c, "after transform loops");
+               
+               rc_emulate_branches(&c->Base);
+               debug_program_log(c, "after emulate branches");
        }
-       debug_program_log(c, "after emulate loops");
-       
-       rc_emulate_branches(&c->Base);
-
-       debug_program_log(c, "after emulate branches");
 
        if (c->Base.is_r500) {
                struct radeon_program_transformation transformations[] = {
@@ -162,6 +165,11 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
 
        debug_program_log(c, "after deadcode");
 
+       if(!c->Base.is_r500){
+               rc_emulate_loops(&loop_state, R300_PFS_MAX_ALU_INST);
+               debug_program_log(c, "after emulate loops");
+       }
+
        rc_optimize(&c->Base);
 
        debug_program_log(c, "after dataflow optimize");
@@ -172,6 +180,16 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
 
        debug_program_log(c, "after dataflow passes");
 
+       if(!c->Base.is_r500) {
+               /* This pass makes it easier for the scheduler to group TEX
+                * instructions and reduces the chances of creating too
+                * many texture indirections.*/
+               rc_rename_regs(&c->Base);
+               if (c->Base.Error)
+                       return;
+               debug_program_log(c, "after register rename");
+       }
+
        rc_pair_translate(c);
        if (c->Base.Error)
                return;
index 507b2e532febea97ffe79971ba4634ce39794126..d347b4df9cd6c17aed1a175c140fdd5b31928f74 100644 (file)
@@ -30,6 +30,7 @@
 #include "radeon_program_alu.h"
 #include "radeon_swizzle.h"
 #include "radeon_emulate_branches.h"
+#include "radeon_emulate_loops.h"
 
 /*
  * Take an already-setup and valid source then swizzle it appropriately to
@@ -145,7 +146,8 @@ static unsigned long t_src(struct r300_vertex_program_code *vp,
                               t_swizzle(GET_SWZ(src->Swizzle, 2)),
                               t_swizzle(GET_SWZ(src->Swizzle, 3)),
                               t_src_class(src->File),
-                              src->Negate) | (src->RelAddr << 4);
+                              src->Negate) |
+              (src->RelAddr << 4) | (src->Abs << 3);
 }
 
 static unsigned long t_src_scalar(struct r300_vertex_program_code *vp,
@@ -161,7 +163,7 @@ static unsigned long t_src_scalar(struct r300_vertex_program_code *vp,
                               t_swizzle(GET_SWZ(src->Swizzle, 0)),
                               t_src_class(src->File),
                               src->Negate ? RC_MASK_XYZW : RC_MASK_NONE) |
-           (src->RelAddr << 4);
+              (src->RelAddr << 4) | (src->Abs << 3);
 }
 
 static int valid_dst(struct r300_vertex_program_code *vp,
@@ -348,7 +350,8 @@ static void translate_vertex_program(struct r300_vertex_program_compiler * compi
                if (!valid_dst(compiler->code, &vpi->DstReg))
                        continue;
 
-               if (compiler->code->length >= VSF_MAX_FRAGMENT_LENGTH) {
+               if (compiler->code->length >= R500_VS_MAX_ALU_DWORDS ||
+                   (compiler->code->length >= R300_VS_MAX_ALU_DWORDS && !compiler->Base.is_r500)) {
                        rc_error(&compiler->Base, "Vertex program has too many instructions\n");
                        return;
                }
@@ -404,7 +407,7 @@ static void allocate_temporary_registers(struct r300_vertex_program_compiler * c
 {
        struct rc_instruction *inst;
        unsigned int num_orig_temps = 0;
-       char hwtemps[VSF_MAX_FRAGMENT_TEMPS];
+       char hwtemps[R300_VS_MAX_TEMPS];
        struct temporary_allocation * ta;
        unsigned int i, j;
 
@@ -463,11 +466,11 @@ static void allocate_temporary_registers(struct r300_vertex_program_compiler * c
                                unsigned int orig = inst->U.I.DstReg.Index;
 
                                if (!ta[orig].Allocated) {
-                                       for(j = 0; j < VSF_MAX_FRAGMENT_TEMPS; ++j) {
+                                       for(j = 0; j < R300_VS_MAX_TEMPS; ++j) {
                                                if (!hwtemps[j])
                                                        break;
                                        }
-                                       if (j >= VSF_MAX_FRAGMENT_TEMPS) {
+                                       if (j >= R300_VS_MAX_TEMPS) {
                                                fprintf(stderr, "Out of hw temporaries\n");
                                        } else {
                                                ta[orig].Allocated = 1;
@@ -485,6 +488,44 @@ static void allocate_temporary_registers(struct r300_vertex_program_compiler * c
        }
 }
 
+/**
+ * R3xx-R4xx vertex engine does not support the Absolute source operand modifier
+ * and the Saturate opcode modifier. Only Absolute is currently transformed.
+ */
+static int transform_nonnative_modifiers(
+       struct radeon_compiler *c,
+       struct rc_instruction *inst,
+       void* unused)
+{
+       const struct rc_opcode_info *opcode = rc_get_opcode_info(inst->U.I.Opcode);
+       unsigned i;
+
+       /* Transform ABS(a) to MAX(a, -a). */
+       for (i = 0; i < opcode->NumSrcRegs; i++) {
+               if (inst->U.I.SrcReg[i].Abs) {
+                       struct rc_instruction *new_inst;
+                       unsigned temp;
+
+                       inst->U.I.SrcReg[i].Abs = 0;
+
+                       temp = rc_find_free_temporary(c);
+
+                       new_inst = rc_insert_new_instruction(c, inst->Prev);
+                       new_inst->U.I.Opcode = RC_OPCODE_MAX;
+                       new_inst->U.I.DstReg.File = RC_FILE_TEMPORARY;
+                       new_inst->U.I.DstReg.Index = temp;
+                       new_inst->U.I.SrcReg[0] = inst->U.I.SrcReg[i];
+                       new_inst->U.I.SrcReg[1] = inst->U.I.SrcReg[i];
+                       new_inst->U.I.SrcReg[1].Negate ^= RC_MASK_XYZW;
+
+                       memset(&inst->U.I.SrcReg[i], 0, sizeof(inst->U.I.SrcReg[i]));
+                       inst->U.I.SrcReg[i].File = RC_FILE_TEMPORARY;
+                       inst->U.I.SrcReg[i].Index = temp;
+                       inst->U.I.SrcReg[i].Swizzle = RC_SWIZZLE_XYZW;
+               }
+       }
+       return 1;
+}
 
 /**
  * Vertex engine cannot read two inputs or two constants at the same time.
@@ -591,6 +632,8 @@ static struct rc_swizzle_caps r300_vertprog_swizzle_caps = {
 
 void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler)
 {
+       struct emulate_loop_state loop_state;
+       
        compiler->Base.SwizzleCaps = &r300_vertprog_swizzle_caps;
 
        addArtificialOutputs(compiler);
@@ -600,19 +643,48 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler)
        /* XXX Ideally this should be done only for r3xx, but since
         * we don't have branching support for r5xx, we use the emulation
         * on all chipsets. */
+       rc_transform_unroll_loops(&compiler->Base, &loop_state);
+       
+       debug_program_log(compiler, "after transform loops");
+       
+       if (compiler->Base.is_r500){
+               rc_emulate_loops(&loop_state, R500_VS_MAX_ALU);
+       } else {
+               rc_emulate_loops(&loop_state, R300_VS_MAX_ALU);
+       }
+       debug_program_log(compiler, "after emulate loops");
+
        rc_emulate_branches(&compiler->Base);
 
        debug_program_log(compiler, "after emulate branches");
 
-       {
+       if (compiler->Base.is_r500) {
                struct radeon_program_transformation transformations[] = {
                        { &r300_transform_vertex_alu, 0 },
                        { &r300_transform_trig_scale_vertex, 0 }
                };
                radeonLocalTransform(&compiler->Base, 2, transformations);
-       }
 
-       debug_program_log(compiler, "after native rewrite");
+               debug_program_log(compiler, "after native rewrite");
+       } else {
+               struct radeon_program_transformation transformations[] = {
+                       { &r300_transform_vertex_alu, 0 },
+                       { &radeonTransformTrigSimple, 0 }
+               };
+               radeonLocalTransform(&compiler->Base, 2, transformations);
+
+               debug_program_log(compiler, "after native rewrite");
+
+               /* Note: This pass has to be done seperately from ALU rewrite,
+                * because it needs to check every instruction.
+                */
+               struct radeon_program_transformation transformations2[] = {
+                       { &transform_nonnative_modifiers, 0 },
+               };
+               radeonLocalTransform(&compiler->Base, 1, transformations2);
+
+               debug_program_log(compiler, "after emulate modifiers");
+       }
 
        {
                /* Note: This pass has to be done seperately from ALU rewrite,
index 632f0bcf4f8fee9e2f2d8e926207bb9139586e93..e6b5522c5b9c32ae1fcad3b45175715626d15904 100644 (file)
@@ -30,6 +30,7 @@
 #include <stdio.h>
 
 #include "../r300_reg.h"
+#include "radeon_emulate_loops.h"
 
 /**
  * Rewrite IF instructions to use the ALU result special register.
@@ -59,6 +60,31 @@ int r500_transform_IF(
        return 1;
 }
 
+/**
+ * Rewrite loops to make them easier to emit.  This is not a local
+ * transformation, because it modifies and reorders an entire block of code.
+ */
+void r500_transform_unroll_loops(struct radeon_compiler * c,
+                                               struct emulate_loop_state *s)
+{
+       int i;
+       
+       rc_transform_unroll_loops(c, s);
+       
+       for( i = s->LoopCount - 1; i >= 0; i-- ){
+               struct rc_instruction * inst_continue;
+               if(!s->Loops[i].EndLoop){
+                       continue;
+               }
+               /* Insert a continue instruction at the end of the loop.  This
+                * is required in order to emit loops correctly. */
+               inst_continue = rc_insert_new_instruction(c,
+                                               s->Loops[i].EndIf->Prev);
+               inst_continue->U.I.Opcode = RC_OPCODE_CONTINUE;
+       }
+
+}
+
 static int r500_swizzle_is_native(rc_opcode opcode, struct rc_src_register reg)
 {
        unsigned int relevant;
@@ -252,7 +278,7 @@ void r500FragmentProgramDump(struct rX00_fragment_program_code *c)
   struct r500_fragment_program_code *code = &c->code.r500;
   fprintf(stderr, "R500 Fragment Program:\n--------\n");
 
-  int n;
+  int n, i;
   uint32_t inst;
   uint32_t inst0;
   char *str = NULL;
@@ -275,8 +301,8 @@ void r500FragmentProgramDump(struct rX00_fragment_program_code *c)
            to_mask((inst >> 15) & 0xf));
 
     switch(inst0 & 0x3) {
-    case 0:
-    case 1:
+    case R500_INST_TYPE_ALU:
+    case R500_INST_TYPE_OUT:
       fprintf(stderr,"\t1:RGB_ADDR   0x%08x:", code->inst[n].inst1);
       inst = code->inst[n].inst1;
 
@@ -319,9 +345,87 @@ void r500FragmentProgramDump(struct rX00_fragment_program_code *c)
              (inst >> 23) & 0x3,
              (inst >> 25) & 0x3, toswiz((inst >> 27) & 0x7), (inst >> 30) & 0x3);
       break;
-    case 2:
+    case R500_INST_TYPE_FC:
+      fprintf(stderr, "\t2:FC_INST    0x%08x:", code->inst[n].inst2);
+      inst = code->inst[n].inst2;
+      /* JUMP_FUNC JUMP_ANY*/
+      fprintf(stderr, "0x%02x %1x ", inst >> 8 & 0xff,
+          (inst & R500_FC_JUMP_ANY) >> 5);
+      
+      /* OP */
+      switch(inst & 0x7){
+      case R500_FC_OP_JUMP:
+       fprintf(stderr, "JUMP");
+        break;
+      case R500_FC_OP_LOOP:
+        fprintf(stderr, "LOOP");
+        break;
+      case R500_FC_OP_ENDLOOP:
+        fprintf(stderr, "ENDLOOP");
+        break;
+      case R500_FC_OP_REP:
+        fprintf(stderr, "REP");
+        break;
+      case R500_FC_OP_ENDREP:
+        fprintf(stderr, "ENDREP");
+        break;
+      case R500_FC_OP_BREAKLOOP:
+        fprintf(stderr, "BREAKLOOP");
+        break;
+      case R500_FC_OP_BREAKREP:
+        fprintf(stderr, "BREAKREP");
+       break;
+      case R500_FC_OP_CONTINUE:
+        fprintf(stderr, "CONTINUE");
+        break;
+      }
+      fprintf(stderr," "); 
+      /* A_OP */
+      switch(inst & (0x3 << 6)){
+      case R500_FC_A_OP_NONE:
+        fprintf(stderr, "NONE");
+        break;
+      case R500_FC_A_OP_POP:
+       fprintf(stderr, "POP");
+        break;
+      case R500_FC_A_OP_PUSH:
+        fprintf(stderr, "PUSH");
+        break;
+      }
+      /* B_OP0 B_OP1 */
+      for(i=0; i<2; i++){
+        fprintf(stderr, " ");
+        switch(inst & (0x3 << (24 + (i * 2)))){
+        /* R500_FC_B_OP0_NONE 
+        * R500_FC_B_OP1_NONE */
+       case 0:
+          fprintf(stderr, "NONE");
+          break;
+        case R500_FC_B_OP0_DECR:
+        case R500_FC_B_OP1_DECR:
+          fprintf(stderr, "DECR");
+          break;
+        case R500_FC_B_OP0_INCR:
+        case R500_FC_B_OP1_INCR:
+          fprintf(stderr, "INCR");
+          break;
+        }
+      }
+      /*POP_CNT B_ELSE */
+      fprintf(stderr, " %d %1x", (inst >> 16) & 0x1f, (inst & R500_FC_B_ELSE) >> 4);
+      inst = code->inst[n].inst3;
+      /* JUMP_ADDR */
+      fprintf(stderr, " %d", inst >> 16);
+      
+      if(code->inst[n].inst2 & R500_FC_IGNORE_UNCOVERED){
+        fprintf(stderr, " IGN_UNC");
+      }
+      inst = code->inst[n].inst3;
+      fprintf(stderr, "\n\t3:FC_ADDR    0x%08x:", inst);
+      fprintf(stderr, "BOOL: 0x%02x, INT: 0x%02x, JUMP_ADDR: %d, JMP_GLBL: %1x\n",
+      inst & 0x1f, (inst >> 8) & 0x1f, (inst >> 16) & 0x1ff, inst >> 31); 
       break;
-    case 3:
+    case R500_INST_TYPE_TEX:
       inst = code->inst[n].inst1;
       fprintf(stderr,"\t1:TEX_INST:  0x%08x: id: %d op:%s, %s, %s %s\n", inst, (inst >> 16) & 0xf,
              to_texop((inst >> 22) & 0x7), (inst & (1<<25)) ? "ACQ" : "",
index 4efbae7ba672929143407995a268ab0c286346e4..0d005a794ff51ec2be4edc199dffb1f079be08f0 100644 (file)
@@ -36,6 +36,8 @@
 #include "radeon_compiler.h"
 #include "radeon_swizzle.h"
 
+struct emulate_loop_state;
+
 extern void r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler);
 
 extern void r500FragmentProgramDump(struct rX00_fragment_program_code *c);
@@ -47,4 +49,6 @@ extern int r500_transform_IF(
        struct rc_instruction * inst,
        void* data);
 
+void r500_transform_unroll_loops(struct radeon_compiler * c,
+                                               struct emulate_loop_state * s);
 #endif
index fb2d8b5a9c0a4ac5fbb854a0cb7932956350af8f..0bd8f0a239f610b855f238e2c25bccab8cc1ccee 100644 (file)
@@ -45,6 +45,8 @@
 
 #include "radeon_program_pair.h"
 
+#define MAX_BRANCH_DEPTH_FULL 32
+#define MAX_BRANCH_DEPTH_PARTIAL 4
 
 #define PROG_CODE \
        struct r500_fragment_program_code *code = &c->code->code.r500
@@ -61,6 +63,10 @@ struct branch_info {
        int Endif;
 };
 
+struct loop_info {
+       int LoopStart;
+};
+
 struct emit_state {
        struct radeon_compiler * C;
        struct r500_fragment_program_code * Code;
@@ -69,7 +75,12 @@ struct emit_state {
        unsigned int CurrentBranchDepth;
        unsigned int BranchesReserved;
 
+       struct loop_info * Loops;
+       unsigned int CurrentLoopDepth;
+       unsigned int LoopsReserved;
+
        unsigned int MaxBranchDepth;
+
 };
 
 static unsigned int translate_rgb_op(struct r300_fragment_program_compiler *c, rc_opcode opcode)
@@ -359,16 +370,49 @@ static void emit_flowcontrol(struct emit_state * s, struct rc_instruction * inst
 
        s->Code->inst[newip].inst0 = R500_INST_TYPE_FC | R500_INST_ALU_WAIT;
 
-       if (inst->U.I.Opcode == RC_OPCODE_IF) {
-               if (s->CurrentBranchDepth >= 32) {
+       switch(inst->U.I.Opcode){
+       struct branch_info * branch;
+       struct loop_info * loop;
+       case RC_OPCODE_BGNLOOP:
+               memory_pool_array_reserve(&s->C->Pool, struct loop_info,
+                       s->Loops, s->CurrentLoopDepth, s->LoopsReserved, 1);
+
+               loop = &s->Loops[s->CurrentLoopDepth++];
+               
+               /* We don't emit an instruction for BGNLOOP, so we need to
+                * decrement the instruction counter, but first we need to
+                * set LoopStart to the current value of inst_end, which
+                * will end up being the first real instruction in the loop.*/
+               loop->LoopStart = s->Code->inst_end--;
+               break;
+       
+       case RC_OPCODE_BRK:
+               /* Don't emit an instruction for BRK */
+               s->Code->inst_end--;
+               break;
+
+       case RC_OPCODE_CONTINUE:
+               loop = &s->Loops[s->CurrentLoopDepth - 1];
+               s->Code->inst[newip].inst2 = R500_FC_OP_JUMP |
+                       R500_FC_JUMP_FUNC(0xff);
+               s->Code->inst[newip].inst3 = R500_FC_JUMP_ADDR(loop->LoopStart);
+               break;
+
+       case RC_OPCODE_ENDLOOP:
+               /* Don't emit an instruction for ENDLOOP */
+               s->Code->inst_end--;
+               s->CurrentLoopDepth--;
+               break;
+
+       case RC_OPCODE_IF:
+               if ( s->CurrentBranchDepth >= MAX_BRANCH_DEPTH_FULL) {
                        rc_error(s->C, "Branch depth exceeds hardware limit");
                        return;
                }
-
                memory_pool_array_reserve(&s->C->Pool, struct branch_info,
                                s->Branches, s->CurrentBranchDepth, s->BranchesReserved, 1);
 
-               struct branch_info * branch = &s->Branches[s->CurrentBranchDepth++];
+               branch = &s->Branches[s->CurrentBranchDepth++];
                branch->If = newip;
                branch->Else = -1;
                branch->Endif = -1;
@@ -377,29 +421,50 @@ static void emit_flowcontrol(struct emit_state * s, struct rc_instruction * inst
                        s->MaxBranchDepth = s->CurrentBranchDepth;
 
                /* actual instruction is filled in at ENDIF time */
-       } else if (inst->U.I.Opcode == RC_OPCODE_ELSE) {
+               break;
+       
+       case RC_OPCODE_ELSE:
                if (!s->CurrentBranchDepth) {
                        rc_error(s->C, "%s: got ELSE outside a branch", __FUNCTION__);
                        return;
                }
 
-               struct branch_info * branch = &s->Branches[s->CurrentBranchDepth - 1];
+               branch = &s->Branches[s->CurrentBranchDepth - 1];
                branch->Else = newip;
 
                /* actual instruction is filled in at ENDIF time */
-       } else if (inst->U.I.Opcode == RC_OPCODE_ENDIF) {
+               break;
+
+       case RC_OPCODE_ENDIF:
                if (!s->CurrentBranchDepth) {
                        rc_error(s->C, "%s: got ELSE outside a branch", __FUNCTION__);
                        return;
                }
 
-               struct branch_info * branch = &s->Branches[s->CurrentBranchDepth - 1];
-               branch->Endif = newip;
-
+               branch = &s->Branches[s->CurrentBranchDepth - 1];
+               
+               if(inst->Prev->U.I.Opcode == RC_OPCODE_BRK){
+                       branch->Endif = --s->Code->inst_end;
+                       s->Code->inst[branch->Endif].inst2 |=
+                               R500_FC_B_OP0_DECR;
+               }
+               else{
+                       branch->Endif = newip;
+               
+                       s->Code->inst[branch->Endif].inst2 = R500_FC_OP_JUMP
+                               | R500_FC_A_OP_NONE /* no address stack */
+                               | R500_FC_JUMP_ANY /* docs says set this, but I don't understand why */
+                               | R500_FC_B_OP0_DECR /* decrement branch counter if stay */
+                               | R500_FC_B_OP1_NONE /* no branch counter if stay */
+                               | R500_FC_B_POP_CNT(1)
+                       ;
+                       s->Code->inst[branch->Endif].inst3 = R500_FC_JUMP_ADDR(branch->Endif + 1);
+               }
                s->Code->inst[branch->If].inst2 = R500_FC_OP_JUMP
                        | R500_FC_A_OP_NONE /* no address stack */
                        | R500_FC_JUMP_FUNC(0x0f) /* jump if ALU result is false */
                        | R500_FC_B_OP0_INCR /* increment branch counter if stay */
+                       | R500_FC_IGNORE_UNCOVERED
                ;
 
                if (branch->Else >= 0) {
@@ -421,17 +486,10 @@ static void emit_flowcontrol(struct emit_state * s, struct rc_instruction * inst
                        s->Code->inst[branch->If].inst3 = R500_FC_JUMP_ADDR(branch->Endif + 1);
                }
 
-               s->Code->inst[branch->Endif].inst2 = R500_FC_OP_JUMP
-                       | R500_FC_A_OP_NONE /* no address stack */
-                       | R500_FC_JUMP_ANY /* docs says set this, but I don't understand why */
-                       | R500_FC_B_OP0_DECR /* decrement branch counter if stay */
-                       | R500_FC_B_OP1_NONE /* no branch counter if stay */
-                       | R500_FC_B_POP_CNT(1)
-               ;
-               s->Code->inst[branch->Endif].inst3 = R500_FC_JUMP_ADDR(branch->Endif + 1);
 
                s->CurrentBranchDepth--;
-       } else {
+               break;
+       default:
                rc_error(s->C, "%s: unknown opcode %s\n", __FUNCTION__, rc_get_opcode_info(inst->U.I.Opcode)->Name);
        }
 }
@@ -486,6 +544,10 @@ void r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compi
                code->inst[ip].inst0 = R500_INST_TYPE_OUT | R500_INST_TEX_SEM_WAIT;
        }
 
+       /* Use FULL flow control mode if branches are nested deep enough.
+        * We don not need to enable FULL flow control mode for loops, becasue
+        * we aren't using the hardware loop instructions.
+        */
        if (s.MaxBranchDepth >= 4) {
                if (code->max_temp_idx < 1)
                        code->max_temp_idx = 1;
index 1979e7e4e49707f79c5549207dfe63acb82adb5a..d03689763bc156330e0630d5ef72f9d4220684fd 100644 (file)
@@ -235,8 +235,11 @@ struct rX00_fragment_program_code {
 };
 
 
-#define VSF_MAX_FRAGMENT_LENGTH (255*4)
-#define VSF_MAX_FRAGMENT_TEMPS (14)
+#define R300_VS_MAX_ALU                256
+#define R300_VS_MAX_ALU_DWORDS  (R300_VS_MAX_ALU * 4)
+#define R500_VS_MAX_ALU                1024
+#define R500_VS_MAX_ALU_DWORDS  (R500_VS_MAX_ALU * 4)
+#define R300_VS_MAX_TEMPS      32
 
 #define VSF_MAX_INPUTS 32
 #define VSF_MAX_OUTPUTS 32
@@ -244,8 +247,8 @@ struct rX00_fragment_program_code {
 struct r300_vertex_program_code {
        int length;
        union {
-               uint32_t d[VSF_MAX_FRAGMENT_LENGTH];
-               float f[VSF_MAX_FRAGMENT_LENGTH];
+               uint32_t d[R500_VS_MAX_ALU_DWORDS];
+               float f[R500_VS_MAX_ALU_DWORDS];
        } body;
 
        int pos_end;
index e3c2c83c0cfba29da029b589f4a0f659f84d2799..fbb4235c223a23d10dd0174f3f41e9ff20e2b940 100644 (file)
@@ -202,32 +202,65 @@ void rc_dataflow_deadcode(struct radeon_compiler * c, rc_dataflow_mark_outputs_f
            inst = inst->Prev) {
                const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
 
-               if (opcode->IsFlowControl) {
-                       if (opcode->Opcode == RC_OPCODE_ENDIF) {
-                               push_branch(&s);
-                       } else {
-                               if (s.BranchStackSize) {
-                                       struct branchinfo * branch = &s.BranchStack[s.BranchStackSize-1];
-
-                                       if (opcode->Opcode == RC_OPCODE_IF) {
-                                               or_updatemasks(&s.R,
-                                                               &s.R,
-                                                               branch->HaveElse ? &branch->StoreElse : &branch->StoreEndif);
-
-                                               s.BranchStackSize--;
-                                       } else if (opcode->Opcode == RC_OPCODE_ELSE) {
-                                               if (branch->HaveElse) {
-                                                       rc_error(c, "%s: Multiple ELSE for one IF/ENDIF\n", __FUNCTION__);
-                                               } else {
-                                                       memcpy(&branch->StoreElse, &s.R, sizeof(s.R));
-                                                       memcpy(&s.R, &branch->StoreEndif, sizeof(s.R));
-                                                       branch->HaveElse = 1;
-                                               }
+               switch(opcode->Opcode){
+               /* Mark all sources in the loop body as used before doing
+                * normal deadcode analysis.  This is probably not optimal.
+                */
+               case RC_OPCODE_ENDLOOP:
+               {
+                       int endloops = 1;
+                       struct rc_instruction *ptr;
+                       for(ptr = inst->Prev; endloops > 0; ptr = ptr->Prev){
+                               opcode = rc_get_opcode_info(ptr->U.I.Opcode);
+                               if(ptr->U.I.Opcode == RC_OPCODE_BGNLOOP){
+                                       endloops--;
+                                       continue;
+                               }
+                               if(ptr->U.I.Opcode == RC_OPCODE_ENDLOOP){
+                                       endloops++;
+                                       continue;
+                               }
+                               if(opcode->HasDstReg){
+                                       int src = 0;
+                                       unsigned int srcmasks[3];
+                                       rc_compute_sources_for_writemask(ptr,
+                                               ptr->U.I.DstReg.WriteMask, srcmasks);
+                                       for(src=0; src < opcode->NumSrcRegs; src++){
+                                               mark_used(&s,
+                                                       ptr->U.I.SrcReg[src].File,
+                                                       ptr->U.I.SrcReg[src].Index,
+                                                       srcmasks[src]);
+                                       }
+                               }
+                       }
+                       break;
+               }
+               case RC_OPCODE_CONTINUE:
+               case RC_OPCODE_BRK:
+               case RC_OPCODE_BGNLOOP:
+                       break;
+               case RC_OPCODE_ENDIF:
+                       push_branch(&s);
+                       break;
+               default:
+                       if (opcode->IsFlowControl && s.BranchStackSize) {
+                               struct branchinfo * branch = &s.BranchStack[s.BranchStackSize-1];
+                               if (opcode->Opcode == RC_OPCODE_IF) {
+                                       or_updatemasks(&s.R,
+                                                       &s.R,
+                                                       branch->HaveElse ? &branch->StoreElse : &branch->StoreEndif);
+
+                                       s.BranchStackSize--;
+                               } else if (opcode->Opcode == RC_OPCODE_ELSE) {
+                                       if (branch->HaveElse) {
+                                               rc_error(c, "%s: Multiple ELSE for one IF/ENDIF\n", __FUNCTION__);
                                        } else {
-                                               rc_error(c, "%s: Unhandled control flow instruction %s\n", __FUNCTION__, opcode->Name);
+                                               memcpy(&branch->StoreElse, &s.R, sizeof(s.R));
+                                               memcpy(&s.R, &branch->StoreEndif, sizeof(s.R));
+                                               branch->HaveElse = 1;
                                        }
                                } else {
-                                       rc_error(c, "%s: Unexpected control flow instruction\n", __FUNCTION__);
+                                       rc_error(c, "%s: Unhandled control flow instruction %s\n", __FUNCTION__, opcode->Name);
                                }
                        }
                }
index 4c5d29f42170ed3cdf5217f72112fa1d937dbbc8..131e9e7436d8eeddcd194448f4cdd915601f495f 100644 (file)
 
 #define DBG(...) do { if (VERBOSE) fprintf(stderr, __VA_ARGS__); } while(0)
 
-struct emulate_loop_state {
-       struct radeon_compiler * C;
-       struct loop_info * Loops;
-       unsigned int LoopCount;
-       unsigned int LoopReserved;
-};
-
-struct loop_info {
-       struct rc_instruction * BeginLoop;
-       struct rc_instruction * Cond;
-       struct rc_instruction * If;
-       struct rc_instruction * Brk;
-       struct rc_instruction * EndIf;
-       struct rc_instruction * EndLoop;
-};
-
 struct const_value {
        
        struct radeon_compiler * C;
@@ -94,22 +78,13 @@ static int src_reg_is_immediate(struct rc_src_register * src,
        c->Program.Constants.Constants[src->Index].Type==RC_CONSTANT_IMMEDIATE;
 }
 
-static unsigned int loop_count_instructions(struct loop_info * loop)
+static unsigned int loop_calc_iterations(struct emulate_loop_state *s, 
+                       struct loop_info * loop, unsigned int max_instructions)
 {
-       unsigned int count = 0;
-       struct rc_instruction * inst = loop->BeginLoop->Next;
-       while(inst != loop->EndLoop){
-               count++;
-               inst = inst->Next;
-       }
-       return count;
-}
-
-static unsigned int loop_calc_iterations(struct loop_info * loop,
-               unsigned int loop_count, unsigned int max_instructions)
-{
-       unsigned int icount = loop_count_instructions(loop);
-       return max_instructions / (loop_count * icount);
+       unsigned int total_i = rc_recompute_ips(s->C);
+       unsigned int loop_i = (loop->EndLoop->IP - loop->BeginLoop->IP) - 1;
+       /* +1 because the program already has one iteration of the loop. */
+       return 1 + ((max_instructions - total_i) / (s->LoopCount * loop_i));
 }
 
 static void loop_unroll(struct emulate_loop_state * s,
@@ -214,8 +189,7 @@ static void get_incr_amount(void * data, struct rc_instruction * inst,
 }
 
 static int transform_const_loop(struct emulate_loop_state * s,
-                                               struct loop_info * loop,
-                                               struct rc_instruction * cond)
+                                               struct loop_info * loop)
 {
        int end_loops = 1;
        int iterations;
@@ -228,13 +202,13 @@ static int transform_const_loop(struct emulate_loop_state * s,
 
        /* Find the counter and the upper limit */
        
-       if(src_reg_is_immediate(&cond->U.I.SrcReg[0], s->C)){
-               limit = &cond->U.I.SrcReg[0];
-               counter = &cond->U.I.SrcReg[1];
+       if(src_reg_is_immediate(&loop->Cond->U.I.SrcReg[0], s->C)){
+               limit = &loop->Cond->U.I.SrcReg[0];
+               counter = &loop->Cond->U.I.SrcReg[1];
        }
-       else if(src_reg_is_immediate(&cond->U.I.SrcReg[1], s->C)){
-               limit = &cond->U.I.SrcReg[1];
-               counter = &cond->U.I.SrcReg[0];
+       else if(src_reg_is_immediate(&loop->Cond->U.I.SrcReg[1], s->C)){
+               limit = &loop->Cond->U.I.SrcReg[1];
+               counter = &loop->Cond->U.I.SrcReg[0];
        }
        else{
                DBG("No constant limit.\n");
@@ -293,8 +267,22 @@ static int transform_const_loop(struct emulate_loop_state * s,
         * simple, since we only support increment and decrement loops.
         */
        limit_value = get_constant_value(s->C, limit, 0);
-       iterations = (int) ((limit_value - counter_value.Value) /
+       DBG("Limit is %f.\n", limit_value);
+       switch(loop->Cond->U.I.Opcode){
+       case RC_OPCODE_SGT:
+       case RC_OPCODE_SLT:
+               iterations = (int) ceilf((limit_value - counter_value.Value) /
                                                        count_inst.Amount);
+               break;
+
+       case RC_OPCODE_SLE:
+       case RC_OPCODE_SGE:
+               iterations = (int) floorf((limit_value - counter_value.Value) /
+                                                       count_inst.Amount) + 1;
+               break;
+       default:
+               return 0;
+       }
 
        DBG("Loop will have %d iterations.\n", iterations);
        
@@ -414,7 +402,7 @@ static struct rc_instruction * transform_loop(struct emulate_loop_state * s,
        }
        
        /* Check if the number of loops is known at compile time. */
-       if(transform_const_loop(s, loop, ptr)){
+       if(transform_const_loop(s, loop)){
                return loop->BeginLoop->Next;
        }
 
@@ -425,9 +413,14 @@ static struct rc_instruction * transform_loop(struct emulate_loop_state * s,
        return loop->EndLoop;
 }
 
-static void rc_transform_loops(struct emulate_loop_state * s)
+void rc_transform_unroll_loops(struct radeon_compiler *c,
+                                       struct emulate_loop_state * s)
 {
-       struct rc_instruction * ptr = s->C->Program.Instructions.Next;
+       struct rc_instruction * ptr;
+       
+       memset(s, 0, sizeof(struct emulate_loop_state));
+       s->C = c;
+       ptr = s->C->Program.Instructions.Next;
        while(ptr != &s->C->Program.Instructions) {
                if(ptr->Type == RC_INSTRUCTION_NORMAL &&
                                        ptr->U.I.Opcode == RC_OPCODE_BGNLOOP){
@@ -440,7 +433,7 @@ static void rc_transform_loops(struct emulate_loop_state * s)
        }
 }
 
-static void rc_unroll_loops(struct emulate_loop_state *s,
+void rc_emulate_loops(struct emulate_loop_state *s,
                                                unsigned int max_instructions)
 {
        int i;
@@ -451,24 +444,8 @@ static void rc_unroll_loops(struct emulate_loop_state *s,
                if(!s->Loops[i].EndLoop){
                        continue;
                }
-               unsigned int iterations = loop_calc_iterations(&s->Loops[i],
-                                               s->LoopCount, max_instructions);
+               unsigned int iterations = loop_calc_iterations(s, &s->Loops[i],
+                                                       max_instructions);
                loop_unroll(s, &s->Loops[i], iterations);
        }
 }
-
-void rc_emulate_loops(struct radeon_compiler *c, unsigned int max_instructions)
-{
-       struct emulate_loop_state s;
-
-       memset(&s, 0, sizeof(struct emulate_loop_state));
-       s.C = c;
-
-       /* We may need to move these two operations to r3xx_(vert|frag)prog.c
-        * and run the optimization passes between them in order to increase
-        * the number of unrolls we can do for each loop.
-        */
-       rc_transform_loops(&s);
-       
-       rc_unroll_loops(&s, max_instructions);
-}
index ddcf1c0fabee71e5ec2e93799b04865d636ec1ce..7748813c4eb33b0e0309273f87f32b65860c0344 100644 (file)
@@ -7,6 +7,26 @@
 
 struct radeon_compiler;
 
-void rc_emulate_loops(struct radeon_compiler *c, unsigned int max_instructions);
+struct loop_info {
+       struct rc_instruction * BeginLoop;
+       struct rc_instruction * Cond;
+       struct rc_instruction * If;
+       struct rc_instruction * Brk;
+       struct rc_instruction * EndIf;
+       struct rc_instruction * EndLoop;
+};
+
+struct emulate_loop_state {
+       struct radeon_compiler * C;
+       struct loop_info * Loops;
+       unsigned int LoopCount;
+       unsigned int LoopReserved;
+};
+
+void rc_transform_unroll_loops(struct radeon_compiler *c,
+                                       struct emulate_loop_state * s);
+
+void rc_emulate_loops(struct emulate_loop_state *s,
+                                       unsigned int max_instructions);
 
 #endif /* RADEON_EMULATE_LOOPS_H */
index 1dc16855dc13a7e5bc7df35718e46a1da549342f..04f234f11d8cc4936a9a4f08bf0ca8a6d411dc9c 100644 (file)
@@ -385,6 +385,12 @@ struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE] = {
                .IsFlowControl = 1,
                .NumSrcRegs = 0,
        },
+       {
+               .Opcode = RC_OPCODE_CONTINUE,
+               .Name = "CONTINUE",
+               .IsFlowControl = 1,
+               .NumSrcRegs = 0
+       },
        {
                .Opcode = RC_OPCODE_REPL_ALPHA,
                .Name = "REPL_ALPHA",
@@ -393,6 +399,10 @@ struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE] = {
        {
                .Opcode = RC_OPCODE_BEGIN_TEX,
                .Name = "BEGIN_TEX"
+       },
+       {
+               .Opcode = RC_OPCODE_KILP,
+               .Name = "KILP",
        }
 };
 
index 91c82ac0890e0a6124d4891e8e063d4f10f8a589..8b9fa07dde2c735f5247f739251eeb28791af6f8 100644 (file)
@@ -187,6 +187,8 @@ typedef enum {
 
        RC_OPCODE_ENDLOOP,
 
+       RC_OPCODE_CONTINUE,
+
        /** special instruction, used in R300-R500 fragment program pair instructions
         * indicates that the result of the alpha operation shall be replicated
         * across all other channels */
@@ -197,6 +199,9 @@ typedef enum {
         * can run simultaneously. */
        RC_OPCODE_BEGIN_TEX,
 
+       /** Stop execution of the shader (GLSL discard) */
+       RC_OPCODE_KILP,
+
        MAX_RC_OPCODE
 } rc_opcode;
 
index 21d72108886358044a4492a47bcc0434726f0c4b..eca065153678f7e58c174ae33ecba82c3c2fd7cc 100644 (file)
@@ -75,6 +75,15 @@ struct peephole_state {
        int BranchDepth;
 };
 
+/**
+ * This is a callback function that is meant to be passed to
+ * rc_for_all_reads_mask.  This function will be called once for each source
+ * register in inst.
+ * @param inst The instruction that the source register belongs to.
+ * @param file The register file of the source register.
+ * @param index The index of the source register.
+ * @param mask The components of the source register that are being read from.
+ */
 static void peephole_scan_read(void * data, struct rc_instruction * inst,
                rc_register_file file, unsigned int index, unsigned int mask)
 {
@@ -153,6 +162,11 @@ static void peephole(struct radeon_compiler * c, struct rc_instruction * inst_mo
        for(struct rc_instruction * inst = inst_mov->Next;
            inst != &c->Program.Instructions;
            inst = inst->Next) {
+               /* XXX In the future we might be able to make the optimizer
+                * smart enough to handle loops. */
+               if(inst->U.I.Opcode == RC_OPCODE_BGNLOOP){
+                       return;
+               }
                rc_for_all_reads_mask(inst, peephole_scan_read, &s);
                rc_for_all_writes_mask(inst, peephole_scan_write, &s);
                if (s.Conflict)
@@ -161,7 +175,8 @@ static void peephole(struct radeon_compiler * c, struct rc_instruction * inst_mo
                if (s.BranchDepth >= 0) {
                        if (inst->U.I.Opcode == RC_OPCODE_IF) {
                                s.BranchDepth++;
-                       } else if (inst->U.I.Opcode == RC_OPCODE_ENDIF) {
+                       } else if (inst->U.I.Opcode == RC_OPCODE_ENDIF
+                               || inst->U.I.Opcode == RC_OPCODE_ELSE) {
                                s.BranchDepth--;
                                if (s.BranchDepth < 0) {
                                        s.DefinedMask &= ~s.MovMask;
@@ -208,7 +223,8 @@ static void peephole(struct radeon_compiler * c, struct rc_instruction * inst_mo
                if (s.BranchDepth >= 0) {
                        if (inst->U.I.Opcode == RC_OPCODE_IF) {
                                s.BranchDepth++;
-                       } else if (inst->U.I.Opcode == RC_OPCODE_ENDIF) {
+                       } else if (inst->U.I.Opcode == RC_OPCODE_ENDIF
+                               || inst->U.I.Opcode == RC_OPCODE_ELSE) {
                                s.BranchDepth--;
                                if (s.BranchDepth < 0)
                                        break; /* no more readers after this point */
index a279549ff8940fdcaff9faf19aaa850c46901f05..fc540496c415c9d9da840466e0a80f4cce94fb36 100644 (file)
@@ -141,12 +141,28 @@ static void add_inst_to_list(struct schedule_instruction ** list, struct schedul
        *list = inst;
 }
 
+static void add_inst_to_list_end(struct schedule_instruction ** list,
+                                       struct schedule_instruction * inst)
+{
+       if(!*list){
+               *list = inst;
+       }else{
+               struct schedule_instruction * temp = *list;
+               while(temp->NextReady){
+                       temp = temp->NextReady;
+               }
+               temp->NextReady = inst;
+       }
+}
+
 static void instruction_ready(struct schedule_state * s, struct schedule_instruction * sinst)
 {
        DBG("%i is now ready\n", sinst->Instruction->IP);
 
+       /* Adding Ready TEX instructions to the end of the "Ready List" helps
+        * us emit TEX instructions in blocks without losing our place. */
        if (sinst->Instruction->Type == RC_INSTRUCTION_NORMAL)
-               add_inst_to_list(&s->ReadyTEX, sinst);
+               add_inst_to_list_end(&s->ReadyTEX, sinst);
        else if (sinst->Instruction->U.P.Alpha.Opcode == RC_OPCODE_NOP)
                add_inst_to_list(&s->ReadyRGB, sinst);
        else if (sinst->Instruction->U.P.RGB.Opcode == RC_OPCODE_NOP)
@@ -163,11 +179,14 @@ static void decrease_dependencies(struct schedule_state * s, struct schedule_ins
                instruction_ready(s, sinst);
 }
 
-static void commit_instruction(struct schedule_state * s, struct schedule_instruction * sinst)
-{
-       DBG("%i: commit\n", sinst->Instruction->IP);
-
-       for(unsigned int i = 0; i < sinst->NumReadValues; ++i) {
+/**
+ * This function decreases the dependencies of the next instruction that
+ * wants to write to each of sinst's read values.
+ */
+static void commit_update_reads(struct schedule_state * s,
+                                       struct schedule_instruction * sinst){
+       unsigned int i;
+       for(i = 0; i < sinst->NumReadValues; ++i) {
                struct reg_value * v = sinst->ReadValues[i];
                assert(v->NumReaders > 0);
                v->NumReaders--;
@@ -176,8 +195,12 @@ static void commit_instruction(struct schedule_state * s, struct schedule_instru
                                decrease_dependencies(s, v->Next->Writer);
                }
        }
+}
 
-       for(unsigned int i = 0; i < sinst->NumWriteValues; ++i) {
+static void commit_update_writes(struct schedule_state * s,
+                                       struct schedule_instruction * sinst){
+       unsigned int i;
+       for(i = 0; i < sinst->NumWriteValues; ++i) {
                struct reg_value * v = sinst->WriteValues[i];
                if (v->NumReaders) {
                        for(struct reg_value_reader * r = v->Readers; r; r = r->Next) {
@@ -196,6 +219,15 @@ static void commit_instruction(struct schedule_state * s, struct schedule_instru
        }
 }
 
+static void commit_alu_instruction(struct schedule_state * s, struct schedule_instruction * sinst)
+{
+       DBG("%i: commit\n", sinst->Instruction->IP);
+
+       commit_update_reads(s, sinst);
+
+       commit_update_writes(s, sinst);
+}
+
 /**
  * Emit all ready texture instructions in a single block.
  *
@@ -208,21 +240,37 @@ static void emit_all_tex(struct schedule_state * s, struct rc_instruction * befo
 
        assert(s->ReadyTEX);
 
-       /* Don't let the ready list change under us! */
-       readytex = s->ReadyTEX;
-       s->ReadyTEX = 0;
-
        /* Node marker for R300 */
        struct rc_instruction * inst_begin = rc_insert_new_instruction(s->C, before->Prev);
        inst_begin->U.I.Opcode = RC_OPCODE_BEGIN_TEX;
 
        /* Link texture instructions back in */
+       readytex = s->ReadyTEX;
        while(readytex) {
-               struct schedule_instruction * tex = readytex;
+               rc_insert_instruction(before->Prev, readytex->Instruction);
+               DBG("%i: commit TEX reads\n", readytex->Instruction->IP);
+
+               /* All of the TEX instructions in the same TEX block have
+                * their source registers read from before any of the
+                * instructions in that block write to their destination
+                * registers.  This means that when we commit a TEX
+                * instruction, any other TEX instruction that wants to write
+                * to one of the committed instruction's source register can be
+                * marked as ready and should be emitted in the same TEX
+                * block. This prevents the following sequence from being
+                * emitted in two different TEX blocks:
+                * 0: TEX temp[0].xyz, temp[1].xy__, 2D[0];
+                * 1: TEX temp[1].xyz, temp[2].xy__, 2D[0];
+                */
+               commit_update_reads(s, readytex);
+               readytex = readytex->NextReady;
+       }
+       readytex = s->ReadyTEX;
+       s->ReadyTEX = 0;
+       while(readytex){
+               DBG("%i: commit TEX writes\n", readytex->Instruction->IP);
+               commit_update_writes(s, readytex);
                readytex = readytex->NextReady;
-
-               rc_insert_instruction(before->Prev, tex->Instruction);
-               commit_instruction(s, tex);
        }
 }
 
@@ -328,7 +376,7 @@ static void emit_one_alu(struct schedule_state *s, struct rc_instruction * befor
                }
 
                rc_insert_instruction(before->Prev, sinst->Instruction);
-               commit_instruction(s, sinst);
+               commit_alu_instruction(s, sinst);
        } else {
                struct schedule_instruction **prgb;
                struct schedule_instruction **palpha;
@@ -346,8 +394,8 @@ static void emit_one_alu(struct schedule_state *s, struct rc_instruction * befor
                                *prgb = (*prgb)->NextReady;
                                *palpha = (*palpha)->NextReady;
                                rc_insert_instruction(before->Prev, psirgb->Instruction);
-                               commit_instruction(s, psirgb);
-                               commit_instruction(s, psialpha);
+                               commit_alu_instruction(s, psirgb);
+                               commit_alu_instruction(s, psialpha);
                                goto success;
                        }
                }
@@ -357,7 +405,7 @@ static void emit_one_alu(struct schedule_state *s, struct rc_instruction * befor
                s->ReadyRGB = s->ReadyRGB->NextReady;
 
                rc_insert_instruction(before->Prev, sinst->Instruction);
-               commit_instruction(s, sinst);
+               commit_alu_instruction(s, sinst);
        success: ;
        }
 }
index c922d3d9a448c367c6cfafde010429323ec1b0d0..3cc28972934d1d3143555ca01287384e08a957cc 100644 (file)
@@ -973,3 +973,32 @@ int radeonTransformDeriv(struct radeon_compiler* c,
 
        return 1;
 }
+
+/**
+ * IF Temp[0].x -\
+ * KILP         - > KIL -abs(Temp[0].x)
+ * ENDIF        -/
+ *
+ * This needs to be done in its own pass, because it modifies the instructions
+ * before and after KILP.
+ */
+void radeonTransformKILP(struct radeon_compiler * c)
+{
+       struct rc_instruction * inst;
+       for (inst = c->Program.Instructions.Next;
+                       inst != &c->Program.Instructions; inst = inst->Next) {
+
+               if (inst->U.I.Opcode != RC_OPCODE_KILP
+                       || inst->Prev->U.I.Opcode != RC_OPCODE_IF
+                       || inst->Next->U.I.Opcode != RC_OPCODE_ENDIF) {
+                       continue;
+               }
+               inst->U.I.Opcode = RC_OPCODE_KIL;
+               inst->U.I.SrcReg[0] = negate(absolute(inst->Prev->U.I.SrcReg[0]));
+
+               /* Remove IF */
+               rc_remove_instruction(inst->Prev);
+               /* Remove ENDIF */
+               rc_remove_instruction(inst->Next);
+       }
+}
index 77d444476f2959d46dfc52f3f49b5732d79b6850..e6e2cc20c5ab42657931432d2067c8c1afc542b8 100644 (file)
@@ -60,4 +60,6 @@ int radeonTransformDeriv(
        struct rc_instruction * inst,
        void*);
 
+void radeonTransformKILP(struct radeon_compiler * c);
+
 #endif /* __RADEON_PROGRAM_ALU_H_ */
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.c b/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.c
new file mode 100644 (file)
index 0000000..31c9866
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2010 Tom Stellard <tstellar@gmail.com>
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/**
+ * \file
+ */
+
+#include "radeon_rename_regs.h"
+
+#include "radeon_compiler.h"
+#include "radeon_dataflow.h"
+
+struct reg_rename {
+       int old_index;
+       int new_index;
+       int temp_index;
+};
+
+static void rename_reg(void * data, struct rc_instruction * inst,
+                       rc_register_file * file, unsigned int * index)
+{
+       struct reg_rename *r = data;
+
+       if(r->old_index == *index && *file == RC_FILE_TEMPORARY) {
+               *index = r->new_index;
+       }
+       else if(r->new_index == *index && *file == RC_FILE_TEMPORARY) {
+               *index = r->temp_index;
+       }
+}
+
+static void rename_all(
+       struct radeon_compiler *c,
+       struct rc_instruction * start,
+       unsigned int old,
+       unsigned int new,
+       unsigned int temp)
+{
+       struct rc_instruction * inst;
+       struct reg_rename r;
+       r.old_index = old;
+       r.new_index = new;
+       r.temp_index = temp;
+       for(inst = start; inst != &c->Program.Instructions;
+                                               inst = inst->Next) {
+               rc_remap_registers(inst, rename_reg, &r);
+       }
+}
+
+/**
+ * This function renames registers in an attempt to get the code close to
+ * SSA form.  After this function has completed, most of the register are only
+ * written to one time, with a few exceptions.  For example, this block of code
+ * will not be modified by this function:
+ * Mov Temp[0].x Const[0].x
+ * Mov Temp[0].y Const[0].y
+ * Basically, destination registers will be renamed if:
+ * 1. There have been no previous writes to that register
+ * or
+ * 2. If the instruction is writting to the exact components (no more, no less)
+ * of a register that has been written to by previous instructions.
+ *
+ * This function assumes all the instructions are still of type
+ * RC_INSTRUCTION_NORMAL.
+ */
+void rc_rename_regs(struct radeon_compiler * c)
+{
+       unsigned int cur_index = 0;
+       unsigned int icount;
+       struct rc_instruction * inst;
+       unsigned int * masks;
+
+       /* The number of instructions in the program is also the maximum
+        * number of temp registers that could potentially be used. */
+       icount = rc_recompute_ips(c);
+       masks = memory_pool_malloc(&c->Pool, icount * sizeof(unsigned int));
+       memset(masks, 0, icount * sizeof(unsigned int));
+
+       for(inst = c->Program.Instructions.Next;
+                                       inst != &c->Program.Instructions;
+                                       inst = inst->Next) {
+               const struct rc_opcode_info * info;
+               if(inst->Type != RC_INSTRUCTION_NORMAL) {
+                       rc_error(c, "%s only works with normal instructions.",
+                                                               __FUNCTION__);
+                       return;
+               }
+               unsigned int old_index, temp_index;
+               struct rc_dst_register * dst = &inst->U.I.DstReg;
+               info = rc_get_opcode_info(inst->U.I.Opcode);
+               if(!info->HasDstReg || dst->File != RC_FILE_TEMPORARY) {
+                       continue;
+               }
+               if(dst->Index >= icount || !masks[dst->Index] ||
+                                       masks[dst->Index] == dst->WriteMask) {
+                       old_index = dst->Index;
+                       /* We need to set dst->Index here so get free temporary
+                        * will work. */
+                       dst->Index = cur_index++;
+                       temp_index = rc_find_free_temporary(c);
+                       rename_all(c, inst->Next, old_index,
+                                               dst->Index, temp_index);
+               }
+               assert(dst->Index < icount);
+               masks[dst->Index] |= dst->WriteMask;
+       }
+}
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.h b/src/mesa/drivers/dri/r300/compiler/radeon_rename_regs.h
new file mode 100644 (file)
index 0000000..4323b99
--- /dev/null
@@ -0,0 +1,9 @@
+
+#ifndef RADEON_RENAME_REGS_H
+#define RADEON_RENAME_REGS_H
+
+struct radeon_compiler;
+
+void rc_rename_regs(struct radeon_compiler * c);
+
+#endif /* RADEON_RENAME_REGS_H */
index 6992ca59dbf29d9152b3e2131eb83c096f05f740..e4b302bbad9d177620ba69f3128de65f0f1f6d40 100644 (file)
@@ -376,13 +376,12 @@ static void r300InitConstValues(GLcontext *ctx, radeonScreenPtr screen)
        ctx->Const.MaxDrawBuffers = 1;
        ctx->Const.MaxColorAttachments = 1;
 
-       /* currently bogus data */
        if (r300->options.hw_tcl_enabled) {
-               ctx->Const.VertexProgram.MaxNativeInstructions = VSF_MAX_FRAGMENT_LENGTH / 4;
-               ctx->Const.VertexProgram.MaxNativeAluInstructions = VSF_MAX_FRAGMENT_LENGTH / 4;
-               ctx->Const.VertexProgram.MaxNativeAttribs = 16; /* r420 */
+               ctx->Const.VertexProgram.MaxNativeInstructions = 255;
+               ctx->Const.VertexProgram.MaxNativeAluInstructions = 255;
+               ctx->Const.VertexProgram.MaxNativeAttribs = 16;
                ctx->Const.VertexProgram.MaxNativeTemps = 32;
-               ctx->Const.VertexProgram.MaxNativeParameters = 256;     /* r420 */
+               ctx->Const.VertexProgram.MaxNativeParameters = 256;
                ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
        }
 
index fbb609b9f618a401956e94fd938b1204f95f5b21..99540e3354fd8dea5779bcc252402f1f4920e888 100644 (file)
@@ -43,7 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "radeon_common.h"
 
 #include "main/mtypes.h"
-#include "shader/prog_instruction.h"
+#include "program/prog_instruction.h"
 #include "compiler/radeon_code.h"
 
 struct r300_context;
index 282c0e18bca490045b8473bbb62dcff14639c1da..5ae9f49840b64eb86183e6d4f337f355c6bda03d 100644 (file)
@@ -523,8 +523,7 @@ static void r300AllocDmaRegions(GLcontext *ctx, const struct gl_client_array *in
                        r300ConvertAttrib(ctx, count, input[i], &vbuf->attribs[index]);
                } else {
                        if (input[i]->BufferObj->Name) {
-                               if (stride % 4 != 0) {
-                                       assert(((intptr_t) input[i]->Ptr) % input[i]->StrideB == 0);
+                               if (stride % 4 != 0 || (intptr_t)input[i]->Ptr % 4 != 0) {
                                        r300AlignDataToDword(ctx, input[i], count, &vbuf->attribs[index]);
                                        vbuf->attribs[index].is_named_bo = GL_FALSE;
                                } else {
index 7be2f74b5b2857132d9f6a9f5f07c2e9cfc34fd4..95f4306f604fcf3be422df6544252bac9f0e6ee1 100644 (file)
@@ -38,8 +38,8 @@
 
 #include "r300_fragprog_common.h"
 
-#include "shader/prog_parameter.h"
-#include "shader/prog_print.h"
+#include "program/prog_parameter.h"
+#include "program/prog_print.h"
 
 #include "compiler/radeon_compiler.h"
 
index ac93563ed9e1438cd5e5c0cccf16c86615f040e2..f25264b6f2d7d5a2768ec0a72a1c971011b54c10 100644 (file)
@@ -3066,8 +3066,8 @@ enum {
 #   define R500_FC_B_OP0_NONE                          (0 << 24)
 #   define R500_FC_B_OP0_DECR                          (1 << 24)
 #   define R500_FC_B_OP0_INCR                          (2 << 24)
-#   define R500_FC_B_OP1_DECR                          (0 << 26)
-#   define R500_FC_B_OP1_NONE                          (1 << 26)
+#   define R500_FC_B_OP1_NONE                          (0 << 26)
+#   define R500_FC_B_OP1_DECR                          (1 << 26)
 #   define R500_FC_B_OP1_INCR                          (2 << 26)
 #   define R500_FC_IGNORE_UNCOVERED                    (1 << 28)
 #define R500_US_FC_INT_CONST_0                         0x4c00
index 9c24166ec5b1f623aa0ccdf70b1763deb731d37f..a9bddf057793bf9ceb0ad01910236094070ee03a 100644 (file)
@@ -27,7 +27,7 @@
 
 #include "main/glheader.h"
 
-#include "shader/program.h"
+#include "program/program.h"
 #include "tnl/tnl.h"
 #include "r300_context.h"
 #include "r300_fragprog_common.h"
index fa33be4998993c083ee7d7b439ce7bfe3f38cebf..0113eecaa3a9410718237c9de95e4cfeefcbd968 100644 (file)
@@ -49,8 +49,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "drivers/common/meta.h"
 #include "swrast/swrast.h"
 #include "swrast_setup/swrast_setup.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_statevars.h"
+#include "program/prog_parameter.h"
+#include "program/prog_statevars.h"
 #include "vbo/vbo.h"
 #include "tnl/tnl.h"
 
index a1fe3780294e5c6c04d113057531f80aceb397f6..67d8b2b32867957ccf3acd4f241b6ed92ed228cc 100644 (file)
@@ -31,12 +31,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/glheader.h"
 #include "main/macros.h"
 #include "main/enums.h"
-#include "shader/program.h"
-#include "shader/programopt.h"
-#include "shader/prog_instruction.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_print.h"
-#include "shader/prog_statevars.h"
+#include "program/program.h"
+#include "program/programopt.h"
+#include "program/prog_instruction.h"
+#include "program/prog_parameter.h"
+#include "program/prog_print.h"
+#include "program/prog_statevars.h"
 #include "tnl/tnl.h"
 
 #include "compiler/radeon_compiler.h"
index 9f9dec840b41cb18e2caa5843fb8f5035ac4012a..471a3723cb904aa2a86dde0649dd107be5cb7ef2 100644 (file)
@@ -28,8 +28,8 @@
 #include "radeon_mesa_to_rc.h"
 
 #include "main/mtypes.h"
-#include "shader/prog_instruction.h"
-#include "shader/prog_parameter.h"
+#include "program/prog_instruction.h"
+#include "program/prog_parameter.h"
 
 #include "compiler/radeon_compiler.h"
 #include "compiler/radeon_program.h"
index afe2d55dc7c13c0f41058d06ff4a15f481cf105d..8013553f679eeb0f03d4301b52ef4af5f8ee37d9 100644 (file)
@@ -46,7 +46,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "r600_context.h"
 #include "radeon_reg.h"
 #include "r600_cmdbuf.h"
-#include "r600_emit.h"
 #include "radeon_bocs_wrapper.h"
 #include "radeon_reg.h"
 
index dff000969993c1b87a1e6ac390fd037eb7c04ffb..78fccd0b6010e431de64c2ac09683d7346aa5d3b 100644 (file)
@@ -37,7 +37,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define __R600_CMDBUF_H__
 
 #include "r600_context.h"
-#include "r600_emit.h"
 
 #define RADEON_CP_PACKET3_NOP                       0xC0001000
 #define RADEON_CP_PACKET3_NEXT_CHAR                 0xC0001900
index f4aed4e87fdd3ae992d398a96ee6d47cfcd65bde..84d9d423124bafbd67fd5bd285c526182d73ed4b 100644 (file)
@@ -59,7 +59,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "radeon_buffer_objects.h"
 #include "radeon_span.h"
 #include "r600_cmdbuf.h"
-#include "r600_emit.h"
 #include "radeon_bocs_wrapper.h"
 #include "radeon_queryobj.h"
 #include "r600_blit.h"
index de5c5d89fead7559a1564b12bac8f65de98f49b2..99a33df4fcb3c6cfbdf348f2ec969ce97af7e303 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "main/mtypes.h"
 #include "main/imports.h"
-#include "shader/prog_parameter.h"
+#include "program/prog_parameter.h"
 
 #include "radeon_debug.h"
 #include "r600_context.h"
@@ -293,7 +293,9 @@ GLuint GetSurfaceFormat(GLenum eType, GLuint nChannels, GLuint * pClient_size)
                 case 2:
                     format = FMT_16_16; break;
                 case 3:
-                    format = FMT_16_16_16; break;
+                    /* 3 comp GL_SHORT vertex format doesnt work on r700
+                       4 somehow works, test - sauerbraten  */
+                    format = FMT_16_16_16_16; break;
                 case 4:
                     format = FMT_16_16_16_16; break;
                 default:
@@ -1262,7 +1264,7 @@ GLboolean checkop3(r700_AssemblerBase* pAsm)
            {
             if( GL_FALSE == mov_temp(pAsm, 1) )
             {
-                return 1;
+                return GL_FALSE;
             }
         }
 
index 2d3c32487e6702f8958e60cb83a0853ca5b97d8e..dbc6cdb1903ea5ab7333d6c9508dd6f1cc558d33 100644 (file)
@@ -28,7 +28,7 @@
 #define _R700_ASSEMBLER_H_
 
 #include "main/mtypes.h"
-#include "shader/prog_instruction.h"
+#include "program/prog_instruction.h"
 
 #include "r700_chip.h"
 #include "r700_shaderinst.h"
index ae249e15fd4346e3c63785270aeed2333105d2a8..0b6b72f8501737039c342d27c9c6d00045022215 100644 (file)
@@ -27,7 +27,9 @@
 #ifndef _R700_CHIP_H_
 #define _R700_CHIP_H_
 
-#include "r600_context.h"
+#include <GL/gl.h>
+
+#include "radeon_common_context.h"
 
 #include "r600_reg.h"
 #include "r600_reg_auto_r6xx.h"
index fbb808e0662e5d07719b3ad359b820c82278b702..f9d84b6ed68946ec27bda626f8e7e94fc7a25bfc 100644 (file)
 #include <math.h>
 
 #include "main/imports.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_statevars.h"
-#include "shader/program.h"
+#include "program/prog_parameter.h"
+#include "program/prog_statevars.h"
+#include "program/program.h"
 
 #include "r600_context.h"
 #include "r600_cmdbuf.h"
+#include "r600_emit.h"
 
 #include "r700_fragprog.h"
 
@@ -586,7 +587,9 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx)
         SETfield(r700->SPI_INTERP_CONTROL_0.u32All, SPI_PNT_SPRITE_SEL_T, PNT_SPRITE_OVRD_Y_shift, PNT_SPRITE_OVRD_Y_mask);
         SETfield(r700->SPI_INTERP_CONTROL_0.u32All, SPI_PNT_SPRITE_SEL_0, PNT_SPRITE_OVRD_Z_shift, PNT_SPRITE_OVRD_Z_mask);
         SETfield(r700->SPI_INTERP_CONTROL_0.u32All, SPI_PNT_SPRITE_SEL_1, PNT_SPRITE_OVRD_W_shift, PNT_SPRITE_OVRD_W_mask);
-        if(ctx->Point.SpriteOrigin == GL_LOWER_LEFT)
+        /* Like e.g. viewport and winding, point sprite coordinates are
+         * inverted when rendering to FBO. */
+        if ((ctx->Point.SpriteOrigin == GL_LOWER_LEFT) == !ctx->DrawBuffer->Name)
             SETbit(r700->SPI_INTERP_CONTROL_0.u32All, PNT_SPRITE_TOP_1_bit);
         else
             CLEARbit(r700->SPI_INTERP_CONTROL_0.u32All, PNT_SPRITE_TOP_1_bit);
index b7124e644a3a196acc7d1f48a37c6bd6a1241b42..835179251153ddc6d9019b48e9cfccac51c23613 100644 (file)
@@ -29,7 +29,7 @@
 #include "main/glheader.h"
 #include "main/imports.h"
 
-#include "shader/program.h"
+#include "program/program.h"
 #include "tnl/tnl.h"
 
 #include "r600_context.h"
index fe2e9d19749a924ccbf2acf136ca459cd0a25270..4d42133867858a5b8a31d9f5115d424d95f2b108 100644 (file)
@@ -27,7 +27,7 @@
 
 #ifndef _R700_OGLPROG_H_
 #define _R700_OGLPROG_H_
-#include "r600_context.h"
+#include "main/dd.h"
 
 extern void r700InitShaderFuncs(struct dd_function_table *functions);
 
index ac64bbf874f283063674c79bd63ee891c4a4a546..5ea8918611ca01cd8604cb825e8a256579291c14 100644 (file)
@@ -41,8 +41,8 @@
 #include "main/framebuffer.h"
 #include "drivers/common/meta.h"
 
-#include "shader/prog_parameter.h"
-#include "shader/prog_statevars.h"
+#include "program/prog_parameter.h"
+#include "program/prog_statevars.h"
 #include "vbo/vbo.h"
 
 #include "r600_context.h"
index 14dd2a5482c3b57720262afb41709c0358078917..137f3007ced30372b359c65afaf081f72cc7c66c 100644 (file)
 #include "main/mtypes.h"
 
 #include "tnl/t_context.h"
-#include "shader/program.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_statevars.h"
+#include "program/program.h"
+#include "program/prog_parameter.h"
+#include "program/prog_statevars.h"
 
 #include "radeon_debug.h"
 #include "r600_context.h"
 #include "r600_cmdbuf.h"
-#include "shader/programopt.h"
+#include "r600_emit.h"
+#include "program/programopt.h"
 
 #include "r700_debug.h"
 #include "r700_vertprog.h"
index 94f476617b6431ddb8f5827348879b57f1840746..5a7d52c4d2f2e4651eb79f06a800740794edab98 100644 (file)
@@ -300,10 +300,10 @@ void radeonDestroyContext(__DRIcontext *driContextPriv )
        _mesa_meta_free(radeon->glCtx);
 
        if (radeon == current) {
-               radeon_firevertices(radeon);
                _mesa_make_current(NULL, NULL, NULL);
        }
 
+       radeon_firevertices(radeon);
        if (!is_empty_list(&radeon->dma.reserved)) {
                rcommonFlushCmdBuf( radeon, __FUNCTION__ );
        }
index 6cd1d87de242c1dd96019586da78b2493398d78c..c877e6c1765a957a694a381f0907db610237707a 100644 (file)
@@ -602,17 +602,17 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t
                        __FUNCTION__, texObj ,t->minLod, t->maxLod);
 
        radeon_mipmap_tree *dst_miptree;
-       dst_miptree = get_biggest_matching_miptree(t, t->minLod, t->maxLod);
+       dst_miptree = get_biggest_matching_miptree(t, t->base.BaseLevel, t->base.MaxLevel);
 
+       radeon_miptree_unreference(&t->mt);
        if (!dst_miptree) {
-               radeon_miptree_unreference(&t->mt);
                radeon_try_alloc_miptree(rmesa, t);
-               dst_miptree = t->mt;
                radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
                        "%s: No matching miptree found, allocated new one %p\n",
                        __FUNCTION__, t->mt);
 
        } else {
+               radeon_miptree_reference(dst_miptree, &t->mt);
                radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
                        "%s: Using miptree %p\n", __FUNCTION__, t->mt);
        }
@@ -629,7 +629,7 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t
                                "Checking image level %d, face %d, mt %p ... ",
                                level, face, img->mt);
                        
-                       if (img->mt != dst_miptree) {
+                       if (img->mt != t->mt) {
                                radeon_print(RADEON_TEXTURE, RADEON_TRACE,
                                        "MIGRATING\n");
 
@@ -637,7 +637,7 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t
                                if (src_bo && radeon_bo_is_referenced_by_cs(src_bo, rmesa->cmdbuf.cs)) {
                                        radeon_firevertices(rmesa);
                                }
-                               migrate_image_to_miptree(dst_miptree, img, face, level);
+                               migrate_image_to_miptree(t->mt, img, face, level);
                        } else
                                radeon_print(RADEON_TEXTURE, RADEON_TRACE, "OK\n");
                }
index 4f59511a528218684bd3f3dffc2341835ee190e8..82107cc6aeb5fad49cceb6d25fa4c0248988c87d 100644 (file)
@@ -52,7 +52,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "radeon_tex.h"
 #elif defined(RADEON_R200)
 #include "r200_context.h"
-#include "r200_ioctl.h"
 #include "r200_tex.h"
 #elif defined(RADEON_R300)
 #include "r300_context.h"
@@ -338,12 +337,6 @@ static const __DRItexBufferExtension radeonTexBufferExtension = {
 #endif
 
 #if defined(RADEON_R200)
-static const __DRIallocateExtension r200AllocateExtension = {
-    { __DRI_ALLOCATE, __DRI_ALLOCATE_VERSION },
-    r200AllocateMemoryMESA,
-    r200FreeMemoryMESA,
-    r200GetMemoryOffsetMESA
-};
 
 static const __DRItexOffsetExtension r200texOffsetExtension = {
     { __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION },
@@ -1209,7 +1202,6 @@ radeonCreateScreen( __DRIscreen *sPriv )
 
    i = 0;
    screen->extensions[i++] = &driCopySubBufferExtension.base;
-   screen->extensions[i++] = &driFrameTrackingExtension.base;
    screen->extensions[i++] = &driReadDrawableExtension;
 
    if ( screen->irq != 0 ) {
@@ -1222,9 +1214,6 @@ radeonCreateScreen( __DRIscreen *sPriv )
 #endif
 
 #if defined(RADEON_R200)
-   if (IS_R200_CLASS(screen))
-      screen->extensions[i++] = &r200AllocateExtension.base;
-
    screen->extensions[i++] = &r200texOffsetExtension.base;
 #endif
 
@@ -1366,8 +1355,8 @@ radeonCreateScreen2(__DRIscreen *sPriv)
 
    i = 0;
    screen->extensions[i++] = &driCopySubBufferExtension.base;
-   screen->extensions[i++] = &driFrameTrackingExtension.base;
    screen->extensions[i++] = &driReadDrawableExtension;
+   screen->extensions[i++] = &dri2ConfigQueryExtension.base;
 
    if ( screen->irq != 0 ) {
        screen->extensions[i++] = &driSwapControlExtension.base;
@@ -1379,9 +1368,6 @@ radeonCreateScreen2(__DRIscreen *sPriv)
 #endif
 
 #if defined(RADEON_R200)
-   if (IS_R200_CLASS(screen))
-       screen->extensions[i++] = &r200AllocateExtension.base;
-
    screen->extensions[i++] = &r200TexBufferExtension.base;
 #endif
 
index 3ababb1ef53872de2bb1fca1af40169a036bb5ca..f878b48e5f9bc465266ffc382e4580b827fca4d7 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "radeon_common_context.h"
 #include "radeon_texture.h"
+#include "radeon_mipmap_tree.h"
 
 #include "main/texgetimage.h"
 
@@ -51,7 +52,15 @@ radeon_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
                  __func__, ctx, texObj, image, compressed);
 
     if (image->mt) {
+        radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
         /* Map the texture image read-only */
+        if (radeon_bo_is_referenced_by_cs(image->mt->bo, rmesa->cmdbuf.cs)) {
+            radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
+                "%s: called for texture that is queued for GPU processing\n",
+                __func__);
+            radeon_firevertices(rmesa);
+        }
+
         radeon_teximage_map(image, GL_FALSE);
     } else {
         /* Image hasn't been uploaded to a miptree yet */
index a22195cccebb72f03f4a2582d727126dfcd43c56..6173231a82eee14e63a5fb1954ce5a49a2010702 100644 (file)
@@ -37,6 +37,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "sis_lock.h"
 
 #include "main/context.h"
+#include "main/macros.h"
 #include "swrast/swrast.h"
 #include "vbo/vbo.h"
 #include "tnl/tnl.h"
index ee10b569bf1d8407b1240b06480c727f4d238ce5..4b3e9d5a38f57dab866d2bd6021cb0dfbeece4d8 100644 (file)
@@ -166,7 +166,6 @@ viaInitDriver(__DRIscreen *sPriv)
     viaScreen->sareaPrivOffset = gDRIPriv->sarea_priv_offset;
 
     i = 0;
-    viaScreen->extensions[i++] = &driFrameTrackingExtension.base;
     viaScreen->extensions[i++] = &driReadDrawableExtension;
     if ( viaScreen->irqEnabled ) {
        viaScreen->extensions[i++] = &driSwapControlExtension.base;
index d58f32b2930cfc7d5c0de56bdc49d01248535d9d..7259bf4c5600ceb0d4920506b66e9f32791ceb7b 100644 (file)
 #include "main/context.h"
 #include "main/extensions.h"
 #include "main/framebuffer.h"
-#include "main/shaders.h"
-#include "shader/shader_api.h"
-#include "shader/prog_print.h"
+#include "main/shaderapi.h"
+#include "main/shaderobj.h"
+#include "program/prog_print.h"
 #include "drivers/common/driverfuncs.h"
 #include "tnl/tnl.h"
 #include "tnl/t_context.h"
 #include "tnl/t_pipeline.h"
 #include "swrast/swrast.h"
-#include "swrast/s_context.h"
-#include "swrast/s_triangle.h"
 #include "swrast_setup/swrast_setup.h"
 #include "vbo/vbo.h"
 
@@ -72,6 +70,7 @@ struct options {
    gl_prog_print_mode Mode;
    const char *VertFile;
    const char *FragFile;
+   const char *GeoFile;
    const char *OutputFile;
    GLboolean Params;
    struct gl_sl_pragmas Pragmas;
@@ -126,6 +125,7 @@ CreateContext(void)
          _mesa_destroy_visual(vis);
       if (buf)
          _mesa_destroy_framebuffer(buf);
+      free(cc);
       return GL_FALSE;
    }
 
@@ -143,6 +143,7 @@ CreateContext(void)
        !_tnl_CreateContext( ctx ) ||
        !_swsetup_CreateContext( ctx )) {
       _mesa_destroy_visual(vis);
+      _mesa_destroy_framebuffer(buf);
       _mesa_free_context_data(ctx);
       free(cc);
       return GL_FALSE;
@@ -251,7 +252,8 @@ CompileShader(const char *filename, GLenum type)
    GLuint shader;
 
    assert(type == GL_FRAGMENT_SHADER ||
-          type == GL_VERTEX_SHADER);
+          type == GL_VERTEX_SHADER ||
+          type == GL_GEOMETRY_SHADER_ARB);
 
    shader = _mesa_CreateShader(type);
    ReadShader(shader, filename);
@@ -267,6 +269,7 @@ Usage(void)
    printf("Usage:\n");
    printf("  --vs FILE          vertex shader input filename\n");
    printf("  --fs FILE          fragment shader input filename\n");
+   printf("  --gs FILE          geometry shader input filename\n");
    printf("  --arb              emit ARB-style instructions\n");
    printf("  --nv               emit NV-style instructions\n");
    printf("  --link             run linker\n");
@@ -290,6 +293,7 @@ ParseOptions(int argc, char *argv[])
    Options.Mode = PROG_PRINT_DEBUG;
    Options.VertFile = NULL;
    Options.FragFile = NULL;
+   Options.GeoFile = NULL;
    Options.OutputFile = NULL;
    Options.Params = GL_FALSE;
    Options.Pragmas.IgnoreOptimize = GL_FALSE;
@@ -311,6 +315,10 @@ ParseOptions(int argc, char *argv[])
          Options.FragFile = argv[i + 1];
          i++;
       }
+      else if (strcmp(argv[i], "--gs") == 0) {
+         Options.GeoFile = argv[i + 1];
+         i++;
+      }
       else if (strcmp(argv[i], "--arb") == 0) {
          Options.Mode = PROG_PRINT_ARB;
       }
@@ -369,7 +377,7 @@ ParseOptions(int argc, char *argv[])
 int
 main(int argc, char *argv[])
 {
-   GLuint v_shader = 0, f_shader = 0;
+   GLuint v_shader = 0, f_shader = 0, g_shader = 0;
 
    ParseOptions(argc, argv);
 
@@ -386,10 +394,19 @@ main(int argc, char *argv[])
       f_shader = CompileShader(Options.FragFile, GL_FRAGMENT_SHADER);
    }
 
-   if (v_shader || f_shader) {
+   if (Options.GeoFile) {
+      g_shader = CompileShader(Options.GeoFile, GL_GEOMETRY_SHADER_ARB);
+   }
+
+
+   if (v_shader || f_shader || g_shader) {
       if (Options.OutputFile) {
+         FILE *f;
          fclose(stdout);
-         /*stdout =*/ freopen(Options.OutputFile, "w", stdout);
+         /*stdout =*/ f = freopen(Options.OutputFile, "w", stdout);
+         if (!f) {
+            fprintf(stderr, "freopen error\n");
+         }
       }
       if (stdout && v_shader) {
          PrintShaderInstructions(v_shader, stdout);
@@ -397,6 +414,9 @@ main(int argc, char *argv[])
       if (stdout && f_shader) {
          PrintShaderInstructions(f_shader, stdout);
       }
+      if (stdout && g_shader) {
+         PrintShaderInstructions(g_shader, stdout);
+      }
       if (Options.OutputFile) {
          fclose(stdout);
       }
index ead405039776272ca5755d88c5b97c8ba20dea67..93d0e8568a1061649fd1f584d3b1c2c22166e1c3 100644 (file)
@@ -1328,6 +1328,7 @@ OSMesaMakeCurrent( OSMesaContext osmesa, void *buffer, GLenum type,
     * size.
     */
    osmesa->rb = new_osmesa_renderbuffer(&osmesa->mesa, osmesa->format, type);
+   _mesa_remove_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT);
    _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT, osmesa->rb);
    assert(osmesa->rb->RefCount == 2);
 
index 955eba4e944d1255f29a60a69e0d27a5ea7fd9c8..8c3f2730f3d06923e6611333c8ea54b2ecc0d9d5 100644 (file)
@@ -1111,31 +1111,6 @@ glXGetAGPOffsetMESA( const GLvoid *pointer )
 }
 
 
-/*** GLX_MESA_allocate_memory */
-
-void PUBLIC *
-glXAllocateMemoryMESA(Display *dpy, int scrn, size_t size,
-                      float readfreq, float writefreq, float priority)
-{
-   /* dummy */
-   return NULL;
-}
-
-void PUBLIC
-glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer)
-{
-   /* dummy */
-}
-
-
-GLuint PUBLIC
-glXGetMemoryOffsetMESA(Display *dpy, int scrn, const void *pointer)
-{
-   /* dummy */
-   return 0;
-}
-
-
 /*** GLX_EXT_texture_from_pixmap */
 
 void PUBLIC
@@ -1387,11 +1362,6 @@ static struct name_address_pair GLX_functions[] = {
    /*** GLX_MESA_agp_offset ***/
    { "glXGetAGPOffsetMESA", (__GLXextFuncPtr) glXGetAGPOffsetMESA },
 
-   /*** GLX_MESA_allocate_memory ***/
-   { "glXAllocateMemoryMESA", (__GLXextFuncPtr) glXAllocateMemoryMESA },
-   { "glXFreeMemoryMESA", (__GLXextFuncPtr) glXFreeMemoryMESA },
-   { "glXGetMemoryOffsetMESA", (__GLXextFuncPtr) glXGetMemoryOffsetMESA },
-
    /*** GLX_EXT_texture_from_pixmap ***/
    { "glXBindTexImageEXT", (__GLXextFuncPtr) glXBindTexImageEXT },
    { "glXReleaseTexImageEXT", (__GLXextFuncPtr) glXReleaseTexImageEXT },
index 06df97dfede6c082db985c13268973bad924df00..82e1f0fdba50cf668ca38193efa83394cc7d9817 100644 (file)
@@ -34,9 +34,9 @@
 #include "api_loopback.h"
 #include "api_exec.h"
 #if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
-#include "shader/arbprogram.h"
+#include "arbprogram.h"
 #endif
-#include "shader/atifragshader.h"
+#include "atifragshader.h"
 #include "attrib.h"
 #include "blend.h"
 #if FEATURE_ARB_vertex_buffer_object
 #include "varray.h"
 #include "viewport.h"
 #if FEATURE_NV_vertex_program
-#include "shader/nvprogram.h"
+#include "nvprogram.h"
 #endif
 #if FEATURE_NV_fragment_program
-#include "shader/nvprogram.h"
+#include "nvprogram.h"
 #endif
 #if FEATURE_ARB_shader_objects
-#include "shaders.h"
+#include "shaderapi.h"
+#include "uniforms.h"
 #endif
 #if FEATURE_ARB_sync
 #include "syncobj.h"
@@ -347,6 +348,7 @@ _mesa_create_exec_table(void)
 
 #if FEATURE_ARB_shader_objects
    _mesa_init_shader_dispatch(exec);
+   _mesa_init_shader_uniform_dispatch(exec);
 #endif
 
    /* 2. GL_EXT_blend_color */
@@ -731,6 +733,12 @@ _mesa_create_exec_table(void)
    SET_GetObjectParameterivAPPLE(exec, _mesa_GetObjectParameterivAPPLE);
 #endif
 
+#if FEATURE_ARB_geometry_shader4
+   SET_FramebufferTextureARB(exec, _mesa_FramebufferTextureARB);
+   SET_FramebufferTextureFaceARB(exec, _mesa_FramebufferTextureFaceARB);
+#endif
+
+
    return exec;
 }
 
index 150bc3886cfee566b9d95cd52da0b6685863cfdb..b3b5c6cc053ae814a7485a8e10f7b602368b4745 100644 (file)
@@ -193,7 +193,7 @@ _mesa_validate_DrawElements(GLcontext *ctx,
       return GL_FALSE;
    }
 
-   if (mode > GL_POLYGON) {
+   if (mode > GL_TRIANGLE_STRIP_ADJACENCY_ARB) {
       _mesa_error(ctx, GL_INVALID_ENUM, "glDrawElements(mode)" );
       return GL_FALSE;
    }
@@ -250,7 +250,7 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode,
       return GL_FALSE;
    }
 
-   if (mode > GL_POLYGON) {
+   if (mode > GL_TRIANGLE_STRIP_ADJACENCY_ARB) {
       _mesa_error(ctx, GL_INVALID_ENUM, "glDrawRangeElements(mode)" );
       return GL_FALSE;
    }
@@ -309,7 +309,7 @@ _mesa_validate_DrawArrays(GLcontext *ctx,
       return GL_FALSE;
    }
 
-   if (mode > GL_POLYGON) {
+   if (mode > GL_TRIANGLE_STRIP_ADJACENCY_ARB) {
       _mesa_error(ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" );
       return GL_FALSE;
    }
@@ -339,7 +339,7 @@ _mesa_validate_DrawArraysInstanced(GLcontext *ctx, GLenum mode, GLint first,
       return GL_FALSE;
    }
 
-   if (mode > GL_POLYGON) {
+   if (mode > GL_TRIANGLE_STRIP_ADJACENCY_ARB) {
       _mesa_error(ctx, GL_INVALID_ENUM,
                   "glDrawArraysInstanced(mode=0x%x)", mode);
       return GL_FALSE;
@@ -384,7 +384,7 @@ _mesa_validate_DrawElementsInstanced(GLcontext *ctx,
       return GL_FALSE;
    }
 
-   if (mode > GL_POLYGON) {
+   if (mode > GL_TRIANGLE_STRIP_ADJACENCY_ARB) {
       _mesa_error(ctx, GL_INVALID_ENUM,
                   "glDrawElementsInstanced(mode = 0x%x)", mode);
       return GL_FALSE;
diff --git a/src/mesa/main/arbprogram.c b/src/mesa/main/arbprogram.c
new file mode 100644 (file)
index 0000000..26d7819
--- /dev/null
@@ -0,0 +1,940 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.0
+ *
+ * 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 arbprogram.c
+ * ARB_vertex/fragment_program state management functions.
+ * \author Brian Paul
+ */
+
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/hash.h"
+#include "main/imports.h"
+#include "main/macros.h"
+#include "main/mtypes.h"
+#include "main/arbprogram.h"
+#include "program/arbprogparse.h"
+#include "program/nvfragparse.h"
+#include "program/nvvertparse.h"
+#include "program/program.h"
+
+
+
+/**
+ * Mixing ARB and NV vertex/fragment programs can be tricky.
+ * Note: GL_VERTEX_PROGRAM_ARB == GL_VERTEX_PROGRAM_NV
+ *  but, GL_FRAGMENT_PROGRAM_ARB != GL_FRAGMENT_PROGRAM_NV
+ * The two different fragment program targets are supposed to be compatible
+ * to some extent (see GL_ARB_fragment_program spec).
+ * This function does the compatibility check.
+ */
+static GLboolean
+compatible_program_targets(GLenum t1, GLenum t2)
+{
+   if (t1 == t2)
+      return GL_TRUE;
+   if (t1 == GL_FRAGMENT_PROGRAM_ARB && t2 == GL_FRAGMENT_PROGRAM_NV)
+      return GL_TRUE;
+   if (t1 == GL_FRAGMENT_PROGRAM_NV && t2 == GL_FRAGMENT_PROGRAM_ARB)
+      return GL_TRUE;
+   return GL_FALSE;
+}
+
+
+/**
+ * Bind a program (make it current)
+ * \note Called from the GL API dispatcher by both glBindProgramNV
+ * and glBindProgramARB.
+ */
+void GLAPIENTRY
+_mesa_BindProgram(GLenum target, GLuint id)
+{
+   struct gl_program *curProg, *newProg;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   /* Error-check target and get curProg */
+   if ((target == GL_VERTEX_PROGRAM_ARB) && /* == GL_VERTEX_PROGRAM_NV */
+        (ctx->Extensions.NV_vertex_program ||
+         ctx->Extensions.ARB_vertex_program)) {
+      curProg = &ctx->VertexProgram.Current->Base;
+   }
+   else if ((target == GL_FRAGMENT_PROGRAM_NV
+             && ctx->Extensions.NV_fragment_program) ||
+            (target == GL_FRAGMENT_PROGRAM_ARB
+             && ctx->Extensions.ARB_fragment_program)) {
+      curProg = &ctx->FragmentProgram.Current->Base;
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glBindProgramNV/ARB(target)");
+      return;
+   }
+
+   /*
+    * Get pointer to new program to bind.
+    * NOTE: binding to a non-existant program is not an error.
+    * That's supposed to be caught in glBegin.
+    */
+   if (id == 0) {
+      /* Bind a default program */
+      newProg = NULL;
+      if (target == GL_VERTEX_PROGRAM_ARB) /* == GL_VERTEX_PROGRAM_NV */
+         newProg = &ctx->Shared->DefaultVertexProgram->Base;
+      else
+         newProg = &ctx->Shared->DefaultFragmentProgram->Base;
+   }
+   else {
+      /* Bind a user program */
+      newProg = _mesa_lookup_program(ctx, id);
+      if (!newProg || newProg == &_mesa_DummyProgram) {
+         /* allocate a new program now */
+         newProg = ctx->Driver.NewProgram(ctx, target, id);
+         if (!newProg) {
+            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindProgramNV/ARB");
+            return;
+         }
+         _mesa_HashInsert(ctx->Shared->Programs, id, newProg);
+      }
+      else if (!compatible_program_targets(newProg->Target, target)) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "glBindProgramNV/ARB(target mismatch)");
+         return;
+      }
+   }
+
+   /** All error checking is complete now **/
+
+   if (curProg->Id == id) {
+      /* binding same program - no change */
+      return;
+   }
+
+   /* signal new program (and its new constants) */
+   FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
+
+   /* bind newProg */
+   if (target == GL_VERTEX_PROGRAM_ARB) { /* == GL_VERTEX_PROGRAM_NV */
+      _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
+                               (struct gl_vertex_program *) newProg);
+   }
+   else if (target == GL_FRAGMENT_PROGRAM_NV ||
+            target == GL_FRAGMENT_PROGRAM_ARB) {
+      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
+                               (struct gl_fragment_program *) newProg);
+   }
+
+   /* Never null pointers */
+   ASSERT(ctx->VertexProgram.Current);
+   ASSERT(ctx->FragmentProgram.Current);
+
+   if (ctx->Driver.BindProgram)
+      ctx->Driver.BindProgram(ctx, target, newProg);
+}
+
+
+/**
+ * Delete a list of programs.
+ * \note Not compiled into display lists.
+ * \note Called by both glDeleteProgramsNV and glDeleteProgramsARB.
+ */
+void GLAPIENTRY 
+_mesa_DeletePrograms(GLsizei n, const GLuint *ids)
+{
+   GLint i;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+   if (n < 0) {
+      _mesa_error( ctx, GL_INVALID_VALUE, "glDeleteProgramsNV" );
+      return;
+   }
+
+   for (i = 0; i < n; i++) {
+      if (ids[i] != 0) {
+         struct gl_program *prog = _mesa_lookup_program(ctx, ids[i]);
+         if (prog == &_mesa_DummyProgram) {
+            _mesa_HashRemove(ctx->Shared->Programs, ids[i]);
+         }
+         else if (prog) {
+            /* Unbind program if necessary */
+            switch (prog->Target) {
+            case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */
+            case GL_VERTEX_STATE_PROGRAM_NV:
+               if (ctx->VertexProgram.Current &&
+                   ctx->VertexProgram.Current->Base.Id == ids[i]) {
+                  /* unbind this currently bound program */
+                  _mesa_BindProgram(prog->Target, 0);
+               }
+               break;
+            case GL_FRAGMENT_PROGRAM_NV:
+            case GL_FRAGMENT_PROGRAM_ARB:
+               if (ctx->FragmentProgram.Current &&
+                   ctx->FragmentProgram.Current->Base.Id == ids[i]) {
+                  /* unbind this currently bound program */
+                  _mesa_BindProgram(prog->Target, 0);
+               }
+               break;
+            default:
+               _mesa_problem(ctx, "bad target in glDeleteProgramsNV");
+               return;
+            }
+            /* The ID is immediately available for re-use now */
+            _mesa_HashRemove(ctx->Shared->Programs, ids[i]);
+            _mesa_reference_program(ctx, &prog, NULL);
+         }
+      }
+   }
+}
+
+
+/**
+ * Generate a list of new program identifiers.
+ * \note Not compiled into display lists.
+ * \note Called by both glGenProgramsNV and glGenProgramsARB.
+ */
+void GLAPIENTRY
+_mesa_GenPrograms(GLsizei n, GLuint *ids)
+{
+   GLuint first;
+   GLuint i;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (n < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGenPrograms");
+      return;
+   }
+
+   if (!ids)
+      return;
+
+   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->Programs, n);
+
+   /* Insert pointer to dummy program as placeholder */
+   for (i = 0; i < (GLuint) n; i++) {
+      _mesa_HashInsert(ctx->Shared->Programs, first + i, &_mesa_DummyProgram);
+   }
+
+   /* Return the program names */
+   for (i = 0; i < (GLuint) n; i++) {
+      ids[i] = first + i;
+   }
+}
+
+
+/**
+ * Determine if id names a vertex or fragment program.
+ * \note Not compiled into display lists.
+ * \note Called from both glIsProgramNV and glIsProgramARB.
+ * \param id is the program identifier
+ * \return GL_TRUE if id is a program, else GL_FALSE.
+ */
+GLboolean GLAPIENTRY
+_mesa_IsProgramARB(GLuint id)
+{
+   struct gl_program *prog = NULL; 
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+
+   if (id == 0)
+      return GL_FALSE;
+
+   prog = _mesa_lookup_program(ctx, id);
+   if (prog && (prog != &_mesa_DummyProgram))
+      return GL_TRUE;
+   else
+      return GL_FALSE;
+}
+
+
+void GLAPIENTRY
+_mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
+                       const GLvoid *string)
+{
+   struct gl_program *base;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+
+   if (!ctx->Extensions.ARB_vertex_program
+       && !ctx->Extensions.ARB_fragment_program) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramStringARB()");
+      return;
+   }
+
+   if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
+      return;
+   }
+
+   /* The first couple cases are complicated.  The same enum value is used for
+    * ARB and NV vertex programs.  If the target is a vertex program, parse it
+    * using the ARB grammar if the string starts with "!!ARB" or if
+    * NV_vertex_program is not supported.
+    */
+   if (target == GL_VERTEX_PROGRAM_ARB
+       && ctx->Extensions.ARB_vertex_program
+       && ((strncmp(string, "!!ARB", 5) == 0)
+          || !ctx->Extensions.NV_vertex_program)) {
+      struct gl_vertex_program *prog = ctx->VertexProgram.Current;
+      _mesa_parse_arb_vertex_program(ctx, target, string, len, prog);
+
+      base = & prog->Base;
+   }
+   else if ((target == GL_VERTEX_PROGRAM_ARB
+            || target == GL_VERTEX_STATE_PROGRAM_NV)
+           && ctx->Extensions.NV_vertex_program) {
+      struct gl_vertex_program *prog = ctx->VertexProgram.Current;
+      _mesa_parse_nv_vertex_program(ctx, target, string, len, prog);
+
+      base = & prog->Base;
+   }
+   else if (target == GL_FRAGMENT_PROGRAM_ARB
+            && ctx->Extensions.ARB_fragment_program) {
+      struct gl_fragment_program *prog = ctx->FragmentProgram.Current;
+      _mesa_parse_arb_fragment_program(ctx, target, string, len, prog);
+
+      base = & prog->Base;
+   }
+   else if (target == GL_FRAGMENT_PROGRAM_NV
+            && ctx->Extensions.NV_fragment_program) {
+      struct gl_fragment_program *prog = ctx->FragmentProgram.Current;
+      _mesa_parse_nv_fragment_program(ctx, target, string, len, prog);
+
+      base = & prog->Base;
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)");
+      return;
+   }
+
+   if (ctx->Program.ErrorPos == -1) {
+      /* finally, give the program to the driver for translation/checking */
+      if (!ctx->Driver.ProgramStringNotify(ctx, target, base)) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "glProgramStringARB(rejected by driver");
+      }
+   }
+}
+
+
+/**
+ * Set a program env parameter register.
+ * \note Called from the GL API dispatcher.
+ * Note, this function is also used by the GL_NV_vertex_program extension
+ * (alias to ProgramParameterdNV)
+ */
+void GLAPIENTRY
+_mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index,
+                               GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+   _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) x, (GLfloat) y, 
+                                 (GLfloat) z, (GLfloat) w);
+}
+
+
+/**
+ * Set a program env parameter register.
+ * \note Called from the GL API dispatcher.
+ * Note, this function is also used by the GL_NV_vertex_program extension
+ * (alias to ProgramParameterdvNV)
+ */
+void GLAPIENTRY
+_mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
+                                const GLdouble *params)
+{
+   _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) params[0], 
+                                 (GLfloat) params[1], (GLfloat) params[2], 
+                                 (GLfloat) params[3]);
+}
+
+
+/**
+ * Set a program env parameter register.
+ * \note Called from the GL API dispatcher.
+ * Note, this function is also used by the GL_NV_vertex_program extension
+ * (alias to ProgramParameterfNV)
+ */
+void GLAPIENTRY
+_mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
+                               GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
+
+   if (target == GL_FRAGMENT_PROGRAM_ARB
+       && ctx->Extensions.ARB_fragment_program) {
+      if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
+         return;
+      }
+      ASSIGN_4V(ctx->FragmentProgram.Parameters[index], x, y, z, w);
+   }
+   else if (target == GL_VERTEX_PROGRAM_ARB /* == GL_VERTEX_PROGRAM_NV */
+       && (ctx->Extensions.ARB_vertex_program || ctx->Extensions.NV_vertex_program)) {
+      if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
+         return;
+      }
+      ASSIGN_4V(ctx->VertexProgram.Parameters[index], x, y, z, w);
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)");
+      return;
+   }
+}
+
+
+
+/**
+ * Set a program env parameter register.
+ * \note Called from the GL API dispatcher.
+ * Note, this function is also used by the GL_NV_vertex_program extension
+ * (alias to ProgramParameterfvNV)
+ */
+void GLAPIENTRY
+_mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
+                                const GLfloat *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
+
+   if (target == GL_FRAGMENT_PROGRAM_ARB
+       && ctx->Extensions.ARB_fragment_program) {
+      if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter4fv(index)");
+         return;
+      }
+      memcpy(ctx->FragmentProgram.Parameters[index], params,
+             4 * sizeof(GLfloat));
+   }
+   else if (target == GL_VERTEX_PROGRAM_ARB /* == GL_VERTEX_PROGRAM_NV */
+       && (ctx->Extensions.ARB_vertex_program || ctx->Extensions.NV_vertex_program)) {
+      if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter4fv(index)");
+         return;
+      }
+      memcpy(ctx->VertexProgram.Parameters[index], params,
+             4 * sizeof(GLfloat));
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter4fv(target)");
+      return;
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
+                                const GLfloat *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLfloat * dest;
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
+
+   if (count <= 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(count)");
+   }
+
+   if (target == GL_FRAGMENT_PROGRAM_ARB
+       && ctx->Extensions.ARB_fragment_program) {
+      if ((index + count) > ctx->Const.FragmentProgram.MaxEnvParams) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(index + count)");
+         return;
+      }
+      dest = ctx->FragmentProgram.Parameters[index];
+   }
+   else if (target == GL_VERTEX_PROGRAM_ARB
+       && ctx->Extensions.ARB_vertex_program) {
+      if ((index + count) > ctx->Const.VertexProgram.MaxEnvParams) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(index + count)");
+         return;
+      }
+      dest = ctx->VertexProgram.Parameters[index];
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameters4fv(target)");
+      return;
+   }
+
+   memcpy(dest, params, count * 4 * sizeof(GLfloat));
+}
+
+
+void GLAPIENTRY
+_mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index,
+                                  GLdouble *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLfloat fparams[4];
+
+   _mesa_GetProgramEnvParameterfvARB(target, index, fparams);
+   if (ctx->ErrorValue == GL_NO_ERROR) {
+      params[0] = fparams[0];
+      params[1] = fparams[1];
+      params[2] = fparams[2];
+      params[3] = fparams[3];
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index, 
+                                  GLfloat *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (target == GL_FRAGMENT_PROGRAM_ARB
+       && ctx->Extensions.ARB_fragment_program) {
+      if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
+         return;
+      }
+      COPY_4V(params, ctx->FragmentProgram.Parameters[index]);
+   }
+   else if (target == GL_VERTEX_PROGRAM_ARB
+       && ctx->Extensions.ARB_vertex_program) {
+      if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
+         return;
+      }
+      COPY_4V(params, ctx->VertexProgram.Parameters[index]);
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)");
+      return;
+   }
+}
+
+
+/**
+ * Note, this function is also used by the GL_NV_fragment_program extension.
+ */
+void GLAPIENTRY
+_mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index,
+                                 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_program *prog;
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
+
+   if ((target == GL_FRAGMENT_PROGRAM_NV
+        && ctx->Extensions.NV_fragment_program) ||
+       (target == GL_FRAGMENT_PROGRAM_ARB
+        && ctx->Extensions.ARB_fragment_program)) {
+      if (index >= ctx->Const.FragmentProgram.MaxLocalParams) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
+         return;
+      }
+      prog = &(ctx->FragmentProgram.Current->Base);
+   }
+   else if (target == GL_VERTEX_PROGRAM_ARB
+            && ctx->Extensions.ARB_vertex_program) {
+      if (index >= ctx->Const.VertexProgram.MaxLocalParams) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
+         return;
+      }
+      prog = &(ctx->VertexProgram.Current->Base);
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
+      return;
+   }
+
+   ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
+   prog->LocalParams[index][0] = x;
+   prog->LocalParams[index][1] = y;
+   prog->LocalParams[index][2] = z;
+   prog->LocalParams[index][3] = w;
+}
+
+
+/**
+ * Note, this function is also used by the GL_NV_fragment_program extension.
+ */
+void GLAPIENTRY
+_mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
+                                  const GLfloat *params)
+{
+   _mesa_ProgramLocalParameter4fARB(target, index, params[0], params[1],
+                                    params[2], params[3]);
+}
+
+
+void GLAPIENTRY
+_mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
+                                  const GLfloat *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLfloat *dest;
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
+
+   if (count <= 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fv(count)");
+   }
+
+   if (target == GL_FRAGMENT_PROGRAM_ARB
+       && ctx->Extensions.ARB_fragment_program) {
+      if ((index + count) > ctx->Const.FragmentProgram.MaxLocalParams) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fvEXT(index + count)");
+         return;
+      }
+      dest = ctx->FragmentProgram.Current->Base.LocalParams[index];
+   }
+   else if (target == GL_VERTEX_PROGRAM_ARB
+            && ctx->Extensions.ARB_vertex_program) {
+      if ((index + count) > ctx->Const.VertexProgram.MaxLocalParams) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fvEXT(index + count)");
+         return;
+      }
+      dest = ctx->VertexProgram.Current->Base.LocalParams[index];
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameters4fvEXT(target)");
+      return;
+   }
+
+   memcpy(dest, params, count * 4 * sizeof(GLfloat));
+}
+
+
+/**
+ * Note, this function is also used by the GL_NV_fragment_program extension.
+ */
+void GLAPIENTRY
+_mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index,
+                                 GLdouble x, GLdouble y,
+                                 GLdouble z, GLdouble w)
+{
+   _mesa_ProgramLocalParameter4fARB(target, index, (GLfloat) x, (GLfloat) y, 
+                                    (GLfloat) z, (GLfloat) w);
+}
+
+
+/**
+ * Note, this function is also used by the GL_NV_fragment_program extension.
+ */
+void GLAPIENTRY
+_mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index,
+                                  const GLdouble *params)
+{
+   _mesa_ProgramLocalParameter4fARB(target, index,
+                                    (GLfloat) params[0], (GLfloat) params[1],
+                                    (GLfloat) params[2], (GLfloat) params[3]);
+}
+
+
+/**
+ * Note, this function is also used by the GL_NV_fragment_program extension.
+ */
+void GLAPIENTRY
+_mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index,
+                                    GLfloat *params)
+{
+   const struct gl_program *prog;
+   GLuint maxParams;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (target == GL_VERTEX_PROGRAM_ARB
+       && ctx->Extensions.ARB_vertex_program) {
+      prog = &(ctx->VertexProgram.Current->Base);
+      maxParams = ctx->Const.VertexProgram.MaxLocalParams;
+   }
+   else if (target == GL_FRAGMENT_PROGRAM_ARB
+            && ctx->Extensions.ARB_fragment_program) {
+      prog = &(ctx->FragmentProgram.Current->Base);
+      maxParams = ctx->Const.FragmentProgram.MaxLocalParams;
+   }
+   else if (target == GL_FRAGMENT_PROGRAM_NV
+            && ctx->Extensions.NV_fragment_program) {
+      prog = &(ctx->FragmentProgram.Current->Base);
+      maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glGetProgramLocalParameterARB(target)");
+      return;
+   }
+
+   if (index >= maxParams) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glGetProgramLocalParameterARB(index)");
+      return;
+   }
+
+   ASSERT(prog);
+   ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
+   COPY_4V(params, prog->LocalParams[index]);
+}
+
+
+/**
+ * Note, this function is also used by the GL_NV_fragment_program extension.
+ */
+void GLAPIENTRY
+_mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index,
+                                    GLdouble *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLfloat floatParams[4];
+   ASSIGN_4V(floatParams, 0.0F, 0.0F, 0.0F, 0.0F);
+   _mesa_GetProgramLocalParameterfvARB(target, index, floatParams);
+   if (ctx->ErrorValue == GL_NO_ERROR) {
+      COPY_4V(params, floatParams);
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
+{
+   const struct gl_program_constants *limits;
+   struct gl_program *prog;
+   GET_CURRENT_CONTEXT(ctx);
+
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (target == GL_VERTEX_PROGRAM_ARB
+       && ctx->Extensions.ARB_vertex_program) {
+      prog = &(ctx->VertexProgram.Current->Base);
+      limits = &ctx->Const.VertexProgram;
+   }
+   else if (target == GL_FRAGMENT_PROGRAM_ARB
+            && ctx->Extensions.ARB_fragment_program) {
+      prog = &(ctx->FragmentProgram.Current->Base);
+      limits = &ctx->Const.FragmentProgram;
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
+      return;
+   }
+
+   ASSERT(prog);
+   ASSERT(limits);
+
+   /* Queries supported for both vertex and fragment programs */
+   switch (pname) {
+      case GL_PROGRAM_LENGTH_ARB:
+         *params
+            = prog->String ? (GLint) strlen((char *) prog->String) : 0;
+         return;
+      case GL_PROGRAM_FORMAT_ARB:
+         *params = prog->Format;
+         return;
+      case GL_PROGRAM_BINDING_ARB:
+         *params = prog->Id;
+         return;
+      case GL_PROGRAM_INSTRUCTIONS_ARB:
+         *params = prog->NumInstructions;
+         return;
+      case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
+         *params = limits->MaxInstructions;
+         return;
+      case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
+         *params = prog->NumNativeInstructions;
+         return;
+      case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
+         *params = limits->MaxNativeInstructions;
+         return;
+      case GL_PROGRAM_TEMPORARIES_ARB:
+         *params = prog->NumTemporaries;
+         return;
+      case GL_MAX_PROGRAM_TEMPORARIES_ARB:
+         *params = limits->MaxTemps;
+         return;
+      case GL_PROGRAM_NATIVE_TEMPORARIES_ARB:
+         *params = prog->NumNativeTemporaries;
+         return;
+      case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
+         *params = limits->MaxNativeTemps;
+         return;
+      case GL_PROGRAM_PARAMETERS_ARB:
+         *params = prog->NumParameters;
+         return;
+      case GL_MAX_PROGRAM_PARAMETERS_ARB:
+         *params = limits->MaxParameters;
+         return;
+      case GL_PROGRAM_NATIVE_PARAMETERS_ARB:
+         *params = prog->NumNativeParameters;
+         return;
+      case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
+         *params = limits->MaxNativeParameters;
+         return;
+      case GL_PROGRAM_ATTRIBS_ARB:
+         *params = prog->NumAttributes;
+         return;
+      case GL_MAX_PROGRAM_ATTRIBS_ARB:
+         *params = limits->MaxAttribs;
+         return;
+      case GL_PROGRAM_NATIVE_ATTRIBS_ARB:
+         *params = prog->NumNativeAttributes;
+         return;
+      case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
+         *params = limits->MaxNativeAttribs;
+         return;
+      case GL_PROGRAM_ADDRESS_REGISTERS_ARB:
+         *params = prog->NumAddressRegs;
+         return;
+      case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
+         *params = limits->MaxAddressRegs;
+         return;
+      case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
+         *params = prog->NumNativeAddressRegs;
+         return;
+      case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
+         *params = limits->MaxNativeAddressRegs;
+         return;
+      case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
+         *params = limits->MaxLocalParams;
+         return;
+      case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
+         *params = limits->MaxEnvParams;
+         return;
+      case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB:
+         /*
+          * XXX we may not really need a driver callback here.
+          * If the number of native instructions, registers, etc. used
+          * are all below the maximums, we could return true.
+          * The spec says that even if this query returns true, there's
+          * no guarantee that the program will run in hardware.
+          */
+         if (prog->Id == 0) {
+            /* default/null program */
+            *params = GL_FALSE;
+         }
+        else if (ctx->Driver.IsProgramNative) {
+            /* ask the driver */
+           *params = ctx->Driver.IsProgramNative( ctx, target, prog );
+         }
+        else {
+            /* probably running in software */
+           *params = GL_TRUE;
+         }
+         return;
+      default:
+         /* continue with fragment-program only queries below */
+         break;
+   }
+
+   /*
+    * The following apply to fragment programs only (at this time)
+    */
+   if (target == GL_FRAGMENT_PROGRAM_ARB) {
+      const struct gl_fragment_program *fp = ctx->FragmentProgram.Current;
+      switch (pname) {
+         case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
+            *params = fp->Base.NumNativeAluInstructions;
+            return;
+         case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
+            *params = fp->Base.NumAluInstructions;
+            return;
+         case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
+            *params = fp->Base.NumTexInstructions;
+            return;
+         case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
+            *params = fp->Base.NumNativeTexInstructions;
+            return;
+         case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
+            *params = fp->Base.NumTexIndirections;
+            return;
+         case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
+            *params = fp->Base.NumNativeTexIndirections;
+            return;
+         case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
+            *params = limits->MaxAluInstructions;
+            return;
+         case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
+            *params = limits->MaxNativeAluInstructions;
+            return;
+         case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
+            *params = limits->MaxTexInstructions;
+            return;
+         case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
+            *params = limits->MaxNativeTexInstructions;
+            return;
+         case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB:
+            *params = limits->MaxTexIndirections;
+            return;
+         case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
+            *params = limits->MaxNativeTexIndirections;
+            return;
+         default:
+            _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
+            return;
+      }
+   } else {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
+      return;
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string)
+{
+   const struct gl_program *prog;
+   char *dst = (char *) string;
+   GET_CURRENT_CONTEXT(ctx);
+
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (target == GL_VERTEX_PROGRAM_ARB) {
+      prog = &(ctx->VertexProgram.Current->Base);
+   }
+   else if (target == GL_FRAGMENT_PROGRAM_ARB) {
+      prog = &(ctx->FragmentProgram.Current->Base);
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)");
+      return;
+   }
+
+   ASSERT(prog);
+
+   if (pname != GL_PROGRAM_STRING_ARB) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)");
+      return;
+   }
+
+   if (prog->String)
+      memcpy(dst, prog->String, strlen((char *) prog->String));
+   else
+      *dst = '\0';
+}
diff --git a/src/mesa/main/arbprogram.h b/src/mesa/main/arbprogram.h
new file mode 100644 (file)
index 0000000..787ffd6
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.2
+ *
+ * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef ARBPROGRAM_H
+#define ARBPROGRAM_H
+
+
+#include "compiler.h"
+#include "glheader.h"
+
+
+extern void GLAPIENTRY
+_mesa_BindProgram(GLenum target, GLuint id);
+
+extern void GLAPIENTRY
+_mesa_DeletePrograms(GLsizei n, const GLuint *ids);
+
+extern void GLAPIENTRY
+_mesa_GenPrograms(GLsizei n, GLuint *ids);
+
+
+extern GLboolean GLAPIENTRY
+_mesa_IsProgramARB(GLuint id);
+
+
+extern void GLAPIENTRY
+_mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
+                       const GLvoid *string);
+
+
+extern void GLAPIENTRY
+_mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index,
+                               GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+
+
+extern void GLAPIENTRY
+_mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
+                                const GLdouble *params);
+
+
+extern void GLAPIENTRY
+_mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
+                               GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+
+
+extern void GLAPIENTRY
+_mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
+                                const GLfloat *params);
+
+
+extern void GLAPIENTRY
+_mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
+                                const GLfloat *params);
+
+
+extern void GLAPIENTRY
+_mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index,
+                                 GLdouble x, GLdouble y,
+                                 GLdouble z, GLdouble w);
+
+
+extern void GLAPIENTRY
+_mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index,
+                                  const GLdouble *params);
+
+
+extern void GLAPIENTRY
+_mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index,
+                                 GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+
+
+extern void GLAPIENTRY
+_mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
+                                  const GLfloat *params);
+
+
+extern void GLAPIENTRY
+_mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
+                                  const GLfloat *params);
+
+
+extern void GLAPIENTRY
+_mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index,
+                                  GLdouble *params);
+
+
+extern void GLAPIENTRY
+_mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index, 
+                                  GLfloat *params);
+
+
+extern void GLAPIENTRY
+_mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index,
+                                    GLdouble *params);
+
+
+extern void GLAPIENTRY
+_mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index, 
+                                    GLfloat *params);
+
+
+extern void GLAPIENTRY
+_mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params);
+
+
+extern void GLAPIENTRY
+_mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string);
+
+
+#endif
diff --git a/src/mesa/main/atifragshader.c b/src/mesa/main/atifragshader.c
new file mode 100644 (file)
index 0000000..550f50b
--- /dev/null
@@ -0,0 +1,794 @@
+/**
+ * \file atifragshader.c
+ * \author David Airlie
+ * Copyright (C) 2004  David Airlie   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and 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
+ * DAVID AIRLIE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION 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/context.h"
+#include "main/hash.h"
+#include "main/imports.h"
+#include "main/macros.h"
+#include "main/enums.h"
+#include "main/mtypes.h"
+#include "main/dispatch.h"
+#include "main/atifragshader.h"
+
+#if FEATURE_ATI_fragment_shader
+
+#define MESA_DEBUG_ATI_FS 0
+
+static struct ati_fragment_shader DummyShader;
+
+
+void
+_mesa_init_ati_fragment_shader_dispatch(struct _glapi_table *disp)
+{
+   SET_GenFragmentShadersATI(disp, _mesa_GenFragmentShadersATI);
+   SET_BindFragmentShaderATI(disp, _mesa_BindFragmentShaderATI);
+   SET_DeleteFragmentShaderATI(disp, _mesa_DeleteFragmentShaderATI);
+   SET_BeginFragmentShaderATI(disp, _mesa_BeginFragmentShaderATI);
+   SET_EndFragmentShaderATI(disp, _mesa_EndFragmentShaderATI);
+   SET_PassTexCoordATI(disp, _mesa_PassTexCoordATI);
+   SET_SampleMapATI(disp, _mesa_SampleMapATI);
+   SET_ColorFragmentOp1ATI(disp, _mesa_ColorFragmentOp1ATI);
+   SET_ColorFragmentOp2ATI(disp, _mesa_ColorFragmentOp2ATI);
+   SET_ColorFragmentOp3ATI(disp, _mesa_ColorFragmentOp3ATI);
+   SET_AlphaFragmentOp1ATI(disp, _mesa_AlphaFragmentOp1ATI);
+   SET_AlphaFragmentOp2ATI(disp, _mesa_AlphaFragmentOp2ATI);
+   SET_AlphaFragmentOp3ATI(disp, _mesa_AlphaFragmentOp3ATI);
+   SET_SetFragmentShaderConstantATI(disp, _mesa_SetFragmentShaderConstantATI);
+}
+
+
+/**
+ * Allocate and initialize a new ATI fragment shader object.
+ */
+struct ati_fragment_shader *
+_mesa_new_ati_fragment_shader(GLcontext *ctx, GLuint id)
+{
+   struct ati_fragment_shader *s = CALLOC_STRUCT(ati_fragment_shader);
+   (void) ctx;
+   if (s) {
+      s->Id = id;
+      s->RefCount = 1;
+   }
+   return s;
+}
+
+
+/**
+ * Delete the given ati fragment shader
+ */
+void
+_mesa_delete_ati_fragment_shader(GLcontext *ctx, struct ati_fragment_shader *s)
+{
+   GLuint i;
+   for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {
+      if (s->Instructions[i])
+         free(s->Instructions[i]);
+      if (s->SetupInst[i])
+         free(s->SetupInst[i]);
+   }
+   free(s);
+}
+
+
+
+static void
+new_arith_inst(struct ati_fragment_shader *prog)
+{
+/* set "default" instruction as not all may get defined.
+   there is no specified way to express a nop with ati fragment shaders we use
+   GL_NONE as the op enum and just set some params to 0 - so nothing to do here */
+   prog->numArithInstr[prog->cur_pass >> 1]++;
+}
+
+static void
+new_tex_inst(struct ati_fragment_shader *prog)
+{
+}
+
+static void match_pair_inst(struct ati_fragment_shader *curProg, GLuint optype)
+{
+   if (optype == curProg->last_optype) {
+      curProg->last_optype = 1;
+   }
+}
+
+#if MESA_DEBUG_ATI_FS
+static char *
+create_dst_mod_str(GLuint mod)
+{
+   static char ret_str[1024];
+
+   memset(ret_str, 0, 1024);
+   if (mod & GL_2X_BIT_ATI)
+      strncat(ret_str, "|2X", 1024);
+
+   if (mod & GL_4X_BIT_ATI)
+      strncat(ret_str, "|4X", 1024);
+
+   if (mod & GL_8X_BIT_ATI)
+      strncat(ret_str, "|8X", 1024);
+   if (mod & GL_HALF_BIT_ATI)
+      strncat(ret_str, "|HA", 1024);
+   if (mod & GL_QUARTER_BIT_ATI)
+      strncat(ret_str, "|QU", 1024);
+   if (mod & GL_EIGHTH_BIT_ATI)
+      strncat(ret_str, "|EI", 1024);
+
+   if (mod & GL_SATURATE_BIT_ATI)
+      strncat(ret_str, "|SAT", 1024);
+
+   if (strlen(ret_str) == 0)
+      strncat(ret_str, "NONE", 1024);
+   return ret_str;
+}
+
+static char *atifs_ops[] = {"ColorFragmentOp1ATI", "ColorFragmentOp2ATI", "ColorFragmentOp3ATI", 
+                           "AlphaFragmentOp1ATI", "AlphaFragmentOp2ATI", "AlphaFragmentOp3ATI" };
+
+static void debug_op(GLint optype, GLuint arg_count, GLenum op, GLuint dst,
+                    GLuint dstMask, GLuint dstMod, GLuint arg1,
+                    GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
+                    GLuint arg2Rep, GLuint arg2Mod, GLuint arg3,
+                    GLuint arg3Rep, GLuint arg3Mod)
+{
+  char *op_name;
+
+  op_name = atifs_ops[(arg_count-1)+(optype?3:0)];
+  
+  fprintf(stderr, "%s(%s, %s", op_name, _mesa_lookup_enum_by_nr(op),
+             _mesa_lookup_enum_by_nr(dst));
+  if (!optype)
+    fprintf(stderr, ", %d", dstMask);
+  
+  fprintf(stderr, ", %s", create_dst_mod_str(dstMod));
+  
+  fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg1),
+             _mesa_lookup_enum_by_nr(arg1Rep), arg1Mod);
+  if (arg_count>1)
+    fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg2),
+             _mesa_lookup_enum_by_nr(arg2Rep), arg2Mod);
+  if (arg_count>2)
+    fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg3),
+             _mesa_lookup_enum_by_nr(arg3Rep), arg3Mod);
+
+  fprintf(stderr,")\n");
+
+}
+#endif
+
+static int check_arith_arg(struct ati_fragment_shader *curProg,
+                       GLuint optype, GLuint arg, GLuint argRep)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (((arg < GL_CON_0_ATI) || (arg > GL_CON_7_ATI)) &&
+      ((arg < GL_REG_0_ATI) || (arg > GL_REG_5_ATI)) &&
+      (arg != GL_ZERO) && (arg != GL_ONE) &&
+      (arg != GL_PRIMARY_COLOR_ARB) && (arg != GL_SECONDARY_INTERPOLATOR_ATI)) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(arg)");
+      return 0;
+   }
+   if ((arg == GL_SECONDARY_INTERPOLATOR_ATI) && (((optype == 0) && (argRep == GL_ALPHA)) ||
+      ((optype == 1) && ((arg == GL_ALPHA) || (argRep == GL_NONE))))) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)");
+      return 0;
+   }
+   if ((arg == GL_SECONDARY_INTERPOLATOR_ATI) && (((optype == 0) && (argRep == GL_ALPHA)) ||
+      ((optype == 1) && ((arg == GL_ALPHA) || (argRep == GL_NONE))))) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)");
+      return 0;
+   }
+   if ((curProg->cur_pass == 1) &&
+      ((arg == GL_PRIMARY_COLOR_ARB) || (arg == GL_SECONDARY_INTERPOLATOR_ATI))) {
+      curProg->interpinp1 = GL_TRUE;
+   }
+   return 1;
+}
+
+GLuint GLAPIENTRY
+_mesa_GenFragmentShadersATI(GLuint range)
+{
+   GLuint first;
+   GLuint i;
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (range == 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGenFragmentShadersATI(range)");
+      return 0;
+   }
+
+   if (ctx->ATIFragmentShader.Compiling) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGenFragmentShadersATI(insideShader)");
+      return 0;
+   }
+
+   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->ATIShaders, range);
+   for (i = 0; i < range; i++) {
+      _mesa_HashInsert(ctx->Shared->ATIShaders, first + i, &DummyShader);
+   }
+
+   return first;
+}
+
+void GLAPIENTRY
+_mesa_BindFragmentShaderATI(GLuint id)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
+   struct ati_fragment_shader *newProg;
+
+   if (ctx->ATIFragmentShader.Compiling) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glBindFragmentShaderATI(insideShader)");
+      return;
+   }
+
+   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+
+   if (curProg->Id == id) {
+      return;
+   }
+
+   /* unbind current */
+   if (curProg->Id != 0) {
+      curProg->RefCount--;
+      if (curProg->RefCount <= 0) {
+        _mesa_HashRemove(ctx->Shared->ATIShaders, id);
+      }
+   }
+
+   /* find new shader */
+   if (id == 0) {
+      newProg = ctx->Shared->DefaultFragmentShader;
+   }
+   else {
+      newProg = (struct ati_fragment_shader *)
+         _mesa_HashLookup(ctx->Shared->ATIShaders, id);
+      if (!newProg || newProg == &DummyShader) {
+        /* allocate a new program now */
+        newProg = _mesa_new_ati_fragment_shader(ctx, id);
+        if (!newProg) {
+           _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFragmentShaderATI");
+           return;
+        }
+        _mesa_HashInsert(ctx->Shared->ATIShaders, id, newProg);
+      }
+
+   }
+
+   /* do actual bind */
+   ctx->ATIFragmentShader.Current = newProg;
+
+   ASSERT(ctx->ATIFragmentShader.Current);
+   if (newProg)
+      newProg->RefCount++;
+
+   /*if (ctx->Driver.BindProgram)
+      ctx->Driver.BindProgram(ctx, target, prog); */
+}
+
+void GLAPIENTRY
+_mesa_DeleteFragmentShaderATI(GLuint id)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (ctx->ATIFragmentShader.Compiling) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteFragmentShaderATI(insideShader)");
+      return;
+   }
+
+   if (id != 0) {
+      struct ati_fragment_shader *prog = (struct ati_fragment_shader *)
+        _mesa_HashLookup(ctx->Shared->ATIShaders, id);
+      if (prog == &DummyShader) {
+        _mesa_HashRemove(ctx->Shared->ATIShaders, id);
+      }
+      else if (prog) {
+        if (ctx->ATIFragmentShader.Current &&
+            ctx->ATIFragmentShader.Current->Id == id) {
+            FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+           _mesa_BindFragmentShaderATI(0);
+        }
+      }
+
+      /* The ID is immediately available for re-use now */
+      _mesa_HashRemove(ctx->Shared->ATIShaders, id);
+      if (prog) {
+        prog->RefCount--;
+        if (prog->RefCount <= 0) {
+           free(prog);
+        }
+      }
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_BeginFragmentShaderATI(void)
+{
+   GLint i;
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (ctx->ATIFragmentShader.Compiling) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginFragmentShaderATI(insideShader)");
+      return;
+   }
+
+   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+
+   /* if the shader was already defined free instructions and get new ones
+      (or, could use the same mem but would need to reinitialize) */
+   /* no idea if it's allowed to redefine a shader */
+   for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {
+         if (ctx->ATIFragmentShader.Current->Instructions[i])
+            free(ctx->ATIFragmentShader.Current->Instructions[i]);
+         if (ctx->ATIFragmentShader.Current->SetupInst[i])
+            free(ctx->ATIFragmentShader.Current->SetupInst[i]);
+   }
+
+   /* malloc the instructions here - not sure if the best place but its
+      a start */
+   for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {
+      ctx->ATIFragmentShader.Current->Instructions[i] =
+        (struct atifs_instruction *)
+        calloc(1, sizeof(struct atifs_instruction) *
+                  (MAX_NUM_INSTRUCTIONS_PER_PASS_ATI));
+      ctx->ATIFragmentShader.Current->SetupInst[i] =
+        (struct atifs_setupinst *)
+        calloc(1, sizeof(struct atifs_setupinst) *
+                  (MAX_NUM_FRAGMENT_REGISTERS_ATI));
+   }
+
+/* can't rely on calloc for initialization as it's possible to redefine a shader (?) */
+   ctx->ATIFragmentShader.Current->LocalConstDef = 0;
+   ctx->ATIFragmentShader.Current->numArithInstr[0] = 0;
+   ctx->ATIFragmentShader.Current->numArithInstr[1] = 0;
+   ctx->ATIFragmentShader.Current->regsAssigned[0] = 0;
+   ctx->ATIFragmentShader.Current->regsAssigned[1] = 0;
+   ctx->ATIFragmentShader.Current->NumPasses = 0;
+   ctx->ATIFragmentShader.Current->cur_pass = 0;
+   ctx->ATIFragmentShader.Current->last_optype = 0;
+   ctx->ATIFragmentShader.Current->interpinp1 = GL_FALSE;
+   ctx->ATIFragmentShader.Current->isValid = GL_FALSE;
+   ctx->ATIFragmentShader.Current->swizzlerq = 0;
+   ctx->ATIFragmentShader.Compiling = 1;
+}
+
+void GLAPIENTRY
+_mesa_EndFragmentShaderATI(void)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
+#if MESA_DEBUG_ATI_FS
+   GLint i, j;
+#endif
+
+   if (!ctx->ATIFragmentShader.Compiling) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(outsideShader)");
+      return;
+   }
+   if (curProg->interpinp1 && (ctx->ATIFragmentShader.Current->cur_pass > 1)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(interpinfirstpass)");
+   /* according to spec, DON'T return here */
+   }
+
+   match_pair_inst(curProg, 0);
+   ctx->ATIFragmentShader.Compiling = 0;
+   ctx->ATIFragmentShader.Current->isValid = GL_TRUE;
+   if ((ctx->ATIFragmentShader.Current->cur_pass == 0) ||
+      (ctx->ATIFragmentShader.Current->cur_pass == 2)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(noarithinst)");
+   }
+   if (ctx->ATIFragmentShader.Current->cur_pass > 1)
+      ctx->ATIFragmentShader.Current->NumPasses = 2;
+   else
+      ctx->ATIFragmentShader.Current->NumPasses = 1;
+
+   ctx->ATIFragmentShader.Current->cur_pass = 0;
+
+#if MESA_DEBUG_ATI_FS
+   for (j = 0; j < MAX_NUM_PASSES_ATI; j++) {
+      for (i = 0; i < MAX_NUM_FRAGMENT_REGISTERS_ATI; i++) {
+        GLuint op = curProg->SetupInst[j][i].Opcode;
+        const char *op_enum = op > 5 ? _mesa_lookup_enum_by_nr(op) : "0";
+        GLuint src = curProg->SetupInst[j][i].src;
+        GLuint swizzle = curProg->SetupInst[j][i].swizzle;
+        fprintf(stderr, "%2d %04X %s %d %04X\n", i, op, op_enum, src,
+             swizzle);
+      }
+      for (i = 0; i < curProg->numArithInstr[j]; i++) {
+        GLuint op0 = curProg->Instructions[j][i].Opcode[0];
+        GLuint op1 = curProg->Instructions[j][i].Opcode[1];
+        const char *op0_enum = op0 > 5 ? _mesa_lookup_enum_by_nr(op0) : "0";
+        const char *op1_enum = op1 > 5 ? _mesa_lookup_enum_by_nr(op1) : "0";
+        GLuint count0 = curProg->Instructions[j][i].ArgCount[0];
+        GLuint count1 = curProg->Instructions[j][i].ArgCount[1];
+        fprintf(stderr, "%2d %04X %s %d %04X %s %d\n", i, op0, op0_enum, count0,
+             op1, op1_enum, count1);
+      }
+   }
+#endif
+
+   if (!ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_SHADER_ATI, NULL)) {
+      ctx->ATIFragmentShader.Current->isValid = GL_FALSE;
+      /* XXX is this the right error? */
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glEndFragmentShaderATI(driver rejected shader)");
+   }
+}
+
+void GLAPIENTRY
+_mesa_PassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
+   struct atifs_setupinst *curI;
+
+   if (!ctx->ATIFragmentShader.Compiling) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(outsideShader)");
+      return;
+   }
+
+   if (curProg->cur_pass == 1) {
+      match_pair_inst(curProg, 0);
+      curProg->cur_pass = 2;
+   }
+   if ((curProg->cur_pass > 2) ||
+      ((1 << (dst - GL_REG_0_ATI)) & curProg->regsAssigned[curProg->cur_pass >> 1])) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoord(pass)");
+      return;
+   }
+   if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI) ||
+      ((dst - GL_REG_0_ATI) >= ctx->Const.MaxTextureUnits)) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(dst)");
+      return;
+   }
+   if (((coord < GL_REG_0_ATI) || (coord > GL_REG_5_ATI)) &&
+       ((coord < GL_TEXTURE0_ARB) || (coord > GL_TEXTURE7_ARB) ||
+       ((coord - GL_TEXTURE0_ARB) >= ctx->Const.MaxTextureUnits))) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(coord)");
+      return;
+   }
+   if ((curProg->cur_pass == 0) && (coord >= GL_REG_0_ATI)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(coord)");
+      return;
+   }
+   if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= GL_SWIZZLE_STQ_DQ_ATI)) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(swizzle)");
+      return;
+   }
+   if ((swizzle & 1) && (coord >= GL_REG_0_ATI)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(swizzle)");
+      return;
+   }
+   if (coord <= GL_TEXTURE7_ARB) {
+      GLuint tmp = coord - GL_TEXTURE0_ARB;
+      if ((((curProg->swizzlerq >> (tmp * 2)) & 3) != 0) &&
+          (((swizzle & 1) + 1) != ((curProg->swizzlerq >> (tmp * 2)) & 3))) {
+        _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(swizzle)");
+        return;
+      } else {
+        curProg->swizzlerq |= (((swizzle & 1) + 1) << (tmp * 2));
+      }
+   }
+
+   curProg->regsAssigned[curProg->cur_pass >> 1] |=  1 << (dst - GL_REG_0_ATI);
+   new_tex_inst(curProg);
+
+   /* add the instructions */
+   curI = &curProg->SetupInst[curProg->cur_pass >> 1][dst - GL_REG_0_ATI];
+
+   curI->Opcode = ATI_FRAGMENT_SHADER_PASS_OP;
+   curI->src = coord;
+   curI->swizzle = swizzle;
+
+#if MESA_DEBUG_ATI_FS
+   _mesa_debug(ctx, "%s(%s, %s, %s)\n", __FUNCTION__,
+              _mesa_lookup_enum_by_nr(dst), _mesa_lookup_enum_by_nr(coord),
+              _mesa_lookup_enum_by_nr(swizzle));
+#endif
+}
+
+void GLAPIENTRY
+_mesa_SampleMapATI(GLuint dst, GLuint interp, GLenum swizzle)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
+   struct atifs_setupinst *curI;
+
+   if (!ctx->ATIFragmentShader.Compiling) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(outsideShader)");
+      return;
+   }
+
+   if (curProg->cur_pass == 1) {
+      match_pair_inst(curProg, 0);
+      curProg->cur_pass = 2;
+   }
+   if ((curProg->cur_pass > 2) ||
+      ((1 << (dst - GL_REG_0_ATI)) & curProg->regsAssigned[curProg->cur_pass >> 1])) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(pass)");
+      return;
+   }
+   if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI) ||
+      ((dst - GL_REG_0_ATI) >= ctx->Const.MaxTextureUnits)) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(dst)");
+      return;
+   }
+   if (((interp < GL_REG_0_ATI) || (interp > GL_REG_5_ATI)) &&
+       ((interp < GL_TEXTURE0_ARB) || (interp > GL_TEXTURE7_ARB) ||
+       ((interp - GL_TEXTURE0_ARB) >= ctx->Const.MaxTextureUnits))) {
+   /* is this texture5 or texture7? spec is a bit unclear there */
+      _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(interp)");
+      return;
+   }
+   if ((curProg->cur_pass == 0) && (interp >= GL_REG_0_ATI)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(interp)");
+      return;
+   }
+   if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= GL_SWIZZLE_STQ_DQ_ATI)) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(swizzle)");
+      return;
+   }
+   if ((swizzle & 1) && (interp >= GL_REG_0_ATI)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(swizzle)");
+      return;
+   }
+   if (interp <= GL_TEXTURE7_ARB) {
+      GLuint tmp = interp - GL_TEXTURE0_ARB;
+      if ((((curProg->swizzlerq >> (tmp * 2)) & 3) != 0) &&
+          (((swizzle & 1) + 1) != ((curProg->swizzlerq >> (tmp * 2)) & 3))) {
+        _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(swizzle)");
+        return;
+      } else {
+        curProg->swizzlerq |= (((swizzle & 1) + 1) << (tmp * 2));
+      }
+   }
+
+   curProg->regsAssigned[curProg->cur_pass >> 1] |=  1 << (dst - GL_REG_0_ATI);
+   new_tex_inst(curProg);
+
+   /* add the instructions */
+   curI = &curProg->SetupInst[curProg->cur_pass >> 1][dst - GL_REG_0_ATI];
+
+   curI->Opcode = ATI_FRAGMENT_SHADER_SAMPLE_OP;
+   curI->src = interp;
+   curI->swizzle = swizzle;
+
+#if MESA_DEBUG_ATI_FS
+   _mesa_debug(ctx, "%s(%s, %s, %s)\n", __FUNCTION__,
+              _mesa_lookup_enum_by_nr(dst), _mesa_lookup_enum_by_nr(interp),
+              _mesa_lookup_enum_by_nr(swizzle));
+#endif
+}
+
+static void
+_mesa_FragmentOpXATI(GLint optype, GLuint arg_count, GLenum op, GLuint dst,
+                    GLuint dstMask, GLuint dstMod, GLuint arg1,
+                    GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
+                    GLuint arg2Rep, GLuint arg2Mod, GLuint arg3,
+                    GLuint arg3Rep, GLuint arg3Mod)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
+   GLint ci;
+   struct atifs_instruction *curI;
+   GLuint modtemp = dstMod & ~GL_SATURATE_BIT_ATI;
+
+   if (!ctx->ATIFragmentShader.Compiling) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(outsideShader)");
+      return;
+   }
+
+   if (curProg->cur_pass==0)
+      curProg->cur_pass=1;
+
+   else if (curProg->cur_pass==2)
+      curProg->cur_pass=3;
+
+   /* decide whether this is a new instruction or not ... all color instructions are new,
+      and alpha instructions might also be new if there was no preceding color inst */
+   if ((optype == 0) || (curProg->last_optype == optype)) {
+      if (curProg->numArithInstr[curProg->cur_pass >> 1] > 7) {
+        _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(instrCount)");
+        return;
+      }
+      /* easier to do that here slight side effect invalid instr will still be inserted as nops */
+      match_pair_inst(curProg, optype);
+      new_arith_inst(curProg);
+   }
+   curProg->last_optype = optype;
+   ci = curProg->numArithInstr[curProg->cur_pass >> 1] - 1;
+
+   /* add the instructions */
+   curI = &curProg->Instructions[curProg->cur_pass >> 1][ci];
+
+   /* error checking */
+   if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI)) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(dst)");
+      return;
+   }
+   if ((modtemp != GL_NONE) && (modtemp != GL_2X_BIT_ATI) &&
+      (modtemp != GL_4X_BIT_ATI) && (modtemp != GL_8X_BIT_ATI) &&
+      (modtemp != GL_HALF_BIT_ATI) && !(modtemp != GL_QUARTER_BIT_ATI) &&
+      (modtemp != GL_EIGHTH_BIT_ATI)) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(dstMod)%x", modtemp);
+      return;
+   }
+   /* op checking? Actually looks like that's missing in the spec but we'll do it anyway */
+   if (((op < GL_ADD_ATI) || (op > GL_DOT2_ADD_ATI)) && !(op == GL_MOV_ATI)) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(op)");
+      return;
+   }
+   if (optype == 1) {
+      if (((op == GL_DOT2_ADD_ATI) && (curI->Opcode[0] != GL_DOT2_ADD_ATI)) ||
+        ((op == GL_DOT3_ATI) && (curI->Opcode[0] != GL_DOT3_ATI)) ||
+        ((op == GL_DOT4_ATI) && (curI->Opcode[0] != GL_DOT4_ATI)) ||
+        ((op != GL_DOT4_ATI) && (curI->Opcode[0] == GL_DOT4_ATI))) {
+        _mesa_error(ctx, GL_INVALID_OPERATION, "AFragmentOpATI(op)");
+        return;
+      }
+   }
+   if ((op == GL_DOT4_ATI) &&
+      (((arg1 == GL_SECONDARY_INTERPOLATOR_ATI) && ((arg1Rep == GL_ALPHA) || (arg1Rep == GL_NONE))) ||
+      (((arg2 == GL_SECONDARY_INTERPOLATOR_ATI) && ((arg2Rep == GL_ALPHA) || (arg2Rep == GL_NONE)))))) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)");
+   }
+
+   if (!check_arith_arg(curProg, optype, arg1, arg1Rep)) {
+      return;
+   }
+   if (arg2) {
+      if (!check_arith_arg(curProg, optype, arg2, arg2Rep)) {
+        return;
+      }
+   }
+   if (arg3) {
+      if (!check_arith_arg(curProg, optype, arg3, arg3Rep)) {
+        return;
+      }
+      if ((arg1 >= GL_CON_0_ATI) && (arg1 <= GL_CON_7_ATI) &&
+         (arg2 >= GL_CON_0_ATI) && (arg2 <= GL_CON_7_ATI) &&
+         (arg3 >= GL_CON_0_ATI) && (arg3 <= GL_CON_7_ATI) &&
+         (arg1 != arg2) && (arg1 != arg3) && (arg2 != arg3)) {
+        _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(3Consts)");
+        return;
+      }
+   }
+
+   /* all ok - not all fully validated though (e.g. argNMod - spec doesn't say anything) */
+
+   curI->Opcode[optype] = op;
+   curI->SrcReg[optype][0].Index = arg1;
+   curI->SrcReg[optype][0].argRep = arg1Rep;
+   curI->SrcReg[optype][0].argMod = arg1Mod;
+   curI->ArgCount[optype] = arg_count;
+
+   if (arg2) {
+      curI->SrcReg[optype][1].Index = arg2;
+      curI->SrcReg[optype][1].argRep = arg2Rep;
+      curI->SrcReg[optype][1].argMod = arg2Mod;
+   }
+
+   if (arg3) {
+      curI->SrcReg[optype][2].Index = arg3;
+      curI->SrcReg[optype][2].argRep = arg3Rep;
+      curI->SrcReg[optype][2].argMod = arg3Mod;
+   }
+
+   curI->DstReg[optype].Index = dst;
+   curI->DstReg[optype].dstMod = dstMod;
+   curI->DstReg[optype].dstMask = dstMask;
+
+#if MESA_DEBUG_ATI_FS
+   debug_op(optype, arg_count, op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3, arg3Rep, arg3Mod);
+#endif
+
+}
+
+void GLAPIENTRY
+_mesa_ColorFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMask,
+                         GLuint dstMod, GLuint arg1, GLuint arg1Rep,
+                         GLuint arg1Mod)
+{
+   _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_COLOR_OP, 1, op, dst, dstMask,
+                       dstMod, arg1, arg1Rep, arg1Mod, 0, 0, 0, 0, 0, 0);
+}
+
+void GLAPIENTRY
+_mesa_ColorFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMask,
+                         GLuint dstMod, GLuint arg1, GLuint arg1Rep,
+                         GLuint arg1Mod, GLuint arg2, GLuint arg2Rep,
+                         GLuint arg2Mod)
+{
+   _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_COLOR_OP, 2, op, dst, dstMask,
+                       dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep,
+                       arg2Mod, 0, 0, 0);
+}
+
+void GLAPIENTRY
+_mesa_ColorFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMask,
+                         GLuint dstMod, GLuint arg1, GLuint arg1Rep,
+                         GLuint arg1Mod, GLuint arg2, GLuint arg2Rep,
+                         GLuint arg2Mod, GLuint arg3, GLuint arg3Rep,
+                         GLuint arg3Mod)
+{
+   _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_COLOR_OP, 3, op, dst, dstMask,
+                       dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep,
+                       arg2Mod, arg3, arg3Rep, arg3Mod);
+}
+
+void GLAPIENTRY
+_mesa_AlphaFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1,
+                         GLuint arg1Rep, GLuint arg1Mod)
+{
+   _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_ALPHA_OP, 1, op, dst, 0, dstMod,
+                       arg1, arg1Rep, arg1Mod, 0, 0, 0, 0, 0, 0);
+}
+
+void GLAPIENTRY
+_mesa_AlphaFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1,
+                         GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
+                         GLuint arg2Rep, GLuint arg2Mod)
+{
+   _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_ALPHA_OP, 2, op, dst, 0, dstMod,
+                       arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, 0, 0,
+                       0);
+}
+
+void GLAPIENTRY
+_mesa_AlphaFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1,
+                         GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
+                         GLuint arg2Rep, GLuint arg2Mod, GLuint arg3,
+                         GLuint arg3Rep, GLuint arg3Mod)
+{
+   _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_ALPHA_OP, 3, op, dst, 0, dstMod,
+                       arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3,
+                       arg3Rep, arg3Mod);
+}
+
+void GLAPIENTRY
+_mesa_SetFragmentShaderConstantATI(GLuint dst, const GLfloat * value)
+{
+   GLuint dstindex;
+   GET_CURRENT_CONTEXT(ctx);
+
+   if ((dst < GL_CON_0_ATI) || (dst > GL_CON_7_ATI)) {
+      /* spec says nothing about what should happen here but we can't just segfault...*/
+      _mesa_error(ctx, GL_INVALID_ENUM, "glSetFragmentShaderConstantATI(dst)");
+      return;
+   }
+
+   dstindex = dst - GL_CON_0_ATI;
+   if (ctx->ATIFragmentShader.Compiling) {
+      struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
+      COPY_4V(curProg->Constants[dstindex], value);
+      curProg->LocalConstDef |= 1 << dstindex;
+   }
+   else {
+      FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+      COPY_4V(ctx->ATIFragmentShader.GlobalConstants[dstindex], value);
+   }
+}
+
+#endif /* FEATURE_ATI_fragment_shader */
diff --git a/src/mesa/main/atifragshader.h b/src/mesa/main/atifragshader.h
new file mode 100644 (file)
index 0000000..31c335e
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Mesa 3-D graphics library ATI Fragment Shader
+ *
+ * Copyright (C) 2004  David Airlie   All Rights Reserved.
+ *
+ */
+
+#ifndef ATIFRAGSHADER_H
+#define ATIFRAGSHADER_H
+
+#include "main/mtypes.h"
+
+#define MAX_NUM_INSTRUCTIONS_PER_PASS_ATI 8
+#define MAX_NUM_PASSES_ATI                2
+#define MAX_NUM_FRAGMENT_REGISTERS_ATI    6
+
+struct ati_fs_opcode_st
+{
+   GLenum opcode;
+   GLint num_src_args;
+};
+
+extern struct ati_fs_opcode_st ati_fs_opcodes[];
+
+struct atifragshader_src_register
+{
+   GLuint Index;
+   GLuint argRep;
+   GLuint argMod;
+};
+
+struct atifragshader_dst_register
+{
+   GLuint Index;
+   GLuint dstMod;
+   GLuint dstMask;
+};
+
+#define ATI_FRAGMENT_SHADER_COLOR_OP 0
+#define ATI_FRAGMENT_SHADER_ALPHA_OP 1
+#define ATI_FRAGMENT_SHADER_PASS_OP  2
+#define ATI_FRAGMENT_SHADER_SAMPLE_OP 3
+
+/* two opcodes - one for color/one for alpha */
+/* up to three source registers for most ops */
+struct atifs_instruction
+{
+   GLenum Opcode[2];
+   GLuint ArgCount[2];
+   struct atifragshader_src_register SrcReg[2][3];
+   struct atifragshader_dst_register DstReg[2];
+};
+
+/* different from arithmetic shader instruction */
+struct atifs_setupinst
+{
+   GLenum Opcode;
+   GLuint src;
+   GLenum swizzle;
+};
+
+
+#if FEATURE_ATI_fragment_shader
+
+extern void
+_mesa_init_ati_fragment_shader_dispatch(struct _glapi_table *disp);
+
+extern struct ati_fragment_shader *
+_mesa_new_ati_fragment_shader(GLcontext *ctx, GLuint id);
+
+extern void
+_mesa_delete_ati_fragment_shader(GLcontext *ctx,
+                                 struct ati_fragment_shader *s);
+
+
+extern GLuint GLAPIENTRY _mesa_GenFragmentShadersATI(GLuint range);
+
+extern void GLAPIENTRY _mesa_BindFragmentShaderATI(GLuint id);
+
+extern void GLAPIENTRY _mesa_DeleteFragmentShaderATI(GLuint id);
+
+extern void GLAPIENTRY _mesa_BeginFragmentShaderATI(void);
+
+extern void GLAPIENTRY _mesa_EndFragmentShaderATI(void);
+
+extern void GLAPIENTRY
+_mesa_PassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle);
+
+extern void GLAPIENTRY
+_mesa_SampleMapATI(GLuint dst, GLuint interp, GLenum swizzle);
+
+extern void GLAPIENTRY
+_mesa_ColorFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMask,
+                         GLuint dstMod, GLuint arg1, GLuint arg1Rep,
+                         GLuint arg1Mod);
+
+extern void GLAPIENTRY
+_mesa_ColorFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMask,
+                         GLuint dstMod, GLuint arg1, GLuint arg1Rep,
+                         GLuint arg1Mod, GLuint arg2, GLuint arg2Rep,
+                         GLuint arg2Mod);
+
+extern void GLAPIENTRY
+_mesa_ColorFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMask,
+                         GLuint dstMod, GLuint arg1, GLuint arg1Rep,
+                         GLuint arg1Mod, GLuint arg2, GLuint arg2Rep,
+                         GLuint arg2Mod, GLuint arg3, GLuint arg3Rep,
+                         GLuint arg3Mod);
+
+extern void GLAPIENTRY
+_mesa_AlphaFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1,
+                         GLuint arg1Rep, GLuint arg1Mod);
+
+extern void GLAPIENTRY
+_mesa_AlphaFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1,
+                         GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
+                         GLuint arg2Rep, GLuint arg2Mod);
+
+extern void GLAPIENTRY
+_mesa_AlphaFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1,
+                         GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
+                         GLuint arg2Rep, GLuint arg2Mod, GLuint arg3,
+                         GLuint arg3Rep, GLuint arg3Mod);
+
+extern void GLAPIENTRY
+_mesa_SetFragmentShaderConstantATI(GLuint dst, const GLfloat * value);
+
+#else /* FEATURE_ATI_fragment_shader */
+
+static INLINE void
+_mesa_init_ati_fragment_shader_dispatch(struct _glapi_table *disp)
+{
+}
+
+static INLINE struct ati_fragment_shader *
+_mesa_new_ati_fragment_shader(GLcontext *ctx, GLuint id)
+{
+   return NULL;
+}
+
+static INLINE void
+_mesa_delete_ati_fragment_shader(GLcontext *ctx,
+                                 struct ati_fragment_shader *s)
+{
+}
+
+#endif /* FEATURE_ATI_fragment_shader */
+
+#endif /* ATIFRAGSHADER_H */
index 235cafcf1ed15579700d8047fe8f4beaaba99fdf..4e232b5731f6fca2283b61c717af494e8b0e3193 100644 (file)
@@ -1924,7 +1924,7 @@ _mesa_BufferObjectUnpurgeable(GLcontext *ctx, GLuint name, GLenum option)
 
    bufObj->Purgeable = GL_FALSE;
 
-   retval = GL_RETAINED_APPLE;
+   retval = option;
    if (ctx->Driver.BufferObjectUnpurgeable)
       retval = ctx->Driver.BufferObjectUnpurgeable(ctx, bufObj, option);
 
@@ -1954,11 +1954,11 @@ _mesa_RenderObjectUnpurgeable(GLcontext *ctx, GLuint name, GLenum option)
 
    bufObj->Purgeable = GL_FALSE;
 
-   retval = GL_RETAINED_APPLE;
+   retval = option;
    if (ctx->Driver.RenderObjectUnpurgeable)
       retval = ctx->Driver.RenderObjectUnpurgeable(ctx, bufObj, option);
 
-   return option;
+   return retval;
 }
 
 
@@ -1984,7 +1984,7 @@ _mesa_TextureObjectUnpurgeable(GLcontext *ctx, GLuint name, GLenum option)
 
    bufObj->Purgeable = GL_FALSE;
 
-   retval = GL_RETAINED_APPLE;
+   retval = option;
    if (ctx->Driver.TextureObjectUnpurgeable)
       retval = ctx->Driver.TextureObjectUnpurgeable(ctx, bufObj, option);
 
index 84f7665fc0759d58ac06e865fe526fd08c9ec7d1..32f7d969d8da183a549fb7cd9cccef057f4e7355 100644 (file)
 /** For GL_EXT_transform_feedback */
 #define MAX_FEEDBACK_ATTRIBS 32
 
+/** For GL_ARB_geometry_shader4 */
+/*@{*/
+#define MAX_GEOMETRY_TEXTURE_IMAGE_UNITS             8
+#define MAX_GEOMETRY_VARYING_COMPONENTS              32
+#define MAX_VERTEX_VARYING_COMPONENTS                32
+#define MAX_GEOMETRY_UNIFORM_COMPONENTS              512
+#define MAX_GEOMETRY_OUTPUT_VERTICES                 256
+#define MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS         1024
+/*@}*/
 
 
 /**
index e140a21b35486a71f2f1b664d9395c8d95505ebf..a369532e99cd68d9814a3a34231d6f8e1a72e678 100644 (file)
 #include "remap.h"
 #include "scissor.h"
 #include "shared.h"
+#include "shaderobj.h"
 #include "simple_list.h"
 #include "state.h"
 #include "stencil.h"
 #include "version.h"
 #include "viewport.h"
 #include "vtxfmt.h"
-#include "shader/program.h"
-#include "shader/prog_print.h"
-#include "shader/shader_api.h"
+#include "program/program.h"
+#include "program/prog_print.h"
 #if _HAVE_FULL_GL
 #include "math/m_matrix.h"
 #endif
@@ -347,6 +347,8 @@ dummy_enum_func(void)
    gl_texture_index ti;
    gl_vert_attrib va;
    gl_vert_result vr;
+   gl_geom_attrib ga;
+   gl_geom_result gr;
 
    (void) bi;
    (void) ci;
@@ -356,6 +358,8 @@ dummy_enum_func(void)
    (void) ti;
    (void) va;
    (void) vr;
+   (void) ga;
+   (void) gr;
 }
 
 
@@ -478,10 +482,21 @@ init_program_limits(GLenum type, struct gl_program_constants *prog)
       prog->MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
       prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
    }
-   else {
+   else if (type == GL_FRAGMENT_PROGRAM_ARB) {
       prog->MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
       prog->MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS;
       prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
+   } else {
+      prog->MaxParameters = MAX_NV_VERTEX_PROGRAM_PARAMS;
+      prog->MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
+      prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
+
+      prog->MaxGeometryTextureImageUnits = MAX_GEOMETRY_TEXTURE_IMAGE_UNITS;
+      prog->MaxGeometryVaryingComponents = MAX_GEOMETRY_VARYING_COMPONENTS;
+      prog->MaxVertexVaryingComponents = MAX_VERTEX_VARYING_COMPONENTS;
+      prog->MaxGeometryUniformComponents = MAX_GEOMETRY_UNIFORM_COMPONENTS;
+      prog->MaxGeometryOutputVertices = MAX_GEOMETRY_OUTPUT_VERTICES;
+      prog->MaxGeometryTotalOutputComponents = MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS;
    }
 
    /* Set the native limits to zero.  This implies that there is no native
@@ -546,6 +561,9 @@ _mesa_init_constants(GLcontext *ctx)
 #endif
 #if FEATURE_ARB_fragment_program
    init_program_limits(GL_FRAGMENT_PROGRAM_ARB, &ctx->Const.FragmentProgram);
+#endif
+#if FEATURE_ARB_geometry_shader4
+   init_program_limits(MESA_GEOMETRY_PROGRAM, &ctx->Const.GeometryProgram);
 #endif
    ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
    ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH;
@@ -1462,6 +1480,8 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
       if (newCtx->FirstTimeCurrent) {
          _mesa_compute_version(newCtx);
 
+         newCtx->Extensions.String = _mesa_make_extension_string(newCtx);
+
          check_context_limits(newCtx);
 
          /* We can use this to help debug user's problems.  Tell them to set
index 53e44533cb3ddbdb0472c1d255cd91649d74e69a..825073ca886cd0c068f8344285ee9d7416e8a177 100644 (file)
@@ -828,54 +828,12 @@ struct dd_function_table {
     * \name GLSL-related functions (ARB extensions and OpenGL 2.x)
     */
    /*@{*/
-   void (*AttachShader)(GLcontext *ctx, GLuint program, GLuint shader);
-   void (*BindAttribLocation)(GLcontext *ctx, GLuint program, GLuint index,
-                              const GLcharARB *name);
-   void (*CompileShader)(GLcontext *ctx, GLuint shader);
-   GLuint (*CreateShader)(GLcontext *ctx, GLenum type);
-   GLuint (*CreateProgram)(GLcontext *ctx);
-   void (*DeleteProgram2)(GLcontext *ctx, GLuint program);
-   void (*DeleteShader)(GLcontext *ctx, GLuint shader);
-   void (*DetachShader)(GLcontext *ctx, GLuint program, GLuint shader);
-   void (*GetActiveAttrib)(GLcontext *ctx, GLuint program, GLuint index,
-                           GLsizei maxLength, GLsizei * length, GLint * size,
-                           GLenum * type, GLcharARB * name);
-   void (*GetActiveUniform)(GLcontext *ctx, GLuint program, GLuint index,
-                            GLsizei maxLength, GLsizei *length, GLint *size,
-                            GLenum *type, GLcharARB *name);
-   void (*GetAttachedShaders)(GLcontext *ctx, GLuint program, GLsizei maxCount,
-                              GLsizei *count, GLuint *obj);
-   GLint (*GetAttribLocation)(GLcontext *ctx, GLuint program,
-                              const GLcharARB *name);
-   GLuint (*GetHandle)(GLcontext *ctx, GLenum pname);
-   void (*GetProgramiv)(GLcontext *ctx, GLuint program,
-                        GLenum pname, GLint *params);
-   void (*GetProgramInfoLog)(GLcontext *ctx, GLuint program, GLsizei bufSize,
-                             GLsizei *length, GLchar *infoLog);
-   void (*GetShaderiv)(GLcontext *ctx, GLuint shader,
-                       GLenum pname, GLint *params);
-   void (*GetShaderInfoLog)(GLcontext *ctx, GLuint shader, GLsizei bufSize,
-                            GLsizei *length, GLchar *infoLog);
-   void (*GetShaderSource)(GLcontext *ctx, GLuint shader, GLsizei maxLength,
-                           GLsizei *length, GLcharARB *sourceOut);
-   void (*GetUniformfv)(GLcontext *ctx, GLuint program, GLint location,
-                        GLfloat *params);
-   void (*GetUniformiv)(GLcontext *ctx, GLuint program, GLint location,
-                        GLint *params);
-   GLint (*GetUniformLocation)(GLcontext *ctx, GLuint program,
-                               const GLcharARB *name);
-   GLboolean (*IsProgram)(GLcontext *ctx, GLuint name);
-   GLboolean (*IsShader)(GLcontext *ctx, GLuint name);
-   void (*LinkProgram)(GLcontext *ctx, GLuint program);
-   void (*ShaderSource)(GLcontext *ctx, GLuint shader, const GLchar *source);
-   void (*Uniform)(GLcontext *ctx, GLint location, GLsizei count,
-                   const GLvoid *values, GLenum type);
-   void (*UniformMatrix)(GLcontext *ctx, GLint cols, GLint rows,
-                         GLint location, GLsizei count,
-                         GLboolean transpose, const GLfloat *values);
-   void (*UseProgram)(GLcontext *ctx, GLuint program);
-   void (*ValidateProgram)(GLcontext *ctx, GLuint program);
-   /* XXX many more to come */
+   struct gl_shader *(*NewShader)(GLcontext *ctx, GLuint name, GLenum type);
+   void (*DeleteShader)(GLcontext *ctx, struct gl_shader *shader);
+   struct gl_shader_program *(*NewShaderProgram)(GLcontext *ctx, GLuint name);
+   void (*DeleteShaderProgram)(GLcontext *ctx,
+                               struct gl_shader_program *shProg);
+   void (*UseProgram)(GLcontext *ctx, struct gl_shader_program *shProg);
    /*@}*/
 
 
index 892520b695908a5bec5b43b55e095ade9f2e949f..885e718a767872687c3d586cb65f4f985d12c1fe 100644 (file)
@@ -62,8 +62,8 @@ nop_get_pointer(GLcontext *ctx, struct gl_renderbuffer *rb, GLint x, GLint y)
 static void
 delete_wrapper(struct gl_renderbuffer *rb)
 {
-   ASSERT(rb->Format == MESA_FORMAT_Z24_S8 ||
-          rb->Format == MESA_FORMAT_S8_Z24);
+   ASSERT(rb->Format == MESA_FORMAT_S8 ||
+          rb->Format == MESA_FORMAT_X8_Z24);
    _mesa_reference_renderbuffer(&rb->Wrapped, NULL);
    free(rb);
 }
@@ -83,7 +83,9 @@ alloc_wrapper_storage(GLcontext *ctx, struct gl_renderbuffer *rb,
    (void) internalFormat;
 
    ASSERT(dsrb->Format == MESA_FORMAT_Z24_S8 ||
-          dsrb->Format == MESA_FORMAT_S8_Z24);
+          dsrb->Format == MESA_FORMAT_Z24_X8 ||
+          dsrb->Format == MESA_FORMAT_S8_Z24 ||
+          dsrb->Format == MESA_FORMAT_X8_Z24);
 
    retVal = dsrb->AllocStorage(ctx, dsrb, dsrb->InternalFormat, width, height);
    if (retVal) {
@@ -352,16 +354,21 @@ _mesa_new_z24_renderbuffer_wrapper(GLcontext *ctx,
    struct gl_renderbuffer *z24rb;
 
    ASSERT(dsrb->Format == MESA_FORMAT_Z24_S8 ||
-          dsrb->Format == MESA_FORMAT_S8_Z24);
+          dsrb->Format == MESA_FORMAT_Z24_X8 ||
+          dsrb->Format == MESA_FORMAT_S8_Z24 ||
+          dsrb->Format == MESA_FORMAT_X8_Z24);
    ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
 
    z24rb = _mesa_new_renderbuffer(ctx, 0);
    if (!z24rb)
       return NULL;
 
+   /* NOTE: need to do manual refcounting here */
    z24rb->Wrapped = dsrb;
+   dsrb->RefCount++;
+
    z24rb->Name = dsrb->Name;
-   z24rb->RefCount = 1;
+   z24rb->RefCount = 0;
    z24rb->Width = dsrb->Width;
    z24rb->Height = dsrb->Height;
    z24rb->InternalFormat = GL_DEPTH_COMPONENT24;
@@ -642,9 +649,12 @@ _mesa_new_s8_renderbuffer_wrapper(GLcontext *ctx, struct gl_renderbuffer *dsrb)
    if (!s8rb)
       return NULL;
 
+   /* NOTE: need to do manual refcounting here */
    s8rb->Wrapped = dsrb;
+   dsrb->RefCount++;
+
    s8rb->Name = dsrb->Name;
-   s8rb->RefCount = 1;
+   s8rb->RefCount = 0;
    s8rb->Width = dsrb->Width;
    s8rb->Height = dsrb->Height;
    s8rb->InternalFormat = GL_STENCIL_INDEX8_EXT;
index 37a97513453c6d9844dd918a847eb4f9274af0da..727414d529f83bd8fa37c95f6cff2c7eddbfe26d 100644 (file)
@@ -34,6 +34,9 @@
 #include "api_arrayelt.h"
 #include "api_exec.h"
 #include "api_loopback.h"
+#if FEATURE_ATI_fragment_shader
+#include "atifragshader.h"
+#endif
 #include "config.h"
 #include "mfeatures.h"
 #if FEATURE_ARB_vertex_buffer_object
 #include "mtypes.h"
 #include "varray.h"
 #if FEATURE_ARB_vertex_program || FEATURE_ARB_fragment_program
-#include "shader/arbprogram.h"
+#include "arbprogram.h"
 #endif
 #if FEATURE_NV_vertex_program || FEATURE_NV_fragment_program
-#include "shader/nvprogram.h"
-#endif
-#if FEATURE_ATI_fragment_shader
-#include "shader/atifragshader.h"
+#include "nvprogram.h"
 #endif
 
 #include "math/m_matrix.h"
index 13705b9f67166d86df1b2c28ca0ed97c0327923e..bc18e1b1131f7715c86451a8e05348af61c8d392 100644 (file)
@@ -607,6 +607,7 @@ LONGSTRING static const char enum_string_table[] =
    "GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE\0"
    "GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE\0"
    "GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE\0"
+   "GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB\0"
    "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME\0"
    "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT\0"
    "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES\0"
@@ -645,6 +646,8 @@ LONGSTRING static const char enum_string_table[] =
    "GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT\0"
    "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\0"
    "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES\0"
+   "GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB\0"
+   "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB\0"
    "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\0"
    "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT\0"
    "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES\0"
@@ -677,6 +680,10 @@ LONGSTRING static const char enum_string_table[] =
    "GL_GENERATE_MIPMAP_HINT\0"
    "GL_GENERATE_MIPMAP_HINT_SGIS\0"
    "GL_GENERATE_MIPMAP_SGIS\0"
+   "GL_GEOMETRY_INPUT_TYPE_ARB\0"
+   "GL_GEOMETRY_OUTPUT_TYPE_ARB\0"
+   "GL_GEOMETRY_SHADER_ARB\0"
+   "GL_GEOMETRY_VERTICES_OUT_ARB\0"
    "GL_GEQUAL\0"
    "GL_GREATER\0"
    "GL_GREEN\0"
@@ -790,6 +797,7 @@ LONGSTRING static const char enum_string_table[] =
    "GL_LINEAR_MIPMAP_LINEAR\0"
    "GL_LINEAR_MIPMAP_NEAREST\0"
    "GL_LINES\0"
+   "GL_LINES_ADJACENCY_ARB\0"
    "GL_LINE_BIT\0"
    "GL_LINE_LOOP\0"
    "GL_LINE_RESET_TOKEN\0"
@@ -799,6 +807,7 @@ LONGSTRING static const char enum_string_table[] =
    "GL_LINE_STIPPLE_PATTERN\0"
    "GL_LINE_STIPPLE_REPEAT\0"
    "GL_LINE_STRIP\0"
+   "GL_LINE_STRIP_ADJACENCY_ARB\0"
    "GL_LINE_TOKEN\0"
    "GL_LINE_WIDTH\0"
    "GL_LINE_WIDTH_GRANULARITY\0"
@@ -984,6 +993,11 @@ LONGSTRING static const char enum_string_table[] =
    "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS\0"
    "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB\0"
    "GL_MAX_FRAGMENT_UNIFORM_VECTORS\0"
+   "GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB\0"
+   "GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB\0"
+   "GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB\0"
+   "GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB\0"
+   "GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB\0"
    "GL_MAX_LIGHTS\0"
    "GL_MAX_LIST_NESTING\0"
    "GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB\0"
@@ -1044,6 +1058,7 @@ LONGSTRING static const char enum_string_table[] =
    "GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT\0"
    "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT\0"
    "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT\0"
+   "GL_MAX_VARYING_COMPONENTS\0"
    "GL_MAX_VARYING_FLOATS\0"
    "GL_MAX_VARYING_FLOATS_ARB\0"
    "GL_MAX_VARYING_VECTORS\0"
@@ -1056,6 +1071,7 @@ LONGSTRING static const char enum_string_table[] =
    "GL_MAX_VERTEX_UNIFORM_VECTORS\0"
    "GL_MAX_VERTEX_UNITS_ARB\0"
    "GL_MAX_VERTEX_UNITS_OES\0"
+   "GL_MAX_VERTEX_VARYING_COMPONENTS_ARB\0"
    "GL_MAX_VIEWPORT_DIMS\0"
    "GL_MEDIUM_FLOAT\0"
    "GL_MEDIUM_INT\0"
@@ -1378,6 +1394,7 @@ LONGSTRING static const char enum_string_table[] =
    "GL_PROGRAM_OBJECT_ARB\0"
    "GL_PROGRAM_PARAMETERS_ARB\0"
    "GL_PROGRAM_PARAMETER_NV\0"
+   "GL_PROGRAM_POINT_SIZE_ARB\0"
    "GL_PROGRAM_RESIDENT_NV\0"
    "GL_PROGRAM_STRING_ARB\0"
    "GL_PROGRAM_STRING_NV\0"
@@ -1931,9 +1948,13 @@ LONGSTRING static const char enum_string_table[] =
    "GL_TRACK_MATRIX_NV\0"
    "GL_TRACK_MATRIX_TRANSFORM_NV\0"
    "GL_TRANSFORM_BIT\0"
+   "GL_TRANSFORM_FEEDBACK\0"
+   "GL_TRANSFORM_FEEDBACK_BINDING\0"
+   "GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE\0"
    "GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT\0"
    "GL_TRANSFORM_FEEDBACK_BUFFER_EXT\0"
    "GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT\0"
+   "GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED\0"
    "GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT\0"
    "GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT\0"
    "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT\0"
@@ -1950,9 +1971,11 @@ LONGSTRING static const char enum_string_table[] =
    "GL_TRANSPOSE_TEXTURE_MATRIX\0"
    "GL_TRANSPOSE_TEXTURE_MATRIX_ARB\0"
    "GL_TRIANGLES\0"
+   "GL_TRIANGLES_ADJACENCY_ARB\0"
    "GL_TRIANGLE_FAN\0"
    "GL_TRIANGLE_MESH_SUN\0"
    "GL_TRIANGLE_STRIP\0"
+   "GL_TRIANGLE_STRIP_ADJACENCY_ARB\0"
    "GL_TRUE\0"
    "GL_UNDEFINED_APPLE\0"
    "GL_UNPACK_ALIGNMENT\0"
@@ -2080,7 +2103,7 @@ LONGSTRING static const char enum_string_table[] =
    "GL_ZOOM_Y\0"
    ;
 
-static const enum_elt all_enums[2042] =
+static const enum_elt all_enums[2065] =
 {
    {     0, 0x00000600 }, /* GL_2D */
    {     6, 0x00001407 }, /* GL_2_BYTES */
@@ -2653,1556 +2676,1583 @@ static const enum_elt all_enums[2042] =
    { 11534, 0x00008211 }, /* GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */
    { 11575, 0x00008216 }, /* GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */
    { 11612, 0x00008213 }, /* GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */
-   { 11649, 0x00008CD1 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */
-   { 11687, 0x00008CD1 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT */
-   { 11729, 0x00008CD1 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES */
-   { 11771, 0x00008CD0 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */
-   { 11809, 0x00008CD0 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT */
-   { 11851, 0x00008CD0 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES */
-   { 11893, 0x00008212 }, /* GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */
-   { 11928, 0x00008217 }, /* GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */
-   { 11967, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT */
-   { 12016, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES */
-   { 12065, 0x00008CD3 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */
-   { 12113, 0x00008CD3 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT */
-   { 12165, 0x00008CD3 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES */
-   { 12217, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
-   { 12257, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */
-   { 12301, 0x00008CD2 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */
-   { 12341, 0x00008CD2 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT */
-   { 12385, 0x00008CD2 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES */
-   { 12429, 0x00008CA6 }, /* GL_FRAMEBUFFER_BINDING */
-   { 12452, 0x00008CA6 }, /* GL_FRAMEBUFFER_BINDING_EXT */
-   { 12479, 0x00008CA6 }, /* GL_FRAMEBUFFER_BINDING_OES */
-   { 12506, 0x00008CD5 }, /* GL_FRAMEBUFFER_COMPLETE */
-   { 12530, 0x00008CD5 }, /* GL_FRAMEBUFFER_COMPLETE_EXT */
-   { 12558, 0x00008CD5 }, /* GL_FRAMEBUFFER_COMPLETE_OES */
-   { 12586, 0x00008218 }, /* GL_FRAMEBUFFER_DEFAULT */
-   { 12609, 0x00008D40 }, /* GL_FRAMEBUFFER_EXT */
-   { 12628, 0x00008CD6 }, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */
-   { 12665, 0x00008CD6 }, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT */
-   { 12706, 0x00008CD6 }, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES */
-   { 12747, 0x00008CD9 }, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS */
-   { 12784, 0x00008CD9 }, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT */
-   { 12825, 0x00008CD9 }, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES */
-   { 12866, 0x00008CDB }, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER */
-   { 12904, 0x00008CDB }, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT */
-   { 12946, 0x00008CDB }, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES */
-   { 12988, 0x00008CD8 }, /* GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT */
-   { 13039, 0x00008CDA }, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT */
-   { 13077, 0x00008CDA }, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES */
-   { 13115, 0x00008CD7 }, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */
-   { 13160, 0x00008CD7 }, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT */
-   { 13209, 0x00008CD7 }, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES */
-   { 13258, 0x00008D56 }, /* GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */
-   { 13296, 0x00008D56 }, /* GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT */
-   { 13338, 0x00008CDC }, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER */
-   { 13376, 0x00008CDC }, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT */
-   { 13418, 0x00008CDC }, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES */
-   { 13460, 0x00008D40 }, /* GL_FRAMEBUFFER_OES */
-   { 13479, 0x00008CDE }, /* GL_FRAMEBUFFER_STATUS_ERROR_EXT */
-   { 13511, 0x00008219 }, /* GL_FRAMEBUFFER_UNDEFINED */
-   { 13536, 0x00008CDD }, /* GL_FRAMEBUFFER_UNSUPPORTED */
-   { 13563, 0x00008CDD }, /* GL_FRAMEBUFFER_UNSUPPORTED_EXT */
-   { 13594, 0x00008CDD }, /* GL_FRAMEBUFFER_UNSUPPORTED_OES */
-   { 13625, 0x00000404 }, /* GL_FRONT */
-   { 13634, 0x00000408 }, /* GL_FRONT_AND_BACK */
-   { 13652, 0x00000B46 }, /* GL_FRONT_FACE */
-   { 13666, 0x00000400 }, /* GL_FRONT_LEFT */
-   { 13680, 0x00000401 }, /* GL_FRONT_RIGHT */
-   { 13695, 0x00008006 }, /* GL_FUNC_ADD */
-   { 13707, 0x00008006 }, /* GL_FUNC_ADD_EXT */
-   { 13723, 0x00008006 }, /* GL_FUNC_ADD_OES */
-   { 13739, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT */
-   { 13764, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT_EXT */
-   { 13793, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT_OES */
-   { 13822, 0x0000800A }, /* GL_FUNC_SUBTRACT */
-   { 13839, 0x0000800A }, /* GL_FUNC_SUBTRACT_EXT */
-   { 13860, 0x0000800A }, /* GL_FUNC_SUBTRACT_OES */
-   { 13881, 0x00008191 }, /* GL_GENERATE_MIPMAP */
-   { 13900, 0x00008192 }, /* GL_GENERATE_MIPMAP_HINT */
-   { 13924, 0x00008192 }, /* GL_GENERATE_MIPMAP_HINT_SGIS */
-   { 13953, 0x00008191 }, /* GL_GENERATE_MIPMAP_SGIS */
-   { 13977, 0x00000206 }, /* GL_GEQUAL */
-   { 13987, 0x00000204 }, /* GL_GREATER */
-   { 13998, 0x00001904 }, /* GL_GREEN */
-   { 14007, 0x00000D19 }, /* GL_GREEN_BIAS */
-   { 14021, 0x00000D53 }, /* GL_GREEN_BITS */
-   { 14035, 0x00000D18 }, /* GL_GREEN_SCALE */
-   { 14050, 0x0000140B }, /* GL_HALF_FLOAT */
-   { 14064, 0x00008D61 }, /* GL_HALF_FLOAT_OES */
-   { 14082, 0x00008DF2 }, /* GL_HIGH_FLOAT */
-   { 14096, 0x00008DF5 }, /* GL_HIGH_INT */
-   { 14108, 0x00008000 }, /* GL_HINT_BIT */
-   { 14120, 0x00008024 }, /* GL_HISTOGRAM */
-   { 14133, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE */
-   { 14157, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE_EXT */
-   { 14185, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE */
-   { 14208, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE_EXT */
-   { 14235, 0x00008024 }, /* GL_HISTOGRAM_EXT */
-   { 14252, 0x00008027 }, /* GL_HISTOGRAM_FORMAT */
-   { 14272, 0x00008027 }, /* GL_HISTOGRAM_FORMAT_EXT */
-   { 14296, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE */
-   { 14320, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE_EXT */
-   { 14348, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE */
-   { 14376, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE_EXT */
-   { 14408, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE */
-   { 14430, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE_EXT */
-   { 14456, 0x0000802D }, /* GL_HISTOGRAM_SINK */
-   { 14474, 0x0000802D }, /* GL_HISTOGRAM_SINK_EXT */
-   { 14496, 0x00008026 }, /* GL_HISTOGRAM_WIDTH */
-   { 14515, 0x00008026 }, /* GL_HISTOGRAM_WIDTH_EXT */
-   { 14538, 0x0000862A }, /* GL_IDENTITY_NV */
-   { 14553, 0x00008150 }, /* GL_IGNORE_BORDER_HP */
-   { 14573, 0x00008B9B }, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT */
-   { 14609, 0x00008B9B }, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */
-   { 14649, 0x00008B9A }, /* GL_IMPLEMENTATION_COLOR_READ_TYPE */
-   { 14683, 0x00008B9A }, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */
-   { 14721, 0x00001E02 }, /* GL_INCR */
-   { 14729, 0x00008507 }, /* GL_INCR_WRAP */
-   { 14742, 0x00008507 }, /* GL_INCR_WRAP_EXT */
-   { 14759, 0x00008222 }, /* GL_INDEX */
-   { 14768, 0x00008077 }, /* GL_INDEX_ARRAY */
-   { 14783, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING */
-   { 14813, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING_ARB */
-   { 14847, 0x00008091 }, /* GL_INDEX_ARRAY_POINTER */
-   { 14870, 0x00008086 }, /* GL_INDEX_ARRAY_STRIDE */
-   { 14892, 0x00008085 }, /* GL_INDEX_ARRAY_TYPE */
-   { 14912, 0x00000D51 }, /* GL_INDEX_BITS */
-   { 14926, 0x00000C20 }, /* GL_INDEX_CLEAR_VALUE */
-   { 14947, 0x00000BF1 }, /* GL_INDEX_LOGIC_OP */
-   { 14965, 0x00000C30 }, /* GL_INDEX_MODE */
-   { 14979, 0x00000D13 }, /* GL_INDEX_OFFSET */
-   { 14995, 0x00000D12 }, /* GL_INDEX_SHIFT */
-   { 15010, 0x00000C21 }, /* GL_INDEX_WRITEMASK */
-   { 15029, 0x00008B84 }, /* GL_INFO_LOG_LENGTH */
-   { 15048, 0x00001404 }, /* GL_INT */
-   { 15055, 0x00008049 }, /* GL_INTENSITY */
-   { 15068, 0x0000804C }, /* GL_INTENSITY12 */
-   { 15083, 0x0000804C }, /* GL_INTENSITY12_EXT */
-   { 15102, 0x0000804D }, /* GL_INTENSITY16 */
-   { 15117, 0x0000804D }, /* GL_INTENSITY16_EXT */
-   { 15136, 0x0000804A }, /* GL_INTENSITY4 */
-   { 15150, 0x0000804A }, /* GL_INTENSITY4_EXT */
-   { 15168, 0x0000804B }, /* GL_INTENSITY8 */
-   { 15182, 0x0000804B }, /* GL_INTENSITY8_EXT */
-   { 15200, 0x00008049 }, /* GL_INTENSITY_EXT */
-   { 15217, 0x00008C8C }, /* GL_INTERLEAVED_ATTRIBS_EXT */
-   { 15244, 0x00008575 }, /* GL_INTERPOLATE */
-   { 15259, 0x00008575 }, /* GL_INTERPOLATE_ARB */
-   { 15278, 0x00008575 }, /* GL_INTERPOLATE_EXT */
-   { 15297, 0x00008DF7 }, /* GL_INT_10_10_10_2_OES */
-   { 15319, 0x00008B53 }, /* GL_INT_VEC2 */
-   { 15331, 0x00008B53 }, /* GL_INT_VEC2_ARB */
-   { 15347, 0x00008B54 }, /* GL_INT_VEC3 */
-   { 15359, 0x00008B54 }, /* GL_INT_VEC3_ARB */
-   { 15375, 0x00008B55 }, /* GL_INT_VEC4 */
-   { 15387, 0x00008B55 }, /* GL_INT_VEC4_ARB */
-   { 15403, 0x00000500 }, /* GL_INVALID_ENUM */
-   { 15419, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION */
-   { 15452, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION_EXT */
-   { 15489, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION_OES */
-   { 15526, 0x00000502 }, /* GL_INVALID_OPERATION */
-   { 15547, 0x00000501 }, /* GL_INVALID_VALUE */
-   { 15564, 0x0000862B }, /* GL_INVERSE_NV */
-   { 15578, 0x0000862D }, /* GL_INVERSE_TRANSPOSE_NV */
-   { 15602, 0x0000150A }, /* GL_INVERT */
-   { 15612, 0x00001E00 }, /* GL_KEEP */
-   { 15620, 0x00008E4E }, /* GL_LAST_VERTEX_CONVENTION */
-   { 15646, 0x00008E4E }, /* GL_LAST_VERTEX_CONVENTION_EXT */
-   { 15676, 0x00000406 }, /* GL_LEFT */
-   { 15684, 0x00000203 }, /* GL_LEQUAL */
-   { 15694, 0x00000201 }, /* GL_LESS */
-   { 15702, 0x00004000 }, /* GL_LIGHT0 */
-   { 15712, 0x00004001 }, /* GL_LIGHT1 */
-   { 15722, 0x00004002 }, /* GL_LIGHT2 */
-   { 15732, 0x00004003 }, /* GL_LIGHT3 */
-   { 15742, 0x00004004 }, /* GL_LIGHT4 */
-   { 15752, 0x00004005 }, /* GL_LIGHT5 */
-   { 15762, 0x00004006 }, /* GL_LIGHT6 */
-   { 15772, 0x00004007 }, /* GL_LIGHT7 */
-   { 15782, 0x00000B50 }, /* GL_LIGHTING */
-   { 15794, 0x00000040 }, /* GL_LIGHTING_BIT */
-   { 15810, 0x00000B53 }, /* GL_LIGHT_MODEL_AMBIENT */
-   { 15833, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL */
-   { 15862, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL_EXT */
-   { 15895, 0x00000B51 }, /* GL_LIGHT_MODEL_LOCAL_VIEWER */
-   { 15923, 0x00000B52 }, /* GL_LIGHT_MODEL_TWO_SIDE */
-   { 15947, 0x00001B01 }, /* GL_LINE */
-   { 15955, 0x00002601 }, /* GL_LINEAR */
-   { 15965, 0x00001208 }, /* GL_LINEAR_ATTENUATION */
-   { 15987, 0x00008170 }, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */
-   { 16017, 0x0000844F }, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */
-   { 16048, 0x00002703 }, /* GL_LINEAR_MIPMAP_LINEAR */
-   { 16072, 0x00002701 }, /* GL_LINEAR_MIPMAP_NEAREST */
-   { 16097, 0x00000001 }, /* GL_LINES */
-   { 16106, 0x00000004 }, /* GL_LINE_BIT */
-   { 16118, 0x00000002 }, /* GL_LINE_LOOP */
-   { 16131, 0x00000707 }, /* GL_LINE_RESET_TOKEN */
-   { 16151, 0x00000B20 }, /* GL_LINE_SMOOTH */
-   { 16166, 0x00000C52 }, /* GL_LINE_SMOOTH_HINT */
-   { 16186, 0x00000B24 }, /* GL_LINE_STIPPLE */
-   { 16202, 0x00000B25 }, /* GL_LINE_STIPPLE_PATTERN */
-   { 16226, 0x00000B26 }, /* GL_LINE_STIPPLE_REPEAT */
-   { 16249, 0x00000003 }, /* GL_LINE_STRIP */
-   { 16263, 0x00000702 }, /* GL_LINE_TOKEN */
-   { 16277, 0x00000B21 }, /* GL_LINE_WIDTH */
-   { 16291, 0x00000B23 }, /* GL_LINE_WIDTH_GRANULARITY */
-   { 16317, 0x00000B22 }, /* GL_LINE_WIDTH_RANGE */
-   { 16337, 0x00008B82 }, /* GL_LINK_STATUS */
-   { 16352, 0x00000B32 }, /* GL_LIST_BASE */
-   { 16365, 0x00020000 }, /* GL_LIST_BIT */
-   { 16377, 0x00000B33 }, /* GL_LIST_INDEX */
-   { 16391, 0x00000B30 }, /* GL_LIST_MODE */
-   { 16404, 0x00000101 }, /* GL_LOAD */
-   { 16412, 0x00000BF1 }, /* GL_LOGIC_OP */
-   { 16424, 0x00000BF0 }, /* GL_LOGIC_OP_MODE */
-   { 16441, 0x00008CA1 }, /* GL_LOWER_LEFT */
-   { 16455, 0x00008DF0 }, /* GL_LOW_FLOAT */
-   { 16468, 0x00008DF3 }, /* GL_LOW_INT */
-   { 16479, 0x00001909 }, /* GL_LUMINANCE */
-   { 16492, 0x00008041 }, /* GL_LUMINANCE12 */
-   { 16507, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12 */
-   { 16530, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12_EXT */
-   { 16557, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4 */
-   { 16579, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4_EXT */
-   { 16605, 0x00008041 }, /* GL_LUMINANCE12_EXT */
-   { 16624, 0x00008042 }, /* GL_LUMINANCE16 */
-   { 16639, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16 */
-   { 16662, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16_EXT */
-   { 16689, 0x00008042 }, /* GL_LUMINANCE16_EXT */
-   { 16708, 0x0000803F }, /* GL_LUMINANCE4 */
-   { 16722, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4 */
-   { 16743, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4_EXT */
-   { 16768, 0x0000803F }, /* GL_LUMINANCE4_EXT */
-   { 16786, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2 */
-   { 16807, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2_EXT */
-   { 16832, 0x00008040 }, /* GL_LUMINANCE8 */
-   { 16846, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8 */
-   { 16867, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8_EXT */
-   { 16892, 0x00008040 }, /* GL_LUMINANCE8_EXT */
-   { 16910, 0x0000190A }, /* GL_LUMINANCE_ALPHA */
-   { 16929, 0x00000D90 }, /* GL_MAP1_COLOR_4 */
-   { 16945, 0x00000DD0 }, /* GL_MAP1_GRID_DOMAIN */
-   { 16965, 0x00000DD1 }, /* GL_MAP1_GRID_SEGMENTS */
-   { 16987, 0x00000D91 }, /* GL_MAP1_INDEX */
-   { 17001, 0x00000D92 }, /* GL_MAP1_NORMAL */
-   { 17016, 0x00000D93 }, /* GL_MAP1_TEXTURE_COORD_1 */
-   { 17040, 0x00000D94 }, /* GL_MAP1_TEXTURE_COORD_2 */
-   { 17064, 0x00000D95 }, /* GL_MAP1_TEXTURE_COORD_3 */
-   { 17088, 0x00000D96 }, /* GL_MAP1_TEXTURE_COORD_4 */
-   { 17112, 0x00000D97 }, /* GL_MAP1_VERTEX_3 */
-   { 17129, 0x00000D98 }, /* GL_MAP1_VERTEX_4 */
-   { 17146, 0x00008660 }, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */
-   { 17174, 0x0000866A }, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */
-   { 17203, 0x0000866B }, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */
-   { 17232, 0x0000866C }, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */
-   { 17261, 0x0000866D }, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */
-   { 17290, 0x0000866E }, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */
-   { 17319, 0x0000866F }, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */
-   { 17348, 0x00008661 }, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */
-   { 17376, 0x00008662 }, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */
-   { 17404, 0x00008663 }, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */
-   { 17432, 0x00008664 }, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */
-   { 17460, 0x00008665 }, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */
-   { 17488, 0x00008666 }, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */
-   { 17516, 0x00008667 }, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */
-   { 17544, 0x00008668 }, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */
-   { 17572, 0x00008669 }, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */
-   { 17600, 0x00000DB0 }, /* GL_MAP2_COLOR_4 */
-   { 17616, 0x00000DD2 }, /* GL_MAP2_GRID_DOMAIN */
-   { 17636, 0x00000DD3 }, /* GL_MAP2_GRID_SEGMENTS */
-   { 17658, 0x00000DB1 }, /* GL_MAP2_INDEX */
-   { 17672, 0x00000DB2 }, /* GL_MAP2_NORMAL */
-   { 17687, 0x00000DB3 }, /* GL_MAP2_TEXTURE_COORD_1 */
-   { 17711, 0x00000DB4 }, /* GL_MAP2_TEXTURE_COORD_2 */
-   { 17735, 0x00000DB5 }, /* GL_MAP2_TEXTURE_COORD_3 */
-   { 17759, 0x00000DB6 }, /* GL_MAP2_TEXTURE_COORD_4 */
-   { 17783, 0x00000DB7 }, /* GL_MAP2_VERTEX_3 */
-   { 17800, 0x00000DB8 }, /* GL_MAP2_VERTEX_4 */
-   { 17817, 0x00008670 }, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */
-   { 17845, 0x0000867A }, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */
-   { 17874, 0x0000867B }, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */
-   { 17903, 0x0000867C }, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */
-   { 17932, 0x0000867D }, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */
-   { 17961, 0x0000867E }, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */
-   { 17990, 0x0000867F }, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */
-   { 18019, 0x00008671 }, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */
-   { 18047, 0x00008672 }, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */
-   { 18075, 0x00008673 }, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */
-   { 18103, 0x00008674 }, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */
-   { 18131, 0x00008675 }, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */
-   { 18159, 0x00008676 }, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */
-   { 18187, 0x00008677 }, /* GL_MAP2_VERTEX_ATTRIB7_4_NV */
-   { 18215, 0x00008678 }, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */
-   { 18243, 0x00008679 }, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */
-   { 18271, 0x00000D10 }, /* GL_MAP_COLOR */
-   { 18284, 0x00000010 }, /* GL_MAP_FLUSH_EXPLICIT_BIT */
-   { 18310, 0x00000008 }, /* GL_MAP_INVALIDATE_BUFFER_BIT */
-   { 18339, 0x00000004 }, /* GL_MAP_INVALIDATE_RANGE_BIT */
-   { 18367, 0x00000001 }, /* GL_MAP_READ_BIT */
-   { 18383, 0x00000D11 }, /* GL_MAP_STENCIL */
-   { 18398, 0x00000020 }, /* GL_MAP_UNSYNCHRONIZED_BIT */
-   { 18424, 0x00000002 }, /* GL_MAP_WRITE_BIT */
-   { 18441, 0x000088C0 }, /* GL_MATRIX0_ARB */
-   { 18456, 0x00008630 }, /* GL_MATRIX0_NV */
-   { 18470, 0x000088CA }, /* GL_MATRIX10_ARB */
-   { 18486, 0x000088CB }, /* GL_MATRIX11_ARB */
-   { 18502, 0x000088CC }, /* GL_MATRIX12_ARB */
-   { 18518, 0x000088CD }, /* GL_MATRIX13_ARB */
-   { 18534, 0x000088CE }, /* GL_MATRIX14_ARB */
-   { 18550, 0x000088CF }, /* GL_MATRIX15_ARB */
-   { 18566, 0x000088D0 }, /* GL_MATRIX16_ARB */
-   { 18582, 0x000088D1 }, /* GL_MATRIX17_ARB */
-   { 18598, 0x000088D2 }, /* GL_MATRIX18_ARB */
-   { 18614, 0x000088D3 }, /* GL_MATRIX19_ARB */
-   { 18630, 0x000088C1 }, /* GL_MATRIX1_ARB */
-   { 18645, 0x00008631 }, /* GL_MATRIX1_NV */
-   { 18659, 0x000088D4 }, /* GL_MATRIX20_ARB */
-   { 18675, 0x000088D5 }, /* GL_MATRIX21_ARB */
-   { 18691, 0x000088D6 }, /* GL_MATRIX22_ARB */
-   { 18707, 0x000088D7 }, /* GL_MATRIX23_ARB */
-   { 18723, 0x000088D8 }, /* GL_MATRIX24_ARB */
-   { 18739, 0x000088D9 }, /* GL_MATRIX25_ARB */
-   { 18755, 0x000088DA }, /* GL_MATRIX26_ARB */
-   { 18771, 0x000088DB }, /* GL_MATRIX27_ARB */
-   { 18787, 0x000088DC }, /* GL_MATRIX28_ARB */
-   { 18803, 0x000088DD }, /* GL_MATRIX29_ARB */
-   { 18819, 0x000088C2 }, /* GL_MATRIX2_ARB */
-   { 18834, 0x00008632 }, /* GL_MATRIX2_NV */
-   { 18848, 0x000088DE }, /* GL_MATRIX30_ARB */
-   { 18864, 0x000088DF }, /* GL_MATRIX31_ARB */
-   { 18880, 0x000088C3 }, /* GL_MATRIX3_ARB */
-   { 18895, 0x00008633 }, /* GL_MATRIX3_NV */
-   { 18909, 0x000088C4 }, /* GL_MATRIX4_ARB */
-   { 18924, 0x00008634 }, /* GL_MATRIX4_NV */
-   { 18938, 0x000088C5 }, /* GL_MATRIX5_ARB */
-   { 18953, 0x00008635 }, /* GL_MATRIX5_NV */
-   { 18967, 0x000088C6 }, /* GL_MATRIX6_ARB */
-   { 18982, 0x00008636 }, /* GL_MATRIX6_NV */
-   { 18996, 0x000088C7 }, /* GL_MATRIX7_ARB */
-   { 19011, 0x00008637 }, /* GL_MATRIX7_NV */
-   { 19025, 0x000088C8 }, /* GL_MATRIX8_ARB */
-   { 19040, 0x000088C9 }, /* GL_MATRIX9_ARB */
-   { 19055, 0x00008844 }, /* GL_MATRIX_INDEX_ARRAY_ARB */
-   { 19081, 0x00008B9E }, /* GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES */
-   { 19122, 0x00008844 }, /* GL_MATRIX_INDEX_ARRAY_OES */
-   { 19148, 0x00008849 }, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */
-   { 19182, 0x00008849 }, /* GL_MATRIX_INDEX_ARRAY_POINTER_OES */
-   { 19216, 0x00008846 }, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */
-   { 19247, 0x00008846 }, /* GL_MATRIX_INDEX_ARRAY_SIZE_OES */
-   { 19278, 0x00008848 }, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */
-   { 19311, 0x00008848 }, /* GL_MATRIX_INDEX_ARRAY_STRIDE_OES */
-   { 19344, 0x00008847 }, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */
-   { 19375, 0x00008847 }, /* GL_MATRIX_INDEX_ARRAY_TYPE_OES */
-   { 19406, 0x00000BA0 }, /* GL_MATRIX_MODE */
-   { 19421, 0x00008840 }, /* GL_MATRIX_PALETTE_ARB */
-   { 19443, 0x00008840 }, /* GL_MATRIX_PALETTE_OES */
-   { 19465, 0x00008008 }, /* GL_MAX */
-   { 19472, 0x00008073 }, /* GL_MAX_3D_TEXTURE_SIZE */
-   { 19495, 0x00008073 }, /* GL_MAX_3D_TEXTURE_SIZE_OES */
-   { 19522, 0x000088FF }, /* GL_MAX_ARRAY_TEXTURE_LAYERS_EXT */
-   { 19554, 0x00000D35 }, /* GL_MAX_ATTRIB_STACK_DEPTH */
-   { 19580, 0x00000D3B }, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */
-   { 19613, 0x00008177 }, /* GL_MAX_CLIPMAP_DEPTH_SGIX */
-   { 19639, 0x00008178 }, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */
-   { 19673, 0x00000D32 }, /* GL_MAX_CLIP_PLANES */
-   { 19692, 0x00008CDF }, /* GL_MAX_COLOR_ATTACHMENTS */
-   { 19717, 0x00008CDF }, /* GL_MAX_COLOR_ATTACHMENTS_EXT */
-   { 19746, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */
-   { 19778, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI */
-   { 19814, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */
-   { 19850, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB */
-   { 19890, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT */
-   { 19916, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT_EXT */
-   { 19946, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH */
-   { 19971, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH_EXT */
-   { 20000, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */
-   { 20029, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB */
-   { 20062, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES */
-   { 20095, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS */
-   { 20115, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ARB */
-   { 20139, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ATI */
-   { 20163, 0x000080E9 }, /* GL_MAX_ELEMENTS_INDICES */
-   { 20187, 0x000080E8 }, /* GL_MAX_ELEMENTS_VERTICES */
-   { 20212, 0x00000D30 }, /* GL_MAX_EVAL_ORDER */
-   { 20230, 0x00008008 }, /* GL_MAX_EXT */
-   { 20241, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */
-   { 20276, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB */
-   { 20315, 0x00008DFD }, /* GL_MAX_FRAGMENT_UNIFORM_VECTORS */
-   { 20347, 0x00000D31 }, /* GL_MAX_LIGHTS */
-   { 20361, 0x00000B31 }, /* GL_MAX_LIST_NESTING */
-   { 20381, 0x00008841 }, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */
-   { 20419, 0x00000D36 }, /* GL_MAX_MODELVIEW_STACK_DEPTH */
-   { 20448, 0x00000D37 }, /* GL_MAX_NAME_STACK_DEPTH */
-   { 20472, 0x00008842 }, /* GL_MAX_PALETTE_MATRICES_ARB */
-   { 20500, 0x00008842 }, /* GL_MAX_PALETTE_MATRICES_OES */
-   { 20528, 0x00000D34 }, /* GL_MAX_PIXEL_MAP_TABLE */
-   { 20551, 0x000088B1 }, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */
-   { 20588, 0x0000880B }, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */
-   { 20624, 0x000088AD }, /* GL_MAX_PROGRAM_ATTRIBS_ARB */
-   { 20651, 0x000088F5 }, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */
-   { 20680, 0x000088B5 }, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */
-   { 20714, 0x000088F4 }, /* GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */
-   { 20750, 0x000088F6 }, /* GL_MAX_PROGRAM_IF_DEPTH_NV */
-   { 20777, 0x000088A1 }, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */
-   { 20809, 0x000088B4 }, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */
-   { 20845, 0x000088F8 }, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */
-   { 20874, 0x000088F7 }, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */
-   { 20903, 0x0000862F }, /* GL_MAX_PROGRAM_MATRICES_ARB */
-   { 20931, 0x0000862E }, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */
-   { 20969, 0x000088B3 }, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
-   { 21013, 0x0000880E }, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
-   { 21056, 0x000088AF }, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */
-   { 21090, 0x000088A3 }, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
-   { 21129, 0x000088AB }, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */
-   { 21166, 0x000088A7 }, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */
-   { 21204, 0x00008810 }, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
-   { 21247, 0x0000880F }, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
-   { 21290, 0x000088A9 }, /* GL_MAX_PROGRAM_PARAMETERS_ARB */
-   { 21320, 0x000088A5 }, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
-   { 21351, 0x0000880D }, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */
-   { 21387, 0x0000880C }, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */
-   { 21423, 0x00000D38 }, /* GL_MAX_PROJECTION_STACK_DEPTH */
-   { 21453, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */
-   { 21487, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_NV */
-   { 21520, 0x000084E8 }, /* GL_MAX_RENDERBUFFER_SIZE */
-   { 21545, 0x000084E8 }, /* GL_MAX_RENDERBUFFER_SIZE_EXT */
-   { 21574, 0x000084E8 }, /* GL_MAX_RENDERBUFFER_SIZE_OES */
-   { 21603, 0x00008D57 }, /* GL_MAX_SAMPLES */
-   { 21618, 0x00008D57 }, /* GL_MAX_SAMPLES_EXT */
-   { 21637, 0x00009111 }, /* GL_MAX_SERVER_WAIT_TIMEOUT */
-   { 21664, 0x00008504 }, /* GL_MAX_SHININESS_NV */
-   { 21684, 0x00008505 }, /* GL_MAX_SPOT_EXPONENT_NV */
-   { 21708, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS */
-   { 21730, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS_ARB */
-   { 21756, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS */
-   { 21783, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS_ARB */
-   { 21814, 0x000084FD }, /* GL_MAX_TEXTURE_LOD_BIAS */
-   { 21838, 0x000084FD }, /* GL_MAX_TEXTURE_LOD_BIAS_EXT */
-   { 21866, 0x000084FF }, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */
-   { 21900, 0x00000D33 }, /* GL_MAX_TEXTURE_SIZE */
-   { 21920, 0x00000D39 }, /* GL_MAX_TEXTURE_STACK_DEPTH */
-   { 21947, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS */
-   { 21968, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS_ARB */
-   { 21993, 0x0000862F }, /* GL_MAX_TRACK_MATRICES_NV */
-   { 22018, 0x0000862E }, /* GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV */
-   { 22053, 0x00008C8A }, /* GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT */
-   { 22106, 0x00008C8B }, /* GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT */
-   { 22153, 0x00008C80 }, /* GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT */
-   { 22203, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS */
-   { 22225, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS_ARB */
-   { 22251, 0x00008DFC }, /* GL_MAX_VARYING_VECTORS */
-   { 22274, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS */
-   { 22296, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS_ARB */
-   { 22322, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */
-   { 22356, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */
-   { 22394, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */
-   { 22427, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB */
-   { 22464, 0x00008DFB }, /* GL_MAX_VERTEX_UNIFORM_VECTORS */
-   { 22494, 0x000086A4 }, /* GL_MAX_VERTEX_UNITS_ARB */
-   { 22518, 0x000086A4 }, /* GL_MAX_VERTEX_UNITS_OES */
-   { 22542, 0x00000D3A }, /* GL_MAX_VIEWPORT_DIMS */
-   { 22563, 0x00008DF1 }, /* GL_MEDIUM_FLOAT */
-   { 22579, 0x00008DF4 }, /* GL_MEDIUM_INT */
-   { 22593, 0x00008007 }, /* GL_MIN */
-   { 22600, 0x0000802E }, /* GL_MINMAX */
-   { 22610, 0x0000802E }, /* GL_MINMAX_EXT */
-   { 22624, 0x0000802F }, /* GL_MINMAX_FORMAT */
-   { 22641, 0x0000802F }, /* GL_MINMAX_FORMAT_EXT */
-   { 22662, 0x00008030 }, /* GL_MINMAX_SINK */
-   { 22677, 0x00008030 }, /* GL_MINMAX_SINK_EXT */
-   { 22696, 0x00008007 }, /* GL_MIN_EXT */
-   { 22707, 0x00008370 }, /* GL_MIRRORED_REPEAT */
-   { 22726, 0x00008370 }, /* GL_MIRRORED_REPEAT_ARB */
-   { 22749, 0x00008370 }, /* GL_MIRRORED_REPEAT_IBM */
-   { 22772, 0x00008742 }, /* GL_MIRROR_CLAMP_ATI */
-   { 22792, 0x00008742 }, /* GL_MIRROR_CLAMP_EXT */
-   { 22812, 0x00008912 }, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */
-   { 22842, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_ATI */
-   { 22870, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */
-   { 22898, 0x00001700 }, /* GL_MODELVIEW */
-   { 22911, 0x00001700 }, /* GL_MODELVIEW0_ARB */
-   { 22929, 0x0000872A }, /* GL_MODELVIEW10_ARB */
-   { 22948, 0x0000872B }, /* GL_MODELVIEW11_ARB */
-   { 22967, 0x0000872C }, /* GL_MODELVIEW12_ARB */
-   { 22986, 0x0000872D }, /* GL_MODELVIEW13_ARB */
-   { 23005, 0x0000872E }, /* GL_MODELVIEW14_ARB */
-   { 23024, 0x0000872F }, /* GL_MODELVIEW15_ARB */
-   { 23043, 0x00008730 }, /* GL_MODELVIEW16_ARB */
-   { 23062, 0x00008731 }, /* GL_MODELVIEW17_ARB */
-   { 23081, 0x00008732 }, /* GL_MODELVIEW18_ARB */
-   { 23100, 0x00008733 }, /* GL_MODELVIEW19_ARB */
-   { 23119, 0x0000850A }, /* GL_MODELVIEW1_ARB */
-   { 23137, 0x00008734 }, /* GL_MODELVIEW20_ARB */
-   { 23156, 0x00008735 }, /* GL_MODELVIEW21_ARB */
-   { 23175, 0x00008736 }, /* GL_MODELVIEW22_ARB */
-   { 23194, 0x00008737 }, /* GL_MODELVIEW23_ARB */
-   { 23213, 0x00008738 }, /* GL_MODELVIEW24_ARB */
-   { 23232, 0x00008739 }, /* GL_MODELVIEW25_ARB */
-   { 23251, 0x0000873A }, /* GL_MODELVIEW26_ARB */
-   { 23270, 0x0000873B }, /* GL_MODELVIEW27_ARB */
-   { 23289, 0x0000873C }, /* GL_MODELVIEW28_ARB */
-   { 23308, 0x0000873D }, /* GL_MODELVIEW29_ARB */
-   { 23327, 0x00008722 }, /* GL_MODELVIEW2_ARB */
-   { 23345, 0x0000873E }, /* GL_MODELVIEW30_ARB */
-   { 23364, 0x0000873F }, /* GL_MODELVIEW31_ARB */
-   { 23383, 0x00008723 }, /* GL_MODELVIEW3_ARB */
-   { 23401, 0x00008724 }, /* GL_MODELVIEW4_ARB */
-   { 23419, 0x00008725 }, /* GL_MODELVIEW5_ARB */
-   { 23437, 0x00008726 }, /* GL_MODELVIEW6_ARB */
-   { 23455, 0x00008727 }, /* GL_MODELVIEW7_ARB */
-   { 23473, 0x00008728 }, /* GL_MODELVIEW8_ARB */
-   { 23491, 0x00008729 }, /* GL_MODELVIEW9_ARB */
-   { 23509, 0x00000BA6 }, /* GL_MODELVIEW_MATRIX */
-   { 23529, 0x0000898D }, /* GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES */
-   { 23571, 0x00008629 }, /* GL_MODELVIEW_PROJECTION_NV */
-   { 23598, 0x00000BA3 }, /* GL_MODELVIEW_STACK_DEPTH */
-   { 23623, 0x00002100 }, /* GL_MODULATE */
-   { 23635, 0x00008744 }, /* GL_MODULATE_ADD_ATI */
-   { 23655, 0x00008745 }, /* GL_MODULATE_SIGNED_ADD_ATI */
-   { 23682, 0x00008746 }, /* GL_MODULATE_SUBTRACT_ATI */
-   { 23707, 0x00000103 }, /* GL_MULT */
-   { 23715, 0x0000809D }, /* GL_MULTISAMPLE */
-   { 23730, 0x000086B2 }, /* GL_MULTISAMPLE_3DFX */
-   { 23750, 0x0000809D }, /* GL_MULTISAMPLE_ARB */
-   { 23769, 0x20000000 }, /* GL_MULTISAMPLE_BIT */
-   { 23788, 0x20000000 }, /* GL_MULTISAMPLE_BIT_3DFX */
-   { 23812, 0x20000000 }, /* GL_MULTISAMPLE_BIT_ARB */
-   { 23835, 0x00008534 }, /* GL_MULTISAMPLE_FILTER_HINT_NV */
-   { 23865, 0x00002A25 }, /* GL_N3F_V3F */
-   { 23876, 0x00000D70 }, /* GL_NAME_STACK_DEPTH */
-   { 23896, 0x0000150E }, /* GL_NAND */
-   { 23904, 0x00002600 }, /* GL_NEAREST */
-   { 23915, 0x0000844E }, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */
-   { 23946, 0x0000844D }, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */
-   { 23978, 0x00002702 }, /* GL_NEAREST_MIPMAP_LINEAR */
-   { 24003, 0x00002700 }, /* GL_NEAREST_MIPMAP_NEAREST */
-   { 24029, 0x00000200 }, /* GL_NEVER */
-   { 24038, 0x00001102 }, /* GL_NICEST */
-   { 24048, 0x00000000 }, /* GL_NONE */
-   { 24056, 0x00000000 }, /* GL_NONE_OES */
-   { 24068, 0x00001505 }, /* GL_NOOP */
-   { 24076, 0x00001508 }, /* GL_NOR */
-   { 24083, 0x00000BA1 }, /* GL_NORMALIZE */
-   { 24096, 0x00008075 }, /* GL_NORMAL_ARRAY */
-   { 24112, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING */
-   { 24143, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING_ARB */
-   { 24178, 0x0000808F }, /* GL_NORMAL_ARRAY_POINTER */
-   { 24202, 0x0000807F }, /* GL_NORMAL_ARRAY_STRIDE */
-   { 24225, 0x0000807E }, /* GL_NORMAL_ARRAY_TYPE */
-   { 24246, 0x00008511 }, /* GL_NORMAL_MAP */
-   { 24260, 0x00008511 }, /* GL_NORMAL_MAP_ARB */
-   { 24278, 0x00008511 }, /* GL_NORMAL_MAP_NV */
-   { 24295, 0x00008511 }, /* GL_NORMAL_MAP_OES */
-   { 24313, 0x00000205 }, /* GL_NOTEQUAL */
-   { 24325, 0x00000000 }, /* GL_NO_ERROR */
-   { 24337, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */
-   { 24371, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB */
-   { 24409, 0x000087FE }, /* GL_NUM_PROGRAM_BINARY_FORMATS_OES */
-   { 24443, 0x00008DF9 }, /* GL_NUM_SHADER_BINARY_FORMATS */
-   { 24472, 0x00008B89 }, /* GL_OBJECT_ACTIVE_ATTRIBUTES_ARB */
-   { 24504, 0x00008B8A }, /* GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB */
-   { 24546, 0x00008B86 }, /* GL_OBJECT_ACTIVE_UNIFORMS_ARB */
-   { 24576, 0x00008B87 }, /* GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB */
-   { 24616, 0x00008B85 }, /* GL_OBJECT_ATTACHED_OBJECTS_ARB */
-   { 24647, 0x00008B81 }, /* GL_OBJECT_COMPILE_STATUS_ARB */
-   { 24676, 0x00008B80 }, /* GL_OBJECT_DELETE_STATUS_ARB */
-   { 24704, 0x00008B84 }, /* GL_OBJECT_INFO_LOG_LENGTH_ARB */
-   { 24734, 0x00002401 }, /* GL_OBJECT_LINEAR */
-   { 24751, 0x00008B82 }, /* GL_OBJECT_LINK_STATUS_ARB */
-   { 24777, 0x00002501 }, /* GL_OBJECT_PLANE */
-   { 24793, 0x00008B88 }, /* GL_OBJECT_SHADER_SOURCE_LENGTH_ARB */
-   { 24828, 0x00008B4F }, /* GL_OBJECT_SUBTYPE_ARB */
-   { 24850, 0x00009112 }, /* GL_OBJECT_TYPE */
-   { 24865, 0x00008B4E }, /* GL_OBJECT_TYPE_ARB */
-   { 24884, 0x00008B83 }, /* GL_OBJECT_VALIDATE_STATUS_ARB */
-   { 24914, 0x00008165 }, /* GL_OCCLUSION_TEST_HP */
-   { 24935, 0x00008166 }, /* GL_OCCLUSION_TEST_RESULT_HP */
-   { 24963, 0x00000001 }, /* GL_ONE */
-   { 24970, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA */
-   { 24998, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA_EXT */
-   { 25030, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR */
-   { 25058, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR_EXT */
-   { 25090, 0x00000305 }, /* GL_ONE_MINUS_DST_ALPHA */
-   { 25113, 0x00000307 }, /* GL_ONE_MINUS_DST_COLOR */
-   { 25136, 0x00000303 }, /* GL_ONE_MINUS_SRC_ALPHA */
-   { 25159, 0x00000301 }, /* GL_ONE_MINUS_SRC_COLOR */
-   { 25182, 0x00008598 }, /* GL_OPERAND0_ALPHA */
-   { 25200, 0x00008598 }, /* GL_OPERAND0_ALPHA_ARB */
-   { 25222, 0x00008598 }, /* GL_OPERAND0_ALPHA_EXT */
-   { 25244, 0x00008590 }, /* GL_OPERAND0_RGB */
-   { 25260, 0x00008590 }, /* GL_OPERAND0_RGB_ARB */
-   { 25280, 0x00008590 }, /* GL_OPERAND0_RGB_EXT */
-   { 25300, 0x00008599 }, /* GL_OPERAND1_ALPHA */
-   { 25318, 0x00008599 }, /* GL_OPERAND1_ALPHA_ARB */
-   { 25340, 0x00008599 }, /* GL_OPERAND1_ALPHA_EXT */
-   { 25362, 0x00008591 }, /* GL_OPERAND1_RGB */
-   { 25378, 0x00008591 }, /* GL_OPERAND1_RGB_ARB */
-   { 25398, 0x00008591 }, /* GL_OPERAND1_RGB_EXT */
-   { 25418, 0x0000859A }, /* GL_OPERAND2_ALPHA */
-   { 25436, 0x0000859A }, /* GL_OPERAND2_ALPHA_ARB */
-   { 25458, 0x0000859A }, /* GL_OPERAND2_ALPHA_EXT */
-   { 25480, 0x00008592 }, /* GL_OPERAND2_RGB */
-   { 25496, 0x00008592 }, /* GL_OPERAND2_RGB_ARB */
-   { 25516, 0x00008592 }, /* GL_OPERAND2_RGB_EXT */
-   { 25536, 0x0000859B }, /* GL_OPERAND3_ALPHA_NV */
-   { 25557, 0x00008593 }, /* GL_OPERAND3_RGB_NV */
-   { 25576, 0x00001507 }, /* GL_OR */
-   { 25582, 0x00000A01 }, /* GL_ORDER */
-   { 25591, 0x0000150D }, /* GL_OR_INVERTED */
-   { 25606, 0x0000150B }, /* GL_OR_REVERSE */
-   { 25620, 0x00000505 }, /* GL_OUT_OF_MEMORY */
-   { 25637, 0x00000D05 }, /* GL_PACK_ALIGNMENT */
-   { 25655, 0x0000806C }, /* GL_PACK_IMAGE_HEIGHT */
-   { 25676, 0x00008758 }, /* GL_PACK_INVERT_MESA */
-   { 25696, 0x00000D01 }, /* GL_PACK_LSB_FIRST */
-   { 25714, 0x00000D02 }, /* GL_PACK_ROW_LENGTH */
-   { 25733, 0x0000806B }, /* GL_PACK_SKIP_IMAGES */
-   { 25753, 0x00000D04 }, /* GL_PACK_SKIP_PIXELS */
-   { 25773, 0x00000D03 }, /* GL_PACK_SKIP_ROWS */
-   { 25791, 0x00000D00 }, /* GL_PACK_SWAP_BYTES */
-   { 25810, 0x00008B92 }, /* GL_PALETTE4_R5_G6_B5_OES */
-   { 25835, 0x00008B94 }, /* GL_PALETTE4_RGB5_A1_OES */
-   { 25859, 0x00008B90 }, /* GL_PALETTE4_RGB8_OES */
-   { 25880, 0x00008B93 }, /* GL_PALETTE4_RGBA4_OES */
-   { 25902, 0x00008B91 }, /* GL_PALETTE4_RGBA8_OES */
-   { 25924, 0x00008B97 }, /* GL_PALETTE8_R5_G6_B5_OES */
-   { 25949, 0x00008B99 }, /* GL_PALETTE8_RGB5_A1_OES */
-   { 25973, 0x00008B95 }, /* GL_PALETTE8_RGB8_OES */
-   { 25994, 0x00008B98 }, /* GL_PALETTE8_RGBA4_OES */
-   { 26016, 0x00008B96 }, /* GL_PALETTE8_RGBA8_OES */
-   { 26038, 0x00000700 }, /* GL_PASS_THROUGH_TOKEN */
-   { 26060, 0x00000C50 }, /* GL_PERSPECTIVE_CORRECTION_HINT */
-   { 26091, 0x00000C79 }, /* GL_PIXEL_MAP_A_TO_A */
-   { 26111, 0x00000CB9 }, /* GL_PIXEL_MAP_A_TO_A_SIZE */
-   { 26136, 0x00000C78 }, /* GL_PIXEL_MAP_B_TO_B */
-   { 26156, 0x00000CB8 }, /* GL_PIXEL_MAP_B_TO_B_SIZE */
-   { 26181, 0x00000C77 }, /* GL_PIXEL_MAP_G_TO_G */
-   { 26201, 0x00000CB7 }, /* GL_PIXEL_MAP_G_TO_G_SIZE */
-   { 26226, 0x00000C75 }, /* GL_PIXEL_MAP_I_TO_A */
-   { 26246, 0x00000CB5 }, /* GL_PIXEL_MAP_I_TO_A_SIZE */
-   { 26271, 0x00000C74 }, /* GL_PIXEL_MAP_I_TO_B */
-   { 26291, 0x00000CB4 }, /* GL_PIXEL_MAP_I_TO_B_SIZE */
-   { 26316, 0x00000C73 }, /* GL_PIXEL_MAP_I_TO_G */
-   { 26336, 0x00000CB3 }, /* GL_PIXEL_MAP_I_TO_G_SIZE */
-   { 26361, 0x00000C70 }, /* GL_PIXEL_MAP_I_TO_I */
-   { 26381, 0x00000CB0 }, /* GL_PIXEL_MAP_I_TO_I_SIZE */
-   { 26406, 0x00000C72 }, /* GL_PIXEL_MAP_I_TO_R */
-   { 26426, 0x00000CB2 }, /* GL_PIXEL_MAP_I_TO_R_SIZE */
-   { 26451, 0x00000C76 }, /* GL_PIXEL_MAP_R_TO_R */
-   { 26471, 0x00000CB6 }, /* GL_PIXEL_MAP_R_TO_R_SIZE */
-   { 26496, 0x00000C71 }, /* GL_PIXEL_MAP_S_TO_S */
-   { 26516, 0x00000CB1 }, /* GL_PIXEL_MAP_S_TO_S_SIZE */
-   { 26541, 0x00000020 }, /* GL_PIXEL_MODE_BIT */
-   { 26559, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER */
-   { 26580, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING */
-   { 26609, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING_EXT */
-   { 26642, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER_EXT */
-   { 26667, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER */
-   { 26690, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING */
-   { 26721, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING_EXT */
-   { 26756, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER_EXT */
-   { 26783, 0x00001B00 }, /* GL_POINT */
-   { 26792, 0x00000000 }, /* GL_POINTS */
-   { 26802, 0x00000002 }, /* GL_POINT_BIT */
-   { 26815, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION */
-   { 26845, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_ARB */
-   { 26879, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_EXT */
-   { 26913, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_SGIS */
-   { 26948, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE */
-   { 26977, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_ARB */
-   { 27010, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_EXT */
-   { 27043, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_SGIS */
-   { 27077, 0x00000B11 }, /* GL_POINT_SIZE */
-   { 27091, 0x00008B9F }, /* GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES */
-   { 27130, 0x00008B9C }, /* GL_POINT_SIZE_ARRAY_OES */
-   { 27154, 0x0000898C }, /* GL_POINT_SIZE_ARRAY_POINTER_OES */
-   { 27186, 0x0000898B }, /* GL_POINT_SIZE_ARRAY_STRIDE_OES */
-   { 27217, 0x0000898A }, /* GL_POINT_SIZE_ARRAY_TYPE_OES */
-   { 27246, 0x00000B13 }, /* GL_POINT_SIZE_GRANULARITY */
-   { 27272, 0x00008127 }, /* GL_POINT_SIZE_MAX */
-   { 27290, 0x00008127 }, /* GL_POINT_SIZE_MAX_ARB */
-   { 27312, 0x00008127 }, /* GL_POINT_SIZE_MAX_EXT */
-   { 27334, 0x00008127 }, /* GL_POINT_SIZE_MAX_SGIS */
-   { 27357, 0x00008126 }, /* GL_POINT_SIZE_MIN */
-   { 27375, 0x00008126 }, /* GL_POINT_SIZE_MIN_ARB */
-   { 27397, 0x00008126 }, /* GL_POINT_SIZE_MIN_EXT */
-   { 27419, 0x00008126 }, /* GL_POINT_SIZE_MIN_SGIS */
-   { 27442, 0x00000B12 }, /* GL_POINT_SIZE_RANGE */
-   { 27462, 0x00000B10 }, /* GL_POINT_SMOOTH */
-   { 27478, 0x00000C51 }, /* GL_POINT_SMOOTH_HINT */
-   { 27499, 0x00008861 }, /* GL_POINT_SPRITE */
-   { 27515, 0x00008861 }, /* GL_POINT_SPRITE_ARB */
-   { 27535, 0x00008CA0 }, /* GL_POINT_SPRITE_COORD_ORIGIN */
-   { 27564, 0x00008861 }, /* GL_POINT_SPRITE_NV */
-   { 27583, 0x00008861 }, /* GL_POINT_SPRITE_OES */
-   { 27603, 0x00008863 }, /* GL_POINT_SPRITE_R_MODE_NV */
-   { 27629, 0x00000701 }, /* GL_POINT_TOKEN */
-   { 27644, 0x00000009 }, /* GL_POLYGON */
-   { 27655, 0x00000008 }, /* GL_POLYGON_BIT */
-   { 27670, 0x00000B40 }, /* GL_POLYGON_MODE */
-   { 27686, 0x00008039 }, /* GL_POLYGON_OFFSET_BIAS */
-   { 27709, 0x00008038 }, /* GL_POLYGON_OFFSET_FACTOR */
-   { 27734, 0x00008037 }, /* GL_POLYGON_OFFSET_FILL */
-   { 27757, 0x00002A02 }, /* GL_POLYGON_OFFSET_LINE */
-   { 27780, 0x00002A01 }, /* GL_POLYGON_OFFSET_POINT */
-   { 27804, 0x00002A00 }, /* GL_POLYGON_OFFSET_UNITS */
-   { 27828, 0x00000B41 }, /* GL_POLYGON_SMOOTH */
-   { 27846, 0x00000C53 }, /* GL_POLYGON_SMOOTH_HINT */
-   { 27869, 0x00000B42 }, /* GL_POLYGON_STIPPLE */
-   { 27888, 0x00000010 }, /* GL_POLYGON_STIPPLE_BIT */
-   { 27911, 0x00000703 }, /* GL_POLYGON_TOKEN */
-   { 27928, 0x00001203 }, /* GL_POSITION */
-   { 27940, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */
-   { 27972, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI */
-   { 28008, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */
-   { 28041, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI */
-   { 28078, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */
-   { 28109, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI */
-   { 28144, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */
-   { 28176, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI */
-   { 28212, 0x000080D2 }, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */
-   { 28245, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */
-   { 28277, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI */
-   { 28313, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */
-   { 28346, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI */
-   { 28383, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS */
-   { 28413, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS_SGI */
-   { 28447, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE */
-   { 28478, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE_SGI */
-   { 28513, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS */
-   { 28544, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS_EXT */
-   { 28579, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE */
-   { 28611, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE_EXT */
-   { 28647, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS */
-   { 28677, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS_EXT */
-   { 28711, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE */
-   { 28742, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE_EXT */
-   { 28777, 0x000080D1 }, /* GL_POST_CONVOLUTION_COLOR_TABLE */
-   { 28809, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS */
-   { 28840, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS_EXT */
-   { 28875, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE */
-   { 28907, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE_EXT */
-   { 28943, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS */
-   { 28972, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS_EXT */
-   { 29005, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE */
-   { 29035, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE_EXT */
-   { 29069, 0x0000817B }, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */
-   { 29108, 0x00008179 }, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */
-   { 29141, 0x0000817C }, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */
-   { 29181, 0x0000817A }, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */
-   { 29215, 0x00008578 }, /* GL_PREVIOUS */
-   { 29227, 0x00008578 }, /* GL_PREVIOUS_ARB */
-   { 29243, 0x00008578 }, /* GL_PREVIOUS_EXT */
-   { 29259, 0x00008577 }, /* GL_PRIMARY_COLOR */
-   { 29276, 0x00008577 }, /* GL_PRIMARY_COLOR_ARB */
-   { 29297, 0x00008577 }, /* GL_PRIMARY_COLOR_EXT */
-   { 29318, 0x00008C87 }, /* GL_PRIMITIVES_GENERATED_EXT */
-   { 29346, 0x000088B0 }, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */
-   { 29379, 0x00008805 }, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */
-   { 29411, 0x000088AC }, /* GL_PROGRAM_ATTRIBS_ARB */
-   { 29434, 0x000087FF }, /* GL_PROGRAM_BINARY_FORMATS_OES */
-   { 29464, 0x00008741 }, /* GL_PROGRAM_BINARY_LENGTH_OES */
-   { 29493, 0x00008677 }, /* GL_PROGRAM_BINDING_ARB */
-   { 29516, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_ARB */
-   { 29546, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_NV */
-   { 29575, 0x00008874 }, /* GL_PROGRAM_ERROR_STRING_ARB */
-   { 29603, 0x00008876 }, /* GL_PROGRAM_FORMAT_ARB */
-   { 29625, 0x00008875 }, /* GL_PROGRAM_FORMAT_ASCII_ARB */
-   { 29653, 0x000088A0 }, /* GL_PROGRAM_INSTRUCTIONS_ARB */
-   { 29681, 0x00008627 }, /* GL_PROGRAM_LENGTH_ARB */
-   { 29703, 0x00008627 }, /* GL_PROGRAM_LENGTH_NV */
-   { 29724, 0x000088B2 }, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
-   { 29764, 0x00008808 }, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
-   { 29803, 0x000088AE }, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */
-   { 29833, 0x000088A2 }, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
-   { 29868, 0x000088AA }, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */
-   { 29901, 0x000088A6 }, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */
-   { 29935, 0x0000880A }, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
-   { 29974, 0x00008809 }, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
-   { 30013, 0x00008B40 }, /* GL_PROGRAM_OBJECT_ARB */
-   { 30035, 0x000088A8 }, /* GL_PROGRAM_PARAMETERS_ARB */
-   { 30061, 0x00008644 }, /* GL_PROGRAM_PARAMETER_NV */
-   { 30085, 0x00008647 }, /* GL_PROGRAM_RESIDENT_NV */
-   { 30108, 0x00008628 }, /* GL_PROGRAM_STRING_ARB */
-   { 30130, 0x00008628 }, /* GL_PROGRAM_STRING_NV */
-   { 30151, 0x00008646 }, /* GL_PROGRAM_TARGET_NV */
-   { 30172, 0x000088A4 }, /* GL_PROGRAM_TEMPORARIES_ARB */
-   { 30199, 0x00008807 }, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */
-   { 30231, 0x00008806 }, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */
-   { 30263, 0x000088B6 }, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */
-   { 30298, 0x00001701 }, /* GL_PROJECTION */
-   { 30312, 0x00000BA7 }, /* GL_PROJECTION_MATRIX */
-   { 30333, 0x0000898E }, /* GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES */
-   { 30376, 0x00000BA4 }, /* GL_PROJECTION_STACK_DEPTH */
-   { 30402, 0x00008E4F }, /* GL_PROVOKING_VERTEX */
-   { 30422, 0x00008E4F }, /* GL_PROVOKING_VERTEX_EXT */
-   { 30446, 0x000080D3 }, /* GL_PROXY_COLOR_TABLE */
-   { 30467, 0x00008025 }, /* GL_PROXY_HISTOGRAM */
-   { 30486, 0x00008025 }, /* GL_PROXY_HISTOGRAM_EXT */
-   { 30509, 0x000080D5 }, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */
-   { 30548, 0x000080D4 }, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */
-   { 30586, 0x00008063 }, /* GL_PROXY_TEXTURE_1D */
-   { 30606, 0x00008C19 }, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */
-   { 30636, 0x00008063 }, /* GL_PROXY_TEXTURE_1D_EXT */
-   { 30660, 0x00008064 }, /* GL_PROXY_TEXTURE_2D */
-   { 30680, 0x00008C1B }, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */
-   { 30710, 0x00008064 }, /* GL_PROXY_TEXTURE_2D_EXT */
-   { 30734, 0x00008070 }, /* GL_PROXY_TEXTURE_3D */
-   { 30754, 0x000080BD }, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */
-   { 30787, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP */
-   { 30813, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP_ARB */
-   { 30843, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */
-   { 30874, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_NV */
-   { 30904, 0x00008A1D }, /* GL_PURGEABLE_APPLE */
-   { 30923, 0x00002003 }, /* GL_Q */
-   { 30928, 0x00001209 }, /* GL_QUADRATIC_ATTENUATION */
-   { 30953, 0x00000007 }, /* GL_QUADS */
-   { 30962, 0x00008E4C }, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */
-   { 31006, 0x00008E4C }, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT */
-   { 31054, 0x00008614 }, /* GL_QUAD_MESH_SUN */
-   { 31071, 0x00000008 }, /* GL_QUAD_STRIP */
-   { 31085, 0x00008E16 }, /* GL_QUERY_BY_REGION_NO_WAIT_NV */
-   { 31115, 0x00008E15 }, /* GL_QUERY_BY_REGION_WAIT_NV */
-   { 31142, 0x00008864 }, /* GL_QUERY_COUNTER_BITS */
-   { 31164, 0x00008864 }, /* GL_QUERY_COUNTER_BITS_ARB */
-   { 31190, 0x00008E14 }, /* GL_QUERY_NO_WAIT_NV */
-   { 31210, 0x00008866 }, /* GL_QUERY_RESULT */
-   { 31226, 0x00008866 }, /* GL_QUERY_RESULT_ARB */
-   { 31246, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE */
-   { 31272, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE_ARB */
-   { 31302, 0x00008E13 }, /* GL_QUERY_WAIT_NV */
-   { 31319, 0x00002002 }, /* GL_R */
-   { 31324, 0x00002A10 }, /* GL_R3_G3_B2 */
-   { 31336, 0x00008C89 }, /* GL_RASTERIZER_DISCARD_EXT */
-   { 31362, 0x00019262 }, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
-   { 31395, 0x00000C02 }, /* GL_READ_BUFFER */
-   { 31410, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER */
-   { 31430, 0x00008CAA }, /* GL_READ_FRAMEBUFFER_BINDING */
-   { 31458, 0x00008CAA }, /* GL_READ_FRAMEBUFFER_BINDING_EXT */
-   { 31490, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER_EXT */
-   { 31514, 0x000088B8 }, /* GL_READ_ONLY */
-   { 31527, 0x000088B8 }, /* GL_READ_ONLY_ARB */
-   { 31544, 0x000088BA }, /* GL_READ_WRITE */
-   { 31558, 0x000088BA }, /* GL_READ_WRITE_ARB */
-   { 31576, 0x00001903 }, /* GL_RED */
-   { 31583, 0x00008016 }, /* GL_REDUCE */
-   { 31593, 0x00008016 }, /* GL_REDUCE_EXT */
-   { 31607, 0x00000D15 }, /* GL_RED_BIAS */
-   { 31619, 0x00000D52 }, /* GL_RED_BITS */
-   { 31631, 0x00000D14 }, /* GL_RED_SCALE */
-   { 31644, 0x00008512 }, /* GL_REFLECTION_MAP */
-   { 31662, 0x00008512 }, /* GL_REFLECTION_MAP_ARB */
-   { 31684, 0x00008512 }, /* GL_REFLECTION_MAP_NV */
-   { 31705, 0x00008512 }, /* GL_REFLECTION_MAP_OES */
-   { 31727, 0x00008A19 }, /* GL_RELEASED_APPLE */
-   { 31745, 0x00001C00 }, /* GL_RENDER */
-   { 31755, 0x00008D41 }, /* GL_RENDERBUFFER */
-   { 31771, 0x00008D53 }, /* GL_RENDERBUFFER_ALPHA_SIZE */
-   { 31798, 0x00008D53 }, /* GL_RENDERBUFFER_ALPHA_SIZE_OES */
-   { 31829, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING */
-   { 31853, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING_EXT */
-   { 31881, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING_OES */
-   { 31909, 0x00008D52 }, /* GL_RENDERBUFFER_BLUE_SIZE */
-   { 31935, 0x00008D52 }, /* GL_RENDERBUFFER_BLUE_SIZE_OES */
-   { 31965, 0x00008D54 }, /* GL_RENDERBUFFER_DEPTH_SIZE */
-   { 31992, 0x00008D54 }, /* GL_RENDERBUFFER_DEPTH_SIZE_OES */
-   { 32023, 0x00008D41 }, /* GL_RENDERBUFFER_EXT */
-   { 32043, 0x00008D51 }, /* GL_RENDERBUFFER_GREEN_SIZE */
-   { 32070, 0x00008D51 }, /* GL_RENDERBUFFER_GREEN_SIZE_OES */
-   { 32101, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT */
-   { 32124, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT_EXT */
-   { 32151, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT_OES */
-   { 32178, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT */
-   { 32210, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT_EXT */
-   { 32246, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT_OES */
-   { 32282, 0x00008D41 }, /* GL_RENDERBUFFER_OES */
-   { 32302, 0x00008D50 }, /* GL_RENDERBUFFER_RED_SIZE */
-   { 32327, 0x00008D50 }, /* GL_RENDERBUFFER_RED_SIZE_OES */
-   { 32356, 0x00008CAB }, /* GL_RENDERBUFFER_SAMPLES */
-   { 32380, 0x00008CAB }, /* GL_RENDERBUFFER_SAMPLES_EXT */
-   { 32408, 0x00008D55 }, /* GL_RENDERBUFFER_STENCIL_SIZE */
-   { 32437, 0x00008D55 }, /* GL_RENDERBUFFER_STENCIL_SIZE_OES */
-   { 32470, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH */
-   { 32492, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH_EXT */
-   { 32518, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH_OES */
-   { 32544, 0x00001F01 }, /* GL_RENDERER */
-   { 32556, 0x00000C40 }, /* GL_RENDER_MODE */
-   { 32571, 0x00002901 }, /* GL_REPEAT */
-   { 32581, 0x00001E01 }, /* GL_REPLACE */
-   { 32592, 0x00008062 }, /* GL_REPLACE_EXT */
-   { 32607, 0x00008153 }, /* GL_REPLICATE_BORDER_HP */
-   { 32630, 0x0000803A }, /* GL_RESCALE_NORMAL */
-   { 32648, 0x0000803A }, /* GL_RESCALE_NORMAL_EXT */
-   { 32670, 0x00008A1B }, /* GL_RETAINED_APPLE */
-   { 32688, 0x00000102 }, /* GL_RETURN */
-   { 32698, 0x00001907 }, /* GL_RGB */
-   { 32705, 0x00008052 }, /* GL_RGB10 */
-   { 32714, 0x00008059 }, /* GL_RGB10_A2 */
-   { 32726, 0x00008059 }, /* GL_RGB10_A2_EXT */
-   { 32742, 0x00008052 }, /* GL_RGB10_EXT */
-   { 32755, 0x00008053 }, /* GL_RGB12 */
-   { 32764, 0x00008053 }, /* GL_RGB12_EXT */
-   { 32777, 0x00008054 }, /* GL_RGB16 */
-   { 32786, 0x00008054 }, /* GL_RGB16_EXT */
-   { 32799, 0x0000804E }, /* GL_RGB2_EXT */
-   { 32811, 0x0000804F }, /* GL_RGB4 */
-   { 32819, 0x0000804F }, /* GL_RGB4_EXT */
-   { 32831, 0x000083A1 }, /* GL_RGB4_S3TC */
-   { 32844, 0x00008050 }, /* GL_RGB5 */
-   { 32852, 0x00008D62 }, /* GL_RGB565 */
-   { 32862, 0x00008D62 }, /* GL_RGB565_OES */
-   { 32876, 0x00008057 }, /* GL_RGB5_A1 */
-   { 32887, 0x00008057 }, /* GL_RGB5_A1_EXT */
-   { 32902, 0x00008057 }, /* GL_RGB5_A1_OES */
-   { 32917, 0x00008050 }, /* GL_RGB5_EXT */
-   { 32929, 0x00008051 }, /* GL_RGB8 */
-   { 32937, 0x00008051 }, /* GL_RGB8_EXT */
-   { 32949, 0x00008051 }, /* GL_RGB8_OES */
-   { 32961, 0x00001908 }, /* GL_RGBA */
-   { 32969, 0x0000805A }, /* GL_RGBA12 */
-   { 32979, 0x0000805A }, /* GL_RGBA12_EXT */
-   { 32993, 0x0000805B }, /* GL_RGBA16 */
-   { 33003, 0x0000805B }, /* GL_RGBA16_EXT */
-   { 33017, 0x00008055 }, /* GL_RGBA2 */
-   { 33026, 0x00008055 }, /* GL_RGBA2_EXT */
-   { 33039, 0x00008056 }, /* GL_RGBA4 */
-   { 33048, 0x000083A5 }, /* GL_RGBA4_DXT5_S3TC */
-   { 33067, 0x00008056 }, /* GL_RGBA4_EXT */
-   { 33080, 0x00008056 }, /* GL_RGBA4_OES */
-   { 33093, 0x000083A3 }, /* GL_RGBA4_S3TC */
-   { 33107, 0x00008058 }, /* GL_RGBA8 */
-   { 33116, 0x00008058 }, /* GL_RGBA8_EXT */
-   { 33129, 0x00008058 }, /* GL_RGBA8_OES */
-   { 33142, 0x00008F97 }, /* GL_RGBA8_SNORM */
-   { 33157, 0x000083A4 }, /* GL_RGBA_DXT5_S3TC */
-   { 33175, 0x00000C31 }, /* GL_RGBA_MODE */
-   { 33188, 0x000083A2 }, /* GL_RGBA_S3TC */
-   { 33201, 0x00008F93 }, /* GL_RGBA_SNORM */
-   { 33215, 0x000083A0 }, /* GL_RGB_S3TC */
-   { 33227, 0x00008573 }, /* GL_RGB_SCALE */
-   { 33240, 0x00008573 }, /* GL_RGB_SCALE_ARB */
-   { 33257, 0x00008573 }, /* GL_RGB_SCALE_EXT */
-   { 33274, 0x00000407 }, /* GL_RIGHT */
-   { 33283, 0x00002000 }, /* GL_S */
-   { 33288, 0x00008B5D }, /* GL_SAMPLER_1D */
-   { 33302, 0x00008B61 }, /* GL_SAMPLER_1D_SHADOW */
-   { 33323, 0x00008B5E }, /* GL_SAMPLER_2D */
-   { 33337, 0x00008B62 }, /* GL_SAMPLER_2D_SHADOW */
-   { 33358, 0x00008B5F }, /* GL_SAMPLER_3D */
-   { 33372, 0x00008B5F }, /* GL_SAMPLER_3D_OES */
-   { 33390, 0x00008B60 }, /* GL_SAMPLER_CUBE */
-   { 33406, 0x000080A9 }, /* GL_SAMPLES */
-   { 33417, 0x000086B4 }, /* GL_SAMPLES_3DFX */
-   { 33433, 0x000080A9 }, /* GL_SAMPLES_ARB */
-   { 33448, 0x00008914 }, /* GL_SAMPLES_PASSED */
-   { 33466, 0x00008914 }, /* GL_SAMPLES_PASSED_ARB */
-   { 33488, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE */
-   { 33516, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE_ARB */
-   { 33548, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE */
-   { 33571, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE_ARB */
-   { 33598, 0x000080A8 }, /* GL_SAMPLE_BUFFERS */
-   { 33616, 0x000086B3 }, /* GL_SAMPLE_BUFFERS_3DFX */
-   { 33639, 0x000080A8 }, /* GL_SAMPLE_BUFFERS_ARB */
-   { 33661, 0x000080A0 }, /* GL_SAMPLE_COVERAGE */
-   { 33680, 0x000080A0 }, /* GL_SAMPLE_COVERAGE_ARB */
-   { 33703, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT */
-   { 33729, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT_ARB */
-   { 33759, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE */
-   { 33784, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE_ARB */
-   { 33813, 0x00080000 }, /* GL_SCISSOR_BIT */
-   { 33828, 0x00000C10 }, /* GL_SCISSOR_BOX */
-   { 33843, 0x00000C11 }, /* GL_SCISSOR_TEST */
-   { 33859, 0x0000845E }, /* GL_SECONDARY_COLOR_ARRAY */
-   { 33884, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */
-   { 33924, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB */
-   { 33968, 0x0000845D }, /* GL_SECONDARY_COLOR_ARRAY_POINTER */
-   { 34001, 0x0000845A }, /* GL_SECONDARY_COLOR_ARRAY_SIZE */
-   { 34031, 0x0000845C }, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */
-   { 34063, 0x0000845B }, /* GL_SECONDARY_COLOR_ARRAY_TYPE */
-   { 34093, 0x00001C02 }, /* GL_SELECT */
-   { 34103, 0x00000DF3 }, /* GL_SELECTION_BUFFER_POINTER */
-   { 34131, 0x00000DF4 }, /* GL_SELECTION_BUFFER_SIZE */
-   { 34156, 0x00008012 }, /* GL_SEPARABLE_2D */
-   { 34172, 0x00008C8D }, /* GL_SEPARATE_ATTRIBS_EXT */
-   { 34196, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR */
-   { 34223, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR_EXT */
-   { 34254, 0x0000150F }, /* GL_SET */
-   { 34261, 0x00008DF8 }, /* GL_SHADER_BINARY_FORMATS */
-   { 34286, 0x00008DFA }, /* GL_SHADER_COMPILER */
-   { 34305, 0x00008B48 }, /* GL_SHADER_OBJECT_ARB */
-   { 34326, 0x00008B88 }, /* GL_SHADER_SOURCE_LENGTH */
-   { 34350, 0x00008B4F }, /* GL_SHADER_TYPE */
-   { 34365, 0x00000B54 }, /* GL_SHADE_MODEL */
-   { 34380, 0x00008B8C }, /* GL_SHADING_LANGUAGE_VERSION */
-   { 34408, 0x000080BF }, /* GL_SHADOW_AMBIENT_SGIX */
-   { 34431, 0x000081FB }, /* GL_SHARED_TEXTURE_PALETTE_EXT */
-   { 34461, 0x00001601 }, /* GL_SHININESS */
-   { 34474, 0x00001402 }, /* GL_SHORT */
-   { 34483, 0x00009119 }, /* GL_SIGNALED */
-   { 34495, 0x00008F9C }, /* GL_SIGNED_NORMALIZED */
-   { 34516, 0x000081F9 }, /* GL_SINGLE_COLOR */
-   { 34532, 0x000081F9 }, /* GL_SINGLE_COLOR_EXT */
-   { 34552, 0x000085CC }, /* GL_SLICE_ACCUM_SUN */
-   { 34571, 0x00008C46 }, /* GL_SLUMINANCE */
-   { 34585, 0x00008C47 }, /* GL_SLUMINANCE8 */
-   { 34600, 0x00008C45 }, /* GL_SLUMINANCE8_ALPHA8 */
-   { 34622, 0x00008C44 }, /* GL_SLUMINANCE_ALPHA */
-   { 34642, 0x00001D01 }, /* GL_SMOOTH */
-   { 34652, 0x00000B23 }, /* GL_SMOOTH_LINE_WIDTH_GRANULARITY */
-   { 34685, 0x00000B22 }, /* GL_SMOOTH_LINE_WIDTH_RANGE */
-   { 34712, 0x00000B13 }, /* GL_SMOOTH_POINT_SIZE_GRANULARITY */
-   { 34745, 0x00000B12 }, /* GL_SMOOTH_POINT_SIZE_RANGE */
-   { 34772, 0x00008588 }, /* GL_SOURCE0_ALPHA */
-   { 34789, 0x00008588 }, /* GL_SOURCE0_ALPHA_ARB */
-   { 34810, 0x00008588 }, /* GL_SOURCE0_ALPHA_EXT */
-   { 34831, 0x00008580 }, /* GL_SOURCE0_RGB */
-   { 34846, 0x00008580 }, /* GL_SOURCE0_RGB_ARB */
-   { 34865, 0x00008580 }, /* GL_SOURCE0_RGB_EXT */
-   { 34884, 0x00008589 }, /* GL_SOURCE1_ALPHA */
-   { 34901, 0x00008589 }, /* GL_SOURCE1_ALPHA_ARB */
-   { 34922, 0x00008589 }, /* GL_SOURCE1_ALPHA_EXT */
-   { 34943, 0x00008581 }, /* GL_SOURCE1_RGB */
-   { 34958, 0x00008581 }, /* GL_SOURCE1_RGB_ARB */
-   { 34977, 0x00008581 }, /* GL_SOURCE1_RGB_EXT */
-   { 34996, 0x0000858A }, /* GL_SOURCE2_ALPHA */
-   { 35013, 0x0000858A }, /* GL_SOURCE2_ALPHA_ARB */
-   { 35034, 0x0000858A }, /* GL_SOURCE2_ALPHA_EXT */
-   { 35055, 0x00008582 }, /* GL_SOURCE2_RGB */
-   { 35070, 0x00008582 }, /* GL_SOURCE2_RGB_ARB */
-   { 35089, 0x00008582 }, /* GL_SOURCE2_RGB_EXT */
-   { 35108, 0x0000858B }, /* GL_SOURCE3_ALPHA_NV */
-   { 35128, 0x00008583 }, /* GL_SOURCE3_RGB_NV */
-   { 35146, 0x00001202 }, /* GL_SPECULAR */
-   { 35158, 0x00002402 }, /* GL_SPHERE_MAP */
-   { 35172, 0x00001206 }, /* GL_SPOT_CUTOFF */
-   { 35187, 0x00001204 }, /* GL_SPOT_DIRECTION */
-   { 35205, 0x00001205 }, /* GL_SPOT_EXPONENT */
-   { 35222, 0x00008588 }, /* GL_SRC0_ALPHA */
-   { 35236, 0x00008580 }, /* GL_SRC0_RGB */
-   { 35248, 0x00008589 }, /* GL_SRC1_ALPHA */
-   { 35262, 0x00008581 }, /* GL_SRC1_RGB */
-   { 35274, 0x0000858A }, /* GL_SRC2_ALPHA */
-   { 35288, 0x00008582 }, /* GL_SRC2_RGB */
-   { 35300, 0x00000302 }, /* GL_SRC_ALPHA */
-   { 35313, 0x00000308 }, /* GL_SRC_ALPHA_SATURATE */
-   { 35335, 0x00000300 }, /* GL_SRC_COLOR */
-   { 35348, 0x00008C40 }, /* GL_SRGB */
-   { 35356, 0x00008C41 }, /* GL_SRGB8 */
-   { 35365, 0x00008C43 }, /* GL_SRGB8_ALPHA8 */
-   { 35381, 0x00008C42 }, /* GL_SRGB_ALPHA */
-   { 35395, 0x00000503 }, /* GL_STACK_OVERFLOW */
-   { 35413, 0x00000504 }, /* GL_STACK_UNDERFLOW */
-   { 35432, 0x000088E6 }, /* GL_STATIC_COPY */
-   { 35447, 0x000088E6 }, /* GL_STATIC_COPY_ARB */
-   { 35466, 0x000088E4 }, /* GL_STATIC_DRAW */
-   { 35481, 0x000088E4 }, /* GL_STATIC_DRAW_ARB */
-   { 35500, 0x000088E5 }, /* GL_STATIC_READ */
-   { 35515, 0x000088E5 }, /* GL_STATIC_READ_ARB */
-   { 35534, 0x00001802 }, /* GL_STENCIL */
-   { 35545, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT */
-   { 35567, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT_EXT */
-   { 35593, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT_OES */
-   { 35619, 0x00008801 }, /* GL_STENCIL_BACK_FAIL */
-   { 35640, 0x00008801 }, /* GL_STENCIL_BACK_FAIL_ATI */
-   { 35665, 0x00008800 }, /* GL_STENCIL_BACK_FUNC */
-   { 35686, 0x00008800 }, /* GL_STENCIL_BACK_FUNC_ATI */
-   { 35711, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */
-   { 35743, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI */
-   { 35779, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */
-   { 35811, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI */
-   { 35847, 0x00008CA3 }, /* GL_STENCIL_BACK_REF */
-   { 35867, 0x00008CA4 }, /* GL_STENCIL_BACK_VALUE_MASK */
-   { 35894, 0x00008CA5 }, /* GL_STENCIL_BACK_WRITEMASK */
-   { 35920, 0x00000D57 }, /* GL_STENCIL_BITS */
-   { 35936, 0x00000400 }, /* GL_STENCIL_BUFFER_BIT */
-   { 35958, 0x00000B91 }, /* GL_STENCIL_CLEAR_VALUE */
-   { 35981, 0x00000B94 }, /* GL_STENCIL_FAIL */
-   { 35997, 0x00000B92 }, /* GL_STENCIL_FUNC */
-   { 36013, 0x00001901 }, /* GL_STENCIL_INDEX */
-   { 36030, 0x00008D46 }, /* GL_STENCIL_INDEX1 */
-   { 36048, 0x00008D49 }, /* GL_STENCIL_INDEX16 */
-   { 36067, 0x00008D49 }, /* GL_STENCIL_INDEX16_EXT */
-   { 36090, 0x00008D46 }, /* GL_STENCIL_INDEX1_EXT */
-   { 36112, 0x00008D46 }, /* GL_STENCIL_INDEX1_OES */
-   { 36134, 0x00008D47 }, /* GL_STENCIL_INDEX4 */
-   { 36152, 0x00008D47 }, /* GL_STENCIL_INDEX4_EXT */
-   { 36174, 0x00008D47 }, /* GL_STENCIL_INDEX4_OES */
-   { 36196, 0x00008D48 }, /* GL_STENCIL_INDEX8 */
-   { 36214, 0x00008D48 }, /* GL_STENCIL_INDEX8_EXT */
-   { 36236, 0x00008D48 }, /* GL_STENCIL_INDEX8_OES */
-   { 36258, 0x00008D45 }, /* GL_STENCIL_INDEX_EXT */
-   { 36279, 0x00000B95 }, /* GL_STENCIL_PASS_DEPTH_FAIL */
-   { 36306, 0x00000B96 }, /* GL_STENCIL_PASS_DEPTH_PASS */
-   { 36333, 0x00000B97 }, /* GL_STENCIL_REF */
-   { 36348, 0x00000B90 }, /* GL_STENCIL_TEST */
-   { 36364, 0x00008910 }, /* GL_STENCIL_TEST_TWO_SIDE_EXT */
-   { 36393, 0x00000B93 }, /* GL_STENCIL_VALUE_MASK */
-   { 36415, 0x00000B98 }, /* GL_STENCIL_WRITEMASK */
-   { 36436, 0x00000C33 }, /* GL_STEREO */
-   { 36446, 0x000085BE }, /* GL_STORAGE_CACHED_APPLE */
-   { 36470, 0x000085BD }, /* GL_STORAGE_PRIVATE_APPLE */
-   { 36495, 0x000085BF }, /* GL_STORAGE_SHARED_APPLE */
-   { 36519, 0x000088E2 }, /* GL_STREAM_COPY */
-   { 36534, 0x000088E2 }, /* GL_STREAM_COPY_ARB */
-   { 36553, 0x000088E0 }, /* GL_STREAM_DRAW */
-   { 36568, 0x000088E0 }, /* GL_STREAM_DRAW_ARB */
-   { 36587, 0x000088E1 }, /* GL_STREAM_READ */
-   { 36602, 0x000088E1 }, /* GL_STREAM_READ_ARB */
-   { 36621, 0x00000D50 }, /* GL_SUBPIXEL_BITS */
-   { 36638, 0x000084E7 }, /* GL_SUBTRACT */
-   { 36650, 0x000084E7 }, /* GL_SUBTRACT_ARB */
-   { 36666, 0x00009113 }, /* GL_SYNC_CONDITION */
-   { 36684, 0x00009116 }, /* GL_SYNC_FENCE */
-   { 36698, 0x00009115 }, /* GL_SYNC_FLAGS */
-   { 36712, 0x00000001 }, /* GL_SYNC_FLUSH_COMMANDS_BIT */
-   { 36739, 0x00009117 }, /* GL_SYNC_GPU_COMMANDS_COMPLETE */
-   { 36769, 0x00009114 }, /* GL_SYNC_STATUS */
-   { 36784, 0x00002001 }, /* GL_T */
-   { 36789, 0x00002A2A }, /* GL_T2F_C3F_V3F */
-   { 36804, 0x00002A2C }, /* GL_T2F_C4F_N3F_V3F */
-   { 36823, 0x00002A29 }, /* GL_T2F_C4UB_V3F */
-   { 36839, 0x00002A2B }, /* GL_T2F_N3F_V3F */
-   { 36854, 0x00002A27 }, /* GL_T2F_V3F */
-   { 36865, 0x00002A2D }, /* GL_T4F_C4F_N3F_V4F */
-   { 36884, 0x00002A28 }, /* GL_T4F_V4F */
-   { 36895, 0x00008031 }, /* GL_TABLE_TOO_LARGE_EXT */
-   { 36918, 0x00001702 }, /* GL_TEXTURE */
-   { 36929, 0x000084C0 }, /* GL_TEXTURE0 */
-   { 36941, 0x000084C0 }, /* GL_TEXTURE0_ARB */
-   { 36957, 0x000084C1 }, /* GL_TEXTURE1 */
-   { 36969, 0x000084CA }, /* GL_TEXTURE10 */
-   { 36982, 0x000084CA }, /* GL_TEXTURE10_ARB */
-   { 36999, 0x000084CB }, /* GL_TEXTURE11 */
-   { 37012, 0x000084CB }, /* GL_TEXTURE11_ARB */
-   { 37029, 0x000084CC }, /* GL_TEXTURE12 */
-   { 37042, 0x000084CC }, /* GL_TEXTURE12_ARB */
-   { 37059, 0x000084CD }, /* GL_TEXTURE13 */
-   { 37072, 0x000084CD }, /* GL_TEXTURE13_ARB */
-   { 37089, 0x000084CE }, /* GL_TEXTURE14 */
-   { 37102, 0x000084CE }, /* GL_TEXTURE14_ARB */
-   { 37119, 0x000084CF }, /* GL_TEXTURE15 */
-   { 37132, 0x000084CF }, /* GL_TEXTURE15_ARB */
-   { 37149, 0x000084D0 }, /* GL_TEXTURE16 */
-   { 37162, 0x000084D0 }, /* GL_TEXTURE16_ARB */
-   { 37179, 0x000084D1 }, /* GL_TEXTURE17 */
-   { 37192, 0x000084D1 }, /* GL_TEXTURE17_ARB */
-   { 37209, 0x000084D2 }, /* GL_TEXTURE18 */
-   { 37222, 0x000084D2 }, /* GL_TEXTURE18_ARB */
-   { 37239, 0x000084D3 }, /* GL_TEXTURE19 */
-   { 37252, 0x000084D3 }, /* GL_TEXTURE19_ARB */
-   { 37269, 0x000084C1 }, /* GL_TEXTURE1_ARB */
-   { 37285, 0x000084C2 }, /* GL_TEXTURE2 */
-   { 37297, 0x000084D4 }, /* GL_TEXTURE20 */
-   { 37310, 0x000084D4 }, /* GL_TEXTURE20_ARB */
-   { 37327, 0x000084D5 }, /* GL_TEXTURE21 */
-   { 37340, 0x000084D5 }, /* GL_TEXTURE21_ARB */
-   { 37357, 0x000084D6 }, /* GL_TEXTURE22 */
-   { 37370, 0x000084D6 }, /* GL_TEXTURE22_ARB */
-   { 37387, 0x000084D7 }, /* GL_TEXTURE23 */
-   { 37400, 0x000084D7 }, /* GL_TEXTURE23_ARB */
-   { 37417, 0x000084D8 }, /* GL_TEXTURE24 */
-   { 37430, 0x000084D8 }, /* GL_TEXTURE24_ARB */
-   { 37447, 0x000084D9 }, /* GL_TEXTURE25 */
-   { 37460, 0x000084D9 }, /* GL_TEXTURE25_ARB */
-   { 37477, 0x000084DA }, /* GL_TEXTURE26 */
-   { 37490, 0x000084DA }, /* GL_TEXTURE26_ARB */
-   { 37507, 0x000084DB }, /* GL_TEXTURE27 */
-   { 37520, 0x000084DB }, /* GL_TEXTURE27_ARB */
-   { 37537, 0x000084DC }, /* GL_TEXTURE28 */
-   { 37550, 0x000084DC }, /* GL_TEXTURE28_ARB */
-   { 37567, 0x000084DD }, /* GL_TEXTURE29 */
-   { 37580, 0x000084DD }, /* GL_TEXTURE29_ARB */
-   { 37597, 0x000084C2 }, /* GL_TEXTURE2_ARB */
-   { 37613, 0x000084C3 }, /* GL_TEXTURE3 */
-   { 37625, 0x000084DE }, /* GL_TEXTURE30 */
-   { 37638, 0x000084DE }, /* GL_TEXTURE30_ARB */
-   { 37655, 0x000084DF }, /* GL_TEXTURE31 */
-   { 37668, 0x000084DF }, /* GL_TEXTURE31_ARB */
-   { 37685, 0x000084C3 }, /* GL_TEXTURE3_ARB */
-   { 37701, 0x000084C4 }, /* GL_TEXTURE4 */
-   { 37713, 0x000084C4 }, /* GL_TEXTURE4_ARB */
-   { 37729, 0x000084C5 }, /* GL_TEXTURE5 */
-   { 37741, 0x000084C5 }, /* GL_TEXTURE5_ARB */
-   { 37757, 0x000084C6 }, /* GL_TEXTURE6 */
-   { 37769, 0x000084C6 }, /* GL_TEXTURE6_ARB */
-   { 37785, 0x000084C7 }, /* GL_TEXTURE7 */
-   { 37797, 0x000084C7 }, /* GL_TEXTURE7_ARB */
-   { 37813, 0x000084C8 }, /* GL_TEXTURE8 */
-   { 37825, 0x000084C8 }, /* GL_TEXTURE8_ARB */
-   { 37841, 0x000084C9 }, /* GL_TEXTURE9 */
-   { 37853, 0x000084C9 }, /* GL_TEXTURE9_ARB */
-   { 37869, 0x00000DE0 }, /* GL_TEXTURE_1D */
-   { 37883, 0x00008C18 }, /* GL_TEXTURE_1D_ARRAY_EXT */
-   { 37907, 0x00000DE1 }, /* GL_TEXTURE_2D */
-   { 37921, 0x00008C1A }, /* GL_TEXTURE_2D_ARRAY_EXT */
-   { 37945, 0x0000806F }, /* GL_TEXTURE_3D */
-   { 37959, 0x0000806F }, /* GL_TEXTURE_3D_OES */
-   { 37977, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE */
-   { 37999, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE_EXT */
-   { 38025, 0x0000813C }, /* GL_TEXTURE_BASE_LEVEL */
-   { 38047, 0x00008068 }, /* GL_TEXTURE_BINDING_1D */
-   { 38069, 0x00008C1C }, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */
-   { 38101, 0x00008069 }, /* GL_TEXTURE_BINDING_2D */
-   { 38123, 0x00008C1D }, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */
-   { 38155, 0x0000806A }, /* GL_TEXTURE_BINDING_3D */
-   { 38177, 0x0000806A }, /* GL_TEXTURE_BINDING_3D_OES */
-   { 38203, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP */
-   { 38231, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP_ARB */
-   { 38263, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP_OES */
-   { 38295, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */
-   { 38328, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_NV */
-   { 38360, 0x00040000 }, /* GL_TEXTURE_BIT */
-   { 38375, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE */
-   { 38396, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE_EXT */
-   { 38421, 0x00001005 }, /* GL_TEXTURE_BORDER */
-   { 38439, 0x00001004 }, /* GL_TEXTURE_BORDER_COLOR */
-   { 38463, 0x00008171 }, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */
-   { 38494, 0x00008176 }, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */
-   { 38524, 0x00008172 }, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */
-   { 38554, 0x00008175 }, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */
-   { 38589, 0x00008173 }, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */
-   { 38620, 0x00008174 }, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */
-   { 38658, 0x000080BC }, /* GL_TEXTURE_COLOR_TABLE_SGI */
-   { 38685, 0x000081EF }, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */
-   { 38717, 0x000080BF }, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
-   { 38751, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC */
-   { 38775, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC_ARB */
-   { 38803, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE */
-   { 38827, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE_ARB */
-   { 38855, 0x0000819B }, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */
-   { 38888, 0x0000819A }, /* GL_TEXTURE_COMPARE_SGIX */
-   { 38912, 0x00001003 }, /* GL_TEXTURE_COMPONENTS */
-   { 38934, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED */
-   { 38956, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED_ARB */
-   { 38982, 0x000086A3 }, /* GL_TEXTURE_COMPRESSED_FORMATS_ARB */
-   { 39016, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */
-   { 39049, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB */
-   { 39086, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT */
-   { 39114, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT_ARB */
-   { 39146, 0x00008078 }, /* GL_TEXTURE_COORD_ARRAY */
-   { 39169, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
-   { 39207, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB */
-   { 39249, 0x00008092 }, /* GL_TEXTURE_COORD_ARRAY_POINTER */
-   { 39280, 0x00008088 }, /* GL_TEXTURE_COORD_ARRAY_SIZE */
-   { 39308, 0x0000808A }, /* GL_TEXTURE_COORD_ARRAY_STRIDE */
-   { 39338, 0x00008089 }, /* GL_TEXTURE_COORD_ARRAY_TYPE */
-   { 39366, 0x00008B9D }, /* GL_TEXTURE_CROP_RECT_OES */
-   { 39391, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP */
-   { 39411, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP_ARB */
-   { 39435, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
-   { 39466, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB */
-   { 39501, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES */
-   { 39536, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
-   { 39567, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB */
-   { 39602, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES */
-   { 39637, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
-   { 39668, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB */
-   { 39703, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES */
-   { 39738, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP_OES */
-   { 39762, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
-   { 39793, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB */
-   { 39828, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES */
-   { 39863, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
-   { 39894, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB */
-   { 39929, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES */
-   { 39964, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
-   { 39995, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB */
-   { 40030, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES */
-   { 40065, 0x000088F4 }, /* GL_TEXTURE_CUBE_MAP_SEAMLESS */
-   { 40094, 0x00008071 }, /* GL_TEXTURE_DEPTH */
-   { 40111, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE */
-   { 40133, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE_ARB */
-   { 40159, 0x00002300 }, /* GL_TEXTURE_ENV */
-   { 40174, 0x00002201 }, /* GL_TEXTURE_ENV_COLOR */
-   { 40195, 0x00002200 }, /* GL_TEXTURE_ENV_MODE */
-   { 40215, 0x00008500 }, /* GL_TEXTURE_FILTER_CONTROL */
-   { 40241, 0x00008500 }, /* GL_TEXTURE_FILTER_CONTROL_EXT */
-   { 40271, 0x00002500 }, /* GL_TEXTURE_GEN_MODE */
-   { 40291, 0x00002500 }, /* GL_TEXTURE_GEN_MODE_OES */
-   { 40315, 0x00000C63 }, /* GL_TEXTURE_GEN_Q */
-   { 40332, 0x00000C62 }, /* GL_TEXTURE_GEN_R */
-   { 40349, 0x00000C60 }, /* GL_TEXTURE_GEN_S */
-   { 40366, 0x00008D60 }, /* GL_TEXTURE_GEN_STR_OES */
-   { 40389, 0x00000C61 }, /* GL_TEXTURE_GEN_T */
-   { 40406, 0x0000819D }, /* GL_TEXTURE_GEQUAL_R_SGIX */
-   { 40431, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE */
-   { 40453, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE_EXT */
-   { 40479, 0x00001001 }, /* GL_TEXTURE_HEIGHT */
-   { 40497, 0x000080ED }, /* GL_TEXTURE_INDEX_SIZE_EXT */
-   { 40523, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE */
-   { 40549, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE_EXT */
-   { 40579, 0x00001003 }, /* GL_TEXTURE_INTERNAL_FORMAT */
-   { 40606, 0x0000819C }, /* GL_TEXTURE_LEQUAL_R_SGIX */
-   { 40631, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS */
-   { 40651, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS_EXT */
-   { 40675, 0x00008190 }, /* GL_TEXTURE_LOD_BIAS_R_SGIX */
-   { 40702, 0x0000818E }, /* GL_TEXTURE_LOD_BIAS_S_SGIX */
-   { 40729, 0x0000818F }, /* GL_TEXTURE_LOD_BIAS_T_SGIX */
-   { 40756, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE */
-   { 40782, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE_EXT */
-   { 40812, 0x00002800 }, /* GL_TEXTURE_MAG_FILTER */
-   { 40834, 0x00000BA8 }, /* GL_TEXTURE_MATRIX */
-   { 40852, 0x0000898F }, /* GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES */
-   { 40892, 0x000084FE }, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */
-   { 40922, 0x0000836B }, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */
-   { 40950, 0x00008369 }, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */
-   { 40978, 0x0000836A }, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */
-   { 41006, 0x0000813D }, /* GL_TEXTURE_MAX_LEVEL */
-   { 41027, 0x0000813B }, /* GL_TEXTURE_MAX_LOD */
-   { 41046, 0x00002801 }, /* GL_TEXTURE_MIN_FILTER */
-   { 41068, 0x0000813A }, /* GL_TEXTURE_MIN_LOD */
-   { 41087, 0x00008066 }, /* GL_TEXTURE_PRIORITY */
-   { 41107, 0x000085B7 }, /* GL_TEXTURE_RANGE_LENGTH_APPLE */
-   { 41137, 0x000085B8 }, /* GL_TEXTURE_RANGE_POINTER_APPLE */
-   { 41168, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_ARB */
-   { 41193, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_NV */
-   { 41217, 0x0000805C }, /* GL_TEXTURE_RED_SIZE */
-   { 41237, 0x0000805C }, /* GL_TEXTURE_RED_SIZE_EXT */
-   { 41261, 0x00008067 }, /* GL_TEXTURE_RESIDENT */
-   { 41281, 0x00000BA5 }, /* GL_TEXTURE_STACK_DEPTH */
-   { 41304, 0x000088F1 }, /* GL_TEXTURE_STENCIL_SIZE */
-   { 41328, 0x000088F1 }, /* GL_TEXTURE_STENCIL_SIZE_EXT */
-   { 41356, 0x000085BC }, /* GL_TEXTURE_STORAGE_HINT_APPLE */
-   { 41386, 0x00008065 }, /* GL_TEXTURE_TOO_LARGE_EXT */
-   { 41411, 0x0000888F }, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */
-   { 41445, 0x00001000 }, /* GL_TEXTURE_WIDTH */
-   { 41462, 0x00008072 }, /* GL_TEXTURE_WRAP_R */
-   { 41480, 0x00008072 }, /* GL_TEXTURE_WRAP_R_OES */
-   { 41502, 0x00002802 }, /* GL_TEXTURE_WRAP_S */
-   { 41520, 0x00002803 }, /* GL_TEXTURE_WRAP_T */
-   { 41538, 0x0000911B }, /* GL_TIMEOUT_EXPIRED */
-   { 41557, 0x000088BF }, /* GL_TIME_ELAPSED_EXT */
-   { 41577, 0x00008648 }, /* GL_TRACK_MATRIX_NV */
-   { 41596, 0x00008649 }, /* GL_TRACK_MATRIX_TRANSFORM_NV */
-   { 41625, 0x00001000 }, /* GL_TRANSFORM_BIT */
-   { 41642, 0x00008C8F }, /* GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT */
-   { 41683, 0x00008C8E }, /* GL_TRANSFORM_FEEDBACK_BUFFER_EXT */
-   { 41716, 0x00008C7F }, /* GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT */
-   { 41754, 0x00008C85 }, /* GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT */
-   { 41792, 0x00008C84 }, /* GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT */
-   { 41831, 0x00008C88 }, /* GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT */
-   { 41876, 0x00008C83 }, /* GL_TRANSFORM_FEEDBACK_VARYINGS_EXT */
-   { 41911, 0x00008C76 }, /* GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT */
-   { 41956, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX */
-   { 41982, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX_ARB */
-   { 42012, 0x000088B7 }, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */
-   { 42044, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX */
-   { 42074, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX_ARB */
-   { 42108, 0x0000862C }, /* GL_TRANSPOSE_NV */
-   { 42124, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX */
-   { 42155, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX_ARB */
-   { 42190, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX */
-   { 42218, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX_ARB */
-   { 42250, 0x00000004 }, /* GL_TRIANGLES */
-   { 42263, 0x00000006 }, /* GL_TRIANGLE_FAN */
-   { 42279, 0x00008615 }, /* GL_TRIANGLE_MESH_SUN */
-   { 42300, 0x00000005 }, /* GL_TRIANGLE_STRIP */
-   { 42318, 0x00000001 }, /* GL_TRUE */
-   { 42326, 0x00008A1C }, /* GL_UNDEFINED_APPLE */
-   { 42345, 0x00000CF5 }, /* GL_UNPACK_ALIGNMENT */
-   { 42365, 0x0000806E }, /* GL_UNPACK_IMAGE_HEIGHT */
-   { 42388, 0x00000CF1 }, /* GL_UNPACK_LSB_FIRST */
-   { 42408, 0x00000CF2 }, /* GL_UNPACK_ROW_LENGTH */
-   { 42429, 0x0000806D }, /* GL_UNPACK_SKIP_IMAGES */
-   { 42451, 0x00000CF4 }, /* GL_UNPACK_SKIP_PIXELS */
-   { 42473, 0x00000CF3 }, /* GL_UNPACK_SKIP_ROWS */
-   { 42493, 0x00000CF0 }, /* GL_UNPACK_SWAP_BYTES */
-   { 42514, 0x00009118 }, /* GL_UNSIGNALED */
-   { 42528, 0x00001401 }, /* GL_UNSIGNED_BYTE */
-   { 42545, 0x00008362 }, /* GL_UNSIGNED_BYTE_2_3_3_REV */
-   { 42572, 0x00008032 }, /* GL_UNSIGNED_BYTE_3_3_2 */
-   { 42595, 0x00001405 }, /* GL_UNSIGNED_INT */
-   { 42611, 0x00008036 }, /* GL_UNSIGNED_INT_10_10_10_2 */
-   { 42638, 0x00008DF6 }, /* GL_UNSIGNED_INT_10_10_10_2_OES */
-   { 42669, 0x000084FA }, /* GL_UNSIGNED_INT_24_8 */
-   { 42690, 0x000084FA }, /* GL_UNSIGNED_INT_24_8_EXT */
-   { 42715, 0x000084FA }, /* GL_UNSIGNED_INT_24_8_NV */
-   { 42739, 0x000084FA }, /* GL_UNSIGNED_INT_24_8_OES */
-   { 42764, 0x00008368 }, /* GL_UNSIGNED_INT_2_10_10_10_REV */
-   { 42795, 0x00008368 }, /* GL_UNSIGNED_INT_2_10_10_10_REV_EXT */
-   { 42830, 0x00008035 }, /* GL_UNSIGNED_INT_8_8_8_8 */
-   { 42854, 0x00008367 }, /* GL_UNSIGNED_INT_8_8_8_8_REV */
-   { 42882, 0x00008C17 }, /* GL_UNSIGNED_NORMALIZED */
-   { 42905, 0x00001403 }, /* GL_UNSIGNED_SHORT */
-   { 42923, 0x00008366 }, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */
-   { 42953, 0x00008366 }, /* GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT */
-   { 42987, 0x00008033 }, /* GL_UNSIGNED_SHORT_4_4_4_4 */
-   { 43013, 0x00008365 }, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */
-   { 43043, 0x00008365 }, /* GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT */
-   { 43077, 0x00008034 }, /* GL_UNSIGNED_SHORT_5_5_5_1 */
-   { 43103, 0x00008363 }, /* GL_UNSIGNED_SHORT_5_6_5 */
-   { 43127, 0x00008364 }, /* GL_UNSIGNED_SHORT_5_6_5_REV */
-   { 43155, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_APPLE */
-   { 43183, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_MESA */
-   { 43210, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */
-   { 43242, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_MESA */
-   { 43273, 0x00008CA2 }, /* GL_UPPER_LEFT */
-   { 43287, 0x00002A20 }, /* GL_V2F */
-   { 43294, 0x00002A21 }, /* GL_V3F */
-   { 43301, 0x00008B83 }, /* GL_VALIDATE_STATUS */
-   { 43320, 0x00001F00 }, /* GL_VENDOR */
-   { 43330, 0x00001F02 }, /* GL_VERSION */
-   { 43341, 0x00008074 }, /* GL_VERTEX_ARRAY */
-   { 43357, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING */
-   { 43381, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING_APPLE */
-   { 43411, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
-   { 43442, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING_ARB */
-   { 43477, 0x0000808E }, /* GL_VERTEX_ARRAY_POINTER */
-   { 43501, 0x0000807A }, /* GL_VERTEX_ARRAY_SIZE */
-   { 43522, 0x0000807C }, /* GL_VERTEX_ARRAY_STRIDE */
-   { 43545, 0x0000807B }, /* GL_VERTEX_ARRAY_TYPE */
-   { 43566, 0x00008650 }, /* GL_VERTEX_ATTRIB_ARRAY0_NV */
-   { 43593, 0x0000865A }, /* GL_VERTEX_ATTRIB_ARRAY10_NV */
-   { 43621, 0x0000865B }, /* GL_VERTEX_ATTRIB_ARRAY11_NV */
-   { 43649, 0x0000865C }, /* GL_VERTEX_ATTRIB_ARRAY12_NV */
-   { 43677, 0x0000865D }, /* GL_VERTEX_ATTRIB_ARRAY13_NV */
-   { 43705, 0x0000865E }, /* GL_VERTEX_ATTRIB_ARRAY14_NV */
-   { 43733, 0x0000865F }, /* GL_VERTEX_ATTRIB_ARRAY15_NV */
-   { 43761, 0x00008651 }, /* GL_VERTEX_ATTRIB_ARRAY1_NV */
-   { 43788, 0x00008652 }, /* GL_VERTEX_ATTRIB_ARRAY2_NV */
-   { 43815, 0x00008653 }, /* GL_VERTEX_ATTRIB_ARRAY3_NV */
-   { 43842, 0x00008654 }, /* GL_VERTEX_ATTRIB_ARRAY4_NV */
-   { 43869, 0x00008655 }, /* GL_VERTEX_ATTRIB_ARRAY5_NV */
-   { 43896, 0x00008656 }, /* GL_VERTEX_ATTRIB_ARRAY6_NV */
-   { 43923, 0x00008657 }, /* GL_VERTEX_ATTRIB_ARRAY7_NV */
-   { 43950, 0x00008658 }, /* GL_VERTEX_ATTRIB_ARRAY8_NV */
-   { 43977, 0x00008659 }, /* GL_VERTEX_ATTRIB_ARRAY9_NV */
-   { 44004, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */
-   { 44042, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB */
-   { 44084, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */
-   { 44115, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB */
-   { 44150, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */
-   { 44184, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB */
-   { 44222, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */
-   { 44253, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB */
-   { 44288, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */
-   { 44316, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB */
-   { 44348, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */
-   { 44378, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB */
-   { 44412, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */
-   { 44440, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB */
-   { 44472, 0x000086A7 }, /* GL_VERTEX_BLEND_ARB */
-   { 44492, 0x00008620 }, /* GL_VERTEX_PROGRAM_ARB */
-   { 44514, 0x0000864A }, /* GL_VERTEX_PROGRAM_BINDING_NV */
-   { 44543, 0x00008620 }, /* GL_VERTEX_PROGRAM_NV */
-   { 44564, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE */
-   { 44593, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_ARB */
-   { 44626, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_NV */
-   { 44658, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE */
-   { 44685, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_ARB */
-   { 44716, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_NV */
-   { 44746, 0x00008B31 }, /* GL_VERTEX_SHADER */
-   { 44763, 0x00008B31 }, /* GL_VERTEX_SHADER_ARB */
-   { 44784, 0x00008621 }, /* GL_VERTEX_STATE_PROGRAM_NV */
-   { 44811, 0x00000BA2 }, /* GL_VIEWPORT */
-   { 44823, 0x00000800 }, /* GL_VIEWPORT_BIT */
-   { 44839, 0x00008A1A }, /* GL_VOLATILE_APPLE */
-   { 44857, 0x0000911D }, /* GL_WAIT_FAILED */
-   { 44872, 0x000086AD }, /* GL_WEIGHT_ARRAY_ARB */
-   { 44892, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */
-   { 44923, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB */
-   { 44958, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING_OES */
-   { 44993, 0x000086AD }, /* GL_WEIGHT_ARRAY_OES */
-   { 45013, 0x000086AC }, /* GL_WEIGHT_ARRAY_POINTER_ARB */
-   { 45041, 0x000086AC }, /* GL_WEIGHT_ARRAY_POINTER_OES */
-   { 45069, 0x000086AB }, /* GL_WEIGHT_ARRAY_SIZE_ARB */
-   { 45094, 0x000086AB }, /* GL_WEIGHT_ARRAY_SIZE_OES */
-   { 45119, 0x000086AA }, /* GL_WEIGHT_ARRAY_STRIDE_ARB */
-   { 45146, 0x000086AA }, /* GL_WEIGHT_ARRAY_STRIDE_OES */
-   { 45173, 0x000086A9 }, /* GL_WEIGHT_ARRAY_TYPE_ARB */
-   { 45198, 0x000086A9 }, /* GL_WEIGHT_ARRAY_TYPE_OES */
-   { 45223, 0x000086A6 }, /* GL_WEIGHT_SUM_UNITY_ARB */
-   { 45247, 0x000081D4 }, /* GL_WRAP_BORDER_SUN */
-   { 45266, 0x000088B9 }, /* GL_WRITE_ONLY */
-   { 45280, 0x000088B9 }, /* GL_WRITE_ONLY_ARB */
-   { 45298, 0x000088B9 }, /* GL_WRITE_ONLY_OES */
-   { 45316, 0x00001506 }, /* GL_XOR */
-   { 45323, 0x000085B9 }, /* GL_YCBCR_422_APPLE */
-   { 45342, 0x00008757 }, /* GL_YCBCR_MESA */
-   { 45356, 0x00000000 }, /* GL_ZERO */
-   { 45364, 0x00000D16 }, /* GL_ZOOM_X */
-   { 45374, 0x00000D17 }, /* GL_ZOOM_Y */
+   { 11649, 0x00008DA7 }, /* GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB */
+   { 11687, 0x00008CD1 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */
+   { 11725, 0x00008CD1 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT */
+   { 11767, 0x00008CD1 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES */
+   { 11809, 0x00008CD0 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */
+   { 11847, 0x00008CD0 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT */
+   { 11889, 0x00008CD0 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES */
+   { 11931, 0x00008212 }, /* GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */
+   { 11966, 0x00008217 }, /* GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */
+   { 12005, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT */
+   { 12054, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES */
+   { 12103, 0x00008CD3 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */
+   { 12151, 0x00008CD3 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT */
+   { 12203, 0x00008CD3 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES */
+   { 12255, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
+   { 12295, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */
+   { 12339, 0x00008CD2 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */
+   { 12379, 0x00008CD2 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT */
+   { 12423, 0x00008CD2 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES */
+   { 12467, 0x00008CA6 }, /* GL_FRAMEBUFFER_BINDING */
+   { 12490, 0x00008CA6 }, /* GL_FRAMEBUFFER_BINDING_EXT */
+   { 12517, 0x00008CA6 }, /* GL_FRAMEBUFFER_BINDING_OES */
+   { 12544, 0x00008CD5 }, /* GL_FRAMEBUFFER_COMPLETE */
+   { 12568, 0x00008CD5 }, /* GL_FRAMEBUFFER_COMPLETE_EXT */
+   { 12596, 0x00008CD5 }, /* GL_FRAMEBUFFER_COMPLETE_OES */
+   { 12624, 0x00008218 }, /* GL_FRAMEBUFFER_DEFAULT */
+   { 12647, 0x00008D40 }, /* GL_FRAMEBUFFER_EXT */
+   { 12666, 0x00008CD6 }, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */
+   { 12703, 0x00008CD6 }, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT */
+   { 12744, 0x00008CD6 }, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES */
+   { 12785, 0x00008CD9 }, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS */
+   { 12822, 0x00008CD9 }, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT */
+   { 12863, 0x00008CD9 }, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES */
+   { 12904, 0x00008CDB }, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER */
+   { 12942, 0x00008CDB }, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT */
+   { 12984, 0x00008CDB }, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES */
+   { 13026, 0x00008CD8 }, /* GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT */
+   { 13077, 0x00008CDA }, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT */
+   { 13115, 0x00008CDA }, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES */
+   { 13153, 0x00008DA9 }, /* GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB */
+   { 13195, 0x00008DA8 }, /* GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB */
+   { 13239, 0x00008CD7 }, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */
+   { 13284, 0x00008CD7 }, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT */
+   { 13333, 0x00008CD7 }, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES */
+   { 13382, 0x00008D56 }, /* GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */
+   { 13420, 0x00008D56 }, /* GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT */
+   { 13462, 0x00008CDC }, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER */
+   { 13500, 0x00008CDC }, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT */
+   { 13542, 0x00008CDC }, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES */
+   { 13584, 0x00008D40 }, /* GL_FRAMEBUFFER_OES */
+   { 13603, 0x00008CDE }, /* GL_FRAMEBUFFER_STATUS_ERROR_EXT */
+   { 13635, 0x00008219 }, /* GL_FRAMEBUFFER_UNDEFINED */
+   { 13660, 0x00008CDD }, /* GL_FRAMEBUFFER_UNSUPPORTED */
+   { 13687, 0x00008CDD }, /* GL_FRAMEBUFFER_UNSUPPORTED_EXT */
+   { 13718, 0x00008CDD }, /* GL_FRAMEBUFFER_UNSUPPORTED_OES */
+   { 13749, 0x00000404 }, /* GL_FRONT */
+   { 13758, 0x00000408 }, /* GL_FRONT_AND_BACK */
+   { 13776, 0x00000B46 }, /* GL_FRONT_FACE */
+   { 13790, 0x00000400 }, /* GL_FRONT_LEFT */
+   { 13804, 0x00000401 }, /* GL_FRONT_RIGHT */
+   { 13819, 0x00008006 }, /* GL_FUNC_ADD */
+   { 13831, 0x00008006 }, /* GL_FUNC_ADD_EXT */
+   { 13847, 0x00008006 }, /* GL_FUNC_ADD_OES */
+   { 13863, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT */
+   { 13888, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT_EXT */
+   { 13917, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT_OES */
+   { 13946, 0x0000800A }, /* GL_FUNC_SUBTRACT */
+   { 13963, 0x0000800A }, /* GL_FUNC_SUBTRACT_EXT */
+   { 13984, 0x0000800A }, /* GL_FUNC_SUBTRACT_OES */
+   { 14005, 0x00008191 }, /* GL_GENERATE_MIPMAP */
+   { 14024, 0x00008192 }, /* GL_GENERATE_MIPMAP_HINT */
+   { 14048, 0x00008192 }, /* GL_GENERATE_MIPMAP_HINT_SGIS */
+   { 14077, 0x00008191 }, /* GL_GENERATE_MIPMAP_SGIS */
+   { 14101, 0x00008DDB }, /* GL_GEOMETRY_INPUT_TYPE_ARB */
+   { 14128, 0x00008DDC }, /* GL_GEOMETRY_OUTPUT_TYPE_ARB */
+   { 14156, 0x00008DD9 }, /* GL_GEOMETRY_SHADER_ARB */
+   { 14179, 0x00008DDA }, /* GL_GEOMETRY_VERTICES_OUT_ARB */
+   { 14208, 0x00000206 }, /* GL_GEQUAL */
+   { 14218, 0x00000204 }, /* GL_GREATER */
+   { 14229, 0x00001904 }, /* GL_GREEN */
+   { 14238, 0x00000D19 }, /* GL_GREEN_BIAS */
+   { 14252, 0x00000D53 }, /* GL_GREEN_BITS */
+   { 14266, 0x00000D18 }, /* GL_GREEN_SCALE */
+   { 14281, 0x0000140B }, /* GL_HALF_FLOAT */
+   { 14295, 0x00008D61 }, /* GL_HALF_FLOAT_OES */
+   { 14313, 0x00008DF2 }, /* GL_HIGH_FLOAT */
+   { 14327, 0x00008DF5 }, /* GL_HIGH_INT */
+   { 14339, 0x00008000 }, /* GL_HINT_BIT */
+   { 14351, 0x00008024 }, /* GL_HISTOGRAM */
+   { 14364, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE */
+   { 14388, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE_EXT */
+   { 14416, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE */
+   { 14439, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE_EXT */
+   { 14466, 0x00008024 }, /* GL_HISTOGRAM_EXT */
+   { 14483, 0x00008027 }, /* GL_HISTOGRAM_FORMAT */
+   { 14503, 0x00008027 }, /* GL_HISTOGRAM_FORMAT_EXT */
+   { 14527, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE */
+   { 14551, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE_EXT */
+   { 14579, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE */
+   { 14607, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE_EXT */
+   { 14639, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE */
+   { 14661, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE_EXT */
+   { 14687, 0x0000802D }, /* GL_HISTOGRAM_SINK */
+   { 14705, 0x0000802D }, /* GL_HISTOGRAM_SINK_EXT */
+   { 14727, 0x00008026 }, /* GL_HISTOGRAM_WIDTH */
+   { 14746, 0x00008026 }, /* GL_HISTOGRAM_WIDTH_EXT */
+   { 14769, 0x0000862A }, /* GL_IDENTITY_NV */
+   { 14784, 0x00008150 }, /* GL_IGNORE_BORDER_HP */
+   { 14804, 0x00008B9B }, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT */
+   { 14840, 0x00008B9B }, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */
+   { 14880, 0x00008B9A }, /* GL_IMPLEMENTATION_COLOR_READ_TYPE */
+   { 14914, 0x00008B9A }, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */
+   { 14952, 0x00001E02 }, /* GL_INCR */
+   { 14960, 0x00008507 }, /* GL_INCR_WRAP */
+   { 14973, 0x00008507 }, /* GL_INCR_WRAP_EXT */
+   { 14990, 0x00008222 }, /* GL_INDEX */
+   { 14999, 0x00008077 }, /* GL_INDEX_ARRAY */
+   { 15014, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING */
+   { 15044, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING_ARB */
+   { 15078, 0x00008091 }, /* GL_INDEX_ARRAY_POINTER */
+   { 15101, 0x00008086 }, /* GL_INDEX_ARRAY_STRIDE */
+   { 15123, 0x00008085 }, /* GL_INDEX_ARRAY_TYPE */
+   { 15143, 0x00000D51 }, /* GL_INDEX_BITS */
+   { 15157, 0x00000C20 }, /* GL_INDEX_CLEAR_VALUE */
+   { 15178, 0x00000BF1 }, /* GL_INDEX_LOGIC_OP */
+   { 15196, 0x00000C30 }, /* GL_INDEX_MODE */
+   { 15210, 0x00000D13 }, /* GL_INDEX_OFFSET */
+   { 15226, 0x00000D12 }, /* GL_INDEX_SHIFT */
+   { 15241, 0x00000C21 }, /* GL_INDEX_WRITEMASK */
+   { 15260, 0x00008B84 }, /* GL_INFO_LOG_LENGTH */
+   { 15279, 0x00001404 }, /* GL_INT */
+   { 15286, 0x00008049 }, /* GL_INTENSITY */
+   { 15299, 0x0000804C }, /* GL_INTENSITY12 */
+   { 15314, 0x0000804C }, /* GL_INTENSITY12_EXT */
+   { 15333, 0x0000804D }, /* GL_INTENSITY16 */
+   { 15348, 0x0000804D }, /* GL_INTENSITY16_EXT */
+   { 15367, 0x0000804A }, /* GL_INTENSITY4 */
+   { 15381, 0x0000804A }, /* GL_INTENSITY4_EXT */
+   { 15399, 0x0000804B }, /* GL_INTENSITY8 */
+   { 15413, 0x0000804B }, /* GL_INTENSITY8_EXT */
+   { 15431, 0x00008049 }, /* GL_INTENSITY_EXT */
+   { 15448, 0x00008C8C }, /* GL_INTERLEAVED_ATTRIBS_EXT */
+   { 15475, 0x00008575 }, /* GL_INTERPOLATE */
+   { 15490, 0x00008575 }, /* GL_INTERPOLATE_ARB */
+   { 15509, 0x00008575 }, /* GL_INTERPOLATE_EXT */
+   { 15528, 0x00008DF7 }, /* GL_INT_10_10_10_2_OES */
+   { 15550, 0x00008B53 }, /* GL_INT_VEC2 */
+   { 15562, 0x00008B53 }, /* GL_INT_VEC2_ARB */
+   { 15578, 0x00008B54 }, /* GL_INT_VEC3 */
+   { 15590, 0x00008B54 }, /* GL_INT_VEC3_ARB */
+   { 15606, 0x00008B55 }, /* GL_INT_VEC4 */
+   { 15618, 0x00008B55 }, /* GL_INT_VEC4_ARB */
+   { 15634, 0x00000500 }, /* GL_INVALID_ENUM */
+   { 15650, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION */
+   { 15683, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION_EXT */
+   { 15720, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION_OES */
+   { 15757, 0x00000502 }, /* GL_INVALID_OPERATION */
+   { 15778, 0x00000501 }, /* GL_INVALID_VALUE */
+   { 15795, 0x0000862B }, /* GL_INVERSE_NV */
+   { 15809, 0x0000862D }, /* GL_INVERSE_TRANSPOSE_NV */
+   { 15833, 0x0000150A }, /* GL_INVERT */
+   { 15843, 0x00001E00 }, /* GL_KEEP */
+   { 15851, 0x00008E4E }, /* GL_LAST_VERTEX_CONVENTION */
+   { 15877, 0x00008E4E }, /* GL_LAST_VERTEX_CONVENTION_EXT */
+   { 15907, 0x00000406 }, /* GL_LEFT */
+   { 15915, 0x00000203 }, /* GL_LEQUAL */
+   { 15925, 0x00000201 }, /* GL_LESS */
+   { 15933, 0x00004000 }, /* GL_LIGHT0 */
+   { 15943, 0x00004001 }, /* GL_LIGHT1 */
+   { 15953, 0x00004002 }, /* GL_LIGHT2 */
+   { 15963, 0x00004003 }, /* GL_LIGHT3 */
+   { 15973, 0x00004004 }, /* GL_LIGHT4 */
+   { 15983, 0x00004005 }, /* GL_LIGHT5 */
+   { 15993, 0x00004006 }, /* GL_LIGHT6 */
+   { 16003, 0x00004007 }, /* GL_LIGHT7 */
+   { 16013, 0x00000B50 }, /* GL_LIGHTING */
+   { 16025, 0x00000040 }, /* GL_LIGHTING_BIT */
+   { 16041, 0x00000B53 }, /* GL_LIGHT_MODEL_AMBIENT */
+   { 16064, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL */
+   { 16093, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL_EXT */
+   { 16126, 0x00000B51 }, /* GL_LIGHT_MODEL_LOCAL_VIEWER */
+   { 16154, 0x00000B52 }, /* GL_LIGHT_MODEL_TWO_SIDE */
+   { 16178, 0x00001B01 }, /* GL_LINE */
+   { 16186, 0x00002601 }, /* GL_LINEAR */
+   { 16196, 0x00001208 }, /* GL_LINEAR_ATTENUATION */
+   { 16218, 0x00008170 }, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */
+   { 16248, 0x0000844F }, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */
+   { 16279, 0x00002703 }, /* GL_LINEAR_MIPMAP_LINEAR */
+   { 16303, 0x00002701 }, /* GL_LINEAR_MIPMAP_NEAREST */
+   { 16328, 0x00000001 }, /* GL_LINES */
+   { 16337, 0x0000000A }, /* GL_LINES_ADJACENCY_ARB */
+   { 16360, 0x00000004 }, /* GL_LINE_BIT */
+   { 16372, 0x00000002 }, /* GL_LINE_LOOP */
+   { 16385, 0x00000707 }, /* GL_LINE_RESET_TOKEN */
+   { 16405, 0x00000B20 }, /* GL_LINE_SMOOTH */
+   { 16420, 0x00000C52 }, /* GL_LINE_SMOOTH_HINT */
+   { 16440, 0x00000B24 }, /* GL_LINE_STIPPLE */
+   { 16456, 0x00000B25 }, /* GL_LINE_STIPPLE_PATTERN */
+   { 16480, 0x00000B26 }, /* GL_LINE_STIPPLE_REPEAT */
+   { 16503, 0x00000003 }, /* GL_LINE_STRIP */
+   { 16517, 0x0000000B }, /* GL_LINE_STRIP_ADJACENCY_ARB */
+   { 16545, 0x00000702 }, /* GL_LINE_TOKEN */
+   { 16559, 0x00000B21 }, /* GL_LINE_WIDTH */
+   { 16573, 0x00000B23 }, /* GL_LINE_WIDTH_GRANULARITY */
+   { 16599, 0x00000B22 }, /* GL_LINE_WIDTH_RANGE */
+   { 16619, 0x00008B82 }, /* GL_LINK_STATUS */
+   { 16634, 0x00000B32 }, /* GL_LIST_BASE */
+   { 16647, 0x00020000 }, /* GL_LIST_BIT */
+   { 16659, 0x00000B33 }, /* GL_LIST_INDEX */
+   { 16673, 0x00000B30 }, /* GL_LIST_MODE */
+   { 16686, 0x00000101 }, /* GL_LOAD */
+   { 16694, 0x00000BF1 }, /* GL_LOGIC_OP */
+   { 16706, 0x00000BF0 }, /* GL_LOGIC_OP_MODE */
+   { 16723, 0x00008CA1 }, /* GL_LOWER_LEFT */
+   { 16737, 0x00008DF0 }, /* GL_LOW_FLOAT */
+   { 16750, 0x00008DF3 }, /* GL_LOW_INT */
+   { 16761, 0x00001909 }, /* GL_LUMINANCE */
+   { 16774, 0x00008041 }, /* GL_LUMINANCE12 */
+   { 16789, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12 */
+   { 16812, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12_EXT */
+   { 16839, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4 */
+   { 16861, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4_EXT */
+   { 16887, 0x00008041 }, /* GL_LUMINANCE12_EXT */
+   { 16906, 0x00008042 }, /* GL_LUMINANCE16 */
+   { 16921, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16 */
+   { 16944, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16_EXT */
+   { 16971, 0x00008042 }, /* GL_LUMINANCE16_EXT */
+   { 16990, 0x0000803F }, /* GL_LUMINANCE4 */
+   { 17004, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4 */
+   { 17025, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4_EXT */
+   { 17050, 0x0000803F }, /* GL_LUMINANCE4_EXT */
+   { 17068, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2 */
+   { 17089, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2_EXT */
+   { 17114, 0x00008040 }, /* GL_LUMINANCE8 */
+   { 17128, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8 */
+   { 17149, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8_EXT */
+   { 17174, 0x00008040 }, /* GL_LUMINANCE8_EXT */
+   { 17192, 0x0000190A }, /* GL_LUMINANCE_ALPHA */
+   { 17211, 0x00000D90 }, /* GL_MAP1_COLOR_4 */
+   { 17227, 0x00000DD0 }, /* GL_MAP1_GRID_DOMAIN */
+   { 17247, 0x00000DD1 }, /* GL_MAP1_GRID_SEGMENTS */
+   { 17269, 0x00000D91 }, /* GL_MAP1_INDEX */
+   { 17283, 0x00000D92 }, /* GL_MAP1_NORMAL */
+   { 17298, 0x00000D93 }, /* GL_MAP1_TEXTURE_COORD_1 */
+   { 17322, 0x00000D94 }, /* GL_MAP1_TEXTURE_COORD_2 */
+   { 17346, 0x00000D95 }, /* GL_MAP1_TEXTURE_COORD_3 */
+   { 17370, 0x00000D96 }, /* GL_MAP1_TEXTURE_COORD_4 */
+   { 17394, 0x00000D97 }, /* GL_MAP1_VERTEX_3 */
+   { 17411, 0x00000D98 }, /* GL_MAP1_VERTEX_4 */
+   { 17428, 0x00008660 }, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */
+   { 17456, 0x0000866A }, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */
+   { 17485, 0x0000866B }, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */
+   { 17514, 0x0000866C }, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */
+   { 17543, 0x0000866D }, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */
+   { 17572, 0x0000866E }, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */
+   { 17601, 0x0000866F }, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */
+   { 17630, 0x00008661 }, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */
+   { 17658, 0x00008662 }, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */
+   { 17686, 0x00008663 }, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */
+   { 17714, 0x00008664 }, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */
+   { 17742, 0x00008665 }, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */
+   { 17770, 0x00008666 }, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */
+   { 17798, 0x00008667 }, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */
+   { 17826, 0x00008668 }, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */
+   { 17854, 0x00008669 }, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */
+   { 17882, 0x00000DB0 }, /* GL_MAP2_COLOR_4 */
+   { 17898, 0x00000DD2 }, /* GL_MAP2_GRID_DOMAIN */
+   { 17918, 0x00000DD3 }, /* GL_MAP2_GRID_SEGMENTS */
+   { 17940, 0x00000DB1 }, /* GL_MAP2_INDEX */
+   { 17954, 0x00000DB2 }, /* GL_MAP2_NORMAL */
+   { 17969, 0x00000DB3 }, /* GL_MAP2_TEXTURE_COORD_1 */
+   { 17993, 0x00000DB4 }, /* GL_MAP2_TEXTURE_COORD_2 */
+   { 18017, 0x00000DB5 }, /* GL_MAP2_TEXTURE_COORD_3 */
+   { 18041, 0x00000DB6 }, /* GL_MAP2_TEXTURE_COORD_4 */
+   { 18065, 0x00000DB7 }, /* GL_MAP2_VERTEX_3 */
+   { 18082, 0x00000DB8 }, /* GL_MAP2_VERTEX_4 */
+   { 18099, 0x00008670 }, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */
+   { 18127, 0x0000867A }, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */
+   { 18156, 0x0000867B }, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */
+   { 18185, 0x0000867C }, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */
+   { 18214, 0x0000867D }, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */
+   { 18243, 0x0000867E }, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */
+   { 18272, 0x0000867F }, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */
+   { 18301, 0x00008671 }, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */
+   { 18329, 0x00008672 }, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */
+   { 18357, 0x00008673 }, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */
+   { 18385, 0x00008674 }, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */
+   { 18413, 0x00008675 }, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */
+   { 18441, 0x00008676 }, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */
+   { 18469, 0x00008677 }, /* GL_MAP2_VERTEX_ATTRIB7_4_NV */
+   { 18497, 0x00008678 }, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */
+   { 18525, 0x00008679 }, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */
+   { 18553, 0x00000D10 }, /* GL_MAP_COLOR */
+   { 18566, 0x00000010 }, /* GL_MAP_FLUSH_EXPLICIT_BIT */
+   { 18592, 0x00000008 }, /* GL_MAP_INVALIDATE_BUFFER_BIT */
+   { 18621, 0x00000004 }, /* GL_MAP_INVALIDATE_RANGE_BIT */
+   { 18649, 0x00000001 }, /* GL_MAP_READ_BIT */
+   { 18665, 0x00000D11 }, /* GL_MAP_STENCIL */
+   { 18680, 0x00000020 }, /* GL_MAP_UNSYNCHRONIZED_BIT */
+   { 18706, 0x00000002 }, /* GL_MAP_WRITE_BIT */
+   { 18723, 0x000088C0 }, /* GL_MATRIX0_ARB */
+   { 18738, 0x00008630 }, /* GL_MATRIX0_NV */
+   { 18752, 0x000088CA }, /* GL_MATRIX10_ARB */
+   { 18768, 0x000088CB }, /* GL_MATRIX11_ARB */
+   { 18784, 0x000088CC }, /* GL_MATRIX12_ARB */
+   { 18800, 0x000088CD }, /* GL_MATRIX13_ARB */
+   { 18816, 0x000088CE }, /* GL_MATRIX14_ARB */
+   { 18832, 0x000088CF }, /* GL_MATRIX15_ARB */
+   { 18848, 0x000088D0 }, /* GL_MATRIX16_ARB */
+   { 18864, 0x000088D1 }, /* GL_MATRIX17_ARB */
+   { 18880, 0x000088D2 }, /* GL_MATRIX18_ARB */
+   { 18896, 0x000088D3 }, /* GL_MATRIX19_ARB */
+   { 18912, 0x000088C1 }, /* GL_MATRIX1_ARB */
+   { 18927, 0x00008631 }, /* GL_MATRIX1_NV */
+   { 18941, 0x000088D4 }, /* GL_MATRIX20_ARB */
+   { 18957, 0x000088D5 }, /* GL_MATRIX21_ARB */
+   { 18973, 0x000088D6 }, /* GL_MATRIX22_ARB */
+   { 18989, 0x000088D7 }, /* GL_MATRIX23_ARB */
+   { 19005, 0x000088D8 }, /* GL_MATRIX24_ARB */
+   { 19021, 0x000088D9 }, /* GL_MATRIX25_ARB */
+   { 19037, 0x000088DA }, /* GL_MATRIX26_ARB */
+   { 19053, 0x000088DB }, /* GL_MATRIX27_ARB */
+   { 19069, 0x000088DC }, /* GL_MATRIX28_ARB */
+   { 19085, 0x000088DD }, /* GL_MATRIX29_ARB */
+   { 19101, 0x000088C2 }, /* GL_MATRIX2_ARB */
+   { 19116, 0x00008632 }, /* GL_MATRIX2_NV */
+   { 19130, 0x000088DE }, /* GL_MATRIX30_ARB */
+   { 19146, 0x000088DF }, /* GL_MATRIX31_ARB */
+   { 19162, 0x000088C3 }, /* GL_MATRIX3_ARB */
+   { 19177, 0x00008633 }, /* GL_MATRIX3_NV */
+   { 19191, 0x000088C4 }, /* GL_MATRIX4_ARB */
+   { 19206, 0x00008634 }, /* GL_MATRIX4_NV */
+   { 19220, 0x000088C5 }, /* GL_MATRIX5_ARB */
+   { 19235, 0x00008635 }, /* GL_MATRIX5_NV */
+   { 19249, 0x000088C6 }, /* GL_MATRIX6_ARB */
+   { 19264, 0x00008636 }, /* GL_MATRIX6_NV */
+   { 19278, 0x000088C7 }, /* GL_MATRIX7_ARB */
+   { 19293, 0x00008637 }, /* GL_MATRIX7_NV */
+   { 19307, 0x000088C8 }, /* GL_MATRIX8_ARB */
+   { 19322, 0x000088C9 }, /* GL_MATRIX9_ARB */
+   { 19337, 0x00008844 }, /* GL_MATRIX_INDEX_ARRAY_ARB */
+   { 19363, 0x00008B9E }, /* GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES */
+   { 19404, 0x00008844 }, /* GL_MATRIX_INDEX_ARRAY_OES */
+   { 19430, 0x00008849 }, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */
+   { 19464, 0x00008849 }, /* GL_MATRIX_INDEX_ARRAY_POINTER_OES */
+   { 19498, 0x00008846 }, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */
+   { 19529, 0x00008846 }, /* GL_MATRIX_INDEX_ARRAY_SIZE_OES */
+   { 19560, 0x00008848 }, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */
+   { 19593, 0x00008848 }, /* GL_MATRIX_INDEX_ARRAY_STRIDE_OES */
+   { 19626, 0x00008847 }, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */
+   { 19657, 0x00008847 }, /* GL_MATRIX_INDEX_ARRAY_TYPE_OES */
+   { 19688, 0x00000BA0 }, /* GL_MATRIX_MODE */
+   { 19703, 0x00008840 }, /* GL_MATRIX_PALETTE_ARB */
+   { 19725, 0x00008840 }, /* GL_MATRIX_PALETTE_OES */
+   { 19747, 0x00008008 }, /* GL_MAX */
+   { 19754, 0x00008073 }, /* GL_MAX_3D_TEXTURE_SIZE */
+   { 19777, 0x00008073 }, /* GL_MAX_3D_TEXTURE_SIZE_OES */
+   { 19804, 0x000088FF }, /* GL_MAX_ARRAY_TEXTURE_LAYERS_EXT */
+   { 19836, 0x00000D35 }, /* GL_MAX_ATTRIB_STACK_DEPTH */
+   { 19862, 0x00000D3B }, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */
+   { 19895, 0x00008177 }, /* GL_MAX_CLIPMAP_DEPTH_SGIX */
+   { 19921, 0x00008178 }, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */
+   { 19955, 0x00000D32 }, /* GL_MAX_CLIP_PLANES */
+   { 19974, 0x00008CDF }, /* GL_MAX_COLOR_ATTACHMENTS */
+   { 19999, 0x00008CDF }, /* GL_MAX_COLOR_ATTACHMENTS_EXT */
+   { 20028, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */
+   { 20060, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI */
+   { 20096, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */
+   { 20132, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB */
+   { 20172, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT */
+   { 20198, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT_EXT */
+   { 20228, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH */
+   { 20253, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH_EXT */
+   { 20282, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */
+   { 20311, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB */
+   { 20344, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES */
+   { 20377, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS */
+   { 20397, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ARB */
+   { 20421, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ATI */
+   { 20445, 0x000080E9 }, /* GL_MAX_ELEMENTS_INDICES */
+   { 20469, 0x000080E8 }, /* GL_MAX_ELEMENTS_VERTICES */
+   { 20494, 0x00000D30 }, /* GL_MAX_EVAL_ORDER */
+   { 20512, 0x00008008 }, /* GL_MAX_EXT */
+   { 20523, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */
+   { 20558, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB */
+   { 20597, 0x00008DFD }, /* GL_MAX_FRAGMENT_UNIFORM_VECTORS */
+   { 20629, 0x00008DE0 }, /* GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB */
+   { 20665, 0x00008C29 }, /* GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB */
+   { 20705, 0x00008DE1 }, /* GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB */
+   { 20749, 0x00008DDF }, /* GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB */
+   { 20788, 0x00008DDD }, /* GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB */
+   { 20827, 0x00000D31 }, /* GL_MAX_LIGHTS */
+   { 20841, 0x00000B31 }, /* GL_MAX_LIST_NESTING */
+   { 20861, 0x00008841 }, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */
+   { 20899, 0x00000D36 }, /* GL_MAX_MODELVIEW_STACK_DEPTH */
+   { 20928, 0x00000D37 }, /* GL_MAX_NAME_STACK_DEPTH */
+   { 20952, 0x00008842 }, /* GL_MAX_PALETTE_MATRICES_ARB */
+   { 20980, 0x00008842 }, /* GL_MAX_PALETTE_MATRICES_OES */
+   { 21008, 0x00000D34 }, /* GL_MAX_PIXEL_MAP_TABLE */
+   { 21031, 0x000088B1 }, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */
+   { 21068, 0x0000880B }, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */
+   { 21104, 0x000088AD }, /* GL_MAX_PROGRAM_ATTRIBS_ARB */
+   { 21131, 0x000088F5 }, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */
+   { 21160, 0x000088B5 }, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */
+   { 21194, 0x000088F4 }, /* GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */
+   { 21230, 0x000088F6 }, /* GL_MAX_PROGRAM_IF_DEPTH_NV */
+   { 21257, 0x000088A1 }, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */
+   { 21289, 0x000088B4 }, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */
+   { 21325, 0x000088F8 }, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */
+   { 21354, 0x000088F7 }, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */
+   { 21383, 0x0000862F }, /* GL_MAX_PROGRAM_MATRICES_ARB */
+   { 21411, 0x0000862E }, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */
+   { 21449, 0x000088B3 }, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
+   { 21493, 0x0000880E }, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
+   { 21536, 0x000088AF }, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */
+   { 21570, 0x000088A3 }, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
+   { 21609, 0x000088AB }, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */
+   { 21646, 0x000088A7 }, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */
+   { 21684, 0x00008810 }, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
+   { 21727, 0x0000880F }, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
+   { 21770, 0x000088A9 }, /* GL_MAX_PROGRAM_PARAMETERS_ARB */
+   { 21800, 0x000088A5 }, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
+   { 21831, 0x0000880D }, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */
+   { 21867, 0x0000880C }, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */
+   { 21903, 0x00000D38 }, /* GL_MAX_PROJECTION_STACK_DEPTH */
+   { 21933, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */
+   { 21967, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_NV */
+   { 22000, 0x000084E8 }, /* GL_MAX_RENDERBUFFER_SIZE */
+   { 22025, 0x000084E8 }, /* GL_MAX_RENDERBUFFER_SIZE_EXT */
+   { 22054, 0x000084E8 }, /* GL_MAX_RENDERBUFFER_SIZE_OES */
+   { 22083, 0x00008D57 }, /* GL_MAX_SAMPLES */
+   { 22098, 0x00008D57 }, /* GL_MAX_SAMPLES_EXT */
+   { 22117, 0x00009111 }, /* GL_MAX_SERVER_WAIT_TIMEOUT */
+   { 22144, 0x00008504 }, /* GL_MAX_SHININESS_NV */
+   { 22164, 0x00008505 }, /* GL_MAX_SPOT_EXPONENT_NV */
+   { 22188, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS */
+   { 22210, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS_ARB */
+   { 22236, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS */
+   { 22263, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS_ARB */
+   { 22294, 0x000084FD }, /* GL_MAX_TEXTURE_LOD_BIAS */
+   { 22318, 0x000084FD }, /* GL_MAX_TEXTURE_LOD_BIAS_EXT */
+   { 22346, 0x000084FF }, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */
+   { 22380, 0x00000D33 }, /* GL_MAX_TEXTURE_SIZE */
+   { 22400, 0x00000D39 }, /* GL_MAX_TEXTURE_STACK_DEPTH */
+   { 22427, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS */
+   { 22448, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS_ARB */
+   { 22473, 0x0000862F }, /* GL_MAX_TRACK_MATRICES_NV */
+   { 22498, 0x0000862E }, /* GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV */
+   { 22533, 0x00008C8A }, /* GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT */
+   { 22586, 0x00008C8B }, /* GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT */
+   { 22633, 0x00008C80 }, /* GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT */
+   { 22683, 0x00008B4B }, /* GL_MAX_VARYING_COMPONENTS */
+   { 22709, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS */
+   { 22731, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS_ARB */
+   { 22757, 0x00008DFC }, /* GL_MAX_VARYING_VECTORS */
+   { 22780, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS */
+   { 22802, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS_ARB */
+   { 22828, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */
+   { 22862, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */
+   { 22900, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */
+   { 22933, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB */
+   { 22970, 0x00008DFB }, /* GL_MAX_VERTEX_UNIFORM_VECTORS */
+   { 23000, 0x000086A4 }, /* GL_MAX_VERTEX_UNITS_ARB */
+   { 23024, 0x000086A4 }, /* GL_MAX_VERTEX_UNITS_OES */
+   { 23048, 0x00008DDE }, /* GL_MAX_VERTEX_VARYING_COMPONENTS_ARB */
+   { 23085, 0x00000D3A }, /* GL_MAX_VIEWPORT_DIMS */
+   { 23106, 0x00008DF1 }, /* GL_MEDIUM_FLOAT */
+   { 23122, 0x00008DF4 }, /* GL_MEDIUM_INT */
+   { 23136, 0x00008007 }, /* GL_MIN */
+   { 23143, 0x0000802E }, /* GL_MINMAX */
+   { 23153, 0x0000802E }, /* GL_MINMAX_EXT */
+   { 23167, 0x0000802F }, /* GL_MINMAX_FORMAT */
+   { 23184, 0x0000802F }, /* GL_MINMAX_FORMAT_EXT */
+   { 23205, 0x00008030 }, /* GL_MINMAX_SINK */
+   { 23220, 0x00008030 }, /* GL_MINMAX_SINK_EXT */
+   { 23239, 0x00008007 }, /* GL_MIN_EXT */
+   { 23250, 0x00008370 }, /* GL_MIRRORED_REPEAT */
+   { 23269, 0x00008370 }, /* GL_MIRRORED_REPEAT_ARB */
+   { 23292, 0x00008370 }, /* GL_MIRRORED_REPEAT_IBM */
+   { 23315, 0x00008742 }, /* GL_MIRROR_CLAMP_ATI */
+   { 23335, 0x00008742 }, /* GL_MIRROR_CLAMP_EXT */
+   { 23355, 0x00008912 }, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */
+   { 23385, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_ATI */
+   { 23413, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */
+   { 23441, 0x00001700 }, /* GL_MODELVIEW */
+   { 23454, 0x00001700 }, /* GL_MODELVIEW0_ARB */
+   { 23472, 0x0000872A }, /* GL_MODELVIEW10_ARB */
+   { 23491, 0x0000872B }, /* GL_MODELVIEW11_ARB */
+   { 23510, 0x0000872C }, /* GL_MODELVIEW12_ARB */
+   { 23529, 0x0000872D }, /* GL_MODELVIEW13_ARB */
+   { 23548, 0x0000872E }, /* GL_MODELVIEW14_ARB */
+   { 23567, 0x0000872F }, /* GL_MODELVIEW15_ARB */
+   { 23586, 0x00008730 }, /* GL_MODELVIEW16_ARB */
+   { 23605, 0x00008731 }, /* GL_MODELVIEW17_ARB */
+   { 23624, 0x00008732 }, /* GL_MODELVIEW18_ARB */
+   { 23643, 0x00008733 }, /* GL_MODELVIEW19_ARB */
+   { 23662, 0x0000850A }, /* GL_MODELVIEW1_ARB */
+   { 23680, 0x00008734 }, /* GL_MODELVIEW20_ARB */
+   { 23699, 0x00008735 }, /* GL_MODELVIEW21_ARB */
+   { 23718, 0x00008736 }, /* GL_MODELVIEW22_ARB */
+   { 23737, 0x00008737 }, /* GL_MODELVIEW23_ARB */
+   { 23756, 0x00008738 }, /* GL_MODELVIEW24_ARB */
+   { 23775, 0x00008739 }, /* GL_MODELVIEW25_ARB */
+   { 23794, 0x0000873A }, /* GL_MODELVIEW26_ARB */
+   { 23813, 0x0000873B }, /* GL_MODELVIEW27_ARB */
+   { 23832, 0x0000873C }, /* GL_MODELVIEW28_ARB */
+   { 23851, 0x0000873D }, /* GL_MODELVIEW29_ARB */
+   { 23870, 0x00008722 }, /* GL_MODELVIEW2_ARB */
+   { 23888, 0x0000873E }, /* GL_MODELVIEW30_ARB */
+   { 23907, 0x0000873F }, /* GL_MODELVIEW31_ARB */
+   { 23926, 0x00008723 }, /* GL_MODELVIEW3_ARB */
+   { 23944, 0x00008724 }, /* GL_MODELVIEW4_ARB */
+   { 23962, 0x00008725 }, /* GL_MODELVIEW5_ARB */
+   { 23980, 0x00008726 }, /* GL_MODELVIEW6_ARB */
+   { 23998, 0x00008727 }, /* GL_MODELVIEW7_ARB */
+   { 24016, 0x00008728 }, /* GL_MODELVIEW8_ARB */
+   { 24034, 0x00008729 }, /* GL_MODELVIEW9_ARB */
+   { 24052, 0x00000BA6 }, /* GL_MODELVIEW_MATRIX */
+   { 24072, 0x0000898D }, /* GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES */
+   { 24114, 0x00008629 }, /* GL_MODELVIEW_PROJECTION_NV */
+   { 24141, 0x00000BA3 }, /* GL_MODELVIEW_STACK_DEPTH */
+   { 24166, 0x00002100 }, /* GL_MODULATE */
+   { 24178, 0x00008744 }, /* GL_MODULATE_ADD_ATI */
+   { 24198, 0x00008745 }, /* GL_MODULATE_SIGNED_ADD_ATI */
+   { 24225, 0x00008746 }, /* GL_MODULATE_SUBTRACT_ATI */
+   { 24250, 0x00000103 }, /* GL_MULT */
+   { 24258, 0x0000809D }, /* GL_MULTISAMPLE */
+   { 24273, 0x000086B2 }, /* GL_MULTISAMPLE_3DFX */
+   { 24293, 0x0000809D }, /* GL_MULTISAMPLE_ARB */
+   { 24312, 0x20000000 }, /* GL_MULTISAMPLE_BIT */
+   { 24331, 0x20000000 }, /* GL_MULTISAMPLE_BIT_3DFX */
+   { 24355, 0x20000000 }, /* GL_MULTISAMPLE_BIT_ARB */
+   { 24378, 0x00008534 }, /* GL_MULTISAMPLE_FILTER_HINT_NV */
+   { 24408, 0x00002A25 }, /* GL_N3F_V3F */
+   { 24419, 0x00000D70 }, /* GL_NAME_STACK_DEPTH */
+   { 24439, 0x0000150E }, /* GL_NAND */
+   { 24447, 0x00002600 }, /* GL_NEAREST */
+   { 24458, 0x0000844E }, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */
+   { 24489, 0x0000844D }, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */
+   { 24521, 0x00002702 }, /* GL_NEAREST_MIPMAP_LINEAR */
+   { 24546, 0x00002700 }, /* GL_NEAREST_MIPMAP_NEAREST */
+   { 24572, 0x00000200 }, /* GL_NEVER */
+   { 24581, 0x00001102 }, /* GL_NICEST */
+   { 24591, 0x00000000 }, /* GL_NONE */
+   { 24599, 0x00000000 }, /* GL_NONE_OES */
+   { 24611, 0x00001505 }, /* GL_NOOP */
+   { 24619, 0x00001508 }, /* GL_NOR */
+   { 24626, 0x00000BA1 }, /* GL_NORMALIZE */
+   { 24639, 0x00008075 }, /* GL_NORMAL_ARRAY */
+   { 24655, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING */
+   { 24686, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING_ARB */
+   { 24721, 0x0000808F }, /* GL_NORMAL_ARRAY_POINTER */
+   { 24745, 0x0000807F }, /* GL_NORMAL_ARRAY_STRIDE */
+   { 24768, 0x0000807E }, /* GL_NORMAL_ARRAY_TYPE */
+   { 24789, 0x00008511 }, /* GL_NORMAL_MAP */
+   { 24803, 0x00008511 }, /* GL_NORMAL_MAP_ARB */
+   { 24821, 0x00008511 }, /* GL_NORMAL_MAP_NV */
+   { 24838, 0x00008511 }, /* GL_NORMAL_MAP_OES */
+   { 24856, 0x00000205 }, /* GL_NOTEQUAL */
+   { 24868, 0x00000000 }, /* GL_NO_ERROR */
+   { 24880, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */
+   { 24914, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB */
+   { 24952, 0x000087FE }, /* GL_NUM_PROGRAM_BINARY_FORMATS_OES */
+   { 24986, 0x00008DF9 }, /* GL_NUM_SHADER_BINARY_FORMATS */
+   { 25015, 0x00008B89 }, /* GL_OBJECT_ACTIVE_ATTRIBUTES_ARB */
+   { 25047, 0x00008B8A }, /* GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB */
+   { 25089, 0x00008B86 }, /* GL_OBJECT_ACTIVE_UNIFORMS_ARB */
+   { 25119, 0x00008B87 }, /* GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB */
+   { 25159, 0x00008B85 }, /* GL_OBJECT_ATTACHED_OBJECTS_ARB */
+   { 25190, 0x00008B81 }, /* GL_OBJECT_COMPILE_STATUS_ARB */
+   { 25219, 0x00008B80 }, /* GL_OBJECT_DELETE_STATUS_ARB */
+   { 25247, 0x00008B84 }, /* GL_OBJECT_INFO_LOG_LENGTH_ARB */
+   { 25277, 0x00002401 }, /* GL_OBJECT_LINEAR */
+   { 25294, 0x00008B82 }, /* GL_OBJECT_LINK_STATUS_ARB */
+   { 25320, 0x00002501 }, /* GL_OBJECT_PLANE */
+   { 25336, 0x00008B88 }, /* GL_OBJECT_SHADER_SOURCE_LENGTH_ARB */
+   { 25371, 0x00008B4F }, /* GL_OBJECT_SUBTYPE_ARB */
+   { 25393, 0x00009112 }, /* GL_OBJECT_TYPE */
+   { 25408, 0x00008B4E }, /* GL_OBJECT_TYPE_ARB */
+   { 25427, 0x00008B83 }, /* GL_OBJECT_VALIDATE_STATUS_ARB */
+   { 25457, 0x00008165 }, /* GL_OCCLUSION_TEST_HP */
+   { 25478, 0x00008166 }, /* GL_OCCLUSION_TEST_RESULT_HP */
+   { 25506, 0x00000001 }, /* GL_ONE */
+   { 25513, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA */
+   { 25541, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA_EXT */
+   { 25573, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR */
+   { 25601, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR_EXT */
+   { 25633, 0x00000305 }, /* GL_ONE_MINUS_DST_ALPHA */
+   { 25656, 0x00000307 }, /* GL_ONE_MINUS_DST_COLOR */
+   { 25679, 0x00000303 }, /* GL_ONE_MINUS_SRC_ALPHA */
+   { 25702, 0x00000301 }, /* GL_ONE_MINUS_SRC_COLOR */
+   { 25725, 0x00008598 }, /* GL_OPERAND0_ALPHA */
+   { 25743, 0x00008598 }, /* GL_OPERAND0_ALPHA_ARB */
+   { 25765, 0x00008598 }, /* GL_OPERAND0_ALPHA_EXT */
+   { 25787, 0x00008590 }, /* GL_OPERAND0_RGB */
+   { 25803, 0x00008590 }, /* GL_OPERAND0_RGB_ARB */
+   { 25823, 0x00008590 }, /* GL_OPERAND0_RGB_EXT */
+   { 25843, 0x00008599 }, /* GL_OPERAND1_ALPHA */
+   { 25861, 0x00008599 }, /* GL_OPERAND1_ALPHA_ARB */
+   { 25883, 0x00008599 }, /* GL_OPERAND1_ALPHA_EXT */
+   { 25905, 0x00008591 }, /* GL_OPERAND1_RGB */
+   { 25921, 0x00008591 }, /* GL_OPERAND1_RGB_ARB */
+   { 25941, 0x00008591 }, /* GL_OPERAND1_RGB_EXT */
+   { 25961, 0x0000859A }, /* GL_OPERAND2_ALPHA */
+   { 25979, 0x0000859A }, /* GL_OPERAND2_ALPHA_ARB */
+   { 26001, 0x0000859A }, /* GL_OPERAND2_ALPHA_EXT */
+   { 26023, 0x00008592 }, /* GL_OPERAND2_RGB */
+   { 26039, 0x00008592 }, /* GL_OPERAND2_RGB_ARB */
+   { 26059, 0x00008592 }, /* GL_OPERAND2_RGB_EXT */
+   { 26079, 0x0000859B }, /* GL_OPERAND3_ALPHA_NV */
+   { 26100, 0x00008593 }, /* GL_OPERAND3_RGB_NV */
+   { 26119, 0x00001507 }, /* GL_OR */
+   { 26125, 0x00000A01 }, /* GL_ORDER */
+   { 26134, 0x0000150D }, /* GL_OR_INVERTED */
+   { 26149, 0x0000150B }, /* GL_OR_REVERSE */
+   { 26163, 0x00000505 }, /* GL_OUT_OF_MEMORY */
+   { 26180, 0x00000D05 }, /* GL_PACK_ALIGNMENT */
+   { 26198, 0x0000806C }, /* GL_PACK_IMAGE_HEIGHT */
+   { 26219, 0x00008758 }, /* GL_PACK_INVERT_MESA */
+   { 26239, 0x00000D01 }, /* GL_PACK_LSB_FIRST */
+   { 26257, 0x00000D02 }, /* GL_PACK_ROW_LENGTH */
+   { 26276, 0x0000806B }, /* GL_PACK_SKIP_IMAGES */
+   { 26296, 0x00000D04 }, /* GL_PACK_SKIP_PIXELS */
+   { 26316, 0x00000D03 }, /* GL_PACK_SKIP_ROWS */
+   { 26334, 0x00000D00 }, /* GL_PACK_SWAP_BYTES */
+   { 26353, 0x00008B92 }, /* GL_PALETTE4_R5_G6_B5_OES */
+   { 26378, 0x00008B94 }, /* GL_PALETTE4_RGB5_A1_OES */
+   { 26402, 0x00008B90 }, /* GL_PALETTE4_RGB8_OES */
+   { 26423, 0x00008B93 }, /* GL_PALETTE4_RGBA4_OES */
+   { 26445, 0x00008B91 }, /* GL_PALETTE4_RGBA8_OES */
+   { 26467, 0x00008B97 }, /* GL_PALETTE8_R5_G6_B5_OES */
+   { 26492, 0x00008B99 }, /* GL_PALETTE8_RGB5_A1_OES */
+   { 26516, 0x00008B95 }, /* GL_PALETTE8_RGB8_OES */
+   { 26537, 0x00008B98 }, /* GL_PALETTE8_RGBA4_OES */
+   { 26559, 0x00008B96 }, /* GL_PALETTE8_RGBA8_OES */
+   { 26581, 0x00000700 }, /* GL_PASS_THROUGH_TOKEN */
+   { 26603, 0x00000C50 }, /* GL_PERSPECTIVE_CORRECTION_HINT */
+   { 26634, 0x00000C79 }, /* GL_PIXEL_MAP_A_TO_A */
+   { 26654, 0x00000CB9 }, /* GL_PIXEL_MAP_A_TO_A_SIZE */
+   { 26679, 0x00000C78 }, /* GL_PIXEL_MAP_B_TO_B */
+   { 26699, 0x00000CB8 }, /* GL_PIXEL_MAP_B_TO_B_SIZE */
+   { 26724, 0x00000C77 }, /* GL_PIXEL_MAP_G_TO_G */
+   { 26744, 0x00000CB7 }, /* GL_PIXEL_MAP_G_TO_G_SIZE */
+   { 26769, 0x00000C75 }, /* GL_PIXEL_MAP_I_TO_A */
+   { 26789, 0x00000CB5 }, /* GL_PIXEL_MAP_I_TO_A_SIZE */
+   { 26814, 0x00000C74 }, /* GL_PIXEL_MAP_I_TO_B */
+   { 26834, 0x00000CB4 }, /* GL_PIXEL_MAP_I_TO_B_SIZE */
+   { 26859, 0x00000C73 }, /* GL_PIXEL_MAP_I_TO_G */
+   { 26879, 0x00000CB3 }, /* GL_PIXEL_MAP_I_TO_G_SIZE */
+   { 26904, 0x00000C70 }, /* GL_PIXEL_MAP_I_TO_I */
+   { 26924, 0x00000CB0 }, /* GL_PIXEL_MAP_I_TO_I_SIZE */
+   { 26949, 0x00000C72 }, /* GL_PIXEL_MAP_I_TO_R */
+   { 26969, 0x00000CB2 }, /* GL_PIXEL_MAP_I_TO_R_SIZE */
+   { 26994, 0x00000C76 }, /* GL_PIXEL_MAP_R_TO_R */
+   { 27014, 0x00000CB6 }, /* GL_PIXEL_MAP_R_TO_R_SIZE */
+   { 27039, 0x00000C71 }, /* GL_PIXEL_MAP_S_TO_S */
+   { 27059, 0x00000CB1 }, /* GL_PIXEL_MAP_S_TO_S_SIZE */
+   { 27084, 0x00000020 }, /* GL_PIXEL_MODE_BIT */
+   { 27102, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER */
+   { 27123, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING */
+   { 27152, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING_EXT */
+   { 27185, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER_EXT */
+   { 27210, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER */
+   { 27233, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING */
+   { 27264, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING_EXT */
+   { 27299, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER_EXT */
+   { 27326, 0x00001B00 }, /* GL_POINT */
+   { 27335, 0x00000000 }, /* GL_POINTS */
+   { 27345, 0x00000002 }, /* GL_POINT_BIT */
+   { 27358, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION */
+   { 27388, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_ARB */
+   { 27422, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_EXT */
+   { 27456, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_SGIS */
+   { 27491, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE */
+   { 27520, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_ARB */
+   { 27553, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_EXT */
+   { 27586, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_SGIS */
+   { 27620, 0x00000B11 }, /* GL_POINT_SIZE */
+   { 27634, 0x00008B9F }, /* GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES */
+   { 27673, 0x00008B9C }, /* GL_POINT_SIZE_ARRAY_OES */
+   { 27697, 0x0000898C }, /* GL_POINT_SIZE_ARRAY_POINTER_OES */
+   { 27729, 0x0000898B }, /* GL_POINT_SIZE_ARRAY_STRIDE_OES */
+   { 27760, 0x0000898A }, /* GL_POINT_SIZE_ARRAY_TYPE_OES */
+   { 27789, 0x00000B13 }, /* GL_POINT_SIZE_GRANULARITY */
+   { 27815, 0x00008127 }, /* GL_POINT_SIZE_MAX */
+   { 27833, 0x00008127 }, /* GL_POINT_SIZE_MAX_ARB */
+   { 27855, 0x00008127 }, /* GL_POINT_SIZE_MAX_EXT */
+   { 27877, 0x00008127 }, /* GL_POINT_SIZE_MAX_SGIS */
+   { 27900, 0x00008126 }, /* GL_POINT_SIZE_MIN */
+   { 27918, 0x00008126 }, /* GL_POINT_SIZE_MIN_ARB */
+   { 27940, 0x00008126 }, /* GL_POINT_SIZE_MIN_EXT */
+   { 27962, 0x00008126 }, /* GL_POINT_SIZE_MIN_SGIS */
+   { 27985, 0x00000B12 }, /* GL_POINT_SIZE_RANGE */
+   { 28005, 0x00000B10 }, /* GL_POINT_SMOOTH */
+   { 28021, 0x00000C51 }, /* GL_POINT_SMOOTH_HINT */
+   { 28042, 0x00008861 }, /* GL_POINT_SPRITE */
+   { 28058, 0x00008861 }, /* GL_POINT_SPRITE_ARB */
+   { 28078, 0x00008CA0 }, /* GL_POINT_SPRITE_COORD_ORIGIN */
+   { 28107, 0x00008861 }, /* GL_POINT_SPRITE_NV */
+   { 28126, 0x00008861 }, /* GL_POINT_SPRITE_OES */
+   { 28146, 0x00008863 }, /* GL_POINT_SPRITE_R_MODE_NV */
+   { 28172, 0x00000701 }, /* GL_POINT_TOKEN */
+   { 28187, 0x00000009 }, /* GL_POLYGON */
+   { 28198, 0x00000008 }, /* GL_POLYGON_BIT */
+   { 28213, 0x00000B40 }, /* GL_POLYGON_MODE */
+   { 28229, 0x00008039 }, /* GL_POLYGON_OFFSET_BIAS */
+   { 28252, 0x00008038 }, /* GL_POLYGON_OFFSET_FACTOR */
+   { 28277, 0x00008037 }, /* GL_POLYGON_OFFSET_FILL */
+   { 28300, 0x00002A02 }, /* GL_POLYGON_OFFSET_LINE */
+   { 28323, 0x00002A01 }, /* GL_POLYGON_OFFSET_POINT */
+   { 28347, 0x00002A00 }, /* GL_POLYGON_OFFSET_UNITS */
+   { 28371, 0x00000B41 }, /* GL_POLYGON_SMOOTH */
+   { 28389, 0x00000C53 }, /* GL_POLYGON_SMOOTH_HINT */
+   { 28412, 0x00000B42 }, /* GL_POLYGON_STIPPLE */
+   { 28431, 0x00000010 }, /* GL_POLYGON_STIPPLE_BIT */
+   { 28454, 0x00000703 }, /* GL_POLYGON_TOKEN */
+   { 28471, 0x00001203 }, /* GL_POSITION */
+   { 28483, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */
+   { 28515, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI */
+   { 28551, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */
+   { 28584, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI */
+   { 28621, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */
+   { 28652, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI */
+   { 28687, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */
+   { 28719, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI */
+   { 28755, 0x000080D2 }, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */
+   { 28788, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */
+   { 28820, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI */
+   { 28856, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */
+   { 28889, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI */
+   { 28926, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS */
+   { 28956, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS_SGI */
+   { 28990, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE */
+   { 29021, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE_SGI */
+   { 29056, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS */
+   { 29087, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS_EXT */
+   { 29122, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE */
+   { 29154, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE_EXT */
+   { 29190, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS */
+   { 29220, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS_EXT */
+   { 29254, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE */
+   { 29285, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE_EXT */
+   { 29320, 0x000080D1 }, /* GL_POST_CONVOLUTION_COLOR_TABLE */
+   { 29352, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS */
+   { 29383, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS_EXT */
+   { 29418, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE */
+   { 29450, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE_EXT */
+   { 29486, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS */
+   { 29515, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS_EXT */
+   { 29548, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE */
+   { 29578, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE_EXT */
+   { 29612, 0x0000817B }, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */
+   { 29651, 0x00008179 }, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */
+   { 29684, 0x0000817C }, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */
+   { 29724, 0x0000817A }, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */
+   { 29758, 0x00008578 }, /* GL_PREVIOUS */
+   { 29770, 0x00008578 }, /* GL_PREVIOUS_ARB */
+   { 29786, 0x00008578 }, /* GL_PREVIOUS_EXT */
+   { 29802, 0x00008577 }, /* GL_PRIMARY_COLOR */
+   { 29819, 0x00008577 }, /* GL_PRIMARY_COLOR_ARB */
+   { 29840, 0x00008577 }, /* GL_PRIMARY_COLOR_EXT */
+   { 29861, 0x00008C87 }, /* GL_PRIMITIVES_GENERATED_EXT */
+   { 29889, 0x000088B0 }, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */
+   { 29922, 0x00008805 }, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */
+   { 29954, 0x000088AC }, /* GL_PROGRAM_ATTRIBS_ARB */
+   { 29977, 0x000087FF }, /* GL_PROGRAM_BINARY_FORMATS_OES */
+   { 30007, 0x00008741 }, /* GL_PROGRAM_BINARY_LENGTH_OES */
+   { 30036, 0x00008677 }, /* GL_PROGRAM_BINDING_ARB */
+   { 30059, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_ARB */
+   { 30089, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_NV */
+   { 30118, 0x00008874 }, /* GL_PROGRAM_ERROR_STRING_ARB */
+   { 30146, 0x00008876 }, /* GL_PROGRAM_FORMAT_ARB */
+   { 30168, 0x00008875 }, /* GL_PROGRAM_FORMAT_ASCII_ARB */
+   { 30196, 0x000088A0 }, /* GL_PROGRAM_INSTRUCTIONS_ARB */
+   { 30224, 0x00008627 }, /* GL_PROGRAM_LENGTH_ARB */
+   { 30246, 0x00008627 }, /* GL_PROGRAM_LENGTH_NV */
+   { 30267, 0x000088B2 }, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
+   { 30307, 0x00008808 }, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
+   { 30346, 0x000088AE }, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */
+   { 30376, 0x000088A2 }, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
+   { 30411, 0x000088AA }, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */
+   { 30444, 0x000088A6 }, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */
+   { 30478, 0x0000880A }, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
+   { 30517, 0x00008809 }, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
+   { 30556, 0x00008B40 }, /* GL_PROGRAM_OBJECT_ARB */
+   { 30578, 0x000088A8 }, /* GL_PROGRAM_PARAMETERS_ARB */
+   { 30604, 0x00008644 }, /* GL_PROGRAM_PARAMETER_NV */
+   { 30628, 0x00008642 }, /* GL_PROGRAM_POINT_SIZE_ARB */
+   { 30654, 0x00008647 }, /* GL_PROGRAM_RESIDENT_NV */
+   { 30677, 0x00008628 }, /* GL_PROGRAM_STRING_ARB */
+   { 30699, 0x00008628 }, /* GL_PROGRAM_STRING_NV */
+   { 30720, 0x00008646 }, /* GL_PROGRAM_TARGET_NV */
+   { 30741, 0x000088A4 }, /* GL_PROGRAM_TEMPORARIES_ARB */
+   { 30768, 0x00008807 }, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */
+   { 30800, 0x00008806 }, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */
+   { 30832, 0x000088B6 }, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */
+   { 30867, 0x00001701 }, /* GL_PROJECTION */
+   { 30881, 0x00000BA7 }, /* GL_PROJECTION_MATRIX */
+   { 30902, 0x0000898E }, /* GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES */
+   { 30945, 0x00000BA4 }, /* GL_PROJECTION_STACK_DEPTH */
+   { 30971, 0x00008E4F }, /* GL_PROVOKING_VERTEX */
+   { 30991, 0x00008E4F }, /* GL_PROVOKING_VERTEX_EXT */
+   { 31015, 0x000080D3 }, /* GL_PROXY_COLOR_TABLE */
+   { 31036, 0x00008025 }, /* GL_PROXY_HISTOGRAM */
+   { 31055, 0x00008025 }, /* GL_PROXY_HISTOGRAM_EXT */
+   { 31078, 0x000080D5 }, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */
+   { 31117, 0x000080D4 }, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */
+   { 31155, 0x00008063 }, /* GL_PROXY_TEXTURE_1D */
+   { 31175, 0x00008C19 }, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */
+   { 31205, 0x00008063 }, /* GL_PROXY_TEXTURE_1D_EXT */
+   { 31229, 0x00008064 }, /* GL_PROXY_TEXTURE_2D */
+   { 31249, 0x00008C1B }, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */
+   { 31279, 0x00008064 }, /* GL_PROXY_TEXTURE_2D_EXT */
+   { 31303, 0x00008070 }, /* GL_PROXY_TEXTURE_3D */
+   { 31323, 0x000080BD }, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */
+   { 31356, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP */
+   { 31382, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP_ARB */
+   { 31412, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */
+   { 31443, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_NV */
+   { 31473, 0x00008A1D }, /* GL_PURGEABLE_APPLE */
+   { 31492, 0x00002003 }, /* GL_Q */
+   { 31497, 0x00001209 }, /* GL_QUADRATIC_ATTENUATION */
+   { 31522, 0x00000007 }, /* GL_QUADS */
+   { 31531, 0x00008E4C }, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */
+   { 31575, 0x00008E4C }, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT */
+   { 31623, 0x00008614 }, /* GL_QUAD_MESH_SUN */
+   { 31640, 0x00000008 }, /* GL_QUAD_STRIP */
+   { 31654, 0x00008E16 }, /* GL_QUERY_BY_REGION_NO_WAIT_NV */
+   { 31684, 0x00008E15 }, /* GL_QUERY_BY_REGION_WAIT_NV */
+   { 31711, 0x00008864 }, /* GL_QUERY_COUNTER_BITS */
+   { 31733, 0x00008864 }, /* GL_QUERY_COUNTER_BITS_ARB */
+   { 31759, 0x00008E14 }, /* GL_QUERY_NO_WAIT_NV */
+   { 31779, 0x00008866 }, /* GL_QUERY_RESULT */
+   { 31795, 0x00008866 }, /* GL_QUERY_RESULT_ARB */
+   { 31815, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE */
+   { 31841, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE_ARB */
+   { 31871, 0x00008E13 }, /* GL_QUERY_WAIT_NV */
+   { 31888, 0x00002002 }, /* GL_R */
+   { 31893, 0x00002A10 }, /* GL_R3_G3_B2 */
+   { 31905, 0x00008C89 }, /* GL_RASTERIZER_DISCARD_EXT */
+   { 31931, 0x00019262 }, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
+   { 31964, 0x00000C02 }, /* GL_READ_BUFFER */
+   { 31979, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER */
+   { 31999, 0x00008CAA }, /* GL_READ_FRAMEBUFFER_BINDING */
+   { 32027, 0x00008CAA }, /* GL_READ_FRAMEBUFFER_BINDING_EXT */
+   { 32059, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER_EXT */
+   { 32083, 0x000088B8 }, /* GL_READ_ONLY */
+   { 32096, 0x000088B8 }, /* GL_READ_ONLY_ARB */
+   { 32113, 0x000088BA }, /* GL_READ_WRITE */
+   { 32127, 0x000088BA }, /* GL_READ_WRITE_ARB */
+   { 32145, 0x00001903 }, /* GL_RED */
+   { 32152, 0x00008016 }, /* GL_REDUCE */
+   { 32162, 0x00008016 }, /* GL_REDUCE_EXT */
+   { 32176, 0x00000D15 }, /* GL_RED_BIAS */
+   { 32188, 0x00000D52 }, /* GL_RED_BITS */
+   { 32200, 0x00000D14 }, /* GL_RED_SCALE */
+   { 32213, 0x00008512 }, /* GL_REFLECTION_MAP */
+   { 32231, 0x00008512 }, /* GL_REFLECTION_MAP_ARB */
+   { 32253, 0x00008512 }, /* GL_REFLECTION_MAP_NV */
+   { 32274, 0x00008512 }, /* GL_REFLECTION_MAP_OES */
+   { 32296, 0x00008A19 }, /* GL_RELEASED_APPLE */
+   { 32314, 0x00001C00 }, /* GL_RENDER */
+   { 32324, 0x00008D41 }, /* GL_RENDERBUFFER */
+   { 32340, 0x00008D53 }, /* GL_RENDERBUFFER_ALPHA_SIZE */
+   { 32367, 0x00008D53 }, /* GL_RENDERBUFFER_ALPHA_SIZE_OES */
+   { 32398, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING */
+   { 32422, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING_EXT */
+   { 32450, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING_OES */
+   { 32478, 0x00008D52 }, /* GL_RENDERBUFFER_BLUE_SIZE */
+   { 32504, 0x00008D52 }, /* GL_RENDERBUFFER_BLUE_SIZE_OES */
+   { 32534, 0x00008D54 }, /* GL_RENDERBUFFER_DEPTH_SIZE */
+   { 32561, 0x00008D54 }, /* GL_RENDERBUFFER_DEPTH_SIZE_OES */
+   { 32592, 0x00008D41 }, /* GL_RENDERBUFFER_EXT */
+   { 32612, 0x00008D51 }, /* GL_RENDERBUFFER_GREEN_SIZE */
+   { 32639, 0x00008D51 }, /* GL_RENDERBUFFER_GREEN_SIZE_OES */
+   { 32670, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT */
+   { 32693, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT_EXT */
+   { 32720, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT_OES */
+   { 32747, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT */
+   { 32779, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT_EXT */
+   { 32815, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT_OES */
+   { 32851, 0x00008D41 }, /* GL_RENDERBUFFER_OES */
+   { 32871, 0x00008D50 }, /* GL_RENDERBUFFER_RED_SIZE */
+   { 32896, 0x00008D50 }, /* GL_RENDERBUFFER_RED_SIZE_OES */
+   { 32925, 0x00008CAB }, /* GL_RENDERBUFFER_SAMPLES */
+   { 32949, 0x00008CAB }, /* GL_RENDERBUFFER_SAMPLES_EXT */
+   { 32977, 0x00008D55 }, /* GL_RENDERBUFFER_STENCIL_SIZE */
+   { 33006, 0x00008D55 }, /* GL_RENDERBUFFER_STENCIL_SIZE_OES */
+   { 33039, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH */
+   { 33061, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH_EXT */
+   { 33087, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH_OES */
+   { 33113, 0x00001F01 }, /* GL_RENDERER */
+   { 33125, 0x00000C40 }, /* GL_RENDER_MODE */
+   { 33140, 0x00002901 }, /* GL_REPEAT */
+   { 33150, 0x00001E01 }, /* GL_REPLACE */
+   { 33161, 0x00008062 }, /* GL_REPLACE_EXT */
+   { 33176, 0x00008153 }, /* GL_REPLICATE_BORDER_HP */
+   { 33199, 0x0000803A }, /* GL_RESCALE_NORMAL */
+   { 33217, 0x0000803A }, /* GL_RESCALE_NORMAL_EXT */
+   { 33239, 0x00008A1B }, /* GL_RETAINED_APPLE */
+   { 33257, 0x00000102 }, /* GL_RETURN */
+   { 33267, 0x00001907 }, /* GL_RGB */
+   { 33274, 0x00008052 }, /* GL_RGB10 */
+   { 33283, 0x00008059 }, /* GL_RGB10_A2 */
+   { 33295, 0x00008059 }, /* GL_RGB10_A2_EXT */
+   { 33311, 0x00008052 }, /* GL_RGB10_EXT */
+   { 33324, 0x00008053 }, /* GL_RGB12 */
+   { 33333, 0x00008053 }, /* GL_RGB12_EXT */
+   { 33346, 0x00008054 }, /* GL_RGB16 */
+   { 33355, 0x00008054 }, /* GL_RGB16_EXT */
+   { 33368, 0x0000804E }, /* GL_RGB2_EXT */
+   { 33380, 0x0000804F }, /* GL_RGB4 */
+   { 33388, 0x0000804F }, /* GL_RGB4_EXT */
+   { 33400, 0x000083A1 }, /* GL_RGB4_S3TC */
+   { 33413, 0x00008050 }, /* GL_RGB5 */
+   { 33421, 0x00008D62 }, /* GL_RGB565 */
+   { 33431, 0x00008D62 }, /* GL_RGB565_OES */
+   { 33445, 0x00008057 }, /* GL_RGB5_A1 */
+   { 33456, 0x00008057 }, /* GL_RGB5_A1_EXT */
+   { 33471, 0x00008057 }, /* GL_RGB5_A1_OES */
+   { 33486, 0x00008050 }, /* GL_RGB5_EXT */
+   { 33498, 0x00008051 }, /* GL_RGB8 */
+   { 33506, 0x00008051 }, /* GL_RGB8_EXT */
+   { 33518, 0x00008051 }, /* GL_RGB8_OES */
+   { 33530, 0x00001908 }, /* GL_RGBA */
+   { 33538, 0x0000805A }, /* GL_RGBA12 */
+   { 33548, 0x0000805A }, /* GL_RGBA12_EXT */
+   { 33562, 0x0000805B }, /* GL_RGBA16 */
+   { 33572, 0x0000805B }, /* GL_RGBA16_EXT */
+   { 33586, 0x00008055 }, /* GL_RGBA2 */
+   { 33595, 0x00008055 }, /* GL_RGBA2_EXT */
+   { 33608, 0x00008056 }, /* GL_RGBA4 */
+   { 33617, 0x000083A5 }, /* GL_RGBA4_DXT5_S3TC */
+   { 33636, 0x00008056 }, /* GL_RGBA4_EXT */
+   { 33649, 0x00008056 }, /* GL_RGBA4_OES */
+   { 33662, 0x000083A3 }, /* GL_RGBA4_S3TC */
+   { 33676, 0x00008058 }, /* GL_RGBA8 */
+   { 33685, 0x00008058 }, /* GL_RGBA8_EXT */
+   { 33698, 0x00008058 }, /* GL_RGBA8_OES */
+   { 33711, 0x00008F97 }, /* GL_RGBA8_SNORM */
+   { 33726, 0x000083A4 }, /* GL_RGBA_DXT5_S3TC */
+   { 33744, 0x00000C31 }, /* GL_RGBA_MODE */
+   { 33757, 0x000083A2 }, /* GL_RGBA_S3TC */
+   { 33770, 0x00008F93 }, /* GL_RGBA_SNORM */
+   { 33784, 0x000083A0 }, /* GL_RGB_S3TC */
+   { 33796, 0x00008573 }, /* GL_RGB_SCALE */
+   { 33809, 0x00008573 }, /* GL_RGB_SCALE_ARB */
+   { 33826, 0x00008573 }, /* GL_RGB_SCALE_EXT */
+   { 33843, 0x00000407 }, /* GL_RIGHT */
+   { 33852, 0x00002000 }, /* GL_S */
+   { 33857, 0x00008B5D }, /* GL_SAMPLER_1D */
+   { 33871, 0x00008B61 }, /* GL_SAMPLER_1D_SHADOW */
+   { 33892, 0x00008B5E }, /* GL_SAMPLER_2D */
+   { 33906, 0x00008B62 }, /* GL_SAMPLER_2D_SHADOW */
+   { 33927, 0x00008B5F }, /* GL_SAMPLER_3D */
+   { 33941, 0x00008B5F }, /* GL_SAMPLER_3D_OES */
+   { 33959, 0x00008B60 }, /* GL_SAMPLER_CUBE */
+   { 33975, 0x000080A9 }, /* GL_SAMPLES */
+   { 33986, 0x000086B4 }, /* GL_SAMPLES_3DFX */
+   { 34002, 0x000080A9 }, /* GL_SAMPLES_ARB */
+   { 34017, 0x00008914 }, /* GL_SAMPLES_PASSED */
+   { 34035, 0x00008914 }, /* GL_SAMPLES_PASSED_ARB */
+   { 34057, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE */
+   { 34085, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE_ARB */
+   { 34117, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE */
+   { 34140, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE_ARB */
+   { 34167, 0x000080A8 }, /* GL_SAMPLE_BUFFERS */
+   { 34185, 0x000086B3 }, /* GL_SAMPLE_BUFFERS_3DFX */
+   { 34208, 0x000080A8 }, /* GL_SAMPLE_BUFFERS_ARB */
+   { 34230, 0x000080A0 }, /* GL_SAMPLE_COVERAGE */
+   { 34249, 0x000080A0 }, /* GL_SAMPLE_COVERAGE_ARB */
+   { 34272, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT */
+   { 34298, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT_ARB */
+   { 34328, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE */
+   { 34353, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE_ARB */
+   { 34382, 0x00080000 }, /* GL_SCISSOR_BIT */
+   { 34397, 0x00000C10 }, /* GL_SCISSOR_BOX */
+   { 34412, 0x00000C11 }, /* GL_SCISSOR_TEST */
+   { 34428, 0x0000845E }, /* GL_SECONDARY_COLOR_ARRAY */
+   { 34453, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */
+   { 34493, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB */
+   { 34537, 0x0000845D }, /* GL_SECONDARY_COLOR_ARRAY_POINTER */
+   { 34570, 0x0000845A }, /* GL_SECONDARY_COLOR_ARRAY_SIZE */
+   { 34600, 0x0000845C }, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */
+   { 34632, 0x0000845B }, /* GL_SECONDARY_COLOR_ARRAY_TYPE */
+   { 34662, 0x00001C02 }, /* GL_SELECT */
+   { 34672, 0x00000DF3 }, /* GL_SELECTION_BUFFER_POINTER */
+   { 34700, 0x00000DF4 }, /* GL_SELECTION_BUFFER_SIZE */
+   { 34725, 0x00008012 }, /* GL_SEPARABLE_2D */
+   { 34741, 0x00008C8D }, /* GL_SEPARATE_ATTRIBS_EXT */
+   { 34765, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR */
+   { 34792, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR_EXT */
+   { 34823, 0x0000150F }, /* GL_SET */
+   { 34830, 0x00008DF8 }, /* GL_SHADER_BINARY_FORMATS */
+   { 34855, 0x00008DFA }, /* GL_SHADER_COMPILER */
+   { 34874, 0x00008B48 }, /* GL_SHADER_OBJECT_ARB */
+   { 34895, 0x00008B88 }, /* GL_SHADER_SOURCE_LENGTH */
+   { 34919, 0x00008B4F }, /* GL_SHADER_TYPE */
+   { 34934, 0x00000B54 }, /* GL_SHADE_MODEL */
+   { 34949, 0x00008B8C }, /* GL_SHADING_LANGUAGE_VERSION */
+   { 34977, 0x000080BF }, /* GL_SHADOW_AMBIENT_SGIX */
+   { 35000, 0x000081FB }, /* GL_SHARED_TEXTURE_PALETTE_EXT */
+   { 35030, 0x00001601 }, /* GL_SHININESS */
+   { 35043, 0x00001402 }, /* GL_SHORT */
+   { 35052, 0x00009119 }, /* GL_SIGNALED */
+   { 35064, 0x00008F9C }, /* GL_SIGNED_NORMALIZED */
+   { 35085, 0x000081F9 }, /* GL_SINGLE_COLOR */
+   { 35101, 0x000081F9 }, /* GL_SINGLE_COLOR_EXT */
+   { 35121, 0x000085CC }, /* GL_SLICE_ACCUM_SUN */
+   { 35140, 0x00008C46 }, /* GL_SLUMINANCE */
+   { 35154, 0x00008C47 }, /* GL_SLUMINANCE8 */
+   { 35169, 0x00008C45 }, /* GL_SLUMINANCE8_ALPHA8 */
+   { 35191, 0x00008C44 }, /* GL_SLUMINANCE_ALPHA */
+   { 35211, 0x00001D01 }, /* GL_SMOOTH */
+   { 35221, 0x00000B23 }, /* GL_SMOOTH_LINE_WIDTH_GRANULARITY */
+   { 35254, 0x00000B22 }, /* GL_SMOOTH_LINE_WIDTH_RANGE */
+   { 35281, 0x00000B13 }, /* GL_SMOOTH_POINT_SIZE_GRANULARITY */
+   { 35314, 0x00000B12 }, /* GL_SMOOTH_POINT_SIZE_RANGE */
+   { 35341, 0x00008588 }, /* GL_SOURCE0_ALPHA */
+   { 35358, 0x00008588 }, /* GL_SOURCE0_ALPHA_ARB */
+   { 35379, 0x00008588 }, /* GL_SOURCE0_ALPHA_EXT */
+   { 35400, 0x00008580 }, /* GL_SOURCE0_RGB */
+   { 35415, 0x00008580 }, /* GL_SOURCE0_RGB_ARB */
+   { 35434, 0x00008580 }, /* GL_SOURCE0_RGB_EXT */
+   { 35453, 0x00008589 }, /* GL_SOURCE1_ALPHA */
+   { 35470, 0x00008589 }, /* GL_SOURCE1_ALPHA_ARB */
+   { 35491, 0x00008589 }, /* GL_SOURCE1_ALPHA_EXT */
+   { 35512, 0x00008581 }, /* GL_SOURCE1_RGB */
+   { 35527, 0x00008581 }, /* GL_SOURCE1_RGB_ARB */
+   { 35546, 0x00008581 }, /* GL_SOURCE1_RGB_EXT */
+   { 35565, 0x0000858A }, /* GL_SOURCE2_ALPHA */
+   { 35582, 0x0000858A }, /* GL_SOURCE2_ALPHA_ARB */
+   { 35603, 0x0000858A }, /* GL_SOURCE2_ALPHA_EXT */
+   { 35624, 0x00008582 }, /* GL_SOURCE2_RGB */
+   { 35639, 0x00008582 }, /* GL_SOURCE2_RGB_ARB */
+   { 35658, 0x00008582 }, /* GL_SOURCE2_RGB_EXT */
+   { 35677, 0x0000858B }, /* GL_SOURCE3_ALPHA_NV */
+   { 35697, 0x00008583 }, /* GL_SOURCE3_RGB_NV */
+   { 35715, 0x00001202 }, /* GL_SPECULAR */
+   { 35727, 0x00002402 }, /* GL_SPHERE_MAP */
+   { 35741, 0x00001206 }, /* GL_SPOT_CUTOFF */
+   { 35756, 0x00001204 }, /* GL_SPOT_DIRECTION */
+   { 35774, 0x00001205 }, /* GL_SPOT_EXPONENT */
+   { 35791, 0x00008588 }, /* GL_SRC0_ALPHA */
+   { 35805, 0x00008580 }, /* GL_SRC0_RGB */
+   { 35817, 0x00008589 }, /* GL_SRC1_ALPHA */
+   { 35831, 0x00008581 }, /* GL_SRC1_RGB */
+   { 35843, 0x0000858A }, /* GL_SRC2_ALPHA */
+   { 35857, 0x00008582 }, /* GL_SRC2_RGB */
+   { 35869, 0x00000302 }, /* GL_SRC_ALPHA */
+   { 35882, 0x00000308 }, /* GL_SRC_ALPHA_SATURATE */
+   { 35904, 0x00000300 }, /* GL_SRC_COLOR */
+   { 35917, 0x00008C40 }, /* GL_SRGB */
+   { 35925, 0x00008C41 }, /* GL_SRGB8 */
+   { 35934, 0x00008C43 }, /* GL_SRGB8_ALPHA8 */
+   { 35950, 0x00008C42 }, /* GL_SRGB_ALPHA */
+   { 35964, 0x00000503 }, /* GL_STACK_OVERFLOW */
+   { 35982, 0x00000504 }, /* GL_STACK_UNDERFLOW */
+   { 36001, 0x000088E6 }, /* GL_STATIC_COPY */
+   { 36016, 0x000088E6 }, /* GL_STATIC_COPY_ARB */
+   { 36035, 0x000088E4 }, /* GL_STATIC_DRAW */
+   { 36050, 0x000088E4 }, /* GL_STATIC_DRAW_ARB */
+   { 36069, 0x000088E5 }, /* GL_STATIC_READ */
+   { 36084, 0x000088E5 }, /* GL_STATIC_READ_ARB */
+   { 36103, 0x00001802 }, /* GL_STENCIL */
+   { 36114, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT */
+   { 36136, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT_EXT */
+   { 36162, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT_OES */
+   { 36188, 0x00008801 }, /* GL_STENCIL_BACK_FAIL */
+   { 36209, 0x00008801 }, /* GL_STENCIL_BACK_FAIL_ATI */
+   { 36234, 0x00008800 }, /* GL_STENCIL_BACK_FUNC */
+   { 36255, 0x00008800 }, /* GL_STENCIL_BACK_FUNC_ATI */
+   { 36280, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */
+   { 36312, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI */
+   { 36348, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */
+   { 36380, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI */
+   { 36416, 0x00008CA3 }, /* GL_STENCIL_BACK_REF */
+   { 36436, 0x00008CA4 }, /* GL_STENCIL_BACK_VALUE_MASK */
+   { 36463, 0x00008CA5 }, /* GL_STENCIL_BACK_WRITEMASK */
+   { 36489, 0x00000D57 }, /* GL_STENCIL_BITS */
+   { 36505, 0x00000400 }, /* GL_STENCIL_BUFFER_BIT */
+   { 36527, 0x00000B91 }, /* GL_STENCIL_CLEAR_VALUE */
+   { 36550, 0x00000B94 }, /* GL_STENCIL_FAIL */
+   { 36566, 0x00000B92 }, /* GL_STENCIL_FUNC */
+   { 36582, 0x00001901 }, /* GL_STENCIL_INDEX */
+   { 36599, 0x00008D46 }, /* GL_STENCIL_INDEX1 */
+   { 36617, 0x00008D49 }, /* GL_STENCIL_INDEX16 */
+   { 36636, 0x00008D49 }, /* GL_STENCIL_INDEX16_EXT */
+   { 36659, 0x00008D46 }, /* GL_STENCIL_INDEX1_EXT */
+   { 36681, 0x00008D46 }, /* GL_STENCIL_INDEX1_OES */
+   { 36703, 0x00008D47 }, /* GL_STENCIL_INDEX4 */
+   { 36721, 0x00008D47 }, /* GL_STENCIL_INDEX4_EXT */
+   { 36743, 0x00008D47 }, /* GL_STENCIL_INDEX4_OES */
+   { 36765, 0x00008D48 }, /* GL_STENCIL_INDEX8 */
+   { 36783, 0x00008D48 }, /* GL_STENCIL_INDEX8_EXT */
+   { 36805, 0x00008D48 }, /* GL_STENCIL_INDEX8_OES */
+   { 36827, 0x00008D45 }, /* GL_STENCIL_INDEX_EXT */
+   { 36848, 0x00000B95 }, /* GL_STENCIL_PASS_DEPTH_FAIL */
+   { 36875, 0x00000B96 }, /* GL_STENCIL_PASS_DEPTH_PASS */
+   { 36902, 0x00000B97 }, /* GL_STENCIL_REF */
+   { 36917, 0x00000B90 }, /* GL_STENCIL_TEST */
+   { 36933, 0x00008910 }, /* GL_STENCIL_TEST_TWO_SIDE_EXT */
+   { 36962, 0x00000B93 }, /* GL_STENCIL_VALUE_MASK */
+   { 36984, 0x00000B98 }, /* GL_STENCIL_WRITEMASK */
+   { 37005, 0x00000C33 }, /* GL_STEREO */
+   { 37015, 0x000085BE }, /* GL_STORAGE_CACHED_APPLE */
+   { 37039, 0x000085BD }, /* GL_STORAGE_PRIVATE_APPLE */
+   { 37064, 0x000085BF }, /* GL_STORAGE_SHARED_APPLE */
+   { 37088, 0x000088E2 }, /* GL_STREAM_COPY */
+   { 37103, 0x000088E2 }, /* GL_STREAM_COPY_ARB */
+   { 37122, 0x000088E0 }, /* GL_STREAM_DRAW */
+   { 37137, 0x000088E0 }, /* GL_STREAM_DRAW_ARB */
+   { 37156, 0x000088E1 }, /* GL_STREAM_READ */
+   { 37171, 0x000088E1 }, /* GL_STREAM_READ_ARB */
+   { 37190, 0x00000D50 }, /* GL_SUBPIXEL_BITS */
+   { 37207, 0x000084E7 }, /* GL_SUBTRACT */
+   { 37219, 0x000084E7 }, /* GL_SUBTRACT_ARB */
+   { 37235, 0x00009113 }, /* GL_SYNC_CONDITION */
+   { 37253, 0x00009116 }, /* GL_SYNC_FENCE */
+   { 37267, 0x00009115 }, /* GL_SYNC_FLAGS */
+   { 37281, 0x00000001 }, /* GL_SYNC_FLUSH_COMMANDS_BIT */
+   { 37308, 0x00009117 }, /* GL_SYNC_GPU_COMMANDS_COMPLETE */
+   { 37338, 0x00009114 }, /* GL_SYNC_STATUS */
+   { 37353, 0x00002001 }, /* GL_T */
+   { 37358, 0x00002A2A }, /* GL_T2F_C3F_V3F */
+   { 37373, 0x00002A2C }, /* GL_T2F_C4F_N3F_V3F */
+   { 37392, 0x00002A29 }, /* GL_T2F_C4UB_V3F */
+   { 37408, 0x00002A2B }, /* GL_T2F_N3F_V3F */
+   { 37423, 0x00002A27 }, /* GL_T2F_V3F */
+   { 37434, 0x00002A2D }, /* GL_T4F_C4F_N3F_V4F */
+   { 37453, 0x00002A28 }, /* GL_T4F_V4F */
+   { 37464, 0x00008031 }, /* GL_TABLE_TOO_LARGE_EXT */
+   { 37487, 0x00001702 }, /* GL_TEXTURE */
+   { 37498, 0x000084C0 }, /* GL_TEXTURE0 */
+   { 37510, 0x000084C0 }, /* GL_TEXTURE0_ARB */
+   { 37526, 0x000084C1 }, /* GL_TEXTURE1 */
+   { 37538, 0x000084CA }, /* GL_TEXTURE10 */
+   { 37551, 0x000084CA }, /* GL_TEXTURE10_ARB */
+   { 37568, 0x000084CB }, /* GL_TEXTURE11 */
+   { 37581, 0x000084CB }, /* GL_TEXTURE11_ARB */
+   { 37598, 0x000084CC }, /* GL_TEXTURE12 */
+   { 37611, 0x000084CC }, /* GL_TEXTURE12_ARB */
+   { 37628, 0x000084CD }, /* GL_TEXTURE13 */
+   { 37641, 0x000084CD }, /* GL_TEXTURE13_ARB */
+   { 37658, 0x000084CE }, /* GL_TEXTURE14 */
+   { 37671, 0x000084CE }, /* GL_TEXTURE14_ARB */
+   { 37688, 0x000084CF }, /* GL_TEXTURE15 */
+   { 37701, 0x000084CF }, /* GL_TEXTURE15_ARB */
+   { 37718, 0x000084D0 }, /* GL_TEXTURE16 */
+   { 37731, 0x000084D0 }, /* GL_TEXTURE16_ARB */
+   { 37748, 0x000084D1 }, /* GL_TEXTURE17 */
+   { 37761, 0x000084D1 }, /* GL_TEXTURE17_ARB */
+   { 37778, 0x000084D2 }, /* GL_TEXTURE18 */
+   { 37791, 0x000084D2 }, /* GL_TEXTURE18_ARB */
+   { 37808, 0x000084D3 }, /* GL_TEXTURE19 */
+   { 37821, 0x000084D3 }, /* GL_TEXTURE19_ARB */
+   { 37838, 0x000084C1 }, /* GL_TEXTURE1_ARB */
+   { 37854, 0x000084C2 }, /* GL_TEXTURE2 */
+   { 37866, 0x000084D4 }, /* GL_TEXTURE20 */
+   { 37879, 0x000084D4 }, /* GL_TEXTURE20_ARB */
+   { 37896, 0x000084D5 }, /* GL_TEXTURE21 */
+   { 37909, 0x000084D5 }, /* GL_TEXTURE21_ARB */
+   { 37926, 0x000084D6 }, /* GL_TEXTURE22 */
+   { 37939, 0x000084D6 }, /* GL_TEXTURE22_ARB */
+   { 37956, 0x000084D7 }, /* GL_TEXTURE23 */
+   { 37969, 0x000084D7 }, /* GL_TEXTURE23_ARB */
+   { 37986, 0x000084D8 }, /* GL_TEXTURE24 */
+   { 37999, 0x000084D8 }, /* GL_TEXTURE24_ARB */
+   { 38016, 0x000084D9 }, /* GL_TEXTURE25 */
+   { 38029, 0x000084D9 }, /* GL_TEXTURE25_ARB */
+   { 38046, 0x000084DA }, /* GL_TEXTURE26 */
+   { 38059, 0x000084DA }, /* GL_TEXTURE26_ARB */
+   { 38076, 0x000084DB }, /* GL_TEXTURE27 */
+   { 38089, 0x000084DB }, /* GL_TEXTURE27_ARB */
+   { 38106, 0x000084DC }, /* GL_TEXTURE28 */
+   { 38119, 0x000084DC }, /* GL_TEXTURE28_ARB */
+   { 38136, 0x000084DD }, /* GL_TEXTURE29 */
+   { 38149, 0x000084DD }, /* GL_TEXTURE29_ARB */
+   { 38166, 0x000084C2 }, /* GL_TEXTURE2_ARB */
+   { 38182, 0x000084C3 }, /* GL_TEXTURE3 */
+   { 38194, 0x000084DE }, /* GL_TEXTURE30 */
+   { 38207, 0x000084DE }, /* GL_TEXTURE30_ARB */
+   { 38224, 0x000084DF }, /* GL_TEXTURE31 */
+   { 38237, 0x000084DF }, /* GL_TEXTURE31_ARB */
+   { 38254, 0x000084C3 }, /* GL_TEXTURE3_ARB */
+   { 38270, 0x000084C4 }, /* GL_TEXTURE4 */
+   { 38282, 0x000084C4 }, /* GL_TEXTURE4_ARB */
+   { 38298, 0x000084C5 }, /* GL_TEXTURE5 */
+   { 38310, 0x000084C5 }, /* GL_TEXTURE5_ARB */
+   { 38326, 0x000084C6 }, /* GL_TEXTURE6 */
+   { 38338, 0x000084C6 }, /* GL_TEXTURE6_ARB */
+   { 38354, 0x000084C7 }, /* GL_TEXTURE7 */
+   { 38366, 0x000084C7 }, /* GL_TEXTURE7_ARB */
+   { 38382, 0x000084C8 }, /* GL_TEXTURE8 */
+   { 38394, 0x000084C8 }, /* GL_TEXTURE8_ARB */
+   { 38410, 0x000084C9 }, /* GL_TEXTURE9 */
+   { 38422, 0x000084C9 }, /* GL_TEXTURE9_ARB */
+   { 38438, 0x00000DE0 }, /* GL_TEXTURE_1D */
+   { 38452, 0x00008C18 }, /* GL_TEXTURE_1D_ARRAY_EXT */
+   { 38476, 0x00000DE1 }, /* GL_TEXTURE_2D */
+   { 38490, 0x00008C1A }, /* GL_TEXTURE_2D_ARRAY_EXT */
+   { 38514, 0x0000806F }, /* GL_TEXTURE_3D */
+   { 38528, 0x0000806F }, /* GL_TEXTURE_3D_OES */
+   { 38546, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE */
+   { 38568, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE_EXT */
+   { 38594, 0x0000813C }, /* GL_TEXTURE_BASE_LEVEL */
+   { 38616, 0x00008068 }, /* GL_TEXTURE_BINDING_1D */
+   { 38638, 0x00008C1C }, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */
+   { 38670, 0x00008069 }, /* GL_TEXTURE_BINDING_2D */
+   { 38692, 0x00008C1D }, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */
+   { 38724, 0x0000806A }, /* GL_TEXTURE_BINDING_3D */
+   { 38746, 0x0000806A }, /* GL_TEXTURE_BINDING_3D_OES */
+   { 38772, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP */
+   { 38800, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP_ARB */
+   { 38832, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP_OES */
+   { 38864, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */
+   { 38897, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_NV */
+   { 38929, 0x00040000 }, /* GL_TEXTURE_BIT */
+   { 38944, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE */
+   { 38965, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE_EXT */
+   { 38990, 0x00001005 }, /* GL_TEXTURE_BORDER */
+   { 39008, 0x00001004 }, /* GL_TEXTURE_BORDER_COLOR */
+   { 39032, 0x00008171 }, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */
+   { 39063, 0x00008176 }, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */
+   { 39093, 0x00008172 }, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */
+   { 39123, 0x00008175 }, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */
+   { 39158, 0x00008173 }, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */
+   { 39189, 0x00008174 }, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */
+   { 39227, 0x000080BC }, /* GL_TEXTURE_COLOR_TABLE_SGI */
+   { 39254, 0x000081EF }, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */
+   { 39286, 0x000080BF }, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
+   { 39320, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC */
+   { 39344, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC_ARB */
+   { 39372, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE */
+   { 39396, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE_ARB */
+   { 39424, 0x0000819B }, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */
+   { 39457, 0x0000819A }, /* GL_TEXTURE_COMPARE_SGIX */
+   { 39481, 0x00001003 }, /* GL_TEXTURE_COMPONENTS */
+   { 39503, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED */
+   { 39525, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED_ARB */
+   { 39551, 0x000086A3 }, /* GL_TEXTURE_COMPRESSED_FORMATS_ARB */
+   { 39585, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */
+   { 39618, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB */
+   { 39655, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT */
+   { 39683, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT_ARB */
+   { 39715, 0x00008078 }, /* GL_TEXTURE_COORD_ARRAY */
+   { 39738, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
+   { 39776, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB */
+   { 39818, 0x00008092 }, /* GL_TEXTURE_COORD_ARRAY_POINTER */
+   { 39849, 0x00008088 }, /* GL_TEXTURE_COORD_ARRAY_SIZE */
+   { 39877, 0x0000808A }, /* GL_TEXTURE_COORD_ARRAY_STRIDE */
+   { 39907, 0x00008089 }, /* GL_TEXTURE_COORD_ARRAY_TYPE */
+   { 39935, 0x00008B9D }, /* GL_TEXTURE_CROP_RECT_OES */
+   { 39960, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP */
+   { 39980, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP_ARB */
+   { 40004, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
+   { 40035, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB */
+   { 40070, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES */
+   { 40105, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
+   { 40136, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB */
+   { 40171, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES */
+   { 40206, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
+   { 40237, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB */
+   { 40272, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES */
+   { 40307, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP_OES */
+   { 40331, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
+   { 40362, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB */
+   { 40397, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES */
+   { 40432, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
+   { 40463, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB */
+   { 40498, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES */
+   { 40533, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
+   { 40564, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB */
+   { 40599, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES */
+   { 40634, 0x000088F4 }, /* GL_TEXTURE_CUBE_MAP_SEAMLESS */
+   { 40663, 0x00008071 }, /* GL_TEXTURE_DEPTH */
+   { 40680, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE */
+   { 40702, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE_ARB */
+   { 40728, 0x00002300 }, /* GL_TEXTURE_ENV */
+   { 40743, 0x00002201 }, /* GL_TEXTURE_ENV_COLOR */
+   { 40764, 0x00002200 }, /* GL_TEXTURE_ENV_MODE */
+   { 40784, 0x00008500 }, /* GL_TEXTURE_FILTER_CONTROL */
+   { 40810, 0x00008500 }, /* GL_TEXTURE_FILTER_CONTROL_EXT */
+   { 40840, 0x00002500 }, /* GL_TEXTURE_GEN_MODE */
+   { 40860, 0x00002500 }, /* GL_TEXTURE_GEN_MODE_OES */
+   { 40884, 0x00000C63 }, /* GL_TEXTURE_GEN_Q */
+   { 40901, 0x00000C62 }, /* GL_TEXTURE_GEN_R */
+   { 40918, 0x00000C60 }, /* GL_TEXTURE_GEN_S */
+   { 40935, 0x00008D60 }, /* GL_TEXTURE_GEN_STR_OES */
+   { 40958, 0x00000C61 }, /* GL_TEXTURE_GEN_T */
+   { 40975, 0x0000819D }, /* GL_TEXTURE_GEQUAL_R_SGIX */
+   { 41000, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE */
+   { 41022, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE_EXT */
+   { 41048, 0x00001001 }, /* GL_TEXTURE_HEIGHT */
+   { 41066, 0x000080ED }, /* GL_TEXTURE_INDEX_SIZE_EXT */
+   { 41092, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE */
+   { 41118, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE_EXT */
+   { 41148, 0x00001003 }, /* GL_TEXTURE_INTERNAL_FORMAT */
+   { 41175, 0x0000819C }, /* GL_TEXTURE_LEQUAL_R_SGIX */
+   { 41200, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS */
+   { 41220, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS_EXT */
+   { 41244, 0x00008190 }, /* GL_TEXTURE_LOD_BIAS_R_SGIX */
+   { 41271, 0x0000818E }, /* GL_TEXTURE_LOD_BIAS_S_SGIX */
+   { 41298, 0x0000818F }, /* GL_TEXTURE_LOD_BIAS_T_SGIX */
+   { 41325, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE */
+   { 41351, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE_EXT */
+   { 41381, 0x00002800 }, /* GL_TEXTURE_MAG_FILTER */
+   { 41403, 0x00000BA8 }, /* GL_TEXTURE_MATRIX */
+   { 41421, 0x0000898F }, /* GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES */
+   { 41461, 0x000084FE }, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */
+   { 41491, 0x0000836B }, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */
+   { 41519, 0x00008369 }, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */
+   { 41547, 0x0000836A }, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */
+   { 41575, 0x0000813D }, /* GL_TEXTURE_MAX_LEVEL */
+   { 41596, 0x0000813B }, /* GL_TEXTURE_MAX_LOD */
+   { 41615, 0x00002801 }, /* GL_TEXTURE_MIN_FILTER */
+   { 41637, 0x0000813A }, /* GL_TEXTURE_MIN_LOD */
+   { 41656, 0x00008066 }, /* GL_TEXTURE_PRIORITY */
+   { 41676, 0x000085B7 }, /* GL_TEXTURE_RANGE_LENGTH_APPLE */
+   { 41706, 0x000085B8 }, /* GL_TEXTURE_RANGE_POINTER_APPLE */
+   { 41737, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_ARB */
+   { 41762, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_NV */
+   { 41786, 0x0000805C }, /* GL_TEXTURE_RED_SIZE */
+   { 41806, 0x0000805C }, /* GL_TEXTURE_RED_SIZE_EXT */
+   { 41830, 0x00008067 }, /* GL_TEXTURE_RESIDENT */
+   { 41850, 0x00000BA5 }, /* GL_TEXTURE_STACK_DEPTH */
+   { 41873, 0x000088F1 }, /* GL_TEXTURE_STENCIL_SIZE */
+   { 41897, 0x000088F1 }, /* GL_TEXTURE_STENCIL_SIZE_EXT */
+   { 41925, 0x000085BC }, /* GL_TEXTURE_STORAGE_HINT_APPLE */
+   { 41955, 0x00008065 }, /* GL_TEXTURE_TOO_LARGE_EXT */
+   { 41980, 0x0000888F }, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */
+   { 42014, 0x00001000 }, /* GL_TEXTURE_WIDTH */
+   { 42031, 0x00008072 }, /* GL_TEXTURE_WRAP_R */
+   { 42049, 0x00008072 }, /* GL_TEXTURE_WRAP_R_OES */
+   { 42071, 0x00002802 }, /* GL_TEXTURE_WRAP_S */
+   { 42089, 0x00002803 }, /* GL_TEXTURE_WRAP_T */
+   { 42107, 0x0000911B }, /* GL_TIMEOUT_EXPIRED */
+   { 42126, 0x000088BF }, /* GL_TIME_ELAPSED_EXT */
+   { 42146, 0x00008648 }, /* GL_TRACK_MATRIX_NV */
+   { 42165, 0x00008649 }, /* GL_TRACK_MATRIX_TRANSFORM_NV */
+   { 42194, 0x00001000 }, /* GL_TRANSFORM_BIT */
+   { 42211, 0x00008E22 }, /* GL_TRANSFORM_FEEDBACK */
+   { 42233, 0x00008E25 }, /* GL_TRANSFORM_FEEDBACK_BINDING */
+   { 42263, 0x00008E24 }, /* GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE */
+   { 42299, 0x00008C8F }, /* GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT */
+   { 42340, 0x00008C8E }, /* GL_TRANSFORM_FEEDBACK_BUFFER_EXT */
+   { 42373, 0x00008C7F }, /* GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT */
+   { 42411, 0x00008E23 }, /* GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED */
+   { 42447, 0x00008C85 }, /* GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT */
+   { 42485, 0x00008C84 }, /* GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT */
+   { 42524, 0x00008C88 }, /* GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT */
+   { 42569, 0x00008C83 }, /* GL_TRANSFORM_FEEDBACK_VARYINGS_EXT */
+   { 42604, 0x00008C76 }, /* GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT */
+   { 42649, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX */
+   { 42675, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX_ARB */
+   { 42705, 0x000088B7 }, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */
+   { 42737, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX */
+   { 42767, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX_ARB */
+   { 42801, 0x0000862C }, /* GL_TRANSPOSE_NV */
+   { 42817, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX */
+   { 42848, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX_ARB */
+   { 42883, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX */
+   { 42911, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX_ARB */
+   { 42943, 0x00000004 }, /* GL_TRIANGLES */
+   { 42956, 0x0000000C }, /* GL_TRIANGLES_ADJACENCY_ARB */
+   { 42983, 0x00000006 }, /* GL_TRIANGLE_FAN */
+   { 42999, 0x00008615 }, /* GL_TRIANGLE_MESH_SUN */
+   { 43020, 0x00000005 }, /* GL_TRIANGLE_STRIP */
+   { 43038, 0x0000000D }, /* GL_TRIANGLE_STRIP_ADJACENCY_ARB */
+   { 43070, 0x00000001 }, /* GL_TRUE */
+   { 43078, 0x00008A1C }, /* GL_UNDEFINED_APPLE */
+   { 43097, 0x00000CF5 }, /* GL_UNPACK_ALIGNMENT */
+   { 43117, 0x0000806E }, /* GL_UNPACK_IMAGE_HEIGHT */
+   { 43140, 0x00000CF1 }, /* GL_UNPACK_LSB_FIRST */
+   { 43160, 0x00000CF2 }, /* GL_UNPACK_ROW_LENGTH */
+   { 43181, 0x0000806D }, /* GL_UNPACK_SKIP_IMAGES */
+   { 43203, 0x00000CF4 }, /* GL_UNPACK_SKIP_PIXELS */
+   { 43225, 0x00000CF3 }, /* GL_UNPACK_SKIP_ROWS */
+   { 43245, 0x00000CF0 }, /* GL_UNPACK_SWAP_BYTES */
+   { 43266, 0x00009118 }, /* GL_UNSIGNALED */
+   { 43280, 0x00001401 }, /* GL_UNSIGNED_BYTE */
+   { 43297, 0x00008362 }, /* GL_UNSIGNED_BYTE_2_3_3_REV */
+   { 43324, 0x00008032 }, /* GL_UNSIGNED_BYTE_3_3_2 */
+   { 43347, 0x00001405 }, /* GL_UNSIGNED_INT */
+   { 43363, 0x00008036 }, /* GL_UNSIGNED_INT_10_10_10_2 */
+   { 43390, 0x00008DF6 }, /* GL_UNSIGNED_INT_10_10_10_2_OES */
+   { 43421, 0x000084FA }, /* GL_UNSIGNED_INT_24_8 */
+   { 43442, 0x000084FA }, /* GL_UNSIGNED_INT_24_8_EXT */
+   { 43467, 0x000084FA }, /* GL_UNSIGNED_INT_24_8_NV */
+   { 43491, 0x000084FA }, /* GL_UNSIGNED_INT_24_8_OES */
+   { 43516, 0x00008368 }, /* GL_UNSIGNED_INT_2_10_10_10_REV */
+   { 43547, 0x00008368 }, /* GL_UNSIGNED_INT_2_10_10_10_REV_EXT */
+   { 43582, 0x00008035 }, /* GL_UNSIGNED_INT_8_8_8_8 */
+   { 43606, 0x00008367 }, /* GL_UNSIGNED_INT_8_8_8_8_REV */
+   { 43634, 0x00008C17 }, /* GL_UNSIGNED_NORMALIZED */
+   { 43657, 0x00001403 }, /* GL_UNSIGNED_SHORT */
+   { 43675, 0x00008366 }, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */
+   { 43705, 0x00008366 }, /* GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT */
+   { 43739, 0x00008033 }, /* GL_UNSIGNED_SHORT_4_4_4_4 */
+   { 43765, 0x00008365 }, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */
+   { 43795, 0x00008365 }, /* GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT */
+   { 43829, 0x00008034 }, /* GL_UNSIGNED_SHORT_5_5_5_1 */
+   { 43855, 0x00008363 }, /* GL_UNSIGNED_SHORT_5_6_5 */
+   { 43879, 0x00008364 }, /* GL_UNSIGNED_SHORT_5_6_5_REV */
+   { 43907, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_APPLE */
+   { 43935, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_MESA */
+   { 43962, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */
+   { 43994, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_MESA */
+   { 44025, 0x00008CA2 }, /* GL_UPPER_LEFT */
+   { 44039, 0x00002A20 }, /* GL_V2F */
+   { 44046, 0x00002A21 }, /* GL_V3F */
+   { 44053, 0x00008B83 }, /* GL_VALIDATE_STATUS */
+   { 44072, 0x00001F00 }, /* GL_VENDOR */
+   { 44082, 0x00001F02 }, /* GL_VERSION */
+   { 44093, 0x00008074 }, /* GL_VERTEX_ARRAY */
+   { 44109, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING */
+   { 44133, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING_APPLE */
+   { 44163, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
+   { 44194, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING_ARB */
+   { 44229, 0x0000808E }, /* GL_VERTEX_ARRAY_POINTER */
+   { 44253, 0x0000807A }, /* GL_VERTEX_ARRAY_SIZE */
+   { 44274, 0x0000807C }, /* GL_VERTEX_ARRAY_STRIDE */
+   { 44297, 0x0000807B }, /* GL_VERTEX_ARRAY_TYPE */
+   { 44318, 0x00008650 }, /* GL_VERTEX_ATTRIB_ARRAY0_NV */
+   { 44345, 0x0000865A }, /* GL_VERTEX_ATTRIB_ARRAY10_NV */
+   { 44373, 0x0000865B }, /* GL_VERTEX_ATTRIB_ARRAY11_NV */
+   { 44401, 0x0000865C }, /* GL_VERTEX_ATTRIB_ARRAY12_NV */
+   { 44429, 0x0000865D }, /* GL_VERTEX_ATTRIB_ARRAY13_NV */
+   { 44457, 0x0000865E }, /* GL_VERTEX_ATTRIB_ARRAY14_NV */
+   { 44485, 0x0000865F }, /* GL_VERTEX_ATTRIB_ARRAY15_NV */
+   { 44513, 0x00008651 }, /* GL_VERTEX_ATTRIB_ARRAY1_NV */
+   { 44540, 0x00008652 }, /* GL_VERTEX_ATTRIB_ARRAY2_NV */
+   { 44567, 0x00008653 }, /* GL_VERTEX_ATTRIB_ARRAY3_NV */
+   { 44594, 0x00008654 }, /* GL_VERTEX_ATTRIB_ARRAY4_NV */
+   { 44621, 0x00008655 }, /* GL_VERTEX_ATTRIB_ARRAY5_NV */
+   { 44648, 0x00008656 }, /* GL_VERTEX_ATTRIB_ARRAY6_NV */
+   { 44675, 0x00008657 }, /* GL_VERTEX_ATTRIB_ARRAY7_NV */
+   { 44702, 0x00008658 }, /* GL_VERTEX_ATTRIB_ARRAY8_NV */
+   { 44729, 0x00008659 }, /* GL_VERTEX_ATTRIB_ARRAY9_NV */
+   { 44756, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */
+   { 44794, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB */
+   { 44836, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */
+   { 44867, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB */
+   { 44902, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */
+   { 44936, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB */
+   { 44974, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */
+   { 45005, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB */
+   { 45040, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */
+   { 45068, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB */
+   { 45100, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */
+   { 45130, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB */
+   { 45164, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */
+   { 45192, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB */
+   { 45224, 0x000086A7 }, /* GL_VERTEX_BLEND_ARB */
+   { 45244, 0x00008620 }, /* GL_VERTEX_PROGRAM_ARB */
+   { 45266, 0x0000864A }, /* GL_VERTEX_PROGRAM_BINDING_NV */
+   { 45295, 0x00008620 }, /* GL_VERTEX_PROGRAM_NV */
+   { 45316, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE */
+   { 45345, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_ARB */
+   { 45378, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_NV */
+   { 45410, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE */
+   { 45437, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_ARB */
+   { 45468, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_NV */
+   { 45498, 0x00008B31 }, /* GL_VERTEX_SHADER */
+   { 45515, 0x00008B31 }, /* GL_VERTEX_SHADER_ARB */
+   { 45536, 0x00008621 }, /* GL_VERTEX_STATE_PROGRAM_NV */
+   { 45563, 0x00000BA2 }, /* GL_VIEWPORT */
+   { 45575, 0x00000800 }, /* GL_VIEWPORT_BIT */
+   { 45591, 0x00008A1A }, /* GL_VOLATILE_APPLE */
+   { 45609, 0x0000911D }, /* GL_WAIT_FAILED */
+   { 45624, 0x000086AD }, /* GL_WEIGHT_ARRAY_ARB */
+   { 45644, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */
+   { 45675, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB */
+   { 45710, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING_OES */
+   { 45745, 0x000086AD }, /* GL_WEIGHT_ARRAY_OES */
+   { 45765, 0x000086AC }, /* GL_WEIGHT_ARRAY_POINTER_ARB */
+   { 45793, 0x000086AC }, /* GL_WEIGHT_ARRAY_POINTER_OES */
+   { 45821, 0x000086AB }, /* GL_WEIGHT_ARRAY_SIZE_ARB */
+   { 45846, 0x000086AB }, /* GL_WEIGHT_ARRAY_SIZE_OES */
+   { 45871, 0x000086AA }, /* GL_WEIGHT_ARRAY_STRIDE_ARB */
+   { 45898, 0x000086AA }, /* GL_WEIGHT_ARRAY_STRIDE_OES */
+   { 45925, 0x000086A9 }, /* GL_WEIGHT_ARRAY_TYPE_ARB */
+   { 45950, 0x000086A9 }, /* GL_WEIGHT_ARRAY_TYPE_OES */
+   { 45975, 0x000086A6 }, /* GL_WEIGHT_SUM_UNITY_ARB */
+   { 45999, 0x000081D4 }, /* GL_WRAP_BORDER_SUN */
+   { 46018, 0x000088B9 }, /* GL_WRITE_ONLY */
+   { 46032, 0x000088B9 }, /* GL_WRITE_ONLY_ARB */
+   { 46050, 0x000088B9 }, /* GL_WRITE_ONLY_OES */
+   { 46068, 0x00001506 }, /* GL_XOR */
+   { 46075, 0x000085B9 }, /* GL_YCBCR_422_APPLE */
+   { 46094, 0x00008757 }, /* GL_YCBCR_MESA */
+   { 46108, 0x00000000 }, /* GL_ZERO */
+   { 46116, 0x00000D16 }, /* GL_ZOOM_X */
+   { 46126, 0x00000D17 }, /* GL_ZOOM_Y */
 };
 
-static const unsigned reduced_enums[1402] =
+static const unsigned reduced_enums[1423] =
 {
        500, /* GL_FALSE */
-       753, /* GL_LINES */
-       755, /* GL_LINE_LOOP */
-       762, /* GL_LINE_STRIP */
-      1913, /* GL_TRIANGLES */
-      1916, /* GL_TRIANGLE_STRIP */
-      1914, /* GL_TRIANGLE_FAN */
-      1376, /* GL_QUADS */
-      1380, /* GL_QUAD_STRIP */
-      1257, /* GL_POLYGON */
-      1269, /* GL_POLYGON_STIPPLE_BIT */
-      1212, /* GL_PIXEL_MODE_BIT */
-       740, /* GL_LIGHTING_BIT */
+       760, /* GL_LINES */
+       763, /* GL_LINE_LOOP */
+       770, /* GL_LINE_STRIP */
+      1934, /* GL_TRIANGLES */
+      1938, /* GL_TRIANGLE_STRIP */
+      1936, /* GL_TRIANGLE_FAN */
+      1393, /* GL_QUADS */
+      1397, /* GL_QUAD_STRIP */
+      1273, /* GL_POLYGON */
+       761, /* GL_LINES_ADJACENCY_ARB */
+       771, /* GL_LINE_STRIP_ADJACENCY_ARB */
+      1935, /* GL_TRIANGLES_ADJACENCY_ARB */
+      1939, /* GL_TRIANGLE_STRIP_ADJACENCY_ARB */
+      1285, /* GL_POLYGON_STIPPLE_BIT */
+      1228, /* GL_PIXEL_MODE_BIT */
+       747, /* GL_LIGHTING_BIT */
        532, /* GL_FOG_BIT */
          8, /* GL_ACCUM */
-       772, /* GL_LOAD */
-      1454, /* GL_RETURN */
-      1080, /* GL_MULT */
+       781, /* GL_LOAD */
+      1471, /* GL_RETURN */
+      1096, /* GL_MULT */
         23, /* GL_ADD */
-      1096, /* GL_NEVER */
-       730, /* GL_LESS */
+      1112, /* GL_NEVER */
+       737, /* GL_LESS */
        490, /* GL_EQUAL */
-       729, /* GL_LEQUAL */
-       642, /* GL_GREATER */
-      1113, /* GL_NOTEQUAL */
-       641, /* GL_GEQUAL */
+       736, /* GL_LEQUAL */
+       649, /* GL_GREATER */
+      1129, /* GL_NOTEQUAL */
+       648, /* GL_GEQUAL */
         47, /* GL_ALWAYS */
-      1605, /* GL_SRC_COLOR */
-      1145, /* GL_ONE_MINUS_SRC_COLOR */
-      1603, /* GL_SRC_ALPHA */
-      1144, /* GL_ONE_MINUS_SRC_ALPHA */
+      1622, /* GL_SRC_COLOR */
+      1161, /* GL_ONE_MINUS_SRC_COLOR */
+      1620, /* GL_SRC_ALPHA */
+      1160, /* GL_ONE_MINUS_SRC_ALPHA */
        469, /* GL_DST_ALPHA */
-      1142, /* GL_ONE_MINUS_DST_ALPHA */
+      1158, /* GL_ONE_MINUS_DST_ALPHA */
        470, /* GL_DST_COLOR */
-      1143, /* GL_ONE_MINUS_DST_COLOR */
-      1604, /* GL_SRC_ALPHA_SATURATE */
-       626, /* GL_FRONT_LEFT */
-       627, /* GL_FRONT_RIGHT */
+      1159, /* GL_ONE_MINUS_DST_COLOR */
+      1621, /* GL_SRC_ALPHA_SATURATE */
+       629, /* GL_FRONT_LEFT */
+       630, /* GL_FRONT_RIGHT */
         69, /* GL_BACK_LEFT */
         70, /* GL_BACK_RIGHT */
-       623, /* GL_FRONT */
+       626, /* GL_FRONT */
         68, /* GL_BACK */
-       728, /* GL_LEFT */
-      1502, /* GL_RIGHT */
-       624, /* GL_FRONT_AND_BACK */
+       735, /* GL_LEFT */
+      1519, /* GL_RIGHT */
+       627, /* GL_FRONT_AND_BACK */
         63, /* GL_AUX0 */
         64, /* GL_AUX1 */
         65, /* GL_AUX2 */
         66, /* GL_AUX3 */
-       716, /* GL_INVALID_ENUM */
-       721, /* GL_INVALID_VALUE */
-       720, /* GL_INVALID_OPERATION */
-      1610, /* GL_STACK_OVERFLOW */
-      1611, /* GL_STACK_UNDERFLOW */
-      1170, /* GL_OUT_OF_MEMORY */
-       717, /* GL_INVALID_FRAMEBUFFER_OPERATION */
+       723, /* GL_INVALID_ENUM */
+       728, /* GL_INVALID_VALUE */
+       727, /* GL_INVALID_OPERATION */
+      1627, /* GL_STACK_OVERFLOW */
+      1628, /* GL_STACK_UNDERFLOW */
+      1186, /* GL_OUT_OF_MEMORY */
+       724, /* GL_INVALID_FRAMEBUFFER_OPERATION */
          0, /* GL_2D */
          2, /* GL_3D */
          3, /* GL_3D_COLOR */
          4, /* GL_3D_COLOR_TEXTURE */
          6, /* GL_4D_COLOR_TEXTURE */
-      1190, /* GL_PASS_THROUGH_TOKEN */
-      1256, /* GL_POINT_TOKEN */
-       763, /* GL_LINE_TOKEN */
-      1270, /* GL_POLYGON_TOKEN */
+      1206, /* GL_PASS_THROUGH_TOKEN */
+      1272, /* GL_POINT_TOKEN */
+       772, /* GL_LINE_TOKEN */
+      1286, /* GL_POLYGON_TOKEN */
         75, /* GL_BITMAP_TOKEN */
        468, /* GL_DRAW_PIXEL_TOKEN */
        315, /* GL_COPY_PIXEL_TOKEN */
-       756, /* GL_LINE_RESET_TOKEN */
+       764, /* GL_LINE_RESET_TOKEN */
        493, /* GL_EXP */
        494, /* GL_EXP2 */
        352, /* GL_CW */
        137, /* GL_CCW */
        158, /* GL_COEFF */
-      1167, /* GL_ORDER */
+      1183, /* GL_ORDER */
        405, /* GL_DOMAIN */
        325, /* GL_CURRENT_COLOR */
        328, /* GL_CURRENT_INDEX */
@@ -4214,33 +4264,33 @@ static const unsigned reduced_enums[1402] =
        343, /* GL_CURRENT_RASTER_POSITION */
        344, /* GL_CURRENT_RASTER_POSITION_VALID */
        341, /* GL_CURRENT_RASTER_DISTANCE */
-      1248, /* GL_POINT_SMOOTH */
-      1232, /* GL_POINT_SIZE */
-      1247, /* GL_POINT_SIZE_RANGE */
-      1238, /* GL_POINT_SIZE_GRANULARITY */
-       757, /* GL_LINE_SMOOTH */
-       764, /* GL_LINE_WIDTH */
-       766, /* GL_LINE_WIDTH_RANGE */
-       765, /* GL_LINE_WIDTH_GRANULARITY */
-       759, /* GL_LINE_STIPPLE */
-       760, /* GL_LINE_STIPPLE_PATTERN */
-       761, /* GL_LINE_STIPPLE_REPEAT */
-       771, /* GL_LIST_MODE */
-       949, /* GL_MAX_LIST_NESTING */
-       768, /* GL_LIST_BASE */
-       770, /* GL_LIST_INDEX */
-      1259, /* GL_POLYGON_MODE */
-      1266, /* GL_POLYGON_SMOOTH */
-      1268, /* GL_POLYGON_STIPPLE */
+      1264, /* GL_POINT_SMOOTH */
+      1248, /* GL_POINT_SIZE */
+      1263, /* GL_POINT_SIZE_RANGE */
+      1254, /* GL_POINT_SIZE_GRANULARITY */
+       765, /* GL_LINE_SMOOTH */
+       773, /* GL_LINE_WIDTH */
+       775, /* GL_LINE_WIDTH_RANGE */
+       774, /* GL_LINE_WIDTH_GRANULARITY */
+       767, /* GL_LINE_STIPPLE */
+       768, /* GL_LINE_STIPPLE_PATTERN */
+       769, /* GL_LINE_STIPPLE_REPEAT */
+       780, /* GL_LIST_MODE */
+       963, /* GL_MAX_LIST_NESTING */
+       777, /* GL_LIST_BASE */
+       779, /* GL_LIST_INDEX */
+      1275, /* GL_POLYGON_MODE */
+      1282, /* GL_POLYGON_SMOOTH */
+      1284, /* GL_POLYGON_STIPPLE */
        479, /* GL_EDGE_FLAG */
        318, /* GL_CULL_FACE */
        319, /* GL_CULL_FACE_MODE */
-       625, /* GL_FRONT_FACE */
-       739, /* GL_LIGHTING */
-       744, /* GL_LIGHT_MODEL_LOCAL_VIEWER */
-       745, /* GL_LIGHT_MODEL_TWO_SIDE */
-       741, /* GL_LIGHT_MODEL_AMBIENT */
-      1552, /* GL_SHADE_MODEL */
+       628, /* GL_FRONT_FACE */
+       746, /* GL_LIGHTING */
+       751, /* GL_LIGHT_MODEL_LOCAL_VIEWER */
+       752, /* GL_LIGHT_MODEL_TWO_SIDE */
+       748, /* GL_LIGHT_MODEL_AMBIENT */
+      1569, /* GL_SHADE_MODEL */
        206, /* GL_COLOR_MATERIAL_FACE */
        207, /* GL_COLOR_MATERIAL_PARAMETER */
        205, /* GL_COLOR_MATERIAL */
@@ -4257,24 +4307,24 @@ static const unsigned reduced_enums[1402] =
        375, /* GL_DEPTH_CLEAR_VALUE */
        389, /* GL_DEPTH_FUNC */
         12, /* GL_ACCUM_CLEAR_VALUE */
-      1654, /* GL_STENCIL_TEST */
-      1635, /* GL_STENCIL_CLEAR_VALUE */
-      1637, /* GL_STENCIL_FUNC */
-      1656, /* GL_STENCIL_VALUE_MASK */
-      1636, /* GL_STENCIL_FAIL */
-      1651, /* GL_STENCIL_PASS_DEPTH_FAIL */
-      1652, /* GL_STENCIL_PASS_DEPTH_PASS */
-      1653, /* GL_STENCIL_REF */
-      1657, /* GL_STENCIL_WRITEMASK */
-       913, /* GL_MATRIX_MODE */
-      1102, /* GL_NORMALIZE */
-      2014, /* GL_VIEWPORT */
-      1075, /* GL_MODELVIEW_STACK_DEPTH */
-      1353, /* GL_PROJECTION_STACK_DEPTH */
-      1879, /* GL_TEXTURE_STACK_DEPTH */
-      1072, /* GL_MODELVIEW_MATRIX */
-      1351, /* GL_PROJECTION_MATRIX */
-      1861, /* GL_TEXTURE_MATRIX */
+      1671, /* GL_STENCIL_TEST */
+      1652, /* GL_STENCIL_CLEAR_VALUE */
+      1654, /* GL_STENCIL_FUNC */
+      1673, /* GL_STENCIL_VALUE_MASK */
+      1653, /* GL_STENCIL_FAIL */
+      1668, /* GL_STENCIL_PASS_DEPTH_FAIL */
+      1669, /* GL_STENCIL_PASS_DEPTH_PASS */
+      1670, /* GL_STENCIL_REF */
+      1674, /* GL_STENCIL_WRITEMASK */
+       922, /* GL_MATRIX_MODE */
+      1118, /* GL_NORMALIZE */
+      2037, /* GL_VIEWPORT */
+      1091, /* GL_MODELVIEW_STACK_DEPTH */
+      1370, /* GL_PROJECTION_STACK_DEPTH */
+      1896, /* GL_TEXTURE_STACK_DEPTH */
+      1088, /* GL_MODELVIEW_MATRIX */
+      1368, /* GL_PROJECTION_MATRIX */
+      1878, /* GL_TEXTURE_MATRIX */
         61, /* GL_ATTRIB_STACK_DEPTH */
        148, /* GL_CLIENT_ATTRIB_STACK_DEPTH */
         43, /* GL_ALPHA_TEST */
@@ -4284,451 +4334,451 @@ static const unsigned reduced_enums[1402] =
         79, /* GL_BLEND_DST */
         93, /* GL_BLEND_SRC */
         76, /* GL_BLEND */
-       774, /* GL_LOGIC_OP_MODE */
-       688, /* GL_INDEX_LOGIC_OP */
+       783, /* GL_LOGIC_OP_MODE */
+       695, /* GL_INDEX_LOGIC_OP */
        204, /* GL_COLOR_LOGIC_OP */
         67, /* GL_AUX_BUFFERS */
        415, /* GL_DRAW_BUFFER */
-      1395, /* GL_READ_BUFFER */
-      1530, /* GL_SCISSOR_BOX */
-      1531, /* GL_SCISSOR_TEST */
-       687, /* GL_INDEX_CLEAR_VALUE */
-       692, /* GL_INDEX_WRITEMASK */
+      1412, /* GL_READ_BUFFER */
+      1547, /* GL_SCISSOR_BOX */
+      1548, /* GL_SCISSOR_TEST */
+       694, /* GL_INDEX_CLEAR_VALUE */
+       699, /* GL_INDEX_WRITEMASK */
        201, /* GL_COLOR_CLEAR_VALUE */
        243, /* GL_COLOR_WRITEMASK */
-       689, /* GL_INDEX_MODE */
-      1495, /* GL_RGBA_MODE */
+       696, /* GL_INDEX_MODE */
+      1512, /* GL_RGBA_MODE */
        414, /* GL_DOUBLEBUFFER */
-      1658, /* GL_STEREO */
-      1446, /* GL_RENDER_MODE */
-      1191, /* GL_PERSPECTIVE_CORRECTION_HINT */
-      1249, /* GL_POINT_SMOOTH_HINT */
-       758, /* GL_LINE_SMOOTH_HINT */
-      1267, /* GL_POLYGON_SMOOTH_HINT */
+      1675, /* GL_STEREO */
+      1463, /* GL_RENDER_MODE */
+      1207, /* GL_PERSPECTIVE_CORRECTION_HINT */
+      1265, /* GL_POINT_SMOOTH_HINT */
+       766, /* GL_LINE_SMOOTH_HINT */
+      1283, /* GL_POLYGON_SMOOTH_HINT */
        552, /* GL_FOG_HINT */
-      1841, /* GL_TEXTURE_GEN_S */
-      1843, /* GL_TEXTURE_GEN_T */
-      1840, /* GL_TEXTURE_GEN_R */
-      1839, /* GL_TEXTURE_GEN_Q */
-      1204, /* GL_PIXEL_MAP_I_TO_I */
-      1210, /* GL_PIXEL_MAP_S_TO_S */
-      1206, /* GL_PIXEL_MAP_I_TO_R */
-      1202, /* GL_PIXEL_MAP_I_TO_G */
-      1200, /* GL_PIXEL_MAP_I_TO_B */
-      1198, /* GL_PIXEL_MAP_I_TO_A */
-      1208, /* GL_PIXEL_MAP_R_TO_R */
-      1196, /* GL_PIXEL_MAP_G_TO_G */
-      1194, /* GL_PIXEL_MAP_B_TO_B */
-      1192, /* GL_PIXEL_MAP_A_TO_A */
-      1205, /* GL_PIXEL_MAP_I_TO_I_SIZE */
-      1211, /* GL_PIXEL_MAP_S_TO_S_SIZE */
-      1207, /* GL_PIXEL_MAP_I_TO_R_SIZE */
-      1203, /* GL_PIXEL_MAP_I_TO_G_SIZE */
-      1201, /* GL_PIXEL_MAP_I_TO_B_SIZE */
-      1199, /* GL_PIXEL_MAP_I_TO_A_SIZE */
-      1209, /* GL_PIXEL_MAP_R_TO_R_SIZE */
-      1197, /* GL_PIXEL_MAP_G_TO_G_SIZE */
-      1195, /* GL_PIXEL_MAP_B_TO_B_SIZE */
-      1193, /* GL_PIXEL_MAP_A_TO_A_SIZE */
-      1926, /* GL_UNPACK_SWAP_BYTES */
-      1921, /* GL_UNPACK_LSB_FIRST */
-      1922, /* GL_UNPACK_ROW_LENGTH */
-      1925, /* GL_UNPACK_SKIP_ROWS */
-      1924, /* GL_UNPACK_SKIP_PIXELS */
-      1919, /* GL_UNPACK_ALIGNMENT */
-      1179, /* GL_PACK_SWAP_BYTES */
-      1174, /* GL_PACK_LSB_FIRST */
-      1175, /* GL_PACK_ROW_LENGTH */
-      1178, /* GL_PACK_SKIP_ROWS */
-      1177, /* GL_PACK_SKIP_PIXELS */
-      1171, /* GL_PACK_ALIGNMENT */
-       854, /* GL_MAP_COLOR */
-       859, /* GL_MAP_STENCIL */
-       691, /* GL_INDEX_SHIFT */
-       690, /* GL_INDEX_OFFSET */
-      1409, /* GL_RED_SCALE */
-      1407, /* GL_RED_BIAS */
-      2040, /* GL_ZOOM_X */
-      2041, /* GL_ZOOM_Y */
-       646, /* GL_GREEN_SCALE */
-       644, /* GL_GREEN_BIAS */
+      1858, /* GL_TEXTURE_GEN_S */
+      1860, /* GL_TEXTURE_GEN_T */
+      1857, /* GL_TEXTURE_GEN_R */
+      1856, /* GL_TEXTURE_GEN_Q */
+      1220, /* GL_PIXEL_MAP_I_TO_I */
+      1226, /* GL_PIXEL_MAP_S_TO_S */
+      1222, /* GL_PIXEL_MAP_I_TO_R */
+      1218, /* GL_PIXEL_MAP_I_TO_G */
+      1216, /* GL_PIXEL_MAP_I_TO_B */
+      1214, /* GL_PIXEL_MAP_I_TO_A */
+      1224, /* GL_PIXEL_MAP_R_TO_R */
+      1212, /* GL_PIXEL_MAP_G_TO_G */
+      1210, /* GL_PIXEL_MAP_B_TO_B */
+      1208, /* GL_PIXEL_MAP_A_TO_A */
+      1221, /* GL_PIXEL_MAP_I_TO_I_SIZE */
+      1227, /* GL_PIXEL_MAP_S_TO_S_SIZE */
+      1223, /* GL_PIXEL_MAP_I_TO_R_SIZE */
+      1219, /* GL_PIXEL_MAP_I_TO_G_SIZE */
+      1217, /* GL_PIXEL_MAP_I_TO_B_SIZE */
+      1215, /* GL_PIXEL_MAP_I_TO_A_SIZE */
+      1225, /* GL_PIXEL_MAP_R_TO_R_SIZE */
+      1213, /* GL_PIXEL_MAP_G_TO_G_SIZE */
+      1211, /* GL_PIXEL_MAP_B_TO_B_SIZE */
+      1209, /* GL_PIXEL_MAP_A_TO_A_SIZE */
+      1949, /* GL_UNPACK_SWAP_BYTES */
+      1944, /* GL_UNPACK_LSB_FIRST */
+      1945, /* GL_UNPACK_ROW_LENGTH */
+      1948, /* GL_UNPACK_SKIP_ROWS */
+      1947, /* GL_UNPACK_SKIP_PIXELS */
+      1942, /* GL_UNPACK_ALIGNMENT */
+      1195, /* GL_PACK_SWAP_BYTES */
+      1190, /* GL_PACK_LSB_FIRST */
+      1191, /* GL_PACK_ROW_LENGTH */
+      1194, /* GL_PACK_SKIP_ROWS */
+      1193, /* GL_PACK_SKIP_PIXELS */
+      1187, /* GL_PACK_ALIGNMENT */
+       863, /* GL_MAP_COLOR */
+       868, /* GL_MAP_STENCIL */
+       698, /* GL_INDEX_SHIFT */
+       697, /* GL_INDEX_OFFSET */
+      1426, /* GL_RED_SCALE */
+      1424, /* GL_RED_BIAS */
+      2063, /* GL_ZOOM_X */
+      2064, /* GL_ZOOM_Y */
+       653, /* GL_GREEN_SCALE */
+       651, /* GL_GREEN_BIAS */
        101, /* GL_BLUE_SCALE */
         99, /* GL_BLUE_BIAS */
         42, /* GL_ALPHA_SCALE */
         40, /* GL_ALPHA_BIAS */
        391, /* GL_DEPTH_SCALE */
        368, /* GL_DEPTH_BIAS */
-       943, /* GL_MAX_EVAL_ORDER */
-       948, /* GL_MAX_LIGHTS */
-       924, /* GL_MAX_CLIP_PLANES */
-       999, /* GL_MAX_TEXTURE_SIZE */
-       955, /* GL_MAX_PIXEL_MAP_TABLE */
-       920, /* GL_MAX_ATTRIB_STACK_DEPTH */
-       951, /* GL_MAX_MODELVIEW_STACK_DEPTH */
-       952, /* GL_MAX_NAME_STACK_DEPTH */
-       981, /* GL_MAX_PROJECTION_STACK_DEPTH */
-      1000, /* GL_MAX_TEXTURE_STACK_DEPTH */
-      1020, /* GL_MAX_VIEWPORT_DIMS */
-       921, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */
-      1668, /* GL_SUBPIXEL_BITS */
-       686, /* GL_INDEX_BITS */
-      1408, /* GL_RED_BITS */
-       645, /* GL_GREEN_BITS */
+       952, /* GL_MAX_EVAL_ORDER */
+       962, /* GL_MAX_LIGHTS */
+       933, /* GL_MAX_CLIP_PLANES */
+      1013, /* GL_MAX_TEXTURE_SIZE */
+       969, /* GL_MAX_PIXEL_MAP_TABLE */
+       929, /* GL_MAX_ATTRIB_STACK_DEPTH */
+       965, /* GL_MAX_MODELVIEW_STACK_DEPTH */
+       966, /* GL_MAX_NAME_STACK_DEPTH */
+       995, /* GL_MAX_PROJECTION_STACK_DEPTH */
+      1014, /* GL_MAX_TEXTURE_STACK_DEPTH */
+      1036, /* GL_MAX_VIEWPORT_DIMS */
+       930, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */
+      1685, /* GL_SUBPIXEL_BITS */
+       693, /* GL_INDEX_BITS */
+      1425, /* GL_RED_BITS */
+       652, /* GL_GREEN_BITS */
        100, /* GL_BLUE_BITS */
         41, /* GL_ALPHA_BITS */
        369, /* GL_DEPTH_BITS */
-      1633, /* GL_STENCIL_BITS */
+      1650, /* GL_STENCIL_BITS */
         14, /* GL_ACCUM_RED_BITS */
         13, /* GL_ACCUM_GREEN_BITS */
         10, /* GL_ACCUM_BLUE_BITS */
          9, /* GL_ACCUM_ALPHA_BITS */
-      1089, /* GL_NAME_STACK_DEPTH */
+      1105, /* GL_NAME_STACK_DEPTH */
         62, /* GL_AUTO_NORMAL */
-       800, /* GL_MAP1_COLOR_4 */
-       803, /* GL_MAP1_INDEX */
-       804, /* GL_MAP1_NORMAL */
-       805, /* GL_MAP1_TEXTURE_COORD_1 */
-       806, /* GL_MAP1_TEXTURE_COORD_2 */
-       807, /* GL_MAP1_TEXTURE_COORD_3 */
-       808, /* GL_MAP1_TEXTURE_COORD_4 */
-       809, /* GL_MAP1_VERTEX_3 */
-       810, /* GL_MAP1_VERTEX_4 */
-       827, /* GL_MAP2_COLOR_4 */
-       830, /* GL_MAP2_INDEX */
-       831, /* GL_MAP2_NORMAL */
-       832, /* GL_MAP2_TEXTURE_COORD_1 */
-       833, /* GL_MAP2_TEXTURE_COORD_2 */
-       834, /* GL_MAP2_TEXTURE_COORD_3 */
-       835, /* GL_MAP2_TEXTURE_COORD_4 */
-       836, /* GL_MAP2_VERTEX_3 */
-       837, /* GL_MAP2_VERTEX_4 */
-       801, /* GL_MAP1_GRID_DOMAIN */
-       802, /* GL_MAP1_GRID_SEGMENTS */
-       828, /* GL_MAP2_GRID_DOMAIN */
-       829, /* GL_MAP2_GRID_SEGMENTS */
-      1751, /* GL_TEXTURE_1D */
-      1753, /* GL_TEXTURE_2D */
+       809, /* GL_MAP1_COLOR_4 */
+       812, /* GL_MAP1_INDEX */
+       813, /* GL_MAP1_NORMAL */
+       814, /* GL_MAP1_TEXTURE_COORD_1 */
+       815, /* GL_MAP1_TEXTURE_COORD_2 */
+       816, /* GL_MAP1_TEXTURE_COORD_3 */
+       817, /* GL_MAP1_TEXTURE_COORD_4 */
+       818, /* GL_MAP1_VERTEX_3 */
+       819, /* GL_MAP1_VERTEX_4 */
+       836, /* GL_MAP2_COLOR_4 */
+       839, /* GL_MAP2_INDEX */
+       840, /* GL_MAP2_NORMAL */
+       841, /* GL_MAP2_TEXTURE_COORD_1 */
+       842, /* GL_MAP2_TEXTURE_COORD_2 */
+       843, /* GL_MAP2_TEXTURE_COORD_3 */
+       844, /* GL_MAP2_TEXTURE_COORD_4 */
+       845, /* GL_MAP2_VERTEX_3 */
+       846, /* GL_MAP2_VERTEX_4 */
+       810, /* GL_MAP1_GRID_DOMAIN */
+       811, /* GL_MAP1_GRID_SEGMENTS */
+       837, /* GL_MAP2_GRID_DOMAIN */
+       838, /* GL_MAP2_GRID_SEGMENTS */
+      1768, /* GL_TEXTURE_1D */
+      1770, /* GL_TEXTURE_2D */
        503, /* GL_FEEDBACK_BUFFER_POINTER */
        504, /* GL_FEEDBACK_BUFFER_SIZE */
        505, /* GL_FEEDBACK_BUFFER_TYPE */
-      1540, /* GL_SELECTION_BUFFER_POINTER */
-      1541, /* GL_SELECTION_BUFFER_SIZE */
-      1885, /* GL_TEXTURE_WIDTH */
-      1847, /* GL_TEXTURE_HEIGHT */
-      1791, /* GL_TEXTURE_COMPONENTS */
-      1775, /* GL_TEXTURE_BORDER_COLOR */
-      1774, /* GL_TEXTURE_BORDER */
+      1557, /* GL_SELECTION_BUFFER_POINTER */
+      1558, /* GL_SELECTION_BUFFER_SIZE */
+      1902, /* GL_TEXTURE_WIDTH */
+      1864, /* GL_TEXTURE_HEIGHT */
+      1808, /* GL_TEXTURE_COMPONENTS */
+      1792, /* GL_TEXTURE_BORDER_COLOR */
+      1791, /* GL_TEXTURE_BORDER */
        406, /* GL_DONT_CARE */
        501, /* GL_FASTEST */
-      1097, /* GL_NICEST */
+      1113, /* GL_NICEST */
         48, /* GL_AMBIENT */
        403, /* GL_DIFFUSE */
-      1592, /* GL_SPECULAR */
-      1271, /* GL_POSITION */
-      1595, /* GL_SPOT_DIRECTION */
-      1596, /* GL_SPOT_EXPONENT */
-      1594, /* GL_SPOT_CUTOFF */
+      1609, /* GL_SPECULAR */
+      1287, /* GL_POSITION */
+      1612, /* GL_SPOT_DIRECTION */
+      1613, /* GL_SPOT_EXPONENT */
+      1611, /* GL_SPOT_CUTOFF */
        288, /* GL_CONSTANT_ATTENUATION */
-       748, /* GL_LINEAR_ATTENUATION */
-      1375, /* GL_QUADRATIC_ATTENUATION */
+       755, /* GL_LINEAR_ATTENUATION */
+      1392, /* GL_QUADRATIC_ATTENUATION */
        257, /* GL_COMPILE */
        258, /* GL_COMPILE_AND_EXECUTE */
        132, /* GL_BYTE */
-      1928, /* GL_UNSIGNED_BYTE */
-      1557, /* GL_SHORT */
-      1943, /* GL_UNSIGNED_SHORT */
-       694, /* GL_INT */
-      1931, /* GL_UNSIGNED_INT */
+      1951, /* GL_UNSIGNED_BYTE */
+      1574, /* GL_SHORT */
+      1966, /* GL_UNSIGNED_SHORT */
+       701, /* GL_INT */
+      1954, /* GL_UNSIGNED_INT */
        512, /* GL_FLOAT */
          1, /* GL_2_BYTES */
          5, /* GL_3_BYTES */
          7, /* GL_4_BYTES */
        413, /* GL_DOUBLE */
-       647, /* GL_HALF_FLOAT */
+       654, /* GL_HALF_FLOAT */
        509, /* GL_FIXED */
        144, /* GL_CLEAR */
         50, /* GL_AND */
         52, /* GL_AND_REVERSE */
        313, /* GL_COPY */
         51, /* GL_AND_INVERTED */
-      1100, /* GL_NOOP */
-      2036, /* GL_XOR */
-      1166, /* GL_OR */
-      1101, /* GL_NOR */
+      1116, /* GL_NOOP */
+      2059, /* GL_XOR */
+      1182, /* GL_OR */
+      1117, /* GL_NOR */
        491, /* GL_EQUIV */
-       724, /* GL_INVERT */
-      1169, /* GL_OR_REVERSE */
+       731, /* GL_INVERT */
+      1185, /* GL_OR_REVERSE */
        314, /* GL_COPY_INVERTED */
-      1168, /* GL_OR_INVERTED */
-      1090, /* GL_NAND */
-      1546, /* GL_SET */
+      1184, /* GL_OR_INVERTED */
+      1106, /* GL_NAND */
+      1563, /* GL_SET */
        488, /* GL_EMISSION */
-      1556, /* GL_SHININESS */
+      1573, /* GL_SHININESS */
         49, /* GL_AMBIENT_AND_DIFFUSE */
        203, /* GL_COLOR_INDEXES */
-      1039, /* GL_MODELVIEW */
-      1350, /* GL_PROJECTION */
-      1686, /* GL_TEXTURE */
+      1055, /* GL_MODELVIEW */
+      1367, /* GL_PROJECTION */
+      1703, /* GL_TEXTURE */
        159, /* GL_COLOR */
        361, /* GL_DEPTH */
-      1618, /* GL_STENCIL */
+      1635, /* GL_STENCIL */
        202, /* GL_COLOR_INDEX */
-      1638, /* GL_STENCIL_INDEX */
+      1655, /* GL_STENCIL_INDEX */
        376, /* GL_DEPTH_COMPONENT */
-      1404, /* GL_RED */
-       643, /* GL_GREEN */
+      1421, /* GL_RED */
+       650, /* GL_GREEN */
         98, /* GL_BLUE */
         31, /* GL_ALPHA */
-      1455, /* GL_RGB */
-      1478, /* GL_RGBA */
-       778, /* GL_LUMINANCE */
-       799, /* GL_LUMINANCE_ALPHA */
+      1472, /* GL_RGB */
+      1495, /* GL_RGBA */
+       787, /* GL_LUMINANCE */
+       808, /* GL_LUMINANCE_ALPHA */
         74, /* GL_BITMAP */
-      1221, /* GL_POINT */
-       746, /* GL_LINE */
+      1237, /* GL_POINT */
+       753, /* GL_LINE */
        506, /* GL_FILL */
-      1415, /* GL_RENDER */
+      1432, /* GL_RENDER */
        502, /* GL_FEEDBACK */
-      1539, /* GL_SELECT */
+      1556, /* GL_SELECT */
        511, /* GL_FLAT */
-      1567, /* GL_SMOOTH */
-       725, /* GL_KEEP */
-      1448, /* GL_REPLACE */
-       676, /* GL_INCR */
+      1584, /* GL_SMOOTH */
+       732, /* GL_KEEP */
+      1465, /* GL_REPLACE */
+       683, /* GL_INCR */
        357, /* GL_DECR */
-      1960, /* GL_VENDOR */
-      1445, /* GL_RENDERER */
-      1961, /* GL_VERSION */
+      1983, /* GL_VENDOR */
+      1462, /* GL_RENDERER */
+      1984, /* GL_VERSION */
        495, /* GL_EXTENSIONS */
-      1503, /* GL_S */
-      1677, /* GL_T */
-      1391, /* GL_R */
-      1374, /* GL_Q */
-      1076, /* GL_MODULATE */
+      1520, /* GL_S */
+      1694, /* GL_T */
+      1408, /* GL_R */
+      1391, /* GL_Q */
+      1092, /* GL_MODULATE */
        356, /* GL_DECAL */
-      1834, /* GL_TEXTURE_ENV_MODE */
-      1833, /* GL_TEXTURE_ENV_COLOR */
-      1832, /* GL_TEXTURE_ENV */
+      1851, /* GL_TEXTURE_ENV_MODE */
+      1850, /* GL_TEXTURE_ENV_COLOR */
+      1849, /* GL_TEXTURE_ENV */
        496, /* GL_EYE_LINEAR */
-      1127, /* GL_OBJECT_LINEAR */
-      1593, /* GL_SPHERE_MAP */
-      1837, /* GL_TEXTURE_GEN_MODE */
-      1129, /* GL_OBJECT_PLANE */
+      1143, /* GL_OBJECT_LINEAR */
+      1610, /* GL_SPHERE_MAP */
+      1854, /* GL_TEXTURE_GEN_MODE */
+      1145, /* GL_OBJECT_PLANE */
        497, /* GL_EYE_PLANE */
-      1091, /* GL_NEAREST */
-       747, /* GL_LINEAR */
-      1095, /* GL_NEAREST_MIPMAP_NEAREST */
-       752, /* GL_LINEAR_MIPMAP_NEAREST */
-      1094, /* GL_NEAREST_MIPMAP_LINEAR */
-       751, /* GL_LINEAR_MIPMAP_LINEAR */
-      1860, /* GL_TEXTURE_MAG_FILTER */
-      1869, /* GL_TEXTURE_MIN_FILTER */
-      1888, /* GL_TEXTURE_WRAP_S */
-      1889, /* GL_TEXTURE_WRAP_T */
+      1107, /* GL_NEAREST */
+       754, /* GL_LINEAR */
+      1111, /* GL_NEAREST_MIPMAP_NEAREST */
+       759, /* GL_LINEAR_MIPMAP_NEAREST */
+      1110, /* GL_NEAREST_MIPMAP_LINEAR */
+       758, /* GL_LINEAR_MIPMAP_LINEAR */
+      1877, /* GL_TEXTURE_MAG_FILTER */
+      1886, /* GL_TEXTURE_MIN_FILTER */
+      1905, /* GL_TEXTURE_WRAP_S */
+      1906, /* GL_TEXTURE_WRAP_T */
        138, /* GL_CLAMP */
-      1447, /* GL_REPEAT */
-      1265, /* GL_POLYGON_OFFSET_UNITS */
-      1264, /* GL_POLYGON_OFFSET_POINT */
-      1263, /* GL_POLYGON_OFFSET_LINE */
-      1392, /* GL_R3_G3_B2 */
-      1957, /* GL_V2F */
-      1958, /* GL_V3F */
+      1464, /* GL_REPEAT */
+      1281, /* GL_POLYGON_OFFSET_UNITS */
+      1280, /* GL_POLYGON_OFFSET_POINT */
+      1279, /* GL_POLYGON_OFFSET_LINE */
+      1409, /* GL_R3_G3_B2 */
+      1980, /* GL_V2F */
+      1981, /* GL_V3F */
        135, /* GL_C4UB_V2F */
        136, /* GL_C4UB_V3F */
        133, /* GL_C3F_V3F */
-      1088, /* GL_N3F_V3F */
+      1104, /* GL_N3F_V3F */
        134, /* GL_C4F_N3F_V3F */
-      1682, /* GL_T2F_V3F */
-      1684, /* GL_T4F_V4F */
-      1680, /* GL_T2F_C4UB_V3F */
-      1678, /* GL_T2F_C3F_V3F */
-      1681, /* GL_T2F_N3F_V3F */
-      1679, /* GL_T2F_C4F_N3F_V3F */
-      1683, /* GL_T4F_C4F_N3F_V4F */
+      1699, /* GL_T2F_V3F */
+      1701, /* GL_T4F_V4F */
+      1697, /* GL_T2F_C4UB_V3F */
+      1695, /* GL_T2F_C3F_V3F */
+      1698, /* GL_T2F_N3F_V3F */
+      1696, /* GL_T2F_C4F_N3F_V3F */
+      1700, /* GL_T4F_C4F_N3F_V4F */
        151, /* GL_CLIP_PLANE0 */
        152, /* GL_CLIP_PLANE1 */
        153, /* GL_CLIP_PLANE2 */
        154, /* GL_CLIP_PLANE3 */
        155, /* GL_CLIP_PLANE4 */
        156, /* GL_CLIP_PLANE5 */
-       731, /* GL_LIGHT0 */
-       732, /* GL_LIGHT1 */
-       733, /* GL_LIGHT2 */
-       734, /* GL_LIGHT3 */
-       735, /* GL_LIGHT4 */
-       736, /* GL_LIGHT5 */
-       737, /* GL_LIGHT6 */
-       738, /* GL_LIGHT7 */
-       651, /* GL_HINT_BIT */
+       738, /* GL_LIGHT0 */
+       739, /* GL_LIGHT1 */
+       740, /* GL_LIGHT2 */
+       741, /* GL_LIGHT3 */
+       742, /* GL_LIGHT4 */
+       743, /* GL_LIGHT5 */
+       744, /* GL_LIGHT6 */
+       745, /* GL_LIGHT7 */
+       658, /* GL_HINT_BIT */
        290, /* GL_CONSTANT_COLOR */
-      1140, /* GL_ONE_MINUS_CONSTANT_COLOR */
+      1156, /* GL_ONE_MINUS_CONSTANT_COLOR */
        285, /* GL_CONSTANT_ALPHA */
-      1138, /* GL_ONE_MINUS_CONSTANT_ALPHA */
+      1154, /* GL_ONE_MINUS_CONSTANT_ALPHA */
         77, /* GL_BLEND_COLOR */
-       628, /* GL_FUNC_ADD */
-      1023, /* GL_MIN */
-       916, /* GL_MAX */
+       631, /* GL_FUNC_ADD */
+      1039, /* GL_MIN */
+       925, /* GL_MAX */
         84, /* GL_BLEND_EQUATION */
-       634, /* GL_FUNC_SUBTRACT */
-       631, /* GL_FUNC_REVERSE_SUBTRACT */
+       637, /* GL_FUNC_SUBTRACT */
+       634, /* GL_FUNC_REVERSE_SUBTRACT */
        293, /* GL_CONVOLUTION_1D */
        294, /* GL_CONVOLUTION_2D */
-      1542, /* GL_SEPARABLE_2D */
+      1559, /* GL_SEPARABLE_2D */
        297, /* GL_CONVOLUTION_BORDER_MODE */
        301, /* GL_CONVOLUTION_FILTER_SCALE */
        299, /* GL_CONVOLUTION_FILTER_BIAS */
-      1405, /* GL_REDUCE */
+      1422, /* GL_REDUCE */
        303, /* GL_CONVOLUTION_FORMAT */
        307, /* GL_CONVOLUTION_WIDTH */
        305, /* GL_CONVOLUTION_HEIGHT */
-       933, /* GL_MAX_CONVOLUTION_WIDTH */
-       931, /* GL_MAX_CONVOLUTION_HEIGHT */
-      1304, /* GL_POST_CONVOLUTION_RED_SCALE */
-      1300, /* GL_POST_CONVOLUTION_GREEN_SCALE */
-      1295, /* GL_POST_CONVOLUTION_BLUE_SCALE */
-      1291, /* GL_POST_CONVOLUTION_ALPHA_SCALE */
-      1302, /* GL_POST_CONVOLUTION_RED_BIAS */
-      1298, /* GL_POST_CONVOLUTION_GREEN_BIAS */
-      1293, /* GL_POST_CONVOLUTION_BLUE_BIAS */
-      1289, /* GL_POST_CONVOLUTION_ALPHA_BIAS */
-       652, /* GL_HISTOGRAM */
-      1357, /* GL_PROXY_HISTOGRAM */
-       668, /* GL_HISTOGRAM_WIDTH */
-       658, /* GL_HISTOGRAM_FORMAT */
-       664, /* GL_HISTOGRAM_RED_SIZE */
-       660, /* GL_HISTOGRAM_GREEN_SIZE */
-       655, /* GL_HISTOGRAM_BLUE_SIZE */
-       653, /* GL_HISTOGRAM_ALPHA_SIZE */
-       662, /* GL_HISTOGRAM_LUMINANCE_SIZE */
-       666, /* GL_HISTOGRAM_SINK */
-      1024, /* GL_MINMAX */
-      1026, /* GL_MINMAX_FORMAT */
-      1028, /* GL_MINMAX_SINK */
-      1685, /* GL_TABLE_TOO_LARGE_EXT */
-      1930, /* GL_UNSIGNED_BYTE_3_3_2 */
-      1946, /* GL_UNSIGNED_SHORT_4_4_4_4 */
-      1949, /* GL_UNSIGNED_SHORT_5_5_5_1 */
-      1940, /* GL_UNSIGNED_INT_8_8_8_8 */
-      1932, /* GL_UNSIGNED_INT_10_10_10_2 */
-      1262, /* GL_POLYGON_OFFSET_FILL */
-      1261, /* GL_POLYGON_OFFSET_FACTOR */
-      1260, /* GL_POLYGON_OFFSET_BIAS */
-      1451, /* GL_RESCALE_NORMAL */
+       942, /* GL_MAX_CONVOLUTION_WIDTH */
+       940, /* GL_MAX_CONVOLUTION_HEIGHT */
+      1320, /* GL_POST_CONVOLUTION_RED_SCALE */
+      1316, /* GL_POST_CONVOLUTION_GREEN_SCALE */
+      1311, /* GL_POST_CONVOLUTION_BLUE_SCALE */
+      1307, /* GL_POST_CONVOLUTION_ALPHA_SCALE */
+      1318, /* GL_POST_CONVOLUTION_RED_BIAS */
+      1314, /* GL_POST_CONVOLUTION_GREEN_BIAS */
+      1309, /* GL_POST_CONVOLUTION_BLUE_BIAS */
+      1305, /* GL_POST_CONVOLUTION_ALPHA_BIAS */
+       659, /* GL_HISTOGRAM */
+      1374, /* GL_PROXY_HISTOGRAM */
+       675, /* GL_HISTOGRAM_WIDTH */
+       665, /* GL_HISTOGRAM_FORMAT */
+       671, /* GL_HISTOGRAM_RED_SIZE */
+       667, /* GL_HISTOGRAM_GREEN_SIZE */
+       662, /* GL_HISTOGRAM_BLUE_SIZE */
+       660, /* GL_HISTOGRAM_ALPHA_SIZE */
+       669, /* GL_HISTOGRAM_LUMINANCE_SIZE */
+       673, /* GL_HISTOGRAM_SINK */
+      1040, /* GL_MINMAX */
+      1042, /* GL_MINMAX_FORMAT */
+      1044, /* GL_MINMAX_SINK */
+      1702, /* GL_TABLE_TOO_LARGE_EXT */
+      1953, /* GL_UNSIGNED_BYTE_3_3_2 */
+      1969, /* GL_UNSIGNED_SHORT_4_4_4_4 */
+      1972, /* GL_UNSIGNED_SHORT_5_5_5_1 */
+      1963, /* GL_UNSIGNED_INT_8_8_8_8 */
+      1955, /* GL_UNSIGNED_INT_10_10_10_2 */
+      1278, /* GL_POLYGON_OFFSET_FILL */
+      1277, /* GL_POLYGON_OFFSET_FACTOR */
+      1276, /* GL_POLYGON_OFFSET_BIAS */
+      1468, /* GL_RESCALE_NORMAL */
         36, /* GL_ALPHA4 */
         38, /* GL_ALPHA8 */
         32, /* GL_ALPHA12 */
         34, /* GL_ALPHA16 */
-       789, /* GL_LUMINANCE4 */
-       795, /* GL_LUMINANCE8 */
-       779, /* GL_LUMINANCE12 */
-       785, /* GL_LUMINANCE16 */
-       790, /* GL_LUMINANCE4_ALPHA4 */
-       793, /* GL_LUMINANCE6_ALPHA2 */
-       796, /* GL_LUMINANCE8_ALPHA8 */
-       782, /* GL_LUMINANCE12_ALPHA4 */
-       780, /* GL_LUMINANCE12_ALPHA12 */
-       786, /* GL_LUMINANCE16_ALPHA16 */
-       695, /* GL_INTENSITY */
-       700, /* GL_INTENSITY4 */
-       702, /* GL_INTENSITY8 */
-       696, /* GL_INTENSITY12 */
-       698, /* GL_INTENSITY16 */
-      1464, /* GL_RGB2_EXT */
-      1465, /* GL_RGB4 */
-      1468, /* GL_RGB5 */
-      1475, /* GL_RGB8 */
-      1456, /* GL_RGB10 */
-      1460, /* GL_RGB12 */
-      1462, /* GL_RGB16 */
-      1483, /* GL_RGBA2 */
-      1485, /* GL_RGBA4 */
-      1471, /* GL_RGB5_A1 */
-      1490, /* GL_RGBA8 */
-      1457, /* GL_RGB10_A2 */
-      1479, /* GL_RGBA12 */
-      1481, /* GL_RGBA16 */
-      1876, /* GL_TEXTURE_RED_SIZE */
-      1845, /* GL_TEXTURE_GREEN_SIZE */
-      1772, /* GL_TEXTURE_BLUE_SIZE */
-      1757, /* GL_TEXTURE_ALPHA_SIZE */
-      1858, /* GL_TEXTURE_LUMINANCE_SIZE */
-      1849, /* GL_TEXTURE_INTENSITY_SIZE */
-      1449, /* GL_REPLACE_EXT */
-      1361, /* GL_PROXY_TEXTURE_1D */
-      1364, /* GL_PROXY_TEXTURE_2D */
-      1883, /* GL_TEXTURE_TOO_LARGE_EXT */
-      1871, /* GL_TEXTURE_PRIORITY */
-      1878, /* GL_TEXTURE_RESIDENT */
-      1760, /* GL_TEXTURE_BINDING_1D */
-      1762, /* GL_TEXTURE_BINDING_2D */
-      1764, /* GL_TEXTURE_BINDING_3D */
-      1176, /* GL_PACK_SKIP_IMAGES */
-      1172, /* GL_PACK_IMAGE_HEIGHT */
-      1923, /* GL_UNPACK_SKIP_IMAGES */
-      1920, /* GL_UNPACK_IMAGE_HEIGHT */
-      1755, /* GL_TEXTURE_3D */
-      1367, /* GL_PROXY_TEXTURE_3D */
-      1829, /* GL_TEXTURE_DEPTH */
-      1886, /* GL_TEXTURE_WRAP_R */
-       917, /* GL_MAX_3D_TEXTURE_SIZE */
-      1962, /* GL_VERTEX_ARRAY */
-      1103, /* GL_NORMAL_ARRAY */
+       798, /* GL_LUMINANCE4 */
+       804, /* GL_LUMINANCE8 */
+       788, /* GL_LUMINANCE12 */
+       794, /* GL_LUMINANCE16 */
+       799, /* GL_LUMINANCE4_ALPHA4 */
+       802, /* GL_LUMINANCE6_ALPHA2 */
+       805, /* GL_LUMINANCE8_ALPHA8 */
+       791, /* GL_LUMINANCE12_ALPHA4 */
+       789, /* GL_LUMINANCE12_ALPHA12 */
+       795, /* GL_LUMINANCE16_ALPHA16 */
+       702, /* GL_INTENSITY */
+       707, /* GL_INTENSITY4 */
+       709, /* GL_INTENSITY8 */
+       703, /* GL_INTENSITY12 */
+       705, /* GL_INTENSITY16 */
+      1481, /* GL_RGB2_EXT */
+      1482, /* GL_RGB4 */
+      1485, /* GL_RGB5 */
+      1492, /* GL_RGB8 */
+      1473, /* GL_RGB10 */
+      1477, /* GL_RGB12 */
+      1479, /* GL_RGB16 */
+      1500, /* GL_RGBA2 */
+      1502, /* GL_RGBA4 */
+      1488, /* GL_RGB5_A1 */
+      1507, /* GL_RGBA8 */
+      1474, /* GL_RGB10_A2 */
+      1496, /* GL_RGBA12 */
+      1498, /* GL_RGBA16 */
+      1893, /* GL_TEXTURE_RED_SIZE */
+      1862, /* GL_TEXTURE_GREEN_SIZE */
+      1789, /* GL_TEXTURE_BLUE_SIZE */
+      1774, /* GL_TEXTURE_ALPHA_SIZE */
+      1875, /* GL_TEXTURE_LUMINANCE_SIZE */
+      1866, /* GL_TEXTURE_INTENSITY_SIZE */
+      1466, /* GL_REPLACE_EXT */
+      1378, /* GL_PROXY_TEXTURE_1D */
+      1381, /* GL_PROXY_TEXTURE_2D */
+      1900, /* GL_TEXTURE_TOO_LARGE_EXT */
+      1888, /* GL_TEXTURE_PRIORITY */
+      1895, /* GL_TEXTURE_RESIDENT */
+      1777, /* GL_TEXTURE_BINDING_1D */
+      1779, /* GL_TEXTURE_BINDING_2D */
+      1781, /* GL_TEXTURE_BINDING_3D */
+      1192, /* GL_PACK_SKIP_IMAGES */
+      1188, /* GL_PACK_IMAGE_HEIGHT */
+      1946, /* GL_UNPACK_SKIP_IMAGES */
+      1943, /* GL_UNPACK_IMAGE_HEIGHT */
+      1772, /* GL_TEXTURE_3D */
+      1384, /* GL_PROXY_TEXTURE_3D */
+      1846, /* GL_TEXTURE_DEPTH */
+      1903, /* GL_TEXTURE_WRAP_R */
+       926, /* GL_MAX_3D_TEXTURE_SIZE */
+      1985, /* GL_VERTEX_ARRAY */
+      1119, /* GL_NORMAL_ARRAY */
        160, /* GL_COLOR_ARRAY */
-       680, /* GL_INDEX_ARRAY */
-      1799, /* GL_TEXTURE_COORD_ARRAY */
+       687, /* GL_INDEX_ARRAY */
+      1816, /* GL_TEXTURE_COORD_ARRAY */
        480, /* GL_EDGE_FLAG_ARRAY */
-      1968, /* GL_VERTEX_ARRAY_SIZE */
-      1970, /* GL_VERTEX_ARRAY_TYPE */
-      1969, /* GL_VERTEX_ARRAY_STRIDE */
-      1108, /* GL_NORMAL_ARRAY_TYPE */
-      1107, /* GL_NORMAL_ARRAY_STRIDE */
+      1991, /* GL_VERTEX_ARRAY_SIZE */
+      1993, /* GL_VERTEX_ARRAY_TYPE */
+      1992, /* GL_VERTEX_ARRAY_STRIDE */
+      1124, /* GL_NORMAL_ARRAY_TYPE */
+      1123, /* GL_NORMAL_ARRAY_STRIDE */
        164, /* GL_COLOR_ARRAY_SIZE */
        166, /* GL_COLOR_ARRAY_TYPE */
        165, /* GL_COLOR_ARRAY_STRIDE */
-       685, /* GL_INDEX_ARRAY_TYPE */
-       684, /* GL_INDEX_ARRAY_STRIDE */
-      1803, /* GL_TEXTURE_COORD_ARRAY_SIZE */
-      1805, /* GL_TEXTURE_COORD_ARRAY_TYPE */
-      1804, /* GL_TEXTURE_COORD_ARRAY_STRIDE */
+       692, /* GL_INDEX_ARRAY_TYPE */
+       691, /* GL_INDEX_ARRAY_STRIDE */
+      1820, /* GL_TEXTURE_COORD_ARRAY_SIZE */
+      1822, /* GL_TEXTURE_COORD_ARRAY_TYPE */
+      1821, /* GL_TEXTURE_COORD_ARRAY_STRIDE */
        484, /* GL_EDGE_FLAG_ARRAY_STRIDE */
-      1967, /* GL_VERTEX_ARRAY_POINTER */
-      1106, /* GL_NORMAL_ARRAY_POINTER */
+      1990, /* GL_VERTEX_ARRAY_POINTER */
+      1122, /* GL_NORMAL_ARRAY_POINTER */
        163, /* GL_COLOR_ARRAY_POINTER */
-       683, /* GL_INDEX_ARRAY_POINTER */
-      1802, /* GL_TEXTURE_COORD_ARRAY_POINTER */
+       690, /* GL_INDEX_ARRAY_POINTER */
+      1819, /* GL_TEXTURE_COORD_ARRAY_POINTER */
        483, /* GL_EDGE_FLAG_ARRAY_POINTER */
-      1081, /* GL_MULTISAMPLE */
-      1516, /* GL_SAMPLE_ALPHA_TO_COVERAGE */
-      1518, /* GL_SAMPLE_ALPHA_TO_ONE */
-      1523, /* GL_SAMPLE_COVERAGE */
-      1520, /* GL_SAMPLE_BUFFERS */
-      1511, /* GL_SAMPLES */
-      1527, /* GL_SAMPLE_COVERAGE_VALUE */
-      1525, /* GL_SAMPLE_COVERAGE_INVERT */
+      1097, /* GL_MULTISAMPLE */
+      1533, /* GL_SAMPLE_ALPHA_TO_COVERAGE */
+      1535, /* GL_SAMPLE_ALPHA_TO_ONE */
+      1540, /* GL_SAMPLE_COVERAGE */
+      1537, /* GL_SAMPLE_BUFFERS */
+      1528, /* GL_SAMPLES */
+      1544, /* GL_SAMPLE_COVERAGE_VALUE */
+      1542, /* GL_SAMPLE_COVERAGE_INVERT */
        208, /* GL_COLOR_MATRIX */
        210, /* GL_COLOR_MATRIX_STACK_DEPTH */
-       927, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */
-      1287, /* GL_POST_COLOR_MATRIX_RED_SCALE */
-      1283, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */
-      1278, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */
-      1274, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */
-      1285, /* GL_POST_COLOR_MATRIX_RED_BIAS */
-      1281, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */
-      1276, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */
-      1272, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */
-      1782, /* GL_TEXTURE_COLOR_TABLE_SGI */
-      1368, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */
-      1784, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
+       936, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */
+      1303, /* GL_POST_COLOR_MATRIX_RED_SCALE */
+      1299, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */
+      1294, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */
+      1290, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */
+      1301, /* GL_POST_COLOR_MATRIX_RED_BIAS */
+      1297, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */
+      1292, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */
+      1288, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */
+      1799, /* GL_TEXTURE_COLOR_TABLE_SGI */
+      1385, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */
+      1801, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
         82, /* GL_BLEND_DST_RGB */
         96, /* GL_BLEND_SRC_RGB */
         80, /* GL_BLEND_DST_ALPHA */
         94, /* GL_BLEND_SRC_ALPHA */
        214, /* GL_COLOR_TABLE */
-      1297, /* GL_POST_CONVOLUTION_COLOR_TABLE */
-      1280, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */
-      1356, /* GL_PROXY_COLOR_TABLE */
-      1360, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */
-      1359, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */
+      1313, /* GL_POST_CONVOLUTION_COLOR_TABLE */
+      1296, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */
+      1373, /* GL_PROXY_COLOR_TABLE */
+      1377, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */
+      1376, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */
        238, /* GL_COLOR_TABLE_SCALE */
        218, /* GL_COLOR_TABLE_BIAS */
        223, /* GL_COLOR_TABLE_FORMAT */
@@ -4741,98 +4791,98 @@ static const unsigned reduced_enums[1402] =
        229, /* GL_COLOR_TABLE_INTENSITY_SIZE */
         71, /* GL_BGR */
         72, /* GL_BGRA */
-       942, /* GL_MAX_ELEMENTS_VERTICES */
-       941, /* GL_MAX_ELEMENTS_INDICES */
-      1848, /* GL_TEXTURE_INDEX_SIZE_EXT */
+       951, /* GL_MAX_ELEMENTS_VERTICES */
+       950, /* GL_MAX_ELEMENTS_INDICES */
+      1865, /* GL_TEXTURE_INDEX_SIZE_EXT */
        157, /* GL_CLIP_VOLUME_CLIPPING_HINT_EXT */
-      1243, /* GL_POINT_SIZE_MIN */
-      1239, /* GL_POINT_SIZE_MAX */
-      1228, /* GL_POINT_FADE_THRESHOLD_SIZE */
-      1224, /* GL_POINT_DISTANCE_ATTENUATION */
+      1259, /* GL_POINT_SIZE_MIN */
+      1255, /* GL_POINT_SIZE_MAX */
+      1244, /* GL_POINT_FADE_THRESHOLD_SIZE */
+      1240, /* GL_POINT_DISTANCE_ATTENUATION */
        139, /* GL_CLAMP_TO_BORDER */
        142, /* GL_CLAMP_TO_EDGE */
-      1870, /* GL_TEXTURE_MIN_LOD */
-      1868, /* GL_TEXTURE_MAX_LOD */
-      1759, /* GL_TEXTURE_BASE_LEVEL */
-      1867, /* GL_TEXTURE_MAX_LEVEL */
-       671, /* GL_IGNORE_BORDER_HP */
+      1887, /* GL_TEXTURE_MIN_LOD */
+      1885, /* GL_TEXTURE_MAX_LOD */
+      1776, /* GL_TEXTURE_BASE_LEVEL */
+      1884, /* GL_TEXTURE_MAX_LEVEL */
+       678, /* GL_IGNORE_BORDER_HP */
        289, /* GL_CONSTANT_BORDER_HP */
-      1450, /* GL_REPLICATE_BORDER_HP */
+      1467, /* GL_REPLICATE_BORDER_HP */
        295, /* GL_CONVOLUTION_BORDER_COLOR */
-      1135, /* GL_OCCLUSION_TEST_HP */
-      1136, /* GL_OCCLUSION_TEST_RESULT_HP */
-       749, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */
-      1776, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */
-      1778, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */
-      1780, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */
-      1781, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */
-      1779, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */
-      1777, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */
-       922, /* GL_MAX_CLIPMAP_DEPTH_SGIX */
-       923, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */
-      1307, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */
-      1309, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */
-      1306, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */
-      1308, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */
-      1856, /* GL_TEXTURE_LOD_BIAS_S_SGIX */
-      1857, /* GL_TEXTURE_LOD_BIAS_T_SGIX */
-      1855, /* GL_TEXTURE_LOD_BIAS_R_SGIX */
-       637, /* GL_GENERATE_MIPMAP */
-       638, /* GL_GENERATE_MIPMAP_HINT */
+      1151, /* GL_OCCLUSION_TEST_HP */
+      1152, /* GL_OCCLUSION_TEST_RESULT_HP */
+       756, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */
+      1793, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */
+      1795, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */
+      1797, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */
+      1798, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */
+      1796, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */
+      1794, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */
+       931, /* GL_MAX_CLIPMAP_DEPTH_SGIX */
+       932, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */
+      1323, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */
+      1325, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */
+      1322, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */
+      1324, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */
+      1873, /* GL_TEXTURE_LOD_BIAS_S_SGIX */
+      1874, /* GL_TEXTURE_LOD_BIAS_T_SGIX */
+      1872, /* GL_TEXTURE_LOD_BIAS_R_SGIX */
+       640, /* GL_GENERATE_MIPMAP */
+       641, /* GL_GENERATE_MIPMAP_HINT */
        555, /* GL_FOG_OFFSET_SGIX */
        556, /* GL_FOG_OFFSET_VALUE_SGIX */
-      1790, /* GL_TEXTURE_COMPARE_SGIX */
-      1789, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */
-      1852, /* GL_TEXTURE_LEQUAL_R_SGIX */
-      1844, /* GL_TEXTURE_GEQUAL_R_SGIX */
+      1807, /* GL_TEXTURE_COMPARE_SGIX */
+      1806, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */
+      1869, /* GL_TEXTURE_LEQUAL_R_SGIX */
+      1861, /* GL_TEXTURE_GEQUAL_R_SGIX */
        377, /* GL_DEPTH_COMPONENT16 */
        381, /* GL_DEPTH_COMPONENT24 */
        385, /* GL_DEPTH_COMPONENT32 */
        320, /* GL_CULL_VERTEX_EXT */
        322, /* GL_CULL_VERTEX_OBJECT_POSITION_EXT */
        321, /* GL_CULL_VERTEX_EYE_POSITION_EXT */
-      2032, /* GL_WRAP_BORDER_SUN */
-      1783, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */
-       742, /* GL_LIGHT_MODEL_COLOR_CONTROL */
-      1560, /* GL_SINGLE_COLOR */
-      1544, /* GL_SEPARATE_SPECULAR_COLOR */
-      1555, /* GL_SHARED_TEXTURE_PALETTE_EXT */
+      2055, /* GL_WRAP_BORDER_SUN */
+      1800, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */
+       749, /* GL_LIGHT_MODEL_COLOR_CONTROL */
+      1577, /* GL_SINGLE_COLOR */
+      1561, /* GL_SEPARATE_SPECULAR_COLOR */
+      1572, /* GL_SHARED_TEXTURE_PALETTE_EXT */
        567, /* GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */
        568, /* GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */
-       577, /* GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */
+       578, /* GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */
        570, /* GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */
        566, /* GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE */
        565, /* GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE */
        569, /* GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */
-       578, /* GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */
-       595, /* GL_FRAMEBUFFER_DEFAULT */
-       619, /* GL_FRAMEBUFFER_UNDEFINED */
+       579, /* GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */
+       596, /* GL_FRAMEBUFFER_DEFAULT */
+       622, /* GL_FRAMEBUFFER_UNDEFINED */
        393, /* GL_DEPTH_STENCIL_ATTACHMENT */
-       679, /* GL_INDEX */
-      1929, /* GL_UNSIGNED_BYTE_2_3_3_REV */
-      1950, /* GL_UNSIGNED_SHORT_5_6_5 */
-      1951, /* GL_UNSIGNED_SHORT_5_6_5_REV */
-      1947, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */
-      1944, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */
-      1941, /* GL_UNSIGNED_INT_8_8_8_8_REV */
-      1938, /* GL_UNSIGNED_INT_2_10_10_10_REV */
-      1865, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */
-      1866, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */
-      1864, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */
-      1031, /* GL_MIRRORED_REPEAT */
-      1498, /* GL_RGB_S3TC */
-      1467, /* GL_RGB4_S3TC */
-      1496, /* GL_RGBA_S3TC */
-      1489, /* GL_RGBA4_S3TC */
-      1494, /* GL_RGBA_DXT5_S3TC */
-      1486, /* GL_RGBA4_DXT5_S3TC */
+       686, /* GL_INDEX */
+      1952, /* GL_UNSIGNED_BYTE_2_3_3_REV */
+      1973, /* GL_UNSIGNED_SHORT_5_6_5 */
+      1974, /* GL_UNSIGNED_SHORT_5_6_5_REV */
+      1970, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */
+      1967, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */
+      1964, /* GL_UNSIGNED_INT_8_8_8_8_REV */
+      1961, /* GL_UNSIGNED_INT_2_10_10_10_REV */
+      1882, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */
+      1883, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */
+      1881, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */
+      1047, /* GL_MIRRORED_REPEAT */
+      1515, /* GL_RGB_S3TC */
+      1484, /* GL_RGB4_S3TC */
+      1513, /* GL_RGBA_S3TC */
+      1506, /* GL_RGBA4_S3TC */
+      1511, /* GL_RGBA_DXT5_S3TC */
+      1503, /* GL_RGBA4_DXT5_S3TC */
        277, /* GL_COMPRESSED_RGB_S3TC_DXT1_EXT */
        272, /* GL_COMPRESSED_RGBA_S3TC_DXT1_EXT */
        273, /* GL_COMPRESSED_RGBA_S3TC_DXT3_EXT */
        274, /* GL_COMPRESSED_RGBA_S3TC_DXT5_EXT */
-      1093, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */
-      1092, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */
-       750, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */
+      1109, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */
+      1108, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */
+       757, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */
        542, /* GL_FOG_COORDINATE_SOURCE */
        534, /* GL_FOG_COORD */
        558, /* GL_FRAGMENT_DEPTH */
@@ -4843,279 +4893,279 @@ static const unsigned reduced_enums[1402] =
        536, /* GL_FOG_COORDINATE_ARRAY */
        212, /* GL_COLOR_SUM */
        347, /* GL_CURRENT_SECONDARY_COLOR */
-      1536, /* GL_SECONDARY_COLOR_ARRAY_SIZE */
-      1538, /* GL_SECONDARY_COLOR_ARRAY_TYPE */
-      1537, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */
-      1535, /* GL_SECONDARY_COLOR_ARRAY_POINTER */
-      1532, /* GL_SECONDARY_COLOR_ARRAY */
+      1553, /* GL_SECONDARY_COLOR_ARRAY_SIZE */
+      1555, /* GL_SECONDARY_COLOR_ARRAY_TYPE */
+      1554, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */
+      1552, /* GL_SECONDARY_COLOR_ARRAY_POINTER */
+      1549, /* GL_SECONDARY_COLOR_ARRAY */
        345, /* GL_CURRENT_RASTER_SECONDARY_COLOR */
         28, /* GL_ALIASED_POINT_SIZE_RANGE */
         27, /* GL_ALIASED_LINE_WIDTH_RANGE */
-      1687, /* GL_TEXTURE0 */
-      1689, /* GL_TEXTURE1 */
-      1711, /* GL_TEXTURE2 */
-      1733, /* GL_TEXTURE3 */
-      1739, /* GL_TEXTURE4 */
-      1741, /* GL_TEXTURE5 */
-      1743, /* GL_TEXTURE6 */
-      1745, /* GL_TEXTURE7 */
-      1747, /* GL_TEXTURE8 */
-      1749, /* GL_TEXTURE9 */
-      1690, /* GL_TEXTURE10 */
-      1692, /* GL_TEXTURE11 */
-      1694, /* GL_TEXTURE12 */
-      1696, /* GL_TEXTURE13 */
-      1698, /* GL_TEXTURE14 */
-      1700, /* GL_TEXTURE15 */
-      1702, /* GL_TEXTURE16 */
-      1704, /* GL_TEXTURE17 */
-      1706, /* GL_TEXTURE18 */
-      1708, /* GL_TEXTURE19 */
-      1712, /* GL_TEXTURE20 */
-      1714, /* GL_TEXTURE21 */
-      1716, /* GL_TEXTURE22 */
-      1718, /* GL_TEXTURE23 */
-      1720, /* GL_TEXTURE24 */
-      1722, /* GL_TEXTURE25 */
-      1724, /* GL_TEXTURE26 */
-      1726, /* GL_TEXTURE27 */
-      1728, /* GL_TEXTURE28 */
-      1730, /* GL_TEXTURE29 */
-      1734, /* GL_TEXTURE30 */
-      1736, /* GL_TEXTURE31 */
+      1704, /* GL_TEXTURE0 */
+      1706, /* GL_TEXTURE1 */
+      1728, /* GL_TEXTURE2 */
+      1750, /* GL_TEXTURE3 */
+      1756, /* GL_TEXTURE4 */
+      1758, /* GL_TEXTURE5 */
+      1760, /* GL_TEXTURE6 */
+      1762, /* GL_TEXTURE7 */
+      1764, /* GL_TEXTURE8 */
+      1766, /* GL_TEXTURE9 */
+      1707, /* GL_TEXTURE10 */
+      1709, /* GL_TEXTURE11 */
+      1711, /* GL_TEXTURE12 */
+      1713, /* GL_TEXTURE13 */
+      1715, /* GL_TEXTURE14 */
+      1717, /* GL_TEXTURE15 */
+      1719, /* GL_TEXTURE16 */
+      1721, /* GL_TEXTURE17 */
+      1723, /* GL_TEXTURE18 */
+      1725, /* GL_TEXTURE19 */
+      1729, /* GL_TEXTURE20 */
+      1731, /* GL_TEXTURE21 */
+      1733, /* GL_TEXTURE22 */
+      1735, /* GL_TEXTURE23 */
+      1737, /* GL_TEXTURE24 */
+      1739, /* GL_TEXTURE25 */
+      1741, /* GL_TEXTURE26 */
+      1743, /* GL_TEXTURE27 */
+      1745, /* GL_TEXTURE28 */
+      1747, /* GL_TEXTURE29 */
+      1751, /* GL_TEXTURE30 */
+      1753, /* GL_TEXTURE31 */
         18, /* GL_ACTIVE_TEXTURE */
        145, /* GL_CLIENT_ACTIVE_TEXTURE */
-      1001, /* GL_MAX_TEXTURE_UNITS */
-      1906, /* GL_TRANSPOSE_MODELVIEW_MATRIX */
-      1909, /* GL_TRANSPOSE_PROJECTION_MATRIX */
-      1911, /* GL_TRANSPOSE_TEXTURE_MATRIX */
-      1903, /* GL_TRANSPOSE_COLOR_MATRIX */
-      1669, /* GL_SUBTRACT */
-       984, /* GL_MAX_RENDERBUFFER_SIZE */
+      1015, /* GL_MAX_TEXTURE_UNITS */
+      1927, /* GL_TRANSPOSE_MODELVIEW_MATRIX */
+      1930, /* GL_TRANSPOSE_PROJECTION_MATRIX */
+      1932, /* GL_TRANSPOSE_TEXTURE_MATRIX */
+      1924, /* GL_TRANSPOSE_COLOR_MATRIX */
+      1686, /* GL_SUBTRACT */
+       998, /* GL_MAX_RENDERBUFFER_SIZE */
        260, /* GL_COMPRESSED_ALPHA */
        264, /* GL_COMPRESSED_LUMINANCE */
        265, /* GL_COMPRESSED_LUMINANCE_ALPHA */
        262, /* GL_COMPRESSED_INTENSITY */
        268, /* GL_COMPRESSED_RGB */
        269, /* GL_COMPRESSED_RGBA */
-      1797, /* GL_TEXTURE_COMPRESSION_HINT */
-      1874, /* GL_TEXTURE_RECTANGLE_ARB */
-      1769, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */
-      1371, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */
-       982, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */
+      1814, /* GL_TEXTURE_COMPRESSION_HINT */
+      1891, /* GL_TEXTURE_RECTANGLE_ARB */
+      1786, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */
+      1388, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */
+       996, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */
        392, /* GL_DEPTH_STENCIL */
-      1934, /* GL_UNSIGNED_INT_24_8 */
-       996, /* GL_MAX_TEXTURE_LOD_BIAS */
-      1863, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */
-       998, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */
-      1835, /* GL_TEXTURE_FILTER_CONTROL */
-      1853, /* GL_TEXTURE_LOD_BIAS */
+      1957, /* GL_UNSIGNED_INT_24_8 */
+      1010, /* GL_MAX_TEXTURE_LOD_BIAS */
+      1880, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */
+      1012, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */
+      1852, /* GL_TEXTURE_FILTER_CONTROL */
+      1870, /* GL_TEXTURE_LOD_BIAS */
        245, /* GL_COMBINE4 */
-       990, /* GL_MAX_SHININESS_NV */
-       991, /* GL_MAX_SPOT_EXPONENT_NV */
-       677, /* GL_INCR_WRAP */
+      1004, /* GL_MAX_SHININESS_NV */
+      1005, /* GL_MAX_SPOT_EXPONENT_NV */
+       684, /* GL_INCR_WRAP */
        358, /* GL_DECR_WRAP */
-      1051, /* GL_MODELVIEW1_ARB */
-      1109, /* GL_NORMAL_MAP */
-      1410, /* GL_REFLECTION_MAP */
-      1807, /* GL_TEXTURE_CUBE_MAP */
-      1766, /* GL_TEXTURE_BINDING_CUBE_MAP */
-      1819, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
-      1809, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
-      1822, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
-      1812, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
-      1825, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
-      1815, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
-      1369, /* GL_PROXY_TEXTURE_CUBE_MAP */
-       935, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */
-      1087, /* GL_MULTISAMPLE_FILTER_HINT_NV */
+      1067, /* GL_MODELVIEW1_ARB */
+      1125, /* GL_NORMAL_MAP */
+      1427, /* GL_REFLECTION_MAP */
+      1824, /* GL_TEXTURE_CUBE_MAP */
+      1783, /* GL_TEXTURE_BINDING_CUBE_MAP */
+      1836, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
+      1826, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
+      1839, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
+      1829, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
+      1842, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
+      1832, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
+      1386, /* GL_PROXY_TEXTURE_CUBE_MAP */
+       944, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */
+      1103, /* GL_MULTISAMPLE_FILTER_HINT_NV */
        550, /* GL_FOG_DISTANCE_MODE_NV */
        499, /* GL_EYE_RADIAL_NV */
        498, /* GL_EYE_PLANE_ABSOLUTE_NV */
        244, /* GL_COMBINE */
        251, /* GL_COMBINE_RGB */
        246, /* GL_COMBINE_ALPHA */
-      1499, /* GL_RGB_SCALE */
+      1516, /* GL_RGB_SCALE */
         24, /* GL_ADD_SIGNED */
-       706, /* GL_INTERPOLATE */
+       713, /* GL_INTERPOLATE */
        284, /* GL_CONSTANT */
-      1313, /* GL_PRIMARY_COLOR */
-      1310, /* GL_PREVIOUS */
-      1575, /* GL_SOURCE0_RGB */
-      1581, /* GL_SOURCE1_RGB */
-      1587, /* GL_SOURCE2_RGB */
-      1591, /* GL_SOURCE3_RGB_NV */
-      1572, /* GL_SOURCE0_ALPHA */
-      1578, /* GL_SOURCE1_ALPHA */
-      1584, /* GL_SOURCE2_ALPHA */
-      1590, /* GL_SOURCE3_ALPHA_NV */
-      1149, /* GL_OPERAND0_RGB */
-      1155, /* GL_OPERAND1_RGB */
-      1161, /* GL_OPERAND2_RGB */
-      1165, /* GL_OPERAND3_RGB_NV */
-      1146, /* GL_OPERAND0_ALPHA */
-      1152, /* GL_OPERAND1_ALPHA */
-      1158, /* GL_OPERAND2_ALPHA */
-      1164, /* GL_OPERAND3_ALPHA_NV */
+      1329, /* GL_PRIMARY_COLOR */
+      1326, /* GL_PREVIOUS */
+      1592, /* GL_SOURCE0_RGB */
+      1598, /* GL_SOURCE1_RGB */
+      1604, /* GL_SOURCE2_RGB */
+      1608, /* GL_SOURCE3_RGB_NV */
+      1589, /* GL_SOURCE0_ALPHA */
+      1595, /* GL_SOURCE1_ALPHA */
+      1601, /* GL_SOURCE2_ALPHA */
+      1607, /* GL_SOURCE3_ALPHA_NV */
+      1165, /* GL_OPERAND0_RGB */
+      1171, /* GL_OPERAND1_RGB */
+      1177, /* GL_OPERAND2_RGB */
+      1181, /* GL_OPERAND3_RGB_NV */
+      1162, /* GL_OPERAND0_ALPHA */
+      1168, /* GL_OPERAND1_ALPHA */
+      1174, /* GL_OPERAND2_ALPHA */
+      1180, /* GL_OPERAND3_ALPHA_NV */
        120, /* GL_BUFFER_OBJECT_APPLE */
-      1963, /* GL_VERTEX_ARRAY_BINDING */
-      1872, /* GL_TEXTURE_RANGE_LENGTH_APPLE */
-      1873, /* GL_TEXTURE_RANGE_POINTER_APPLE */
-      2037, /* GL_YCBCR_422_APPLE */
-      1952, /* GL_UNSIGNED_SHORT_8_8_APPLE */
-      1954, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */
-      1882, /* GL_TEXTURE_STORAGE_HINT_APPLE */
-      1660, /* GL_STORAGE_PRIVATE_APPLE */
-      1659, /* GL_STORAGE_CACHED_APPLE */
-      1661, /* GL_STORAGE_SHARED_APPLE */
-      1562, /* GL_SLICE_ACCUM_SUN */
-      1379, /* GL_QUAD_MESH_SUN */
-      1915, /* GL_TRIANGLE_MESH_SUN */
-      2002, /* GL_VERTEX_PROGRAM_ARB */
-      2013, /* GL_VERTEX_STATE_PROGRAM_NV */
-      1989, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */
-      1995, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */
-      1997, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */
-      1999, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */
+      1986, /* GL_VERTEX_ARRAY_BINDING */
+      1889, /* GL_TEXTURE_RANGE_LENGTH_APPLE */
+      1890, /* GL_TEXTURE_RANGE_POINTER_APPLE */
+      2060, /* GL_YCBCR_422_APPLE */
+      1975, /* GL_UNSIGNED_SHORT_8_8_APPLE */
+      1977, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */
+      1899, /* GL_TEXTURE_STORAGE_HINT_APPLE */
+      1677, /* GL_STORAGE_PRIVATE_APPLE */
+      1676, /* GL_STORAGE_CACHED_APPLE */
+      1678, /* GL_STORAGE_SHARED_APPLE */
+      1579, /* GL_SLICE_ACCUM_SUN */
+      1396, /* GL_QUAD_MESH_SUN */
+      1937, /* GL_TRIANGLE_MESH_SUN */
+      2025, /* GL_VERTEX_PROGRAM_ARB */
+      2036, /* GL_VERTEX_STATE_PROGRAM_NV */
+      2012, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */
+      2018, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */
+      2020, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */
+      2022, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */
        349, /* GL_CURRENT_VERTEX_ATTRIB */
-      1329, /* GL_PROGRAM_LENGTH_ARB */
-      1343, /* GL_PROGRAM_STRING_ARB */
-      1074, /* GL_MODELVIEW_PROJECTION_NV */
-       670, /* GL_IDENTITY_NV */
-       722, /* GL_INVERSE_NV */
-      1908, /* GL_TRANSPOSE_NV */
-       723, /* GL_INVERSE_TRANSPOSE_NV */
-       968, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */
-       967, /* GL_MAX_PROGRAM_MATRICES_ARB */
-       863, /* GL_MATRIX0_NV */
-       875, /* GL_MATRIX1_NV */
-       887, /* GL_MATRIX2_NV */
-       891, /* GL_MATRIX3_NV */
-       893, /* GL_MATRIX4_NV */
-       895, /* GL_MATRIX5_NV */
-       897, /* GL_MATRIX6_NV */
-       899, /* GL_MATRIX7_NV */
+      1345, /* GL_PROGRAM_LENGTH_ARB */
+      1360, /* GL_PROGRAM_STRING_ARB */
+      1090, /* GL_MODELVIEW_PROJECTION_NV */
+       677, /* GL_IDENTITY_NV */
+       729, /* GL_INVERSE_NV */
+      1929, /* GL_TRANSPOSE_NV */
+       730, /* GL_INVERSE_TRANSPOSE_NV */
+       982, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */
+       981, /* GL_MAX_PROGRAM_MATRICES_ARB */
+       872, /* GL_MATRIX0_NV */
+       884, /* GL_MATRIX1_NV */
+       896, /* GL_MATRIX2_NV */
+       900, /* GL_MATRIX3_NV */
+       902, /* GL_MATRIX4_NV */
+       904, /* GL_MATRIX5_NV */
+       906, /* GL_MATRIX6_NV */
+       908, /* GL_MATRIX7_NV */
        332, /* GL_CURRENT_MATRIX_STACK_DEPTH_ARB */
        329, /* GL_CURRENT_MATRIX_ARB */
-      2005, /* GL_VERTEX_PROGRAM_POINT_SIZE */
-      2008, /* GL_VERTEX_PROGRAM_TWO_SIDE */
-      1341, /* GL_PROGRAM_PARAMETER_NV */
-      1993, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */
-      1345, /* GL_PROGRAM_TARGET_NV */
-      1342, /* GL_PROGRAM_RESIDENT_NV */
-      1892, /* GL_TRACK_MATRIX_NV */
-      1893, /* GL_TRACK_MATRIX_TRANSFORM_NV */
-      2003, /* GL_VERTEX_PROGRAM_BINDING_NV */
-      1323, /* GL_PROGRAM_ERROR_POSITION_ARB */
+      2028, /* GL_VERTEX_PROGRAM_POINT_SIZE */
+      2031, /* GL_VERTEX_PROGRAM_TWO_SIDE */
+      1357, /* GL_PROGRAM_PARAMETER_NV */
+      2016, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */
+      1362, /* GL_PROGRAM_TARGET_NV */
+      1359, /* GL_PROGRAM_RESIDENT_NV */
+      1909, /* GL_TRACK_MATRIX_NV */
+      1910, /* GL_TRACK_MATRIX_TRANSFORM_NV */
+      2026, /* GL_VERTEX_PROGRAM_BINDING_NV */
+      1339, /* GL_PROGRAM_ERROR_POSITION_ARB */
        373, /* GL_DEPTH_CLAMP */
-      1971, /* GL_VERTEX_ATTRIB_ARRAY0_NV */
-      1978, /* GL_VERTEX_ATTRIB_ARRAY1_NV */
-      1979, /* GL_VERTEX_ATTRIB_ARRAY2_NV */
-      1980, /* GL_VERTEX_ATTRIB_ARRAY3_NV */
-      1981, /* GL_VERTEX_ATTRIB_ARRAY4_NV */
-      1982, /* GL_VERTEX_ATTRIB_ARRAY5_NV */
-      1983, /* GL_VERTEX_ATTRIB_ARRAY6_NV */
-      1984, /* GL_VERTEX_ATTRIB_ARRAY7_NV */
-      1985, /* GL_VERTEX_ATTRIB_ARRAY8_NV */
-      1986, /* GL_VERTEX_ATTRIB_ARRAY9_NV */
-      1972, /* GL_VERTEX_ATTRIB_ARRAY10_NV */
-      1973, /* GL_VERTEX_ATTRIB_ARRAY11_NV */
-      1974, /* GL_VERTEX_ATTRIB_ARRAY12_NV */
-      1975, /* GL_VERTEX_ATTRIB_ARRAY13_NV */
-      1976, /* GL_VERTEX_ATTRIB_ARRAY14_NV */
-      1977, /* GL_VERTEX_ATTRIB_ARRAY15_NV */
-       811, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */
-       818, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */
-       819, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */
-       820, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */
-       821, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */
-       822, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */
-       823, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */
-       824, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */
-       825, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */
-       826, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */
-       812, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */
-       813, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */
-       814, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */
-       815, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */
-       816, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */
-       817, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */
-       838, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */
-       845, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */
-       846, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */
-       847, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */
-       848, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */
-       849, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */
-       850, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */
-      1322, /* GL_PROGRAM_BINDING_ARB */
-       852, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */
-       853, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */
-       839, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */
-       840, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */
-       841, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */
-       842, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */
-       843, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */
-       844, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */
-      1795, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */
-      1792, /* GL_TEXTURE_COMPRESSED */
-      1115, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */
+      1994, /* GL_VERTEX_ATTRIB_ARRAY0_NV */
+      2001, /* GL_VERTEX_ATTRIB_ARRAY1_NV */
+      2002, /* GL_VERTEX_ATTRIB_ARRAY2_NV */
+      2003, /* GL_VERTEX_ATTRIB_ARRAY3_NV */
+      2004, /* GL_VERTEX_ATTRIB_ARRAY4_NV */
+      2005, /* GL_VERTEX_ATTRIB_ARRAY5_NV */
+      2006, /* GL_VERTEX_ATTRIB_ARRAY6_NV */
+      2007, /* GL_VERTEX_ATTRIB_ARRAY7_NV */
+      2008, /* GL_VERTEX_ATTRIB_ARRAY8_NV */
+      2009, /* GL_VERTEX_ATTRIB_ARRAY9_NV */
+      1995, /* GL_VERTEX_ATTRIB_ARRAY10_NV */
+      1996, /* GL_VERTEX_ATTRIB_ARRAY11_NV */
+      1997, /* GL_VERTEX_ATTRIB_ARRAY12_NV */
+      1998, /* GL_VERTEX_ATTRIB_ARRAY13_NV */
+      1999, /* GL_VERTEX_ATTRIB_ARRAY14_NV */
+      2000, /* GL_VERTEX_ATTRIB_ARRAY15_NV */
+       820, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */
+       827, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */
+       828, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */
+       829, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */
+       830, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */
+       831, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */
+       832, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */
+       833, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */
+       834, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */
+       835, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */
+       821, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */
+       822, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */
+       823, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */
+       824, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */
+       825, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */
+       826, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */
+       847, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */
+       854, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */
+       855, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */
+       856, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */
+       857, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */
+       858, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */
+       859, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */
+      1338, /* GL_PROGRAM_BINDING_ARB */
+       861, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */
+       862, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */
+       848, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */
+       849, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */
+       850, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */
+       851, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */
+       852, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */
+       853, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */
+      1812, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */
+      1809, /* GL_TEXTURE_COMPRESSED */
+      1131, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */
        282, /* GL_COMPRESSED_TEXTURE_FORMATS */
-      1018, /* GL_MAX_VERTEX_UNITS_ARB */
+      1033, /* GL_MAX_VERTEX_UNITS_ARB */
         22, /* GL_ACTIVE_VERTEX_UNITS_ARB */
-      2031, /* GL_WEIGHT_SUM_UNITY_ARB */
-      2001, /* GL_VERTEX_BLEND_ARB */
+      2054, /* GL_WEIGHT_SUM_UNITY_ARB */
+      2024, /* GL_VERTEX_BLEND_ARB */
        351, /* GL_CURRENT_WEIGHT_ARB */
-      2029, /* GL_WEIGHT_ARRAY_TYPE_ARB */
-      2027, /* GL_WEIGHT_ARRAY_STRIDE_ARB */
-      2025, /* GL_WEIGHT_ARRAY_SIZE_ARB */
-      2023, /* GL_WEIGHT_ARRAY_POINTER_ARB */
-      2018, /* GL_WEIGHT_ARRAY_ARB */
+      2052, /* GL_WEIGHT_ARRAY_TYPE_ARB */
+      2050, /* GL_WEIGHT_ARRAY_STRIDE_ARB */
+      2048, /* GL_WEIGHT_ARRAY_SIZE_ARB */
+      2046, /* GL_WEIGHT_ARRAY_POINTER_ARB */
+      2041, /* GL_WEIGHT_ARRAY_ARB */
        407, /* GL_DOT3_RGB */
        408, /* GL_DOT3_RGBA */
        276, /* GL_COMPRESSED_RGB_FXT1_3DFX */
        271, /* GL_COMPRESSED_RGBA_FXT1_3DFX */
-      1082, /* GL_MULTISAMPLE_3DFX */
-      1521, /* GL_SAMPLE_BUFFERS_3DFX */
-      1512, /* GL_SAMPLES_3DFX */
-      1062, /* GL_MODELVIEW2_ARB */
-      1065, /* GL_MODELVIEW3_ARB */
-      1066, /* GL_MODELVIEW4_ARB */
-      1067, /* GL_MODELVIEW5_ARB */
-      1068, /* GL_MODELVIEW6_ARB */
-      1069, /* GL_MODELVIEW7_ARB */
-      1070, /* GL_MODELVIEW8_ARB */
-      1071, /* GL_MODELVIEW9_ARB */
-      1041, /* GL_MODELVIEW10_ARB */
-      1042, /* GL_MODELVIEW11_ARB */
-      1043, /* GL_MODELVIEW12_ARB */
-      1044, /* GL_MODELVIEW13_ARB */
-      1045, /* GL_MODELVIEW14_ARB */
-      1046, /* GL_MODELVIEW15_ARB */
-      1047, /* GL_MODELVIEW16_ARB */
-      1048, /* GL_MODELVIEW17_ARB */
-      1049, /* GL_MODELVIEW18_ARB */
-      1050, /* GL_MODELVIEW19_ARB */
-      1052, /* GL_MODELVIEW20_ARB */
-      1053, /* GL_MODELVIEW21_ARB */
-      1054, /* GL_MODELVIEW22_ARB */
-      1055, /* GL_MODELVIEW23_ARB */
-      1056, /* GL_MODELVIEW24_ARB */
-      1057, /* GL_MODELVIEW25_ARB */
-      1058, /* GL_MODELVIEW26_ARB */
-      1059, /* GL_MODELVIEW27_ARB */
-      1060, /* GL_MODELVIEW28_ARB */
-      1061, /* GL_MODELVIEW29_ARB */
-      1063, /* GL_MODELVIEW30_ARB */
-      1064, /* GL_MODELVIEW31_ARB */
+      1098, /* GL_MULTISAMPLE_3DFX */
+      1538, /* GL_SAMPLE_BUFFERS_3DFX */
+      1529, /* GL_SAMPLES_3DFX */
+      1078, /* GL_MODELVIEW2_ARB */
+      1081, /* GL_MODELVIEW3_ARB */
+      1082, /* GL_MODELVIEW4_ARB */
+      1083, /* GL_MODELVIEW5_ARB */
+      1084, /* GL_MODELVIEW6_ARB */
+      1085, /* GL_MODELVIEW7_ARB */
+      1086, /* GL_MODELVIEW8_ARB */
+      1087, /* GL_MODELVIEW9_ARB */
+      1057, /* GL_MODELVIEW10_ARB */
+      1058, /* GL_MODELVIEW11_ARB */
+      1059, /* GL_MODELVIEW12_ARB */
+      1060, /* GL_MODELVIEW13_ARB */
+      1061, /* GL_MODELVIEW14_ARB */
+      1062, /* GL_MODELVIEW15_ARB */
+      1063, /* GL_MODELVIEW16_ARB */
+      1064, /* GL_MODELVIEW17_ARB */
+      1065, /* GL_MODELVIEW18_ARB */
+      1066, /* GL_MODELVIEW19_ARB */
+      1068, /* GL_MODELVIEW20_ARB */
+      1069, /* GL_MODELVIEW21_ARB */
+      1070, /* GL_MODELVIEW22_ARB */
+      1071, /* GL_MODELVIEW23_ARB */
+      1072, /* GL_MODELVIEW24_ARB */
+      1073, /* GL_MODELVIEW25_ARB */
+      1074, /* GL_MODELVIEW26_ARB */
+      1075, /* GL_MODELVIEW27_ARB */
+      1076, /* GL_MODELVIEW28_ARB */
+      1077, /* GL_MODELVIEW29_ARB */
+      1079, /* GL_MODELVIEW30_ARB */
+      1080, /* GL_MODELVIEW31_ARB */
        412, /* GL_DOT3_RGB_EXT */
        410, /* GL_DOT3_RGBA_EXT */
-      1035, /* GL_MIRROR_CLAMP_EXT */
-      1038, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */
-      1077, /* GL_MODULATE_ADD_ATI */
-      1078, /* GL_MODULATE_SIGNED_ADD_ATI */
-      1079, /* GL_MODULATE_SUBTRACT_ATI */
-      2038, /* GL_YCBCR_MESA */
-      1173, /* GL_PACK_INVERT_MESA */
+      1051, /* GL_MIRROR_CLAMP_EXT */
+      1054, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */
+      1093, /* GL_MODULATE_ADD_ATI */
+      1094, /* GL_MODULATE_SIGNED_ADD_ATI */
+      1095, /* GL_MODULATE_SUBTRACT_ATI */
+      2061, /* GL_YCBCR_MESA */
+      1189, /* GL_PACK_INVERT_MESA */
        354, /* GL_DEBUG_OBJECT_MESA */
        355, /* GL_DEBUG_PRINT_MESA */
        353, /* GL_DEBUG_ASSERT_MESA */
@@ -5129,26 +5179,26 @@ static const unsigned reduced_enums[1402] =
        471, /* GL_DU8DV8_ATI */
        126, /* GL_BUMP_ENVMAP_ATI */
        130, /* GL_BUMP_TARGET_ATI */
-      1117, /* GL_NUM_PROGRAM_BINARY_FORMATS_OES */
-      1320, /* GL_PROGRAM_BINARY_FORMATS_OES */
-      1624, /* GL_STENCIL_BACK_FUNC */
-      1622, /* GL_STENCIL_BACK_FAIL */
-      1626, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */
-      1628, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */
+      1133, /* GL_NUM_PROGRAM_BINARY_FORMATS_OES */
+      1336, /* GL_PROGRAM_BINARY_FORMATS_OES */
+      1641, /* GL_STENCIL_BACK_FUNC */
+      1639, /* GL_STENCIL_BACK_FAIL */
+      1643, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */
+      1645, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */
        559, /* GL_FRAGMENT_PROGRAM_ARB */
-      1318, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */
-      1348, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */
-      1347, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */
-      1332, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
-      1338, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
-      1337, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
-       957, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */
-       980, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */
-       979, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */
-       970, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
-       976, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
-       975, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
-       938, /* GL_MAX_DRAW_BUFFERS */
+      1334, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */
+      1365, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */
+      1364, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */
+      1348, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
+      1354, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
+      1353, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
+       971, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */
+       994, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */
+       993, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */
+       984, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
+       990, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
+       989, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
+       947, /* GL_MAX_DRAW_BUFFERS */
        416, /* GL_DRAW_BUFFER0 */
        419, /* GL_DRAW_BUFFER1 */
        440, /* GL_DRAW_BUFFER2 */
@@ -5166,172 +5216,172 @@ static const unsigned reduced_enums[1402] =
        432, /* GL_DRAW_BUFFER14 */
        435, /* GL_DRAW_BUFFER15 */
         85, /* GL_BLEND_EQUATION_ALPHA */
-       914, /* GL_MATRIX_PALETTE_ARB */
-       950, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */
-       953, /* GL_MAX_PALETTE_MATRICES_ARB */
+       923, /* GL_MATRIX_PALETTE_ARB */
+       964, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */
+       967, /* GL_MAX_PALETTE_MATRICES_ARB */
        335, /* GL_CURRENT_PALETTE_MATRIX_ARB */
-       902, /* GL_MATRIX_INDEX_ARRAY_ARB */
+       911, /* GL_MATRIX_INDEX_ARRAY_ARB */
        330, /* GL_CURRENT_MATRIX_INDEX_ARB */
-       907, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */
-       911, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */
-       909, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */
-       905, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */
-      1830, /* GL_TEXTURE_DEPTH_SIZE */
+       916, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */
+       920, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */
+       918, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */
+       914, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */
+      1847, /* GL_TEXTURE_DEPTH_SIZE */
        400, /* GL_DEPTH_TEXTURE_MODE */
-      1787, /* GL_TEXTURE_COMPARE_MODE */
-      1785, /* GL_TEXTURE_COMPARE_FUNC */
+      1804, /* GL_TEXTURE_COMPARE_MODE */
+      1802, /* GL_TEXTURE_COMPARE_FUNC */
        255, /* GL_COMPARE_R_TO_TEXTURE */
-      1250, /* GL_POINT_SPRITE */
+      1266, /* GL_POINT_SPRITE */
        309, /* GL_COORD_REPLACE */
-      1255, /* GL_POINT_SPRITE_R_MODE_NV */
-      1383, /* GL_QUERY_COUNTER_BITS */
+      1271, /* GL_POINT_SPRITE_R_MODE_NV */
+      1400, /* GL_QUERY_COUNTER_BITS */
        338, /* GL_CURRENT_QUERY */
-      1386, /* GL_QUERY_RESULT */
-      1388, /* GL_QUERY_RESULT_AVAILABLE */
-      1011, /* GL_MAX_VERTEX_ATTRIBS */
-      1991, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */
+      1403, /* GL_QUERY_RESULT */
+      1405, /* GL_QUERY_RESULT_AVAILABLE */
+      1026, /* GL_MAX_VERTEX_ATTRIBS */
+      2014, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */
        398, /* GL_DEPTH_STENCIL_TO_RGBA_NV */
        397, /* GL_DEPTH_STENCIL_TO_BGRA_NV */
-       992, /* GL_MAX_TEXTURE_COORDS */
-       994, /* GL_MAX_TEXTURE_IMAGE_UNITS */
-      1325, /* GL_PROGRAM_ERROR_STRING_ARB */
-      1327, /* GL_PROGRAM_FORMAT_ASCII_ARB */
-      1326, /* GL_PROGRAM_FORMAT_ARB */
-      1884, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */
+      1006, /* GL_MAX_TEXTURE_COORDS */
+      1008, /* GL_MAX_TEXTURE_IMAGE_UNITS */
+      1341, /* GL_PROGRAM_ERROR_STRING_ARB */
+      1343, /* GL_PROGRAM_FORMAT_ASCII_ARB */
+      1342, /* GL_PROGRAM_FORMAT_ARB */
+      1901, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */
        371, /* GL_DEPTH_BOUNDS_TEST_EXT */
        370, /* GL_DEPTH_BOUNDS_EXT */
         53, /* GL_ARRAY_BUFFER */
        485, /* GL_ELEMENT_ARRAY_BUFFER */
         54, /* GL_ARRAY_BUFFER_BINDING */
        486, /* GL_ELEMENT_ARRAY_BUFFER_BINDING */
-      1965, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
-      1104, /* GL_NORMAL_ARRAY_BUFFER_BINDING */
+      1988, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
+      1120, /* GL_NORMAL_ARRAY_BUFFER_BINDING */
        161, /* GL_COLOR_ARRAY_BUFFER_BINDING */
-       681, /* GL_INDEX_ARRAY_BUFFER_BINDING */
-      1800, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
+       688, /* GL_INDEX_ARRAY_BUFFER_BINDING */
+      1817, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
        481, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING */
-      1533, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */
+      1550, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */
        537, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING */
-      2019, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */
-      1987, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */
-      1328, /* GL_PROGRAM_INSTRUCTIONS_ARB */
-       963, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */
-      1334, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
-       972, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
-      1346, /* GL_PROGRAM_TEMPORARIES_ARB */
-       978, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
-      1336, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */
-       974, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */
-      1340, /* GL_PROGRAM_PARAMETERS_ARB */
-       977, /* GL_MAX_PROGRAM_PARAMETERS_ARB */
-      1335, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */
-       973, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */
-      1319, /* GL_PROGRAM_ATTRIBS_ARB */
-       958, /* GL_MAX_PROGRAM_ATTRIBS_ARB */
-      1333, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */
-       971, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */
-      1317, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */
-       956, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */
-      1331, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
-       969, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
-       964, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */
-       960, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */
-      1349, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */
-      1905, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */
-      1400, /* GL_READ_ONLY */
-      2033, /* GL_WRITE_ONLY */
-      1402, /* GL_READ_WRITE */
+      2042, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */
+      2010, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */
+      1344, /* GL_PROGRAM_INSTRUCTIONS_ARB */
+       977, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */
+      1350, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
+       986, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
+      1363, /* GL_PROGRAM_TEMPORARIES_ARB */
+       992, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
+      1352, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */
+       988, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */
+      1356, /* GL_PROGRAM_PARAMETERS_ARB */
+       991, /* GL_MAX_PROGRAM_PARAMETERS_ARB */
+      1351, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */
+       987, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */
+      1335, /* GL_PROGRAM_ATTRIBS_ARB */
+       972, /* GL_MAX_PROGRAM_ATTRIBS_ARB */
+      1349, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */
+       985, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */
+      1333, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */
+       970, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */
+      1347, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
+       983, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
+       978, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */
+       974, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */
+      1366, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */
+      1926, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */
+      1417, /* GL_READ_ONLY */
+      2056, /* GL_WRITE_ONLY */
+      1419, /* GL_READ_WRITE */
        110, /* GL_BUFFER_ACCESS */
        114, /* GL_BUFFER_MAPPED */
        117, /* GL_BUFFER_MAP_POINTER */
-      1891, /* GL_TIME_ELAPSED_EXT */
-       862, /* GL_MATRIX0_ARB */
-       874, /* GL_MATRIX1_ARB */
-       886, /* GL_MATRIX2_ARB */
-       890, /* GL_MATRIX3_ARB */
-       892, /* GL_MATRIX4_ARB */
-       894, /* GL_MATRIX5_ARB */
-       896, /* GL_MATRIX6_ARB */
-       898, /* GL_MATRIX7_ARB */
-       900, /* GL_MATRIX8_ARB */
-       901, /* GL_MATRIX9_ARB */
-       864, /* GL_MATRIX10_ARB */
-       865, /* GL_MATRIX11_ARB */
-       866, /* GL_MATRIX12_ARB */
-       867, /* GL_MATRIX13_ARB */
-       868, /* GL_MATRIX14_ARB */
-       869, /* GL_MATRIX15_ARB */
-       870, /* GL_MATRIX16_ARB */
-       871, /* GL_MATRIX17_ARB */
-       872, /* GL_MATRIX18_ARB */
-       873, /* GL_MATRIX19_ARB */
-       876, /* GL_MATRIX20_ARB */
-       877, /* GL_MATRIX21_ARB */
-       878, /* GL_MATRIX22_ARB */
-       879, /* GL_MATRIX23_ARB */
-       880, /* GL_MATRIX24_ARB */
-       881, /* GL_MATRIX25_ARB */
-       882, /* GL_MATRIX26_ARB */
-       883, /* GL_MATRIX27_ARB */
-       884, /* GL_MATRIX28_ARB */
-       885, /* GL_MATRIX29_ARB */
-       888, /* GL_MATRIX30_ARB */
-       889, /* GL_MATRIX31_ARB */
-      1664, /* GL_STREAM_DRAW */
-      1666, /* GL_STREAM_READ */
-      1662, /* GL_STREAM_COPY */
-      1614, /* GL_STATIC_DRAW */
-      1616, /* GL_STATIC_READ */
-      1612, /* GL_STATIC_COPY */
+      1908, /* GL_TIME_ELAPSED_EXT */
+       871, /* GL_MATRIX0_ARB */
+       883, /* GL_MATRIX1_ARB */
+       895, /* GL_MATRIX2_ARB */
+       899, /* GL_MATRIX3_ARB */
+       901, /* GL_MATRIX4_ARB */
+       903, /* GL_MATRIX5_ARB */
+       905, /* GL_MATRIX6_ARB */
+       907, /* GL_MATRIX7_ARB */
+       909, /* GL_MATRIX8_ARB */
+       910, /* GL_MATRIX9_ARB */
+       873, /* GL_MATRIX10_ARB */
+       874, /* GL_MATRIX11_ARB */
+       875, /* GL_MATRIX12_ARB */
+       876, /* GL_MATRIX13_ARB */
+       877, /* GL_MATRIX14_ARB */
+       878, /* GL_MATRIX15_ARB */
+       879, /* GL_MATRIX16_ARB */
+       880, /* GL_MATRIX17_ARB */
+       881, /* GL_MATRIX18_ARB */
+       882, /* GL_MATRIX19_ARB */
+       885, /* GL_MATRIX20_ARB */
+       886, /* GL_MATRIX21_ARB */
+       887, /* GL_MATRIX22_ARB */
+       888, /* GL_MATRIX23_ARB */
+       889, /* GL_MATRIX24_ARB */
+       890, /* GL_MATRIX25_ARB */
+       891, /* GL_MATRIX26_ARB */
+       892, /* GL_MATRIX27_ARB */
+       893, /* GL_MATRIX28_ARB */
+       894, /* GL_MATRIX29_ARB */
+       897, /* GL_MATRIX30_ARB */
+       898, /* GL_MATRIX31_ARB */
+      1681, /* GL_STREAM_DRAW */
+      1683, /* GL_STREAM_READ */
+      1679, /* GL_STREAM_COPY */
+      1631, /* GL_STATIC_DRAW */
+      1633, /* GL_STATIC_READ */
+      1629, /* GL_STATIC_COPY */
        475, /* GL_DYNAMIC_DRAW */
        477, /* GL_DYNAMIC_READ */
        473, /* GL_DYNAMIC_COPY */
-      1213, /* GL_PIXEL_PACK_BUFFER */
-      1217, /* GL_PIXEL_UNPACK_BUFFER */
-      1214, /* GL_PIXEL_PACK_BUFFER_BINDING */
-      1218, /* GL_PIXEL_UNPACK_BUFFER_BINDING */
+      1229, /* GL_PIXEL_PACK_BUFFER */
+      1233, /* GL_PIXEL_UNPACK_BUFFER */
+      1230, /* GL_PIXEL_PACK_BUFFER_BINDING */
+      1234, /* GL_PIXEL_UNPACK_BUFFER_BINDING */
        362, /* GL_DEPTH24_STENCIL8 */
-      1880, /* GL_TEXTURE_STENCIL_SIZE */
-      1828, /* GL_TEXTURE_CUBE_MAP_SEAMLESS */
-       959, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */
-       962, /* GL_MAX_PROGRAM_IF_DEPTH_NV */
-       966, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */
-       965, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */
-       919, /* GL_MAX_ARRAY_TEXTURE_LAYERS_EXT */
-      1655, /* GL_STENCIL_TEST_TWO_SIDE_EXT */
+      1897, /* GL_TEXTURE_STENCIL_SIZE */
+      1845, /* GL_TEXTURE_CUBE_MAP_SEAMLESS */
+       973, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */
+       976, /* GL_MAX_PROGRAM_IF_DEPTH_NV */
+       980, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */
+       979, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */
+       928, /* GL_MAX_ARRAY_TEXTURE_LAYERS_EXT */
+      1672, /* GL_STENCIL_TEST_TWO_SIDE_EXT */
         17, /* GL_ACTIVE_STENCIL_FACE_EXT */
-      1036, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */
-      1514, /* GL_SAMPLES_PASSED */
-      1237, /* GL_POINT_SIZE_ARRAY_TYPE_OES */
-      1236, /* GL_POINT_SIZE_ARRAY_STRIDE_OES */
-      1235, /* GL_POINT_SIZE_ARRAY_POINTER_OES */
-      1073, /* GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES */
-      1352, /* GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES */
-      1862, /* GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES */
+      1052, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */
+      1531, /* GL_SAMPLES_PASSED */
+      1253, /* GL_POINT_SIZE_ARRAY_TYPE_OES */
+      1252, /* GL_POINT_SIZE_ARRAY_STRIDE_OES */
+      1251, /* GL_POINT_SIZE_ARRAY_POINTER_OES */
+      1089, /* GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES */
+      1369, /* GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES */
+      1879, /* GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES */
        121, /* GL_BUFFER_SERIALIZED_MODIFY_APPLE */
        113, /* GL_BUFFER_FLUSHING_UNMAP_APPLE */
-      1414, /* GL_RELEASED_APPLE */
-      2016, /* GL_VOLATILE_APPLE */
-      1453, /* GL_RETAINED_APPLE */
-      1918, /* GL_UNDEFINED_APPLE */
-      1373, /* GL_PURGEABLE_APPLE */
+      1431, /* GL_RELEASED_APPLE */
+      2039, /* GL_VOLATILE_APPLE */
+      1470, /* GL_RETAINED_APPLE */
+      1941, /* GL_UNDEFINED_APPLE */
+      1390, /* GL_PURGEABLE_APPLE */
        560, /* GL_FRAGMENT_SHADER */
-      2011, /* GL_VERTEX_SHADER */
-      1339, /* GL_PROGRAM_OBJECT_ARB */
-      1549, /* GL_SHADER_OBJECT_ARB */
-       945, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */
-      1015, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */
-      1008, /* GL_MAX_VARYING_FLOATS */
-      1013, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */
-       929, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */
-      1133, /* GL_OBJECT_TYPE_ARB */
-      1551, /* GL_SHADER_TYPE */
+      2034, /* GL_VERTEX_SHADER */
+      1355, /* GL_PROGRAM_OBJECT_ARB */
+      1566, /* GL_SHADER_OBJECT_ARB */
+       954, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */
+      1030, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */
+      1023, /* GL_MAX_VARYING_FLOATS */
+      1028, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */
+       938, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */
+      1149, /* GL_OBJECT_TYPE_ARB */
+      1568, /* GL_SHADER_TYPE */
        525, /* GL_FLOAT_VEC2 */
        527, /* GL_FLOAT_VEC3 */
        529, /* GL_FLOAT_VEC4 */
-       710, /* GL_INT_VEC2 */
-       712, /* GL_INT_VEC3 */
-       714, /* GL_INT_VEC4 */
+       717, /* GL_INT_VEC2 */
+       719, /* GL_INT_VEC3 */
+       721, /* GL_INT_VEC4 */
        102, /* GL_BOOL */
        104, /* GL_BOOL_VEC2 */
        106, /* GL_BOOL_VEC3 */
@@ -5339,12 +5389,12 @@ static const unsigned reduced_enums[1402] =
        513, /* GL_FLOAT_MAT2 */
        517, /* GL_FLOAT_MAT3 */
        521, /* GL_FLOAT_MAT4 */
-      1504, /* GL_SAMPLER_1D */
-      1506, /* GL_SAMPLER_2D */
-      1508, /* GL_SAMPLER_3D */
-      1510, /* GL_SAMPLER_CUBE */
-      1505, /* GL_SAMPLER_1D_SHADOW */
-      1507, /* GL_SAMPLER_2D_SHADOW */
+      1521, /* GL_SAMPLER_1D */
+      1523, /* GL_SAMPLER_2D */
+      1525, /* GL_SAMPLER_3D */
+      1527, /* GL_SAMPLER_CUBE */
+      1522, /* GL_SAMPLER_1D_SHADOW */
+      1524, /* GL_SAMPLER_2D_SHADOW */
        515, /* GL_FLOAT_MAT2x3 */
        516, /* GL_FLOAT_MAT2x4 */
        519, /* GL_FLOAT_MAT3x2 */
@@ -5353,96 +5403,97 @@ static const unsigned reduced_enums[1402] =
        524, /* GL_FLOAT_MAT4x3 */
        360, /* GL_DELETE_STATUS */
        259, /* GL_COMPILE_STATUS */
-       767, /* GL_LINK_STATUS */
-      1959, /* GL_VALIDATE_STATUS */
-       693, /* GL_INFO_LOG_LENGTH */
+       776, /* GL_LINK_STATUS */
+      1982, /* GL_VALIDATE_STATUS */
+       700, /* GL_INFO_LOG_LENGTH */
         56, /* GL_ATTACHED_SHADERS */
         20, /* GL_ACTIVE_UNIFORMS */
         21, /* GL_ACTIVE_UNIFORM_MAX_LENGTH */
-      1550, /* GL_SHADER_SOURCE_LENGTH */
+      1567, /* GL_SHADER_SOURCE_LENGTH */
         15, /* GL_ACTIVE_ATTRIBUTES */
         16, /* GL_ACTIVE_ATTRIBUTE_MAX_LENGTH */
        562, /* GL_FRAGMENT_SHADER_DERIVATIVE_HINT */
-      1553, /* GL_SHADING_LANGUAGE_VERSION */
+      1570, /* GL_SHADING_LANGUAGE_VERSION */
        337, /* GL_CURRENT_PROGRAM */
-      1182, /* GL_PALETTE4_RGB8_OES */
-      1184, /* GL_PALETTE4_RGBA8_OES */
-      1180, /* GL_PALETTE4_R5_G6_B5_OES */
-      1183, /* GL_PALETTE4_RGBA4_OES */
-      1181, /* GL_PALETTE4_RGB5_A1_OES */
-      1187, /* GL_PALETTE8_RGB8_OES */
-      1189, /* GL_PALETTE8_RGBA8_OES */
-      1185, /* GL_PALETTE8_R5_G6_B5_OES */
-      1188, /* GL_PALETTE8_RGBA4_OES */
-      1186, /* GL_PALETTE8_RGB5_A1_OES */
-       675, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */
-       673, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */
-      1234, /* GL_POINT_SIZE_ARRAY_OES */
-      1806, /* GL_TEXTURE_CROP_RECT_OES */
-       903, /* GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES */
-      1233, /* GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES */
-      1942, /* GL_UNSIGNED_NORMALIZED */
-      1752, /* GL_TEXTURE_1D_ARRAY_EXT */
-      1362, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */
-      1754, /* GL_TEXTURE_2D_ARRAY_EXT */
-      1365, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */
-      1761, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */
-      1763, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */
-      1606, /* GL_SRGB */
-      1607, /* GL_SRGB8 */
-      1609, /* GL_SRGB_ALPHA */
-      1608, /* GL_SRGB8_ALPHA8 */
-      1566, /* GL_SLUMINANCE_ALPHA */
-      1565, /* GL_SLUMINANCE8_ALPHA8 */
-      1563, /* GL_SLUMINANCE */
-      1564, /* GL_SLUMINANCE8 */
+      1198, /* GL_PALETTE4_RGB8_OES */
+      1200, /* GL_PALETTE4_RGBA8_OES */
+      1196, /* GL_PALETTE4_R5_G6_B5_OES */
+      1199, /* GL_PALETTE4_RGBA4_OES */
+      1197, /* GL_PALETTE4_RGB5_A1_OES */
+      1203, /* GL_PALETTE8_RGB8_OES */
+      1205, /* GL_PALETTE8_RGBA8_OES */
+      1201, /* GL_PALETTE8_R5_G6_B5_OES */
+      1204, /* GL_PALETTE8_RGBA4_OES */
+      1202, /* GL_PALETTE8_RGB5_A1_OES */
+       682, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */
+       680, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */
+      1250, /* GL_POINT_SIZE_ARRAY_OES */
+      1823, /* GL_TEXTURE_CROP_RECT_OES */
+       912, /* GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES */
+      1249, /* GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES */
+      1965, /* GL_UNSIGNED_NORMALIZED */
+      1769, /* GL_TEXTURE_1D_ARRAY_EXT */
+      1379, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */
+      1771, /* GL_TEXTURE_2D_ARRAY_EXT */
+      1382, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */
+      1778, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */
+      1780, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */
+       958, /* GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB */
+      1623, /* GL_SRGB */
+      1624, /* GL_SRGB8 */
+      1626, /* GL_SRGB_ALPHA */
+      1625, /* GL_SRGB8_ALPHA8 */
+      1583, /* GL_SLUMINANCE_ALPHA */
+      1582, /* GL_SLUMINANCE8_ALPHA8 */
+      1580, /* GL_SLUMINANCE */
+      1581, /* GL_SLUMINANCE8 */
        280, /* GL_COMPRESSED_SRGB */
        281, /* GL_COMPRESSED_SRGB_ALPHA */
        278, /* GL_COMPRESSED_SLUMINANCE */
        279, /* GL_COMPRESSED_SLUMINANCE_ALPHA */
-      1902, /* GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT */
-      1897, /* GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT */
-      1007, /* GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT */
-      1901, /* GL_TRANSFORM_FEEDBACK_VARYINGS_EXT */
-      1899, /* GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT */
-      1898, /* GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT */
-      1316, /* GL_PRIMITIVES_GENERATED_EXT */
-      1900, /* GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT */
-      1393, /* GL_RASTERIZER_DISCARD_EXT */
-      1005, /* GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT */
-      1006, /* GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT */
-       705, /* GL_INTERLEAVED_ATTRIBS_EXT */
-      1543, /* GL_SEPARATE_ATTRIBS_EXT */
-      1896, /* GL_TRANSFORM_FEEDBACK_BUFFER_EXT */
-      1895, /* GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT */
-      1252, /* GL_POINT_SPRITE_COORD_ORIGIN */
-       775, /* GL_LOWER_LEFT */
-      1956, /* GL_UPPER_LEFT */
-      1630, /* GL_STENCIL_BACK_REF */
-      1631, /* GL_STENCIL_BACK_VALUE_MASK */
-      1632, /* GL_STENCIL_BACK_WRITEMASK */
+      1923, /* GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT */
+      1917, /* GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT */
+      1021, /* GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT */
+      1922, /* GL_TRANSFORM_FEEDBACK_VARYINGS_EXT */
+      1920, /* GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT */
+      1919, /* GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT */
+      1332, /* GL_PRIMITIVES_GENERATED_EXT */
+      1921, /* GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT */
+      1410, /* GL_RASTERIZER_DISCARD_EXT */
+      1019, /* GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT */
+      1020, /* GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT */
+       712, /* GL_INTERLEAVED_ATTRIBS_EXT */
+      1560, /* GL_SEPARATE_ATTRIBS_EXT */
+      1916, /* GL_TRANSFORM_FEEDBACK_BUFFER_EXT */
+      1915, /* GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT */
+      1268, /* GL_POINT_SPRITE_COORD_ORIGIN */
+       784, /* GL_LOWER_LEFT */
+      1979, /* GL_UPPER_LEFT */
+      1647, /* GL_STENCIL_BACK_REF */
+      1648, /* GL_STENCIL_BACK_VALUE_MASK */
+      1649, /* GL_STENCIL_BACK_WRITEMASK */
        465, /* GL_DRAW_FRAMEBUFFER_BINDING */
-      1419, /* GL_RENDERBUFFER_BINDING */
-      1396, /* GL_READ_FRAMEBUFFER */
+      1436, /* GL_RENDERBUFFER_BINDING */
+      1413, /* GL_READ_FRAMEBUFFER */
        464, /* GL_DRAW_FRAMEBUFFER */
-      1397, /* GL_READ_FRAMEBUFFER_BINDING */
-      1438, /* GL_RENDERBUFFER_SAMPLES */
-       574, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */
-       571, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */
-       586, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */
-       581, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */
-       584, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
-       592, /* GL_FRAMEBUFFER_COMPLETE */
-       597, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */
-       609, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */
-       606, /* GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT */
-       601, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT */
-       607, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT */
-       603, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER */
-       614, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER */
-       620, /* GL_FRAMEBUFFER_UNSUPPORTED */
-       618, /* GL_FRAMEBUFFER_STATUS_ERROR_EXT */
-       925, /* GL_MAX_COLOR_ATTACHMENTS */
+      1414, /* GL_READ_FRAMEBUFFER_BINDING */
+      1455, /* GL_RENDERBUFFER_SAMPLES */
+       575, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */
+       572, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */
+       587, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */
+       582, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */
+       585, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
+       593, /* GL_FRAMEBUFFER_COMPLETE */
+       598, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */
+       612, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */
+       607, /* GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT */
+       602, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT */
+       608, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT */
+       604, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER */
+       617, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER */
+       623, /* GL_FRAMEBUFFER_UNSUPPORTED */
+       621, /* GL_FRAMEBUFFER_STATUS_ERROR_EXT */
+       934, /* GL_MAX_COLOR_ATTACHMENTS */
        167, /* GL_COLOR_ATTACHMENT0 */
        170, /* GL_COLOR_ATTACHMENT1 */
        184, /* GL_COLOR_ATTACHMENT2 */
@@ -5460,75 +5511,91 @@ static const unsigned reduced_enums[1402] =
        179, /* GL_COLOR_ATTACHMENT14 */
        181, /* GL_COLOR_ATTACHMENT15 */
        365, /* GL_DEPTH_ATTACHMENT */
-      1619, /* GL_STENCIL_ATTACHMENT */
+      1636, /* GL_STENCIL_ATTACHMENT */
        564, /* GL_FRAMEBUFFER */
-      1416, /* GL_RENDERBUFFER */
-      1442, /* GL_RENDERBUFFER_WIDTH */
-      1429, /* GL_RENDERBUFFER_HEIGHT */
-      1432, /* GL_RENDERBUFFER_INTERNAL_FORMAT */
-      1650, /* GL_STENCIL_INDEX_EXT */
-      1639, /* GL_STENCIL_INDEX1 */
-      1644, /* GL_STENCIL_INDEX4 */
-      1647, /* GL_STENCIL_INDEX8 */
-      1640, /* GL_STENCIL_INDEX16 */
-      1436, /* GL_RENDERBUFFER_RED_SIZE */
-      1427, /* GL_RENDERBUFFER_GREEN_SIZE */
-      1422, /* GL_RENDERBUFFER_BLUE_SIZE */
-      1417, /* GL_RENDERBUFFER_ALPHA_SIZE */
-      1424, /* GL_RENDERBUFFER_DEPTH_SIZE */
-      1440, /* GL_RENDERBUFFER_STENCIL_SIZE */
-       612, /* GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */
-       987, /* GL_MAX_SAMPLES */
-      1842, /* GL_TEXTURE_GEN_STR_OES */
-       648, /* GL_HALF_FLOAT_OES */
-      1470, /* GL_RGB565_OES */
-       776, /* GL_LOW_FLOAT */
-      1021, /* GL_MEDIUM_FLOAT */
-       649, /* GL_HIGH_FLOAT */
-       777, /* GL_LOW_INT */
-      1022, /* GL_MEDIUM_INT */
-       650, /* GL_HIGH_INT */
-      1933, /* GL_UNSIGNED_INT_10_10_10_2_OES */
-       709, /* GL_INT_10_10_10_2_OES */
-      1547, /* GL_SHADER_BINARY_FORMATS */
-      1118, /* GL_NUM_SHADER_BINARY_FORMATS */
-      1548, /* GL_SHADER_COMPILER */
-      1017, /* GL_MAX_VERTEX_UNIFORM_VECTORS */
-      1010, /* GL_MAX_VARYING_VECTORS */
-       947, /* GL_MAX_FRAGMENT_UNIFORM_VECTORS */
-      1390, /* GL_QUERY_WAIT_NV */
-      1385, /* GL_QUERY_NO_WAIT_NV */
-      1382, /* GL_QUERY_BY_REGION_WAIT_NV */
-      1381, /* GL_QUERY_BY_REGION_NO_WAIT_NV */
-      1377, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */
+      1433, /* GL_RENDERBUFFER */
+      1459, /* GL_RENDERBUFFER_WIDTH */
+      1446, /* GL_RENDERBUFFER_HEIGHT */
+      1449, /* GL_RENDERBUFFER_INTERNAL_FORMAT */
+      1667, /* GL_STENCIL_INDEX_EXT */
+      1656, /* GL_STENCIL_INDEX1 */
+      1661, /* GL_STENCIL_INDEX4 */
+      1664, /* GL_STENCIL_INDEX8 */
+      1657, /* GL_STENCIL_INDEX16 */
+      1453, /* GL_RENDERBUFFER_RED_SIZE */
+      1444, /* GL_RENDERBUFFER_GREEN_SIZE */
+      1439, /* GL_RENDERBUFFER_BLUE_SIZE */
+      1434, /* GL_RENDERBUFFER_ALPHA_SIZE */
+      1441, /* GL_RENDERBUFFER_DEPTH_SIZE */
+      1457, /* GL_RENDERBUFFER_STENCIL_SIZE */
+       615, /* GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */
+      1001, /* GL_MAX_SAMPLES */
+      1859, /* GL_TEXTURE_GEN_STR_OES */
+       655, /* GL_HALF_FLOAT_OES */
+      1487, /* GL_RGB565_OES */
+       571, /* GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB */
+       611, /* GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB */
+       610, /* GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB */
+       646, /* GL_GEOMETRY_SHADER_ARB */
+       647, /* GL_GEOMETRY_VERTICES_OUT_ARB */
+       644, /* GL_GEOMETRY_INPUT_TYPE_ARB */
+       645, /* GL_GEOMETRY_OUTPUT_TYPE_ARB */
+       961, /* GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB */
+      1035, /* GL_MAX_VERTEX_VARYING_COMPONENTS_ARB */
+       960, /* GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB */
+       957, /* GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB */
+       959, /* GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB */
+       785, /* GL_LOW_FLOAT */
+      1037, /* GL_MEDIUM_FLOAT */
+       656, /* GL_HIGH_FLOAT */
+       786, /* GL_LOW_INT */
+      1038, /* GL_MEDIUM_INT */
+       657, /* GL_HIGH_INT */
+      1956, /* GL_UNSIGNED_INT_10_10_10_2_OES */
+       716, /* GL_INT_10_10_10_2_OES */
+      1564, /* GL_SHADER_BINARY_FORMATS */
+      1134, /* GL_NUM_SHADER_BINARY_FORMATS */
+      1565, /* GL_SHADER_COMPILER */
+      1032, /* GL_MAX_VERTEX_UNIFORM_VECTORS */
+      1025, /* GL_MAX_VARYING_VECTORS */
+       956, /* GL_MAX_FRAGMENT_UNIFORM_VECTORS */
+      1407, /* GL_QUERY_WAIT_NV */
+      1402, /* GL_QUERY_NO_WAIT_NV */
+      1399, /* GL_QUERY_BY_REGION_WAIT_NV */
+      1398, /* GL_QUERY_BY_REGION_NO_WAIT_NV */
+      1912, /* GL_TRANSFORM_FEEDBACK */
+      1918, /* GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED */
+      1914, /* GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE */
+      1913, /* GL_TRANSFORM_FEEDBACK_BINDING */
+      1394, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */
        507, /* GL_FIRST_VERTEX_CONVENTION */
-       726, /* GL_LAST_VERTEX_CONVENTION */
-      1354, /* GL_PROVOKING_VERTEX */
+       733, /* GL_LAST_VERTEX_CONVENTION */
+      1371, /* GL_PROVOKING_VERTEX */
        316, /* GL_COPY_READ_BUFFER */
        317, /* GL_COPY_WRITE_BUFFER */
-      1497, /* GL_RGBA_SNORM */
-      1493, /* GL_RGBA8_SNORM */
-      1559, /* GL_SIGNED_NORMALIZED */
-       989, /* GL_MAX_SERVER_WAIT_TIMEOUT */
-      1132, /* GL_OBJECT_TYPE */
-      1671, /* GL_SYNC_CONDITION */
-      1676, /* GL_SYNC_STATUS */
-      1673, /* GL_SYNC_FLAGS */
-      1672, /* GL_SYNC_FENCE */
-      1675, /* GL_SYNC_GPU_COMMANDS_COMPLETE */
-      1927, /* GL_UNSIGNALED */
-      1558, /* GL_SIGNALED */
+      1514, /* GL_RGBA_SNORM */
+      1510, /* GL_RGBA8_SNORM */
+      1576, /* GL_SIGNED_NORMALIZED */
+      1003, /* GL_MAX_SERVER_WAIT_TIMEOUT */
+      1148, /* GL_OBJECT_TYPE */
+      1688, /* GL_SYNC_CONDITION */
+      1693, /* GL_SYNC_STATUS */
+      1690, /* GL_SYNC_FLAGS */
+      1689, /* GL_SYNC_FENCE */
+      1692, /* GL_SYNC_GPU_COMMANDS_COMPLETE */
+      1950, /* GL_UNSIGNALED */
+      1575, /* GL_SIGNALED */
         46, /* GL_ALREADY_SIGNALED */
-      1890, /* GL_TIMEOUT_EXPIRED */
+      1907, /* GL_TIMEOUT_EXPIRED */
        283, /* GL_CONDITION_SATISFIED */
-      2017, /* GL_WAIT_FAILED */
+      2040, /* GL_WAIT_FAILED */
        492, /* GL_EVAL_BIT */
-      1394, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
-       769, /* GL_LIST_BIT */
-      1771, /* GL_TEXTURE_BIT */
-      1529, /* GL_SCISSOR_BIT */
+      1411, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
+       778, /* GL_LIST_BIT */
+      1788, /* GL_TEXTURE_BIT */
+      1546, /* GL_SCISSOR_BIT */
         29, /* GL_ALL_ATTRIB_BITS */
-      1084, /* GL_MULTISAMPLE_BIT */
+      1100, /* GL_MULTISAMPLE_BIT */
         30, /* GL_ALL_CLIENT_ATTRIB_BITS */
 };
 
@@ -5581,7 +5648,8 @@ const char *_mesa_lookup_enum_by_nr( int nr )
    }
    else {
       /* this is not re-entrant safe, no big deal here */
-      _mesa_snprintf(token_tmp, sizeof(token_tmp), "0x%x", nr);
+      _mesa_snprintf(token_tmp, sizeof(token_tmp) - 1, "0x%x", nr);
+      token_tmp[sizeof(token_tmp) - 1] = '\0';
       return token_tmp;
    }
 }
index 371ef3a39732398a5ff3eea55407f06c5e9524fb..19a1eebe6e9e6903be8cff3273b1083277cd1f8f 100644 (file)
@@ -44,9 +44,11 @@ static const struct {
    const char *name;
    int flag_offset;
 } default_extensions[] = {
+   { OFF, "GL_ARB_blend_func_extended",        F(ARB_blend_func_extended) },
    { OFF, "GL_ARB_copy_buffer",                F(ARB_copy_buffer) },
-   { OFF, "GL_ARB_depth_texture",              F(ARB_depth_texture) },
+   { OFF, "GL_ARB_depth_buffer_float",         F(ARB_depth_buffer_float) },
    { OFF, "GL_ARB_depth_clamp",                F(ARB_depth_clamp) },
+   { OFF, "GL_ARB_depth_texture",              F(ARB_depth_texture) },
    { ON,  "GL_ARB_draw_buffers",               F(ARB_draw_buffers) },
    { OFF, "GL_ARB_draw_elements_base_vertex",  F(ARB_draw_elements_base_vertex) },
    { OFF, "GL_ARB_draw_instanced",             F(ARB_draw_instanced) },
@@ -55,17 +57,22 @@ static const struct {
    { OFF, "GL_ARB_fragment_program_shadow",    F(ARB_fragment_program_shadow) },
    { OFF, "GL_ARB_fragment_shader",            F(ARB_fragment_shader) },
    { OFF, "GL_ARB_framebuffer_object",         F(ARB_framebuffer_object) },
+   { OFF, "GL_ARB_explicit_attrib_location",   F(ARB_explicit_attrib_location) },
+   { OFF, "GL_ARB_geometry_shader4",           F(ARB_geometry_shader4) },
    { OFF, "GL_ARB_half_float_pixel",           F(ARB_half_float_pixel) },
    { OFF, "GL_ARB_half_float_vertex",          F(ARB_half_float_vertex) },
    { OFF, "GL_ARB_imaging",                    F(ARB_imaging) },
+   { OFF, "GL_ARB_instanced_arrays",           F(ARB_instanced_arrays) },
    { OFF, "GL_ARB_map_buffer_range",           F(ARB_map_buffer_range) },
    { ON,  "GL_ARB_multisample",                F(ARB_multisample) },
    { OFF, "GL_ARB_multitexture",               F(ARB_multitexture) },
    { OFF, "GL_ARB_occlusion_query",            F(ARB_occlusion_query) },
+   { OFF, "GL_ARB_occlusion_query2",           F(ARB_occlusion_query2) },
    { OFF, "GL_ARB_pixel_buffer_object",        F(EXT_pixel_buffer_object) },
    { OFF, "GL_ARB_point_parameters",           F(EXT_point_parameters) },
    { OFF, "GL_ARB_point_sprite",               F(ARB_point_sprite) },
    { OFF, "GL_ARB_provoking_vertex",           F(EXT_provoking_vertex) },
+   { OFF, "GL_ARB_sampler_objects",            F(ARB_sampler_objects) },
    { OFF, "GL_ARB_seamless_cube_map",          F(ARB_seamless_cube_map) },
    { OFF, "GL_ARB_shader_objects",             F(ARB_shader_objects) },
    { OFF, "GL_ARB_shading_language_100",       F(ARB_shading_language_100) },
@@ -74,6 +81,7 @@ static const struct {
    { OFF, "GL_ARB_shadow_ambient",             F(ARB_shadow_ambient) },
    { OFF, "GL_ARB_sync",                       F(ARB_sync) },
    { OFF, "GL_ARB_texture_border_clamp",       F(ARB_texture_border_clamp) },
+   { OFF, "GL_ARB_texture_buffer_object",      F(ARB_texture_buffer_object) },
    { ON,  "GL_ARB_texture_compression",        F(ARB_texture_compression) },
    { OFF, "GL_ARB_texture_cube_map",           F(ARB_texture_cube_map) },
    { OFF, "GL_ARB_texture_env_add",            F(EXT_texture_env_add) },
@@ -82,16 +90,21 @@ static const struct {
    { OFF, "GL_ARB_texture_env_dot3",           F(ARB_texture_env_dot3) },
    { OFF, "GL_MESAX_texture_float",            F(ARB_texture_float) },
    { OFF, "GL_ARB_texture_mirrored_repeat",    F(ARB_texture_mirrored_repeat)},
+   { OFF, "GL_ARB_texture_multisample",        F(ARB_texture_multisample) },
    { OFF, "GL_ARB_texture_non_power_of_two",   F(ARB_texture_non_power_of_two)},
    { OFF, "GL_ARB_texture_rectangle",          F(NV_texture_rectangle) },
+   { OFF, "GL_ARB_texture_rg",                 F(ARB_texture_rg) },
+   { OFF, "GL_ARB_texture_rgb10_a2ui",         F(ARB_texture_rgb10_a2ui) },
    { OFF, "GL_ARB_texture_swizzle",            F(EXT_texture_swizzle) },
    { ON,  "GL_ARB_transpose_matrix",           F(ARB_transpose_matrix) },
    { OFF, "GL_ARB_transform_feedback2",        F(ARB_transform_feedback2) },
+   { OFF, "GL_ARB_uniform_buffer_object",      F(ARB_uniform_buffer_object) },
    { OFF, "GL_ARB_vertex_array_bgra",          F(EXT_vertex_array_bgra) },
    { OFF, "GL_ARB_vertex_array_object",        F(ARB_vertex_array_object) },
    { ON,  "GL_ARB_vertex_buffer_object",       F(ARB_vertex_buffer_object) },
    { OFF, "GL_ARB_vertex_program",             F(ARB_vertex_program) },
    { OFF, "GL_ARB_vertex_shader",              F(ARB_vertex_shader) },
+   { OFF, "GL_ARB_vertex_type_2_10_10_10_rev", F(ARB_vertex_type_2_10_10_10_rev) },
    { ON,  "GL_ARB_window_pos",                 F(ARB_window_pos) },
    { ON,  "GL_EXT_abgr",                       F(EXT_abgr) },
    { ON,  "GL_EXT_bgra",                       F(EXT_bgra) },
@@ -113,11 +126,13 @@ static const struct {
    { OFF, "GL_EXT_framebuffer_blit",           F(EXT_framebuffer_blit) },
    { OFF, "GL_EXT_framebuffer_multisample",    F(EXT_framebuffer_multisample) },
    { OFF, "GL_EXT_framebuffer_object",         F(EXT_framebuffer_object) },
+   { OFF, "GL_EXT_framebuffer_sRGB",           F(EXT_framebuffer_sRGB) },
    { OFF, "GL_EXT_fog_coord",                  F(EXT_fog_coord) },
    { OFF, "GL_EXT_gpu_program_parameters",     F(EXT_gpu_program_parameters) },
    { OFF, "GL_EXT_histogram",                  F(EXT_histogram) },
    { ON,  "GL_EXT_multi_draw_arrays",          F(EXT_multi_draw_arrays) },
    { OFF, "GL_EXT_packed_depth_stencil",       F(EXT_packed_depth_stencil) },
+   { OFF, "GL_EXT_packed_float",               F(EXT_packed_float) },
    { ON,  "GL_EXT_packed_pixels",              F(EXT_packed_pixels) },
    { OFF, "GL_EXT_paletted_texture",           F(EXT_paletted_texture) },
    { OFF, "GL_EXT_pixel_buffer_object",        F(EXT_pixel_buffer_object) },
@@ -136,16 +151,19 @@ static const struct {
    { ON,  "GL_EXT_texture3D",                  F(EXT_texture3D) },
    { OFF, "GL_EXT_texture_array",              F(EXT_texture_array) },
    { OFF, "GL_EXT_texture_compression_s3tc",   F(EXT_texture_compression_s3tc) },
+   { OFF, "GL_EXT_texture_compression_rgtc",   F(EXT_texture_compression_rgtc) },
    { OFF, "GL_EXT_texture_cube_map",           F(ARB_texture_cube_map) },
    { ON,  "GL_EXT_texture_edge_clamp",         F(SGIS_texture_edge_clamp) },
    { OFF, "GL_EXT_texture_env_add",            F(EXT_texture_env_add) },
    { OFF, "GL_EXT_texture_env_combine",        F(EXT_texture_env_combine) },
    { OFF, "GL_EXT_texture_env_dot3",           F(EXT_texture_env_dot3) },
    { OFF, "GL_EXT_texture_filter_anisotropic", F(EXT_texture_filter_anisotropic) },
+   { OFF, "GL_EXT_texture_integer",            F(EXT_texture_integer) },
    { OFF, "GL_EXT_texture_lod_bias",           F(EXT_texture_lod_bias) },
    { OFF, "GL_EXT_texture_mirror_clamp",       F(EXT_texture_mirror_clamp) },
    { ON,  "GL_EXT_texture_object",             F(EXT_texture_object) },
    { OFF, "GL_EXT_texture_rectangle",          F(NV_texture_rectangle) },
+   { OFF, "GL_EXT_texture_shared_exponent",    F(EXT_texture_shared_exponent) },
    { OFF, "GL_EXT_texture_sRGB",               F(EXT_texture_sRGB) },
    { OFF, "GL_EXT_texture_swizzle",            F(EXT_texture_swizzle) },
    { OFF, "GL_EXT_timer_query",                F(EXT_timer_query) },
@@ -183,9 +201,10 @@ static const struct {
    { ON,  "GL_NV_light_max_exponent",          F(NV_light_max_exponent) },
    { OFF, "GL_NV_packed_depth_stencil",        F(EXT_packed_depth_stencil) },
    { OFF, "GL_NV_point_sprite",                F(NV_point_sprite) },
+   { OFF, "GL_NV_primitive_restart",           F(NV_primitive_restart) },
+   { ON,  "GL_NV_texgen_reflection",           F(NV_texgen_reflection) },
    { OFF, "GL_NV_texture_env_combine4",        F(NV_texture_env_combine4) },
    { OFF, "GL_NV_texture_rectangle",           F(NV_texture_rectangle) },
-   { ON,  "GL_NV_texgen_reflection",           F(NV_texgen_reflection) },
    { OFF, "GL_NV_vertex_program",              F(NV_vertex_program) },
    { OFF, "GL_NV_vertex_program1_1",           F(NV_vertex_program1_1) },
    { ON,  "GL_OES_read_format",                F(OES_read_format) },
@@ -230,6 +249,9 @@ _mesa_enable_sw_extensions(GLcontext *ctx)
 #endif
 #if FEATURE_ARB_framebuffer_object
    ctx->Extensions.ARB_framebuffer_object = GL_TRUE;
+#endif
+#if FEATURE_ARB_geometry_shader4
+   ctx->Extensions.ARB_geometry_shader4 = GL_TRUE;
 #endif
    ctx->Extensions.ARB_half_float_pixel = GL_TRUE;
    ctx->Extensions.ARB_half_float_vertex = GL_TRUE;
index 09fafbc8b9df49499a1ad27903974f18a8dd4706..8c86b392c7b06e9d77afaa6dff1655e58607607d 100644 (file)
@@ -147,6 +147,8 @@ invalidate_framebuffer(struct gl_framebuffer *fb)
 /**
  * Given a GL_*_ATTACHMENTn token, return a pointer to the corresponding
  * gl_renderbuffer_attachment object.
+ * This function is only used for user-created FB objects, not the
+ * default / window-system FB object.
  * If \p attachment is GL_DEPTH_STENCIL_ATTACHMENT, return a pointer to
  * the depth buffer attachment point.
  */
@@ -156,6 +158,8 @@ _mesa_get_attachment(GLcontext *ctx, struct gl_framebuffer *fb,
 {
    GLuint i;
 
+   assert(fb->Name > 0);
+
    switch (attachment) {
    case GL_COLOR_ATTACHMENT0_EXT:
    case GL_COLOR_ATTACHMENT1_EXT:
@@ -188,6 +192,23 @@ _mesa_get_attachment(GLcontext *ctx, struct gl_framebuffer *fb,
       /* fall-through / new in GL 3.0 */
    case GL_STENCIL_ATTACHMENT_EXT:
       return &fb->Attachment[BUFFER_STENCIL];
+   default:
+      return NULL;
+   }
+}
+
+
+/**
+ * As above, but only used for getting attachments of the default /
+ * window-system framebuffer (not user-created framebuffer objects).
+ */
+static struct gl_renderbuffer_attachment *
+_mesa_get_fb0_attachment(GLcontext *ctx, struct gl_framebuffer *fb,
+                         GLenum attachment)
+{
+   assert(fb->Name == 0);
+
+   switch (attachment) {
    case GL_FRONT_LEFT:
       return &fb->Attachment[BUFFER_FRONT_LEFT];
    case GL_FRONT_RIGHT:
@@ -196,12 +217,26 @@ _mesa_get_attachment(GLcontext *ctx, struct gl_framebuffer *fb,
       return &fb->Attachment[BUFFER_BACK_LEFT];
    case GL_BACK_RIGHT:
       return &fb->Attachment[BUFFER_BACK_RIGHT];
+   case GL_AUX0:
+      if (fb->Visual.numAuxBuffers == 1) {
+         return &fb->Attachment[BUFFER_AUX0];
+      }
+      return NULL;
+   case GL_DEPTH_BUFFER:
+      /* fall-through / new in GL 3.0 */
+   case GL_DEPTH_ATTACHMENT_EXT:
+      return &fb->Attachment[BUFFER_DEPTH];
+   case GL_STENCIL_BUFFER:
+      /* fall-through / new in GL 3.0 */
+   case GL_STENCIL_ATTACHMENT_EXT:
+      return &fb->Attachment[BUFFER_STENCIL];
    default:
       return NULL;
    }
 }
 
 
+
 /**
  * Remove any texture or renderbuffer attached to the given attachment
  * point.  Update reference counts, etc.
@@ -1885,7 +1920,15 @@ _mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
       return;
    }
 
-   att = _mesa_get_attachment(ctx, buffer, attachment);
+   if (buffer->Name == 0) {
+      /* the default / window-system FBO */
+      att = _mesa_get_fb0_attachment(ctx, buffer, attachment);
+   }
+   else {
+      /* user-created framebuffer FBO */
+      att = _mesa_get_attachment(ctx, buffer, attachment);
+   }
+
    if (att == NULL) {
       _mesa_error(ctx, GL_INVALID_ENUM,
                   "glGetFramebufferAttachmentParameterivEXT(attachment)");
@@ -2256,3 +2299,25 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                                mask, filter);
 }
 #endif /* FEATURE_EXT_framebuffer_blit */
+
+#if FEATURE_ARB_geometry_shader4
+void GLAPIENTRY
+_mesa_FramebufferTextureARB(GLenum target, GLenum attachment,
+                            GLuint texture, GLint level)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION,
+               "glFramebufferTextureARB "
+               "not implemented!");
+}
+
+void GLAPIENTRY
+_mesa_FramebufferTextureFaceARB(GLenum target, GLenum attachment,
+                                GLuint texture, GLint level, GLenum face)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION,
+               "glFramebufferTextureFaceARB "
+               "not implemented!");
+}
+#endif /* FEATURE_ARB_geometry_shader4 */
index 40a18f834121b0cabc1a25180258019d52fbf89f..ff946033a4ddd0150439611e58ae700d38ae4189 100644 (file)
@@ -149,5 +149,13 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                          GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
                          GLbitfield mask, GLenum filter);
 
+extern void GLAPIENTRY
+_mesa_FramebufferTextureARB(GLenum target, GLenum attachment,
+                            GLuint texture, GLint level);
+
+extern void GLAPIENTRY
+_mesa_FramebufferTextureFaceARB(GLenum target, GLenum attachment,
+                                GLuint texture, GLint level, GLenum face);
+
 
 #endif /* FBOBJECT_H */
index 70ac47f36d77fd7135593b501991604a7478c6a4..92fec09bad04a4b4ef32f6410db9d2ea23bdd965 100644 (file)
 #include "main/macros.h"
 #include "main/enums.h"
 #include "main/ffvertex_prog.h"
-#include "shader/program.h"
-#include "shader/prog_cache.h"
-#include "shader/prog_instruction.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_print.h"
-#include "shader/prog_statevars.h"
+#include "program/program.h"
+#include "program/prog_cache.h"
+#include "program/prog_instruction.h"
+#include "program/prog_parameter.h"
+#include "program/prog_print.h"
+#include "program/prog_statevars.h"
 
 
 /** Max of number of lights and texture coord units */
index 3671140e85900234f246e366781d1f89a8d56073..49463fcc3c20db5750abb5566f3032efe807d560 100644 (file)
@@ -48,7 +48,7 @@ struct gl_format_info
 
    /**
     * Logical data type: one of  GL_UNSIGNED_NORMALIZED, GL_SIGNED_NORMALED,
-    * GL_UNSIGNED_INT, GL_SIGNED_INT, GL_FLOAT.
+    * GL_UNSIGNED_INT, GL_INT, GL_FLOAT.
     */
    GLenum DataType;
 
@@ -628,6 +628,66 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] =
       0, 16, 0, 0, 0,
       1, 1, 2
    },
+
+   /* unnormalized signed int formats */
+   {
+      MESA_FORMAT_RGBA_INT8,
+      "MESA_FORMAT_RGBA_INT8",
+      GL_RGBA,
+      GL_INT,
+      8, 8, 8, 8,
+      0, 0, 0, 0, 0,
+      1, 1, 4
+   },
+   {
+      MESA_FORMAT_RGBA_INT16,
+      "MESA_FORMAT_RGBA_INT16",
+      GL_RGBA,
+      GL_INT,
+      16, 16, 16, 16,
+      0, 0, 0, 0, 0,
+      1, 1, 8
+   },
+   {
+      MESA_FORMAT_RGBA_INT32,
+      "MESA_FORMAT_RGBA_INT32",
+      GL_RGBA,
+      GL_INT,
+      32, 32, 32, 32,
+      0, 0, 0, 0, 0,
+      1, 1, 16
+   },
+
+   /* unnormalized unsigned int formats */
+   {
+      MESA_FORMAT_RGBA_UINT8,
+      "MESA_FORMAT_RGBA_UINT8",
+      GL_RGBA,
+      GL_UNSIGNED_INT,
+      8, 8, 8, 8,
+      0, 0, 0, 0, 0,
+      1, 1, 4
+   },
+   {
+      MESA_FORMAT_RGBA_UINT16,
+      "MESA_FORMAT_RGBA_UINT16",
+      GL_RGBA,
+      GL_UNSIGNED_INT,
+      16, 16, 16, 16,
+      0, 0, 0, 0, 0,
+      1, 1, 8
+   },
+   {
+      MESA_FORMAT_RGBA_UINT32,
+      "MESA_FORMAT_RGBA_UINT32",
+      GL_RGBA,
+      GL_UNSIGNED_INT,
+      32, 32, 32, 32,
+      0, 0, 0, 0, 0,
+      1, 1, 16
+   },
+
+
    {
       MESA_FORMAT_DUDV8,
       "MESA_FORMAT_DUDV8",
@@ -1230,6 +1290,36 @@ _mesa_format_to_type_and_comps(gl_format format,
       *comps = 1;
       return;
 
+   case MESA_FORMAT_RGBA_INT8:
+      *datatype = GL_BYTE;
+      *comps = 4;
+      return;
+   case MESA_FORMAT_RGBA_INT16:
+      *datatype = GL_SHORT;
+      *comps = 4;
+      return;
+   case MESA_FORMAT_RGBA_INT32:
+      *datatype = GL_INT;
+      *comps = 4;
+      return;
+
+   /**
+    * \name Non-normalized unsigned integer formats.
+    */
+   case MESA_FORMAT_RGBA_UINT8:
+      *datatype = GL_UNSIGNED_BYTE;
+      *comps = 4;
+      return;
+   case MESA_FORMAT_RGBA_UINT16:
+      *datatype = GL_UNSIGNED_SHORT;
+      *comps = 4;
+      return;
+   case MESA_FORMAT_RGBA_UINT32:
+      *datatype = GL_UNSIGNED_INT;
+      *comps = 4;
+      return;
+
+
    default:
       _mesa_problem(NULL, "bad format in _mesa_format_to_type_and_comps");
       *datatype = 0;
index c744688122f1fb010d105c813a1b4738f8312fde..aa14185628f108f7fdaad7b1a689ed8988979bda 100644 (file)
@@ -130,6 +130,22 @@ typedef enum
    MESA_FORMAT_INTENSITY_FLOAT16,
    /*@}*/
 
+   /**
+    * \name Non-normalized signed integer formats.
+    * XXX Note: these are just stand-ins for some better hardware
+    * formats TBD such as BGRA or ARGB.
+    */
+   MESA_FORMAT_RGBA_INT8,
+   MESA_FORMAT_RGBA_INT16,
+   MESA_FORMAT_RGBA_INT32,
+
+   /**
+    * \name Non-normalized unsigned integer formats.
+    */
+   MESA_FORMAT_RGBA_UINT8,
+   MESA_FORMAT_RGBA_UINT16,
+   MESA_FORMAT_RGBA_UINT32,
+
                                   /* msb <------ TEXEL BITS -----------> lsb */
                                   /* ---- ---- ---- ---- ---- ---- ---- ---- */
    /**
index 01f84180af730a258fb5b3950a4c938176639494..56558cfcc1edf43de3b7b247f0343edcd009c217 100644 (file)
@@ -879,6 +879,7 @@ _mesa_source_buffer_exists(GLcontext *ctx, GLenum format)
          return GL_FALSE;
       }
       ASSERT(_mesa_get_format_bits(ctx->ReadBuffer->_ColorReadBuffer->Format, GL_RED_BITS) > 0 ||
+             _mesa_get_format_bits(ctx->ReadBuffer->_ColorReadBuffer->Format, GL_ALPHA_BITS) > 0 ||
              _mesa_get_format_bits(ctx->ReadBuffer->_ColorReadBuffer->Format, GL_INDEX_BITS) > 0);
       break;
    case GL_DEPTH:
index 03f2707f4f02c60d120f093d144db6ad3eed980b..632dadd1a5d5f419096d0907cd8c542f6d7594f0 100644 (file)
@@ -303,6 +303,7 @@ EXTRA_EXT2(ARB_fragment_program, NV_fragment_program);
 EXTRA_EXT2(ARB_vertex_program, NV_vertex_program);
 EXTRA_EXT2(ARB_vertex_program, ARB_fragment_program);
 EXTRA_EXT(ARB_vertex_buffer_object);
+EXTRA_EXT(ARB_geometry_shader4);
 
 static const int
 extra_ARB_vertex_program_ARB_fragment_program_NV_vertex_program[] = {
@@ -667,7 +668,7 @@ static const struct value_desc values[] = {
    { GL_MAX_3D_TEXTURE_SIZE, LOC_CUSTOM, TYPE_INT,
      offsetof(GLcontext, Const.Max3DTextureLevels), NO_EXTRA },
 
-   /* GL_ARB_fragment_shader/OES_standard_derivatives */
+   /* GL_ARB_fragment_program/OES_standard_derivatives */
    { GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB,
      CONTEXT_ENUM(Hint.FragmentShaderDerivative), extra_ARB_fragment_shader },
 #endif /* FEATURE_GL || FEATURE_ES2 */
@@ -1220,6 +1221,26 @@ static const struct value_desc values[] = {
    { GL_TRANSFORM_FEEDBACK_BINDING, LOC_CUSTOM, TYPE_INT, 0,
      extra_ARB_transform_feedback2 },
 
+   /* GL_ARB_geometry_shader4 */
+   { GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB,
+     CONTEXT_INT(Const.GeometryProgram.MaxGeometryTextureImageUnits),
+     extra_ARB_geometry_shader4 },
+   { GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB,
+     CONTEXT_INT(Const.GeometryProgram.MaxGeometryOutputVertices),
+     extra_ARB_geometry_shader4 },
+   { GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB,
+     CONTEXT_INT(Const.GeometryProgram.MaxGeometryTotalOutputComponents),
+     extra_ARB_geometry_shader4 },
+   { GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB,
+     CONTEXT_INT(Const.GeometryProgram.MaxGeometryUniformComponents),
+     extra_ARB_geometry_shader4 },
+   { GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB,
+     CONTEXT_INT(Const.GeometryProgram.MaxGeometryVaryingComponents),
+     extra_ARB_geometry_shader4 },
+   { GL_MAX_VERTEX_VARYING_COMPONENTS_ARB,
+     CONTEXT_INT(Const.GeometryProgram.MaxVertexVaryingComponents),
+     extra_ARB_geometry_shader4 },
+
    /* GL 3.0 */
    { GL_NUM_EXTENSIONS, LOC_CUSTOM, TYPE_INT, 0, extra_version_30 },
    { GL_MAJOR_VERSION, CONTEXT_INT(VersionMajor), extra_version_30 },
index 54db5794bf64becfa16a20d56d8b256ba8a982f3..7961ad7e7dd048774cc84baaf3a7f9a1f2ed4198 100644 (file)
@@ -95,8 +95,6 @@ _mesa_GetString( GLenum name )
       case GL_VERSION:
          return (const GLubyte *) ctx->VersionString;
       case GL_EXTENSIONS:
-         if (!ctx->Extensions.String)
-            ctx->Extensions.String = _mesa_make_extension_string(ctx);
          return (const GLubyte *) ctx->Extensions.String;
 #if FEATURE_ARB_shading_language_100 || FEATURE_ES2
       case GL_SHADING_LANGUAGE_VERSION:
index 93b01423dcf08551c297d8a72e91cd49c6348738..63c28342f2655aad3a765971ca84bc2a486e0468 100644 (file)
@@ -274,17 +274,25 @@ _mesa_components_in_format( GLenum format )
       case GL_STENCIL_INDEX:
       case GL_DEPTH_COMPONENT:
       case GL_RED:
+      case GL_RED_INTEGER_EXT:
       case GL_GREEN:
+      case GL_GREEN_INTEGER_EXT:
       case GL_BLUE:
+      case GL_BLUE_INTEGER_EXT:
       case GL_ALPHA:
+      case GL_ALPHA_INTEGER_EXT:
       case GL_LUMINANCE:
+      case GL_LUMINANCE_INTEGER_EXT:
       case GL_INTENSITY:
          return 1;
       case GL_LUMINANCE_ALPHA:
+      case GL_LUMINANCE_ALPHA_INTEGER_EXT:
         return 2;
       case GL_RGB:
+      case GL_RGB_INTEGER_EXT:
         return 3;
       case GL_RGBA:
+      case GL_RGBA_INTEGER_EXT:
         return 4;
       case GL_BGR:
         return 3;
@@ -523,6 +531,28 @@ _mesa_is_legal_format_and_type( GLcontext *ctx, GLenum format, GLenum type )
             default:
                return GL_FALSE;
          }
+      case GL_RED_INTEGER_EXT:
+      case GL_GREEN_INTEGER_EXT:
+      case GL_BLUE_INTEGER_EXT:
+      case GL_ALPHA_INTEGER_EXT:
+      case GL_RGB_INTEGER_EXT:
+      case GL_RGBA_INTEGER_EXT:
+      case GL_BGR_INTEGER_EXT:
+      case GL_BGRA_INTEGER_EXT:
+      case GL_LUMINANCE_INTEGER_EXT:
+      case GL_LUMINANCE_ALPHA_INTEGER_EXT:
+         switch (type) {
+            case GL_BYTE:
+            case GL_UNSIGNED_BYTE:
+            case GL_SHORT:
+            case GL_UNSIGNED_SHORT:
+            case GL_INT:
+            case GL_UNSIGNED_INT:
+               return ctx->Extensions.EXT_texture_integer;
+            default:
+               return GL_FALSE;
+         }
+
       default:
          ; /* fall-through */
    }
@@ -776,6 +806,30 @@ _mesa_is_dudv_format(GLenum format)
 }
 
 
+/**
+ * Test if the given format is an integer (non-normalized) format.
+ */
+GLboolean
+_mesa_is_integer_format(GLenum format)
+{
+   switch (format) {
+   case GL_RED_INTEGER_EXT:
+   case GL_GREEN_INTEGER_EXT:
+   case GL_BLUE_INTEGER_EXT:
+   case GL_ALPHA_INTEGER_EXT:
+   case GL_RGB_INTEGER_EXT:
+   case GL_RGBA_INTEGER_EXT:
+   case GL_BGR_INTEGER_EXT:
+   case GL_BGRA_INTEGER_EXT:
+   case GL_LUMINANCE_INTEGER_EXT:
+   case GL_LUMINANCE_ALPHA_INTEGER_EXT:
+      return GL_TRUE;
+   default:
+      return GL_FALSE;
+   }
+}
+
+
 /**
  * Test if an image format is a supported compressed format.
  * \param format the internal format token provided by the user.
@@ -3275,6 +3329,8 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
    GLint redIndex, greenIndex, blueIndex, alphaIndex;
    GLint stride;
    GLint rComp, bComp, gComp, aComp;
+   GLboolean intFormat;
+   GLfloat rs = 1.0f, gs = 1.0f, bs = 1.0f, as = 1.0f; /* scale factors */
 
    ASSERT(srcFormat == GL_RED ||
           srcFormat == GL_GREEN ||
@@ -3289,7 +3345,17 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
           srcFormat == GL_BGRA ||
           srcFormat == GL_ABGR_EXT ||
           srcFormat == GL_DU8DV8_ATI ||
-          srcFormat == GL_DUDV_ATI);
+          srcFormat == GL_DUDV_ATI ||
+          srcFormat == GL_RED_INTEGER_EXT ||
+          srcFormat == GL_GREEN_INTEGER_EXT ||
+          srcFormat == GL_BLUE_INTEGER_EXT ||
+          srcFormat == GL_ALPHA_INTEGER_EXT ||
+          srcFormat == GL_RGB_INTEGER_EXT ||
+          srcFormat == GL_RGBA_INTEGER_EXT ||
+          srcFormat == GL_BGR_INTEGER_EXT ||
+          srcFormat == GL_BGRA_INTEGER_EXT ||
+          srcFormat == GL_LUMINANCE_INTEGER_EXT ||
+          srcFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT);
 
    ASSERT(srcType == GL_UNSIGNED_BYTE ||
           srcType == GL_BYTE ||
@@ -3316,31 +3382,37 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
 
    switch (srcFormat) {
       case GL_RED:
+      case GL_RED_INTEGER_EXT:
          redIndex = 0;
          greenIndex = blueIndex = alphaIndex = -1;
          stride = 1;
          break;
       case GL_GREEN:
+      case GL_GREEN_INTEGER_EXT:
          greenIndex = 0;
          redIndex = blueIndex = alphaIndex = -1;
          stride = 1;
          break;
       case GL_BLUE:
+      case GL_BLUE_INTEGER_EXT:
          blueIndex = 0;
          redIndex = greenIndex = alphaIndex = -1;
          stride = 1;
          break;
       case GL_ALPHA:
+      case GL_ALPHA_INTEGER_EXT:
          redIndex = greenIndex = blueIndex = -1;
          alphaIndex = 0;
          stride = 1;
          break;
       case GL_LUMINANCE:
+      case GL_LUMINANCE_INTEGER_EXT:
          redIndex = greenIndex = blueIndex = 0;
          alphaIndex = -1;
          stride = 1;
          break;
       case GL_LUMINANCE_ALPHA:
+      case GL_LUMINANCE_ALPHA_INTEGER_EXT:
          redIndex = greenIndex = blueIndex = 0;
          alphaIndex = 1;
          stride = 2;
@@ -3350,6 +3422,7 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
          stride = 1;
          break;
       case GL_RGB:
+      case GL_RGB_INTEGER:
          redIndex = 0;
          greenIndex = 1;
          blueIndex = 2;
@@ -3372,6 +3445,7 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
          stride = 3;
          break;
       case GL_RGBA:
+      case GL_RGBA_INTEGER:
          redIndex = 0;
          greenIndex = 1;
          blueIndex = 2;
@@ -3418,12 +3492,20 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
          return;
    }
 
+   intFormat = _mesa_is_integer_format(srcFormat);
 
-#define PROCESS(INDEX, CHANNEL, DEFAULT, TYPE, CONVERSION)             \
+#define PROCESS(INDEX, CHANNEL, DEFAULT, DEFAULT_INT, TYPE, CONVERSION) \
    if ((INDEX) < 0) {                                                  \
       GLuint i;                                                                \
-      for (i = 0; i < n; i++) {                                                \
-         rgba[i][CHANNEL] = DEFAULT;                                   \
+      if (intFormat) {                                                 \
+         for (i = 0; i < n; i++) {                                     \
+            rgba[i][CHANNEL] = DEFAULT_INT;                            \
+         }                                                             \
+      }                                                                        \
+      else {                                                           \
+         for (i = 0; i < n; i++) {                                     \
+            rgba[i][CHANNEL] = DEFAULT;                                        \
+         }                                                             \
       }                                                                        \
    }                                                                   \
    else if (swapBytes) {                                               \
@@ -3437,77 +3519,93 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
          else if (sizeof(TYPE) == 4) {                                 \
             SWAP4BYTE(value);                                          \
          }                                                             \
-         rgba[i][CHANNEL] = (GLfloat) CONVERSION(value);               \
+         if (intFormat)                                                        \
+            rgba[i][CHANNEL] = (GLfloat) value;                                \
+         else                                                          \
+            rgba[i][CHANNEL] = (GLfloat) CONVERSION(value);            \
          s += stride;                                                  \
       }                                                                        \
    }                                                                   \
    else {                                                              \
       const TYPE *s = (const TYPE *) src;                              \
       GLuint i;                                                                \
-      for (i = 0; i < n; i++) {                                                \
-         rgba[i][CHANNEL] = (GLfloat) CONVERSION(s[INDEX]);            \
-         s += stride;                                                  \
+      if (intFormat) {                                                 \
+         for (i = 0; i < n; i++) {                                     \
+            rgba[i][CHANNEL] = (GLfloat) s[INDEX];                     \
+            s += stride;                                               \
+         }                                                             \
+      }                                                                        \
+      else {                                                           \
+         for (i = 0; i < n; i++) {                                     \
+            rgba[i][CHANNEL] = (GLfloat) CONVERSION(s[INDEX]);         \
+            s += stride;                                               \
+         }                                                             \
       }                                                                        \
    }
 
    switch (srcType) {
       case GL_UNSIGNED_BYTE:
-         PROCESS(redIndex,   RCOMP, 0.0F, GLubyte, UBYTE_TO_FLOAT);
-         PROCESS(greenIndex, GCOMP, 0.0F, GLubyte, UBYTE_TO_FLOAT);
-         PROCESS(blueIndex,  BCOMP, 0.0F, GLubyte, UBYTE_TO_FLOAT);
-         PROCESS(alphaIndex, ACOMP, 1.0F, GLubyte, UBYTE_TO_FLOAT);
+         PROCESS(redIndex,   RCOMP, 0.0F,   0, GLubyte, UBYTE_TO_FLOAT);
+         PROCESS(greenIndex, GCOMP, 0.0F,   0, GLubyte, UBYTE_TO_FLOAT);
+         PROCESS(blueIndex,  BCOMP, 0.0F,   0, GLubyte, UBYTE_TO_FLOAT);
+         PROCESS(alphaIndex, ACOMP, 1.0F, 255, GLubyte, UBYTE_TO_FLOAT);
          break;
       case GL_BYTE:
-         PROCESS(redIndex,   RCOMP, 0.0F, GLbyte, BYTE_TO_FLOAT);
-         PROCESS(greenIndex, GCOMP, 0.0F, GLbyte, BYTE_TO_FLOAT);
-         PROCESS(blueIndex,  BCOMP, 0.0F, GLbyte, BYTE_TO_FLOAT);
-         PROCESS(alphaIndex, ACOMP, 1.0F, GLbyte, BYTE_TO_FLOAT);
+         PROCESS(redIndex,   RCOMP, 0.0F,   0, GLbyte, BYTE_TO_FLOAT);
+         PROCESS(greenIndex, GCOMP, 0.0F,   0, GLbyte, BYTE_TO_FLOAT);
+         PROCESS(blueIndex,  BCOMP, 0.0F,   0, GLbyte, BYTE_TO_FLOAT);
+         PROCESS(alphaIndex, ACOMP, 1.0F, 127, GLbyte, BYTE_TO_FLOAT);
          break;
       case GL_UNSIGNED_SHORT:
-         PROCESS(redIndex,   RCOMP, 0.0F, GLushort, USHORT_TO_FLOAT);
-         PROCESS(greenIndex, GCOMP, 0.0F, GLushort, USHORT_TO_FLOAT);
-         PROCESS(blueIndex,  BCOMP, 0.0F, GLushort, USHORT_TO_FLOAT);
-         PROCESS(alphaIndex, ACOMP, 1.0F, GLushort, USHORT_TO_FLOAT);
+         PROCESS(redIndex,   RCOMP, 0.0F,      0, GLushort, USHORT_TO_FLOAT);
+         PROCESS(greenIndex, GCOMP, 0.0F,      0, GLushort, USHORT_TO_FLOAT);
+         PROCESS(blueIndex,  BCOMP, 0.0F,      0, GLushort, USHORT_TO_FLOAT);
+         PROCESS(alphaIndex, ACOMP, 1.0F, 0xffff, GLushort, USHORT_TO_FLOAT);
          break;
       case GL_SHORT:
-         PROCESS(redIndex,   RCOMP, 0.0F, GLshort, SHORT_TO_FLOAT);
-         PROCESS(greenIndex, GCOMP, 0.0F, GLshort, SHORT_TO_FLOAT);
-         PROCESS(blueIndex,  BCOMP, 0.0F, GLshort, SHORT_TO_FLOAT);
-         PROCESS(alphaIndex, ACOMP, 1.0F, GLshort, SHORT_TO_FLOAT);
+         PROCESS(redIndex,   RCOMP, 0.0F,     0, GLshort, SHORT_TO_FLOAT);
+         PROCESS(greenIndex, GCOMP, 0.0F,     0, GLshort, SHORT_TO_FLOAT);
+         PROCESS(blueIndex,  BCOMP, 0.0F,     0, GLshort, SHORT_TO_FLOAT);
+         PROCESS(alphaIndex, ACOMP, 1.0F, 32767, GLshort, SHORT_TO_FLOAT);
          break;
       case GL_UNSIGNED_INT:
-         PROCESS(redIndex,   RCOMP, 0.0F, GLuint, UINT_TO_FLOAT);
-         PROCESS(greenIndex, GCOMP, 0.0F, GLuint, UINT_TO_FLOAT);
-         PROCESS(blueIndex,  BCOMP, 0.0F, GLuint, UINT_TO_FLOAT);
-         PROCESS(alphaIndex, ACOMP, 1.0F, GLuint, UINT_TO_FLOAT);
+         PROCESS(redIndex,   RCOMP, 0.0F,          0, GLuint, UINT_TO_FLOAT);
+         PROCESS(greenIndex, GCOMP, 0.0F,          0, GLuint, UINT_TO_FLOAT);
+         PROCESS(blueIndex,  BCOMP, 0.0F,          0, GLuint, UINT_TO_FLOAT);
+         PROCESS(alphaIndex, ACOMP, 1.0F, 0xffffffff, GLuint, UINT_TO_FLOAT);
          break;
       case GL_INT:
-         PROCESS(redIndex,   RCOMP, 0.0F, GLint, INT_TO_FLOAT);
-         PROCESS(greenIndex, GCOMP, 0.0F, GLint, INT_TO_FLOAT);
-         PROCESS(blueIndex,  BCOMP, 0.0F, GLint, INT_TO_FLOAT);
-         PROCESS(alphaIndex, ACOMP, 1.0F, GLint, INT_TO_FLOAT);
+         PROCESS(redIndex,   RCOMP, 0.0F,          0, GLint, INT_TO_FLOAT);
+         PROCESS(greenIndex, GCOMP, 0.0F,          0, GLint, INT_TO_FLOAT);
+         PROCESS(blueIndex,  BCOMP, 0.0F,          0, GLint, INT_TO_FLOAT);
+         PROCESS(alphaIndex, ACOMP, 1.0F, 2147483647, GLint, INT_TO_FLOAT);
          break;
       case GL_FLOAT:
-         PROCESS(redIndex,   RCOMP, 0.0F, GLfloat, (GLfloat));
-         PROCESS(greenIndex, GCOMP, 0.0F, GLfloat, (GLfloat));
-         PROCESS(blueIndex,  BCOMP, 0.0F, GLfloat, (GLfloat));
-         PROCESS(alphaIndex, ACOMP, 1.0F, GLfloat, (GLfloat));
+         PROCESS(redIndex,   RCOMP, 0.0F, 0.0F, GLfloat, (GLfloat));
+         PROCESS(greenIndex, GCOMP, 0.0F, 0.0F, GLfloat, (GLfloat));
+         PROCESS(blueIndex,  BCOMP, 0.0F, 0.0F, GLfloat, (GLfloat));
+         PROCESS(alphaIndex, ACOMP, 1.0F, 1.0F, GLfloat, (GLfloat));
          break;
       case GL_HALF_FLOAT_ARB:
-         PROCESS(redIndex,   RCOMP, 0.0F, GLhalfARB, _mesa_half_to_float);
-         PROCESS(greenIndex, GCOMP, 0.0F, GLhalfARB, _mesa_half_to_float);
-         PROCESS(blueIndex,  BCOMP, 0.0F, GLhalfARB, _mesa_half_to_float);
-         PROCESS(alphaIndex, ACOMP, 1.0F, GLhalfARB, _mesa_half_to_float);
+         PROCESS(redIndex,   RCOMP, 0.0F, 0.0F, GLhalfARB, _mesa_half_to_float);
+         PROCESS(greenIndex, GCOMP, 0.0F, 0.0F, GLhalfARB, _mesa_half_to_float);
+         PROCESS(blueIndex,  BCOMP, 0.0F, 0.0F, GLhalfARB, _mesa_half_to_float);
+         PROCESS(alphaIndex, ACOMP, 1.0F, 1.0F, GLhalfARB, _mesa_half_to_float);
          break;
       case GL_UNSIGNED_BYTE_3_3_2:
          {
             const GLubyte *ubsrc = (const GLubyte *) src;
             GLuint i;
+            if (!intFormat) {
+               rs = 1.0F / 7.0F;
+               gs = 1.0F / 7.0F;
+               bs = 1.0F / 3.0F;
+            }
             for (i = 0; i < n; i ++) {
                GLubyte p = ubsrc[i];
-               rgba[i][rComp] = ((p >> 5)      ) * (1.0F / 7.0F);
-               rgba[i][gComp] = ((p >> 2) & 0x7) * (1.0F / 7.0F);
-               rgba[i][bComp] = ((p     ) & 0x3) * (1.0F / 3.0F);
+               rgba[i][rComp] = ((p >> 5)      ) * rs;
+               rgba[i][gComp] = ((p >> 2) & 0x7) * gs;
+               rgba[i][bComp] = ((p     ) & 0x3) * bs;
                rgba[i][aComp] = 1.0F;
             }
          }
@@ -3516,25 +3614,35 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
          {
             const GLubyte *ubsrc = (const GLubyte *) src;
             GLuint i;
+            if (!intFormat) {
+               rs = 1.0F / 7.0F;
+               gs = 1.0F / 7.0F;
+               bs = 1.0F / 3.0F;
+            }
             for (i = 0; i < n; i ++) {
                GLubyte p = ubsrc[i];
-               rgba[i][rComp] = ((p     ) & 0x7) * (1.0F / 7.0F);
-               rgba[i][gComp] = ((p >> 3) & 0x7) * (1.0F / 7.0F);
-               rgba[i][bComp] = ((p >> 6)      ) * (1.0F / 3.0F);
+               rgba[i][rComp] = ((p     ) & 0x7) * rs;
+               rgba[i][gComp] = ((p >> 3) & 0x7) * gs;
+               rgba[i][bComp] = ((p >> 6)      ) * bs;
                rgba[i][aComp] = 1.0F;
             }
          }
          break;
       case GL_UNSIGNED_SHORT_5_6_5:
+         if (!intFormat) {
+            rs = 1.0F / 31.0F;
+            gs = 1.0F / 63.0F;
+            bs = 1.0F / 31.0F;
+         }
          if (swapBytes) {
             const GLushort *ussrc = (const GLushort *) src;
             GLuint i;
             for (i = 0; i < n; i ++) {
                GLushort p = ussrc[i];
                SWAP2BYTE(p);
-               rgba[i][rComp] = ((p >> 11)       ) * (1.0F / 31.0F);
-               rgba[i][gComp] = ((p >>  5) & 0x3f) * (1.0F / 63.0F);
-               rgba[i][bComp] = ((p      ) & 0x1f) * (1.0F / 31.0F);
+               rgba[i][rComp] = ((p >> 11)       ) * rs;
+               rgba[i][gComp] = ((p >>  5) & 0x3f) * gs;
+               rgba[i][bComp] = ((p      ) & 0x1f) * bs;
                rgba[i][aComp] = 1.0F;
             }
          }
@@ -3543,23 +3651,28 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
             GLuint i;
             for (i = 0; i < n; i ++) {
                GLushort p = ussrc[i];
-               rgba[i][rComp] = ((p >> 11)       ) * (1.0F / 31.0F);
-               rgba[i][gComp] = ((p >>  5) & 0x3f) * (1.0F / 63.0F);
-               rgba[i][bComp] = ((p      ) & 0x1f) * (1.0F / 31.0F);
+               rgba[i][rComp] = ((p >> 11)       ) * rs;
+               rgba[i][gComp] = ((p >>  5) & 0x3f) * gs;
+               rgba[i][bComp] = ((p      ) & 0x1f) * bs;
                rgba[i][aComp] = 1.0F;
             }
          }
          break;
       case GL_UNSIGNED_SHORT_5_6_5_REV:
+         if (!intFormat) {
+            rs = 1.0F / 31.0F;
+            gs = 1.0F / 63.0F;
+            bs = 1.0F / 31.0F;
+         }
          if (swapBytes) {
             const GLushort *ussrc = (const GLushort *) src;
             GLuint i;
             for (i = 0; i < n; i ++) {
                GLushort p = ussrc[i];
                SWAP2BYTE(p);
-               rgba[i][rComp] = ((p      ) & 0x1f) * (1.0F / 31.0F);
-               rgba[i][gComp] = ((p >>  5) & 0x3f) * (1.0F / 63.0F);
-               rgba[i][bComp] = ((p >> 11)       ) * (1.0F / 31.0F);
+               rgba[i][rComp] = ((p      ) & 0x1f) * rs;
+               rgba[i][gComp] = ((p >>  5) & 0x3f) * gs;
+               rgba[i][bComp] = ((p >> 11)       ) * bs;
                rgba[i][aComp] = 1.0F;
             }
          }
@@ -3568,24 +3681,27 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
             GLuint i;
             for (i = 0; i < n; i ++) {
                GLushort p = ussrc[i];
-               rgba[i][rComp] = ((p      ) & 0x1f) * (1.0F / 31.0F);
-               rgba[i][gComp] = ((p >>  5) & 0x3f) * (1.0F / 63.0F);
-               rgba[i][bComp] = ((p >> 11)       ) * (1.0F / 31.0F);
+               rgba[i][rComp] = ((p      ) & 0x1f) * rs;
+               rgba[i][gComp] = ((p >>  5) & 0x3f) * gs;
+               rgba[i][bComp] = ((p >> 11)       ) * bs;
                rgba[i][aComp] = 1.0F;
             }
          }
          break;
       case GL_UNSIGNED_SHORT_4_4_4_4:
+         if (!intFormat) {
+            rs = gs = bs = as = 1.0F / 15.0F;
+         }
          if (swapBytes) {
             const GLushort *ussrc = (const GLushort *) src;
             GLuint i;
             for (i = 0; i < n; i ++) {
                GLushort p = ussrc[i];
                SWAP2BYTE(p);
-               rgba[i][rComp] = ((p >> 12)      ) * (1.0F / 15.0F);
-               rgba[i][gComp] = ((p >>  8) & 0xf) * (1.0F / 15.0F);
-               rgba[i][bComp] = ((p >>  4) & 0xf) * (1.0F / 15.0F);
-               rgba[i][aComp] = ((p      ) & 0xf) * (1.0F / 15.0F);
+               rgba[i][rComp] = ((p >> 12)      ) * rs;
+               rgba[i][gComp] = ((p >>  8) & 0xf) * gs;
+               rgba[i][bComp] = ((p >>  4) & 0xf) * bs;
+               rgba[i][aComp] = ((p      ) & 0xf) * as;
             }
          }
          else {
@@ -3593,24 +3709,27 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
             GLuint i;
             for (i = 0; i < n; i ++) {
                GLushort p = ussrc[i];
-               rgba[i][rComp] = ((p >> 12)      ) * (1.0F / 15.0F);
-               rgba[i][gComp] = ((p >>  8) & 0xf) * (1.0F / 15.0F);
-               rgba[i][bComp] = ((p >>  4) & 0xf) * (1.0F / 15.0F);
-               rgba[i][aComp] = ((p      ) & 0xf) * (1.0F / 15.0F);
+               rgba[i][rComp] = ((p >> 12)      ) * rs;
+               rgba[i][gComp] = ((p >>  8) & 0xf) * gs;
+               rgba[i][bComp] = ((p >>  4) & 0xf) * bs;
+               rgba[i][aComp] = ((p      ) & 0xf) * as;
             }
          }
          break;
       case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+         if (!intFormat) {
+            rs = gs = bs = as = 1.0F / 15.0F;
+         }
          if (swapBytes) {
             const GLushort *ussrc = (const GLushort *) src;
             GLuint i;
             for (i = 0; i < n; i ++) {
                GLushort p = ussrc[i];
                SWAP2BYTE(p);
-               rgba[i][rComp] = ((p      ) & 0xf) * (1.0F / 15.0F);
-               rgba[i][gComp] = ((p >>  4) & 0xf) * (1.0F / 15.0F);
-               rgba[i][bComp] = ((p >>  8) & 0xf) * (1.0F / 15.0F);
-               rgba[i][aComp] = ((p >> 12)      ) * (1.0F / 15.0F);
+               rgba[i][rComp] = ((p      ) & 0xf) * rs;
+               rgba[i][gComp] = ((p >>  4) & 0xf) * gs;
+               rgba[i][bComp] = ((p >>  8) & 0xf) * bs;
+               rgba[i][aComp] = ((p >> 12)      ) * as;
             }
          }
          else {
@@ -3618,24 +3737,27 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
             GLuint i;
             for (i = 0; i < n; i ++) {
                GLushort p = ussrc[i];
-               rgba[i][rComp] = ((p      ) & 0xf) * (1.0F / 15.0F);
-               rgba[i][gComp] = ((p >>  4) & 0xf) * (1.0F / 15.0F);
-               rgba[i][bComp] = ((p >>  8) & 0xf) * (1.0F / 15.0F);
-               rgba[i][aComp] = ((p >> 12)      ) * (1.0F / 15.0F);
+               rgba[i][rComp] = ((p      ) & 0xf) * rs;
+               rgba[i][gComp] = ((p >>  4) & 0xf) * gs;
+               rgba[i][bComp] = ((p >>  8) & 0xf) * bs;
+               rgba[i][aComp] = ((p >> 12)      ) * as;
             }
          }
          break;
       case GL_UNSIGNED_SHORT_5_5_5_1:
+         if (!intFormat) {
+            rs = gs = bs = 1.0F / 31.0F;
+         }
          if (swapBytes) {
             const GLushort *ussrc = (const GLushort *) src;
             GLuint i;
             for (i = 0; i < n; i ++) {
                GLushort p = ussrc[i];
                SWAP2BYTE(p);
-               rgba[i][rComp] = ((p >> 11)       ) * (1.0F / 31.0F);
-               rgba[i][gComp] = ((p >>  6) & 0x1f) * (1.0F / 31.0F);
-               rgba[i][bComp] = ((p >>  1) & 0x1f) * (1.0F / 31.0F);
-               rgba[i][aComp] = ((p      ) & 0x1)  * (1.0F /  1.0F);
+               rgba[i][rComp] = ((p >> 11)       ) * rs;
+               rgba[i][gComp] = ((p >>  6) & 0x1f) * gs;
+               rgba[i][bComp] = ((p >>  1) & 0x1f) * bs;
+               rgba[i][aComp] = ((p      ) & 0x1)  * as;
             }
          }
          else {
@@ -3643,24 +3765,27 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
             GLuint i;
             for (i = 0; i < n; i ++) {
                GLushort p = ussrc[i];
-               rgba[i][rComp] = ((p >> 11)       ) * (1.0F / 31.0F);
-               rgba[i][gComp] = ((p >>  6) & 0x1f) * (1.0F / 31.0F);
-               rgba[i][bComp] = ((p >>  1) & 0x1f) * (1.0F / 31.0F);
-               rgba[i][aComp] = ((p      ) & 0x1)  * (1.0F /  1.0F);
+               rgba[i][rComp] = ((p >> 11)       ) * rs;
+               rgba[i][gComp] = ((p >>  6) & 0x1f) * gs;
+               rgba[i][bComp] = ((p >>  1) & 0x1f) * bs;
+               rgba[i][aComp] = ((p      ) & 0x1)  * as;
             }
          }
          break;
       case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+         if (!intFormat) {
+            rs = gs = bs = 1.0F / 31.0F;
+         }
          if (swapBytes) {
             const GLushort *ussrc = (const GLushort *) src;
             GLuint i;
             for (i = 0; i < n; i ++) {
                GLushort p = ussrc[i];
                SWAP2BYTE(p);
-               rgba[i][rComp] = ((p      ) & 0x1f) * (1.0F / 31.0F);
-               rgba[i][gComp] = ((p >>  5) & 0x1f) * (1.0F / 31.0F);
-               rgba[i][bComp] = ((p >> 10) & 0x1f) * (1.0F / 31.0F);
-               rgba[i][aComp] = ((p >> 15)       ) * (1.0F /  1.0F);
+               rgba[i][rComp] = ((p      ) & 0x1f) * rs;
+               rgba[i][gComp] = ((p >>  5) & 0x1f) * gs;
+               rgba[i][bComp] = ((p >> 10) & 0x1f) * bs;
+               rgba[i][aComp] = ((p >> 15)       ) * as;
             }
          }
          else {
@@ -3668,10 +3793,10 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
             GLuint i;
             for (i = 0; i < n; i ++) {
                GLushort p = ussrc[i];
-               rgba[i][rComp] = ((p      ) & 0x1f) * (1.0F / 31.0F);
-               rgba[i][gComp] = ((p >>  5) & 0x1f) * (1.0F / 31.0F);
-               rgba[i][bComp] = ((p >> 10) & 0x1f) * (1.0F / 31.0F);
-               rgba[i][aComp] = ((p >> 15)       ) * (1.0F /  1.0F);
+               rgba[i][rComp] = ((p      ) & 0x1f) * rs;
+               rgba[i][gComp] = ((p >>  5) & 0x1f) * gs;
+               rgba[i][bComp] = ((p >> 10) & 0x1f) * bs;
+               rgba[i][aComp] = ((p >> 15)       ) * as;
             }
          }
          break;
@@ -3679,23 +3804,45 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
          if (swapBytes) {
             const GLuint *uisrc = (const GLuint *) src;
             GLuint i;
-            for (i = 0; i < n; i ++) {
-               GLuint p = uisrc[i];
-               rgba[i][rComp] = UBYTE_TO_FLOAT((p      ) & 0xff);
-               rgba[i][gComp] = UBYTE_TO_FLOAT((p >>  8) & 0xff);
-               rgba[i][bComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff);
-               rgba[i][aComp] = UBYTE_TO_FLOAT((p >> 24)       );
+            if (intFormat) {
+               for (i = 0; i < n; i ++) {
+                  GLuint p = uisrc[i];
+                  rgba[i][rComp] = (GLfloat) ((p      ) & 0xff);
+                  rgba[i][gComp] = (GLfloat) ((p >>  8) & 0xff);
+                  rgba[i][bComp] = (GLfloat) ((p >> 16) & 0xff);
+                  rgba[i][aComp] = (GLfloat) ((p >> 24)       );
+               }
+            }
+            else {
+               for (i = 0; i < n; i ++) {
+                  GLuint p = uisrc[i];
+                  rgba[i][rComp] = UBYTE_TO_FLOAT((p      ) & 0xff);
+                  rgba[i][gComp] = UBYTE_TO_FLOAT((p >>  8) & 0xff);
+                  rgba[i][bComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff);
+                  rgba[i][aComp] = UBYTE_TO_FLOAT((p >> 24)       );
+               }
             }
          }
          else {
             const GLuint *uisrc = (const GLuint *) src;
             GLuint i;
-            for (i = 0; i < n; i ++) {
-               GLuint p = uisrc[i];
-               rgba[i][rComp] = UBYTE_TO_FLOAT((p >> 24)       );
-               rgba[i][gComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff);
-               rgba[i][bComp] = UBYTE_TO_FLOAT((p >>  8) & 0xff);
-               rgba[i][aComp] = UBYTE_TO_FLOAT((p      ) & 0xff);
+            if (intFormat) {
+               for (i = 0; i < n; i ++) {
+                  GLuint p = uisrc[i];
+                  rgba[i][rComp] = (GLfloat) ((p >> 24)       );
+                  rgba[i][gComp] = (GLfloat) ((p >> 16) & 0xff);
+                  rgba[i][bComp] = (GLfloat) ((p >>  8) & 0xff);
+                  rgba[i][aComp] = (GLfloat) ((p      ) & 0xff);
+               }
+            }
+            else {
+               for (i = 0; i < n; i ++) {
+                  GLuint p = uisrc[i];
+                  rgba[i][rComp] = UBYTE_TO_FLOAT((p >> 24)       );
+                  rgba[i][gComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff);
+                  rgba[i][bComp] = UBYTE_TO_FLOAT((p >>  8) & 0xff);
+                  rgba[i][aComp] = UBYTE_TO_FLOAT((p      ) & 0xff);
+               }
             }
          }
          break;
@@ -3703,37 +3850,65 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
          if (swapBytes) {
             const GLuint *uisrc = (const GLuint *) src;
             GLuint i;
-            for (i = 0; i < n; i ++) {
-               GLuint p = uisrc[i];
-               rgba[i][rComp] = UBYTE_TO_FLOAT((p >> 24)       );
-               rgba[i][gComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff);
-               rgba[i][bComp] = UBYTE_TO_FLOAT((p >>  8) & 0xff);
-               rgba[i][aComp] = UBYTE_TO_FLOAT((p      ) & 0xff);
+            if (intFormat) {
+               for (i = 0; i < n; i ++) {
+                  GLuint p = uisrc[i];
+                  rgba[i][rComp] = (GLfloat) ((p >> 24)       );
+                  rgba[i][gComp] = (GLfloat) ((p >> 16) & 0xff);
+                  rgba[i][bComp] = (GLfloat) ((p >>  8) & 0xff);
+                  rgba[i][aComp] = (GLfloat) ((p      ) & 0xff);
+               }
+            }
+            else {
+               for (i = 0; i < n; i ++) {
+                  GLuint p = uisrc[i];
+                  rgba[i][rComp] = UBYTE_TO_FLOAT((p >> 24)       );
+                  rgba[i][gComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff);
+                  rgba[i][bComp] = UBYTE_TO_FLOAT((p >>  8) & 0xff);
+                  rgba[i][aComp] = UBYTE_TO_FLOAT((p      ) & 0xff);
+               }
             }
          }
          else {
             const GLuint *uisrc = (const GLuint *) src;
             GLuint i;
-            for (i = 0; i < n; i ++) {
-               GLuint p = uisrc[i];
-               rgba[i][rComp] = UBYTE_TO_FLOAT((p      ) & 0xff);
-               rgba[i][gComp] = UBYTE_TO_FLOAT((p >>  8) & 0xff);
-               rgba[i][bComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff);
-               rgba[i][aComp] = UBYTE_TO_FLOAT((p >> 24)       );
+            if (intFormat) {
+               for (i = 0; i < n; i ++) {
+                  GLuint p = uisrc[i];
+                  rgba[i][rComp] = (GLfloat) ((p      ) & 0xff);
+                  rgba[i][gComp] = (GLfloat) ((p >>  8) & 0xff);
+                  rgba[i][bComp] = (GLfloat) ((p >> 16) & 0xff);
+                  rgba[i][aComp] = (GLfloat) ((p >> 24)       );
+               }
+            }
+            else {
+               for (i = 0; i < n; i ++) {
+                  GLuint p = uisrc[i];
+                  rgba[i][rComp] = UBYTE_TO_FLOAT((p      ) & 0xff);
+                  rgba[i][gComp] = UBYTE_TO_FLOAT((p >>  8) & 0xff);
+                  rgba[i][bComp] = UBYTE_TO_FLOAT((p >> 16) & 0xff);
+                  rgba[i][aComp] = UBYTE_TO_FLOAT((p >> 24)       );
+               }
             }
          }
          break;
       case GL_UNSIGNED_INT_10_10_10_2:
+         if (!intFormat) {
+            rs = 1.0F / 1023.0F;
+            gs = 1.0F / 1023.0F;
+            bs = 1.0F / 1023.0F;
+            as = 1.0F / 3.0F;
+         }
          if (swapBytes) {
             const GLuint *uisrc = (const GLuint *) src;
             GLuint i;
             for (i = 0; i < n; i ++) {
                GLuint p = uisrc[i];
                SWAP4BYTE(p);
-               rgba[i][rComp] = ((p >> 22)        ) * (1.0F / 1023.0F);
-               rgba[i][gComp] = ((p >> 12) & 0x3ff) * (1.0F / 1023.0F);
-               rgba[i][bComp] = ((p >>  2) & 0x3ff) * (1.0F / 1023.0F);
-               rgba[i][aComp] = ((p      ) & 0x3  ) * (1.0F /    3.0F);
+               rgba[i][rComp] = ((p >> 22)        ) * rs;
+               rgba[i][gComp] = ((p >> 12) & 0x3ff) * gs;
+               rgba[i][bComp] = ((p >>  2) & 0x3ff) * bs;
+               rgba[i][aComp] = ((p      ) & 0x3  ) * as;
             }
          }
          else {
@@ -3741,24 +3916,30 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
             GLuint i;
             for (i = 0; i < n; i ++) {
                GLuint p = uisrc[i];
-               rgba[i][rComp] = ((p >> 22)        ) * (1.0F / 1023.0F);
-               rgba[i][gComp] = ((p >> 12) & 0x3ff) * (1.0F / 1023.0F);
-               rgba[i][bComp] = ((p >>  2) & 0x3ff) * (1.0F / 1023.0F);
-               rgba[i][aComp] = ((p      ) & 0x3  ) * (1.0F /    3.0F);
+               rgba[i][rComp] = ((p >> 22)        ) * rs;
+               rgba[i][gComp] = ((p >> 12) & 0x3ff) * gs;
+               rgba[i][bComp] = ((p >>  2) & 0x3ff) * bs;
+               rgba[i][aComp] = ((p      ) & 0x3  ) * as;
             }
          }
          break;
       case GL_UNSIGNED_INT_2_10_10_10_REV:
+         if (!intFormat) {
+            rs = 1.0F / 1023.0F;
+            gs = 1.0F / 1023.0F;
+            bs = 1.0F / 1023.0F;
+            as = 1.0F / 3.0F;
+         }
          if (swapBytes) {
             const GLuint *uisrc = (const GLuint *) src;
             GLuint i;
             for (i = 0; i < n; i ++) {
                GLuint p = uisrc[i];
                SWAP4BYTE(p);
-               rgba[i][rComp] = ((p      ) & 0x3ff) * (1.0F / 1023.0F);
-               rgba[i][gComp] = ((p >> 10) & 0x3ff) * (1.0F / 1023.0F);
-               rgba[i][bComp] = ((p >> 20) & 0x3ff) * (1.0F / 1023.0F);
-               rgba[i][aComp] = ((p >> 30)        ) * (1.0F /    3.0F);
+               rgba[i][rComp] = ((p      ) & 0x3ff) * rs;
+               rgba[i][gComp] = ((p >> 10) & 0x3ff) * gs;
+               rgba[i][bComp] = ((p >> 20) & 0x3ff) * bs;
+               rgba[i][aComp] = ((p >> 30)        ) * as;
             }
          }
          else {
@@ -3766,10 +3947,10 @@ extract_float_rgba(GLuint n, GLfloat rgba[][4],
             GLuint i;
             for (i = 0; i < n; i ++) {
                GLuint p = uisrc[i];
-               rgba[i][rComp] = ((p      ) & 0x3ff) * (1.0F / 1023.0F);
-               rgba[i][gComp] = ((p >> 10) & 0x3ff) * (1.0F / 1023.0F);
-               rgba[i][bComp] = ((p >> 20) & 0x3ff) * (1.0F / 1023.0F);
-               rgba[i][aComp] = ((p >> 30)        ) * (1.0F /    3.0F);
+               rgba[i][rComp] = ((p      ) & 0x3ff) * rs;
+               rgba[i][gComp] = ((p >> 10) & 0x3ff) * gs;
+               rgba[i][bComp] = ((p >> 20) & 0x3ff) * bs;
+               rgba[i][aComp] = ((p >> 30)        ) * as;
             }
          }
          break;
@@ -4161,6 +4342,16 @@ _mesa_unpack_color_span_float( GLcontext *ctx,
           srcFormat == GL_RGBA ||
           srcFormat == GL_BGRA ||
           srcFormat == GL_ABGR_EXT ||
+          srcFormat == GL_RED_INTEGER_EXT ||
+          srcFormat == GL_GREEN_INTEGER_EXT ||
+          srcFormat == GL_BLUE_INTEGER_EXT ||
+          srcFormat == GL_ALPHA_INTEGER_EXT ||
+          srcFormat == GL_RGB_INTEGER_EXT ||
+          srcFormat == GL_RGBA_INTEGER_EXT ||
+          srcFormat == GL_BGR_INTEGER_EXT ||
+          srcFormat == GL_BGRA_INTEGER_EXT ||
+          srcFormat == GL_LUMINANCE_INTEGER_EXT ||
+          srcFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT ||
           srcFormat == GL_COLOR_INDEX);
 
    ASSERT(srcType == GL_BITMAP ||
index 48582eb3bbe1490464a1a3b81e3ba363cad5d9ef..8b180d6bfe603aa5a6d98b73ef1b000de052314c 100644 (file)
@@ -78,6 +78,9 @@ _mesa_is_depth_or_stencil_format(GLenum format);
 extern GLboolean
 _mesa_is_dudv_format(GLenum format);
 
+extern GLboolean
+_mesa_is_integer_format(GLenum format);
+
 extern GLboolean
 _mesa_is_compressed_format(GLcontext *ctx, GLenum format);
 
index 25080db40c43f3b1ad8af3018b9c1ba2c7c05104..c399351096717ece4f6bde12e25e9332e2fe442a 100644 (file)
@@ -756,7 +756,7 @@ _mesa_strdup( const char *s )
 float
 _mesa_strtof( const char *s, char **end )
 {
-#ifdef _GNU_SOURCE
+#if defined(_GNU_SOURCE) && !defined(__CYGWIN__)
    static locale_t loc = NULL;
    if (!loc) {
       loc = newlocale(LC_CTYPE_MASK, "C", NULL);
index da825a095ea586dc977cc5272f8fe3e3c84ad080..9c2ffd66d69908dc74ce0b19c520e448ee684c77 100644 (file)
@@ -444,42 +444,6 @@ _mesa_next_pow_two_64(uint64_t x)
 }
 
 
-/***
- *** UNCLAMPED_FLOAT_TO_UBYTE: clamp float to [0,1] and map to ubyte in [0,255]
- *** CLAMPED_FLOAT_TO_UBYTE: map float known to be in [0,1] to ubyte in [0,255]
- ***/
-#if defined(USE_IEEE) && !defined(DEBUG)
-#define IEEE_0996 0x3f7f0000   /* 0.996 or so */
-/* This function/macro is sensitive to precision.  Test very carefully
- * if you change it!
- */
-#define UNCLAMPED_FLOAT_TO_UBYTE(UB, F)                                        \
-        do {                                                           \
-           fi_type __tmp;                                              \
-           __tmp.f = (F);                                              \
-           if (__tmp.i < 0)                                            \
-              UB = (GLubyte) 0;                                                \
-           else if (__tmp.i >= IEEE_0996)                              \
-              UB = (GLubyte) 255;                                      \
-           else {                                                      \
-              __tmp.f = __tmp.f * (255.0F/256.0F) + 32768.0F;          \
-              UB = (GLubyte) __tmp.i;                                  \
-           }                                                           \
-        } while (0)
-#define CLAMPED_FLOAT_TO_UBYTE(UB, F)                                  \
-        do {                                                           \
-           fi_type __tmp;                                              \
-           __tmp.f = (F) * (255.0F/256.0F) + 32768.0F;                 \
-           UB = (GLubyte) __tmp.i;                                     \
-        } while (0)
-#else
-#define UNCLAMPED_FLOAT_TO_UBYTE(ub, f) \
-       ub = ((GLubyte) IROUND(CLAMP((f), 0.0F, 1.0F) * 255.0F))
-#define CLAMPED_FLOAT_TO_UBYTE(ub, f) \
-       ub = ((GLubyte) IROUND((f) * 255.0F))
-#endif
-
-
 /**
  * Return 1 if this is a little endian machine, 0 if big endian.
  */
index 40e17e53d6ce1f2bf383f39836609d2eb47e5ec1..b2ec0ba9b73fbf91c4ade70ec558eac29f0ffbf7 100644 (file)
@@ -130,6 +130,41 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256];
 #define UNCLAMPED_FLOAT_TO_SHORT(s, f)  \
         s = ( (GLshort) IROUND( CLAMP((f), -1.0F, 1.0F) * 32767.0F) )
 
+/***
+ *** UNCLAMPED_FLOAT_TO_UBYTE: clamp float to [0,1] and map to ubyte in [0,255]
+ *** CLAMPED_FLOAT_TO_UBYTE: map float known to be in [0,1] to ubyte in [0,255]
+ ***/
+#if defined(USE_IEEE) && !defined(DEBUG)
+#define IEEE_0996 0x3f7f0000   /* 0.996 or so */
+/* This function/macro is sensitive to precision.  Test very carefully
+ * if you change it!
+ */
+#define UNCLAMPED_FLOAT_TO_UBYTE(UB, F)                                        \
+        do {                                                           \
+           fi_type __tmp;                                              \
+           __tmp.f = (F);                                              \
+           if (__tmp.i < 0)                                            \
+              UB = (GLubyte) 0;                                                \
+           else if (__tmp.i >= IEEE_0996)                              \
+              UB = (GLubyte) 255;                                      \
+           else {                                                      \
+              __tmp.f = __tmp.f * (255.0F/256.0F) + 32768.0F;          \
+              UB = (GLubyte) __tmp.i;                                  \
+           }                                                           \
+        } while (0)
+#define CLAMPED_FLOAT_TO_UBYTE(UB, F)                                  \
+        do {                                                           \
+           fi_type __tmp;                                              \
+           __tmp.f = (F) * (255.0F/256.0F) + 32768.0F;                 \
+           UB = (GLubyte) __tmp.i;                                     \
+        } while (0)
+#else
+#define UNCLAMPED_FLOAT_TO_UBYTE(ub, f) \
+       ub = ((GLubyte) IROUND(CLAMP((f), 0.0F, 1.0F) * 255.0F))
+#define CLAMPED_FLOAT_TO_UBYTE(ub, f) \
+       ub = ((GLubyte) IROUND((f) * 255.0F))
+#endif
+
 /*@}*/
 
 
index 6ed05da7ac84446683e0b2115cf4c68c91382731..4e838abe0369a8f0cf4fb1bbb5881909a50c09f3 100644 (file)
 #define FEATURE_ARB_shader_objects        (FEATURE_ARB_vertex_shader || FEATURE_ARB_fragment_shader)
 #define FEATURE_ARB_shading_language_100  FEATURE_ARB_shader_objects
 #define FEATURE_ARB_shading_language_120  FEATURE_ARB_shader_objects
+#define FEATURE_ARB_geometry_shader4      FEATURE_ARB_shader_objects
 
 #define FEATURE_ARB_framebuffer_object    (FEATURE_GL && FEATURE_EXT_framebuffer_object)
 #define FEATURE_ARB_map_buffer_range      FEATURE_GL
index f8257d565bf48ca535dba1058c48f21ee2410daf..f17529c6c73ce7a841f2d9e8d9e65f1ccec8b1f2 100644 (file)
 #include "math/m_matrix.h"     /* GLmatrix */
 #include "main/simple_list.h"  /* struct simple_node */
 
+/**
+ * Internal token
+ *  Must be simply different than GL_VERTEX_PROGRAM
+ *    and GL_FRAGMENT_PROGRAM_ARB
+ *  FIXME: this will have to be a real GL extension
+ */
+#define MESA_GEOMETRY_PROGRAM 0x9999
 
 /**
  * Color channel data type.
@@ -238,6 +245,78 @@ typedef enum
 } gl_vert_result;
 
 
+/*********************************************/
+
+/**
+ * Indexes for geometry program attributes.
+ */
+typedef enum
+{
+   GEOM_ATTRIB_POSITION = 0,
+   GEOM_ATTRIB_COLOR0 = 1,
+   GEOM_ATTRIB_COLOR1 = 2,
+   GEOM_ATTRIB_SECONDARY_COLOR0 = 3,
+   GEOM_ATTRIB_SECONDARY_COLOR1 = 4,
+   GEOM_ATTRIB_FOG_FRAG_COORD = 5,
+   GEOM_ATTRIB_POINT_SIZE = 6,
+   GEOM_ATTRIB_CLIP_VERTEX = 7,
+   GEOM_ATTRIB_PRIMITIVE_ID = 8,
+   GEOM_ATTRIB_TEX_COORD = 9,
+
+   GEOM_ATTRIB_VAR0 = 16,
+   GEOM_ATTRIB_MAX = (GEOM_ATTRIB_VAR0 + MAX_VARYING)
+} gl_geom_attrib;
+
+/**
+ * Bitflags for geometry attributes.
+ * These are used in bitfields in many places.
+ */
+/*@{*/
+#define GEOM_BIT_COLOR0      (1 << GEOM_ATTRIB_COLOR0)
+#define GEOM_BIT_COLOR1      (1 << GEOM_ATTRIB_COLOR1)
+#define GEOM_BIT_SCOLOR0     (1 << GEOM_ATTRIB_SECONDARY_COLOR0)
+#define GEOM_BIT_SCOLOR1     (1 << GEOM_ATTRIB_SECONDARY_COLOR1)
+#define GEOM_BIT_TEX_COORD   (1 << GEOM_ATTRIB_TEX_COORD)
+#define GEOM_BIT_FOG_COORD   (1 << GEOM_ATTRIB_FOG_FRAG_COORD)
+#define GEOM_BIT_POSITION    (1 << GEOM_ATTRIB_POSITION)
+#define GEOM_BIT_POINT_SIDE  (1 << GEOM_ATTRIB_POINT_SIZE)
+#define GEOM_BIT_CLIP_VERTEX (1 << GEOM_ATTRIB_CLIP_VERTEX)
+#define GEOM_BIT_PRIM_ID     (1 << GEOM_ATTRIB_PRIMITIVE_ID)
+#define GEOM_BIT_VAR0        (1 << GEOM_ATTRIB_VAR0)
+
+#define GEOM_BIT_VAR(g)  (1 << (GEOM_BIT_VAR0 + (g)))
+/*@}*/
+
+
+/**
+ * Indexes for geometry program result attributes
+ */
+/*@{*/
+typedef enum {
+   GEOM_RESULT_POS  = 0,
+   GEOM_RESULT_COL0  = 1,
+   GEOM_RESULT_COL1  = 2,
+   GEOM_RESULT_SCOL0 = 3,
+   GEOM_RESULT_SCOL1 = 4,
+   GEOM_RESULT_FOGC = 5,
+   GEOM_RESULT_TEX0 = 6,
+   GEOM_RESULT_TEX1 = 7,
+   GEOM_RESULT_TEX2 = 8,
+   GEOM_RESULT_TEX3 = 9,
+   GEOM_RESULT_TEX4 = 10,
+   GEOM_RESULT_TEX5 = 11,
+   GEOM_RESULT_TEX6 = 12,
+   GEOM_RESULT_TEX7 = 13,
+   GEOM_RESULT_PSIZ = 14,
+   GEOM_RESULT_CLPV = 15,
+   GEOM_RESULT_PRID = 16,
+   GEOM_RESULT_LAYR = 17,
+   GEOM_RESULT_VAR0 = 18,  /**< shader varying, should really be 16 */
+   /* ### we need to -2 because var0 is 18 instead 16 like in the others */
+   GEOM_RESULT_MAX  =  (GEOM_RESULT_VAR0 + MAX_VARYING - 2)
+} gl_geom_result;
+/*@}*/
+
 /**
  * Indexes for fragment program input attributes.
  */
@@ -1763,6 +1842,18 @@ struct gl_vertex_program
 };
 
 
+/** Geometry program object */
+struct gl_geometry_program
+{
+   struct gl_program Base;   /**< base class */
+
+   GLint VerticesOut;
+   GLenum InputType;  /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB,
+                           GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */
+   GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */
+};
+
+
 /** Fragment program object */
 struct gl_fragment_program
 {
@@ -1820,6 +1911,26 @@ struct gl_vertex_program_state
 };
 
 
+/**
+ * Context state for geometry programs.
+ */
+struct gl_geometry_program_state
+{
+   GLboolean Enabled;               /**< GL_ARB_GEOMETRY_SHADER4 */
+   GLboolean _Enabled;              /**< Enabled and valid program? */
+   struct gl_geometry_program *Current;  /**< user-bound geometry program */
+
+   /** Currently enabled and valid program (including internal programs
+    * and compiled shader programs).
+    */
+   struct gl_geometry_program *_Current;
+
+   GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */
+
+   /** Cache of fixed-function programs */
+   struct gl_program_cache *Cache;
+};
+
 /**
  * Context state for fragment programs.
  */
@@ -1920,6 +2031,9 @@ struct gl_query_state
    struct gl_query_object *PrimitivesGenerated;
    struct gl_query_object *PrimitivesWritten;
 
+   /** GL_ARB_timer_query */
+   struct gl_query_object *TimeElapsed;
+
    GLenum CondRenderMode;
 };
 
@@ -1954,7 +2068,7 @@ struct gl_sl_pragmas
  */
 struct gl_shader
 {
-   GLenum Type;  /**< GL_FRAGMENT_SHADER || GL_VERTEX_SHADER (first field!) */
+   GLenum Type;  /**< GL_FRAGMENT_SHADER || GL_VERTEX_SHADER || GL_GEOMETRY_SHADER_ARB (first field!) */
    GLuint Name;  /**< AKA the handle */
    GLint RefCount;  /**< Reference count */
    GLboolean DeletePending;
@@ -2002,9 +2116,18 @@ struct gl_shader_program
       GLchar **VaryingNames;  /**< Array [NumVarying] of char * */
    } TransformFeedback;
 
+   /** Geometry shader state - copied into gl_geometry_program at link time */
+   struct {
+      GLint VerticesOut;
+      GLenum InputType;  /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB,
+                              GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */
+      GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */
+   } Geom;
+
    /* post-link info: */
    struct gl_vertex_program *VertexProgram;     /**< Linked vertex program */
    struct gl_fragment_program *FragmentProgram; /**< Linked fragment prog */
+   struct gl_geometry_program *GeometryProgram; /**< Linked geometry prog */
    struct gl_uniform_list *Uniforms;
    struct gl_program_parameter_list *Varying;
    GLboolean LinkStatus;   /**< GL_LINK_STATUS */
@@ -2133,7 +2256,7 @@ struct gl_shared_state
    struct gl_buffer_object *NullBufferObj;
 
    /**
-    * \name Vertex/fragment programs
+    * \name Vertex/geometry/fragment programs
     */
    /*@{*/
    struct _mesa_HashTable *Programs; /**< All vertex/fragment programs */
@@ -2142,6 +2265,9 @@ struct gl_shared_state
 #endif
 #if FEATURE_ARB_fragment_program
    struct gl_fragment_program *DefaultFragmentProgram;
+#endif
+#if FEATURE_ARB_geometry_shader4
+   struct gl_geometry_program *DefaultGeometryProgram;
 #endif
    /*@}*/
 
@@ -2401,6 +2527,14 @@ struct gl_program_constants
    GLuint MaxNativeParameters;
    /* For shaders */
    GLuint MaxUniformComponents;
+#if FEATURE_ARB_geometry_shader4
+   GLuint MaxGeometryTextureImageUnits;
+   GLuint MaxGeometryVaryingComponents;
+   GLuint MaxVertexVaryingComponents;
+   GLuint MaxGeometryUniformComponents;
+   GLuint MaxGeometryOutputVertices;
+   GLuint MaxGeometryTotalOutputComponents;
+#endif
 };
 
 
@@ -2447,6 +2581,7 @@ struct gl_constants
 
    struct gl_program_constants VertexProgram;   /**< GL_ARB_vertex_program */
    struct gl_program_constants FragmentProgram; /**< GL_ARB_fragment_program */
+   struct gl_program_constants GeometryProgram;  /**< GL_ARB_geometry_shader4 */
    GLuint MaxProgramMatrices;
    GLuint MaxProgramMatrixStackDepth;
 
@@ -2491,9 +2626,11 @@ struct gl_constants
 struct gl_extensions
 {
    GLboolean dummy;  /* don't remove this! */
+   GLboolean ARB_blend_func_extended;
    GLboolean ARB_copy_buffer;
-   GLboolean ARB_depth_texture;
+   GLboolean ARB_depth_buffer_float;
    GLboolean ARB_depth_clamp;
+   GLboolean ARB_depth_texture;
    GLboolean ARB_draw_buffers;
    GLboolean ARB_draw_elements_base_vertex;
    GLboolean ARB_draw_instanced;
@@ -2502,22 +2639,28 @@ struct gl_extensions
    GLboolean ARB_fragment_program_shadow;
    GLboolean ARB_fragment_shader;
    GLboolean ARB_framebuffer_object;
+   GLboolean ARB_explicit_attrib_location;
+   GLboolean ARB_geometry_shader4;
    GLboolean ARB_half_float_pixel;
    GLboolean ARB_half_float_vertex;
    GLboolean ARB_imaging;
+   GLboolean ARB_instanced_arrays;
    GLboolean ARB_map_buffer_range;
    GLboolean ARB_multisample;
    GLboolean ARB_multitexture;
    GLboolean ARB_occlusion_query;
+   GLboolean ARB_occlusion_query2;
    GLboolean ARB_point_sprite;
+   GLboolean ARB_sampler_objects;
    GLboolean ARB_seamless_cube_map;
    GLboolean ARB_shader_objects;
    GLboolean ARB_shading_language_100;
    GLboolean ARB_shading_language_120;
    GLboolean ARB_shadow;
-   GLboolean ARB_shadow_ambient; /* or GL_ARB_shadow_ambient */
+   GLboolean ARB_shadow_ambient;
    GLboolean ARB_sync;
    GLboolean ARB_texture_border_clamp;
+   GLboolean ARB_texture_buffer_object;
    GLboolean ARB_texture_compression;
    GLboolean ARB_texture_cube_map;
    GLboolean ARB_texture_env_combine;
@@ -2525,13 +2668,19 @@ struct gl_extensions
    GLboolean ARB_texture_env_dot3;
    GLboolean ARB_texture_float;
    GLboolean ARB_texture_mirrored_repeat;
+   GLboolean ARB_texture_multisample;
    GLboolean ARB_texture_non_power_of_two;
+   GLboolean ARB_texture_rg;
+   GLboolean ARB_texture_rgb10_a2ui;
+   GLboolean ARB_timer_query;
    GLboolean ARB_transform_feedback2;
    GLboolean ARB_transpose_matrix;
+   GLboolean ARB_uniform_buffer_object;
    GLboolean ARB_vertex_array_object;
    GLboolean ARB_vertex_buffer_object;
    GLboolean ARB_vertex_program;
    GLboolean ARB_vertex_shader;
+   GLboolean ARB_vertex_type_2_10_10_10_rev;
    GLboolean ARB_window_pos;
    GLboolean EXT_abgr;
    GLboolean EXT_bgra;
@@ -2553,11 +2702,13 @@ struct gl_extensions
    GLboolean EXT_framebuffer_blit;
    GLboolean EXT_framebuffer_multisample;
    GLboolean EXT_framebuffer_object;
+   GLboolean EXT_framebuffer_sRGB;
    GLboolean EXT_gpu_program_parameters;
    GLboolean EXT_histogram;
    GLboolean EXT_multi_draw_arrays;
    GLboolean EXT_paletted_texture;
    GLboolean EXT_packed_depth_stencil;
+   GLboolean EXT_packed_float;
    GLboolean EXT_packed_pixels;
    GLboolean EXT_pixel_buffer_object;
    GLboolean EXT_point_parameters;
@@ -2576,12 +2727,15 @@ struct gl_extensions
    GLboolean EXT_texture3D;
    GLboolean EXT_texture_array;
    GLboolean EXT_texture_compression_s3tc;
+   GLboolean EXT_texture_compression_rgtc;
    GLboolean EXT_texture_env_add;
    GLboolean EXT_texture_env_combine;
    GLboolean EXT_texture_env_dot3;
    GLboolean EXT_texture_filter_anisotropic;
+   GLboolean EXT_texture_integer;
    GLboolean EXT_texture_lod_bias;
    GLboolean EXT_texture_mirror_clamp;
+   GLboolean EXT_texture_shared_exponent;
    GLboolean EXT_texture_sRGB;
    GLboolean EXT_texture_swizzle;
    GLboolean EXT_transform_feedback;
@@ -2613,6 +2767,7 @@ struct gl_extensions
    GLboolean NV_fragment_program_option;
    GLboolean NV_light_max_exponent;
    GLboolean NV_point_sprite;
+   GLboolean NV_primitive_restart;
    GLboolean NV_texgen_reflection;
    GLboolean NV_texture_env_combine4;
    GLboolean NV_texture_rectangle;
@@ -3058,6 +3213,7 @@ struct __GLcontextRec
    struct gl_program_state Program;  /**< general program state */
    struct gl_vertex_program_state VertexProgram;
    struct gl_fragment_program_state FragmentProgram;
+   struct gl_geometry_program_state GeometryProgram;
    struct gl_ati_fragment_shader_state ATIFragmentShader;
 
    struct gl_shader_state Shader; /**< GLSL shader object state */
diff --git a/src/mesa/main/nvprogram.c b/src/mesa/main/nvprogram.c
new file mode 100644 (file)
index 0000000..100ff2c
--- /dev/null
@@ -0,0 +1,917 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.2
+ *
+ * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file nvprogram.c
+ * NVIDIA vertex/fragment program state management functions.
+ * \author Brian Paul
+ */
+
+/*
+ * Regarding GL_NV_fragment/vertex_program, GL_NV_vertex_program1_1, etc:
+ *
+ * Portions of this software may use or implement intellectual
+ * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims
+ * any and all warranties with respect to such intellectual property,
+ * including any use thereof or modifications thereto.
+ */
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/hash.h"
+#include "main/imports.h"
+#include "main/macros.h"
+#include "main/nvprogram.h"
+#include "program/arbprogparse.h"
+#include "program/nvfragparse.h"
+#include "program/nvvertparse.h"
+#include "program/program.h"
+#include "program/prog_instruction.h"
+#include "program/prog_parameter.h"
+
+
+
+/**
+ * Execute a vertex state program.
+ * \note Called from the GL API dispatcher.
+ */
+void GLAPIENTRY
+_mesa_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params)
+{
+   struct gl_vertex_program *vprog;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (target != GL_VERTEX_STATE_PROGRAM_NV) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glExecuteProgramNV");
+      return;
+   }
+
+   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+
+   vprog = (struct gl_vertex_program *) _mesa_lookup_program(ctx, id);
+
+   if (!vprog || vprog->Base.Target != GL_VERTEX_STATE_PROGRAM_NV) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glExecuteProgramNV");
+      return;
+   }
+   
+   _mesa_problem(ctx, "glExecuteProgramNV() not supported");
+}
+
+
+/**
+ * Determine if a set of programs is resident in hardware.
+ * \note Not compiled into display lists.
+ * \note Called from the GL API dispatcher.
+ */
+GLboolean GLAPIENTRY
+_mesa_AreProgramsResidentNV(GLsizei n, const GLuint *ids,
+                            GLboolean *residences)
+{
+   GLint i, j;
+   GLboolean allResident = GL_TRUE;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+
+   if (n < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glAreProgramsResidentNV(n)");
+      return GL_FALSE;
+   }
+
+   for (i = 0; i < n; i++) {
+      const struct gl_program *prog;
+      if (ids[i] == 0) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glAreProgramsResidentNV");
+         return GL_FALSE;
+      }
+      prog = _mesa_lookup_program(ctx, ids[i]);
+      if (!prog) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glAreProgramsResidentNV");
+         return GL_FALSE;
+      }
+      if (prog->Resident) {
+        if (!allResident)
+           residences[i] = GL_TRUE;
+      }
+      else {
+         if (allResident) {
+           allResident = GL_FALSE;
+           for (j = 0; j < i; j++)
+              residences[j] = GL_TRUE;
+        }
+        residences[i] = GL_FALSE;
+      }
+   }
+
+   return allResident;
+}
+
+
+/**
+ * Request that a set of programs be resident in hardware.
+ * \note Called from the GL API dispatcher.
+ */
+void GLAPIENTRY
+_mesa_RequestResidentProgramsNV(GLsizei n, const GLuint *ids)
+{
+   GLint i;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (n < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glRequestResidentProgramsNV(n)");
+      return;
+   }
+
+   /* just error checking for now */
+   for (i = 0; i < n; i++) {
+      struct gl_program *prog;
+
+      if (ids[i] == 0) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glRequestResidentProgramsNV(id)");
+         return;
+      }
+
+      prog = _mesa_lookup_program(ctx, ids[i]);
+      if (!prog) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glRequestResidentProgramsNV(id)");
+         return;
+      }
+
+      /* XXX this is really a hardware thing we should hook out */
+      prog->Resident = GL_TRUE;
+   }
+}
+
+
+/**
+ * Get a program parameter register.
+ * \note Not compiled into display lists.
+ * \note Called from the GL API dispatcher.
+ */
+void GLAPIENTRY
+_mesa_GetProgramParameterfvNV(GLenum target, GLuint index,
+                              GLenum pname, GLfloat *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (target == GL_VERTEX_PROGRAM_NV) {
+      if (pname == GL_PROGRAM_PARAMETER_NV) {
+         if (index < MAX_NV_VERTEX_PROGRAM_PARAMS) {
+            COPY_4V(params, ctx->VertexProgram.Parameters[index]);
+         }
+         else {
+            _mesa_error(ctx, GL_INVALID_VALUE,
+                        "glGetProgramParameterfvNV(index)");
+            return;
+         }
+      }
+      else {
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramParameterfvNV(pname)");
+         return;
+      }
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramParameterfvNV(target)");
+      return;
+   }
+}
+
+
+/**
+ * Get a program parameter register.
+ * \note Not compiled into display lists.
+ * \note Called from the GL API dispatcher.
+ */
+void GLAPIENTRY
+_mesa_GetProgramParameterdvNV(GLenum target, GLuint index,
+                              GLenum pname, GLdouble *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (target == GL_VERTEX_PROGRAM_NV) {
+      if (pname == GL_PROGRAM_PARAMETER_NV) {
+         if (index < MAX_NV_VERTEX_PROGRAM_PARAMS) {
+            COPY_4V(params, ctx->VertexProgram.Parameters[index]);
+         }
+         else {
+            _mesa_error(ctx, GL_INVALID_VALUE,
+                        "glGetProgramParameterdvNV(index)");
+            return;
+         }
+      }
+      else {
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramParameterdvNV(pname)");
+         return;
+      }
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramParameterdvNV(target)");
+      return;
+   }
+}
+
+
+/**
+ * Get a program attribute.
+ * \note Not compiled into display lists.
+ * \note Called from the GL API dispatcher.
+ */
+void GLAPIENTRY
+_mesa_GetProgramivNV(GLuint id, GLenum pname, GLint *params)
+{
+   struct gl_program *prog;
+   GET_CURRENT_CONTEXT(ctx);
+
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   prog = _mesa_lookup_program(ctx, id);
+   if (!prog) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramivNV");
+      return;
+   }
+
+   switch (pname) {
+      case GL_PROGRAM_TARGET_NV:
+         *params = prog->Target;
+         return;
+      case GL_PROGRAM_LENGTH_NV:
+         *params = prog->String ?(GLint) strlen((char *) prog->String) : 0;
+         return;
+      case GL_PROGRAM_RESIDENT_NV:
+         *params = prog->Resident;
+         return;
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivNV(pname)");
+         return;
+   }
+}
+
+
+/**
+ * Get the program source code.
+ * \note Not compiled into display lists.
+ * \note Called from the GL API dispatcher.
+ */
+void GLAPIENTRY
+_mesa_GetProgramStringNV(GLuint id, GLenum pname, GLubyte *program)
+{
+   struct gl_program *prog;
+   GET_CURRENT_CONTEXT(ctx);
+
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (pname != GL_PROGRAM_STRING_NV) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringNV(pname)");
+      return;
+   }
+
+   prog = _mesa_lookup_program(ctx, id);
+   if (!prog) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramStringNV");
+      return;
+   }
+
+   if (prog->String) {
+      memcpy(program, prog->String, strlen((char *) prog->String));
+   }
+   else {
+      program[0] = 0;
+   }
+}
+
+
+/**
+ * Get matrix tracking information.
+ * \note Not compiled into display lists.
+ * \note Called from the GL API dispatcher.
+ */
+void GLAPIENTRY
+_mesa_GetTrackMatrixivNV(GLenum target, GLuint address,
+                         GLenum pname, GLint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (target == GL_VERTEX_PROGRAM_NV
+       && ctx->Extensions.NV_vertex_program) {
+      GLuint i;
+
+      if ((address & 0x3) || address >= MAX_NV_VERTEX_PROGRAM_PARAMS) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glGetTrackMatrixivNV(address)");
+         return;
+      }
+
+      i = address / 4;
+
+      switch (pname) {
+         case GL_TRACK_MATRIX_NV:
+            params[0] = (GLint) ctx->VertexProgram.TrackMatrix[i];
+            return;
+         case GL_TRACK_MATRIX_TRANSFORM_NV:
+            params[0] = (GLint) ctx->VertexProgram.TrackMatrixTransform[i];
+            return;
+         default:
+            _mesa_error(ctx, GL_INVALID_ENUM, "glGetTrackMatrixivNV");
+            return;
+      }
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTrackMatrixivNV");
+      return;
+   }
+}
+
+
+/**
+ * Get a vertex (or vertex array) attribute.
+ * \note Not compiled into display lists.
+ * \note Called from the GL API dispatcher.
+ */
+void GLAPIENTRY
+_mesa_GetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params)
+{
+   const struct gl_client_array *array;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)");
+      return;
+   }
+
+   array = &ctx->Array.ArrayObj->VertexAttrib[index];
+
+   switch (pname) {
+      case GL_ATTRIB_ARRAY_SIZE_NV:
+         params[0] = array->Size;
+         break;
+      case GL_ATTRIB_ARRAY_STRIDE_NV:
+         params[0] = array->Stride;
+         break;
+      case GL_ATTRIB_ARRAY_TYPE_NV:
+         params[0] = array->Type;
+         break;
+      case GL_CURRENT_ATTRIB_NV:
+         if (index == 0) {
+            _mesa_error(ctx, GL_INVALID_OPERATION,
+                        "glGetVertexAttribdvNV(index == 0)");
+            return;
+         }
+        FLUSH_CURRENT(ctx, 0);
+         COPY_4V(params, ctx->Current.Attrib[index]);
+         break;
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribdvNV");
+         return;
+   }
+}
+
+/**
+ * Get a vertex (or vertex array) attribute.
+ * \note Not compiled into display lists.
+ * \note Called from the GL API dispatcher.
+ */
+void GLAPIENTRY
+_mesa_GetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params)
+{
+   const struct gl_client_array *array;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)");
+      return;
+   }
+
+   array = &ctx->Array.ArrayObj->VertexAttrib[index];
+
+   switch (pname) {
+      case GL_ATTRIB_ARRAY_SIZE_NV:
+         params[0] = (GLfloat) array->Size;
+         break;
+      case GL_ATTRIB_ARRAY_STRIDE_NV:
+         params[0] = (GLfloat) array->Stride;
+         break;
+      case GL_ATTRIB_ARRAY_TYPE_NV:
+         params[0] = (GLfloat) array->Type;
+         break;
+      case GL_CURRENT_ATTRIB_NV:
+         if (index == 0) {
+            _mesa_error(ctx, GL_INVALID_OPERATION,
+                        "glGetVertexAttribfvNV(index == 0)");
+            return;
+         }
+        FLUSH_CURRENT(ctx, 0);
+         COPY_4V(params, ctx->Current.Attrib[index]);
+         break;
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribdvNV");
+         return;
+   }
+}
+
+/**
+ * Get a vertex (or vertex array) attribute.
+ * \note Not compiled into display lists.
+ * \note Called from the GL API dispatcher.
+ */
+void GLAPIENTRY
+_mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params)
+{
+   const struct gl_client_array *array;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)");
+      return;
+   }
+
+   array = &ctx->Array.ArrayObj->VertexAttrib[index];
+
+   switch (pname) {
+      case GL_ATTRIB_ARRAY_SIZE_NV:
+         params[0] = array->Size;
+         break;
+      case GL_ATTRIB_ARRAY_STRIDE_NV:
+         params[0] = array->Stride;
+         break;
+      case GL_ATTRIB_ARRAY_TYPE_NV:
+         params[0] = array->Type;
+         break;
+      case GL_CURRENT_ATTRIB_NV:
+         if (index == 0) {
+            _mesa_error(ctx, GL_INVALID_OPERATION,
+                        "glGetVertexAttribivNV(index == 0)");
+            return;
+         }
+        FLUSH_CURRENT(ctx, 0);
+         params[0] = (GLint) ctx->Current.Attrib[index][0];
+         params[1] = (GLint) ctx->Current.Attrib[index][1];
+         params[2] = (GLint) ctx->Current.Attrib[index][2];
+         params[3] = (GLint) ctx->Current.Attrib[index][3];
+         break;
+      case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
+         params[0] = array->BufferObj->Name;
+         break;
+      default:
+         _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribdvNV");
+         return;
+   }
+}
+
+
+/**
+ * Get a vertex array attribute pointer.
+ * \note Not compiled into display lists.
+ * \note Called from the GL API dispatcher.
+ */
+void GLAPIENTRY
+_mesa_GetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid **pointer)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerNV(index)");
+      return;
+   }
+
+   if (pname != GL_ATTRIB_ARRAY_POINTER_NV) {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerNV(pname)");
+      return;
+   }
+
+   *pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[index].Ptr;
+}
+
+void
+_mesa_emit_nv_temp_initialization(GLcontext *ctx,
+                                 struct gl_program *program)
+{
+   struct prog_instruction *inst;
+   GLuint i;
+
+   if (!ctx->Shader.EmitNVTempInitialization)
+      return;
+
+   /* We'll swizzle up a zero temporary so we can use it for the
+    * ARL.
+    */
+   if (program->NumTemporaries == 0)
+      program->NumTemporaries = 1;
+
+   _mesa_insert_instructions(program, 0, program->NumTemporaries + 1);
+
+   for (i = 0; i < program->NumTemporaries; i++) {
+      struct prog_instruction *inst = &program->Instructions[i];
+
+      inst->Opcode = OPCODE_SWZ;
+      inst->DstReg.File = PROGRAM_TEMPORARY;
+      inst->DstReg.Index = i;
+      inst->DstReg.WriteMask = WRITEMASK_XYZW;
+      inst->SrcReg[0].File = PROGRAM_TEMPORARY;
+      inst->SrcReg[0].Index = 0;
+      inst->SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_ZERO,
+                                             SWIZZLE_ZERO,
+                                             SWIZZLE_ZERO,
+                                             SWIZZLE_ZERO);
+   }
+
+   inst = &program->Instructions[i];
+   inst->Opcode = OPCODE_ARL;
+   inst->DstReg.File = PROGRAM_ADDRESS;
+   inst->DstReg.Index = 0;
+   inst->DstReg.WriteMask = WRITEMASK_XYZW;
+   inst->SrcReg[0].File = PROGRAM_TEMPORARY;
+   inst->SrcReg[0].Index = 0;
+   inst->SrcReg[0].Swizzle = SWIZZLE_XXXX;
+
+   if (program->NumAddressRegs == 0)
+      program->NumAddressRegs = 1;
+}
+
+void
+_mesa_setup_nv_temporary_count(GLcontext *ctx, struct gl_program *program)
+{
+   GLuint i;
+
+   program->NumTemporaries = 0;
+   for (i = 0; i < program->NumInstructions; i++) {
+      struct prog_instruction *inst = &program->Instructions[i];
+
+      if (inst->DstReg.File == PROGRAM_TEMPORARY) {
+        program->NumTemporaries = MAX2(program->NumTemporaries,
+                                       inst->DstReg.Index + 1);
+      }
+      if (inst->SrcReg[0].File == PROGRAM_TEMPORARY) {
+        program->NumTemporaries = MAX2((GLint)program->NumTemporaries,
+                                       inst->SrcReg[0].Index + 1);
+      }
+      if (inst->SrcReg[1].File == PROGRAM_TEMPORARY) {
+        program->NumTemporaries = MAX2((GLint)program->NumTemporaries,
+                                       inst->SrcReg[1].Index + 1);
+      }
+      if (inst->SrcReg[2].File == PROGRAM_TEMPORARY) {
+        program->NumTemporaries = MAX2((GLint)program->NumTemporaries,
+                                       inst->SrcReg[2].Index + 1);
+      }
+   }
+}
+
+/**
+ * Load/parse/compile a program.
+ * \note Called from the GL API dispatcher.
+ */
+void GLAPIENTRY
+_mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len,
+                    const GLubyte *program)
+{
+   struct gl_program *prog;
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (!ctx->Extensions.NV_vertex_program
+       && !ctx->Extensions.NV_fragment_program) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV()");
+      return;
+   }
+
+   if (id == 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glLoadProgramNV(id)");
+      return;
+   }
+
+   if (len < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glLoadProgramNV(len)");
+      return;
+   }
+
+   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+
+   prog = _mesa_lookup_program(ctx, id);
+
+   if (prog && prog->Target != 0 && prog->Target != target) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(target)");
+      return;
+   }
+
+   if ((target == GL_VERTEX_PROGRAM_NV ||
+        target == GL_VERTEX_STATE_PROGRAM_NV)
+       && ctx->Extensions.NV_vertex_program) {
+      struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog;
+      if (!vprog || prog == &_mesa_DummyProgram) {
+         vprog = (struct gl_vertex_program *)
+            ctx->Driver.NewProgram(ctx, target, id);
+         if (!vprog) {
+            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
+            return;
+         }
+         _mesa_HashInsert(ctx->Shared->Programs, id, vprog);
+      }
+
+      if (ctx->Extensions.ARB_vertex_program
+         && (strncmp((char *) program, "!!ARB", 5) == 0)) {
+        _mesa_parse_arb_vertex_program(ctx, target, program, len, vprog);
+      } else {
+        _mesa_parse_nv_vertex_program(ctx, target, program, len, vprog);
+      }
+   }
+   else if (target == GL_FRAGMENT_PROGRAM_NV
+            && ctx->Extensions.NV_fragment_program) {
+      struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog;
+      if (!fprog || prog == &_mesa_DummyProgram) {
+         fprog = (struct gl_fragment_program *)
+            ctx->Driver.NewProgram(ctx, target, id);
+         if (!fprog) {
+            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
+            return;
+         }
+         _mesa_HashInsert(ctx->Shared->Programs, id, fprog);
+      }
+      _mesa_parse_nv_fragment_program(ctx, target, program, len, fprog);
+   }
+   else if (target == GL_FRAGMENT_PROGRAM_ARB
+            && ctx->Extensions.ARB_fragment_program) {
+      struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog;
+      if (!fprog || prog == &_mesa_DummyProgram) {
+         fprog = (struct gl_fragment_program *)
+            ctx->Driver.NewProgram(ctx, target, id);
+         if (!fprog) {
+            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
+            return;
+         }
+         _mesa_HashInsert(ctx->Shared->Programs, id, fprog);
+      }
+      _mesa_parse_arb_fragment_program(ctx, target, program, len, fprog);
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glLoadProgramNV(target)");
+   }
+}
+
+
+
+/**
+ * Set a sequence of program parameter registers.
+ * \note Called from the GL API dispatcher.
+ */
+void GLAPIENTRY
+_mesa_ProgramParameters4dvNV(GLenum target, GLuint index,
+                             GLuint num, const GLdouble *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) {
+      GLuint i;
+      if (index + num > MAX_NV_VERTEX_PROGRAM_PARAMS) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramParameters4dvNV");
+         return;
+      }
+      for (i = 0; i < num; i++) {
+         ctx->VertexProgram.Parameters[index + i][0] = (GLfloat) params[0];
+         ctx->VertexProgram.Parameters[index + i][1] = (GLfloat) params[1];
+         ctx->VertexProgram.Parameters[index + i][2] = (GLfloat) params[2];
+         ctx->VertexProgram.Parameters[index + i][3] = (GLfloat) params[3];
+         params += 4;
+      };
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameters4dvNV");
+      return;
+   }
+}
+
+
+/**
+ * Set a sequence of program parameter registers.
+ * \note Called from the GL API dispatcher.
+ */
+void GLAPIENTRY
+_mesa_ProgramParameters4fvNV(GLenum target, GLuint index,
+                             GLuint num, const GLfloat *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) {
+      GLuint i;
+      if (index + num > MAX_NV_VERTEX_PROGRAM_PARAMS) {
+         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramParameters4fvNV");
+         return;
+      }
+      for (i = 0; i < num; i++) {
+         COPY_4V(ctx->VertexProgram.Parameters[index + i], params);
+         params += 4;
+      }
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameters4fvNV");
+      return;
+   }
+}
+
+
+
+/**
+ * Setup tracking of matrices into program parameter registers.
+ * \note Called from the GL API dispatcher.
+ */
+void GLAPIENTRY
+_mesa_TrackMatrixNV(GLenum target, GLuint address,
+                    GLenum matrix, GLenum transform)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+
+   if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) {
+      if (address & 0x3) {
+         /* addr must be multiple of four */
+         _mesa_error(ctx, GL_INVALID_VALUE, "glTrackMatrixNV(address)");
+         return;
+      }
+
+      switch (matrix) {
+         case GL_NONE:
+         case GL_MODELVIEW:
+         case GL_PROJECTION:
+         case GL_TEXTURE:
+         case GL_COLOR:
+         case GL_MODELVIEW_PROJECTION_NV:
+         case GL_MATRIX0_NV:
+         case GL_MATRIX1_NV:
+         case GL_MATRIX2_NV:
+         case GL_MATRIX3_NV:
+         case GL_MATRIX4_NV:
+         case GL_MATRIX5_NV:
+         case GL_MATRIX6_NV:
+         case GL_MATRIX7_NV:
+            /* OK, fallthrough */
+            break;
+         default:
+            _mesa_error(ctx, GL_INVALID_ENUM, "glTrackMatrixNV(matrix)");
+            return;
+      }
+
+      switch (transform) {
+         case GL_IDENTITY_NV:
+         case GL_INVERSE_NV:
+         case GL_TRANSPOSE_NV:
+         case GL_INVERSE_TRANSPOSE_NV:
+            /* OK, fallthrough */
+            break;
+         default:
+            _mesa_error(ctx, GL_INVALID_ENUM, "glTrackMatrixNV(transform)");
+            return;
+      }
+
+      ctx->VertexProgram.TrackMatrix[address / 4] = matrix;
+      ctx->VertexProgram.TrackMatrixTransform[address / 4] = transform;
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glTrackMatrixNV(target)");
+      return;
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name,
+                                GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+   struct gl_program *prog;
+   struct gl_fragment_program *fragProg;
+   GLfloat *v;
+
+   GET_CURRENT_CONTEXT(ctx);
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
+
+   prog = _mesa_lookup_program(ctx, id);
+   if (!prog || prog->Target != GL_FRAGMENT_PROGRAM_NV) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramNamedParameterNV");
+      return;
+   }
+
+   if (len <= 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glProgramNamedParameterNV(len)");
+      return;
+   }
+
+   fragProg = (struct gl_fragment_program *) prog;
+   v = _mesa_lookup_parameter_value(fragProg->Base.Parameters, len,
+                                    (char *) name);
+   if (v) {
+      v[0] = x;
+      v[1] = y;
+      v[2] = z;
+      v[3] = w;
+      return;
+   }
+
+   _mesa_error(ctx, GL_INVALID_VALUE, "glProgramNamedParameterNV(name)");
+}
+
+
+void GLAPIENTRY
+_mesa_ProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte *name,
+                                 const float v[])
+{
+   _mesa_ProgramNamedParameter4fNV(id, len, name, v[0], v[1], v[2], v[3]);
+}
+
+
+void GLAPIENTRY
+_mesa_ProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte *name,
+                                GLdouble x, GLdouble y, GLdouble z, GLdouble w)
+{
+   _mesa_ProgramNamedParameter4fNV(id, len, name, (GLfloat)x, (GLfloat)y, 
+                                   (GLfloat)z, (GLfloat)w);
+}
+
+
+void GLAPIENTRY
+_mesa_ProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte *name,
+                                 const double v[])
+{
+   _mesa_ProgramNamedParameter4fNV(id, len, name,
+                                   (GLfloat)v[0], (GLfloat)v[1],
+                                   (GLfloat)v[2], (GLfloat)v[3]);
+}
+
+
+void GLAPIENTRY
+_mesa_GetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name,
+                                   GLfloat *params)
+{
+   struct gl_program *prog;
+   struct gl_fragment_program *fragProg;
+   const GLfloat *v;
+
+   GET_CURRENT_CONTEXT(ctx);
+
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   prog = _mesa_lookup_program(ctx, id);
+   if (!prog || prog->Target != GL_FRAGMENT_PROGRAM_NV) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramNamedParameterNV");
+      return;
+   }
+
+   if (len <= 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramNamedParameterNV");
+      return;
+   }
+
+   fragProg = (struct gl_fragment_program *) prog;
+   v = _mesa_lookup_parameter_value(fragProg->Base.Parameters,
+                                    len, (char *) name);
+   if (v) {
+      params[0] = v[0];
+      params[1] = v[1];
+      params[2] = v[2];
+      params[3] = v[3];
+      return;
+   }
+
+   _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramNamedParameterNV");
+}
+
+
+void GLAPIENTRY
+_mesa_GetProgramNamedParameterdvNV(GLuint id, GLsizei len, const GLubyte *name,
+                                   GLdouble *params)
+{
+   GLfloat floatParams[4];
+   _mesa_GetProgramNamedParameterfvNV(id, len, name, floatParams);
+   COPY_4V(params, floatParams);
+}
diff --git a/src/mesa/main/nvprogram.h b/src/mesa/main/nvprogram.h
new file mode 100644 (file)
index 0000000..8ee5966
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  5.1
+ *
+ * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Brian Paul
+ */
+
+
+#ifndef NVPROGRAM_H
+#define NVPROGRAM_H
+
+
+extern void GLAPIENTRY
+_mesa_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params);
+
+extern GLboolean GLAPIENTRY 
+_mesa_AreProgramsResidentNV(GLsizei n, const GLuint *ids, GLboolean *residences);
+
+extern void GLAPIENTRY
+_mesa_RequestResidentProgramsNV(GLsizei n, const GLuint *ids);
+
+extern void GLAPIENTRY
+_mesa_GetProgramParameterfvNV(GLenum target, GLuint index, GLenum pname, GLfloat *params);
+
+extern void GLAPIENTRY
+_mesa_GetProgramParameterdvNV(GLenum target, GLuint index, GLenum pname, GLdouble *params);
+
+extern void GLAPIENTRY
+_mesa_GetProgramivNV(GLuint id, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetProgramStringNV(GLuint id, GLenum pname, GLubyte *program);
+
+extern void GLAPIENTRY
+_mesa_GetTrackMatrixivNV(GLenum target, GLuint address, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params);
+
+extern void GLAPIENTRY
+_mesa_GetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params);
+
+extern void GLAPIENTRY
+_mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid **pointer);
+
+extern void GLAPIENTRY
+_mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len, const GLubyte *program);
+
+extern void GLAPIENTRY
+_mesa_ProgramParameters4dvNV(GLenum target, GLuint index, GLuint num, const GLdouble *params);
+
+extern void GLAPIENTRY
+_mesa_ProgramParameters4fvNV(GLenum target, GLuint index, GLuint num, const GLfloat *params);
+
+extern void GLAPIENTRY
+_mesa_TrackMatrixNV(GLenum target, GLuint address, GLenum matrix, GLenum transform);
+
+
+extern void GLAPIENTRY
+_mesa_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name,
+                                GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+
+extern void GLAPIENTRY
+_mesa_ProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte *name,
+                                 const float v[]);
+
+extern void GLAPIENTRY
+_mesa_ProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte *name,
+                                GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+
+extern void GLAPIENTRY
+_mesa_ProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte *name,
+                                 const double v[]);
+
+extern void GLAPIENTRY
+_mesa_GetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name,
+                                   GLfloat *params);
+
+extern void GLAPIENTRY
+_mesa_GetProgramNamedParameterdvNV(GLuint id, GLsizei len, const GLubyte *name,
+                                   GLdouble *params);
+
+extern void
+_mesa_setup_nv_temporary_count(GLcontext *ctx, struct gl_program *program);
+
+extern void
+_mesa_emit_nv_temp_initialization(GLcontext *ctx,
+                                 struct gl_program *program);
+
+#endif
index a0969f6b9ffe6a281067d67f7ab9dd2245a2be46..6f62415ba8cd2f244f29ba574413777565398705 100644 (file)
@@ -71,7 +71,8 @@ fpclassify(double x)
 }
 
 #elif defined(__APPLE__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \
-     defined(__DragonFly__) || (defined(__sun) && defined(__C99FEATURES__))
+     defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \
+     (defined(__sun) && defined(__C99FEATURES__))
 
 /* fpclassify is available. */
 
index 2df11a454dfe90690f8bf51c9bc0bb963af55fca..631cc901588f73dba2a69ff180ac86fd1cf06025 100644 (file)
@@ -446,9 +446,9 @@ static const char _mesa_function_pool[] =
    "\0"
    "glCreateProgramObjectARB\0"
    "\0"
-   /* _mesa_function_pool[2906]: FragmentLightModelivSGIX (dynamic) */
+   /* _mesa_function_pool[2906]: DeleteTransformFeedbacks (will be remapped) */
    "ip\0"
-   "glFragmentLightModelivSGIX\0"
+   "glDeleteTransformFeedbacks\0"
    "\0"
    /* _mesa_function_pool[2937]: UniformMatrix4x3fv (will be remapped) */
    "iiip\0"
@@ -664,3757 +664,3801 @@ static const char _mesa_function_pool[] =
    "iip\0"
    "glGetTexEnvfv\0"
    "\0"
-   /* _mesa_function_pool[4480]: TexCoord2fColor4fNormal3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[4480]: BindTransformFeedback (will be remapped) */
+   "ii\0"
+   "glBindTransformFeedback\0"
+   "\0"
+   /* _mesa_function_pool[4508]: TexCoord2fColor4fNormal3fVertex3fSUN (dynamic) */
    "ffffffffffff\0"
    "glTexCoord2fColor4fNormal3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[4533]: Indexub (offset 315) */
+   /* _mesa_function_pool[4561]: Indexub (offset 315) */
    "i\0"
    "glIndexub\0"
    "\0"
-   /* _mesa_function_pool[4546]: TexEnvi (offset 186) */
+   /* _mesa_function_pool[4574]: TexEnvi (offset 186) */
    "iii\0"
    "glTexEnvi\0"
    "\0"
-   /* _mesa_function_pool[4561]: GetClipPlane (offset 259) */
+   /* _mesa_function_pool[4589]: GetClipPlane (offset 259) */
    "ip\0"
    "glGetClipPlane\0"
    "\0"
-   /* _mesa_function_pool[4580]: CombinerParameterfvNV (will be remapped) */
+   /* _mesa_function_pool[4608]: CombinerParameterfvNV (will be remapped) */
    "ip\0"
    "glCombinerParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[4608]: VertexAttribs3dvNV (will be remapped) */
+   /* _mesa_function_pool[4636]: VertexAttribs3dvNV (will be remapped) */
    "iip\0"
    "glVertexAttribs3dvNV\0"
    "\0"
-   /* _mesa_function_pool[4634]: VertexAttribs4fvNV (will be remapped) */
+   /* _mesa_function_pool[4662]: VertexAttribs4fvNV (will be remapped) */
    "iip\0"
    "glVertexAttribs4fvNV\0"
    "\0"
-   /* _mesa_function_pool[4660]: VertexArrayRangeNV (will be remapped) */
+   /* _mesa_function_pool[4688]: VertexArrayRangeNV (will be remapped) */
    "ip\0"
    "glVertexArrayRangeNV\0"
    "\0"
-   /* _mesa_function_pool[4685]: FragmentLightiSGIX (dynamic) */
+   /* _mesa_function_pool[4713]: FragmentLightiSGIX (dynamic) */
    "iii\0"
    "glFragmentLightiSGIX\0"
    "\0"
-   /* _mesa_function_pool[4711]: PolygonOffsetEXT (will be remapped) */
+   /* _mesa_function_pool[4739]: PolygonOffsetEXT (will be remapped) */
    "ff\0"
    "glPolygonOffsetEXT\0"
    "\0"
-   /* _mesa_function_pool[4734]: PollAsyncSGIX (dynamic) */
+   /* _mesa_function_pool[4762]: PollAsyncSGIX (dynamic) */
    "p\0"
    "glPollAsyncSGIX\0"
    "\0"
-   /* _mesa_function_pool[4753]: DeleteFragmentShaderATI (will be remapped) */
+   /* _mesa_function_pool[4781]: DeleteFragmentShaderATI (will be remapped) */
    "i\0"
    "glDeleteFragmentShaderATI\0"
    "\0"
-   /* _mesa_function_pool[4782]: Scaled (offset 301) */
+   /* _mesa_function_pool[4810]: Scaled (offset 301) */
    "ddd\0"
    "glScaled\0"
    "\0"
-   /* _mesa_function_pool[4796]: Scalef (offset 302) */
+   /* _mesa_function_pool[4824]: ResumeTransformFeedback (will be remapped) */
+   "\0"
+   "glResumeTransformFeedback\0"
+   "\0"
+   /* _mesa_function_pool[4852]: Scalef (offset 302) */
    "fff\0"
    "glScalef\0"
    "\0"
-   /* _mesa_function_pool[4810]: TexCoord2fNormal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[4866]: TexCoord2fNormal3fVertex3fvSUN (dynamic) */
    "ppp\0"
    "glTexCoord2fNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[4848]: MultTransposeMatrixdARB (will be remapped) */
+   /* _mesa_function_pool[4904]: MultTransposeMatrixdARB (will be remapped) */
    "p\0"
    "glMultTransposeMatrixd\0"
    "glMultTransposeMatrixdARB\0"
    "\0"
-   /* _mesa_function_pool[4900]: ObjectUnpurgeableAPPLE (will be remapped) */
+   /* _mesa_function_pool[4956]: ColorMaskIndexedEXT (will be remapped) */
+   "iiiii\0"
+   "glColorMaskIndexedEXT\0"
+   "\0"
+   /* _mesa_function_pool[4985]: ObjectUnpurgeableAPPLE (will be remapped) */
    "iii\0"
    "glObjectUnpurgeableAPPLE\0"
    "\0"
-   /* _mesa_function_pool[4930]: AlphaFunc (offset 240) */
+   /* _mesa_function_pool[5015]: AlphaFunc (offset 240) */
    "if\0"
    "glAlphaFunc\0"
    "\0"
-   /* _mesa_function_pool[4946]: WindowPos2svMESA (will be remapped) */
+   /* _mesa_function_pool[5031]: WindowPos2svMESA (will be remapped) */
    "p\0"
    "glWindowPos2sv\0"
    "glWindowPos2svARB\0"
    "glWindowPos2svMESA\0"
    "\0"
-   /* _mesa_function_pool[5001]: EdgeFlag (offset 41) */
+   /* _mesa_function_pool[5086]: EdgeFlag (offset 41) */
    "i\0"
    "glEdgeFlag\0"
    "\0"
-   /* _mesa_function_pool[5015]: TexCoord2iv (offset 107) */
+   /* _mesa_function_pool[5100]: TexCoord2iv (offset 107) */
    "p\0"
    "glTexCoord2iv\0"
    "\0"
-   /* _mesa_function_pool[5032]: CompressedTexImage1DARB (will be remapped) */
+   /* _mesa_function_pool[5117]: CompressedTexImage1DARB (will be remapped) */
    "iiiiiip\0"
    "glCompressedTexImage1D\0"
    "glCompressedTexImage1DARB\0"
    "\0"
-   /* _mesa_function_pool[5090]: Rotated (offset 299) */
+   /* _mesa_function_pool[5175]: Rotated (offset 299) */
    "dddd\0"
    "glRotated\0"
    "\0"
-   /* _mesa_function_pool[5106]: VertexAttrib2sNV (will be remapped) */
+   /* _mesa_function_pool[5191]: VertexAttrib2sNV (will be remapped) */
    "iii\0"
    "glVertexAttrib2sNV\0"
    "\0"
-   /* _mesa_function_pool[5130]: ReadPixels (offset 256) */
+   /* _mesa_function_pool[5215]: ReadPixels (offset 256) */
    "iiiiiip\0"
    "glReadPixels\0"
    "\0"
-   /* _mesa_function_pool[5152]: EdgeFlagv (offset 42) */
+   /* _mesa_function_pool[5237]: EdgeFlagv (offset 42) */
    "p\0"
    "glEdgeFlagv\0"
    "\0"
-   /* _mesa_function_pool[5167]: NormalPointerListIBM (dynamic) */
+   /* _mesa_function_pool[5252]: NormalPointerListIBM (dynamic) */
    "iipi\0"
    "glNormalPointerListIBM\0"
    "\0"
-   /* _mesa_function_pool[5196]: IndexPointerEXT (will be remapped) */
+   /* _mesa_function_pool[5281]: IndexPointerEXT (will be remapped) */
    "iiip\0"
    "glIndexPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[5220]: Color4iv (offset 32) */
+   /* _mesa_function_pool[5305]: Color4iv (offset 32) */
    "p\0"
    "glColor4iv\0"
    "\0"
-   /* _mesa_function_pool[5234]: TexParameterf (offset 178) */
+   /* _mesa_function_pool[5319]: TexParameterf (offset 178) */
    "iif\0"
    "glTexParameterf\0"
    "\0"
-   /* _mesa_function_pool[5255]: TexParameteri (offset 180) */
+   /* _mesa_function_pool[5340]: TexParameteri (offset 180) */
    "iii\0"
    "glTexParameteri\0"
    "\0"
-   /* _mesa_function_pool[5276]: NormalPointerEXT (will be remapped) */
+   /* _mesa_function_pool[5361]: NormalPointerEXT (will be remapped) */
    "iiip\0"
    "glNormalPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[5301]: MultiTexCoord3dARB (offset 392) */
+   /* _mesa_function_pool[5386]: MultiTexCoord3dARB (offset 392) */
    "iddd\0"
    "glMultiTexCoord3d\0"
    "glMultiTexCoord3dARB\0"
    "\0"
-   /* _mesa_function_pool[5346]: MultiTexCoord2iARB (offset 388) */
+   /* _mesa_function_pool[5431]: MultiTexCoord2iARB (offset 388) */
    "iii\0"
    "glMultiTexCoord2i\0"
    "glMultiTexCoord2iARB\0"
    "\0"
-   /* _mesa_function_pool[5390]: DrawPixels (offset 257) */
+   /* _mesa_function_pool[5475]: DrawPixels (offset 257) */
    "iiiip\0"
    "glDrawPixels\0"
    "\0"
-   /* _mesa_function_pool[5410]: ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[5495]: ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (dynamic) */
    "iffffffff\0"
    "glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[5470]: MultiTexCoord2svARB (offset 391) */
+   /* _mesa_function_pool[5555]: MultiTexCoord2svARB (offset 391) */
    "ip\0"
    "glMultiTexCoord2sv\0"
    "glMultiTexCoord2svARB\0"
    "\0"
-   /* _mesa_function_pool[5515]: ReplacementCodeubvSUN (dynamic) */
+   /* _mesa_function_pool[5600]: ReplacementCodeubvSUN (dynamic) */
    "p\0"
    "glReplacementCodeubvSUN\0"
    "\0"
-   /* _mesa_function_pool[5542]: Uniform3iARB (will be remapped) */
+   /* _mesa_function_pool[5627]: Uniform3iARB (will be remapped) */
    "iiii\0"
    "glUniform3i\0"
    "glUniform3iARB\0"
    "\0"
-   /* _mesa_function_pool[5575]: GetFragmentMaterialfvSGIX (dynamic) */
+   /* _mesa_function_pool[5660]: DrawTransformFeedback (will be remapped) */
+   "ii\0"
+   "glDrawTransformFeedback\0"
+   "\0"
+   /* _mesa_function_pool[5688]: GetFragmentMaterialfvSGIX (dynamic) */
    "iip\0"
    "glGetFragmentMaterialfvSGIX\0"
    "\0"
-   /* _mesa_function_pool[5608]: GetShaderInfoLog (will be remapped) */
+   /* _mesa_function_pool[5721]: GetShaderInfoLog (will be remapped) */
    "iipp\0"
    "glGetShaderInfoLog\0"
    "\0"
-   /* _mesa_function_pool[5633]: WeightivARB (dynamic) */
+   /* _mesa_function_pool[5746]: WeightivARB (dynamic) */
    "ip\0"
    "glWeightivARB\0"
    "\0"
-   /* _mesa_function_pool[5651]: PollInstrumentsSGIX (dynamic) */
+   /* _mesa_function_pool[5764]: PollInstrumentsSGIX (dynamic) */
    "p\0"
    "glPollInstrumentsSGIX\0"
    "\0"
-   /* _mesa_function_pool[5676]: GlobalAlphaFactordSUN (dynamic) */
+   /* _mesa_function_pool[5789]: GlobalAlphaFactordSUN (dynamic) */
    "d\0"
    "glGlobalAlphaFactordSUN\0"
    "\0"
-   /* _mesa_function_pool[5703]: GetFinalCombinerInputParameterfvNV (will be remapped) */
+   /* _mesa_function_pool[5816]: GetFinalCombinerInputParameterfvNV (will be remapped) */
    "iip\0"
    "glGetFinalCombinerInputParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[5745]: GenerateMipmapEXT (will be remapped) */
+   /* _mesa_function_pool[5858]: GenerateMipmapEXT (will be remapped) */
    "i\0"
    "glGenerateMipmap\0"
    "glGenerateMipmapEXT\0"
    "\0"
-   /* _mesa_function_pool[5785]: GenLists (offset 5) */
+   /* _mesa_function_pool[5898]: GenLists (offset 5) */
    "i\0"
    "glGenLists\0"
    "\0"
-   /* _mesa_function_pool[5799]: SetFragmentShaderConstantATI (will be remapped) */
+   /* _mesa_function_pool[5912]: SetFragmentShaderConstantATI (will be remapped) */
    "ip\0"
    "glSetFragmentShaderConstantATI\0"
    "\0"
-   /* _mesa_function_pool[5834]: GetMapAttribParameterivNV (dynamic) */
+   /* _mesa_function_pool[5947]: GetMapAttribParameterivNV (dynamic) */
    "iiip\0"
    "glGetMapAttribParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[5868]: CreateShaderObjectARB (will be remapped) */
+   /* _mesa_function_pool[5981]: CreateShaderObjectARB (will be remapped) */
    "i\0"
    "glCreateShaderObjectARB\0"
    "\0"
-   /* _mesa_function_pool[5895]: GetSharpenTexFuncSGIS (dynamic) */
+   /* _mesa_function_pool[6008]: GetSharpenTexFuncSGIS (dynamic) */
    "ip\0"
    "glGetSharpenTexFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[5923]: BufferDataARB (will be remapped) */
+   /* _mesa_function_pool[6036]: BufferDataARB (will be remapped) */
    "iipi\0"
    "glBufferData\0"
    "glBufferDataARB\0"
    "\0"
-   /* _mesa_function_pool[5958]: FlushVertexArrayRangeNV (will be remapped) */
+   /* _mesa_function_pool[6071]: FlushVertexArrayRangeNV (will be remapped) */
    "\0"
    "glFlushVertexArrayRangeNV\0"
    "\0"
-   /* _mesa_function_pool[5986]: MapGrid2d (offset 226) */
+   /* _mesa_function_pool[6099]: MapGrid2d (offset 226) */
    "iddidd\0"
    "glMapGrid2d\0"
    "\0"
-   /* _mesa_function_pool[6006]: MapGrid2f (offset 227) */
+   /* _mesa_function_pool[6119]: MapGrid2f (offset 227) */
    "iffiff\0"
    "glMapGrid2f\0"
    "\0"
-   /* _mesa_function_pool[6026]: SampleMapATI (will be remapped) */
+   /* _mesa_function_pool[6139]: SampleMapATI (will be remapped) */
    "iii\0"
    "glSampleMapATI\0"
    "\0"
-   /* _mesa_function_pool[6046]: VertexPointerEXT (will be remapped) */
+   /* _mesa_function_pool[6159]: VertexPointerEXT (will be remapped) */
    "iiiip\0"
    "glVertexPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[6072]: GetTexFilterFuncSGIS (dynamic) */
+   /* _mesa_function_pool[6185]: GetTexFilterFuncSGIS (dynamic) */
    "iip\0"
    "glGetTexFilterFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[6100]: Scissor (offset 176) */
+   /* _mesa_function_pool[6213]: Scissor (offset 176) */
    "iiii\0"
    "glScissor\0"
    "\0"
-   /* _mesa_function_pool[6116]: Fogf (offset 153) */
+   /* _mesa_function_pool[6229]: Fogf (offset 153) */
    "if\0"
    "glFogf\0"
    "\0"
-   /* _mesa_function_pool[6127]: GetCombinerOutputParameterfvNV (will be remapped) */
-   "iiip\0"
-   "glGetCombinerOutputParameterfvNV\0"
+   /* _mesa_function_pool[6240]: ReplacementCodeuiColor4ubVertex3fvSUN (dynamic) */
+   "ppp\0"
+   "glReplacementCodeuiColor4ubVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[6166]: TexSubImage1D (offset 332) */
+   /* _mesa_function_pool[6285]: TexSubImage1D (offset 332) */
    "iiiiiip\0"
    "glTexSubImage1D\0"
    "glTexSubImage1DEXT\0"
    "\0"
-   /* _mesa_function_pool[6210]: VertexAttrib1sARB (will be remapped) */
+   /* _mesa_function_pool[6329]: VertexAttrib1sARB (will be remapped) */
    "ii\0"
    "glVertexAttrib1s\0"
    "glVertexAttrib1sARB\0"
    "\0"
-   /* _mesa_function_pool[6251]: FenceSync (will be remapped) */
+   /* _mesa_function_pool[6370]: FenceSync (will be remapped) */
    "ii\0"
    "glFenceSync\0"
    "\0"
-   /* _mesa_function_pool[6267]: Color4usv (offset 40) */
+   /* _mesa_function_pool[6386]: Color4usv (offset 40) */
    "p\0"
    "glColor4usv\0"
    "\0"
-   /* _mesa_function_pool[6282]: Fogi (offset 155) */
+   /* _mesa_function_pool[6401]: Fogi (offset 155) */
    "ii\0"
    "glFogi\0"
    "\0"
-   /* _mesa_function_pool[6293]: DepthRange (offset 288) */
+   /* _mesa_function_pool[6412]: DepthRange (offset 288) */
    "dd\0"
    "glDepthRange\0"
    "\0"
-   /* _mesa_function_pool[6310]: RasterPos3iv (offset 75) */
+   /* _mesa_function_pool[6429]: RasterPos3iv (offset 75) */
    "p\0"
    "glRasterPos3iv\0"
    "\0"
-   /* _mesa_function_pool[6328]: FinalCombinerInputNV (will be remapped) */
+   /* _mesa_function_pool[6447]: FinalCombinerInputNV (will be remapped) */
    "iiii\0"
    "glFinalCombinerInputNV\0"
    "\0"
-   /* _mesa_function_pool[6357]: TexCoord2i (offset 106) */
+   /* _mesa_function_pool[6476]: TexCoord2i (offset 106) */
    "ii\0"
    "glTexCoord2i\0"
    "\0"
-   /* _mesa_function_pool[6374]: PixelMapfv (offset 251) */
+   /* _mesa_function_pool[6493]: PixelMapfv (offset 251) */
    "iip\0"
    "glPixelMapfv\0"
    "\0"
-   /* _mesa_function_pool[6392]: Color4ui (offset 37) */
+   /* _mesa_function_pool[6511]: Color4ui (offset 37) */
    "iiii\0"
    "glColor4ui\0"
    "\0"
-   /* _mesa_function_pool[6409]: RasterPos3s (offset 76) */
+   /* _mesa_function_pool[6528]: RasterPos3s (offset 76) */
    "iii\0"
    "glRasterPos3s\0"
    "\0"
-   /* _mesa_function_pool[6428]: Color3usv (offset 24) */
+   /* _mesa_function_pool[6547]: Color3usv (offset 24) */
    "p\0"
    "glColor3usv\0"
    "\0"
-   /* _mesa_function_pool[6443]: FlushRasterSGIX (dynamic) */
+   /* _mesa_function_pool[6562]: FlushRasterSGIX (dynamic) */
    "\0"
    "glFlushRasterSGIX\0"
    "\0"
-   /* _mesa_function_pool[6463]: TexCoord2f (offset 104) */
+   /* _mesa_function_pool[6582]: TexCoord2f (offset 104) */
    "ff\0"
    "glTexCoord2f\0"
    "\0"
-   /* _mesa_function_pool[6480]: ReplacementCodeuiTexCoord2fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[6599]: ReplacementCodeuiTexCoord2fVertex3fSUN (dynamic) */
    "ifffff\0"
    "glReplacementCodeuiTexCoord2fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[6529]: TexCoord2d (offset 102) */
+   /* _mesa_function_pool[6648]: TexCoord2d (offset 102) */
    "dd\0"
    "glTexCoord2d\0"
    "\0"
-   /* _mesa_function_pool[6546]: RasterPos3d (offset 70) */
+   /* _mesa_function_pool[6665]: RasterPos3d (offset 70) */
    "ddd\0"
    "glRasterPos3d\0"
    "\0"
-   /* _mesa_function_pool[6565]: RasterPos3f (offset 72) */
+   /* _mesa_function_pool[6684]: RasterPos3f (offset 72) */
    "fff\0"
    "glRasterPos3f\0"
    "\0"
-   /* _mesa_function_pool[6584]: Uniform1fARB (will be remapped) */
+   /* _mesa_function_pool[6703]: Uniform1fARB (will be remapped) */
    "if\0"
    "glUniform1f\0"
    "glUniform1fARB\0"
    "\0"
-   /* _mesa_function_pool[6615]: AreTexturesResident (offset 322) */
+   /* _mesa_function_pool[6734]: AreTexturesResident (offset 322) */
    "ipp\0"
    "glAreTexturesResident\0"
    "glAreTexturesResidentEXT\0"
    "\0"
-   /* _mesa_function_pool[6667]: TexCoord2s (offset 108) */
+   /* _mesa_function_pool[6786]: TexCoord2s (offset 108) */
    "ii\0"
    "glTexCoord2s\0"
    "\0"
-   /* _mesa_function_pool[6684]: StencilOpSeparate (will be remapped) */
+   /* _mesa_function_pool[6803]: StencilOpSeparate (will be remapped) */
    "iiii\0"
    "glStencilOpSeparate\0"
    "glStencilOpSeparateATI\0"
    "\0"
-   /* _mesa_function_pool[6733]: ColorTableParameteriv (offset 341) */
+   /* _mesa_function_pool[6852]: ColorTableParameteriv (offset 341) */
    "iip\0"
    "glColorTableParameteriv\0"
    "glColorTableParameterivSGI\0"
    "\0"
-   /* _mesa_function_pool[6789]: FogCoordPointerListIBM (dynamic) */
+   /* _mesa_function_pool[6908]: FogCoordPointerListIBM (dynamic) */
    "iipi\0"
    "glFogCoordPointerListIBM\0"
    "\0"
-   /* _mesa_function_pool[6820]: WindowPos3dMESA (will be remapped) */
+   /* _mesa_function_pool[6939]: WindowPos3dMESA (will be remapped) */
    "ddd\0"
    "glWindowPos3d\0"
    "glWindowPos3dARB\0"
    "glWindowPos3dMESA\0"
    "\0"
-   /* _mesa_function_pool[6874]: Color4us (offset 39) */
+   /* _mesa_function_pool[6993]: Color4us (offset 39) */
    "iiii\0"
    "glColor4us\0"
    "\0"
-   /* _mesa_function_pool[6891]: PointParameterfvEXT (will be remapped) */
+   /* _mesa_function_pool[7010]: PointParameterfvEXT (will be remapped) */
    "ip\0"
    "glPointParameterfv\0"
    "glPointParameterfvARB\0"
    "glPointParameterfvEXT\0"
    "glPointParameterfvSGIS\0"
    "\0"
-   /* _mesa_function_pool[6981]: Color3bv (offset 10) */
+   /* _mesa_function_pool[7100]: Color3bv (offset 10) */
    "p\0"
    "glColor3bv\0"
    "\0"
-   /* _mesa_function_pool[6995]: WindowPos2fvMESA (will be remapped) */
+   /* _mesa_function_pool[7114]: WindowPos2fvMESA (will be remapped) */
    "p\0"
    "glWindowPos2fv\0"
    "glWindowPos2fvARB\0"
    "glWindowPos2fvMESA\0"
    "\0"
-   /* _mesa_function_pool[7050]: SecondaryColor3bvEXT (will be remapped) */
+   /* _mesa_function_pool[7169]: SecondaryColor3bvEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3bv\0"
    "glSecondaryColor3bvEXT\0"
    "\0"
-   /* _mesa_function_pool[7096]: VertexPointerListIBM (dynamic) */
+   /* _mesa_function_pool[7215]: VertexPointerListIBM (dynamic) */
    "iiipi\0"
    "glVertexPointerListIBM\0"
    "\0"
-   /* _mesa_function_pool[7126]: GetProgramLocalParameterfvARB (will be remapped) */
+   /* _mesa_function_pool[7245]: GetProgramLocalParameterfvARB (will be remapped) */
    "iip\0"
    "glGetProgramLocalParameterfvARB\0"
    "\0"
-   /* _mesa_function_pool[7163]: FragmentMaterialfSGIX (dynamic) */
+   /* _mesa_function_pool[7282]: FragmentMaterialfSGIX (dynamic) */
    "iif\0"
    "glFragmentMaterialfSGIX\0"
    "\0"
-   /* _mesa_function_pool[7192]: TexCoord2fNormal3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[7311]: TexCoord2fNormal3fVertex3fSUN (dynamic) */
    "ffffffff\0"
    "glTexCoord2fNormal3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[7234]: RenderbufferStorageEXT (will be remapped) */
+   /* _mesa_function_pool[7353]: RenderbufferStorageEXT (will be remapped) */
    "iiii\0"
    "glRenderbufferStorage\0"
    "glRenderbufferStorageEXT\0"
    "\0"
-   /* _mesa_function_pool[7287]: IsFenceNV (will be remapped) */
+   /* _mesa_function_pool[7406]: IsFenceNV (will be remapped) */
    "i\0"
    "glIsFenceNV\0"
    "\0"
-   /* _mesa_function_pool[7302]: AttachObjectARB (will be remapped) */
+   /* _mesa_function_pool[7421]: AttachObjectARB (will be remapped) */
    "ii\0"
    "glAttachObjectARB\0"
    "\0"
-   /* _mesa_function_pool[7324]: GetFragmentLightivSGIX (dynamic) */
+   /* _mesa_function_pool[7443]: GetFragmentLightivSGIX (dynamic) */
    "iip\0"
    "glGetFragmentLightivSGIX\0"
    "\0"
-   /* _mesa_function_pool[7354]: UniformMatrix2fvARB (will be remapped) */
+   /* _mesa_function_pool[7473]: UniformMatrix2fvARB (will be remapped) */
    "iiip\0"
    "glUniformMatrix2fv\0"
    "glUniformMatrix2fvARB\0"
    "\0"
-   /* _mesa_function_pool[7401]: MultiTexCoord2fARB (offset 386) */
+   /* _mesa_function_pool[7520]: MultiTexCoord2fARB (offset 386) */
    "iff\0"
    "glMultiTexCoord2f\0"
    "glMultiTexCoord2fARB\0"
    "\0"
-   /* _mesa_function_pool[7445]: ColorTable (offset 339) */
+   /* _mesa_function_pool[7564]: ColorTable (offset 339) */
    "iiiiip\0"
    "glColorTable\0"
    "glColorTableSGI\0"
    "glColorTableEXT\0"
    "\0"
-   /* _mesa_function_pool[7498]: IndexPointer (offset 314) */
+   /* _mesa_function_pool[7617]: IndexPointer (offset 314) */
    "iip\0"
    "glIndexPointer\0"
    "\0"
-   /* _mesa_function_pool[7518]: Accum (offset 213) */
+   /* _mesa_function_pool[7637]: Accum (offset 213) */
    "if\0"
    "glAccum\0"
    "\0"
-   /* _mesa_function_pool[7530]: GetTexImage (offset 281) */
+   /* _mesa_function_pool[7649]: GetTexImage (offset 281) */
    "iiiip\0"
    "glGetTexImage\0"
    "\0"
-   /* _mesa_function_pool[7551]: MapControlPointsNV (dynamic) */
+   /* _mesa_function_pool[7670]: MapControlPointsNV (dynamic) */
    "iiiiiiiip\0"
    "glMapControlPointsNV\0"
    "\0"
-   /* _mesa_function_pool[7583]: ConvolutionFilter2D (offset 349) */
+   /* _mesa_function_pool[7702]: ConvolutionFilter2D (offset 349) */
    "iiiiiip\0"
    "glConvolutionFilter2D\0"
    "glConvolutionFilter2DEXT\0"
    "\0"
-   /* _mesa_function_pool[7639]: Finish (offset 216) */
+   /* _mesa_function_pool[7758]: Finish (offset 216) */
    "\0"
    "glFinish\0"
    "\0"
-   /* _mesa_function_pool[7650]: MapParameterfvNV (dynamic) */
+   /* _mesa_function_pool[7769]: MapParameterfvNV (dynamic) */
    "iip\0"
    "glMapParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[7674]: ClearStencil (offset 207) */
+   /* _mesa_function_pool[7793]: ClearStencil (offset 207) */
    "i\0"
    "glClearStencil\0"
    "\0"
-   /* _mesa_function_pool[7692]: VertexAttrib3dvARB (will be remapped) */
+   /* _mesa_function_pool[7811]: VertexAttrib3dvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib3dv\0"
    "glVertexAttrib3dvARB\0"
    "\0"
-   /* _mesa_function_pool[7735]: HintPGI (dynamic) */
+   /* _mesa_function_pool[7854]: HintPGI (dynamic) */
    "ii\0"
    "glHintPGI\0"
    "\0"
-   /* _mesa_function_pool[7749]: ConvolutionParameteriv (offset 353) */
+   /* _mesa_function_pool[7868]: ConvolutionParameteriv (offset 353) */
    "iip\0"
    "glConvolutionParameteriv\0"
    "glConvolutionParameterivEXT\0"
    "\0"
-   /* _mesa_function_pool[7807]: Color4s (offset 33) */
+   /* _mesa_function_pool[7926]: Color4s (offset 33) */
    "iiii\0"
    "glColor4s\0"
    "\0"
-   /* _mesa_function_pool[7823]: InterleavedArrays (offset 317) */
+   /* _mesa_function_pool[7942]: InterleavedArrays (offset 317) */
    "iip\0"
    "glInterleavedArrays\0"
    "\0"
-   /* _mesa_function_pool[7848]: RasterPos2fv (offset 65) */
+   /* _mesa_function_pool[7967]: RasterPos2fv (offset 65) */
    "p\0"
    "glRasterPos2fv\0"
    "\0"
-   /* _mesa_function_pool[7866]: TexCoord1fv (offset 97) */
+   /* _mesa_function_pool[7985]: TexCoord1fv (offset 97) */
    "p\0"
    "glTexCoord1fv\0"
    "\0"
-   /* _mesa_function_pool[7883]: Vertex2d (offset 126) */
+   /* _mesa_function_pool[8002]: Vertex2d (offset 126) */
    "dd\0"
    "glVertex2d\0"
    "\0"
-   /* _mesa_function_pool[7898]: CullParameterdvEXT (will be remapped) */
+   /* _mesa_function_pool[8017]: CullParameterdvEXT (will be remapped) */
    "ip\0"
    "glCullParameterdvEXT\0"
    "\0"
-   /* _mesa_function_pool[7923]: ProgramNamedParameter4fNV (will be remapped) */
+   /* _mesa_function_pool[8042]: ProgramNamedParameter4fNV (will be remapped) */
    "iipffff\0"
    "glProgramNamedParameter4fNV\0"
    "\0"
-   /* _mesa_function_pool[7960]: Color3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[8079]: Color3fVertex3fSUN (dynamic) */
    "ffffff\0"
    "glColor3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[7989]: ProgramEnvParameter4fvARB (will be remapped) */
+   /* _mesa_function_pool[8108]: ProgramEnvParameter4fvARB (will be remapped) */
    "iip\0"
    "glProgramEnvParameter4fvARB\0"
    "glProgramParameter4fvNV\0"
    "\0"
-   /* _mesa_function_pool[8046]: Color4i (offset 31) */
+   /* _mesa_function_pool[8165]: Color4i (offset 31) */
    "iiii\0"
    "glColor4i\0"
    "\0"
-   /* _mesa_function_pool[8062]: Color4f (offset 29) */
+   /* _mesa_function_pool[8181]: Color4f (offset 29) */
    "ffff\0"
    "glColor4f\0"
    "\0"
-   /* _mesa_function_pool[8078]: RasterPos4fv (offset 81) */
+   /* _mesa_function_pool[8197]: RasterPos4fv (offset 81) */
    "p\0"
    "glRasterPos4fv\0"
    "\0"
-   /* _mesa_function_pool[8096]: Color4d (offset 27) */
+   /* _mesa_function_pool[8215]: Color4d (offset 27) */
    "dddd\0"
    "glColor4d\0"
    "\0"
-   /* _mesa_function_pool[8112]: ClearIndex (offset 205) */
+   /* _mesa_function_pool[8231]: ClearIndex (offset 205) */
    "f\0"
    "glClearIndex\0"
    "\0"
-   /* _mesa_function_pool[8128]: Color4b (offset 25) */
+   /* _mesa_function_pool[8247]: Color4b (offset 25) */
    "iiii\0"
    "glColor4b\0"
    "\0"
-   /* _mesa_function_pool[8144]: LoadMatrixd (offset 292) */
+   /* _mesa_function_pool[8263]: LoadMatrixd (offset 292) */
    "p\0"
    "glLoadMatrixd\0"
    "\0"
-   /* _mesa_function_pool[8161]: FragmentLightModeliSGIX (dynamic) */
+   /* _mesa_function_pool[8280]: FragmentLightModeliSGIX (dynamic) */
    "ii\0"
    "glFragmentLightModeliSGIX\0"
    "\0"
-   /* _mesa_function_pool[8191]: RasterPos2dv (offset 63) */
+   /* _mesa_function_pool[8310]: RasterPos2dv (offset 63) */
    "p\0"
    "glRasterPos2dv\0"
    "\0"
-   /* _mesa_function_pool[8209]: ConvolutionParameterfv (offset 351) */
+   /* _mesa_function_pool[8328]: ConvolutionParameterfv (offset 351) */
    "iip\0"
    "glConvolutionParameterfv\0"
    "glConvolutionParameterfvEXT\0"
    "\0"
-   /* _mesa_function_pool[8267]: TbufferMask3DFX (dynamic) */
+   /* _mesa_function_pool[8386]: TbufferMask3DFX (dynamic) */
    "i\0"
    "glTbufferMask3DFX\0"
    "\0"
-   /* _mesa_function_pool[8288]: GetTexGendv (offset 278) */
+   /* _mesa_function_pool[8407]: GetTexGendv (offset 278) */
    "iip\0"
    "glGetTexGendv\0"
    "\0"
-   /* _mesa_function_pool[8307]: GetVertexAttribfvNV (will be remapped) */
+   /* _mesa_function_pool[8426]: GetVertexAttribfvNV (will be remapped) */
    "iip\0"
    "glGetVertexAttribfvNV\0"
    "\0"
-   /* _mesa_function_pool[8334]: BeginTransformFeedbackEXT (will be remapped) */
+   /* _mesa_function_pool[8453]: BeginTransformFeedbackEXT (will be remapped) */
    "i\0"
    "glBeginTransformFeedbackEXT\0"
    "glBeginTransformFeedback\0"
    "\0"
-   /* _mesa_function_pool[8390]: LoadProgramNV (will be remapped) */
+   /* _mesa_function_pool[8509]: LoadProgramNV (will be remapped) */
    "iiip\0"
    "glLoadProgramNV\0"
    "\0"
-   /* _mesa_function_pool[8412]: WaitSync (will be remapped) */
+   /* _mesa_function_pool[8531]: WaitSync (will be remapped) */
    "iii\0"
    "glWaitSync\0"
    "\0"
-   /* _mesa_function_pool[8428]: EndList (offset 1) */
+   /* _mesa_function_pool[8547]: EndList (offset 1) */
    "\0"
    "glEndList\0"
    "\0"
-   /* _mesa_function_pool[8440]: VertexAttrib4fvNV (will be remapped) */
+   /* _mesa_function_pool[8559]: VertexAttrib4fvNV (will be remapped) */
    "ip\0"
    "glVertexAttrib4fvNV\0"
    "\0"
-   /* _mesa_function_pool[8464]: GetAttachedObjectsARB (will be remapped) */
+   /* _mesa_function_pool[8583]: GetAttachedObjectsARB (will be remapped) */
    "iipp\0"
    "glGetAttachedObjectsARB\0"
    "\0"
-   /* _mesa_function_pool[8494]: Uniform3fvARB (will be remapped) */
+   /* _mesa_function_pool[8613]: Uniform3fvARB (will be remapped) */
    "iip\0"
    "glUniform3fv\0"
    "glUniform3fvARB\0"
    "\0"
-   /* _mesa_function_pool[8528]: EvalCoord1fv (offset 231) */
+   /* _mesa_function_pool[8647]: EvalCoord1fv (offset 231) */
    "p\0"
    "glEvalCoord1fv\0"
    "\0"
-   /* _mesa_function_pool[8546]: DrawRangeElements (offset 338) */
+   /* _mesa_function_pool[8665]: DrawRangeElements (offset 338) */
    "iiiiip\0"
    "glDrawRangeElements\0"
    "glDrawRangeElementsEXT\0"
    "\0"
-   /* _mesa_function_pool[8597]: EvalMesh2 (offset 238) */
+   /* _mesa_function_pool[8716]: EvalMesh2 (offset 238) */
    "iiiii\0"
    "glEvalMesh2\0"
    "\0"
-   /* _mesa_function_pool[8616]: Vertex4fv (offset 145) */
+   /* _mesa_function_pool[8735]: Vertex4fv (offset 145) */
    "p\0"
    "glVertex4fv\0"
    "\0"
-   /* _mesa_function_pool[8631]: SpriteParameterfvSGIX (dynamic) */
+   /* _mesa_function_pool[8750]: GenTransformFeedbacks (will be remapped) */
+   "ip\0"
+   "glGenTransformFeedbacks\0"
+   "\0"
+   /* _mesa_function_pool[8778]: SpriteParameterfvSGIX (dynamic) */
    "ip\0"
    "glSpriteParameterfvSGIX\0"
    "\0"
-   /* _mesa_function_pool[8659]: CheckFramebufferStatusEXT (will be remapped) */
+   /* _mesa_function_pool[8806]: CheckFramebufferStatusEXT (will be remapped) */
    "i\0"
    "glCheckFramebufferStatus\0"
    "glCheckFramebufferStatusEXT\0"
    "\0"
-   /* _mesa_function_pool[8715]: GlobalAlphaFactoruiSUN (dynamic) */
+   /* _mesa_function_pool[8862]: GlobalAlphaFactoruiSUN (dynamic) */
    "i\0"
    "glGlobalAlphaFactoruiSUN\0"
    "\0"
-   /* _mesa_function_pool[8743]: GetHandleARB (will be remapped) */
+   /* _mesa_function_pool[8890]: GetHandleARB (will be remapped) */
    "i\0"
    "glGetHandleARB\0"
    "\0"
-   /* _mesa_function_pool[8761]: GetVertexAttribivARB (will be remapped) */
+   /* _mesa_function_pool[8908]: GetVertexAttribivARB (will be remapped) */
    "iip\0"
    "glGetVertexAttribiv\0"
    "glGetVertexAttribivARB\0"
    "\0"
-   /* _mesa_function_pool[8809]: GetCombinerInputParameterfvNV (will be remapped) */
+   /* _mesa_function_pool[8956]: GetCombinerInputParameterfvNV (will be remapped) */
    "iiiip\0"
    "glGetCombinerInputParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[8848]: CreateProgram (will be remapped) */
+   /* _mesa_function_pool[8995]: CreateProgram (will be remapped) */
    "\0"
    "glCreateProgram\0"
    "\0"
-   /* _mesa_function_pool[8866]: LoadTransposeMatrixdARB (will be remapped) */
+   /* _mesa_function_pool[9013]: LoadTransposeMatrixdARB (will be remapped) */
    "p\0"
    "glLoadTransposeMatrixd\0"
    "glLoadTransposeMatrixdARB\0"
    "\0"
-   /* _mesa_function_pool[8918]: GetMinmax (offset 364) */
+   /* _mesa_function_pool[9065]: GetMinmax (offset 364) */
    "iiiip\0"
    "glGetMinmax\0"
    "glGetMinmaxEXT\0"
    "\0"
-   /* _mesa_function_pool[8952]: StencilFuncSeparate (will be remapped) */
+   /* _mesa_function_pool[9099]: StencilFuncSeparate (will be remapped) */
    "iiii\0"
    "glStencilFuncSeparate\0"
    "\0"
-   /* _mesa_function_pool[8980]: SecondaryColor3sEXT (will be remapped) */
+   /* _mesa_function_pool[9127]: SecondaryColor3sEXT (will be remapped) */
    "iii\0"
    "glSecondaryColor3s\0"
    "glSecondaryColor3sEXT\0"
    "\0"
-   /* _mesa_function_pool[9026]: Color3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[9173]: Color3fVertex3fvSUN (dynamic) */
    "pp\0"
    "glColor3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[9052]: Normal3fv (offset 57) */
+   /* _mesa_function_pool[9199]: Normal3fv (offset 57) */
    "p\0"
    "glNormal3fv\0"
    "\0"
-   /* _mesa_function_pool[9067]: GlobalAlphaFactorbSUN (dynamic) */
+   /* _mesa_function_pool[9214]: GlobalAlphaFactorbSUN (dynamic) */
    "i\0"
    "glGlobalAlphaFactorbSUN\0"
    "\0"
-   /* _mesa_function_pool[9094]: Color3us (offset 23) */
+   /* _mesa_function_pool[9241]: Color3us (offset 23) */
    "iii\0"
    "glColor3us\0"
    "\0"
-   /* _mesa_function_pool[9110]: ImageTransformParameterfvHP (dynamic) */
+   /* _mesa_function_pool[9257]: ImageTransformParameterfvHP (dynamic) */
    "iip\0"
    "glImageTransformParameterfvHP\0"
    "\0"
-   /* _mesa_function_pool[9145]: VertexAttrib4ivARB (will be remapped) */
+   /* _mesa_function_pool[9292]: VertexAttrib4ivARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4iv\0"
    "glVertexAttrib4ivARB\0"
    "\0"
-   /* _mesa_function_pool[9188]: End (offset 43) */
+   /* _mesa_function_pool[9335]: End (offset 43) */
    "\0"
    "glEnd\0"
    "\0"
-   /* _mesa_function_pool[9196]: VertexAttrib3fNV (will be remapped) */
+   /* _mesa_function_pool[9343]: VertexAttrib3fNV (will be remapped) */
    "ifff\0"
    "glVertexAttrib3fNV\0"
    "\0"
-   /* _mesa_function_pool[9221]: VertexAttribs2dvNV (will be remapped) */
+   /* _mesa_function_pool[9368]: VertexAttribs2dvNV (will be remapped) */
    "iip\0"
    "glVertexAttribs2dvNV\0"
    "\0"
-   /* _mesa_function_pool[9247]: GetQueryObjectui64vEXT (will be remapped) */
+   /* _mesa_function_pool[9394]: GetQueryObjectui64vEXT (will be remapped) */
    "iip\0"
    "glGetQueryObjectui64vEXT\0"
    "\0"
-   /* _mesa_function_pool[9277]: MultiTexCoord3fvARB (offset 395) */
+   /* _mesa_function_pool[9424]: MultiTexCoord3fvARB (offset 395) */
    "ip\0"
    "glMultiTexCoord3fv\0"
    "glMultiTexCoord3fvARB\0"
    "\0"
-   /* _mesa_function_pool[9322]: SecondaryColor3dEXT (will be remapped) */
+   /* _mesa_function_pool[9469]: SecondaryColor3dEXT (will be remapped) */
    "ddd\0"
    "glSecondaryColor3d\0"
    "glSecondaryColor3dEXT\0"
    "\0"
-   /* _mesa_function_pool[9368]: Color3ub (offset 19) */
+   /* _mesa_function_pool[9515]: Color3ub (offset 19) */
    "iii\0"
    "glColor3ub\0"
    "\0"
-   /* _mesa_function_pool[9384]: GetProgramParameterfvNV (will be remapped) */
+   /* _mesa_function_pool[9531]: GetProgramParameterfvNV (will be remapped) */
    "iiip\0"
    "glGetProgramParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[9416]: TangentPointerEXT (dynamic) */
+   /* _mesa_function_pool[9563]: TangentPointerEXT (dynamic) */
    "iip\0"
    "glTangentPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[9441]: Color4fNormal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[9588]: Color4fNormal3fVertex3fvSUN (dynamic) */
    "ppp\0"
    "glColor4fNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[9476]: GetInstrumentsSGIX (dynamic) */
+   /* _mesa_function_pool[9623]: GetInstrumentsSGIX (dynamic) */
    "\0"
    "glGetInstrumentsSGIX\0"
    "\0"
-   /* _mesa_function_pool[9499]: Color3ui (offset 21) */
+   /* _mesa_function_pool[9646]: Color3ui (offset 21) */
    "iii\0"
    "glColor3ui\0"
    "\0"
-   /* _mesa_function_pool[9515]: EvalMapsNV (dynamic) */
+   /* _mesa_function_pool[9662]: EvalMapsNV (dynamic) */
    "ii\0"
    "glEvalMapsNV\0"
    "\0"
-   /* _mesa_function_pool[9532]: TexSubImage2D (offset 333) */
+   /* _mesa_function_pool[9679]: TexSubImage2D (offset 333) */
    "iiiiiiiip\0"
    "glTexSubImage2D\0"
    "glTexSubImage2DEXT\0"
    "\0"
-   /* _mesa_function_pool[9578]: FragmentLightivSGIX (dynamic) */
+   /* _mesa_function_pool[9725]: FragmentLightivSGIX (dynamic) */
    "iip\0"
    "glFragmentLightivSGIX\0"
    "\0"
-   /* _mesa_function_pool[9605]: GetTexParameterPointervAPPLE (will be remapped) */
+   /* _mesa_function_pool[9752]: GetTexParameterPointervAPPLE (will be remapped) */
    "iip\0"
    "glGetTexParameterPointervAPPLE\0"
    "\0"
-   /* _mesa_function_pool[9641]: TexGenfv (offset 191) */
+   /* _mesa_function_pool[9788]: TexGenfv (offset 191) */
    "iip\0"
    "glTexGenfv\0"
    "\0"
-   /* _mesa_function_pool[9657]: GetTransformFeedbackVaryingEXT (will be remapped) */
+   /* _mesa_function_pool[9804]: GetTransformFeedbackVaryingEXT (will be remapped) */
    "iiipppp\0"
    "glGetTransformFeedbackVaryingEXT\0"
    "glGetTransformFeedbackVarying\0"
    "\0"
-   /* _mesa_function_pool[9729]: VertexAttrib4bvARB (will be remapped) */
+   /* _mesa_function_pool[9876]: VertexAttrib4bvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4bv\0"
    "glVertexAttrib4bvARB\0"
    "\0"
-   /* _mesa_function_pool[9772]: AlphaFragmentOp2ATI (will be remapped) */
+   /* _mesa_function_pool[9919]: AlphaFragmentOp2ATI (will be remapped) */
    "iiiiiiiii\0"
    "glAlphaFragmentOp2ATI\0"
    "\0"
-   /* _mesa_function_pool[9805]: GetIntegerIndexedvEXT (will be remapped) */
+   /* _mesa_function_pool[9952]: GetIntegerIndexedvEXT (will be remapped) */
    "iip\0"
    "glGetIntegerIndexedvEXT\0"
    "\0"
-   /* _mesa_function_pool[9834]: MultiTexCoord4sARB (offset 406) */
+   /* _mesa_function_pool[9981]: MultiTexCoord4sARB (offset 406) */
    "iiiii\0"
    "glMultiTexCoord4s\0"
    "glMultiTexCoord4sARB\0"
    "\0"
-   /* _mesa_function_pool[9880]: GetFragmentMaterialivSGIX (dynamic) */
+   /* _mesa_function_pool[10027]: GetFragmentMaterialivSGIX (dynamic) */
    "iip\0"
    "glGetFragmentMaterialivSGIX\0"
    "\0"
-   /* _mesa_function_pool[9913]: WindowPos4dMESA (will be remapped) */
+   /* _mesa_function_pool[10060]: WindowPos4dMESA (will be remapped) */
    "dddd\0"
    "glWindowPos4dMESA\0"
    "\0"
-   /* _mesa_function_pool[9937]: WeightPointerARB (dynamic) */
+   /* _mesa_function_pool[10084]: WeightPointerARB (dynamic) */
    "iiip\0"
    "glWeightPointerARB\0"
    "\0"
-   /* _mesa_function_pool[9962]: WindowPos2dMESA (will be remapped) */
+   /* _mesa_function_pool[10109]: WindowPos2dMESA (will be remapped) */
    "dd\0"
    "glWindowPos2d\0"
    "glWindowPos2dARB\0"
    "glWindowPos2dMESA\0"
    "\0"
-   /* _mesa_function_pool[10015]: FramebufferTexture3DEXT (will be remapped) */
+   /* _mesa_function_pool[10162]: FramebufferTexture3DEXT (will be remapped) */
    "iiiiii\0"
    "glFramebufferTexture3D\0"
    "glFramebufferTexture3DEXT\0"
    "\0"
-   /* _mesa_function_pool[10072]: BlendEquation (offset 337) */
+   /* _mesa_function_pool[10219]: BlendEquation (offset 337) */
    "i\0"
    "glBlendEquation\0"
    "glBlendEquationEXT\0"
    "\0"
-   /* _mesa_function_pool[10110]: VertexAttrib3dNV (will be remapped) */
+   /* _mesa_function_pool[10257]: VertexAttrib3dNV (will be remapped) */
    "iddd\0"
    "glVertexAttrib3dNV\0"
    "\0"
-   /* _mesa_function_pool[10135]: VertexAttrib3dARB (will be remapped) */
+   /* _mesa_function_pool[10282]: VertexAttrib3dARB (will be remapped) */
    "iddd\0"
    "glVertexAttrib3d\0"
    "glVertexAttrib3dARB\0"
    "\0"
-   /* _mesa_function_pool[10178]: ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[10325]: ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (dynamic) */
    "ppppp\0"
    "glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[10242]: VertexAttrib4fARB (will be remapped) */
+   /* _mesa_function_pool[10389]: VertexAttrib4fARB (will be remapped) */
    "iffff\0"
    "glVertexAttrib4f\0"
    "glVertexAttrib4fARB\0"
    "\0"
-   /* _mesa_function_pool[10286]: GetError (offset 261) */
+   /* _mesa_function_pool[10433]: GetError (offset 261) */
    "\0"
    "glGetError\0"
    "\0"
-   /* _mesa_function_pool[10299]: IndexFuncEXT (dynamic) */
+   /* _mesa_function_pool[10446]: IndexFuncEXT (dynamic) */
    "if\0"
    "glIndexFuncEXT\0"
    "\0"
-   /* _mesa_function_pool[10318]: TexCoord3dv (offset 111) */
+   /* _mesa_function_pool[10465]: TexCoord3dv (offset 111) */
    "p\0"
    "glTexCoord3dv\0"
    "\0"
-   /* _mesa_function_pool[10335]: Indexdv (offset 45) */
+   /* _mesa_function_pool[10482]: Indexdv (offset 45) */
    "p\0"
    "glIndexdv\0"
    "\0"
-   /* _mesa_function_pool[10348]: FramebufferTexture2DEXT (will be remapped) */
+   /* _mesa_function_pool[10495]: FramebufferTexture2DEXT (will be remapped) */
    "iiiii\0"
    "glFramebufferTexture2D\0"
    "glFramebufferTexture2DEXT\0"
    "\0"
-   /* _mesa_function_pool[10404]: Normal3s (offset 60) */
+   /* _mesa_function_pool[10551]: Normal3s (offset 60) */
    "iii\0"
    "glNormal3s\0"
    "\0"
-   /* _mesa_function_pool[10420]: GetObjectParameterivAPPLE (will be remapped) */
+   /* _mesa_function_pool[10567]: GetObjectParameterivAPPLE (will be remapped) */
    "iiip\0"
    "glGetObjectParameterivAPPLE\0"
    "\0"
-   /* _mesa_function_pool[10454]: PushName (offset 201) */
+   /* _mesa_function_pool[10601]: PushName (offset 201) */
    "i\0"
    "glPushName\0"
    "\0"
-   /* _mesa_function_pool[10468]: MultiTexCoord2dvARB (offset 385) */
+   /* _mesa_function_pool[10615]: MultiTexCoord2dvARB (offset 385) */
    "ip\0"
    "glMultiTexCoord2dv\0"
    "glMultiTexCoord2dvARB\0"
    "\0"
-   /* _mesa_function_pool[10513]: CullParameterfvEXT (will be remapped) */
+   /* _mesa_function_pool[10660]: CullParameterfvEXT (will be remapped) */
    "ip\0"
    "glCullParameterfvEXT\0"
    "\0"
-   /* _mesa_function_pool[10538]: Normal3i (offset 58) */
+   /* _mesa_function_pool[10685]: Normal3i (offset 58) */
    "iii\0"
    "glNormal3i\0"
    "\0"
-   /* _mesa_function_pool[10554]: ProgramNamedParameter4fvNV (will be remapped) */
+   /* _mesa_function_pool[10701]: ProgramNamedParameter4fvNV (will be remapped) */
    "iipp\0"
    "glProgramNamedParameter4fvNV\0"
    "\0"
-   /* _mesa_function_pool[10589]: SecondaryColorPointerEXT (will be remapped) */
+   /* _mesa_function_pool[10736]: SecondaryColorPointerEXT (will be remapped) */
    "iiip\0"
    "glSecondaryColorPointer\0"
    "glSecondaryColorPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[10646]: VertexAttrib4fvARB (will be remapped) */
+   /* _mesa_function_pool[10793]: VertexAttrib4fvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4fv\0"
    "glVertexAttrib4fvARB\0"
    "\0"
-   /* _mesa_function_pool[10689]: ColorPointerListIBM (dynamic) */
+   /* _mesa_function_pool[10836]: ColorPointerListIBM (dynamic) */
    "iiipi\0"
    "glColorPointerListIBM\0"
    "\0"
-   /* _mesa_function_pool[10718]: GetActiveUniformARB (will be remapped) */
+   /* _mesa_function_pool[10865]: GetActiveUniformARB (will be remapped) */
    "iiipppp\0"
    "glGetActiveUniform\0"
    "glGetActiveUniformARB\0"
    "\0"
-   /* _mesa_function_pool[10768]: ImageTransformParameteriHP (dynamic) */
+   /* _mesa_function_pool[10915]: ImageTransformParameteriHP (dynamic) */
    "iii\0"
    "glImageTransformParameteriHP\0"
    "\0"
-   /* _mesa_function_pool[10802]: Normal3b (offset 52) */
+   /* _mesa_function_pool[10949]: Normal3b (offset 52) */
    "iii\0"
    "glNormal3b\0"
    "\0"
-   /* _mesa_function_pool[10818]: Normal3d (offset 54) */
+   /* _mesa_function_pool[10965]: Normal3d (offset 54) */
    "ddd\0"
    "glNormal3d\0"
    "\0"
-   /* _mesa_function_pool[10834]: Normal3f (offset 56) */
+   /* _mesa_function_pool[10981]: Normal3f (offset 56) */
    "fff\0"
    "glNormal3f\0"
    "\0"
-   /* _mesa_function_pool[10850]: MultiTexCoord1svARB (offset 383) */
+   /* _mesa_function_pool[10997]: MultiTexCoord1svARB (offset 383) */
    "ip\0"
    "glMultiTexCoord1sv\0"
    "glMultiTexCoord1svARB\0"
    "\0"
-   /* _mesa_function_pool[10895]: Indexi (offset 48) */
+   /* _mesa_function_pool[11042]: Indexi (offset 48) */
    "i\0"
    "glIndexi\0"
    "\0"
-   /* _mesa_function_pool[10907]: EGLImageTargetTexture2DOES (will be remapped) */
+   /* _mesa_function_pool[11054]: EGLImageTargetTexture2DOES (will be remapped) */
    "ip\0"
    "glEGLImageTargetTexture2DOES\0"
    "\0"
-   /* _mesa_function_pool[10940]: EndQueryARB (will be remapped) */
+   /* _mesa_function_pool[11087]: EndQueryARB (will be remapped) */
    "i\0"
    "glEndQuery\0"
    "glEndQueryARB\0"
    "\0"
-   /* _mesa_function_pool[10968]: DeleteFencesNV (will be remapped) */
+   /* _mesa_function_pool[11115]: DeleteFencesNV (will be remapped) */
    "ip\0"
    "glDeleteFencesNV\0"
    "\0"
-   /* _mesa_function_pool[10989]: DeformationMap3dSGIX (dynamic) */
-   "iddiiddiiddiip\0"
-   "glDeformationMap3dSGIX\0"
-   "\0"
-   /* _mesa_function_pool[11028]: BindBufferRangeEXT (will be remapped) */
+   /* _mesa_function_pool[11136]: BindBufferRangeEXT (will be remapped) */
    "iiiii\0"
    "glBindBufferRangeEXT\0"
    "glBindBufferRange\0"
    "\0"
-   /* _mesa_function_pool[11074]: DepthMask (offset 211) */
+   /* _mesa_function_pool[11182]: DepthMask (offset 211) */
    "i\0"
    "glDepthMask\0"
    "\0"
-   /* _mesa_function_pool[11089]: IsShader (will be remapped) */
+   /* _mesa_function_pool[11197]: IsShader (will be remapped) */
    "i\0"
    "glIsShader\0"
    "\0"
-   /* _mesa_function_pool[11103]: Indexf (offset 46) */
+   /* _mesa_function_pool[11211]: Indexf (offset 46) */
    "f\0"
    "glIndexf\0"
    "\0"
-   /* _mesa_function_pool[11115]: GetImageTransformParameterivHP (dynamic) */
+   /* _mesa_function_pool[11223]: GetImageTransformParameterivHP (dynamic) */
    "iip\0"
    "glGetImageTransformParameterivHP\0"
    "\0"
-   /* _mesa_function_pool[11153]: Indexd (offset 44) */
+   /* _mesa_function_pool[11261]: Indexd (offset 44) */
    "d\0"
    "glIndexd\0"
    "\0"
-   /* _mesa_function_pool[11165]: GetMaterialiv (offset 270) */
+   /* _mesa_function_pool[11273]: GetMaterialiv (offset 270) */
    "iip\0"
    "glGetMaterialiv\0"
    "\0"
-   /* _mesa_function_pool[11186]: StencilOp (offset 244) */
+   /* _mesa_function_pool[11294]: StencilOp (offset 244) */
    "iii\0"
    "glStencilOp\0"
    "\0"
-   /* _mesa_function_pool[11203]: WindowPos4ivMESA (will be remapped) */
+   /* _mesa_function_pool[11311]: WindowPos4ivMESA (will be remapped) */
    "p\0"
    "glWindowPos4ivMESA\0"
    "\0"
-   /* _mesa_function_pool[11225]: MultiTexCoord3svARB (offset 399) */
+   /* _mesa_function_pool[11333]: FramebufferTextureLayer (dynamic) */
+   "iiiii\0"
+   "glFramebufferTextureLayerARB\0"
+   "\0"
+   /* _mesa_function_pool[11369]: MultiTexCoord3svARB (offset 399) */
    "ip\0"
    "glMultiTexCoord3sv\0"
    "glMultiTexCoord3svARB\0"
    "\0"
-   /* _mesa_function_pool[11270]: TexEnvfv (offset 185) */
+   /* _mesa_function_pool[11414]: TexEnvfv (offset 185) */
    "iip\0"
    "glTexEnvfv\0"
    "\0"
-   /* _mesa_function_pool[11286]: MultiTexCoord4iARB (offset 404) */
+   /* _mesa_function_pool[11430]: MultiTexCoord4iARB (offset 404) */
    "iiiii\0"
    "glMultiTexCoord4i\0"
    "glMultiTexCoord4iARB\0"
    "\0"
-   /* _mesa_function_pool[11332]: Indexs (offset 50) */
+   /* _mesa_function_pool[11476]: Indexs (offset 50) */
    "i\0"
    "glIndexs\0"
    "\0"
-   /* _mesa_function_pool[11344]: Binormal3ivEXT (dynamic) */
+   /* _mesa_function_pool[11488]: Binormal3ivEXT (dynamic) */
    "p\0"
    "glBinormal3ivEXT\0"
    "\0"
-   /* _mesa_function_pool[11364]: ResizeBuffersMESA (will be remapped) */
+   /* _mesa_function_pool[11508]: ResizeBuffersMESA (will be remapped) */
    "\0"
    "glResizeBuffersMESA\0"
    "\0"
-   /* _mesa_function_pool[11386]: GetUniformivARB (will be remapped) */
+   /* _mesa_function_pool[11530]: GetUniformivARB (will be remapped) */
    "iip\0"
    "glGetUniformiv\0"
    "glGetUniformivARB\0"
    "\0"
-   /* _mesa_function_pool[11424]: PixelTexGenParameteriSGIS (will be remapped) */
+   /* _mesa_function_pool[11568]: PixelTexGenParameteriSGIS (will be remapped) */
    "ii\0"
    "glPixelTexGenParameteriSGIS\0"
    "\0"
-   /* _mesa_function_pool[11456]: VertexPointervINTEL (dynamic) */
+   /* _mesa_function_pool[11600]: VertexPointervINTEL (dynamic) */
    "iip\0"
    "glVertexPointervINTEL\0"
    "\0"
-   /* _mesa_function_pool[11483]: Vertex2i (offset 130) */
+   /* _mesa_function_pool[11627]: Vertex2i (offset 130) */
    "ii\0"
    "glVertex2i\0"
    "\0"
-   /* _mesa_function_pool[11498]: LoadMatrixf (offset 291) */
+   /* _mesa_function_pool[11642]: LoadMatrixf (offset 291) */
    "p\0"
    "glLoadMatrixf\0"
    "\0"
-   /* _mesa_function_pool[11515]: Vertex2f (offset 128) */
+   /* _mesa_function_pool[11659]: Vertex2f (offset 128) */
    "ff\0"
    "glVertex2f\0"
    "\0"
-   /* _mesa_function_pool[11530]: ReplacementCodeuiColor4fNormal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[11674]: ReplacementCodeuiColor4fNormal3fVertex3fvSUN (dynamic) */
    "pppp\0"
    "glReplacementCodeuiColor4fNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[11583]: Color4bv (offset 26) */
+   /* _mesa_function_pool[11727]: Color4bv (offset 26) */
    "p\0"
    "glColor4bv\0"
    "\0"
-   /* _mesa_function_pool[11597]: VertexPointer (offset 321) */
+   /* _mesa_function_pool[11741]: VertexPointer (offset 321) */
    "iiip\0"
    "glVertexPointer\0"
    "\0"
-   /* _mesa_function_pool[11619]: SecondaryColor3uiEXT (will be remapped) */
+   /* _mesa_function_pool[11763]: SecondaryColor3uiEXT (will be remapped) */
    "iii\0"
    "glSecondaryColor3ui\0"
    "glSecondaryColor3uiEXT\0"
    "\0"
-   /* _mesa_function_pool[11667]: StartInstrumentsSGIX (dynamic) */
+   /* _mesa_function_pool[11811]: StartInstrumentsSGIX (dynamic) */
    "\0"
    "glStartInstrumentsSGIX\0"
    "\0"
-   /* _mesa_function_pool[11692]: SecondaryColor3usvEXT (will be remapped) */
+   /* _mesa_function_pool[11836]: SecondaryColor3usvEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3usv\0"
    "glSecondaryColor3usvEXT\0"
    "\0"
-   /* _mesa_function_pool[11740]: VertexAttrib2fvNV (will be remapped) */
+   /* _mesa_function_pool[11884]: VertexAttrib2fvNV (will be remapped) */
    "ip\0"
    "glVertexAttrib2fvNV\0"
    "\0"
-   /* _mesa_function_pool[11764]: ProgramLocalParameter4dvARB (will be remapped) */
+   /* _mesa_function_pool[11908]: ProgramLocalParameter4dvARB (will be remapped) */
    "iip\0"
    "glProgramLocalParameter4dvARB\0"
    "\0"
-   /* _mesa_function_pool[11799]: DeleteLists (offset 4) */
+   /* _mesa_function_pool[11943]: DeleteLists (offset 4) */
    "ii\0"
    "glDeleteLists\0"
    "\0"
-   /* _mesa_function_pool[11817]: LogicOp (offset 242) */
+   /* _mesa_function_pool[11961]: LogicOp (offset 242) */
    "i\0"
    "glLogicOp\0"
    "\0"
-   /* _mesa_function_pool[11830]: MatrixIndexuivARB (dynamic) */
+   /* _mesa_function_pool[11974]: MatrixIndexuivARB (dynamic) */
    "ip\0"
    "glMatrixIndexuivARB\0"
    "\0"
-   /* _mesa_function_pool[11854]: Vertex2s (offset 132) */
+   /* _mesa_function_pool[11998]: Vertex2s (offset 132) */
    "ii\0"
    "glVertex2s\0"
    "\0"
-   /* _mesa_function_pool[11869]: RenderbufferStorageMultisample (will be remapped) */
+   /* _mesa_function_pool[12013]: RenderbufferStorageMultisample (will be remapped) */
    "iiiii\0"
    "glRenderbufferStorageMultisample\0"
    "glRenderbufferStorageMultisampleEXT\0"
    "\0"
-   /* _mesa_function_pool[11945]: TexCoord4fv (offset 121) */
+   /* _mesa_function_pool[12089]: TexCoord4fv (offset 121) */
    "p\0"
    "glTexCoord4fv\0"
    "\0"
-   /* _mesa_function_pool[11962]: Tangent3sEXT (dynamic) */
+   /* _mesa_function_pool[12106]: Tangent3sEXT (dynamic) */
    "iii\0"
    "glTangent3sEXT\0"
    "\0"
-   /* _mesa_function_pool[11982]: GlobalAlphaFactorfSUN (dynamic) */
+   /* _mesa_function_pool[12126]: GlobalAlphaFactorfSUN (dynamic) */
    "f\0"
    "glGlobalAlphaFactorfSUN\0"
    "\0"
-   /* _mesa_function_pool[12009]: MultiTexCoord3iARB (offset 396) */
+   /* _mesa_function_pool[12153]: MultiTexCoord3iARB (offset 396) */
    "iiii\0"
    "glMultiTexCoord3i\0"
    "glMultiTexCoord3iARB\0"
    "\0"
-   /* _mesa_function_pool[12054]: IsProgram (will be remapped) */
+   /* _mesa_function_pool[12198]: IsProgram (will be remapped) */
    "i\0"
    "glIsProgram\0"
    "\0"
-   /* _mesa_function_pool[12069]: TexCoordPointerListIBM (dynamic) */
+   /* _mesa_function_pool[12213]: TexCoordPointerListIBM (dynamic) */
    "iiipi\0"
    "glTexCoordPointerListIBM\0"
    "\0"
-   /* _mesa_function_pool[12101]: GlobalAlphaFactorusSUN (dynamic) */
+   /* _mesa_function_pool[12245]: GlobalAlphaFactorusSUN (dynamic) */
    "i\0"
    "glGlobalAlphaFactorusSUN\0"
    "\0"
-   /* _mesa_function_pool[12129]: VertexAttrib2dvNV (will be remapped) */
+   /* _mesa_function_pool[12273]: VertexAttrib2dvNV (will be remapped) */
    "ip\0"
    "glVertexAttrib2dvNV\0"
    "\0"
-   /* _mesa_function_pool[12153]: FramebufferRenderbufferEXT (will be remapped) */
+   /* _mesa_function_pool[12297]: FramebufferRenderbufferEXT (will be remapped) */
    "iiii\0"
    "glFramebufferRenderbuffer\0"
    "glFramebufferRenderbufferEXT\0"
    "\0"
-   /* _mesa_function_pool[12214]: VertexAttrib1dvNV (will be remapped) */
+   /* _mesa_function_pool[12358]: VertexAttrib1dvNV (will be remapped) */
    "ip\0"
    "glVertexAttrib1dvNV\0"
    "\0"
-   /* _mesa_function_pool[12238]: GenTextures (offset 328) */
+   /* _mesa_function_pool[12382]: GenTextures (offset 328) */
    "ip\0"
    "glGenTextures\0"
    "glGenTexturesEXT\0"
    "\0"
-   /* _mesa_function_pool[12273]: SetFenceNV (will be remapped) */
+   /* _mesa_function_pool[12417]: FramebufferTextureARB (will be remapped) */
+   "iiii\0"
+   "glFramebufferTextureARB\0"
+   "\0"
+   /* _mesa_function_pool[12447]: SetFenceNV (will be remapped) */
    "ii\0"
    "glSetFenceNV\0"
    "\0"
-   /* _mesa_function_pool[12290]: FramebufferTexture1DEXT (will be remapped) */
+   /* _mesa_function_pool[12464]: FramebufferTexture1DEXT (will be remapped) */
    "iiiii\0"
    "glFramebufferTexture1D\0"
    "glFramebufferTexture1DEXT\0"
    "\0"
-   /* _mesa_function_pool[12346]: GetCombinerOutputParameterivNV (will be remapped) */
+   /* _mesa_function_pool[12520]: GetCombinerOutputParameterivNV (will be remapped) */
    "iiip\0"
    "glGetCombinerOutputParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[12385]: PixelTexGenParameterivSGIS (will be remapped) */
+   /* _mesa_function_pool[12559]: MultiModeDrawArraysIBM (will be remapped) */
+   "pppii\0"
+   "glMultiModeDrawArraysIBM\0"
+   "\0"
+   /* _mesa_function_pool[12591]: PixelTexGenParameterivSGIS (will be remapped) */
    "ip\0"
    "glPixelTexGenParameterivSGIS\0"
    "\0"
-   /* _mesa_function_pool[12418]: TextureNormalEXT (dynamic) */
+   /* _mesa_function_pool[12624]: TextureNormalEXT (dynamic) */
    "i\0"
    "glTextureNormalEXT\0"
    "\0"
-   /* _mesa_function_pool[12440]: IndexPointerListIBM (dynamic) */
+   /* _mesa_function_pool[12646]: IndexPointerListIBM (dynamic) */
    "iipi\0"
    "glIndexPointerListIBM\0"
    "\0"
-   /* _mesa_function_pool[12468]: WeightfvARB (dynamic) */
+   /* _mesa_function_pool[12674]: WeightfvARB (dynamic) */
    "ip\0"
    "glWeightfvARB\0"
    "\0"
-   /* _mesa_function_pool[12486]: RasterPos2sv (offset 69) */
+   /* _mesa_function_pool[12692]: GetCombinerOutputParameterfvNV (will be remapped) */
+   "iiip\0"
+   "glGetCombinerOutputParameterfvNV\0"
+   "\0"
+   /* _mesa_function_pool[12731]: RasterPos2sv (offset 69) */
    "p\0"
    "glRasterPos2sv\0"
    "\0"
-   /* _mesa_function_pool[12504]: Color4ubv (offset 36) */
+   /* _mesa_function_pool[12749]: Color4ubv (offset 36) */
    "p\0"
    "glColor4ubv\0"
    "\0"
-   /* _mesa_function_pool[12519]: DrawBuffer (offset 202) */
+   /* _mesa_function_pool[12764]: DrawBuffer (offset 202) */
    "i\0"
    "glDrawBuffer\0"
    "\0"
-   /* _mesa_function_pool[12535]: TexCoord2fv (offset 105) */
+   /* _mesa_function_pool[12780]: TexCoord2fv (offset 105) */
    "p\0"
    "glTexCoord2fv\0"
    "\0"
-   /* _mesa_function_pool[12552]: WindowPos4fMESA (will be remapped) */
+   /* _mesa_function_pool[12797]: WindowPos4fMESA (will be remapped) */
    "ffff\0"
    "glWindowPos4fMESA\0"
    "\0"
-   /* _mesa_function_pool[12576]: TexCoord1sv (offset 101) */
+   /* _mesa_function_pool[12821]: TexCoord1sv (offset 101) */
    "p\0"
    "glTexCoord1sv\0"
    "\0"
-   /* _mesa_function_pool[12593]: WindowPos3dvMESA (will be remapped) */
+   /* _mesa_function_pool[12838]: WindowPos3dvMESA (will be remapped) */
    "p\0"
    "glWindowPos3dv\0"
    "glWindowPos3dvARB\0"
    "glWindowPos3dvMESA\0"
    "\0"
-   /* _mesa_function_pool[12648]: DepthFunc (offset 245) */
+   /* _mesa_function_pool[12893]: DepthFunc (offset 245) */
    "i\0"
    "glDepthFunc\0"
    "\0"
-   /* _mesa_function_pool[12663]: PixelMapusv (offset 253) */
+   /* _mesa_function_pool[12908]: PixelMapusv (offset 253) */
    "iip\0"
    "glPixelMapusv\0"
    "\0"
-   /* _mesa_function_pool[12682]: GetQueryObjecti64vEXT (will be remapped) */
+   /* _mesa_function_pool[12927]: GetQueryObjecti64vEXT (will be remapped) */
    "iip\0"
    "glGetQueryObjecti64vEXT\0"
    "\0"
-   /* _mesa_function_pool[12711]: MultiTexCoord1dARB (offset 376) */
+   /* _mesa_function_pool[12956]: MultiTexCoord1dARB (offset 376) */
    "id\0"
    "glMultiTexCoord1d\0"
    "glMultiTexCoord1dARB\0"
    "\0"
-   /* _mesa_function_pool[12754]: PointParameterivNV (will be remapped) */
+   /* _mesa_function_pool[12999]: PointParameterivNV (will be remapped) */
    "ip\0"
    "glPointParameteriv\0"
    "glPointParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[12798]: BlendFunc (offset 241) */
+   /* _mesa_function_pool[13043]: BlendFunc (offset 241) */
    "ii\0"
    "glBlendFunc\0"
    "\0"
-   /* _mesa_function_pool[12814]: EndTransformFeedbackEXT (will be remapped) */
+   /* _mesa_function_pool[13059]: EndTransformFeedbackEXT (will be remapped) */
    "\0"
    "glEndTransformFeedbackEXT\0"
    "glEndTransformFeedback\0"
    "\0"
-   /* _mesa_function_pool[12865]: Uniform2fvARB (will be remapped) */
+   /* _mesa_function_pool[13110]: Uniform2fvARB (will be remapped) */
    "iip\0"
    "glUniform2fv\0"
    "glUniform2fvARB\0"
    "\0"
-   /* _mesa_function_pool[12899]: BufferParameteriAPPLE (will be remapped) */
+   /* _mesa_function_pool[13144]: BufferParameteriAPPLE (will be remapped) */
    "iii\0"
    "glBufferParameteriAPPLE\0"
    "\0"
-   /* _mesa_function_pool[12928]: MultiTexCoord3dvARB (offset 393) */
+   /* _mesa_function_pool[13173]: MultiTexCoord3dvARB (offset 393) */
    "ip\0"
    "glMultiTexCoord3dv\0"
    "glMultiTexCoord3dvARB\0"
    "\0"
-   /* _mesa_function_pool[12973]: ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[13218]: ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (dynamic) */
    "pppp\0"
    "glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[13029]: DeleteObjectARB (will be remapped) */
+   /* _mesa_function_pool[13274]: DeleteObjectARB (will be remapped) */
    "i\0"
    "glDeleteObjectARB\0"
    "\0"
-   /* _mesa_function_pool[13050]: MatrixIndexPointerARB (dynamic) */
+   /* _mesa_function_pool[13295]: MatrixIndexPointerARB (dynamic) */
    "iiip\0"
    "glMatrixIndexPointerARB\0"
    "\0"
-   /* _mesa_function_pool[13080]: ProgramNamedParameter4dvNV (will be remapped) */
+   /* _mesa_function_pool[13325]: ProgramNamedParameter4dvNV (will be remapped) */
    "iipp\0"
    "glProgramNamedParameter4dvNV\0"
    "\0"
-   /* _mesa_function_pool[13115]: Tangent3fvEXT (dynamic) */
+   /* _mesa_function_pool[13360]: Tangent3fvEXT (dynamic) */
    "p\0"
    "glTangent3fvEXT\0"
    "\0"
-   /* _mesa_function_pool[13134]: Flush (offset 217) */
+   /* _mesa_function_pool[13379]: Flush (offset 217) */
    "\0"
    "glFlush\0"
    "\0"
-   /* _mesa_function_pool[13144]: Color4uiv (offset 38) */
+   /* _mesa_function_pool[13389]: Color4uiv (offset 38) */
    "p\0"
    "glColor4uiv\0"
    "\0"
-   /* _mesa_function_pool[13159]: GenVertexArrays (will be remapped) */
+   /* _mesa_function_pool[13404]: GenVertexArrays (will be remapped) */
    "ip\0"
    "glGenVertexArrays\0"
    "\0"
-   /* _mesa_function_pool[13181]: RasterPos3sv (offset 77) */
+   /* _mesa_function_pool[13426]: RasterPos3sv (offset 77) */
    "p\0"
    "glRasterPos3sv\0"
    "\0"
-   /* _mesa_function_pool[13199]: BindFramebufferEXT (will be remapped) */
+   /* _mesa_function_pool[13444]: BindFramebufferEXT (will be remapped) */
    "ii\0"
    "glBindFramebuffer\0"
    "glBindFramebufferEXT\0"
    "\0"
-   /* _mesa_function_pool[13242]: ReferencePlaneSGIX (dynamic) */
+   /* _mesa_function_pool[13487]: ReferencePlaneSGIX (dynamic) */
    "p\0"
    "glReferencePlaneSGIX\0"
    "\0"
-   /* _mesa_function_pool[13266]: PushAttrib (offset 219) */
+   /* _mesa_function_pool[13511]: PushAttrib (offset 219) */
    "i\0"
    "glPushAttrib\0"
    "\0"
-   /* _mesa_function_pool[13282]: RasterPos2i (offset 66) */
+   /* _mesa_function_pool[13527]: RasterPos2i (offset 66) */
    "ii\0"
    "glRasterPos2i\0"
    "\0"
-   /* _mesa_function_pool[13300]: ValidateProgramARB (will be remapped) */
+   /* _mesa_function_pool[13545]: ValidateProgramARB (will be remapped) */
    "i\0"
    "glValidateProgram\0"
    "glValidateProgramARB\0"
    "\0"
-   /* _mesa_function_pool[13342]: TexParameteriv (offset 181) */
+   /* _mesa_function_pool[13587]: TexParameteriv (offset 181) */
    "iip\0"
    "glTexParameteriv\0"
    "\0"
-   /* _mesa_function_pool[13364]: UnlockArraysEXT (will be remapped) */
+   /* _mesa_function_pool[13609]: UnlockArraysEXT (will be remapped) */
    "\0"
    "glUnlockArraysEXT\0"
    "\0"
-   /* _mesa_function_pool[13384]: TexCoord2fColor3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[13629]: TexCoord2fColor3fVertex3fSUN (dynamic) */
    "ffffffff\0"
    "glTexCoord2fColor3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[13425]: WindowPos3fvMESA (will be remapped) */
+   /* _mesa_function_pool[13670]: WindowPos3fvMESA (will be remapped) */
    "p\0"
    "glWindowPos3fv\0"
    "glWindowPos3fvARB\0"
    "glWindowPos3fvMESA\0"
    "\0"
-   /* _mesa_function_pool[13480]: RasterPos2f (offset 64) */
+   /* _mesa_function_pool[13725]: RasterPos2f (offset 64) */
    "ff\0"
    "glRasterPos2f\0"
    "\0"
-   /* _mesa_function_pool[13498]: VertexAttrib1svNV (will be remapped) */
+   /* _mesa_function_pool[13743]: VertexAttrib1svNV (will be remapped) */
    "ip\0"
    "glVertexAttrib1svNV\0"
    "\0"
-   /* _mesa_function_pool[13522]: RasterPos2d (offset 62) */
+   /* _mesa_function_pool[13767]: RasterPos2d (offset 62) */
    "dd\0"
    "glRasterPos2d\0"
    "\0"
-   /* _mesa_function_pool[13540]: RasterPos3fv (offset 73) */
+   /* _mesa_function_pool[13785]: RasterPos3fv (offset 73) */
    "p\0"
    "glRasterPos3fv\0"
    "\0"
-   /* _mesa_function_pool[13558]: CopyTexSubImage3D (offset 373) */
+   /* _mesa_function_pool[13803]: CopyTexSubImage3D (offset 373) */
    "iiiiiiiii\0"
    "glCopyTexSubImage3D\0"
    "glCopyTexSubImage3DEXT\0"
    "\0"
-   /* _mesa_function_pool[13612]: VertexAttrib2dARB (will be remapped) */
+   /* _mesa_function_pool[13857]: VertexAttrib2dARB (will be remapped) */
    "idd\0"
    "glVertexAttrib2d\0"
    "glVertexAttrib2dARB\0"
    "\0"
-   /* _mesa_function_pool[13654]: Color4ub (offset 35) */
+   /* _mesa_function_pool[13899]: Color4ub (offset 35) */
    "iiii\0"
    "glColor4ub\0"
    "\0"
-   /* _mesa_function_pool[13671]: GetInteger64v (will be remapped) */
+   /* _mesa_function_pool[13916]: GetInteger64v (will be remapped) */
    "ip\0"
    "glGetInteger64v\0"
    "\0"
-   /* _mesa_function_pool[13691]: TextureColorMaskSGIS (dynamic) */
+   /* _mesa_function_pool[13936]: TextureColorMaskSGIS (dynamic) */
    "iiii\0"
    "glTextureColorMaskSGIS\0"
    "\0"
-   /* _mesa_function_pool[13720]: RasterPos2s (offset 68) */
+   /* _mesa_function_pool[13965]: RasterPos2s (offset 68) */
    "ii\0"
    "glRasterPos2s\0"
    "\0"
-   /* _mesa_function_pool[13738]: GetColorTable (offset 343) */
+   /* _mesa_function_pool[13983]: GetColorTable (offset 343) */
    "iiip\0"
    "glGetColorTable\0"
    "glGetColorTableSGI\0"
    "glGetColorTableEXT\0"
    "\0"
-   /* _mesa_function_pool[13798]: SelectBuffer (offset 195) */
+   /* _mesa_function_pool[14043]: SelectBuffer (offset 195) */
    "ip\0"
    "glSelectBuffer\0"
    "\0"
-   /* _mesa_function_pool[13817]: Indexiv (offset 49) */
+   /* _mesa_function_pool[14062]: Indexiv (offset 49) */
    "p\0"
    "glIndexiv\0"
    "\0"
-   /* _mesa_function_pool[13830]: TexCoord3i (offset 114) */
+   /* _mesa_function_pool[14075]: TexCoord3i (offset 114) */
    "iii\0"
    "glTexCoord3i\0"
    "\0"
-   /* _mesa_function_pool[13848]: CopyColorTable (offset 342) */
+   /* _mesa_function_pool[14093]: CopyColorTable (offset 342) */
    "iiiii\0"
    "glCopyColorTable\0"
    "glCopyColorTableSGI\0"
    "\0"
-   /* _mesa_function_pool[13892]: GetHistogramParameterfv (offset 362) */
+   /* _mesa_function_pool[14137]: GetHistogramParameterfv (offset 362) */
    "iip\0"
    "glGetHistogramParameterfv\0"
    "glGetHistogramParameterfvEXT\0"
    "\0"
-   /* _mesa_function_pool[13952]: Frustum (offset 289) */
+   /* _mesa_function_pool[14197]: Frustum (offset 289) */
    "dddddd\0"
    "glFrustum\0"
    "\0"
-   /* _mesa_function_pool[13970]: GetString (offset 275) */
+   /* _mesa_function_pool[14215]: GetString (offset 275) */
    "i\0"
    "glGetString\0"
    "\0"
-   /* _mesa_function_pool[13985]: ColorPointervINTEL (dynamic) */
+   /* _mesa_function_pool[14230]: ColorPointervINTEL (dynamic) */
    "iip\0"
    "glColorPointervINTEL\0"
    "\0"
-   /* _mesa_function_pool[14011]: TexEnvf (offset 184) */
+   /* _mesa_function_pool[14256]: TexEnvf (offset 184) */
    "iif\0"
    "glTexEnvf\0"
    "\0"
-   /* _mesa_function_pool[14026]: TexCoord3d (offset 110) */
+   /* _mesa_function_pool[14271]: TexCoord3d (offset 110) */
    "ddd\0"
    "glTexCoord3d\0"
    "\0"
-   /* _mesa_function_pool[14044]: AlphaFragmentOp1ATI (will be remapped) */
+   /* _mesa_function_pool[14289]: AlphaFragmentOp1ATI (will be remapped) */
    "iiiiii\0"
    "glAlphaFragmentOp1ATI\0"
    "\0"
-   /* _mesa_function_pool[14074]: TexCoord3f (offset 112) */
+   /* _mesa_function_pool[14319]: TexCoord3f (offset 112) */
    "fff\0"
    "glTexCoord3f\0"
    "\0"
-   /* _mesa_function_pool[14092]: MultiTexCoord3ivARB (offset 397) */
+   /* _mesa_function_pool[14337]: MultiTexCoord3ivARB (offset 397) */
    "ip\0"
    "glMultiTexCoord3iv\0"
    "glMultiTexCoord3ivARB\0"
    "\0"
-   /* _mesa_function_pool[14137]: MultiTexCoord2sARB (offset 390) */
+   /* _mesa_function_pool[14382]: MultiTexCoord2sARB (offset 390) */
    "iii\0"
    "glMultiTexCoord2s\0"
    "glMultiTexCoord2sARB\0"
    "\0"
-   /* _mesa_function_pool[14181]: VertexAttrib1dvARB (will be remapped) */
+   /* _mesa_function_pool[14426]: VertexAttrib1dvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib1dv\0"
    "glVertexAttrib1dvARB\0"
    "\0"
-   /* _mesa_function_pool[14224]: DeleteTextures (offset 327) */
+   /* _mesa_function_pool[14469]: DeleteTextures (offset 327) */
    "ip\0"
    "glDeleteTextures\0"
    "glDeleteTexturesEXT\0"
    "\0"
-   /* _mesa_function_pool[14265]: TexCoordPointerEXT (will be remapped) */
+   /* _mesa_function_pool[14510]: TexCoordPointerEXT (will be remapped) */
    "iiiip\0"
    "glTexCoordPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[14293]: TexSubImage4DSGIS (dynamic) */
+   /* _mesa_function_pool[14538]: TexSubImage4DSGIS (dynamic) */
    "iiiiiiiiiiiip\0"
    "glTexSubImage4DSGIS\0"
    "\0"
-   /* _mesa_function_pool[14328]: TexCoord3s (offset 116) */
+   /* _mesa_function_pool[14573]: TexCoord3s (offset 116) */
    "iii\0"
    "glTexCoord3s\0"
    "\0"
-   /* _mesa_function_pool[14346]: GetTexLevelParameteriv (offset 285) */
+   /* _mesa_function_pool[14591]: GetTexLevelParameteriv (offset 285) */
    "iiip\0"
    "glGetTexLevelParameteriv\0"
    "\0"
-   /* _mesa_function_pool[14377]: DrawArraysInstanced (will be remapped) */
+   /* _mesa_function_pool[14622]: DrawArraysInstanced (will be remapped) */
    "iiii\0"
    "glDrawArraysInstanced\0"
    "glDrawArraysInstancedARB\0"
    "glDrawArraysInstancedEXT\0"
    "\0"
-   /* _mesa_function_pool[14455]: CombinerStageParameterfvNV (dynamic) */
+   /* _mesa_function_pool[14700]: CombinerStageParameterfvNV (dynamic) */
    "iip\0"
    "glCombinerStageParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[14489]: StopInstrumentsSGIX (dynamic) */
+   /* _mesa_function_pool[14734]: StopInstrumentsSGIX (dynamic) */
    "i\0"
    "glStopInstrumentsSGIX\0"
    "\0"
-   /* _mesa_function_pool[14514]: TexCoord4fColor4fNormal3fVertex4fSUN (dynamic) */
+   /* _mesa_function_pool[14759]: TexCoord4fColor4fNormal3fVertex4fSUN (dynamic) */
    "fffffffffffffff\0"
    "glTexCoord4fColor4fNormal3fVertex4fSUN\0"
    "\0"
-   /* _mesa_function_pool[14570]: ClearAccum (offset 204) */
+   /* _mesa_function_pool[14815]: ClearAccum (offset 204) */
    "ffff\0"
    "glClearAccum\0"
    "\0"
-   /* _mesa_function_pool[14589]: DeformSGIX (dynamic) */
+   /* _mesa_function_pool[14834]: DeformSGIX (dynamic) */
    "i\0"
    "glDeformSGIX\0"
    "\0"
-   /* _mesa_function_pool[14605]: GetVertexAttribfvARB (will be remapped) */
+   /* _mesa_function_pool[14850]: GetVertexAttribfvARB (will be remapped) */
    "iip\0"
    "glGetVertexAttribfv\0"
    "glGetVertexAttribfvARB\0"
    "\0"
-   /* _mesa_function_pool[14653]: SecondaryColor3ivEXT (will be remapped) */
+   /* _mesa_function_pool[14898]: SecondaryColor3ivEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3iv\0"
    "glSecondaryColor3ivEXT\0"
    "\0"
-   /* _mesa_function_pool[14699]: TexCoord4iv (offset 123) */
+   /* _mesa_function_pool[14944]: TexCoord4iv (offset 123) */
    "p\0"
    "glTexCoord4iv\0"
    "\0"
-   /* _mesa_function_pool[14716]: UniformMatrix4x2fv (will be remapped) */
+   /* _mesa_function_pool[14961]: UniformMatrix4x2fv (will be remapped) */
    "iiip\0"
    "glUniformMatrix4x2fv\0"
    "\0"
-   /* _mesa_function_pool[14743]: GetDetailTexFuncSGIS (dynamic) */
+   /* _mesa_function_pool[14988]: GetDetailTexFuncSGIS (dynamic) */
    "ip\0"
    "glGetDetailTexFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[14770]: GetCombinerStageParameterfvNV (dynamic) */
+   /* _mesa_function_pool[15015]: GetCombinerStageParameterfvNV (dynamic) */
    "iip\0"
    "glGetCombinerStageParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[14807]: PolygonOffset (offset 319) */
+   /* _mesa_function_pool[15052]: PolygonOffset (offset 319) */
    "ff\0"
    "glPolygonOffset\0"
    "\0"
-   /* _mesa_function_pool[14827]: BindVertexArray (will be remapped) */
+   /* _mesa_function_pool[15072]: BindVertexArray (will be remapped) */
    "i\0"
    "glBindVertexArray\0"
    "\0"
-   /* _mesa_function_pool[14848]: Color4ubVertex2fvSUN (dynamic) */
+   /* _mesa_function_pool[15093]: Color4ubVertex2fvSUN (dynamic) */
    "pp\0"
    "glColor4ubVertex2fvSUN\0"
    "\0"
-   /* _mesa_function_pool[14875]: Rectd (offset 86) */
+   /* _mesa_function_pool[15120]: Rectd (offset 86) */
    "dddd\0"
    "glRectd\0"
    "\0"
-   /* _mesa_function_pool[14889]: TexFilterFuncSGIS (dynamic) */
+   /* _mesa_function_pool[15134]: TexFilterFuncSGIS (dynamic) */
    "iiip\0"
    "glTexFilterFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[14915]: SampleMaskSGIS (will be remapped) */
+   /* _mesa_function_pool[15160]: SampleMaskSGIS (will be remapped) */
    "fi\0"
    "glSampleMaskSGIS\0"
    "glSampleMaskEXT\0"
    "\0"
-   /* _mesa_function_pool[14952]: GetAttribLocationARB (will be remapped) */
+   /* _mesa_function_pool[15197]: GetAttribLocationARB (will be remapped) */
    "ip\0"
    "glGetAttribLocation\0"
    "glGetAttribLocationARB\0"
    "\0"
-   /* _mesa_function_pool[14999]: RasterPos3i (offset 74) */
+   /* _mesa_function_pool[15244]: RasterPos3i (offset 74) */
    "iii\0"
    "glRasterPos3i\0"
    "\0"
-   /* _mesa_function_pool[15018]: VertexAttrib4ubvARB (will be remapped) */
+   /* _mesa_function_pool[15263]: VertexAttrib4ubvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4ubv\0"
    "glVertexAttrib4ubvARB\0"
    "\0"
-   /* _mesa_function_pool[15063]: DetailTexFuncSGIS (dynamic) */
+   /* _mesa_function_pool[15308]: DetailTexFuncSGIS (dynamic) */
    "iip\0"
    "glDetailTexFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[15088]: Normal3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[15333]: Normal3fVertex3fSUN (dynamic) */
    "ffffff\0"
    "glNormal3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[15118]: CopyTexImage2D (offset 324) */
+   /* _mesa_function_pool[15363]: CopyTexImage2D (offset 324) */
    "iiiiiiii\0"
    "glCopyTexImage2D\0"
    "glCopyTexImage2DEXT\0"
    "\0"
-   /* _mesa_function_pool[15165]: GetBufferPointervARB (will be remapped) */
+   /* _mesa_function_pool[15410]: GetBufferPointervARB (will be remapped) */
    "iip\0"
    "glGetBufferPointerv\0"
    "glGetBufferPointervARB\0"
    "\0"
-   /* _mesa_function_pool[15213]: ProgramEnvParameter4fARB (will be remapped) */
+   /* _mesa_function_pool[15458]: ProgramEnvParameter4fARB (will be remapped) */
    "iiffff\0"
    "glProgramEnvParameter4fARB\0"
    "glProgramParameter4fNV\0"
    "\0"
-   /* _mesa_function_pool[15271]: Uniform3ivARB (will be remapped) */
+   /* _mesa_function_pool[15516]: Uniform3ivARB (will be remapped) */
    "iip\0"
    "glUniform3iv\0"
    "glUniform3ivARB\0"
    "\0"
-   /* _mesa_function_pool[15305]: Lightfv (offset 160) */
+   /* _mesa_function_pool[15550]: Lightfv (offset 160) */
    "iip\0"
    "glLightfv\0"
    "\0"
-   /* _mesa_function_pool[15320]: ClearDepth (offset 208) */
+   /* _mesa_function_pool[15565]: ClearDepth (offset 208) */
    "d\0"
    "glClearDepth\0"
    "\0"
-   /* _mesa_function_pool[15336]: GetFenceivNV (will be remapped) */
+   /* _mesa_function_pool[15581]: GetFenceivNV (will be remapped) */
    "iip\0"
    "glGetFenceivNV\0"
    "\0"
-   /* _mesa_function_pool[15356]: WindowPos4dvMESA (will be remapped) */
+   /* _mesa_function_pool[15601]: WindowPos4dvMESA (will be remapped) */
    "p\0"
    "glWindowPos4dvMESA\0"
    "\0"
-   /* _mesa_function_pool[15378]: ColorSubTable (offset 346) */
+   /* _mesa_function_pool[15623]: ColorSubTable (offset 346) */
    "iiiiip\0"
    "glColorSubTable\0"
    "glColorSubTableEXT\0"
    "\0"
-   /* _mesa_function_pool[15421]: Color4fv (offset 30) */
+   /* _mesa_function_pool[15666]: Color4fv (offset 30) */
    "p\0"
    "glColor4fv\0"
    "\0"
-   /* _mesa_function_pool[15435]: MultiTexCoord4ivARB (offset 405) */
+   /* _mesa_function_pool[15680]: MultiTexCoord4ivARB (offset 405) */
    "ip\0"
    "glMultiTexCoord4iv\0"
    "glMultiTexCoord4ivARB\0"
    "\0"
-   /* _mesa_function_pool[15480]: DrawElementsInstanced (will be remapped) */
+   /* _mesa_function_pool[15725]: DrawElementsInstanced (will be remapped) */
    "iiipi\0"
    "glDrawElementsInstanced\0"
    "glDrawElementsInstancedARB\0"
    "glDrawElementsInstancedEXT\0"
    "\0"
-   /* _mesa_function_pool[15565]: ColorPointer (offset 308) */
+   /* _mesa_function_pool[15810]: ColorPointer (offset 308) */
    "iiip\0"
    "glColorPointer\0"
    "\0"
-   /* _mesa_function_pool[15586]: Rects (offset 92) */
+   /* _mesa_function_pool[15831]: Rects (offset 92) */
    "iiii\0"
    "glRects\0"
    "\0"
-   /* _mesa_function_pool[15600]: GetMapAttribParameterfvNV (dynamic) */
+   /* _mesa_function_pool[15845]: GetMapAttribParameterfvNV (dynamic) */
    "iiip\0"
    "glGetMapAttribParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[15634]: Lightiv (offset 162) */
+   /* _mesa_function_pool[15879]: Lightiv (offset 162) */
    "iip\0"
    "glLightiv\0"
    "\0"
-   /* _mesa_function_pool[15649]: VertexAttrib4sARB (will be remapped) */
+   /* _mesa_function_pool[15894]: VertexAttrib4sARB (will be remapped) */
    "iiiii\0"
    "glVertexAttrib4s\0"
    "glVertexAttrib4sARB\0"
    "\0"
-   /* _mesa_function_pool[15693]: GetQueryObjectuivARB (will be remapped) */
+   /* _mesa_function_pool[15938]: GetQueryObjectuivARB (will be remapped) */
    "iip\0"
    "glGetQueryObjectuiv\0"
    "glGetQueryObjectuivARB\0"
    "\0"
-   /* _mesa_function_pool[15741]: GetTexParameteriv (offset 283) */
+   /* _mesa_function_pool[15986]: GetTexParameteriv (offset 283) */
    "iip\0"
    "glGetTexParameteriv\0"
    "\0"
-   /* _mesa_function_pool[15766]: MapParameterivNV (dynamic) */
+   /* _mesa_function_pool[16011]: MapParameterivNV (dynamic) */
    "iip\0"
    "glMapParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[15790]: GenRenderbuffersEXT (will be remapped) */
+   /* _mesa_function_pool[16035]: GenRenderbuffersEXT (will be remapped) */
    "ip\0"
    "glGenRenderbuffers\0"
    "glGenRenderbuffersEXT\0"
    "\0"
-   /* _mesa_function_pool[15835]: VertexAttrib2dvARB (will be remapped) */
+   /* _mesa_function_pool[16080]: VertexAttrib2dvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib2dv\0"
    "glVertexAttrib2dvARB\0"
    "\0"
-   /* _mesa_function_pool[15878]: EdgeFlagPointerEXT (will be remapped) */
+   /* _mesa_function_pool[16123]: EdgeFlagPointerEXT (will be remapped) */
    "iip\0"
    "glEdgeFlagPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[15904]: VertexAttribs2svNV (will be remapped) */
+   /* _mesa_function_pool[16149]: VertexAttribs2svNV (will be remapped) */
    "iip\0"
    "glVertexAttribs2svNV\0"
    "\0"
-   /* _mesa_function_pool[15930]: WeightbvARB (dynamic) */
+   /* _mesa_function_pool[16175]: WeightbvARB (dynamic) */
    "ip\0"
    "glWeightbvARB\0"
    "\0"
-   /* _mesa_function_pool[15948]: VertexAttrib2fvARB (will be remapped) */
+   /* _mesa_function_pool[16193]: VertexAttrib2fvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib2fv\0"
    "glVertexAttrib2fvARB\0"
    "\0"
-   /* _mesa_function_pool[15991]: GetBufferParameterivARB (will be remapped) */
+   /* _mesa_function_pool[16236]: GetBufferParameterivARB (will be remapped) */
    "iip\0"
    "glGetBufferParameteriv\0"
    "glGetBufferParameterivARB\0"
    "\0"
-   /* _mesa_function_pool[16045]: Rectdv (offset 87) */
+   /* _mesa_function_pool[16290]: Rectdv (offset 87) */
    "pp\0"
    "glRectdv\0"
    "\0"
-   /* _mesa_function_pool[16058]: ListParameteriSGIX (dynamic) */
+   /* _mesa_function_pool[16303]: ListParameteriSGIX (dynamic) */
    "iii\0"
    "glListParameteriSGIX\0"
    "\0"
-   /* _mesa_function_pool[16084]: ReplacementCodeuiColor4fNormal3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[16329]: ReplacementCodeuiColor4fNormal3fVertex3fSUN (dynamic) */
    "iffffffffff\0"
    "glReplacementCodeuiColor4fNormal3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[16143]: InstrumentsBufferSGIX (dynamic) */
+   /* _mesa_function_pool[16388]: InstrumentsBufferSGIX (dynamic) */
    "ip\0"
    "glInstrumentsBufferSGIX\0"
    "\0"
-   /* _mesa_function_pool[16171]: VertexAttrib4NivARB (will be remapped) */
+   /* _mesa_function_pool[16416]: VertexAttrib4NivARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4Niv\0"
    "glVertexAttrib4NivARB\0"
    "\0"
-   /* _mesa_function_pool[16216]: GetAttachedShaders (will be remapped) */
+   /* _mesa_function_pool[16461]: GetAttachedShaders (will be remapped) */
    "iipp\0"
    "glGetAttachedShaders\0"
    "\0"
-   /* _mesa_function_pool[16243]: GenVertexArraysAPPLE (will be remapped) */
+   /* _mesa_function_pool[16488]: GenVertexArraysAPPLE (will be remapped) */
    "ip\0"
    "glGenVertexArraysAPPLE\0"
    "\0"
-   /* _mesa_function_pool[16270]: Materialiv (offset 172) */
+   /* _mesa_function_pool[16515]: Materialiv (offset 172) */
    "iip\0"
    "glMaterialiv\0"
    "\0"
-   /* _mesa_function_pool[16288]: PushClientAttrib (offset 335) */
+   /* _mesa_function_pool[16533]: PushClientAttrib (offset 335) */
    "i\0"
    "glPushClientAttrib\0"
    "\0"
-   /* _mesa_function_pool[16310]: ProgramEnvParameters4fvEXT (will be remapped) */
+   /* _mesa_function_pool[16555]: ProgramEnvParameters4fvEXT (will be remapped) */
    "iiip\0"
    "glProgramEnvParameters4fvEXT\0"
    "\0"
-   /* _mesa_function_pool[16345]: TexCoord2fColor4fNormal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[16590]: TexCoord2fColor4fNormal3fVertex3fvSUN (dynamic) */
    "pppp\0"
    "glTexCoord2fColor4fNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[16391]: WindowPos2iMESA (will be remapped) */
+   /* _mesa_function_pool[16636]: WindowPos2iMESA (will be remapped) */
    "ii\0"
    "glWindowPos2i\0"
    "glWindowPos2iARB\0"
    "glWindowPos2iMESA\0"
    "\0"
-   /* _mesa_function_pool[16444]: SecondaryColor3fvEXT (will be remapped) */
+   /* _mesa_function_pool[16689]: SecondaryColor3fvEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3fv\0"
    "glSecondaryColor3fvEXT\0"
    "\0"
-   /* _mesa_function_pool[16490]: PolygonMode (offset 174) */
+   /* _mesa_function_pool[16735]: PolygonMode (offset 174) */
    "ii\0"
    "glPolygonMode\0"
    "\0"
-   /* _mesa_function_pool[16508]: CompressedTexSubImage1DARB (will be remapped) */
+   /* _mesa_function_pool[16753]: CompressedTexSubImage1DARB (will be remapped) */
    "iiiiiip\0"
    "glCompressedTexSubImage1D\0"
    "glCompressedTexSubImage1DARB\0"
    "\0"
-   /* _mesa_function_pool[16572]: GetVertexAttribivNV (will be remapped) */
+   /* _mesa_function_pool[16817]: GetVertexAttribivNV (will be remapped) */
    "iip\0"
    "glGetVertexAttribivNV\0"
    "\0"
-   /* _mesa_function_pool[16599]: GetProgramStringARB (will be remapped) */
+   /* _mesa_function_pool[16844]: GetProgramStringARB (will be remapped) */
    "iip\0"
    "glGetProgramStringARB\0"
    "\0"
-   /* _mesa_function_pool[16626]: TexBumpParameterfvATI (will be remapped) */
+   /* _mesa_function_pool[16871]: TexBumpParameterfvATI (will be remapped) */
    "ip\0"
    "glTexBumpParameterfvATI\0"
    "\0"
-   /* _mesa_function_pool[16654]: CompileShaderARB (will be remapped) */
+   /* _mesa_function_pool[16899]: CompileShaderARB (will be remapped) */
    "i\0"
    "glCompileShader\0"
    "glCompileShaderARB\0"
    "\0"
-   /* _mesa_function_pool[16692]: DeleteShader (will be remapped) */
+   /* _mesa_function_pool[16937]: DeleteShader (will be remapped) */
    "i\0"
    "glDeleteShader\0"
    "\0"
-   /* _mesa_function_pool[16710]: DisableClientState (offset 309) */
+   /* _mesa_function_pool[16955]: DisableClientState (offset 309) */
    "i\0"
    "glDisableClientState\0"
    "\0"
-   /* _mesa_function_pool[16734]: TexGeni (offset 192) */
+   /* _mesa_function_pool[16979]: TexGeni (offset 192) */
    "iii\0"
    "glTexGeni\0"
    "\0"
-   /* _mesa_function_pool[16749]: TexGenf (offset 190) */
+   /* _mesa_function_pool[16994]: TexGenf (offset 190) */
    "iif\0"
    "glTexGenf\0"
    "\0"
-   /* _mesa_function_pool[16764]: Uniform3fARB (will be remapped) */
+   /* _mesa_function_pool[17009]: Uniform3fARB (will be remapped) */
    "ifff\0"
    "glUniform3f\0"
    "glUniform3fARB\0"
    "\0"
-   /* _mesa_function_pool[16797]: TexGend (offset 188) */
+   /* _mesa_function_pool[17042]: TexGend (offset 188) */
    "iid\0"
    "glTexGend\0"
    "\0"
-   /* _mesa_function_pool[16812]: ListParameterfvSGIX (dynamic) */
+   /* _mesa_function_pool[17057]: ListParameterfvSGIX (dynamic) */
    "iip\0"
    "glListParameterfvSGIX\0"
    "\0"
-   /* _mesa_function_pool[16839]: GetPolygonStipple (offset 274) */
+   /* _mesa_function_pool[17084]: GetPolygonStipple (offset 274) */
    "p\0"
    "glGetPolygonStipple\0"
    "\0"
-   /* _mesa_function_pool[16862]: Tangent3dvEXT (dynamic) */
+   /* _mesa_function_pool[17107]: Tangent3dvEXT (dynamic) */
    "p\0"
    "glTangent3dvEXT\0"
    "\0"
-   /* _mesa_function_pool[16881]: BindBufferOffsetEXT (will be remapped) */
+   /* _mesa_function_pool[17126]: BindBufferOffsetEXT (will be remapped) */
    "iiii\0"
    "glBindBufferOffsetEXT\0"
    "\0"
-   /* _mesa_function_pool[16909]: WindowPos3sMESA (will be remapped) */
+   /* _mesa_function_pool[17154]: WindowPos3sMESA (will be remapped) */
    "iii\0"
    "glWindowPos3s\0"
    "glWindowPos3sARB\0"
    "glWindowPos3sMESA\0"
    "\0"
-   /* _mesa_function_pool[16963]: VertexAttrib2svNV (will be remapped) */
+   /* _mesa_function_pool[17208]: VertexAttrib2svNV (will be remapped) */
    "ip\0"
    "glVertexAttrib2svNV\0"
    "\0"
-   /* _mesa_function_pool[16987]: DisableIndexedEXT (will be remapped) */
+   /* _mesa_function_pool[17232]: DisableIndexedEXT (will be remapped) */
    "ii\0"
    "glDisableIndexedEXT\0"
    "\0"
-   /* _mesa_function_pool[17011]: BindBufferBaseEXT (will be remapped) */
+   /* _mesa_function_pool[17256]: BindBufferBaseEXT (will be remapped) */
    "iii\0"
    "glBindBufferBaseEXT\0"
    "glBindBufferBase\0"
    "\0"
-   /* _mesa_function_pool[17053]: TexCoord2fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[17298]: TexCoord2fVertex3fvSUN (dynamic) */
    "pp\0"
    "glTexCoord2fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[17082]: WindowPos4sMESA (will be remapped) */
+   /* _mesa_function_pool[17327]: WindowPos4sMESA (will be remapped) */
    "iiii\0"
    "glWindowPos4sMESA\0"
    "\0"
-   /* _mesa_function_pool[17106]: VertexAttrib4NuivARB (will be remapped) */
+   /* _mesa_function_pool[17351]: VertexAttrib4NuivARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4Nuiv\0"
    "glVertexAttrib4NuivARB\0"
    "\0"
-   /* _mesa_function_pool[17153]: ClientActiveTextureARB (offset 375) */
+   /* _mesa_function_pool[17398]: ClientActiveTextureARB (offset 375) */
    "i\0"
    "glClientActiveTexture\0"
    "glClientActiveTextureARB\0"
    "\0"
-   /* _mesa_function_pool[17203]: PixelTexGenSGIX (will be remapped) */
+   /* _mesa_function_pool[17448]: PixelTexGenSGIX (will be remapped) */
    "i\0"
    "glPixelTexGenSGIX\0"
    "\0"
-   /* _mesa_function_pool[17224]: ReplacementCodeusvSUN (dynamic) */
+   /* _mesa_function_pool[17469]: ReplacementCodeusvSUN (dynamic) */
    "p\0"
    "glReplacementCodeusvSUN\0"
    "\0"
-   /* _mesa_function_pool[17251]: Uniform4fARB (will be remapped) */
+   /* _mesa_function_pool[17496]: Uniform4fARB (will be remapped) */
    "iffff\0"
    "glUniform4f\0"
    "glUniform4fARB\0"
    "\0"
-   /* _mesa_function_pool[17285]: Color4sv (offset 34) */
+   /* _mesa_function_pool[17530]: Color4sv (offset 34) */
    "p\0"
    "glColor4sv\0"
    "\0"
-   /* _mesa_function_pool[17299]: FlushMappedBufferRange (will be remapped) */
+   /* _mesa_function_pool[17544]: FlushMappedBufferRange (will be remapped) */
    "iii\0"
    "glFlushMappedBufferRange\0"
    "\0"
-   /* _mesa_function_pool[17329]: IsProgramNV (will be remapped) */
+   /* _mesa_function_pool[17574]: IsProgramNV (will be remapped) */
    "i\0"
    "glIsProgramARB\0"
    "glIsProgramNV\0"
    "\0"
-   /* _mesa_function_pool[17361]: FlushMappedBufferRangeAPPLE (will be remapped) */
+   /* _mesa_function_pool[17606]: FlushMappedBufferRangeAPPLE (will be remapped) */
    "iii\0"
    "glFlushMappedBufferRangeAPPLE\0"
    "\0"
-   /* _mesa_function_pool[17396]: PixelZoom (offset 246) */
+   /* _mesa_function_pool[17641]: PixelZoom (offset 246) */
    "ff\0"
    "glPixelZoom\0"
    "\0"
-   /* _mesa_function_pool[17412]: ReplacementCodePointerSUN (dynamic) */
+   /* _mesa_function_pool[17657]: ReplacementCodePointerSUN (dynamic) */
    "iip\0"
    "glReplacementCodePointerSUN\0"
    "\0"
-   /* _mesa_function_pool[17445]: ProgramEnvParameter4dARB (will be remapped) */
+   /* _mesa_function_pool[17690]: ProgramEnvParameter4dARB (will be remapped) */
    "iidddd\0"
    "glProgramEnvParameter4dARB\0"
    "glProgramParameter4dNV\0"
    "\0"
-   /* _mesa_function_pool[17503]: ColorTableParameterfv (offset 340) */
+   /* _mesa_function_pool[17748]: ColorTableParameterfv (offset 340) */
    "iip\0"
    "glColorTableParameterfv\0"
    "glColorTableParameterfvSGI\0"
    "\0"
-   /* _mesa_function_pool[17559]: FragmentLightModelfSGIX (dynamic) */
+   /* _mesa_function_pool[17804]: FragmentLightModelfSGIX (dynamic) */
    "if\0"
    "glFragmentLightModelfSGIX\0"
    "\0"
-   /* _mesa_function_pool[17589]: Binormal3bvEXT (dynamic) */
+   /* _mesa_function_pool[17834]: Binormal3bvEXT (dynamic) */
    "p\0"
    "glBinormal3bvEXT\0"
    "\0"
-   /* _mesa_function_pool[17609]: PixelMapuiv (offset 252) */
+   /* _mesa_function_pool[17854]: PixelMapuiv (offset 252) */
    "iip\0"
    "glPixelMapuiv\0"
    "\0"
-   /* _mesa_function_pool[17628]: Color3dv (offset 12) */
+   /* _mesa_function_pool[17873]: Color3dv (offset 12) */
    "p\0"
    "glColor3dv\0"
    "\0"
-   /* _mesa_function_pool[17642]: IsTexture (offset 330) */
+   /* _mesa_function_pool[17887]: IsTexture (offset 330) */
    "i\0"
    "glIsTexture\0"
    "glIsTextureEXT\0"
    "\0"
-   /* _mesa_function_pool[17672]: VertexWeightfvEXT (dynamic) */
+   /* _mesa_function_pool[17917]: VertexWeightfvEXT (dynamic) */
    "p\0"
    "glVertexWeightfvEXT\0"
    "\0"
-   /* _mesa_function_pool[17695]: VertexAttrib1dARB (will be remapped) */
+   /* _mesa_function_pool[17940]: VertexAttrib1dARB (will be remapped) */
    "id\0"
    "glVertexAttrib1d\0"
    "glVertexAttrib1dARB\0"
    "\0"
-   /* _mesa_function_pool[17736]: ImageTransformParameterivHP (dynamic) */
+   /* _mesa_function_pool[17981]: ImageTransformParameterivHP (dynamic) */
    "iip\0"
    "glImageTransformParameterivHP\0"
    "\0"
-   /* _mesa_function_pool[17771]: TexCoord4i (offset 122) */
+   /* _mesa_function_pool[18016]: TexCoord4i (offset 122) */
    "iiii\0"
    "glTexCoord4i\0"
    "\0"
-   /* _mesa_function_pool[17790]: DeleteQueriesARB (will be remapped) */
+   /* _mesa_function_pool[18035]: DeleteQueriesARB (will be remapped) */
    "ip\0"
    "glDeleteQueries\0"
    "glDeleteQueriesARB\0"
    "\0"
-   /* _mesa_function_pool[17829]: Color4ubVertex2fSUN (dynamic) */
+   /* _mesa_function_pool[18074]: Color4ubVertex2fSUN (dynamic) */
    "iiiiff\0"
    "glColor4ubVertex2fSUN\0"
    "\0"
-   /* _mesa_function_pool[17859]: FragmentColorMaterialSGIX (dynamic) */
+   /* _mesa_function_pool[18104]: FragmentColorMaterialSGIX (dynamic) */
    "ii\0"
    "glFragmentColorMaterialSGIX\0"
    "\0"
-   /* _mesa_function_pool[17891]: CurrentPaletteMatrixARB (dynamic) */
+   /* _mesa_function_pool[18136]: CurrentPaletteMatrixARB (dynamic) */
    "i\0"
    "glCurrentPaletteMatrixARB\0"
    "\0"
-   /* _mesa_function_pool[17920]: GetMapdv (offset 266) */
+   /* _mesa_function_pool[18165]: GetMapdv (offset 266) */
    "iip\0"
    "glGetMapdv\0"
    "\0"
-   /* _mesa_function_pool[17936]: ObjectPurgeableAPPLE (will be remapped) */
+   /* _mesa_function_pool[18181]: ObjectPurgeableAPPLE (will be remapped) */
    "iii\0"
    "glObjectPurgeableAPPLE\0"
    "\0"
-   /* _mesa_function_pool[17964]: SamplePatternSGIS (will be remapped) */
+   /* _mesa_function_pool[18209]: SamplePatternSGIS (will be remapped) */
    "i\0"
    "glSamplePatternSGIS\0"
    "glSamplePatternEXT\0"
    "\0"
-   /* _mesa_function_pool[18006]: PixelStoref (offset 249) */
+   /* _mesa_function_pool[18251]: PixelStoref (offset 249) */
    "if\0"
    "glPixelStoref\0"
    "\0"
-   /* _mesa_function_pool[18024]: IsQueryARB (will be remapped) */
+   /* _mesa_function_pool[18269]: IsQueryARB (will be remapped) */
    "i\0"
    "glIsQuery\0"
    "glIsQueryARB\0"
    "\0"
-   /* _mesa_function_pool[18050]: ReplacementCodeuiColor4ubVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[18295]: ReplacementCodeuiColor4ubVertex3fSUN (dynamic) */
    "iiiiifff\0"
    "glReplacementCodeuiColor4ubVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[18099]: PixelStorei (offset 250) */
+   /* _mesa_function_pool[18344]: PixelStorei (offset 250) */
    "ii\0"
    "glPixelStorei\0"
    "\0"
-   /* _mesa_function_pool[18117]: VertexAttrib4usvARB (will be remapped) */
+   /* _mesa_function_pool[18362]: VertexAttrib4usvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4usv\0"
    "glVertexAttrib4usvARB\0"
    "\0"
-   /* _mesa_function_pool[18162]: LinkProgramARB (will be remapped) */
+   /* _mesa_function_pool[18407]: LinkProgramARB (will be remapped) */
    "i\0"
    "glLinkProgram\0"
    "glLinkProgramARB\0"
    "\0"
-   /* _mesa_function_pool[18196]: VertexAttrib2fNV (will be remapped) */
+   /* _mesa_function_pool[18441]: VertexAttrib2fNV (will be remapped) */
    "iff\0"
    "glVertexAttrib2fNV\0"
    "\0"
-   /* _mesa_function_pool[18220]: ShaderSourceARB (will be remapped) */
+   /* _mesa_function_pool[18465]: ShaderSourceARB (will be remapped) */
    "iipp\0"
    "glShaderSource\0"
    "glShaderSourceARB\0"
    "\0"
-   /* _mesa_function_pool[18259]: FragmentMaterialiSGIX (dynamic) */
+   /* _mesa_function_pool[18504]: FragmentMaterialiSGIX (dynamic) */
    "iii\0"
    "glFragmentMaterialiSGIX\0"
    "\0"
-   /* _mesa_function_pool[18288]: EvalCoord2dv (offset 233) */
+   /* _mesa_function_pool[18533]: EvalCoord2dv (offset 233) */
    "p\0"
    "glEvalCoord2dv\0"
    "\0"
-   /* _mesa_function_pool[18306]: VertexAttrib3svARB (will be remapped) */
+   /* _mesa_function_pool[18551]: VertexAttrib3svARB (will be remapped) */
    "ip\0"
    "glVertexAttrib3sv\0"
    "glVertexAttrib3svARB\0"
    "\0"
-   /* _mesa_function_pool[18349]: ColorMaterial (offset 151) */
+   /* _mesa_function_pool[18594]: ColorMaterial (offset 151) */
    "ii\0"
    "glColorMaterial\0"
    "\0"
-   /* _mesa_function_pool[18369]: CompressedTexSubImage3DARB (will be remapped) */
+   /* _mesa_function_pool[18614]: CompressedTexSubImage3DARB (will be remapped) */
    "iiiiiiiiiip\0"
    "glCompressedTexSubImage3D\0"
    "glCompressedTexSubImage3DARB\0"
    "\0"
-   /* _mesa_function_pool[18437]: WindowPos2ivMESA (will be remapped) */
+   /* _mesa_function_pool[18682]: WindowPos2ivMESA (will be remapped) */
    "p\0"
    "glWindowPos2iv\0"
    "glWindowPos2ivARB\0"
    "glWindowPos2ivMESA\0"
    "\0"
-   /* _mesa_function_pool[18492]: IsFramebufferEXT (will be remapped) */
+   /* _mesa_function_pool[18737]: IsFramebufferEXT (will be remapped) */
    "i\0"
    "glIsFramebuffer\0"
    "glIsFramebufferEXT\0"
    "\0"
-   /* _mesa_function_pool[18530]: Uniform4ivARB (will be remapped) */
+   /* _mesa_function_pool[18775]: Uniform4ivARB (will be remapped) */
    "iip\0"
    "glUniform4iv\0"
    "glUniform4ivARB\0"
    "\0"
-   /* _mesa_function_pool[18564]: GetVertexAttribdvARB (will be remapped) */
+   /* _mesa_function_pool[18809]: GetVertexAttribdvARB (will be remapped) */
    "iip\0"
    "glGetVertexAttribdv\0"
    "glGetVertexAttribdvARB\0"
    "\0"
-   /* _mesa_function_pool[18612]: TexBumpParameterivATI (will be remapped) */
+   /* _mesa_function_pool[18857]: TexBumpParameterivATI (will be remapped) */
    "ip\0"
    "glTexBumpParameterivATI\0"
    "\0"
-   /* _mesa_function_pool[18640]: GetSeparableFilter (offset 359) */
+   /* _mesa_function_pool[18885]: GetSeparableFilter (offset 359) */
    "iiippp\0"
    "glGetSeparableFilter\0"
    "glGetSeparableFilterEXT\0"
    "\0"
-   /* _mesa_function_pool[18693]: Binormal3dEXT (dynamic) */
+   /* _mesa_function_pool[18938]: Binormal3dEXT (dynamic) */
    "ddd\0"
    "glBinormal3dEXT\0"
    "\0"
-   /* _mesa_function_pool[18714]: SpriteParameteriSGIX (dynamic) */
+   /* _mesa_function_pool[18959]: SpriteParameteriSGIX (dynamic) */
    "ii\0"
    "glSpriteParameteriSGIX\0"
    "\0"
-   /* _mesa_function_pool[18741]: RequestResidentProgramsNV (will be remapped) */
+   /* _mesa_function_pool[18986]: RequestResidentProgramsNV (will be remapped) */
    "ip\0"
    "glRequestResidentProgramsNV\0"
    "\0"
-   /* _mesa_function_pool[18773]: TagSampleBufferSGIX (dynamic) */
+   /* _mesa_function_pool[19018]: TagSampleBufferSGIX (dynamic) */
    "\0"
    "glTagSampleBufferSGIX\0"
    "\0"
-   /* _mesa_function_pool[18797]: TransformFeedbackVaryingsEXT (will be remapped) */
+   /* _mesa_function_pool[19042]: TransformFeedbackVaryingsEXT (will be remapped) */
    "iipi\0"
    "glTransformFeedbackVaryingsEXT\0"
    "glTransformFeedbackVaryings\0"
    "\0"
-   /* _mesa_function_pool[18862]: FeedbackBuffer (offset 194) */
+   /* _mesa_function_pool[19107]: FeedbackBuffer (offset 194) */
    "iip\0"
    "glFeedbackBuffer\0"
    "\0"
-   /* _mesa_function_pool[18884]: RasterPos2iv (offset 67) */
+   /* _mesa_function_pool[19129]: RasterPos2iv (offset 67) */
    "p\0"
    "glRasterPos2iv\0"
    "\0"
-   /* _mesa_function_pool[18902]: TexImage1D (offset 182) */
+   /* _mesa_function_pool[19147]: TexImage1D (offset 182) */
    "iiiiiiip\0"
    "glTexImage1D\0"
    "\0"
-   /* _mesa_function_pool[18925]: ListParameterivSGIX (dynamic) */
+   /* _mesa_function_pool[19170]: ListParameterivSGIX (dynamic) */
    "iip\0"
    "glListParameterivSGIX\0"
    "\0"
-   /* _mesa_function_pool[18952]: MultiDrawElementsEXT (will be remapped) */
+   /* _mesa_function_pool[19197]: MultiDrawElementsEXT (will be remapped) */
    "ipipi\0"
    "glMultiDrawElements\0"
    "glMultiDrawElementsEXT\0"
    "\0"
-   /* _mesa_function_pool[19002]: Color3s (offset 17) */
+   /* _mesa_function_pool[19247]: Color3s (offset 17) */
    "iii\0"
    "glColor3s\0"
    "\0"
-   /* _mesa_function_pool[19017]: Uniform1ivARB (will be remapped) */
+   /* _mesa_function_pool[19262]: Uniform1ivARB (will be remapped) */
    "iip\0"
    "glUniform1iv\0"
    "glUniform1ivARB\0"
    "\0"
-   /* _mesa_function_pool[19051]: WindowPos2sMESA (will be remapped) */
+   /* _mesa_function_pool[19296]: WindowPos2sMESA (will be remapped) */
    "ii\0"
    "glWindowPos2s\0"
    "glWindowPos2sARB\0"
    "glWindowPos2sMESA\0"
    "\0"
-   /* _mesa_function_pool[19104]: WeightusvARB (dynamic) */
+   /* _mesa_function_pool[19349]: WeightusvARB (dynamic) */
    "ip\0"
    "glWeightusvARB\0"
    "\0"
-   /* _mesa_function_pool[19123]: TexCoordPointer (offset 320) */
+   /* _mesa_function_pool[19368]: TexCoordPointer (offset 320) */
    "iiip\0"
    "glTexCoordPointer\0"
    "\0"
-   /* _mesa_function_pool[19147]: FogCoordPointerEXT (will be remapped) */
+   /* _mesa_function_pool[19392]: FogCoordPointerEXT (will be remapped) */
    "iip\0"
    "glFogCoordPointer\0"
    "glFogCoordPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[19191]: IndexMaterialEXT (dynamic) */
+   /* _mesa_function_pool[19436]: IndexMaterialEXT (dynamic) */
    "ii\0"
    "glIndexMaterialEXT\0"
    "\0"
-   /* _mesa_function_pool[19214]: Color3i (offset 15) */
+   /* _mesa_function_pool[19459]: Color3i (offset 15) */
    "iii\0"
    "glColor3i\0"
    "\0"
-   /* _mesa_function_pool[19229]: FrontFace (offset 157) */
+   /* _mesa_function_pool[19474]: FrontFace (offset 157) */
    "i\0"
    "glFrontFace\0"
    "\0"
-   /* _mesa_function_pool[19244]: EvalCoord2d (offset 232) */
+   /* _mesa_function_pool[19489]: EvalCoord2d (offset 232) */
    "dd\0"
    "glEvalCoord2d\0"
    "\0"
-   /* _mesa_function_pool[19262]: SecondaryColor3ubvEXT (will be remapped) */
+   /* _mesa_function_pool[19507]: SecondaryColor3ubvEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3ubv\0"
    "glSecondaryColor3ubvEXT\0"
    "\0"
-   /* _mesa_function_pool[19310]: EvalCoord2f (offset 234) */
+   /* _mesa_function_pool[19555]: EvalCoord2f (offset 234) */
    "ff\0"
    "glEvalCoord2f\0"
    "\0"
-   /* _mesa_function_pool[19328]: VertexAttrib4dvARB (will be remapped) */
+   /* _mesa_function_pool[19573]: VertexAttrib4dvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4dv\0"
    "glVertexAttrib4dvARB\0"
    "\0"
-   /* _mesa_function_pool[19371]: BindAttribLocationARB (will be remapped) */
+   /* _mesa_function_pool[19616]: BindAttribLocationARB (will be remapped) */
    "iip\0"
    "glBindAttribLocation\0"
    "glBindAttribLocationARB\0"
    "\0"
-   /* _mesa_function_pool[19421]: Color3b (offset 9) */
+   /* _mesa_function_pool[19666]: Color3b (offset 9) */
    "iii\0"
    "glColor3b\0"
    "\0"
-   /* _mesa_function_pool[19436]: MultiTexCoord2dARB (offset 384) */
+   /* _mesa_function_pool[19681]: MultiTexCoord2dARB (offset 384) */
    "idd\0"
    "glMultiTexCoord2d\0"
    "glMultiTexCoord2dARB\0"
    "\0"
-   /* _mesa_function_pool[19480]: ExecuteProgramNV (will be remapped) */
+   /* _mesa_function_pool[19725]: ExecuteProgramNV (will be remapped) */
    "iip\0"
    "glExecuteProgramNV\0"
    "\0"
-   /* _mesa_function_pool[19504]: Color3f (offset 13) */
+   /* _mesa_function_pool[19749]: Color3f (offset 13) */
    "fff\0"
    "glColor3f\0"
    "\0"
-   /* _mesa_function_pool[19519]: LightEnviSGIX (dynamic) */
+   /* _mesa_function_pool[19764]: LightEnviSGIX (dynamic) */
    "ii\0"
    "glLightEnviSGIX\0"
    "\0"
-   /* _mesa_function_pool[19539]: Color3d (offset 11) */
+   /* _mesa_function_pool[19784]: Color3d (offset 11) */
    "ddd\0"
    "glColor3d\0"
    "\0"
-   /* _mesa_function_pool[19554]: Normal3dv (offset 55) */
+   /* _mesa_function_pool[19799]: Normal3dv (offset 55) */
    "p\0"
    "glNormal3dv\0"
    "\0"
-   /* _mesa_function_pool[19569]: Lightf (offset 159) */
+   /* _mesa_function_pool[19814]: Lightf (offset 159) */
    "iif\0"
    "glLightf\0"
    "\0"
-   /* _mesa_function_pool[19583]: ReplacementCodeuiSUN (dynamic) */
+   /* _mesa_function_pool[19828]: ReplacementCodeuiSUN (dynamic) */
    "i\0"
    "glReplacementCodeuiSUN\0"
    "\0"
-   /* _mesa_function_pool[19609]: MatrixMode (offset 293) */
+   /* _mesa_function_pool[19854]: MatrixMode (offset 293) */
    "i\0"
    "glMatrixMode\0"
    "\0"
-   /* _mesa_function_pool[19625]: GetPixelMapusv (offset 273) */
+   /* _mesa_function_pool[19870]: GetPixelMapusv (offset 273) */
    "ip\0"
    "glGetPixelMapusv\0"
    "\0"
-   /* _mesa_function_pool[19646]: Lighti (offset 161) */
+   /* _mesa_function_pool[19891]: Lighti (offset 161) */
    "iii\0"
    "glLighti\0"
    "\0"
-   /* _mesa_function_pool[19660]: VertexAttribPointerNV (will be remapped) */
+   /* _mesa_function_pool[19905]: VertexAttribPointerNV (will be remapped) */
    "iiiip\0"
    "glVertexAttribPointerNV\0"
    "\0"
-   /* _mesa_function_pool[19691]: ProgramLocalParameters4fvEXT (will be remapped) */
+   /* _mesa_function_pool[19936]: ProgramLocalParameters4fvEXT (will be remapped) */
    "iiip\0"
    "glProgramLocalParameters4fvEXT\0"
    "\0"
-   /* _mesa_function_pool[19728]: GetBooleanIndexedvEXT (will be remapped) */
+   /* _mesa_function_pool[19973]: GetBooleanIndexedvEXT (will be remapped) */
    "iip\0"
    "glGetBooleanIndexedvEXT\0"
    "\0"
-   /* _mesa_function_pool[19757]: GetFramebufferAttachmentParameterivEXT (will be remapped) */
+   /* _mesa_function_pool[20002]: GetFramebufferAttachmentParameterivEXT (will be remapped) */
    "iiip\0"
    "glGetFramebufferAttachmentParameteriv\0"
    "glGetFramebufferAttachmentParameterivEXT\0"
    "\0"
-   /* _mesa_function_pool[19842]: PixelTransformParameterfEXT (dynamic) */
+   /* _mesa_function_pool[20087]: PixelTransformParameterfEXT (dynamic) */
    "iif\0"
    "glPixelTransformParameterfEXT\0"
    "\0"
-   /* _mesa_function_pool[19877]: MultiTexCoord4dvARB (offset 401) */
+   /* _mesa_function_pool[20122]: MultiTexCoord4dvARB (offset 401) */
    "ip\0"
    "glMultiTexCoord4dv\0"
    "glMultiTexCoord4dvARB\0"
    "\0"
-   /* _mesa_function_pool[19922]: PixelTransformParameteriEXT (dynamic) */
+   /* _mesa_function_pool[20167]: PixelTransformParameteriEXT (dynamic) */
    "iii\0"
    "glPixelTransformParameteriEXT\0"
    "\0"
-   /* _mesa_function_pool[19957]: GetDoublev (offset 260) */
+   /* _mesa_function_pool[20202]: GetDoublev (offset 260) */
    "ip\0"
    "glGetDoublev\0"
    "\0"
-   /* _mesa_function_pool[19974]: MultMatrixd (offset 295) */
+   /* _mesa_function_pool[20219]: MultMatrixd (offset 295) */
    "p\0"
    "glMultMatrixd\0"
    "\0"
-   /* _mesa_function_pool[19991]: MultMatrixf (offset 294) */
+   /* _mesa_function_pool[20236]: MultMatrixf (offset 294) */
    "p\0"
    "glMultMatrixf\0"
    "\0"
-   /* _mesa_function_pool[20008]: TexCoord2fColor4ubVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[20253]: TexCoord2fColor4ubVertex3fSUN (dynamic) */
    "ffiiiifff\0"
    "glTexCoord2fColor4ubVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[20051]: Uniform1iARB (will be remapped) */
+   /* _mesa_function_pool[20296]: Uniform1iARB (will be remapped) */
    "ii\0"
    "glUniform1i\0"
    "glUniform1iARB\0"
    "\0"
-   /* _mesa_function_pool[20082]: VertexAttribPointerARB (will be remapped) */
+   /* _mesa_function_pool[20327]: VertexAttribPointerARB (will be remapped) */
    "iiiiip\0"
    "glVertexAttribPointer\0"
    "glVertexAttribPointerARB\0"
    "\0"
-   /* _mesa_function_pool[20137]: SharpenTexFuncSGIS (dynamic) */
+   /* _mesa_function_pool[20382]: VertexAttrib3sNV (will be remapped) */
+   "iiii\0"
+   "glVertexAttrib3sNV\0"
+   "\0"
+   /* _mesa_function_pool[20407]: SharpenTexFuncSGIS (dynamic) */
    "iip\0"
    "glSharpenTexFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[20163]: MultiTexCoord4fvARB (offset 403) */
+   /* _mesa_function_pool[20433]: MultiTexCoord4fvARB (offset 403) */
    "ip\0"
    "glMultiTexCoord4fv\0"
    "glMultiTexCoord4fvARB\0"
    "\0"
-   /* _mesa_function_pool[20208]: UniformMatrix2x3fv (will be remapped) */
+   /* _mesa_function_pool[20478]: UniformMatrix2x3fv (will be remapped) */
    "iiip\0"
    "glUniformMatrix2x3fv\0"
    "\0"
-   /* _mesa_function_pool[20235]: TrackMatrixNV (will be remapped) */
+   /* _mesa_function_pool[20505]: TrackMatrixNV (will be remapped) */
    "iiii\0"
    "glTrackMatrixNV\0"
    "\0"
-   /* _mesa_function_pool[20257]: CombinerParameteriNV (will be remapped) */
+   /* _mesa_function_pool[20527]: CombinerParameteriNV (will be remapped) */
    "ii\0"
    "glCombinerParameteriNV\0"
    "\0"
-   /* _mesa_function_pool[20284]: DeleteAsyncMarkersSGIX (dynamic) */
+   /* _mesa_function_pool[20554]: DeleteAsyncMarkersSGIX (dynamic) */
    "ii\0"
    "glDeleteAsyncMarkersSGIX\0"
    "\0"
-   /* _mesa_function_pool[20313]: ReplacementCodeusSUN (dynamic) */
+   /* _mesa_function_pool[20583]: ReplacementCodeusSUN (dynamic) */
    "i\0"
    "glReplacementCodeusSUN\0"
    "\0"
-   /* _mesa_function_pool[20339]: IsAsyncMarkerSGIX (dynamic) */
+   /* _mesa_function_pool[20609]: IsAsyncMarkerSGIX (dynamic) */
    "i\0"
    "glIsAsyncMarkerSGIX\0"
    "\0"
-   /* _mesa_function_pool[20362]: FrameZoomSGIX (dynamic) */
+   /* _mesa_function_pool[20632]: FrameZoomSGIX (dynamic) */
    "i\0"
    "glFrameZoomSGIX\0"
    "\0"
-   /* _mesa_function_pool[20381]: Normal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[20651]: Normal3fVertex3fvSUN (dynamic) */
    "pp\0"
    "glNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[20408]: RasterPos4sv (offset 85) */
+   /* _mesa_function_pool[20678]: RasterPos4sv (offset 85) */
    "p\0"
    "glRasterPos4sv\0"
    "\0"
-   /* _mesa_function_pool[20426]: VertexAttrib4NsvARB (will be remapped) */
+   /* _mesa_function_pool[20696]: VertexAttrib4NsvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4Nsv\0"
    "glVertexAttrib4NsvARB\0"
    "\0"
-   /* _mesa_function_pool[20471]: VertexAttrib3fvARB (will be remapped) */
+   /* _mesa_function_pool[20741]: VertexAttrib3fvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib3fv\0"
    "glVertexAttrib3fvARB\0"
    "\0"
-   /* _mesa_function_pool[20514]: ClearColor (offset 206) */
+   /* _mesa_function_pool[20784]: ClearColor (offset 206) */
    "ffff\0"
    "glClearColor\0"
    "\0"
-   /* _mesa_function_pool[20533]: GetSynciv (will be remapped) */
+   /* _mesa_function_pool[20803]: GetSynciv (will be remapped) */
    "iiipp\0"
    "glGetSynciv\0"
    "\0"
-   /* _mesa_function_pool[20552]: DeleteFramebuffersEXT (will be remapped) */
+   /* _mesa_function_pool[20822]: DeleteFramebuffersEXT (will be remapped) */
    "ip\0"
    "glDeleteFramebuffers\0"
    "glDeleteFramebuffersEXT\0"
    "\0"
-   /* _mesa_function_pool[20601]: GlobalAlphaFactorsSUN (dynamic) */
+   /* _mesa_function_pool[20871]: GlobalAlphaFactorsSUN (dynamic) */
    "i\0"
    "glGlobalAlphaFactorsSUN\0"
    "\0"
-   /* _mesa_function_pool[20628]: IsEnabledIndexedEXT (will be remapped) */
+   /* _mesa_function_pool[20898]: IsEnabledIndexedEXT (will be remapped) */
    "ii\0"
    "glIsEnabledIndexedEXT\0"
    "\0"
-   /* _mesa_function_pool[20654]: TexEnviv (offset 187) */
+   /* _mesa_function_pool[20924]: TexEnviv (offset 187) */
    "iip\0"
    "glTexEnviv\0"
    "\0"
-   /* _mesa_function_pool[20670]: TexSubImage3D (offset 372) */
+   /* _mesa_function_pool[20940]: TexSubImage3D (offset 372) */
    "iiiiiiiiiip\0"
    "glTexSubImage3D\0"
    "glTexSubImage3DEXT\0"
    "\0"
-   /* _mesa_function_pool[20718]: Tangent3fEXT (dynamic) */
+   /* _mesa_function_pool[20988]: Tangent3fEXT (dynamic) */
    "fff\0"
    "glTangent3fEXT\0"
    "\0"
-   /* _mesa_function_pool[20738]: SecondaryColor3uivEXT (will be remapped) */
+   /* _mesa_function_pool[21008]: SecondaryColor3uivEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3uiv\0"
    "glSecondaryColor3uivEXT\0"
    "\0"
-   /* _mesa_function_pool[20786]: MatrixIndexubvARB (dynamic) */
+   /* _mesa_function_pool[21056]: MatrixIndexubvARB (dynamic) */
    "ip\0"
    "glMatrixIndexubvARB\0"
    "\0"
-   /* _mesa_function_pool[20810]: Color4fNormal3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[21080]: Color4fNormal3fVertex3fSUN (dynamic) */
    "ffffffffff\0"
    "glColor4fNormal3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[20851]: PixelTexGenParameterfSGIS (will be remapped) */
+   /* _mesa_function_pool[21121]: PixelTexGenParameterfSGIS (will be remapped) */
    "if\0"
    "glPixelTexGenParameterfSGIS\0"
    "\0"
-   /* _mesa_function_pool[20883]: CreateShader (will be remapped) */
+   /* _mesa_function_pool[21153]: CreateShader (will be remapped) */
    "i\0"
    "glCreateShader\0"
    "\0"
-   /* _mesa_function_pool[20901]: GetColorTableParameterfv (offset 344) */
+   /* _mesa_function_pool[21171]: GetColorTableParameterfv (offset 344) */
    "iip\0"
    "glGetColorTableParameterfv\0"
    "glGetColorTableParameterfvSGI\0"
    "glGetColorTableParameterfvEXT\0"
    "\0"
-   /* _mesa_function_pool[20993]: FragmentLightModelfvSGIX (dynamic) */
+   /* _mesa_function_pool[21263]: FragmentLightModelfvSGIX (dynamic) */
    "ip\0"
    "glFragmentLightModelfvSGIX\0"
    "\0"
-   /* _mesa_function_pool[21024]: Bitmap (offset 8) */
+   /* _mesa_function_pool[21294]: Bitmap (offset 8) */
    "iiffffp\0"
    "glBitmap\0"
    "\0"
-   /* _mesa_function_pool[21042]: MultiTexCoord3fARB (offset 394) */
+   /* _mesa_function_pool[21312]: MultiTexCoord3fARB (offset 394) */
    "ifff\0"
    "glMultiTexCoord3f\0"
    "glMultiTexCoord3fARB\0"
    "\0"
-   /* _mesa_function_pool[21087]: GetTexLevelParameterfv (offset 284) */
+   /* _mesa_function_pool[21357]: GetTexLevelParameterfv (offset 284) */
    "iiip\0"
    "glGetTexLevelParameterfv\0"
    "\0"
-   /* _mesa_function_pool[21118]: GetPixelTexGenParameterfvSGIS (will be remapped) */
+   /* _mesa_function_pool[21388]: GetPixelTexGenParameterfvSGIS (will be remapped) */
    "ip\0"
    "glGetPixelTexGenParameterfvSGIS\0"
    "\0"
-   /* _mesa_function_pool[21154]: GenFramebuffersEXT (will be remapped) */
+   /* _mesa_function_pool[21424]: GenFramebuffersEXT (will be remapped) */
    "ip\0"
    "glGenFramebuffers\0"
    "glGenFramebuffersEXT\0"
    "\0"
-   /* _mesa_function_pool[21197]: GetProgramParameterdvNV (will be remapped) */
+   /* _mesa_function_pool[21467]: GetProgramParameterdvNV (will be remapped) */
    "iiip\0"
    "glGetProgramParameterdvNV\0"
    "\0"
-   /* _mesa_function_pool[21229]: Vertex2sv (offset 133) */
+   /* _mesa_function_pool[21499]: Vertex2sv (offset 133) */
    "p\0"
    "glVertex2sv\0"
    "\0"
-   /* _mesa_function_pool[21244]: GetIntegerv (offset 263) */
+   /* _mesa_function_pool[21514]: GetIntegerv (offset 263) */
    "ip\0"
    "glGetIntegerv\0"
    "\0"
-   /* _mesa_function_pool[21262]: IsVertexArrayAPPLE (will be remapped) */
+   /* _mesa_function_pool[21532]: IsVertexArrayAPPLE (will be remapped) */
    "i\0"
    "glIsVertexArray\0"
    "glIsVertexArrayAPPLE\0"
    "\0"
-   /* _mesa_function_pool[21302]: FragmentLightfvSGIX (dynamic) */
+   /* _mesa_function_pool[21572]: FragmentLightfvSGIX (dynamic) */
    "iip\0"
    "glFragmentLightfvSGIX\0"
    "\0"
-   /* _mesa_function_pool[21329]: DetachShader (will be remapped) */
+   /* _mesa_function_pool[21599]: DetachShader (will be remapped) */
    "ii\0"
    "glDetachShader\0"
    "\0"
-   /* _mesa_function_pool[21348]: VertexAttrib4NubARB (will be remapped) */
+   /* _mesa_function_pool[21618]: VertexAttrib4NubARB (will be remapped) */
    "iiiii\0"
    "glVertexAttrib4Nub\0"
    "glVertexAttrib4NubARB\0"
    "\0"
-   /* _mesa_function_pool[21396]: GetProgramEnvParameterfvARB (will be remapped) */
+   /* _mesa_function_pool[21666]: GetProgramEnvParameterfvARB (will be remapped) */
    "iip\0"
    "glGetProgramEnvParameterfvARB\0"
    "\0"
-   /* _mesa_function_pool[21431]: GetTrackMatrixivNV (will be remapped) */
+   /* _mesa_function_pool[21701]: GetTrackMatrixivNV (will be remapped) */
    "iiip\0"
    "glGetTrackMatrixivNV\0"
    "\0"
-   /* _mesa_function_pool[21458]: VertexAttrib3svNV (will be remapped) */
+   /* _mesa_function_pool[21728]: VertexAttrib3svNV (will be remapped) */
    "ip\0"
    "glVertexAttrib3svNV\0"
    "\0"
-   /* _mesa_function_pool[21482]: Uniform4fvARB (will be remapped) */
+   /* _mesa_function_pool[21752]: Uniform4fvARB (will be remapped) */
    "iip\0"
    "glUniform4fv\0"
    "glUniform4fvARB\0"
    "\0"
-   /* _mesa_function_pool[21516]: MultTransposeMatrixfARB (will be remapped) */
+   /* _mesa_function_pool[21786]: MultTransposeMatrixfARB (will be remapped) */
    "p\0"
    "glMultTransposeMatrixf\0"
    "glMultTransposeMatrixfARB\0"
    "\0"
-   /* _mesa_function_pool[21568]: GetTexEnviv (offset 277) */
+   /* _mesa_function_pool[21838]: GetTexEnviv (offset 277) */
    "iip\0"
    "glGetTexEnviv\0"
    "\0"
-   /* _mesa_function_pool[21587]: ColorFragmentOp1ATI (will be remapped) */
+   /* _mesa_function_pool[21857]: ColorFragmentOp1ATI (will be remapped) */
    "iiiiiii\0"
    "glColorFragmentOp1ATI\0"
    "\0"
-   /* _mesa_function_pool[21618]: GetUniformfvARB (will be remapped) */
+   /* _mesa_function_pool[21888]: GetUniformfvARB (will be remapped) */
    "iip\0"
    "glGetUniformfv\0"
    "glGetUniformfvARB\0"
    "\0"
-   /* _mesa_function_pool[21656]: EGLImageTargetRenderbufferStorageOES (will be remapped) */
+   /* _mesa_function_pool[21926]: EGLImageTargetRenderbufferStorageOES (will be remapped) */
    "ip\0"
    "glEGLImageTargetRenderbufferStorageOES\0"
    "\0"
-   /* _mesa_function_pool[21699]: PopClientAttrib (offset 334) */
+   /* _mesa_function_pool[21969]: PopClientAttrib (offset 334) */
    "\0"
    "glPopClientAttrib\0"
    "\0"
-   /* _mesa_function_pool[21719]: ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[21989]: ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (dynamic) */
    "iffffffffffff\0"
    "glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[21790]: DetachObjectARB (will be remapped) */
+   /* _mesa_function_pool[22060]: DetachObjectARB (will be remapped) */
    "ii\0"
    "glDetachObjectARB\0"
    "\0"
-   /* _mesa_function_pool[21812]: VertexBlendARB (dynamic) */
+   /* _mesa_function_pool[22082]: VertexBlendARB (dynamic) */
    "i\0"
    "glVertexBlendARB\0"
    "\0"
-   /* _mesa_function_pool[21832]: WindowPos3iMESA (will be remapped) */
+   /* _mesa_function_pool[22102]: WindowPos3iMESA (will be remapped) */
    "iii\0"
    "glWindowPos3i\0"
    "glWindowPos3iARB\0"
    "glWindowPos3iMESA\0"
    "\0"
-   /* _mesa_function_pool[21886]: SeparableFilter2D (offset 360) */
+   /* _mesa_function_pool[22156]: SeparableFilter2D (offset 360) */
    "iiiiiipp\0"
    "glSeparableFilter2D\0"
    "glSeparableFilter2DEXT\0"
    "\0"
-   /* _mesa_function_pool[21939]: ReplacementCodeuiColor4ubVertex3fvSUN (dynamic) */
-   "ppp\0"
-   "glReplacementCodeuiColor4ubVertex3fvSUN\0"
+   /* _mesa_function_pool[22209]: ProgramParameteriARB (will be remapped) */
+   "iii\0"
+   "glProgramParameteriARB\0"
    "\0"
-   /* _mesa_function_pool[21984]: Map1d (offset 220) */
+   /* _mesa_function_pool[22237]: Map1d (offset 220) */
    "iddiip\0"
    "glMap1d\0"
    "\0"
-   /* _mesa_function_pool[22000]: Map1f (offset 221) */
+   /* _mesa_function_pool[22253]: Map1f (offset 221) */
    "iffiip\0"
    "glMap1f\0"
    "\0"
-   /* _mesa_function_pool[22016]: CompressedTexImage2DARB (will be remapped) */
+   /* _mesa_function_pool[22269]: CompressedTexImage2DARB (will be remapped) */
    "iiiiiiip\0"
    "glCompressedTexImage2D\0"
    "glCompressedTexImage2DARB\0"
    "\0"
-   /* _mesa_function_pool[22075]: ArrayElement (offset 306) */
+   /* _mesa_function_pool[22328]: ArrayElement (offset 306) */
    "i\0"
    "glArrayElement\0"
    "glArrayElementEXT\0"
    "\0"
-   /* _mesa_function_pool[22111]: TexImage2D (offset 183) */
+   /* _mesa_function_pool[22364]: TexImage2D (offset 183) */
    "iiiiiiiip\0"
    "glTexImage2D\0"
    "\0"
-   /* _mesa_function_pool[22135]: DepthBoundsEXT (will be remapped) */
+   /* _mesa_function_pool[22388]: DepthBoundsEXT (will be remapped) */
    "dd\0"
    "glDepthBoundsEXT\0"
    "\0"
-   /* _mesa_function_pool[22156]: ProgramParameters4fvNV (will be remapped) */
+   /* _mesa_function_pool[22409]: ProgramParameters4fvNV (will be remapped) */
    "iiip\0"
    "glProgramParameters4fvNV\0"
    "\0"
-   /* _mesa_function_pool[22187]: DeformationMap3fSGIX (dynamic) */
+   /* _mesa_function_pool[22440]: DeformationMap3fSGIX (dynamic) */
    "iffiiffiiffiip\0"
    "glDeformationMap3fSGIX\0"
    "\0"
-   /* _mesa_function_pool[22226]: GetProgramivNV (will be remapped) */
+   /* _mesa_function_pool[22479]: GetProgramivNV (will be remapped) */
    "iip\0"
    "glGetProgramivNV\0"
    "\0"
-   /* _mesa_function_pool[22248]: GetMinmaxParameteriv (offset 366) */
+   /* _mesa_function_pool[22501]: GetMinmaxParameteriv (offset 366) */
    "iip\0"
    "glGetMinmaxParameteriv\0"
    "glGetMinmaxParameterivEXT\0"
    "\0"
-   /* _mesa_function_pool[22302]: PixelTransferf (offset 247) */
+   /* _mesa_function_pool[22555]: PixelTransferf (offset 247) */
    "if\0"
    "glPixelTransferf\0"
    "\0"
-   /* _mesa_function_pool[22323]: CopyTexImage1D (offset 323) */
+   /* _mesa_function_pool[22576]: CopyTexImage1D (offset 323) */
    "iiiiiii\0"
    "glCopyTexImage1D\0"
    "glCopyTexImage1DEXT\0"
    "\0"
-   /* _mesa_function_pool[22369]: PushMatrix (offset 298) */
+   /* _mesa_function_pool[22622]: PushMatrix (offset 298) */
    "\0"
    "glPushMatrix\0"
    "\0"
-   /* _mesa_function_pool[22384]: Fogiv (offset 156) */
+   /* _mesa_function_pool[22637]: Fogiv (offset 156) */
    "ip\0"
    "glFogiv\0"
    "\0"
-   /* _mesa_function_pool[22396]: TexCoord1dv (offset 95) */
+   /* _mesa_function_pool[22649]: TexCoord1dv (offset 95) */
    "p\0"
    "glTexCoord1dv\0"
    "\0"
-   /* _mesa_function_pool[22413]: AlphaFragmentOp3ATI (will be remapped) */
+   /* _mesa_function_pool[22666]: AlphaFragmentOp3ATI (will be remapped) */
    "iiiiiiiiiiii\0"
    "glAlphaFragmentOp3ATI\0"
    "\0"
-   /* _mesa_function_pool[22449]: PixelTransferi (offset 248) */
+   /* _mesa_function_pool[22702]: PixelTransferi (offset 248) */
    "ii\0"
    "glPixelTransferi\0"
    "\0"
-   /* _mesa_function_pool[22470]: GetVertexAttribdvNV (will be remapped) */
+   /* _mesa_function_pool[22723]: GetVertexAttribdvNV (will be remapped) */
    "iip\0"
    "glGetVertexAttribdvNV\0"
    "\0"
-   /* _mesa_function_pool[22497]: VertexAttrib3fvNV (will be remapped) */
+   /* _mesa_function_pool[22750]: VertexAttrib3fvNV (will be remapped) */
    "ip\0"
    "glVertexAttrib3fvNV\0"
    "\0"
-   /* _mesa_function_pool[22521]: Rotatef (offset 300) */
+   /* _mesa_function_pool[22774]: Rotatef (offset 300) */
    "ffff\0"
    "glRotatef\0"
    "\0"
-   /* _mesa_function_pool[22537]: GetFinalCombinerInputParameterivNV (will be remapped) */
+   /* _mesa_function_pool[22790]: GetFinalCombinerInputParameterivNV (will be remapped) */
    "iip\0"
    "glGetFinalCombinerInputParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[22579]: Vertex3i (offset 138) */
+   /* _mesa_function_pool[22832]: Vertex3i (offset 138) */
    "iii\0"
    "glVertex3i\0"
    "\0"
-   /* _mesa_function_pool[22595]: Vertex3f (offset 136) */
+   /* _mesa_function_pool[22848]: Vertex3f (offset 136) */
    "fff\0"
    "glVertex3f\0"
    "\0"
-   /* _mesa_function_pool[22611]: Clear (offset 203) */
+   /* _mesa_function_pool[22864]: Clear (offset 203) */
    "i\0"
    "glClear\0"
    "\0"
-   /* _mesa_function_pool[22622]: Vertex3d (offset 134) */
+   /* _mesa_function_pool[22875]: Vertex3d (offset 134) */
    "ddd\0"
    "glVertex3d\0"
    "\0"
-   /* _mesa_function_pool[22638]: GetMapParameterivNV (dynamic) */
+   /* _mesa_function_pool[22891]: GetMapParameterivNV (dynamic) */
    "iip\0"
    "glGetMapParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[22665]: Uniform4iARB (will be remapped) */
+   /* _mesa_function_pool[22918]: Uniform4iARB (will be remapped) */
    "iiiii\0"
    "glUniform4i\0"
    "glUniform4iARB\0"
    "\0"
-   /* _mesa_function_pool[22699]: ReadBuffer (offset 254) */
+   /* _mesa_function_pool[22952]: ReadBuffer (offset 254) */
    "i\0"
    "glReadBuffer\0"
    "\0"
-   /* _mesa_function_pool[22715]: ConvolutionParameteri (offset 352) */
+   /* _mesa_function_pool[22968]: ConvolutionParameteri (offset 352) */
    "iii\0"
    "glConvolutionParameteri\0"
    "glConvolutionParameteriEXT\0"
    "\0"
-   /* _mesa_function_pool[22771]: Ortho (offset 296) */
+   /* _mesa_function_pool[23024]: Ortho (offset 296) */
    "dddddd\0"
    "glOrtho\0"
    "\0"
-   /* _mesa_function_pool[22787]: Binormal3sEXT (dynamic) */
+   /* _mesa_function_pool[23040]: Binormal3sEXT (dynamic) */
    "iii\0"
    "glBinormal3sEXT\0"
    "\0"
-   /* _mesa_function_pool[22808]: ListBase (offset 6) */
+   /* _mesa_function_pool[23061]: ListBase (offset 6) */
    "i\0"
    "glListBase\0"
    "\0"
-   /* _mesa_function_pool[22822]: Vertex3s (offset 140) */
+   /* _mesa_function_pool[23075]: Vertex3s (offset 140) */
    "iii\0"
    "glVertex3s\0"
    "\0"
-   /* _mesa_function_pool[22838]: ConvolutionParameterf (offset 350) */
+   /* _mesa_function_pool[23091]: ConvolutionParameterf (offset 350) */
    "iif\0"
    "glConvolutionParameterf\0"
    "glConvolutionParameterfEXT\0"
    "\0"
-   /* _mesa_function_pool[22894]: GetColorTableParameteriv (offset 345) */
+   /* _mesa_function_pool[23147]: GetColorTableParameteriv (offset 345) */
    "iip\0"
    "glGetColorTableParameteriv\0"
    "glGetColorTableParameterivSGI\0"
    "glGetColorTableParameterivEXT\0"
    "\0"
-   /* _mesa_function_pool[22986]: ProgramEnvParameter4dvARB (will be remapped) */
+   /* _mesa_function_pool[23239]: ProgramEnvParameter4dvARB (will be remapped) */
    "iip\0"
    "glProgramEnvParameter4dvARB\0"
    "glProgramParameter4dvNV\0"
    "\0"
-   /* _mesa_function_pool[23043]: ShadeModel (offset 177) */
+   /* _mesa_function_pool[23296]: ShadeModel (offset 177) */
    "i\0"
    "glShadeModel\0"
    "\0"
-   /* _mesa_function_pool[23059]: VertexAttribs2fvNV (will be remapped) */
+   /* _mesa_function_pool[23312]: VertexAttribs2fvNV (will be remapped) */
    "iip\0"
    "glVertexAttribs2fvNV\0"
    "\0"
-   /* _mesa_function_pool[23085]: Rectiv (offset 91) */
+   /* _mesa_function_pool[23338]: Rectiv (offset 91) */
    "pp\0"
    "glRectiv\0"
    "\0"
-   /* _mesa_function_pool[23098]: UseProgramObjectARB (will be remapped) */
+   /* _mesa_function_pool[23351]: UseProgramObjectARB (will be remapped) */
    "i\0"
    "glUseProgram\0"
    "glUseProgramObjectARB\0"
    "\0"
-   /* _mesa_function_pool[23136]: GetMapParameterfvNV (dynamic) */
+   /* _mesa_function_pool[23389]: GetMapParameterfvNV (dynamic) */
    "iip\0"
    "glGetMapParameterfvNV\0"
    "\0"
-   /* _mesa_function_pool[23163]: EndConditionalRenderNV (will be remapped) */
+   /* _mesa_function_pool[23416]: EndConditionalRenderNV (will be remapped) */
    "\0"
    "glEndConditionalRenderNV\0"
    "\0"
-   /* _mesa_function_pool[23190]: PassTexCoordATI (will be remapped) */
+   /* _mesa_function_pool[23443]: PassTexCoordATI (will be remapped) */
    "iii\0"
    "glPassTexCoordATI\0"
    "\0"
-   /* _mesa_function_pool[23213]: DeleteProgram (will be remapped) */
+   /* _mesa_function_pool[23466]: DeleteProgram (will be remapped) */
    "i\0"
    "glDeleteProgram\0"
    "\0"
-   /* _mesa_function_pool[23232]: Tangent3ivEXT (dynamic) */
+   /* _mesa_function_pool[23485]: Tangent3ivEXT (dynamic) */
    "p\0"
    "glTangent3ivEXT\0"
    "\0"
-   /* _mesa_function_pool[23251]: Tangent3dEXT (dynamic) */
+   /* _mesa_function_pool[23504]: Tangent3dEXT (dynamic) */
    "ddd\0"
    "glTangent3dEXT\0"
    "\0"
-   /* _mesa_function_pool[23271]: SecondaryColor3dvEXT (will be remapped) */
+   /* _mesa_function_pool[23524]: SecondaryColor3dvEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3dv\0"
    "glSecondaryColor3dvEXT\0"
    "\0"
-   /* _mesa_function_pool[23317]: Vertex2fv (offset 129) */
+   /* _mesa_function_pool[23570]: Vertex2fv (offset 129) */
    "p\0"
    "glVertex2fv\0"
    "\0"
-   /* _mesa_function_pool[23332]: MultiDrawArraysEXT (will be remapped) */
+   /* _mesa_function_pool[23585]: MultiDrawArraysEXT (will be remapped) */
    "ippi\0"
    "glMultiDrawArrays\0"
    "glMultiDrawArraysEXT\0"
    "\0"
-   /* _mesa_function_pool[23377]: BindRenderbufferEXT (will be remapped) */
+   /* _mesa_function_pool[23630]: BindRenderbufferEXT (will be remapped) */
    "ii\0"
    "glBindRenderbuffer\0"
    "glBindRenderbufferEXT\0"
    "\0"
-   /* _mesa_function_pool[23422]: MultiTexCoord4dARB (offset 400) */
+   /* _mesa_function_pool[23675]: MultiTexCoord4dARB (offset 400) */
    "idddd\0"
    "glMultiTexCoord4d\0"
    "glMultiTexCoord4dARB\0"
    "\0"
-   /* _mesa_function_pool[23468]: Vertex3sv (offset 141) */
+   /* _mesa_function_pool[23721]: FramebufferTextureFaceARB (will be remapped) */
+   "iiiii\0"
+   "glFramebufferTextureFaceARB\0"
+   "\0"
+   /* _mesa_function_pool[23756]: Vertex3sv (offset 141) */
    "p\0"
    "glVertex3sv\0"
    "\0"
-   /* _mesa_function_pool[23483]: SecondaryColor3usEXT (will be remapped) */
+   /* _mesa_function_pool[23771]: SecondaryColor3usEXT (will be remapped) */
    "iii\0"
    "glSecondaryColor3us\0"
    "glSecondaryColor3usEXT\0"
    "\0"
-   /* _mesa_function_pool[23531]: ProgramLocalParameter4fvARB (will be remapped) */
+   /* _mesa_function_pool[23819]: ProgramLocalParameter4fvARB (will be remapped) */
    "iip\0"
    "glProgramLocalParameter4fvARB\0"
    "\0"
-   /* _mesa_function_pool[23566]: DeleteProgramsNV (will be remapped) */
+   /* _mesa_function_pool[23854]: DeleteProgramsNV (will be remapped) */
    "ip\0"
    "glDeleteProgramsARB\0"
    "glDeleteProgramsNV\0"
    "\0"
-   /* _mesa_function_pool[23609]: EvalMesh1 (offset 236) */
+   /* _mesa_function_pool[23897]: EvalMesh1 (offset 236) */
    "iii\0"
    "glEvalMesh1\0"
    "\0"
-   /* _mesa_function_pool[23626]: MultiTexCoord1sARB (offset 382) */
+   /* _mesa_function_pool[23914]: PauseTransformFeedback (will be remapped) */
+   "\0"
+   "glPauseTransformFeedback\0"
+   "\0"
+   /* _mesa_function_pool[23941]: MultiTexCoord1sARB (offset 382) */
    "ii\0"
    "glMultiTexCoord1s\0"
    "glMultiTexCoord1sARB\0"
    "\0"
-   /* _mesa_function_pool[23669]: ReplacementCodeuiColor3fVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[23984]: ReplacementCodeuiColor3fVertex3fSUN (dynamic) */
    "iffffff\0"
    "glReplacementCodeuiColor3fVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[23716]: GetVertexAttribPointervNV (will be remapped) */
+   /* _mesa_function_pool[24031]: GetVertexAttribPointervNV (will be remapped) */
    "iip\0"
    "glGetVertexAttribPointerv\0"
    "glGetVertexAttribPointervARB\0"
    "glGetVertexAttribPointervNV\0"
    "\0"
-   /* _mesa_function_pool[23804]: VertexAttribs1fvNV (will be remapped) */
+   /* _mesa_function_pool[24119]: VertexAttribs1fvNV (will be remapped) */
    "iip\0"
    "glVertexAttribs1fvNV\0"
    "\0"
-   /* _mesa_function_pool[23830]: MultiTexCoord1dvARB (offset 377) */
+   /* _mesa_function_pool[24145]: MultiTexCoord1dvARB (offset 377) */
    "ip\0"
    "glMultiTexCoord1dv\0"
    "glMultiTexCoord1dvARB\0"
    "\0"
-   /* _mesa_function_pool[23875]: Uniform2iARB (will be remapped) */
+   /* _mesa_function_pool[24190]: Uniform2iARB (will be remapped) */
    "iii\0"
    "glUniform2i\0"
    "glUniform2iARB\0"
    "\0"
-   /* _mesa_function_pool[23907]: Vertex2iv (offset 131) */
+   /* _mesa_function_pool[24222]: Vertex2iv (offset 131) */
    "p\0"
    "glVertex2iv\0"
    "\0"
-   /* _mesa_function_pool[23922]: GetProgramStringNV (will be remapped) */
+   /* _mesa_function_pool[24237]: GetProgramStringNV (will be remapped) */
    "iip\0"
    "glGetProgramStringNV\0"
    "\0"
-   /* _mesa_function_pool[23948]: ColorPointerEXT (will be remapped) */
+   /* _mesa_function_pool[24263]: ColorPointerEXT (will be remapped) */
    "iiiip\0"
    "glColorPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[23973]: LineWidth (offset 168) */
+   /* _mesa_function_pool[24288]: LineWidth (offset 168) */
    "f\0"
    "glLineWidth\0"
    "\0"
-   /* _mesa_function_pool[23988]: MapBufferARB (will be remapped) */
+   /* _mesa_function_pool[24303]: MapBufferARB (will be remapped) */
    "ii\0"
    "glMapBuffer\0"
    "glMapBufferARB\0"
    "\0"
-   /* _mesa_function_pool[24019]: MultiDrawElementsBaseVertex (will be remapped) */
+   /* _mesa_function_pool[24334]: MultiDrawElementsBaseVertex (will be remapped) */
    "ipipip\0"
    "glMultiDrawElementsBaseVertex\0"
    "\0"
-   /* _mesa_function_pool[24057]: Binormal3svEXT (dynamic) */
+   /* _mesa_function_pool[24372]: Binormal3svEXT (dynamic) */
    "p\0"
    "glBinormal3svEXT\0"
    "\0"
-   /* _mesa_function_pool[24077]: ApplyTextureEXT (dynamic) */
+   /* _mesa_function_pool[24392]: ApplyTextureEXT (dynamic) */
    "i\0"
    "glApplyTextureEXT\0"
    "\0"
-   /* _mesa_function_pool[24098]: TexGendv (offset 189) */
+   /* _mesa_function_pool[24413]: TexGendv (offset 189) */
    "iip\0"
    "glTexGendv\0"
    "\0"
-   /* _mesa_function_pool[24114]: EnableIndexedEXT (will be remapped) */
+   /* _mesa_function_pool[24429]: EnableIndexedEXT (will be remapped) */
    "ii\0"
    "glEnableIndexedEXT\0"
    "\0"
-   /* _mesa_function_pool[24137]: TextureMaterialEXT (dynamic) */
+   /* _mesa_function_pool[24452]: TextureMaterialEXT (dynamic) */
    "ii\0"
    "glTextureMaterialEXT\0"
    "\0"
-   /* _mesa_function_pool[24162]: TextureLightEXT (dynamic) */
+   /* _mesa_function_pool[24477]: TextureLightEXT (dynamic) */
    "i\0"
    "glTextureLightEXT\0"
    "\0"
-   /* _mesa_function_pool[24183]: ResetMinmax (offset 370) */
+   /* _mesa_function_pool[24498]: ResetMinmax (offset 370) */
    "i\0"
    "glResetMinmax\0"
    "glResetMinmaxEXT\0"
    "\0"
-   /* _mesa_function_pool[24217]: SpriteParameterfSGIX (dynamic) */
+   /* _mesa_function_pool[24532]: SpriteParameterfSGIX (dynamic) */
    "if\0"
    "glSpriteParameterfSGIX\0"
    "\0"
-   /* _mesa_function_pool[24244]: EnableClientState (offset 313) */
+   /* _mesa_function_pool[24559]: EnableClientState (offset 313) */
    "i\0"
    "glEnableClientState\0"
    "\0"
-   /* _mesa_function_pool[24267]: VertexAttrib4sNV (will be remapped) */
+   /* _mesa_function_pool[24582]: VertexAttrib4sNV (will be remapped) */
    "iiiii\0"
    "glVertexAttrib4sNV\0"
    "\0"
-   /* _mesa_function_pool[24293]: GetConvolutionParameterfv (offset 357) */
+   /* _mesa_function_pool[24608]: GetConvolutionParameterfv (offset 357) */
    "iip\0"
    "glGetConvolutionParameterfv\0"
    "glGetConvolutionParameterfvEXT\0"
    "\0"
-   /* _mesa_function_pool[24357]: VertexAttribs4dvNV (will be remapped) */
+   /* _mesa_function_pool[24672]: VertexAttribs4dvNV (will be remapped) */
    "iip\0"
    "glVertexAttribs4dvNV\0"
    "\0"
-   /* _mesa_function_pool[24383]: MultiModeDrawArraysIBM (will be remapped) */
-   "pppii\0"
-   "glMultiModeDrawArraysIBM\0"
-   "\0"
-   /* _mesa_function_pool[24415]: VertexAttrib4dARB (will be remapped) */
+   /* _mesa_function_pool[24698]: VertexAttrib4dARB (will be remapped) */
    "idddd\0"
    "glVertexAttrib4d\0"
    "glVertexAttrib4dARB\0"
    "\0"
-   /* _mesa_function_pool[24459]: GetTexBumpParameterfvATI (will be remapped) */
+   /* _mesa_function_pool[24742]: GetTexBumpParameterfvATI (will be remapped) */
    "ip\0"
    "glGetTexBumpParameterfvATI\0"
    "\0"
-   /* _mesa_function_pool[24490]: ProgramNamedParameter4dNV (will be remapped) */
+   /* _mesa_function_pool[24773]: ProgramNamedParameter4dNV (will be remapped) */
    "iipdddd\0"
    "glProgramNamedParameter4dNV\0"
    "\0"
-   /* _mesa_function_pool[24527]: GetMaterialfv (offset 269) */
+   /* _mesa_function_pool[24810]: GetMaterialfv (offset 269) */
    "iip\0"
    "glGetMaterialfv\0"
    "\0"
-   /* _mesa_function_pool[24548]: VertexWeightfEXT (dynamic) */
+   /* _mesa_function_pool[24831]: VertexWeightfEXT (dynamic) */
    "f\0"
    "glVertexWeightfEXT\0"
    "\0"
-   /* _mesa_function_pool[24570]: Binormal3fEXT (dynamic) */
+   /* _mesa_function_pool[24853]: Binormal3fEXT (dynamic) */
    "fff\0"
    "glBinormal3fEXT\0"
    "\0"
-   /* _mesa_function_pool[24591]: CallList (offset 2) */
+   /* _mesa_function_pool[24874]: CallList (offset 2) */
    "i\0"
    "glCallList\0"
    "\0"
-   /* _mesa_function_pool[24605]: Materialfv (offset 170) */
+   /* _mesa_function_pool[24888]: Materialfv (offset 170) */
    "iip\0"
    "glMaterialfv\0"
    "\0"
-   /* _mesa_function_pool[24623]: TexCoord3fv (offset 113) */
+   /* _mesa_function_pool[24906]: TexCoord3fv (offset 113) */
    "p\0"
    "glTexCoord3fv\0"
    "\0"
-   /* _mesa_function_pool[24640]: FogCoordfvEXT (will be remapped) */
+   /* _mesa_function_pool[24923]: FogCoordfvEXT (will be remapped) */
    "p\0"
    "glFogCoordfv\0"
    "glFogCoordfvEXT\0"
    "\0"
-   /* _mesa_function_pool[24672]: MultiTexCoord1ivARB (offset 381) */
+   /* _mesa_function_pool[24955]: MultiTexCoord1ivARB (offset 381) */
    "ip\0"
    "glMultiTexCoord1iv\0"
    "glMultiTexCoord1ivARB\0"
    "\0"
-   /* _mesa_function_pool[24717]: SecondaryColor3ubEXT (will be remapped) */
+   /* _mesa_function_pool[25000]: SecondaryColor3ubEXT (will be remapped) */
    "iii\0"
    "glSecondaryColor3ub\0"
    "glSecondaryColor3ubEXT\0"
    "\0"
-   /* _mesa_function_pool[24765]: MultiTexCoord2ivARB (offset 389) */
+   /* _mesa_function_pool[25048]: MultiTexCoord2ivARB (offset 389) */
    "ip\0"
    "glMultiTexCoord2iv\0"
    "glMultiTexCoord2ivARB\0"
    "\0"
-   /* _mesa_function_pool[24810]: FogFuncSGIS (dynamic) */
+   /* _mesa_function_pool[25093]: FogFuncSGIS (dynamic) */
    "ip\0"
    "glFogFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[24828]: CopyTexSubImage2D (offset 326) */
+   /* _mesa_function_pool[25111]: CopyTexSubImage2D (offset 326) */
    "iiiiiiii\0"
    "glCopyTexSubImage2D\0"
    "glCopyTexSubImage2DEXT\0"
    "\0"
-   /* _mesa_function_pool[24881]: GetObjectParameterivARB (will be remapped) */
+   /* _mesa_function_pool[25164]: GetObjectParameterivARB (will be remapped) */
    "iip\0"
    "glGetObjectParameterivARB\0"
    "\0"
-   /* _mesa_function_pool[24912]: Color3iv (offset 16) */
+   /* _mesa_function_pool[25195]: Color3iv (offset 16) */
    "p\0"
    "glColor3iv\0"
    "\0"
-   /* _mesa_function_pool[24926]: TexCoord4fVertex4fSUN (dynamic) */
+   /* _mesa_function_pool[25209]: TexCoord4fVertex4fSUN (dynamic) */
    "ffffffff\0"
    "glTexCoord4fVertex4fSUN\0"
    "\0"
-   /* _mesa_function_pool[24960]: DrawElements (offset 311) */
+   /* _mesa_function_pool[25243]: DrawElements (offset 311) */
    "iiip\0"
    "glDrawElements\0"
    "\0"
-   /* _mesa_function_pool[24981]: BindVertexArrayAPPLE (will be remapped) */
+   /* _mesa_function_pool[25264]: BindVertexArrayAPPLE (will be remapped) */
    "i\0"
    "glBindVertexArrayAPPLE\0"
    "\0"
-   /* _mesa_function_pool[25007]: GetProgramLocalParameterdvARB (will be remapped) */
+   /* _mesa_function_pool[25290]: GetProgramLocalParameterdvARB (will be remapped) */
    "iip\0"
    "glGetProgramLocalParameterdvARB\0"
    "\0"
-   /* _mesa_function_pool[25044]: GetHistogramParameteriv (offset 363) */
+   /* _mesa_function_pool[25327]: GetHistogramParameteriv (offset 363) */
    "iip\0"
    "glGetHistogramParameteriv\0"
    "glGetHistogramParameterivEXT\0"
    "\0"
-   /* _mesa_function_pool[25104]: MultiTexCoord1iARB (offset 380) */
+   /* _mesa_function_pool[25387]: MultiTexCoord1iARB (offset 380) */
    "ii\0"
    "glMultiTexCoord1i\0"
    "glMultiTexCoord1iARB\0"
    "\0"
-   /* _mesa_function_pool[25147]: GetConvolutionFilter (offset 356) */
+   /* _mesa_function_pool[25430]: GetConvolutionFilter (offset 356) */
    "iiip\0"
    "glGetConvolutionFilter\0"
    "glGetConvolutionFilterEXT\0"
    "\0"
-   /* _mesa_function_pool[25202]: GetProgramivARB (will be remapped) */
+   /* _mesa_function_pool[25485]: GetProgramivARB (will be remapped) */
    "iip\0"
    "glGetProgramivARB\0"
    "\0"
-   /* _mesa_function_pool[25225]: BlendFuncSeparateEXT (will be remapped) */
+   /* _mesa_function_pool[25508]: BlendFuncSeparateEXT (will be remapped) */
    "iiii\0"
    "glBlendFuncSeparate\0"
    "glBlendFuncSeparateEXT\0"
    "glBlendFuncSeparateINGR\0"
    "\0"
-   /* _mesa_function_pool[25298]: MapBufferRange (will be remapped) */
+   /* _mesa_function_pool[25581]: MapBufferRange (will be remapped) */
    "iiii\0"
    "glMapBufferRange\0"
    "\0"
-   /* _mesa_function_pool[25321]: ProgramParameters4dvNV (will be remapped) */
+   /* _mesa_function_pool[25604]: ProgramParameters4dvNV (will be remapped) */
    "iiip\0"
    "glProgramParameters4dvNV\0"
    "\0"
-   /* _mesa_function_pool[25352]: TexCoord2fColor3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[25635]: TexCoord2fColor3fVertex3fvSUN (dynamic) */
    "ppp\0"
    "glTexCoord2fColor3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[25389]: EvalPoint2 (offset 239) */
+   /* _mesa_function_pool[25672]: EvalPoint2 (offset 239) */
    "ii\0"
    "glEvalPoint2\0"
    "\0"
-   /* _mesa_function_pool[25406]: EvalPoint1 (offset 237) */
+   /* _mesa_function_pool[25689]: EvalPoint1 (offset 237) */
    "i\0"
    "glEvalPoint1\0"
    "\0"
-   /* _mesa_function_pool[25422]: Binormal3dvEXT (dynamic) */
+   /* _mesa_function_pool[25705]: Binormal3dvEXT (dynamic) */
    "p\0"
    "glBinormal3dvEXT\0"
    "\0"
-   /* _mesa_function_pool[25442]: PopMatrix (offset 297) */
+   /* _mesa_function_pool[25725]: PopMatrix (offset 297) */
    "\0"
    "glPopMatrix\0"
    "\0"
-   /* _mesa_function_pool[25456]: FinishFenceNV (will be remapped) */
+   /* _mesa_function_pool[25739]: FinishFenceNV (will be remapped) */
    "i\0"
    "glFinishFenceNV\0"
    "\0"
-   /* _mesa_function_pool[25475]: GetFogFuncSGIS (dynamic) */
+   /* _mesa_function_pool[25758]: GetFogFuncSGIS (dynamic) */
    "p\0"
    "glGetFogFuncSGIS\0"
    "\0"
-   /* _mesa_function_pool[25495]: GetUniformLocationARB (will be remapped) */
+   /* _mesa_function_pool[25778]: GetUniformLocationARB (will be remapped) */
    "ip\0"
    "glGetUniformLocation\0"
    "glGetUniformLocationARB\0"
    "\0"
-   /* _mesa_function_pool[25544]: SecondaryColor3fEXT (will be remapped) */
+   /* _mesa_function_pool[25827]: SecondaryColor3fEXT (will be remapped) */
    "fff\0"
    "glSecondaryColor3f\0"
    "glSecondaryColor3fEXT\0"
    "\0"
-   /* _mesa_function_pool[25590]: GetTexGeniv (offset 280) */
+   /* _mesa_function_pool[25873]: GetTexGeniv (offset 280) */
    "iip\0"
    "glGetTexGeniv\0"
    "\0"
-   /* _mesa_function_pool[25609]: CombinerInputNV (will be remapped) */
+   /* _mesa_function_pool[25892]: CombinerInputNV (will be remapped) */
    "iiiiii\0"
    "glCombinerInputNV\0"
    "\0"
-   /* _mesa_function_pool[25635]: VertexAttrib3sARB (will be remapped) */
+   /* _mesa_function_pool[25918]: VertexAttrib3sARB (will be remapped) */
    "iiii\0"
    "glVertexAttrib3s\0"
    "glVertexAttrib3sARB\0"
    "\0"
-   /* _mesa_function_pool[25678]: ColorMaskIndexedEXT (will be remapped) */
-   "iiiii\0"
-   "glColorMaskIndexedEXT\0"
+   /* _mesa_function_pool[25961]: IsTransformFeedback (will be remapped) */
+   "i\0"
+   "glIsTransformFeedback\0"
    "\0"
-   /* _mesa_function_pool[25707]: ReplacementCodeuiNormal3fVertex3fvSUN (dynamic) */
+   /* _mesa_function_pool[25986]: ReplacementCodeuiNormal3fVertex3fvSUN (dynamic) */
    "ppp\0"
    "glReplacementCodeuiNormal3fVertex3fvSUN\0"
    "\0"
-   /* _mesa_function_pool[25752]: Map2d (offset 222) */
+   /* _mesa_function_pool[26031]: Map2d (offset 222) */
    "iddiiddiip\0"
    "glMap2d\0"
    "\0"
-   /* _mesa_function_pool[25772]: Map2f (offset 223) */
+   /* _mesa_function_pool[26051]: Map2f (offset 223) */
    "iffiiffiip\0"
    "glMap2f\0"
    "\0"
-   /* _mesa_function_pool[25792]: ProgramStringARB (will be remapped) */
+   /* _mesa_function_pool[26071]: ProgramStringARB (will be remapped) */
    "iiip\0"
    "glProgramStringARB\0"
    "\0"
-   /* _mesa_function_pool[25817]: Vertex4s (offset 148) */
+   /* _mesa_function_pool[26096]: Vertex4s (offset 148) */
    "iiii\0"
    "glVertex4s\0"
    "\0"
-   /* _mesa_function_pool[25834]: TexCoord4fVertex4fvSUN (dynamic) */
+   /* _mesa_function_pool[26113]: TexCoord4fVertex4fvSUN (dynamic) */
    "pp\0"
    "glTexCoord4fVertex4fvSUN\0"
    "\0"
-   /* _mesa_function_pool[25863]: VertexAttrib3sNV (will be remapped) */
-   "iiii\0"
-   "glVertexAttrib3sNV\0"
+   /* _mesa_function_pool[26142]: FragmentLightModelivSGIX (dynamic) */
+   "ip\0"
+   "glFragmentLightModelivSGIX\0"
    "\0"
-   /* _mesa_function_pool[25888]: VertexAttrib1fNV (will be remapped) */
+   /* _mesa_function_pool[26173]: VertexAttrib1fNV (will be remapped) */
    "if\0"
    "glVertexAttrib1fNV\0"
    "\0"
-   /* _mesa_function_pool[25911]: Vertex4f (offset 144) */
+   /* _mesa_function_pool[26196]: Vertex4f (offset 144) */
    "ffff\0"
    "glVertex4f\0"
    "\0"
-   /* _mesa_function_pool[25928]: EvalCoord1d (offset 228) */
+   /* _mesa_function_pool[26213]: EvalCoord1d (offset 228) */
    "d\0"
    "glEvalCoord1d\0"
    "\0"
-   /* _mesa_function_pool[25945]: Vertex4d (offset 142) */
+   /* _mesa_function_pool[26230]: Vertex4d (offset 142) */
    "dddd\0"
    "glVertex4d\0"
    "\0"
-   /* _mesa_function_pool[25962]: RasterPos4dv (offset 79) */
+   /* _mesa_function_pool[26247]: RasterPos4dv (offset 79) */
    "p\0"
    "glRasterPos4dv\0"
    "\0"
-   /* _mesa_function_pool[25980]: FragmentLightfSGIX (dynamic) */
+   /* _mesa_function_pool[26265]: FragmentLightfSGIX (dynamic) */
    "iif\0"
    "glFragmentLightfSGIX\0"
    "\0"
-   /* _mesa_function_pool[26006]: GetCompressedTexImageARB (will be remapped) */
+   /* _mesa_function_pool[26291]: GetCompressedTexImageARB (will be remapped) */
    "iip\0"
    "glGetCompressedTexImage\0"
    "glGetCompressedTexImageARB\0"
    "\0"
-   /* _mesa_function_pool[26062]: GetTexGenfv (offset 279) */
+   /* _mesa_function_pool[26347]: GetTexGenfv (offset 279) */
    "iip\0"
    "glGetTexGenfv\0"
    "\0"
-   /* _mesa_function_pool[26081]: Vertex4i (offset 146) */
+   /* _mesa_function_pool[26366]: Vertex4i (offset 146) */
    "iiii\0"
    "glVertex4i\0"
    "\0"
-   /* _mesa_function_pool[26098]: VertexWeightPointerEXT (dynamic) */
+   /* _mesa_function_pool[26383]: VertexWeightPointerEXT (dynamic) */
    "iiip\0"
    "glVertexWeightPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[26129]: GetHistogram (offset 361) */
+   /* _mesa_function_pool[26414]: GetHistogram (offset 361) */
    "iiiip\0"
    "glGetHistogram\0"
    "glGetHistogramEXT\0"
    "\0"
-   /* _mesa_function_pool[26169]: ActiveStencilFaceEXT (will be remapped) */
+   /* _mesa_function_pool[26454]: ActiveStencilFaceEXT (will be remapped) */
    "i\0"
    "glActiveStencilFaceEXT\0"
    "\0"
-   /* _mesa_function_pool[26195]: StencilFuncSeparateATI (will be remapped) */
+   /* _mesa_function_pool[26480]: StencilFuncSeparateATI (will be remapped) */
    "iiii\0"
    "glStencilFuncSeparateATI\0"
    "\0"
-   /* _mesa_function_pool[26226]: Materialf (offset 169) */
+   /* _mesa_function_pool[26511]: Materialf (offset 169) */
    "iif\0"
    "glMaterialf\0"
    "\0"
-   /* _mesa_function_pool[26243]: GetShaderSourceARB (will be remapped) */
+   /* _mesa_function_pool[26528]: GetShaderSourceARB (will be remapped) */
    "iipp\0"
    "glGetShaderSource\0"
    "glGetShaderSourceARB\0"
    "\0"
-   /* _mesa_function_pool[26288]: IglooInterfaceSGIX (dynamic) */
+   /* _mesa_function_pool[26573]: IglooInterfaceSGIX (dynamic) */
    "ip\0"
    "glIglooInterfaceSGIX\0"
    "\0"
-   /* _mesa_function_pool[26313]: Materiali (offset 171) */
+   /* _mesa_function_pool[26598]: Materiali (offset 171) */
    "iii\0"
    "glMateriali\0"
    "\0"
-   /* _mesa_function_pool[26330]: VertexAttrib4dNV (will be remapped) */
+   /* _mesa_function_pool[26615]: VertexAttrib4dNV (will be remapped) */
    "idddd\0"
    "glVertexAttrib4dNV\0"
    "\0"
-   /* _mesa_function_pool[26356]: MultiModeDrawElementsIBM (will be remapped) */
+   /* _mesa_function_pool[26641]: MultiModeDrawElementsIBM (will be remapped) */
    "ppipii\0"
    "glMultiModeDrawElementsIBM\0"
    "\0"
-   /* _mesa_function_pool[26391]: Indexsv (offset 51) */
+   /* _mesa_function_pool[26676]: Indexsv (offset 51) */
    "p\0"
    "glIndexsv\0"
    "\0"
-   /* _mesa_function_pool[26404]: MultiTexCoord4svARB (offset 407) */
+   /* _mesa_function_pool[26689]: MultiTexCoord4svARB (offset 407) */
    "ip\0"
    "glMultiTexCoord4sv\0"
    "glMultiTexCoord4svARB\0"
    "\0"
-   /* _mesa_function_pool[26449]: LightModelfv (offset 164) */
+   /* _mesa_function_pool[26734]: LightModelfv (offset 164) */
    "ip\0"
    "glLightModelfv\0"
    "\0"
-   /* _mesa_function_pool[26468]: TexCoord2dv (offset 103) */
+   /* _mesa_function_pool[26753]: TexCoord2dv (offset 103) */
    "p\0"
    "glTexCoord2dv\0"
    "\0"
-   /* _mesa_function_pool[26485]: GenQueriesARB (will be remapped) */
+   /* _mesa_function_pool[26770]: GenQueriesARB (will be remapped) */
    "ip\0"
    "glGenQueries\0"
    "glGenQueriesARB\0"
    "\0"
-   /* _mesa_function_pool[26518]: EvalCoord1dv (offset 229) */
+   /* _mesa_function_pool[26803]: EvalCoord1dv (offset 229) */
    "p\0"
    "glEvalCoord1dv\0"
    "\0"
-   /* _mesa_function_pool[26536]: ReplacementCodeuiVertex3fSUN (dynamic) */
+   /* _mesa_function_pool[26821]: ReplacementCodeuiVertex3fSUN (dynamic) */
    "ifff\0"
    "glReplacementCodeuiVertex3fSUN\0"
    "\0"
-   /* _mesa_function_pool[26573]: Translated (offset 303) */
+   /* _mesa_function_pool[26858]: Translated (offset 303) */
    "ddd\0"
    "glTranslated\0"
    "\0"
-   /* _mesa_function_pool[26591]: Translatef (offset 304) */
+   /* _mesa_function_pool[26876]: Translatef (offset 304) */
    "fff\0"
    "glTranslatef\0"
    "\0"
-   /* _mesa_function_pool[26609]: StencilMask (offset 209) */
+   /* _mesa_function_pool[26894]: StencilMask (offset 209) */
    "i\0"
    "glStencilMask\0"
    "\0"
-   /* _mesa_function_pool[26626]: Tangent3iEXT (dynamic) */
+   /* _mesa_function_pool[26911]: Tangent3iEXT (dynamic) */
    "iii\0"
    "glTangent3iEXT\0"
    "\0"
-   /* _mesa_function_pool[26646]: GetLightiv (offset 265) */
+   /* _mesa_function_pool[26931]: GetLightiv (offset 265) */
    "iip\0"
    "glGetLightiv\0"
    "\0"
-   /* _mesa_function_pool[26664]: DrawMeshArraysSUN (dynamic) */
+   /* _mesa_function_pool[26949]: DrawMeshArraysSUN (dynamic) */
    "iiii\0"
    "glDrawMeshArraysSUN\0"
    "\0"
-   /* _mesa_function_pool[26690]: IsList (offset 287) */
+   /* _mesa_function_pool[26975]: IsList (offset 287) */
    "i\0"
    "glIsList\0"
    "\0"
-   /* _mesa_function_pool[26702]: IsSync (will be remapped) */
+   /* _mesa_function_pool[26987]: IsSync (will be remapped) */
    "i\0"
    "glIsSync\0"
    "\0"
-   /* _mesa_function_pool[26714]: RenderMode (offset 196) */
+   /* _mesa_function_pool[26999]: RenderMode (offset 196) */
    "i\0"
    "glRenderMode\0"
    "\0"
-   /* _mesa_function_pool[26730]: GetMapControlPointsNV (dynamic) */
+   /* _mesa_function_pool[27015]: GetMapControlPointsNV (dynamic) */
    "iiiiiip\0"
    "glGetMapControlPointsNV\0"
    "\0"
-   /* _mesa_function_pool[26763]: DrawBuffersARB (will be remapped) */
+   /* _mesa_function_pool[27048]: DrawBuffersARB (will be remapped) */
    "ip\0"
    "glDrawBuffers\0"
    "glDrawBuffersARB\0"
    "glDrawBuffersATI\0"
    "\0"
-   /* _mesa_function_pool[26815]: ProgramLocalParameter4fARB (will be remapped) */
+   /* _mesa_function_pool[27100]: ProgramLocalParameter4fARB (will be remapped) */
    "iiffff\0"
    "glProgramLocalParameter4fARB\0"
    "\0"
-   /* _mesa_function_pool[26852]: SpriteParameterivSGIX (dynamic) */
+   /* _mesa_function_pool[27137]: SpriteParameterivSGIX (dynamic) */
    "ip\0"
    "glSpriteParameterivSGIX\0"
    "\0"
-   /* _mesa_function_pool[26880]: ProvokingVertexEXT (will be remapped) */
+   /* _mesa_function_pool[27165]: ProvokingVertexEXT (will be remapped) */
    "i\0"
    "glProvokingVertexEXT\0"
    "glProvokingVertex\0"
    "\0"
-   /* _mesa_function_pool[26922]: MultiTexCoord1fARB (offset 378) */
+   /* _mesa_function_pool[27207]: MultiTexCoord1fARB (offset 378) */
    "if\0"
    "glMultiTexCoord1f\0"
    "glMultiTexCoord1fARB\0"
    "\0"
-   /* _mesa_function_pool[26965]: LoadName (offset 198) */
+   /* _mesa_function_pool[27250]: LoadName (offset 198) */
    "i\0"
    "glLoadName\0"
    "\0"
-   /* _mesa_function_pool[26979]: VertexAttribs4ubvNV (will be remapped) */
+   /* _mesa_function_pool[27264]: VertexAttribs4ubvNV (will be remapped) */
    "iip\0"
    "glVertexAttribs4ubvNV\0"
    "\0"
-   /* _mesa_function_pool[27006]: WeightsvARB (dynamic) */
+   /* _mesa_function_pool[27291]: WeightsvARB (dynamic) */
    "ip\0"
    "glWeightsvARB\0"
    "\0"
-   /* _mesa_function_pool[27024]: Uniform1fvARB (will be remapped) */
+   /* _mesa_function_pool[27309]: Uniform1fvARB (will be remapped) */
    "iip\0"
    "glUniform1fv\0"
    "glUniform1fvARB\0"
    "\0"
-   /* _mesa_function_pool[27058]: CopyTexSubImage1D (offset 325) */
+   /* _mesa_function_pool[27343]: CopyTexSubImage1D (offset 325) */
    "iiiiii\0"
    "glCopyTexSubImage1D\0"
    "glCopyTexSubImage1DEXT\0"
    "\0"
-   /* _mesa_function_pool[27109]: CullFace (offset 152) */
+   /* _mesa_function_pool[27394]: CullFace (offset 152) */
    "i\0"
    "glCullFace\0"
    "\0"
-   /* _mesa_function_pool[27123]: BindTexture (offset 307) */
+   /* _mesa_function_pool[27408]: BindTexture (offset 307) */
    "ii\0"
    "glBindTexture\0"
    "glBindTextureEXT\0"
    "\0"
-   /* _mesa_function_pool[27158]: BeginFragmentShaderATI (will be remapped) */
+   /* _mesa_function_pool[27443]: BeginFragmentShaderATI (will be remapped) */
    "\0"
    "glBeginFragmentShaderATI\0"
    "\0"
-   /* _mesa_function_pool[27185]: MultiTexCoord4fARB (offset 402) */
+   /* _mesa_function_pool[27470]: MultiTexCoord4fARB (offset 402) */
    "iffff\0"
    "glMultiTexCoord4f\0"
    "glMultiTexCoord4fARB\0"
    "\0"
-   /* _mesa_function_pool[27231]: VertexAttribs3svNV (will be remapped) */
+   /* _mesa_function_pool[27516]: VertexAttribs3svNV (will be remapped) */
    "iip\0"
    "glVertexAttribs3svNV\0"
    "\0"
-   /* _mesa_function_pool[27257]: StencilFunc (offset 243) */
+   /* _mesa_function_pool[27542]: StencilFunc (offset 243) */
    "iii\0"
    "glStencilFunc\0"
    "\0"
-   /* _mesa_function_pool[27276]: CopyPixels (offset 255) */
+   /* _mesa_function_pool[27561]: CopyPixels (offset 255) */
    "iiiii\0"
    "glCopyPixels\0"
    "\0"
-   /* _mesa_function_pool[27296]: Rectsv (offset 93) */
+   /* _mesa_function_pool[27581]: Rectsv (offset 93) */
    "pp\0"
    "glRectsv\0"
    "\0"
-   /* _mesa_function_pool[27309]: ReplacementCodeuivSUN (dynamic) */
+   /* _mesa_function_pool[27594]: ReplacementCodeuivSUN (dynamic) */
    "p\0"
    "glReplacementCodeuivSUN\0"
    "\0"
-   /* _mesa_function_pool[27336]: EnableVertexAttribArrayARB (will be remapped) */
+   /* _mesa_function_pool[27621]: EnableVertexAttribArrayARB (will be remapped) */
    "i\0"
    "glEnableVertexAttribArray\0"
    "glEnableVertexAttribArrayARB\0"
    "\0"
-   /* _mesa_function_pool[27394]: NormalPointervINTEL (dynamic) */
+   /* _mesa_function_pool[27679]: NormalPointervINTEL (dynamic) */
    "ip\0"
    "glNormalPointervINTEL\0"
    "\0"
-   /* _mesa_function_pool[27420]: CopyConvolutionFilter2D (offset 355) */
+   /* _mesa_function_pool[27705]: CopyConvolutionFilter2D (offset 355) */
    "iiiiii\0"
    "glCopyConvolutionFilter2D\0"
    "glCopyConvolutionFilter2DEXT\0"
    "\0"
-   /* _mesa_function_pool[27483]: WindowPos3ivMESA (will be remapped) */
+   /* _mesa_function_pool[27768]: WindowPos3ivMESA (will be remapped) */
    "p\0"
    "glWindowPos3iv\0"
    "glWindowPos3ivARB\0"
    "glWindowPos3ivMESA\0"
    "\0"
-   /* _mesa_function_pool[27538]: CopyBufferSubData (will be remapped) */
+   /* _mesa_function_pool[27823]: CopyBufferSubData (will be remapped) */
    "iiiii\0"
    "glCopyBufferSubData\0"
    "\0"
-   /* _mesa_function_pool[27565]: NormalPointer (offset 318) */
+   /* _mesa_function_pool[27850]: NormalPointer (offset 318) */
    "iip\0"
    "glNormalPointer\0"
    "\0"
-   /* _mesa_function_pool[27586]: TexParameterfv (offset 179) */
+   /* _mesa_function_pool[27871]: TexParameterfv (offset 179) */
    "iip\0"
    "glTexParameterfv\0"
    "\0"
-   /* _mesa_function_pool[27608]: IsBufferARB (will be remapped) */
+   /* _mesa_function_pool[27893]: IsBufferARB (will be remapped) */
    "i\0"
    "glIsBuffer\0"
    "glIsBufferARB\0"
    "\0"
-   /* _mesa_function_pool[27636]: WindowPos4iMESA (will be remapped) */
+   /* _mesa_function_pool[27921]: WindowPos4iMESA (will be remapped) */
    "iiii\0"
    "glWindowPos4iMESA\0"
    "\0"
-   /* _mesa_function_pool[27660]: VertexAttrib4uivARB (will be remapped) */
+   /* _mesa_function_pool[27945]: VertexAttrib4uivARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4uiv\0"
    "glVertexAttrib4uivARB\0"
    "\0"
-   /* _mesa_function_pool[27705]: Tangent3bvEXT (dynamic) */
+   /* _mesa_function_pool[27990]: Tangent3bvEXT (dynamic) */
    "p\0"
    "glTangent3bvEXT\0"
    "\0"
-   /* _mesa_function_pool[27724]: UniformMatrix3x4fv (will be remapped) */
+   /* _mesa_function_pool[28009]: UniformMatrix3x4fv (will be remapped) */
    "iiip\0"
    "glUniformMatrix3x4fv\0"
    "\0"
-   /* _mesa_function_pool[27751]: ClipPlane (offset 150) */
+   /* _mesa_function_pool[28036]: ClipPlane (offset 150) */
    "ip\0"
    "glClipPlane\0"
    "\0"
-   /* _mesa_function_pool[27767]: Recti (offset 90) */
+   /* _mesa_function_pool[28052]: Recti (offset 90) */
    "iiii\0"
    "glRecti\0"
    "\0"
-   /* _mesa_function_pool[27781]: DrawRangeElementsBaseVertex (will be remapped) */
+   /* _mesa_function_pool[28066]: DrawRangeElementsBaseVertex (will be remapped) */
    "iiiiipi\0"
    "glDrawRangeElementsBaseVertex\0"
    "\0"
-   /* _mesa_function_pool[27820]: TexCoordPointervINTEL (dynamic) */
+   /* _mesa_function_pool[28105]: TexCoordPointervINTEL (dynamic) */
    "iip\0"
    "glTexCoordPointervINTEL\0"
    "\0"
-   /* _mesa_function_pool[27849]: DeleteBuffersARB (will be remapped) */
+   /* _mesa_function_pool[28134]: DeleteBuffersARB (will be remapped) */
    "ip\0"
    "glDeleteBuffers\0"
    "glDeleteBuffersARB\0"
    "\0"
-   /* _mesa_function_pool[27888]: PixelTransformParameterfvEXT (dynamic) */
+   /* _mesa_function_pool[28173]: PixelTransformParameterfvEXT (dynamic) */
    "iip\0"
    "glPixelTransformParameterfvEXT\0"
    "\0"
-   /* _mesa_function_pool[27924]: WindowPos4fvMESA (will be remapped) */
+   /* _mesa_function_pool[28209]: WindowPos4fvMESA (will be remapped) */
    "p\0"
    "glWindowPos4fvMESA\0"
    "\0"
-   /* _mesa_function_pool[27946]: GetPixelMapuiv (offset 272) */
+   /* _mesa_function_pool[28231]: GetPixelMapuiv (offset 272) */
    "ip\0"
    "glGetPixelMapuiv\0"
    "\0"
-   /* _mesa_function_pool[27967]: Rectf (offset 88) */
+   /* _mesa_function_pool[28252]: Rectf (offset 88) */
    "ffff\0"
    "glRectf\0"
    "\0"
-   /* _mesa_function_pool[27981]: VertexAttrib1sNV (will be remapped) */
+   /* _mesa_function_pool[28266]: VertexAttrib1sNV (will be remapped) */
    "ii\0"
    "glVertexAttrib1sNV\0"
    "\0"
-   /* _mesa_function_pool[28004]: Indexfv (offset 47) */
+   /* _mesa_function_pool[28289]: Indexfv (offset 47) */
    "p\0"
    "glIndexfv\0"
    "\0"
-   /* _mesa_function_pool[28017]: SecondaryColor3svEXT (will be remapped) */
+   /* _mesa_function_pool[28302]: SecondaryColor3svEXT (will be remapped) */
    "p\0"
    "glSecondaryColor3sv\0"
    "glSecondaryColor3svEXT\0"
    "\0"
-   /* _mesa_function_pool[28063]: LoadTransposeMatrixfARB (will be remapped) */
+   /* _mesa_function_pool[28348]: LoadTransposeMatrixfARB (will be remapped) */
    "p\0"
    "glLoadTransposeMatrixf\0"
    "glLoadTransposeMatrixfARB\0"
    "\0"
-   /* _mesa_function_pool[28115]: GetPointerv (offset 329) */
+   /* _mesa_function_pool[28400]: GetPointerv (offset 329) */
    "ip\0"
    "glGetPointerv\0"
    "glGetPointervEXT\0"
    "\0"
-   /* _mesa_function_pool[28150]: Tangent3bEXT (dynamic) */
+   /* _mesa_function_pool[28435]: Tangent3bEXT (dynamic) */
    "iii\0"
    "glTangent3bEXT\0"
    "\0"
-   /* _mesa_function_pool[28170]: CombinerParameterfNV (will be remapped) */
+   /* _mesa_function_pool[28455]: CombinerParameterfNV (will be remapped) */
    "if\0"
    "glCombinerParameterfNV\0"
    "\0"
-   /* _mesa_function_pool[28197]: IndexMask (offset 212) */
+   /* _mesa_function_pool[28482]: IndexMask (offset 212) */
    "i\0"
    "glIndexMask\0"
    "\0"
-   /* _mesa_function_pool[28212]: BindProgramNV (will be remapped) */
+   /* _mesa_function_pool[28497]: BindProgramNV (will be remapped) */
    "ii\0"
    "glBindProgramARB\0"
    "glBindProgramNV\0"
    "\0"
-   /* _mesa_function_pool[28249]: VertexAttrib4svARB (will be remapped) */
+   /* _mesa_function_pool[28534]: VertexAttrib4svARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4sv\0"
    "glVertexAttrib4svARB\0"
    "\0"
-   /* _mesa_function_pool[28292]: GetFloatv (offset 262) */
+   /* _mesa_function_pool[28577]: GetFloatv (offset 262) */
    "ip\0"
    "glGetFloatv\0"
    "\0"
-   /* _mesa_function_pool[28308]: CreateDebugObjectMESA (dynamic) */
+   /* _mesa_function_pool[28593]: CreateDebugObjectMESA (dynamic) */
    "\0"
    "glCreateDebugObjectMESA\0"
    "\0"
-   /* _mesa_function_pool[28334]: GetShaderiv (will be remapped) */
+   /* _mesa_function_pool[28619]: GetShaderiv (will be remapped) */
    "iip\0"
    "glGetShaderiv\0"
    "\0"
-   /* _mesa_function_pool[28353]: ClientWaitSync (will be remapped) */
+   /* _mesa_function_pool[28638]: ClientWaitSync (will be remapped) */
    "iii\0"
    "glClientWaitSync\0"
    "\0"
-   /* _mesa_function_pool[28375]: TexCoord4s (offset 124) */
+   /* _mesa_function_pool[28660]: TexCoord4s (offset 124) */
    "iiii\0"
    "glTexCoord4s\0"
    "\0"
-   /* _mesa_function_pool[28394]: TexCoord3sv (offset 117) */
+   /* _mesa_function_pool[28679]: TexCoord3sv (offset 117) */
    "p\0"
    "glTexCoord3sv\0"
    "\0"
-   /* _mesa_function_pool[28411]: BindFragmentShaderATI (will be remapped) */
+   /* _mesa_function_pool[28696]: BindFragmentShaderATI (will be remapped) */
    "i\0"
    "glBindFragmentShaderATI\0"
    "\0"
-   /* _mesa_function_pool[28438]: PopAttrib (offset 218) */
+   /* _mesa_function_pool[28723]: PopAttrib (offset 218) */
    "\0"
    "glPopAttrib\0"
    "\0"
-   /* _mesa_function_pool[28452]: Fogfv (offset 154) */
+   /* _mesa_function_pool[28737]: Fogfv (offset 154) */
    "ip\0"
    "glFogfv\0"
    "\0"
-   /* _mesa_function_pool[28464]: UnmapBufferARB (will be remapped) */
+   /* _mesa_function_pool[28749]: UnmapBufferARB (will be remapped) */
    "i\0"
    "glUnmapBuffer\0"
    "glUnmapBufferARB\0"
    "\0"
-   /* _mesa_function_pool[28498]: InitNames (offset 197) */
+   /* _mesa_function_pool[28783]: InitNames (offset 197) */
    "\0"
    "glInitNames\0"
    "\0"
-   /* _mesa_function_pool[28512]: Normal3sv (offset 61) */
+   /* _mesa_function_pool[28797]: Normal3sv (offset 61) */
    "p\0"
    "glNormal3sv\0"
    "\0"
-   /* _mesa_function_pool[28527]: Minmax (offset 368) */
+   /* _mesa_function_pool[28812]: Minmax (offset 368) */
    "iii\0"
    "glMinmax\0"
    "glMinmaxEXT\0"
    "\0"
-   /* _mesa_function_pool[28553]: TexCoord4d (offset 118) */
+   /* _mesa_function_pool[28838]: TexCoord4d (offset 118) */
    "dddd\0"
    "glTexCoord4d\0"
    "\0"
-   /* _mesa_function_pool[28572]: TexCoord4f (offset 120) */
+   /* _mesa_function_pool[28857]: DeformationMap3dSGIX (dynamic) */
+   "iddiiddiiddiip\0"
+   "glDeformationMap3dSGIX\0"
+   "\0"
+   /* _mesa_function_pool[28896]: TexCoord4f (offset 120) */
    "ffff\0"
    "glTexCoord4f\0"
    "\0"
-   /* _mesa_function_pool[28591]: FogCoorddvEXT (will be remapped) */
+   /* _mesa_function_pool[28915]: FogCoorddvEXT (will be remapped) */
    "p\0"
    "glFogCoorddv\0"
    "glFogCoorddvEXT\0"
    "\0"
-   /* _mesa_function_pool[28623]: FinishTextureSUNX (dynamic) */
+   /* _mesa_function_pool[28947]: FinishTextureSUNX (dynamic) */
    "\0"
    "glFinishTextureSUNX\0"
    "\0"
-   /* _mesa_function_pool[28645]: GetFragmentLightfvSGIX (dynamic) */
+   /* _mesa_function_pool[28969]: GetFragmentLightfvSGIX (dynamic) */
    "iip\0"
    "glGetFragmentLightfvSGIX\0"
    "\0"
-   /* _mesa_function_pool[28675]: Binormal3fvEXT (dynamic) */
+   /* _mesa_function_pool[28999]: Binormal3fvEXT (dynamic) */
    "p\0"
    "glBinormal3fvEXT\0"
    "\0"
-   /* _mesa_function_pool[28695]: GetBooleanv (offset 258) */
+   /* _mesa_function_pool[29019]: GetBooleanv (offset 258) */
    "ip\0"
    "glGetBooleanv\0"
    "\0"
-   /* _mesa_function_pool[28713]: ColorFragmentOp3ATI (will be remapped) */
+   /* _mesa_function_pool[29037]: ColorFragmentOp3ATI (will be remapped) */
    "iiiiiiiiiiiii\0"
    "glColorFragmentOp3ATI\0"
    "\0"
-   /* _mesa_function_pool[28750]: Hint (offset 158) */
+   /* _mesa_function_pool[29074]: Hint (offset 158) */
    "ii\0"
    "glHint\0"
    "\0"
-   /* _mesa_function_pool[28761]: Color4dv (offset 28) */
+   /* _mesa_function_pool[29085]: Color4dv (offset 28) */
    "p\0"
    "glColor4dv\0"
    "\0"
-   /* _mesa_function_pool[28775]: VertexAttrib2svARB (will be remapped) */
+   /* _mesa_function_pool[29099]: VertexAttrib2svARB (will be remapped) */
    "ip\0"
    "glVertexAttrib2sv\0"
    "glVertexAttrib2svARB\0"
    "\0"
-   /* _mesa_function_pool[28818]: AreProgramsResidentNV (will be remapped) */
+   /* _mesa_function_pool[29142]: AreProgramsResidentNV (will be remapped) */
    "ipp\0"
    "glAreProgramsResidentNV\0"
    "\0"
-   /* _mesa_function_pool[28847]: WindowPos3svMESA (will be remapped) */
+   /* _mesa_function_pool[29171]: WindowPos3svMESA (will be remapped) */
    "p\0"
    "glWindowPos3sv\0"
    "glWindowPos3svARB\0"
    "glWindowPos3svMESA\0"
    "\0"
-   /* _mesa_function_pool[28902]: CopyColorSubTable (offset 347) */
+   /* _mesa_function_pool[29226]: CopyColorSubTable (offset 347) */
    "iiiii\0"
    "glCopyColorSubTable\0"
    "glCopyColorSubTableEXT\0"
    "\0"
-   /* _mesa_function_pool[28952]: WeightdvARB (dynamic) */
+   /* _mesa_function_pool[29276]: WeightdvARB (dynamic) */
    "ip\0"
    "glWeightdvARB\0"
    "\0"
-   /* _mesa_function_pool[28970]: DeleteRenderbuffersEXT (will be remapped) */
+   /* _mesa_function_pool[29294]: DeleteRenderbuffersEXT (will be remapped) */
    "ip\0"
    "glDeleteRenderbuffers\0"
    "glDeleteRenderbuffersEXT\0"
    "\0"
-   /* _mesa_function_pool[29021]: VertexAttrib4NubvARB (will be remapped) */
+   /* _mesa_function_pool[29345]: VertexAttrib4NubvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib4Nubv\0"
    "glVertexAttrib4NubvARB\0"
    "\0"
-   /* _mesa_function_pool[29068]: VertexAttrib3dvNV (will be remapped) */
+   /* _mesa_function_pool[29392]: VertexAttrib3dvNV (will be remapped) */
    "ip\0"
    "glVertexAttrib3dvNV\0"
    "\0"
-   /* _mesa_function_pool[29092]: GetObjectParameterfvARB (will be remapped) */
+   /* _mesa_function_pool[29416]: GetObjectParameterfvARB (will be remapped) */
    "iip\0"
    "glGetObjectParameterfvARB\0"
    "\0"
-   /* _mesa_function_pool[29123]: Vertex4iv (offset 147) */
+   /* _mesa_function_pool[29447]: Vertex4iv (offset 147) */
    "p\0"
    "glVertex4iv\0"
    "\0"
-   /* _mesa_function_pool[29138]: GetProgramEnvParameterdvARB (will be remapped) */
+   /* _mesa_function_pool[29462]: GetProgramEnvParameterdvARB (will be remapped) */
    "iip\0"
    "glGetProgramEnvParameterdvARB\0"
    "\0"
-   /* _mesa_function_pool[29173]: TexCoord4dv (offset 119) */
+   /* _mesa_function_pool[29497]: TexCoord4dv (offset 119) */
    "p\0"
    "glTexCoord4dv\0"
    "\0"
-   /* _mesa_function_pool[29190]: LockArraysEXT (will be remapped) */
+   /* _mesa_function_pool[29514]: LockArraysEXT (will be remapped) */
    "ii\0"
    "glLockArraysEXT\0"
    "\0"
-   /* _mesa_function_pool[29210]: Begin (offset 7) */
+   /* _mesa_function_pool[29534]: Begin (offset 7) */
    "i\0"
    "glBegin\0"
    "\0"
-   /* _mesa_function_pool[29221]: LightModeli (offset 165) */
+   /* _mesa_function_pool[29545]: LightModeli (offset 165) */
    "ii\0"
    "glLightModeli\0"
    "\0"
-   /* _mesa_function_pool[29239]: Rectfv (offset 89) */
+   /* _mesa_function_pool[29563]: Rectfv (offset 89) */
    "pp\0"
    "glRectfv\0"
    "\0"
-   /* _mesa_function_pool[29252]: LightModelf (offset 163) */
+   /* _mesa_function_pool[29576]: LightModelf (offset 163) */
    "if\0"
    "glLightModelf\0"
    "\0"
-   /* _mesa_function_pool[29270]: GetTexParameterfv (offset 282) */
+   /* _mesa_function_pool[29594]: GetTexParameterfv (offset 282) */
    "iip\0"
    "glGetTexParameterfv\0"
    "\0"
-   /* _mesa_function_pool[29295]: GetLightfv (offset 264) */
+   /* _mesa_function_pool[29619]: GetLightfv (offset 264) */
    "iip\0"
    "glGetLightfv\0"
    "\0"
-   /* _mesa_function_pool[29313]: PixelTransformParameterivEXT (dynamic) */
+   /* _mesa_function_pool[29637]: PixelTransformParameterivEXT (dynamic) */
    "iip\0"
    "glPixelTransformParameterivEXT\0"
    "\0"
-   /* _mesa_function_pool[29349]: BinormalPointerEXT (dynamic) */
+   /* _mesa_function_pool[29673]: BinormalPointerEXT (dynamic) */
    "iip\0"
    "glBinormalPointerEXT\0"
    "\0"
-   /* _mesa_function_pool[29375]: VertexAttrib1dNV (will be remapped) */
+   /* _mesa_function_pool[29699]: VertexAttrib1dNV (will be remapped) */
    "id\0"
    "glVertexAttrib1dNV\0"
    "\0"
-   /* _mesa_function_pool[29398]: GetCombinerInputParameterivNV (will be remapped) */
+   /* _mesa_function_pool[29722]: GetCombinerInputParameterivNV (will be remapped) */
    "iiiip\0"
    "glGetCombinerInputParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[29437]: Disable (offset 214) */
+   /* _mesa_function_pool[29761]: Disable (offset 214) */
    "i\0"
    "glDisable\0"
    "\0"
-   /* _mesa_function_pool[29450]: MultiTexCoord2fvARB (offset 387) */
+   /* _mesa_function_pool[29774]: MultiTexCoord2fvARB (offset 387) */
    "ip\0"
    "glMultiTexCoord2fv\0"
    "glMultiTexCoord2fvARB\0"
    "\0"
-   /* _mesa_function_pool[29495]: GetRenderbufferParameterivEXT (will be remapped) */
+   /* _mesa_function_pool[29819]: GetRenderbufferParameterivEXT (will be remapped) */
    "iip\0"
    "glGetRenderbufferParameteriv\0"
    "glGetRenderbufferParameterivEXT\0"
    "\0"
-   /* _mesa_function_pool[29561]: CombinerParameterivNV (will be remapped) */
+   /* _mesa_function_pool[29885]: CombinerParameterivNV (will be remapped) */
    "ip\0"
    "glCombinerParameterivNV\0"
    "\0"
-   /* _mesa_function_pool[29589]: GenFragmentShadersATI (will be remapped) */
+   /* _mesa_function_pool[29913]: GenFragmentShadersATI (will be remapped) */
    "i\0"
    "glGenFragmentShadersATI\0"
    "\0"
-   /* _mesa_function_pool[29616]: DrawArrays (offset 310) */
+   /* _mesa_function_pool[29940]: DrawArrays (offset 310) */
    "iii\0"
    "glDrawArrays\0"
    "glDrawArraysEXT\0"
    "\0"
-   /* _mesa_function_pool[29650]: WeightuivARB (dynamic) */
+   /* _mesa_function_pool[29974]: WeightuivARB (dynamic) */
    "ip\0"
    "glWeightuivARB\0"
    "\0"
-   /* _mesa_function_pool[29669]: VertexAttrib2sARB (will be remapped) */
+   /* _mesa_function_pool[29993]: VertexAttrib2sARB (will be remapped) */
    "iii\0"
    "glVertexAttrib2s\0"
    "glVertexAttrib2sARB\0"
    "\0"
-   /* _mesa_function_pool[29711]: ColorMask (offset 210) */
+   /* _mesa_function_pool[30035]: ColorMask (offset 210) */
    "iiii\0"
    "glColorMask\0"
    "\0"
-   /* _mesa_function_pool[29729]: GenAsyncMarkersSGIX (dynamic) */
+   /* _mesa_function_pool[30053]: GenAsyncMarkersSGIX (dynamic) */
    "i\0"
    "glGenAsyncMarkersSGIX\0"
    "\0"
-   /* _mesa_function_pool[29754]: Tangent3svEXT (dynamic) */
+   /* _mesa_function_pool[30078]: Tangent3svEXT (dynamic) */
    "p\0"
    "glTangent3svEXT\0"
    "\0"
-   /* _mesa_function_pool[29773]: GetListParameterivSGIX (dynamic) */
+   /* _mesa_function_pool[30097]: GetListParameterivSGIX (dynamic) */
    "iip\0"
    "glGetListParameterivSGIX\0"
    "\0"
-   /* _mesa_function_pool[29803]: BindBufferARB (will be remapped) */
+   /* _mesa_function_pool[30127]: BindBufferARB (will be remapped) */
    "ii\0"
    "glBindBuffer\0"
    "glBindBufferARB\0"
    "\0"
-   /* _mesa_function_pool[29836]: GetInfoLogARB (will be remapped) */
+   /* _mesa_function_pool[30160]: GetInfoLogARB (will be remapped) */
    "iipp\0"
    "glGetInfoLogARB\0"
    "\0"
-   /* _mesa_function_pool[29858]: RasterPos4iv (offset 83) */
+   /* _mesa_function_pool[30182]: RasterPos4iv (offset 83) */
    "p\0"
    "glRasterPos4iv\0"
    "\0"
-   /* _mesa_function_pool[29876]: Enable (offset 215) */
+   /* _mesa_function_pool[30200]: Enable (offset 215) */
    "i\0"
    "glEnable\0"
    "\0"
-   /* _mesa_function_pool[29888]: LineStipple (offset 167) */
+   /* _mesa_function_pool[30212]: LineStipple (offset 167) */
    "ii\0"
    "glLineStipple\0"
    "\0"
-   /* _mesa_function_pool[29906]: VertexAttribs4svNV (will be remapped) */
+   /* _mesa_function_pool[30230]: VertexAttribs4svNV (will be remapped) */
    "iip\0"
    "glVertexAttribs4svNV\0"
    "\0"
-   /* _mesa_function_pool[29932]: EdgeFlagPointerListIBM (dynamic) */
+   /* _mesa_function_pool[30256]: EdgeFlagPointerListIBM (dynamic) */
    "ipi\0"
    "glEdgeFlagPointerListIBM\0"
    "\0"
-   /* _mesa_function_pool[29962]: UniformMatrix3x2fv (will be remapped) */
+   /* _mesa_function_pool[30286]: UniformMatrix3x2fv (will be remapped) */
    "iiip\0"
    "glUniformMatrix3x2fv\0"
    "\0"
-   /* _mesa_function_pool[29989]: GetMinmaxParameterfv (offset 365) */
+   /* _mesa_function_pool[30313]: GetMinmaxParameterfv (offset 365) */
    "iip\0"
    "glGetMinmaxParameterfv\0"
    "glGetMinmaxParameterfvEXT\0"
    "\0"
-   /* _mesa_function_pool[30043]: VertexAttrib1fvARB (will be remapped) */
+   /* _mesa_function_pool[30367]: VertexAttrib1fvARB (will be remapped) */
    "ip\0"
    "glVertexAttrib1fv\0"
    "glVertexAttrib1fvARB\0"
    "\0"
-   /* _mesa_function_pool[30086]: GenBuffersARB (will be remapped) */
+   /* _mesa_function_pool[30410]: GenBuffersARB (will be remapped) */
    "ip\0"
    "glGenBuffers\0"
    "glGenBuffersARB\0"
    "\0"
-   /* _mesa_function_pool[30119]: VertexAttribs1svNV (will be remapped) */
+   /* _mesa_function_pool[30443]: VertexAttribs1svNV (will be remapped) */
    "iip\0"
    "glVertexAttribs1svNV\0"
    "\0"
-   /* _mesa_function_pool[30145]: Vertex3fv (offset 137) */
+   /* _mesa_function_pool[30469]: Vertex3fv (offset 137) */
    "p\0"
    "glVertex3fv\0"
    "\0"
-   /* _mesa_function_pool[30160]: GetTexBumpParameterivATI (will be remapped) */
+   /* _mesa_function_pool[30484]: GetTexBumpParameterivATI (will be remapped) */
    "ip\0"
    "glGetTexBumpParameterivATI\0"
    "\0"
-   /* _mesa_function_pool[30191]: Binormal3bEXT (dynamic) */
+   /* _mesa_function_pool[30515]: Binormal3bEXT (dynamic) */
    "iii\0"
    "glBinormal3bEXT\0"
    "\0"
-   /* _mesa_function_pool[30212]: FragmentMaterialivSGIX (dynamic) */
+   /* _mesa_function_pool[30536]: FragmentMaterialivSGIX (dynamic) */
    "iip\0"
    "glFragmentMaterialivSGIX\0"
    "\0"
-   /* _mesa_function_pool[30242]: IsRenderbufferEXT (will be remapped) */
+   /* _mesa_function_pool[30566]: IsRenderbufferEXT (will be remapped) */
    "i\0"
    "glIsRenderbuffer\0"
    "glIsRenderbufferEXT\0"
    "\0"
-   /* _mesa_function_pool[30282]: GenProgramsNV (will be remapped) */
+   /* _mesa_function_pool[30606]: GenProgramsNV (will be remapped) */
    "ip\0"
    "glGenProgramsARB\0"
    "glGenProgramsNV\0"
    "\0"
-   /* _mesa_function_pool[30319]: VertexAttrib4dvNV (will be remapped) */
+   /* _mesa_function_pool[30643]: VertexAttrib4dvNV (will be remapped) */
    "ip\0"
    "glVertexAttrib4dvNV\0"
    "\0"
-   /* _mesa_function_pool[30343]: EndFragmentShaderATI (will be remapped) */
+   /* _mesa_function_pool[30667]: EndFragmentShaderATI (will be remapped) */
    "\0"
    "glEndFragmentShaderATI\0"
    "\0"
-   /* _mesa_function_pool[30368]: Binormal3iEXT (dynamic) */
+   /* _mesa_function_pool[30692]: Binormal3iEXT (dynamic) */
    "iii\0"
    "glBinormal3iEXT\0"
    "\0"
-   /* _mesa_function_pool[30389]: WindowPos2fMESA (will be remapped) */
+   /* _mesa_function_pool[30713]: WindowPos2fMESA (will be remapped) */
    "ff\0"
    "glWindowPos2f\0"
    "glWindowPos2fARB\0"
@@ -4425,414 +4469,424 @@ static const char _mesa_function_pool[] =
 /* these functions need to be remapped */
 static const struct gl_function_pool_remap MESA_remap_table_functions[] = {
    {  1461, AttachShader_remap_index },
-   {  8848, CreateProgram_remap_index },
-   { 20883, CreateShader_remap_index },
-   { 23213, DeleteProgram_remap_index },
-   { 16692, DeleteShader_remap_index },
-   { 21329, DetachShader_remap_index },
-   { 16216, GetAttachedShaders_remap_index },
+   {  8995, CreateProgram_remap_index },
+   { 21153, CreateShader_remap_index },
+   { 23466, DeleteProgram_remap_index },
+   { 16937, DeleteShader_remap_index },
+   { 21599, DetachShader_remap_index },
+   { 16461, GetAttachedShaders_remap_index },
    {  4275, GetProgramInfoLog_remap_index },
    {   361, GetProgramiv_remap_index },
-   {  5608, GetShaderInfoLog_remap_index },
-   { 28334, GetShaderiv_remap_index },
-   { 12054, IsProgram_remap_index },
-   { 11089, IsShader_remap_index },
-   {  8952, StencilFuncSeparate_remap_index },
+   {  5721, GetShaderInfoLog_remap_index },
+   { 28619, GetShaderiv_remap_index },
+   { 12198, IsProgram_remap_index },
+   { 11197, IsShader_remap_index },
+   {  9099, StencilFuncSeparate_remap_index },
    {  3487, StencilMaskSeparate_remap_index },
-   {  6684, StencilOpSeparate_remap_index },
-   { 20208, UniformMatrix2x3fv_remap_index },
+   {  6803, StencilOpSeparate_remap_index },
+   { 20478, UniformMatrix2x3fv_remap_index },
    {  2615, UniformMatrix2x4fv_remap_index },
-   { 29962, UniformMatrix3x2fv_remap_index },
-   { 27724, UniformMatrix3x4fv_remap_index },
-   { 14716, UniformMatrix4x2fv_remap_index },
+   { 30286, UniformMatrix3x2fv_remap_index },
+   { 28009, UniformMatrix3x4fv_remap_index },
+   { 14961, UniformMatrix4x2fv_remap_index },
    {  2937, UniformMatrix4x3fv_remap_index },
-   { 14377, DrawArraysInstanced_remap_index },
-   { 15480, DrawElementsInstanced_remap_index },
-   {  8866, LoadTransposeMatrixdARB_remap_index },
-   { 28063, LoadTransposeMatrixfARB_remap_index },
-   {  4848, MultTransposeMatrixdARB_remap_index },
-   { 21516, MultTransposeMatrixfARB_remap_index },
+   { 14622, DrawArraysInstanced_remap_index },
+   { 15725, DrawElementsInstanced_remap_index },
+   {  9013, LoadTransposeMatrixdARB_remap_index },
+   { 28348, LoadTransposeMatrixfARB_remap_index },
+   {  4904, MultTransposeMatrixdARB_remap_index },
+   { 21786, MultTransposeMatrixfARB_remap_index },
    {   172, SampleCoverageARB_remap_index },
-   {  5032, CompressedTexImage1DARB_remap_index },
-   { 22016, CompressedTexImage2DARB_remap_index },
+   {  5117, CompressedTexImage1DARB_remap_index },
+   { 22269, CompressedTexImage2DARB_remap_index },
    {  3550, CompressedTexImage3DARB_remap_index },
-   { 16508, CompressedTexSubImage1DARB_remap_index },
+   { 16753, CompressedTexSubImage1DARB_remap_index },
    {  1880, CompressedTexSubImage2DARB_remap_index },
-   { 18369, CompressedTexSubImage3DARB_remap_index },
-   { 26006, GetCompressedTexImageARB_remap_index },
+   { 18614, CompressedTexSubImage3DARB_remap_index },
+   { 26291, GetCompressedTexImageARB_remap_index },
    {  3395, DisableVertexAttribArrayARB_remap_index },
-   { 27336, EnableVertexAttribArrayARB_remap_index },
-   { 29138, GetProgramEnvParameterdvARB_remap_index },
-   { 21396, GetProgramEnvParameterfvARB_remap_index },
-   { 25007, GetProgramLocalParameterdvARB_remap_index },
-   {  7126, GetProgramLocalParameterfvARB_remap_index },
-   { 16599, GetProgramStringARB_remap_index },
-   { 25202, GetProgramivARB_remap_index },
-   { 18564, GetVertexAttribdvARB_remap_index },
-   { 14605, GetVertexAttribfvARB_remap_index },
-   {  8761, GetVertexAttribivARB_remap_index },
-   { 17445, ProgramEnvParameter4dARB_remap_index },
-   { 22986, ProgramEnvParameter4dvARB_remap_index },
-   { 15213, ProgramEnvParameter4fARB_remap_index },
-   {  7989, ProgramEnvParameter4fvARB_remap_index },
+   { 27621, EnableVertexAttribArrayARB_remap_index },
+   { 29462, GetProgramEnvParameterdvARB_remap_index },
+   { 21666, GetProgramEnvParameterfvARB_remap_index },
+   { 25290, GetProgramLocalParameterdvARB_remap_index },
+   {  7245, GetProgramLocalParameterfvARB_remap_index },
+   { 16844, GetProgramStringARB_remap_index },
+   { 25485, GetProgramivARB_remap_index },
+   { 18809, GetVertexAttribdvARB_remap_index },
+   { 14850, GetVertexAttribfvARB_remap_index },
+   {  8908, GetVertexAttribivARB_remap_index },
+   { 17690, ProgramEnvParameter4dARB_remap_index },
+   { 23239, ProgramEnvParameter4dvARB_remap_index },
+   { 15458, ProgramEnvParameter4fARB_remap_index },
+   {  8108, ProgramEnvParameter4fvARB_remap_index },
    {  3513, ProgramLocalParameter4dARB_remap_index },
-   { 11764, ProgramLocalParameter4dvARB_remap_index },
-   { 26815, ProgramLocalParameter4fARB_remap_index },
-   { 23531, ProgramLocalParameter4fvARB_remap_index },
-   { 25792, ProgramStringARB_remap_index },
-   { 17695, VertexAttrib1dARB_remap_index },
-   { 14181, VertexAttrib1dvARB_remap_index },
+   { 11908, ProgramLocalParameter4dvARB_remap_index },
+   { 27100, ProgramLocalParameter4fARB_remap_index },
+   { 23819, ProgramLocalParameter4fvARB_remap_index },
+   { 26071, ProgramStringARB_remap_index },
+   { 17940, VertexAttrib1dARB_remap_index },
+   { 14426, VertexAttrib1dvARB_remap_index },
    {  3688, VertexAttrib1fARB_remap_index },
-   { 30043, VertexAttrib1fvARB_remap_index },
-   {  6210, VertexAttrib1sARB_remap_index },
+   { 30367, VertexAttrib1fvARB_remap_index },
+   {  6329, VertexAttrib1sARB_remap_index },
    {  2054, VertexAttrib1svARB_remap_index },
-   { 13612, VertexAttrib2dARB_remap_index },
-   { 15835, VertexAttrib2dvARB_remap_index },
+   { 13857, VertexAttrib2dARB_remap_index },
+   { 16080, VertexAttrib2dvARB_remap_index },
    {  1480, VertexAttrib2fARB_remap_index },
-   { 15948, VertexAttrib2fvARB_remap_index },
-   { 29669, VertexAttrib2sARB_remap_index },
-   { 28775, VertexAttrib2svARB_remap_index },
-   { 10135, VertexAttrib3dARB_remap_index },
-   {  7692, VertexAttrib3dvARB_remap_index },
+   { 16193, VertexAttrib2fvARB_remap_index },
+   { 29993, VertexAttrib2sARB_remap_index },
+   { 29099, VertexAttrib2svARB_remap_index },
+   { 10282, VertexAttrib3dARB_remap_index },
+   {  7811, VertexAttrib3dvARB_remap_index },
    {  1567, VertexAttrib3fARB_remap_index },
-   { 20471, VertexAttrib3fvARB_remap_index },
-   { 25635, VertexAttrib3sARB_remap_index },
-   { 18306, VertexAttrib3svARB_remap_index },
+   { 20741, VertexAttrib3fvARB_remap_index },
+   { 25918, VertexAttrib3sARB_remap_index },
+   { 18551, VertexAttrib3svARB_remap_index },
    {  4301, VertexAttrib4NbvARB_remap_index },
-   { 16171, VertexAttrib4NivARB_remap_index },
-   { 20426, VertexAttrib4NsvARB_remap_index },
-   { 21348, VertexAttrib4NubARB_remap_index },
-   { 29021, VertexAttrib4NubvARB_remap_index },
-   { 17106, VertexAttrib4NuivARB_remap_index },
+   { 16416, VertexAttrib4NivARB_remap_index },
+   { 20696, VertexAttrib4NsvARB_remap_index },
+   { 21618, VertexAttrib4NubARB_remap_index },
+   { 29345, VertexAttrib4NubvARB_remap_index },
+   { 17351, VertexAttrib4NuivARB_remap_index },
    {  2810, VertexAttrib4NusvARB_remap_index },
-   {  9729, VertexAttrib4bvARB_remap_index },
-   { 24415, VertexAttrib4dARB_remap_index },
-   { 19328, VertexAttrib4dvARB_remap_index },
-   { 10242, VertexAttrib4fARB_remap_index },
-   { 10646, VertexAttrib4fvARB_remap_index },
-   {  9145, VertexAttrib4ivARB_remap_index },
-   { 15649, VertexAttrib4sARB_remap_index },
-   { 28249, VertexAttrib4svARB_remap_index },
-   { 15018, VertexAttrib4ubvARB_remap_index },
-   { 27660, VertexAttrib4uivARB_remap_index },
-   { 18117, VertexAttrib4usvARB_remap_index },
-   { 20082, VertexAttribPointerARB_remap_index },
-   { 29803, BindBufferARB_remap_index },
-   {  5923, BufferDataARB_remap_index },
+   {  9876, VertexAttrib4bvARB_remap_index },
+   { 24698, VertexAttrib4dARB_remap_index },
+   { 19573, VertexAttrib4dvARB_remap_index },
+   { 10389, VertexAttrib4fARB_remap_index },
+   { 10793, VertexAttrib4fvARB_remap_index },
+   {  9292, VertexAttrib4ivARB_remap_index },
+   { 15894, VertexAttrib4sARB_remap_index },
+   { 28534, VertexAttrib4svARB_remap_index },
+   { 15263, VertexAttrib4ubvARB_remap_index },
+   { 27945, VertexAttrib4uivARB_remap_index },
+   { 18362, VertexAttrib4usvARB_remap_index },
+   { 20327, VertexAttribPointerARB_remap_index },
+   { 30127, BindBufferARB_remap_index },
+   {  6036, BufferDataARB_remap_index },
    {  1382, BufferSubDataARB_remap_index },
-   { 27849, DeleteBuffersARB_remap_index },
-   { 30086, GenBuffersARB_remap_index },
-   { 15991, GetBufferParameterivARB_remap_index },
-   { 15165, GetBufferPointervARB_remap_index },
+   { 28134, DeleteBuffersARB_remap_index },
+   { 30410, GenBuffersARB_remap_index },
+   { 16236, GetBufferParameterivARB_remap_index },
+   { 15410, GetBufferPointervARB_remap_index },
    {  1335, GetBufferSubDataARB_remap_index },
-   { 27608, IsBufferARB_remap_index },
-   { 23988, MapBufferARB_remap_index },
-   { 28464, UnmapBufferARB_remap_index },
+   { 27893, IsBufferARB_remap_index },
+   { 24303, MapBufferARB_remap_index },
+   { 28749, UnmapBufferARB_remap_index },
    {   268, BeginQueryARB_remap_index },
-   { 17790, DeleteQueriesARB_remap_index },
-   { 10940, EndQueryARB_remap_index },
-   { 26485, GenQueriesARB_remap_index },
+   { 18035, DeleteQueriesARB_remap_index },
+   { 11087, EndQueryARB_remap_index },
+   { 26770, GenQueriesARB_remap_index },
    {  1772, GetQueryObjectivARB_remap_index },
-   { 15693, GetQueryObjectuivARB_remap_index },
+   { 15938, GetQueryObjectuivARB_remap_index },
    {  1624, GetQueryivARB_remap_index },
-   { 18024, IsQueryARB_remap_index },
-   {  7302, AttachObjectARB_remap_index },
-   { 16654, CompileShaderARB_remap_index },
+   { 18269, IsQueryARB_remap_index },
+   {  7421, AttachObjectARB_remap_index },
+   { 16899, CompileShaderARB_remap_index },
    {  2879, CreateProgramObjectARB_remap_index },
-   {  5868, CreateShaderObjectARB_remap_index },
-   { 13029, DeleteObjectARB_remap_index },
-   { 21790, DetachObjectARB_remap_index },
-   { 10718, GetActiveUniformARB_remap_index },
-   {  8464, GetAttachedObjectsARB_remap_index },
-   {  8743, GetHandleARB_remap_index },
-   { 29836, GetInfoLogARB_remap_index },
-   { 29092, GetObjectParameterfvARB_remap_index },
-   { 24881, GetObjectParameterivARB_remap_index },
-   { 26243, GetShaderSourceARB_remap_index },
-   { 25495, GetUniformLocationARB_remap_index },
-   { 21618, GetUniformfvARB_remap_index },
-   { 11386, GetUniformivARB_remap_index },
-   { 18162, LinkProgramARB_remap_index },
-   { 18220, ShaderSourceARB_remap_index },
-   {  6584, Uniform1fARB_remap_index },
-   { 27024, Uniform1fvARB_remap_index },
-   { 20051, Uniform1iARB_remap_index },
-   { 19017, Uniform1ivARB_remap_index },
+   {  5981, CreateShaderObjectARB_remap_index },
+   { 13274, DeleteObjectARB_remap_index },
+   { 22060, DetachObjectARB_remap_index },
+   { 10865, GetActiveUniformARB_remap_index },
+   {  8583, GetAttachedObjectsARB_remap_index },
+   {  8890, GetHandleARB_remap_index },
+   { 30160, GetInfoLogARB_remap_index },
+   { 29416, GetObjectParameterfvARB_remap_index },
+   { 25164, GetObjectParameterivARB_remap_index },
+   { 26528, GetShaderSourceARB_remap_index },
+   { 25778, GetUniformLocationARB_remap_index },
+   { 21888, GetUniformfvARB_remap_index },
+   { 11530, GetUniformivARB_remap_index },
+   { 18407, LinkProgramARB_remap_index },
+   { 18465, ShaderSourceARB_remap_index },
+   {  6703, Uniform1fARB_remap_index },
+   { 27309, Uniform1fvARB_remap_index },
+   { 20296, Uniform1iARB_remap_index },
+   { 19262, Uniform1ivARB_remap_index },
    {  2003, Uniform2fARB_remap_index },
-   { 12865, Uniform2fvARB_remap_index },
-   { 23875, Uniform2iARB_remap_index },
+   { 13110, Uniform2fvARB_remap_index },
+   { 24190, Uniform2iARB_remap_index },
    {  2123, Uniform2ivARB_remap_index },
-   { 16764, Uniform3fARB_remap_index },
-   {  8494, Uniform3fvARB_remap_index },
-   {  5542, Uniform3iARB_remap_index },
-   { 15271, Uniform3ivARB_remap_index },
-   { 17251, Uniform4fARB_remap_index },
-   { 21482, Uniform4fvARB_remap_index },
-   { 22665, Uniform4iARB_remap_index },
-   { 18530, Uniform4ivARB_remap_index },
-   {  7354, UniformMatrix2fvARB_remap_index },
+   { 17009, Uniform3fARB_remap_index },
+   {  8613, Uniform3fvARB_remap_index },
+   {  5627, Uniform3iARB_remap_index },
+   { 15516, Uniform3ivARB_remap_index },
+   { 17496, Uniform4fARB_remap_index },
+   { 21752, Uniform4fvARB_remap_index },
+   { 22918, Uniform4iARB_remap_index },
+   { 18775, Uniform4ivARB_remap_index },
+   {  7473, UniformMatrix2fvARB_remap_index },
    {    17, UniformMatrix3fvARB_remap_index },
    {  2475, UniformMatrix4fvARB_remap_index },
-   { 23098, UseProgramObjectARB_remap_index },
-   { 13300, ValidateProgramARB_remap_index },
-   { 19371, BindAttribLocationARB_remap_index },
+   { 23351, UseProgramObjectARB_remap_index },
+   { 13545, ValidateProgramARB_remap_index },
+   { 19616, BindAttribLocationARB_remap_index },
    {  4346, GetActiveAttribARB_remap_index },
-   { 14952, GetAttribLocationARB_remap_index },
-   { 26763, DrawBuffersARB_remap_index },
-   { 11869, RenderbufferStorageMultisample_remap_index },
-   { 17299, FlushMappedBufferRange_remap_index },
-   { 25298, MapBufferRange_remap_index },
-   { 14827, BindVertexArray_remap_index },
-   { 13159, GenVertexArrays_remap_index },
-   { 27538, CopyBufferSubData_remap_index },
-   { 28353, ClientWaitSync_remap_index },
+   { 15197, GetAttribLocationARB_remap_index },
+   { 27048, DrawBuffersARB_remap_index },
+   { 12013, RenderbufferStorageMultisample_remap_index },
+   { 12417, FramebufferTextureARB_remap_index },
+   { 23721, FramebufferTextureFaceARB_remap_index },
+   { 22209, ProgramParameteriARB_remap_index },
+   { 17544, FlushMappedBufferRange_remap_index },
+   { 25581, MapBufferRange_remap_index },
+   { 15072, BindVertexArray_remap_index },
+   { 13404, GenVertexArrays_remap_index },
+   { 27823, CopyBufferSubData_remap_index },
+   { 28638, ClientWaitSync_remap_index },
    {  2394, DeleteSync_remap_index },
-   {  6251, FenceSync_remap_index },
-   { 13671, GetInteger64v_remap_index },
-   { 20533, GetSynciv_remap_index },
-   { 26702, IsSync_remap_index },
-   {  8412, WaitSync_remap_index },
+   {  6370, FenceSync_remap_index },
+   { 13916, GetInteger64v_remap_index },
+   { 20803, GetSynciv_remap_index },
+   { 26987, IsSync_remap_index },
+   {  8531, WaitSync_remap_index },
    {  3363, DrawElementsBaseVertex_remap_index },
-   { 27781, DrawRangeElementsBaseVertex_remap_index },
-   { 24019, MultiDrawElementsBaseVertex_remap_index },
-   {  4711, PolygonOffsetEXT_remap_index },
-   { 21118, GetPixelTexGenParameterfvSGIS_remap_index },
+   { 28066, DrawRangeElementsBaseVertex_remap_index },
+   { 24334, MultiDrawElementsBaseVertex_remap_index },
+   {  4480, BindTransformFeedback_remap_index },
+   {  2906, DeleteTransformFeedbacks_remap_index },
+   {  5660, DrawTransformFeedback_remap_index },
+   {  8750, GenTransformFeedbacks_remap_index },
+   { 25961, IsTransformFeedback_remap_index },
+   { 23914, PauseTransformFeedback_remap_index },
+   {  4824, ResumeTransformFeedback_remap_index },
+   {  4739, PolygonOffsetEXT_remap_index },
+   { 21388, GetPixelTexGenParameterfvSGIS_remap_index },
    {  3895, GetPixelTexGenParameterivSGIS_remap_index },
-   { 20851, PixelTexGenParameterfSGIS_remap_index },
+   { 21121, PixelTexGenParameterfSGIS_remap_index },
    {   580, PixelTexGenParameterfvSGIS_remap_index },
-   { 11424, PixelTexGenParameteriSGIS_remap_index },
-   { 12385, PixelTexGenParameterivSGIS_remap_index },
-   { 14915, SampleMaskSGIS_remap_index },
-   { 17964, SamplePatternSGIS_remap_index },
-   { 23948, ColorPointerEXT_remap_index },
-   { 15878, EdgeFlagPointerEXT_remap_index },
-   {  5196, IndexPointerEXT_remap_index },
-   {  5276, NormalPointerEXT_remap_index },
-   { 14265, TexCoordPointerEXT_remap_index },
-   {  6046, VertexPointerEXT_remap_index },
+   { 11568, PixelTexGenParameteriSGIS_remap_index },
+   { 12591, PixelTexGenParameterivSGIS_remap_index },
+   { 15160, SampleMaskSGIS_remap_index },
+   { 18209, SamplePatternSGIS_remap_index },
+   { 24263, ColorPointerEXT_remap_index },
+   { 16123, EdgeFlagPointerEXT_remap_index },
+   {  5281, IndexPointerEXT_remap_index },
+   {  5361, NormalPointerEXT_remap_index },
+   { 14510, TexCoordPointerEXT_remap_index },
+   {  6159, VertexPointerEXT_remap_index },
    {  3165, PointParameterfEXT_remap_index },
-   {  6891, PointParameterfvEXT_remap_index },
-   { 29190, LockArraysEXT_remap_index },
-   { 13364, UnlockArraysEXT_remap_index },
-   {  7898, CullParameterdvEXT_remap_index },
-   { 10513, CullParameterfvEXT_remap_index },
+   {  7010, PointParameterfvEXT_remap_index },
+   { 29514, LockArraysEXT_remap_index },
+   { 13609, UnlockArraysEXT_remap_index },
+   {  8017, CullParameterdvEXT_remap_index },
+   { 10660, CullParameterfvEXT_remap_index },
    {  1151, SecondaryColor3bEXT_remap_index },
-   {  7050, SecondaryColor3bvEXT_remap_index },
-   {  9322, SecondaryColor3dEXT_remap_index },
-   { 23271, SecondaryColor3dvEXT_remap_index },
-   { 25544, SecondaryColor3fEXT_remap_index },
-   { 16444, SecondaryColor3fvEXT_remap_index },
+   {  7169, SecondaryColor3bvEXT_remap_index },
+   {  9469, SecondaryColor3dEXT_remap_index },
+   { 23524, SecondaryColor3dvEXT_remap_index },
+   { 25827, SecondaryColor3fEXT_remap_index },
+   { 16689, SecondaryColor3fvEXT_remap_index },
    {   426, SecondaryColor3iEXT_remap_index },
-   { 14653, SecondaryColor3ivEXT_remap_index },
-   {  8980, SecondaryColor3sEXT_remap_index },
-   { 28017, SecondaryColor3svEXT_remap_index },
-   { 24717, SecondaryColor3ubEXT_remap_index },
-   { 19262, SecondaryColor3ubvEXT_remap_index },
-   { 11619, SecondaryColor3uiEXT_remap_index },
-   { 20738, SecondaryColor3uivEXT_remap_index },
-   { 23483, SecondaryColor3usEXT_remap_index },
-   { 11692, SecondaryColor3usvEXT_remap_index },
-   { 10589, SecondaryColorPointerEXT_remap_index },
-   { 23332, MultiDrawArraysEXT_remap_index },
-   { 18952, MultiDrawElementsEXT_remap_index },
-   { 19147, FogCoordPointerEXT_remap_index },
+   { 14898, SecondaryColor3ivEXT_remap_index },
+   {  9127, SecondaryColor3sEXT_remap_index },
+   { 28302, SecondaryColor3svEXT_remap_index },
+   { 25000, SecondaryColor3ubEXT_remap_index },
+   { 19507, SecondaryColor3ubvEXT_remap_index },
+   { 11763, SecondaryColor3uiEXT_remap_index },
+   { 21008, SecondaryColor3uivEXT_remap_index },
+   { 23771, SecondaryColor3usEXT_remap_index },
+   { 11836, SecondaryColor3usvEXT_remap_index },
+   { 10736, SecondaryColorPointerEXT_remap_index },
+   { 23585, MultiDrawArraysEXT_remap_index },
+   { 19197, MultiDrawElementsEXT_remap_index },
+   { 19392, FogCoordPointerEXT_remap_index },
    {  4044, FogCoorddEXT_remap_index },
-   { 28591, FogCoorddvEXT_remap_index },
+   { 28915, FogCoorddvEXT_remap_index },
    {  4136, FogCoordfEXT_remap_index },
-   { 24640, FogCoordfvEXT_remap_index },
-   { 17203, PixelTexGenSGIX_remap_index },
-   { 25225, BlendFuncSeparateEXT_remap_index },
-   {  5958, FlushVertexArrayRangeNV_remap_index },
-   {  4660, VertexArrayRangeNV_remap_index },
-   { 25609, CombinerInputNV_remap_index },
+   { 24923, FogCoordfvEXT_remap_index },
+   { 17448, PixelTexGenSGIX_remap_index },
+   { 25508, BlendFuncSeparateEXT_remap_index },
+   {  6071, FlushVertexArrayRangeNV_remap_index },
+   {  4688, VertexArrayRangeNV_remap_index },
+   { 25892, CombinerInputNV_remap_index },
    {  1946, CombinerOutputNV_remap_index },
-   { 28170, CombinerParameterfNV_remap_index },
-   {  4580, CombinerParameterfvNV_remap_index },
-   { 20257, CombinerParameteriNV_remap_index },
-   { 29561, CombinerParameterivNV_remap_index },
-   {  6328, FinalCombinerInputNV_remap_index },
-   {  8809, GetCombinerInputParameterfvNV_remap_index },
-   { 29398, GetCombinerInputParameterivNV_remap_index },
-   {  6127, GetCombinerOutputParameterfvNV_remap_index },
-   { 12346, GetCombinerOutputParameterivNV_remap_index },
-   {  5703, GetFinalCombinerInputParameterfvNV_remap_index },
-   { 22537, GetFinalCombinerInputParameterivNV_remap_index },
-   { 11364, ResizeBuffersMESA_remap_index },
-   {  9962, WindowPos2dMESA_remap_index },
+   { 28455, CombinerParameterfNV_remap_index },
+   {  4608, CombinerParameterfvNV_remap_index },
+   { 20527, CombinerParameteriNV_remap_index },
+   { 29885, CombinerParameterivNV_remap_index },
+   {  6447, FinalCombinerInputNV_remap_index },
+   {  8956, GetCombinerInputParameterfvNV_remap_index },
+   { 29722, GetCombinerInputParameterivNV_remap_index },
+   { 12692, GetCombinerOutputParameterfvNV_remap_index },
+   { 12520, GetCombinerOutputParameterivNV_remap_index },
+   {  5816, GetFinalCombinerInputParameterfvNV_remap_index },
+   { 22790, GetFinalCombinerInputParameterivNV_remap_index },
+   { 11508, ResizeBuffersMESA_remap_index },
+   { 10109, WindowPos2dMESA_remap_index },
    {   944, WindowPos2dvMESA_remap_index },
-   { 30389, WindowPos2fMESA_remap_index },
-   {  6995, WindowPos2fvMESA_remap_index },
-   { 16391, WindowPos2iMESA_remap_index },
-   { 18437, WindowPos2ivMESA_remap_index },
-   { 19051, WindowPos2sMESA_remap_index },
-   {  4946, WindowPos2svMESA_remap_index },
-   {  6820, WindowPos3dMESA_remap_index },
-   { 12593, WindowPos3dvMESA_remap_index },
+   { 30713, WindowPos2fMESA_remap_index },
+   {  7114, WindowPos2fvMESA_remap_index },
+   { 16636, WindowPos2iMESA_remap_index },
+   { 18682, WindowPos2ivMESA_remap_index },
+   { 19296, WindowPos2sMESA_remap_index },
+   {  5031, WindowPos2svMESA_remap_index },
+   {  6939, WindowPos3dMESA_remap_index },
+   { 12838, WindowPos3dvMESA_remap_index },
    {   472, WindowPos3fMESA_remap_index },
-   { 13425, WindowPos3fvMESA_remap_index },
-   { 21832, WindowPos3iMESA_remap_index },
-   { 27483, WindowPos3ivMESA_remap_index },
-   { 16909, WindowPos3sMESA_remap_index },
-   { 28847, WindowPos3svMESA_remap_index },
-   {  9913, WindowPos4dMESA_remap_index },
-   { 15356, WindowPos4dvMESA_remap_index },
-   { 12552, WindowPos4fMESA_remap_index },
-   { 27924, WindowPos4fvMESA_remap_index },
-   { 27636, WindowPos4iMESA_remap_index },
-   { 11203, WindowPos4ivMESA_remap_index },
-   { 17082, WindowPos4sMESA_remap_index },
+   { 13670, WindowPos3fvMESA_remap_index },
+   { 22102, WindowPos3iMESA_remap_index },
+   { 27768, WindowPos3ivMESA_remap_index },
+   { 17154, WindowPos3sMESA_remap_index },
+   { 29171, WindowPos3svMESA_remap_index },
+   { 10060, WindowPos4dMESA_remap_index },
+   { 15601, WindowPos4dvMESA_remap_index },
+   { 12797, WindowPos4fMESA_remap_index },
+   { 28209, WindowPos4fvMESA_remap_index },
+   { 27921, WindowPos4iMESA_remap_index },
+   { 11311, WindowPos4ivMESA_remap_index },
+   { 17327, WindowPos4sMESA_remap_index },
    {  2857, WindowPos4svMESA_remap_index },
-   { 24383, MultiModeDrawArraysIBM_remap_index },
-   { 26356, MultiModeDrawElementsIBM_remap_index },
-   { 10968, DeleteFencesNV_remap_index },
-   { 25456, FinishFenceNV_remap_index },
+   { 12559, MultiModeDrawArraysIBM_remap_index },
+   { 26641, MultiModeDrawElementsIBM_remap_index },
+   { 11115, DeleteFencesNV_remap_index },
+   { 25739, FinishFenceNV_remap_index },
    {  3287, GenFencesNV_remap_index },
-   { 15336, GetFenceivNV_remap_index },
-   {  7287, IsFenceNV_remap_index },
-   { 12273, SetFenceNV_remap_index },
+   { 15581, GetFenceivNV_remap_index },
+   {  7406, IsFenceNV_remap_index },
+   { 12447, SetFenceNV_remap_index },
    {  3744, TestFenceNV_remap_index },
-   { 28818, AreProgramsResidentNV_remap_index },
-   { 28212, BindProgramNV_remap_index },
-   { 23566, DeleteProgramsNV_remap_index },
-   { 19480, ExecuteProgramNV_remap_index },
-   { 30282, GenProgramsNV_remap_index },
-   { 21197, GetProgramParameterdvNV_remap_index },
-   {  9384, GetProgramParameterfvNV_remap_index },
-   { 23922, GetProgramStringNV_remap_index },
-   { 22226, GetProgramivNV_remap_index },
-   { 21431, GetTrackMatrixivNV_remap_index },
-   { 23716, GetVertexAttribPointervNV_remap_index },
-   { 22470, GetVertexAttribdvNV_remap_index },
-   {  8307, GetVertexAttribfvNV_remap_index },
-   { 16572, GetVertexAttribivNV_remap_index },
-   { 17329, IsProgramNV_remap_index },
-   {  8390, LoadProgramNV_remap_index },
-   { 25321, ProgramParameters4dvNV_remap_index },
-   { 22156, ProgramParameters4fvNV_remap_index },
-   { 18741, RequestResidentProgramsNV_remap_index },
-   { 20235, TrackMatrixNV_remap_index },
-   { 29375, VertexAttrib1dNV_remap_index },
-   { 12214, VertexAttrib1dvNV_remap_index },
-   { 25888, VertexAttrib1fNV_remap_index },
+   { 29142, AreProgramsResidentNV_remap_index },
+   { 28497, BindProgramNV_remap_index },
+   { 23854, DeleteProgramsNV_remap_index },
+   { 19725, ExecuteProgramNV_remap_index },
+   { 30606, GenProgramsNV_remap_index },
+   { 21467, GetProgramParameterdvNV_remap_index },
+   {  9531, GetProgramParameterfvNV_remap_index },
+   { 24237, GetProgramStringNV_remap_index },
+   { 22479, GetProgramivNV_remap_index },
+   { 21701, GetTrackMatrixivNV_remap_index },
+   { 24031, GetVertexAttribPointervNV_remap_index },
+   { 22723, GetVertexAttribdvNV_remap_index },
+   {  8426, GetVertexAttribfvNV_remap_index },
+   { 16817, GetVertexAttribivNV_remap_index },
+   { 17574, IsProgramNV_remap_index },
+   {  8509, LoadProgramNV_remap_index },
+   { 25604, ProgramParameters4dvNV_remap_index },
+   { 22409, ProgramParameters4fvNV_remap_index },
+   { 18986, RequestResidentProgramsNV_remap_index },
+   { 20505, TrackMatrixNV_remap_index },
+   { 29699, VertexAttrib1dNV_remap_index },
+   { 12358, VertexAttrib1dvNV_remap_index },
+   { 26173, VertexAttrib1fNV_remap_index },
    {  2245, VertexAttrib1fvNV_remap_index },
-   { 27981, VertexAttrib1sNV_remap_index },
-   { 13498, VertexAttrib1svNV_remap_index },
+   { 28266, VertexAttrib1sNV_remap_index },
+   { 13743, VertexAttrib1svNV_remap_index },
    {  4251, VertexAttrib2dNV_remap_index },
-   { 12129, VertexAttrib2dvNV_remap_index },
-   { 18196, VertexAttrib2fNV_remap_index },
-   { 11740, VertexAttrib2fvNV_remap_index },
-   {  5106, VertexAttrib2sNV_remap_index },
-   { 16963, VertexAttrib2svNV_remap_index },
-   { 10110, VertexAttrib3dNV_remap_index },
-   { 29068, VertexAttrib3dvNV_remap_index },
-   {  9196, VertexAttrib3fNV_remap_index },
-   { 22497, VertexAttrib3fvNV_remap_index },
-   { 25863, VertexAttrib3sNV_remap_index },
-   { 21458, VertexAttrib3svNV_remap_index },
-   { 26330, VertexAttrib4dNV_remap_index },
-   { 30319, VertexAttrib4dvNV_remap_index },
+   { 12273, VertexAttrib2dvNV_remap_index },
+   { 18441, VertexAttrib2fNV_remap_index },
+   { 11884, VertexAttrib2fvNV_remap_index },
+   {  5191, VertexAttrib2sNV_remap_index },
+   { 17208, VertexAttrib2svNV_remap_index },
+   { 10257, VertexAttrib3dNV_remap_index },
+   { 29392, VertexAttrib3dvNV_remap_index },
+   {  9343, VertexAttrib3fNV_remap_index },
+   { 22750, VertexAttrib3fvNV_remap_index },
+   { 20382, VertexAttrib3sNV_remap_index },
+   { 21728, VertexAttrib3svNV_remap_index },
+   { 26615, VertexAttrib4dNV_remap_index },
+   { 30643, VertexAttrib4dvNV_remap_index },
    {  3945, VertexAttrib4fNV_remap_index },
-   {  8440, VertexAttrib4fvNV_remap_index },
-   { 24267, VertexAttrib4sNV_remap_index },
+   {  8559, VertexAttrib4fvNV_remap_index },
+   { 24582, VertexAttrib4sNV_remap_index },
    {  1293, VertexAttrib4svNV_remap_index },
    {  4409, VertexAttrib4ubNV_remap_index },
    {   734, VertexAttrib4ubvNV_remap_index },
-   { 19660, VertexAttribPointerNV_remap_index },
+   { 19905, VertexAttribPointerNV_remap_index },
    {  2097, VertexAttribs1dvNV_remap_index },
-   { 23804, VertexAttribs1fvNV_remap_index },
-   { 30119, VertexAttribs1svNV_remap_index },
-   {  9221, VertexAttribs2dvNV_remap_index },
-   { 23059, VertexAttribs2fvNV_remap_index },
-   { 15904, VertexAttribs2svNV_remap_index },
-   {  4608, VertexAttribs3dvNV_remap_index },
+   { 24119, VertexAttribs1fvNV_remap_index },
+   { 30443, VertexAttribs1svNV_remap_index },
+   {  9368, VertexAttribs2dvNV_remap_index },
+   { 23312, VertexAttribs2fvNV_remap_index },
+   { 16149, VertexAttribs2svNV_remap_index },
+   {  4636, VertexAttribs3dvNV_remap_index },
    {  1977, VertexAttribs3fvNV_remap_index },
-   { 27231, VertexAttribs3svNV_remap_index },
-   { 24357, VertexAttribs4dvNV_remap_index },
-   {  4634, VertexAttribs4fvNV_remap_index },
-   { 29906, VertexAttribs4svNV_remap_index },
-   { 26979, VertexAttribs4ubvNV_remap_index },
-   { 24459, GetTexBumpParameterfvATI_remap_index },
-   { 30160, GetTexBumpParameterivATI_remap_index },
-   { 16626, TexBumpParameterfvATI_remap_index },
-   { 18612, TexBumpParameterivATI_remap_index },
-   { 14044, AlphaFragmentOp1ATI_remap_index },
-   {  9772, AlphaFragmentOp2ATI_remap_index },
-   { 22413, AlphaFragmentOp3ATI_remap_index },
-   { 27158, BeginFragmentShaderATI_remap_index },
-   { 28411, BindFragmentShaderATI_remap_index },
-   { 21587, ColorFragmentOp1ATI_remap_index },
+   { 27516, VertexAttribs3svNV_remap_index },
+   { 24672, VertexAttribs4dvNV_remap_index },
+   {  4662, VertexAttribs4fvNV_remap_index },
+   { 30230, VertexAttribs4svNV_remap_index },
+   { 27264, VertexAttribs4ubvNV_remap_index },
+   { 24742, GetTexBumpParameterfvATI_remap_index },
+   { 30484, GetTexBumpParameterivATI_remap_index },
+   { 16871, TexBumpParameterfvATI_remap_index },
+   { 18857, TexBumpParameterivATI_remap_index },
+   { 14289, AlphaFragmentOp1ATI_remap_index },
+   {  9919, AlphaFragmentOp2ATI_remap_index },
+   { 22666, AlphaFragmentOp3ATI_remap_index },
+   { 27443, BeginFragmentShaderATI_remap_index },
+   { 28696, BindFragmentShaderATI_remap_index },
+   { 21857, ColorFragmentOp1ATI_remap_index },
    {  3823, ColorFragmentOp2ATI_remap_index },
-   { 28713, ColorFragmentOp3ATI_remap_index },
-   {  4753, DeleteFragmentShaderATI_remap_index },
-   { 30343, EndFragmentShaderATI_remap_index },
-   { 29589, GenFragmentShadersATI_remap_index },
-   { 23190, PassTexCoordATI_remap_index },
-   {  6026, SampleMapATI_remap_index },
-   {  5799, SetFragmentShaderConstantATI_remap_index },
+   { 29037, ColorFragmentOp3ATI_remap_index },
+   {  4781, DeleteFragmentShaderATI_remap_index },
+   { 30667, EndFragmentShaderATI_remap_index },
+   { 29913, GenFragmentShadersATI_remap_index },
+   { 23443, PassTexCoordATI_remap_index },
+   {  6139, SampleMapATI_remap_index },
+   {  5912, SetFragmentShaderConstantATI_remap_index },
    {   319, PointParameteriNV_remap_index },
-   { 12754, PointParameterivNV_remap_index },
-   { 26169, ActiveStencilFaceEXT_remap_index },
-   { 24981, BindVertexArrayAPPLE_remap_index },
+   { 12999, PointParameterivNV_remap_index },
+   { 26454, ActiveStencilFaceEXT_remap_index },
+   { 25264, BindVertexArrayAPPLE_remap_index },
    {  2522, DeleteVertexArraysAPPLE_remap_index },
-   { 16243, GenVertexArraysAPPLE_remap_index },
-   { 21262, IsVertexArrayAPPLE_remap_index },
+   { 16488, GenVertexArraysAPPLE_remap_index },
+   { 21532, IsVertexArrayAPPLE_remap_index },
    {   775, GetProgramNamedParameterdvNV_remap_index },
    {  3128, GetProgramNamedParameterfvNV_remap_index },
-   { 24490, ProgramNamedParameter4dNV_remap_index },
-   { 13080, ProgramNamedParameter4dvNV_remap_index },
-   {  7923, ProgramNamedParameter4fNV_remap_index },
-   { 10554, ProgramNamedParameter4fvNV_remap_index },
-   { 22135, DepthBoundsEXT_remap_index },
+   { 24773, ProgramNamedParameter4dNV_remap_index },
+   { 13325, ProgramNamedParameter4dvNV_remap_index },
+   {  8042, ProgramNamedParameter4fNV_remap_index },
+   { 10701, ProgramNamedParameter4fvNV_remap_index },
+   { 22388, DepthBoundsEXT_remap_index },
    {  1043, BlendEquationSeparateEXT_remap_index },
-   { 13199, BindFramebufferEXT_remap_index },
-   { 23377, BindRenderbufferEXT_remap_index },
-   {  8659, CheckFramebufferStatusEXT_remap_index },
-   { 20552, DeleteFramebuffersEXT_remap_index },
-   { 28970, DeleteRenderbuffersEXT_remap_index },
-   { 12153, FramebufferRenderbufferEXT_remap_index },
-   { 12290, FramebufferTexture1DEXT_remap_index },
-   { 10348, FramebufferTexture2DEXT_remap_index },
-   { 10015, FramebufferTexture3DEXT_remap_index },
-   { 21154, GenFramebuffersEXT_remap_index },
-   { 15790, GenRenderbuffersEXT_remap_index },
-   {  5745, GenerateMipmapEXT_remap_index },
-   { 19757, GetFramebufferAttachmentParameterivEXT_remap_index },
-   { 29495, GetRenderbufferParameterivEXT_remap_index },
-   { 18492, IsFramebufferEXT_remap_index },
-   { 30242, IsRenderbufferEXT_remap_index },
-   {  7234, RenderbufferStorageEXT_remap_index },
+   { 13444, BindFramebufferEXT_remap_index },
+   { 23630, BindRenderbufferEXT_remap_index },
+   {  8806, CheckFramebufferStatusEXT_remap_index },
+   { 20822, DeleteFramebuffersEXT_remap_index },
+   { 29294, DeleteRenderbuffersEXT_remap_index },
+   { 12297, FramebufferRenderbufferEXT_remap_index },
+   { 12464, FramebufferTexture1DEXT_remap_index },
+   { 10495, FramebufferTexture2DEXT_remap_index },
+   { 10162, FramebufferTexture3DEXT_remap_index },
+   { 21424, GenFramebuffersEXT_remap_index },
+   { 16035, GenRenderbuffersEXT_remap_index },
+   {  5858, GenerateMipmapEXT_remap_index },
+   { 20002, GetFramebufferAttachmentParameterivEXT_remap_index },
+   { 29819, GetRenderbufferParameterivEXT_remap_index },
+   { 18737, IsFramebufferEXT_remap_index },
+   { 30566, IsRenderbufferEXT_remap_index },
+   {  7353, RenderbufferStorageEXT_remap_index },
    {   651, BlitFramebufferEXT_remap_index },
-   { 12899, BufferParameteriAPPLE_remap_index },
-   { 17361, FlushMappedBufferRangeAPPLE_remap_index },
+   { 13144, BufferParameteriAPPLE_remap_index },
+   { 17606, FlushMappedBufferRangeAPPLE_remap_index },
    {  2701, FramebufferTextureLayerEXT_remap_index },
-   { 25678, ColorMaskIndexedEXT_remap_index },
-   { 16987, DisableIndexedEXT_remap_index },
-   { 24114, EnableIndexedEXT_remap_index },
-   { 19728, GetBooleanIndexedvEXT_remap_index },
-   {  9805, GetIntegerIndexedvEXT_remap_index },
-   { 20628, IsEnabledIndexedEXT_remap_index },
+   {  4956, ColorMaskIndexedEXT_remap_index },
+   { 17232, DisableIndexedEXT_remap_index },
+   { 24429, EnableIndexedEXT_remap_index },
+   { 19973, GetBooleanIndexedvEXT_remap_index },
+   {  9952, GetIntegerIndexedvEXT_remap_index },
+   { 20898, IsEnabledIndexedEXT_remap_index },
    {  4074, BeginConditionalRenderNV_remap_index },
-   { 23163, EndConditionalRenderNV_remap_index },
-   {  8334, BeginTransformFeedbackEXT_remap_index },
-   { 17011, BindBufferBaseEXT_remap_index },
-   { 16881, BindBufferOffsetEXT_remap_index },
-   { 11028, BindBufferRangeEXT_remap_index },
-   { 12814, EndTransformFeedbackEXT_remap_index },
-   {  9657, GetTransformFeedbackVaryingEXT_remap_index },
-   { 18797, TransformFeedbackVaryingsEXT_remap_index },
-   { 26880, ProvokingVertexEXT_remap_index },
-   {  9605, GetTexParameterPointervAPPLE_remap_index },
+   { 23416, EndConditionalRenderNV_remap_index },
+   {  8453, BeginTransformFeedbackEXT_remap_index },
+   { 17256, BindBufferBaseEXT_remap_index },
+   { 17126, BindBufferOffsetEXT_remap_index },
+   { 11136, BindBufferRangeEXT_remap_index },
+   { 13059, EndTransformFeedbackEXT_remap_index },
+   {  9804, GetTransformFeedbackVaryingEXT_remap_index },
+   { 19042, TransformFeedbackVaryingsEXT_remap_index },
+   { 27165, ProvokingVertexEXT_remap_index },
+   {  9752, GetTexParameterPointervAPPLE_remap_index },
    {  4436, TextureRangeAPPLE_remap_index },
-   { 10420, GetObjectParameterivAPPLE_remap_index },
-   { 17936, ObjectPurgeableAPPLE_remap_index },
-   {  4900, ObjectUnpurgeableAPPLE_remap_index },
-   { 26195, StencilFuncSeparateATI_remap_index },
-   { 16310, ProgramEnvParameters4fvEXT_remap_index },
-   { 19691, ProgramLocalParameters4fvEXT_remap_index },
-   { 12682, GetQueryObjecti64vEXT_remap_index },
-   {  9247, GetQueryObjectui64vEXT_remap_index },
-   { 21656, EGLImageTargetRenderbufferStorageOES_remap_index },
-   { 10907, EGLImageTargetTexture2DOES_remap_index },
+   { 10567, GetObjectParameterivAPPLE_remap_index },
+   { 18181, ObjectPurgeableAPPLE_remap_index },
+   {  4985, ObjectUnpurgeableAPPLE_remap_index },
+   { 26480, StencilFuncSeparateATI_remap_index },
+   { 16555, ProgramEnvParameters4fvEXT_remap_index },
+   { 19936, ProgramLocalParameters4fvEXT_remap_index },
+   { 12927, GetQueryObjecti64vEXT_remap_index },
+   {  9394, GetQueryObjectui64vEXT_remap_index },
+   { 21926, EGLImageTargetRenderbufferStorageOES_remap_index },
+   { 11054, EGLImageTargetTexture2DOES_remap_index },
    {    -1, -1 }
 };
 
@@ -4841,108 +4895,108 @@ static const struct gl_function_remap MESA_alt_functions[] = {
    /* from GL_EXT_blend_color */
    {  2440, _gloffset_BlendColor },
    /* from GL_EXT_blend_minmax */
-   { 10072, _gloffset_BlendEquation },
+   { 10219, _gloffset_BlendEquation },
    /* from GL_EXT_color_subtable */
-   { 15378, _gloffset_ColorSubTable },
-   { 28902, _gloffset_CopyColorSubTable },
+   { 15623, _gloffset_ColorSubTable },
+   { 29226, _gloffset_CopyColorSubTable },
    /* from GL_EXT_convolution */
    {   213, _gloffset_ConvolutionFilter1D },
    {  2284, _gloffset_CopyConvolutionFilter1D },
    {  3624, _gloffset_GetConvolutionParameteriv },
-   {  7583, _gloffset_ConvolutionFilter2D },
-   {  7749, _gloffset_ConvolutionParameteriv },
-   {  8209, _gloffset_ConvolutionParameterfv },
-   { 18640, _gloffset_GetSeparableFilter },
-   { 21886, _gloffset_SeparableFilter2D },
-   { 22715, _gloffset_ConvolutionParameteri },
-   { 22838, _gloffset_ConvolutionParameterf },
-   { 24293, _gloffset_GetConvolutionParameterfv },
-   { 25147, _gloffset_GetConvolutionFilter },
-   { 27420, _gloffset_CopyConvolutionFilter2D },
+   {  7702, _gloffset_ConvolutionFilter2D },
+   {  7868, _gloffset_ConvolutionParameteriv },
+   {  8328, _gloffset_ConvolutionParameterfv },
+   { 18885, _gloffset_GetSeparableFilter },
+   { 22156, _gloffset_SeparableFilter2D },
+   { 22968, _gloffset_ConvolutionParameteri },
+   { 23091, _gloffset_ConvolutionParameterf },
+   { 24608, _gloffset_GetConvolutionParameterfv },
+   { 25430, _gloffset_GetConvolutionFilter },
+   { 27705, _gloffset_CopyConvolutionFilter2D },
    /* from GL_EXT_copy_texture */
-   { 13558, _gloffset_CopyTexSubImage3D },
-   { 15118, _gloffset_CopyTexImage2D },
-   { 22323, _gloffset_CopyTexImage1D },
-   { 24828, _gloffset_CopyTexSubImage2D },
-   { 27058, _gloffset_CopyTexSubImage1D },
+   { 13803, _gloffset_CopyTexSubImage3D },
+   { 15363, _gloffset_CopyTexImage2D },
+   { 22576, _gloffset_CopyTexImage1D },
+   { 25111, _gloffset_CopyTexSubImage2D },
+   { 27343, _gloffset_CopyTexSubImage1D },
    /* from GL_EXT_draw_range_elements */
-   {  8546, _gloffset_DrawRangeElements },
+   {  8665, _gloffset_DrawRangeElements },
    /* from GL_EXT_histogram */
    {   812, _gloffset_Histogram },
    {  3088, _gloffset_ResetHistogram },
-   {  8918, _gloffset_GetMinmax },
-   { 13892, _gloffset_GetHistogramParameterfv },
-   { 22248, _gloffset_GetMinmaxParameteriv },
-   { 24183, _gloffset_ResetMinmax },
-   { 25044, _gloffset_GetHistogramParameteriv },
-   { 26129, _gloffset_GetHistogram },
-   { 28527, _gloffset_Minmax },
-   { 29989, _gloffset_GetMinmaxParameterfv },
+   {  9065, _gloffset_GetMinmax },
+   { 14137, _gloffset_GetHistogramParameterfv },
+   { 22501, _gloffset_GetMinmaxParameteriv },
+   { 24498, _gloffset_ResetMinmax },
+   { 25327, _gloffset_GetHistogramParameteriv },
+   { 26414, _gloffset_GetHistogram },
+   { 28812, _gloffset_Minmax },
+   { 30313, _gloffset_GetMinmaxParameterfv },
    /* from GL_EXT_paletted_texture */
-   {  7445, _gloffset_ColorTable },
-   { 13738, _gloffset_GetColorTable },
-   { 20901, _gloffset_GetColorTableParameterfv },
-   { 22894, _gloffset_GetColorTableParameteriv },
+   {  7564, _gloffset_ColorTable },
+   { 13983, _gloffset_GetColorTable },
+   { 21171, _gloffset_GetColorTableParameterfv },
+   { 23147, _gloffset_GetColorTableParameteriv },
    /* from GL_EXT_subtexture */
-   {  6166, _gloffset_TexSubImage1D },
-   {  9532, _gloffset_TexSubImage2D },
+   {  6285, _gloffset_TexSubImage1D },
+   {  9679, _gloffset_TexSubImage2D },
    /* from GL_EXT_texture3D */
    {  1658, _gloffset_TexImage3D },
-   { 20670, _gloffset_TexSubImage3D },
+   { 20940, _gloffset_TexSubImage3D },
    /* from GL_EXT_texture_object */
    {  2964, _gloffset_PrioritizeTextures },
-   {  6615, _gloffset_AreTexturesResident },
-   { 12238, _gloffset_GenTextures },
-   { 14224, _gloffset_DeleteTextures },
-   { 17642, _gloffset_IsTexture },
-   { 27123, _gloffset_BindTexture },
+   {  6734, _gloffset_AreTexturesResident },
+   { 12382, _gloffset_GenTextures },
+   { 14469, _gloffset_DeleteTextures },
+   { 17887, _gloffset_IsTexture },
+   { 27408, _gloffset_BindTexture },
    /* from GL_EXT_vertex_array */
-   { 22075, _gloffset_ArrayElement },
-   { 28115, _gloffset_GetPointerv },
-   { 29616, _gloffset_DrawArrays },
+   { 22328, _gloffset_ArrayElement },
+   { 28400, _gloffset_GetPointerv },
+   { 29940, _gloffset_DrawArrays },
    /* from GL_SGI_color_table */
-   {  6733, _gloffset_ColorTableParameteriv },
-   {  7445, _gloffset_ColorTable },
-   { 13738, _gloffset_GetColorTable },
-   { 13848, _gloffset_CopyColorTable },
-   { 17503, _gloffset_ColorTableParameterfv },
-   { 20901, _gloffset_GetColorTableParameterfv },
-   { 22894, _gloffset_GetColorTableParameteriv },
+   {  6852, _gloffset_ColorTableParameteriv },
+   {  7564, _gloffset_ColorTable },
+   { 13983, _gloffset_GetColorTable },
+   { 14093, _gloffset_CopyColorTable },
+   { 17748, _gloffset_ColorTableParameterfv },
+   { 21171, _gloffset_GetColorTableParameterfv },
+   { 23147, _gloffset_GetColorTableParameteriv },
    /* from GL_VERSION_1_3 */
    {   381, _gloffset_MultiTexCoord3sARB },
    {   613, _gloffset_ActiveTextureARB },
    {  3761, _gloffset_MultiTexCoord1fvARB },
-   {  5301, _gloffset_MultiTexCoord3dARB },
-   {  5346, _gloffset_MultiTexCoord2iARB },
-   {  5470, _gloffset_MultiTexCoord2svARB },
-   {  7401, _gloffset_MultiTexCoord2fARB },
-   {  9277, _gloffset_MultiTexCoord3fvARB },
-   {  9834, _gloffset_MultiTexCoord4sARB },
-   { 10468, _gloffset_MultiTexCoord2dvARB },
-   { 10850, _gloffset_MultiTexCoord1svARB },
-   { 11225, _gloffset_MultiTexCoord3svARB },
-   { 11286, _gloffset_MultiTexCoord4iARB },
-   { 12009, _gloffset_MultiTexCoord3iARB },
-   { 12711, _gloffset_MultiTexCoord1dARB },
-   { 12928, _gloffset_MultiTexCoord3dvARB },
-   { 14092, _gloffset_MultiTexCoord3ivARB },
-   { 14137, _gloffset_MultiTexCoord2sARB },
-   { 15435, _gloffset_MultiTexCoord4ivARB },
-   { 17153, _gloffset_ClientActiveTextureARB },
-   { 19436, _gloffset_MultiTexCoord2dARB },
-   { 19877, _gloffset_MultiTexCoord4dvARB },
-   { 20163, _gloffset_MultiTexCoord4fvARB },
-   { 21042, _gloffset_MultiTexCoord3fARB },
-   { 23422, _gloffset_MultiTexCoord4dARB },
-   { 23626, _gloffset_MultiTexCoord1sARB },
-   { 23830, _gloffset_MultiTexCoord1dvARB },
-   { 24672, _gloffset_MultiTexCoord1ivARB },
-   { 24765, _gloffset_MultiTexCoord2ivARB },
-   { 25104, _gloffset_MultiTexCoord1iARB },
-   { 26404, _gloffset_MultiTexCoord4svARB },
-   { 26922, _gloffset_MultiTexCoord1fARB },
-   { 27185, _gloffset_MultiTexCoord4fARB },
-   { 29450, _gloffset_MultiTexCoord2fvARB },
+   {  5386, _gloffset_MultiTexCoord3dARB },
+   {  5431, _gloffset_MultiTexCoord2iARB },
+   {  5555, _gloffset_MultiTexCoord2svARB },
+   {  7520, _gloffset_MultiTexCoord2fARB },
+   {  9424, _gloffset_MultiTexCoord3fvARB },
+   {  9981, _gloffset_MultiTexCoord4sARB },
+   { 10615, _gloffset_MultiTexCoord2dvARB },
+   { 10997, _gloffset_MultiTexCoord1svARB },
+   { 11369, _gloffset_MultiTexCoord3svARB },
+   { 11430, _gloffset_MultiTexCoord4iARB },
+   { 12153, _gloffset_MultiTexCoord3iARB },
+   { 12956, _gloffset_MultiTexCoord1dARB },
+   { 13173, _gloffset_MultiTexCoord3dvARB },
+   { 14337, _gloffset_MultiTexCoord3ivARB },
+   { 14382, _gloffset_MultiTexCoord2sARB },
+   { 15680, _gloffset_MultiTexCoord4ivARB },
+   { 17398, _gloffset_ClientActiveTextureARB },
+   { 19681, _gloffset_MultiTexCoord2dARB },
+   { 20122, _gloffset_MultiTexCoord4dvARB },
+   { 20433, _gloffset_MultiTexCoord4fvARB },
+   { 21312, _gloffset_MultiTexCoord3fARB },
+   { 23675, _gloffset_MultiTexCoord4dARB },
+   { 23941, _gloffset_MultiTexCoord1sARB },
+   { 24145, _gloffset_MultiTexCoord1dvARB },
+   { 24955, _gloffset_MultiTexCoord1ivARB },
+   { 25048, _gloffset_MultiTexCoord2ivARB },
+   { 25387, _gloffset_MultiTexCoord1iARB },
+   { 26689, _gloffset_MultiTexCoord4svARB },
+   { 27207, _gloffset_MultiTexCoord1fARB },
+   { 27470, _gloffset_MultiTexCoord4fARB },
+   { 29774, _gloffset_MultiTexCoord2fvARB },
    {    -1, -1 }
 };
 
@@ -4950,7 +5004,7 @@ static const struct gl_function_remap MESA_alt_functions[] = {
 
 #if defined(need_GL_3DFX_tbuffer)
 static const struct gl_function_remap GL_3DFX_tbuffer_functions[] = {
-   {  8267, -1 }, /* TbufferMask3DFX */
+   {  8386, -1 }, /* TbufferMask3DFX */
    {    -1, -1 }
 };
 #endif
@@ -5018,6 +5072,14 @@ static const struct gl_function_remap GL_ARB_framebuffer_object_functions[] = {
 };
 #endif
 
+#if defined(need_GL_ARB_geometry_shader4)
+/* functions defined in MESA_remap_table_functions are excluded */
+static const struct gl_function_remap GL_ARB_geometry_shader4_functions[] = {
+   { 11333, -1 }, /* FramebufferTextureLayer */
+   {    -1, -1 }
+};
+#endif
+
 #if defined(need_GL_ARB_map_buffer_range)
 /* functions defined in MESA_remap_table_functions are excluded */
 static const struct gl_function_remap GL_ARB_map_buffer_range_functions[] = {
@@ -5028,10 +5090,10 @@ static const struct gl_function_remap GL_ARB_map_buffer_range_functions[] = {
 #if defined(need_GL_ARB_matrix_palette)
 static const struct gl_function_remap GL_ARB_matrix_palette_functions[] = {
    {  3339, -1 }, /* MatrixIndexusvARB */
-   { 11830, -1 }, /* MatrixIndexuivARB */
-   { 13050, -1 }, /* MatrixIndexPointerARB */
-   { 17891, -1 }, /* CurrentPaletteMatrixARB */
-   { 20786, -1 }, /* MatrixIndexubvARB */
+   { 11974, -1 }, /* MatrixIndexuivARB */
+   { 13295, -1 }, /* MatrixIndexPointerARB */
+   { 18136, -1 }, /* CurrentPaletteMatrixARB */
+   { 21056, -1 }, /* MatrixIndexubvARB */
    {    -1, -1 }
 };
 #endif
@@ -5085,6 +5147,13 @@ static const struct gl_function_remap GL_ARB_texture_compression_functions[] = {
 };
 #endif
 
+#if defined(need_GL_ARB_transform_feedback2)
+/* functions defined in MESA_remap_table_functions are excluded */
+static const struct gl_function_remap GL_ARB_transform_feedback2_functions[] = {
+   {    -1, -1 }
+};
+#endif
+
 #if defined(need_GL_ARB_transpose_matrix)
 /* functions defined in MESA_remap_table_functions are excluded */
 static const struct gl_function_remap GL_ARB_transpose_matrix_functions[] = {
@@ -5102,15 +5171,15 @@ static const struct gl_function_remap GL_ARB_vertex_array_object_functions[] = {
 #if defined(need_GL_ARB_vertex_blend)
 static const struct gl_function_remap GL_ARB_vertex_blend_functions[] = {
    {  2226, -1 }, /* WeightubvARB */
-   {  5633, -1 }, /* WeightivARB */
-   {  9937, -1 }, /* WeightPointerARB */
-   { 12468, -1 }, /* WeightfvARB */
-   { 15930, -1 }, /* WeightbvARB */
-   { 19104, -1 }, /* WeightusvARB */
-   { 21812, -1 }, /* VertexBlendARB */
-   { 27006, -1 }, /* WeightsvARB */
-   { 28952, -1 }, /* WeightdvARB */
-   { 29650, -1 }, /* WeightuivARB */
+   {  5746, -1 }, /* WeightivARB */
+   { 10084, -1 }, /* WeightPointerARB */
+   { 12674, -1 }, /* WeightfvARB */
+   { 16175, -1 }, /* WeightbvARB */
+   { 19349, -1 }, /* WeightusvARB */
+   { 22082, -1 }, /* VertexBlendARB */
+   { 27291, -1 }, /* WeightsvARB */
+   { 29276, -1 }, /* WeightdvARB */
+   { 29974, -1 }, /* WeightuivARB */
    {    -1, -1 }
 };
 #endif
@@ -5201,15 +5270,15 @@ static const struct gl_function_remap GL_EXT_blend_func_separate_functions[] = {
 
 #if defined(need_GL_EXT_blend_minmax)
 static const struct gl_function_remap GL_EXT_blend_minmax_functions[] = {
-   { 10072, _gloffset_BlendEquation },
+   { 10219, _gloffset_BlendEquation },
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_EXT_color_subtable)
 static const struct gl_function_remap GL_EXT_color_subtable_functions[] = {
-   { 15378, _gloffset_ColorSubTable },
-   { 28902, _gloffset_CopyColorSubTable },
+   { 15623, _gloffset_ColorSubTable },
+   { 29226, _gloffset_CopyColorSubTable },
    {    -1, -1 }
 };
 #endif
@@ -5226,55 +5295,55 @@ static const struct gl_function_remap GL_EXT_convolution_functions[] = {
    {   213, _gloffset_ConvolutionFilter1D },
    {  2284, _gloffset_CopyConvolutionFilter1D },
    {  3624, _gloffset_GetConvolutionParameteriv },
-   {  7583, _gloffset_ConvolutionFilter2D },
-   {  7749, _gloffset_ConvolutionParameteriv },
-   {  8209, _gloffset_ConvolutionParameterfv },
-   { 18640, _gloffset_GetSeparableFilter },
-   { 21886, _gloffset_SeparableFilter2D },
-   { 22715, _gloffset_ConvolutionParameteri },
-   { 22838, _gloffset_ConvolutionParameterf },
-   { 24293, _gloffset_GetConvolutionParameterfv },
-   { 25147, _gloffset_GetConvolutionFilter },
-   { 27420, _gloffset_CopyConvolutionFilter2D },
+   {  7702, _gloffset_ConvolutionFilter2D },
+   {  7868, _gloffset_ConvolutionParameteriv },
+   {  8328, _gloffset_ConvolutionParameterfv },
+   { 18885, _gloffset_GetSeparableFilter },
+   { 22156, _gloffset_SeparableFilter2D },
+   { 22968, _gloffset_ConvolutionParameteri },
+   { 23091, _gloffset_ConvolutionParameterf },
+   { 24608, _gloffset_GetConvolutionParameterfv },
+   { 25430, _gloffset_GetConvolutionFilter },
+   { 27705, _gloffset_CopyConvolutionFilter2D },
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_EXT_coordinate_frame)
 static const struct gl_function_remap GL_EXT_coordinate_frame_functions[] = {
-   {  9416, -1 }, /* TangentPointerEXT */
-   { 11344, -1 }, /* Binormal3ivEXT */
-   { 11962, -1 }, /* Tangent3sEXT */
-   { 13115, -1 }, /* Tangent3fvEXT */
-   { 16862, -1 }, /* Tangent3dvEXT */
-   { 17589, -1 }, /* Binormal3bvEXT */
-   { 18693, -1 }, /* Binormal3dEXT */
-   { 20718, -1 }, /* Tangent3fEXT */
-   { 22787, -1 }, /* Binormal3sEXT */
-   { 23232, -1 }, /* Tangent3ivEXT */
-   { 23251, -1 }, /* Tangent3dEXT */
-   { 24057, -1 }, /* Binormal3svEXT */
-   { 24570, -1 }, /* Binormal3fEXT */
-   { 25422, -1 }, /* Binormal3dvEXT */
-   { 26626, -1 }, /* Tangent3iEXT */
-   { 27705, -1 }, /* Tangent3bvEXT */
-   { 28150, -1 }, /* Tangent3bEXT */
-   { 28675, -1 }, /* Binormal3fvEXT */
-   { 29349, -1 }, /* BinormalPointerEXT */
-   { 29754, -1 }, /* Tangent3svEXT */
-   { 30191, -1 }, /* Binormal3bEXT */
-   { 30368, -1 }, /* Binormal3iEXT */
+   {  9563, -1 }, /* TangentPointerEXT */
+   { 11488, -1 }, /* Binormal3ivEXT */
+   { 12106, -1 }, /* Tangent3sEXT */
+   { 13360, -1 }, /* Tangent3fvEXT */
+   { 17107, -1 }, /* Tangent3dvEXT */
+   { 17834, -1 }, /* Binormal3bvEXT */
+   { 18938, -1 }, /* Binormal3dEXT */
+   { 20988, -1 }, /* Tangent3fEXT */
+   { 23040, -1 }, /* Binormal3sEXT */
+   { 23485, -1 }, /* Tangent3ivEXT */
+   { 23504, -1 }, /* Tangent3dEXT */
+   { 24372, -1 }, /* Binormal3svEXT */
+   { 24853, -1 }, /* Binormal3fEXT */
+   { 25705, -1 }, /* Binormal3dvEXT */
+   { 26911, -1 }, /* Tangent3iEXT */
+   { 27990, -1 }, /* Tangent3bvEXT */
+   { 28435, -1 }, /* Tangent3bEXT */
+   { 28999, -1 }, /* Binormal3fvEXT */
+   { 29673, -1 }, /* BinormalPointerEXT */
+   { 30078, -1 }, /* Tangent3svEXT */
+   { 30515, -1 }, /* Binormal3bEXT */
+   { 30692, -1 }, /* Binormal3iEXT */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_EXT_copy_texture)
 static const struct gl_function_remap GL_EXT_copy_texture_functions[] = {
-   { 13558, _gloffset_CopyTexSubImage3D },
-   { 15118, _gloffset_CopyTexImage2D },
-   { 22323, _gloffset_CopyTexImage1D },
-   { 24828, _gloffset_CopyTexSubImage2D },
-   { 27058, _gloffset_CopyTexSubImage1D },
+   { 13803, _gloffset_CopyTexSubImage3D },
+   { 15363, _gloffset_CopyTexImage2D },
+   { 22576, _gloffset_CopyTexImage1D },
+   { 25111, _gloffset_CopyTexSubImage2D },
+   { 27343, _gloffset_CopyTexSubImage1D },
    {    -1, -1 }
 };
 #endif
@@ -5309,7 +5378,7 @@ static const struct gl_function_remap GL_EXT_draw_instanced_functions[] = {
 
 #if defined(need_GL_EXT_draw_range_elements)
 static const struct gl_function_remap GL_EXT_draw_range_elements_functions[] = {
-   {  8546, _gloffset_DrawRangeElements },
+   {  8665, _gloffset_DrawRangeElements },
    {    -1, -1 }
 };
 #endif
@@ -5353,37 +5422,37 @@ static const struct gl_function_remap GL_EXT_gpu_program_parameters_functions[]
 static const struct gl_function_remap GL_EXT_histogram_functions[] = {
    {   812, _gloffset_Histogram },
    {  3088, _gloffset_ResetHistogram },
-   {  8918, _gloffset_GetMinmax },
-   { 13892, _gloffset_GetHistogramParameterfv },
-   { 22248, _gloffset_GetMinmaxParameteriv },
-   { 24183, _gloffset_ResetMinmax },
-   { 25044, _gloffset_GetHistogramParameteriv },
-   { 26129, _gloffset_GetHistogram },
-   { 28527, _gloffset_Minmax },
-   { 29989, _gloffset_GetMinmaxParameterfv },
+   {  9065, _gloffset_GetMinmax },
+   { 14137, _gloffset_GetHistogramParameterfv },
+   { 22501, _gloffset_GetMinmaxParameteriv },
+   { 24498, _gloffset_ResetMinmax },
+   { 25327, _gloffset_GetHistogramParameteriv },
+   { 26414, _gloffset_GetHistogram },
+   { 28812, _gloffset_Minmax },
+   { 30313, _gloffset_GetMinmaxParameterfv },
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_EXT_index_func)
 static const struct gl_function_remap GL_EXT_index_func_functions[] = {
-   { 10299, -1 }, /* IndexFuncEXT */
+   { 10446, -1 }, /* IndexFuncEXT */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_EXT_index_material)
 static const struct gl_function_remap GL_EXT_index_material_functions[] = {
-   { 19191, -1 }, /* IndexMaterialEXT */
+   { 19436, -1 }, /* IndexMaterialEXT */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_EXT_light_texture)
 static const struct gl_function_remap GL_EXT_light_texture_functions[] = {
-   { 24077, -1 }, /* ApplyTextureEXT */
-   { 24137, -1 }, /* TextureMaterialEXT */
-   { 24162, -1 }, /* TextureLightEXT */
+   { 24392, -1 }, /* ApplyTextureEXT */
+   { 24452, -1 }, /* TextureMaterialEXT */
+   { 24477, -1 }, /* TextureLightEXT */
    {    -1, -1 }
 };
 #endif
@@ -5404,20 +5473,20 @@ static const struct gl_function_remap GL_EXT_multisample_functions[] = {
 
 #if defined(need_GL_EXT_paletted_texture)
 static const struct gl_function_remap GL_EXT_paletted_texture_functions[] = {
-   {  7445, _gloffset_ColorTable },
-   { 13738, _gloffset_GetColorTable },
-   { 20901, _gloffset_GetColorTableParameterfv },
-   { 22894, _gloffset_GetColorTableParameteriv },
+   {  7564, _gloffset_ColorTable },
+   { 13983, _gloffset_GetColorTable },
+   { 21171, _gloffset_GetColorTableParameterfv },
+   { 23147, _gloffset_GetColorTableParameteriv },
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_EXT_pixel_transform)
 static const struct gl_function_remap GL_EXT_pixel_transform_functions[] = {
-   { 19842, -1 }, /* PixelTransformParameterfEXT */
-   { 19922, -1 }, /* PixelTransformParameteriEXT */
-   { 27888, -1 }, /* PixelTransformParameterfvEXT */
-   { 29313, -1 }, /* PixelTransformParameterivEXT */
+   { 20087, -1 }, /* PixelTransformParameterfEXT */
+   { 20167, -1 }, /* PixelTransformParameteriEXT */
+   { 28173, -1 }, /* PixelTransformParameterfvEXT */
+   { 29637, -1 }, /* PixelTransformParameterivEXT */
    {    -1, -1 }
 };
 #endif
@@ -5459,8 +5528,8 @@ static const struct gl_function_remap GL_EXT_stencil_two_side_functions[] = {
 
 #if defined(need_GL_EXT_subtexture)
 static const struct gl_function_remap GL_EXT_subtexture_functions[] = {
-   {  6166, _gloffset_TexSubImage1D },
-   {  9532, _gloffset_TexSubImage2D },
+   {  6285, _gloffset_TexSubImage1D },
+   {  9679, _gloffset_TexSubImage2D },
    {    -1, -1 }
 };
 #endif
@@ -5468,7 +5537,7 @@ static const struct gl_function_remap GL_EXT_subtexture_functions[] = {
 #if defined(need_GL_EXT_texture3D)
 static const struct gl_function_remap GL_EXT_texture3D_functions[] = {
    {  1658, _gloffset_TexImage3D },
-   { 20670, _gloffset_TexSubImage3D },
+   { 20940, _gloffset_TexSubImage3D },
    {    -1, -1 }
 };
 #endif
@@ -5483,18 +5552,18 @@ static const struct gl_function_remap GL_EXT_texture_array_functions[] = {
 #if defined(need_GL_EXT_texture_object)
 static const struct gl_function_remap GL_EXT_texture_object_functions[] = {
    {  2964, _gloffset_PrioritizeTextures },
-   {  6615, _gloffset_AreTexturesResident },
-   { 12238, _gloffset_GenTextures },
-   { 14224, _gloffset_DeleteTextures },
-   { 17642, _gloffset_IsTexture },
-   { 27123, _gloffset_BindTexture },
+   {  6734, _gloffset_AreTexturesResident },
+   { 12382, _gloffset_GenTextures },
+   { 14469, _gloffset_DeleteTextures },
+   { 17887, _gloffset_IsTexture },
+   { 27408, _gloffset_BindTexture },
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_EXT_texture_perturb_normal)
 static const struct gl_function_remap GL_EXT_texture_perturb_normal_functions[] = {
-   { 12418, -1 }, /* TextureNormalEXT */
+   { 12624, -1 }, /* TextureNormalEXT */
    {    -1, -1 }
 };
 #endif
@@ -5516,18 +5585,18 @@ static const struct gl_function_remap GL_EXT_transform_feedback_functions[] = {
 #if defined(need_GL_EXT_vertex_array)
 /* functions defined in MESA_remap_table_functions are excluded */
 static const struct gl_function_remap GL_EXT_vertex_array_functions[] = {
-   { 22075, _gloffset_ArrayElement },
-   { 28115, _gloffset_GetPointerv },
-   { 29616, _gloffset_DrawArrays },
+   { 22328, _gloffset_ArrayElement },
+   { 28400, _gloffset_GetPointerv },
+   { 29940, _gloffset_DrawArrays },
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_EXT_vertex_weighting)
 static const struct gl_function_remap GL_EXT_vertex_weighting_functions[] = {
-   { 17672, -1 }, /* VertexWeightfvEXT */
-   { 24548, -1 }, /* VertexWeightfEXT */
-   { 26098, -1 }, /* VertexWeightPointerEXT */
+   { 17917, -1 }, /* VertexWeightfvEXT */
+   { 24831, -1 }, /* VertexWeightfEXT */
+   { 26383, -1 }, /* VertexWeightPointerEXT */
    {    -1, -1 }
 };
 #endif
@@ -5536,10 +5605,10 @@ static const struct gl_function_remap GL_EXT_vertex_weighting_functions[] = {
 static const struct gl_function_remap GL_HP_image_transform_functions[] = {
    {  2157, -1 }, /* GetImageTransformParameterfvHP */
    {  3305, -1 }, /* ImageTransformParameterfHP */
-   {  9110, -1 }, /* ImageTransformParameterfvHP */
-   { 10768, -1 }, /* ImageTransformParameteriHP */
-   { 11115, -1 }, /* GetImageTransformParameterivHP */
-   { 17736, -1 }, /* ImageTransformParameterivHP */
+   {  9257, -1 }, /* ImageTransformParameterfvHP */
+   { 10915, -1 }, /* ImageTransformParameteriHP */
+   { 11223, -1 }, /* GetImageTransformParameterivHP */
+   { 17981, -1 }, /* ImageTransformParameterivHP */
    {    -1, -1 }
 };
 #endif
@@ -5554,13 +5623,13 @@ static const struct gl_function_remap GL_IBM_multimode_draw_arrays_functions[] =
 #if defined(need_GL_IBM_vertex_array_lists)
 static const struct gl_function_remap GL_IBM_vertex_array_lists_functions[] = {
    {  3857, -1 }, /* SecondaryColorPointerListIBM */
-   {  5167, -1 }, /* NormalPointerListIBM */
-   {  6789, -1 }, /* FogCoordPointerListIBM */
-   {  7096, -1 }, /* VertexPointerListIBM */
-   { 10689, -1 }, /* ColorPointerListIBM */
-   { 12069, -1 }, /* TexCoordPointerListIBM */
-   { 12440, -1 }, /* IndexPointerListIBM */
-   { 29932, -1 }, /* EdgeFlagPointerListIBM */
+   {  5252, -1 }, /* NormalPointerListIBM */
+   {  6908, -1 }, /* FogCoordPointerListIBM */
+   {  7215, -1 }, /* VertexPointerListIBM */
+   { 10836, -1 }, /* ColorPointerListIBM */
+   { 12213, -1 }, /* TexCoordPointerListIBM */
+   { 12646, -1 }, /* IndexPointerListIBM */
+   { 30256, -1 }, /* EdgeFlagPointerListIBM */
    {    -1, -1 }
 };
 #endif
@@ -5574,10 +5643,10 @@ static const struct gl_function_remap GL_INGR_blend_func_separate_functions[] =
 
 #if defined(need_GL_INTEL_parallel_arrays)
 static const struct gl_function_remap GL_INTEL_parallel_arrays_functions[] = {
-   { 11456, -1 }, /* VertexPointervINTEL */
-   { 13985, -1 }, /* ColorPointervINTEL */
-   { 27394, -1 }, /* NormalPointervINTEL */
-   { 27820, -1 }, /* TexCoordPointervINTEL */
+   { 11600, -1 }, /* VertexPointervINTEL */
+   { 14230, -1 }, /* ColorPointervINTEL */
+   { 27679, -1 }, /* NormalPointervINTEL */
+   { 28105, -1 }, /* TexCoordPointervINTEL */
    {    -1, -1 }
 };
 #endif
@@ -5594,7 +5663,7 @@ static const struct gl_function_remap GL_MESA_shader_debug_functions[] = {
    {  1522, -1 }, /* GetDebugLogLengthMESA */
    {  3063, -1 }, /* ClearDebugLogMESA */
    {  4018, -1 }, /* GetDebugLogMESA */
-   { 28308, -1 }, /* CreateDebugObjectMESA */
+   { 28593, -1 }, /* CreateDebugObjectMESA */
    {    -1, -1 }
 };
 #endif
@@ -5615,15 +5684,15 @@ static const struct gl_function_remap GL_NV_condtitional_render_functions[] = {
 
 #if defined(need_GL_NV_evaluators)
 static const struct gl_function_remap GL_NV_evaluators_functions[] = {
-   {  5834, -1 }, /* GetMapAttribParameterivNV */
-   {  7551, -1 }, /* MapControlPointsNV */
-   {  7650, -1 }, /* MapParameterfvNV */
-   {  9515, -1 }, /* EvalMapsNV */
-   { 15600, -1 }, /* GetMapAttribParameterfvNV */
-   { 15766, -1 }, /* MapParameterivNV */
-   { 22638, -1 }, /* GetMapParameterivNV */
-   { 23136, -1 }, /* GetMapParameterfvNV */
-   { 26730, -1 }, /* GetMapControlPointsNV */
+   {  5947, -1 }, /* GetMapAttribParameterivNV */
+   {  7670, -1 }, /* MapControlPointsNV */
+   {  7769, -1 }, /* MapParameterfvNV */
+   {  9662, -1 }, /* EvalMapsNV */
+   { 15845, -1 }, /* GetMapAttribParameterfvNV */
+   { 16011, -1 }, /* MapParameterivNV */
+   { 22891, -1 }, /* GetMapParameterivNV */
+   { 23389, -1 }, /* GetMapParameterfvNV */
+   { 27015, -1 }, /* GetMapControlPointsNV */
    {    -1, -1 }
 };
 #endif
@@ -5658,8 +5727,8 @@ static const struct gl_function_remap GL_NV_register_combiners_functions[] = {
 
 #if defined(need_GL_NV_register_combiners2)
 static const struct gl_function_remap GL_NV_register_combiners2_functions[] = {
-   { 14455, -1 }, /* CombinerStageParameterfvNV */
-   { 14770, -1 }, /* GetCombinerStageParameterfvNV */
+   { 14700, -1 }, /* CombinerStageParameterfvNV */
+   { 15015, -1 }, /* GetCombinerStageParameterfvNV */
    {    -1, -1 }
 };
 #endif
@@ -5687,23 +5756,23 @@ static const struct gl_function_remap GL_OES_EGL_image_functions[] = {
 
 #if defined(need_GL_PGI_misc_hints)
 static const struct gl_function_remap GL_PGI_misc_hints_functions[] = {
-   {  7735, -1 }, /* HintPGI */
+   {  7854, -1 }, /* HintPGI */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGIS_detail_texture)
 static const struct gl_function_remap GL_SGIS_detail_texture_functions[] = {
-   { 14743, -1 }, /* GetDetailTexFuncSGIS */
-   { 15063, -1 }, /* DetailTexFuncSGIS */
+   { 14988, -1 }, /* GetDetailTexFuncSGIS */
+   { 15308, -1 }, /* DetailTexFuncSGIS */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGIS_fog_function)
 static const struct gl_function_remap GL_SGIS_fog_function_functions[] = {
-   { 24810, -1 }, /* FogFuncSGIS */
-   { 25475, -1 }, /* GetFogFuncSGIS */
+   { 25093, -1 }, /* FogFuncSGIS */
+   { 25758, -1 }, /* GetFogFuncSGIS */
    {    -1, -1 }
 };
 #endif
@@ -5731,8 +5800,8 @@ static const struct gl_function_remap GL_SGIS_point_parameters_functions[] = {
 
 #if defined(need_GL_SGIS_sharpen_texture)
 static const struct gl_function_remap GL_SGIS_sharpen_texture_functions[] = {
-   {  5895, -1 }, /* GetSharpenTexFuncSGIS */
-   { 20137, -1 }, /* SharpenTexFuncSGIS */
+   {  6008, -1 }, /* GetSharpenTexFuncSGIS */
+   { 20407, -1 }, /* SharpenTexFuncSGIS */
    {    -1, -1 }
 };
 #endif
@@ -5740,22 +5809,22 @@ static const struct gl_function_remap GL_SGIS_sharpen_texture_functions[] = {
 #if defined(need_GL_SGIS_texture4D)
 static const struct gl_function_remap GL_SGIS_texture4D_functions[] = {
    {   894, -1 }, /* TexImage4DSGIS */
-   { 14293, -1 }, /* TexSubImage4DSGIS */
+   { 14538, -1 }, /* TexSubImage4DSGIS */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGIS_texture_color_mask)
 static const struct gl_function_remap GL_SGIS_texture_color_mask_functions[] = {
-   { 13691, -1 }, /* TextureColorMaskSGIS */
+   { 13936, -1 }, /* TextureColorMaskSGIS */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGIS_texture_filter4)
 static const struct gl_function_remap GL_SGIS_texture_filter4_functions[] = {
-   {  6072, -1 }, /* GetTexFilterFuncSGIS */
-   { 14889, -1 }, /* TexFilterFuncSGIS */
+   {  6185, -1 }, /* GetTexFilterFuncSGIS */
+   { 15134, -1 }, /* TexFilterFuncSGIS */
    {    -1, -1 }
 };
 #endif
@@ -5764,17 +5833,17 @@ static const struct gl_function_remap GL_SGIS_texture_filter4_functions[] = {
 static const struct gl_function_remap GL_SGIX_async_functions[] = {
    {  3014, -1 }, /* AsyncMarkerSGIX */
    {  3997, -1 }, /* FinishAsyncSGIX */
-   {  4734, -1 }, /* PollAsyncSGIX */
-   { 20284, -1 }, /* DeleteAsyncMarkersSGIX */
-   { 20339, -1 }, /* IsAsyncMarkerSGIX */
-   { 29729, -1 }, /* GenAsyncMarkersSGIX */
+   {  4762, -1 }, /* PollAsyncSGIX */
+   { 20554, -1 }, /* DeleteAsyncMarkersSGIX */
+   { 20609, -1 }, /* IsAsyncMarkerSGIX */
+   { 30053, -1 }, /* GenAsyncMarkersSGIX */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGIX_flush_raster)
 static const struct gl_function_remap GL_SGIX_flush_raster_functions[] = {
-   {  6443, -1 }, /* FlushRasterSGIX */
+   {  6562, -1 }, /* FlushRasterSGIX */
    {    -1, -1 }
 };
 #endif
@@ -5782,37 +5851,37 @@ static const struct gl_function_remap GL_SGIX_flush_raster_functions[] = {
 #if defined(need_GL_SGIX_fragment_lighting)
 static const struct gl_function_remap GL_SGIX_fragment_lighting_functions[] = {
    {  2410, -1 }, /* FragmentMaterialfvSGIX */
-   {  2906, -1 }, /* FragmentLightModelivSGIX */
-   {  4685, -1 }, /* FragmentLightiSGIX */
-   {  5575, -1 }, /* GetFragmentMaterialfvSGIX */
-   {  7163, -1 }, /* FragmentMaterialfSGIX */
-   {  7324, -1 }, /* GetFragmentLightivSGIX */
-   {  8161, -1 }, /* FragmentLightModeliSGIX */
-   {  9578, -1 }, /* FragmentLightivSGIX */
-   {  9880, -1 }, /* GetFragmentMaterialivSGIX */
-   { 17559, -1 }, /* FragmentLightModelfSGIX */
-   { 17859, -1 }, /* FragmentColorMaterialSGIX */
-   { 18259, -1 }, /* FragmentMaterialiSGIX */
-   { 19519, -1 }, /* LightEnviSGIX */
-   { 20993, -1 }, /* FragmentLightModelfvSGIX */
-   { 21302, -1 }, /* FragmentLightfvSGIX */
-   { 25980, -1 }, /* FragmentLightfSGIX */
-   { 28645, -1 }, /* GetFragmentLightfvSGIX */
-   { 30212, -1 }, /* FragmentMaterialivSGIX */
+   {  4713, -1 }, /* FragmentLightiSGIX */
+   {  5688, -1 }, /* GetFragmentMaterialfvSGIX */
+   {  7282, -1 }, /* FragmentMaterialfSGIX */
+   {  7443, -1 }, /* GetFragmentLightivSGIX */
+   {  8280, -1 }, /* FragmentLightModeliSGIX */
+   {  9725, -1 }, /* FragmentLightivSGIX */
+   { 10027, -1 }, /* GetFragmentMaterialivSGIX */
+   { 17804, -1 }, /* FragmentLightModelfSGIX */
+   { 18104, -1 }, /* FragmentColorMaterialSGIX */
+   { 18504, -1 }, /* FragmentMaterialiSGIX */
+   { 19764, -1 }, /* LightEnviSGIX */
+   { 21263, -1 }, /* FragmentLightModelfvSGIX */
+   { 21572, -1 }, /* FragmentLightfvSGIX */
+   { 26142, -1 }, /* FragmentLightModelivSGIX */
+   { 26265, -1 }, /* FragmentLightfSGIX */
+   { 28969, -1 }, /* GetFragmentLightfvSGIX */
+   { 30536, -1 }, /* FragmentMaterialivSGIX */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGIX_framezoom)
 static const struct gl_function_remap GL_SGIX_framezoom_functions[] = {
-   { 20362, -1 }, /* FrameZoomSGIX */
+   { 20632, -1 }, /* FrameZoomSGIX */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGIX_igloo_interface)
 static const struct gl_function_remap GL_SGIX_igloo_interface_functions[] = {
-   { 26288, -1 }, /* IglooInterfaceSGIX */
+   { 26573, -1 }, /* IglooInterfaceSGIX */
    {    -1, -1 }
 };
 #endif
@@ -5820,11 +5889,11 @@ static const struct gl_function_remap GL_SGIX_igloo_interface_functions[] = {
 #if defined(need_GL_SGIX_instruments)
 static const struct gl_function_remap GL_SGIX_instruments_functions[] = {
    {  2573, -1 }, /* ReadInstrumentsSGIX */
-   {  5651, -1 }, /* PollInstrumentsSGIX */
-   {  9476, -1 }, /* GetInstrumentsSGIX */
-   { 11667, -1 }, /* StartInstrumentsSGIX */
-   { 14489, -1 }, /* StopInstrumentsSGIX */
-   { 16143, -1 }, /* InstrumentsBufferSGIX */
+   {  5764, -1 }, /* PollInstrumentsSGIX */
+   {  9623, -1 }, /* GetInstrumentsSGIX */
+   { 11811, -1 }, /* StartInstrumentsSGIX */
+   { 14734, -1 }, /* StopInstrumentsSGIX */
+   { 16388, -1 }, /* InstrumentsBufferSGIX */
    {    -1, -1 }
 };
 #endif
@@ -5833,10 +5902,10 @@ static const struct gl_function_remap GL_SGIX_instruments_functions[] = {
 static const struct gl_function_remap GL_SGIX_list_priority_functions[] = {
    {  1125, -1 }, /* ListParameterfSGIX */
    {  2763, -1 }, /* GetListParameterfvSGIX */
-   { 16058, -1 }, /* ListParameteriSGIX */
-   { 16812, -1 }, /* ListParameterfvSGIX */
-   { 18925, -1 }, /* ListParameterivSGIX */
-   { 29773, -1 }, /* GetListParameterivSGIX */
+   { 16303, -1 }, /* ListParameteriSGIX */
+   { 17057, -1 }, /* ListParameterfvSGIX */
+   { 19170, -1 }, /* ListParameterivSGIX */
+   { 30097, -1 }, /* GetListParameterivSGIX */
    {    -1, -1 }
 };
 #endif
@@ -5851,53 +5920,53 @@ static const struct gl_function_remap GL_SGIX_pixel_texture_functions[] = {
 #if defined(need_GL_SGIX_polynomial_ffd)
 static const struct gl_function_remap GL_SGIX_polynomial_ffd_functions[] = {
    {  3251, -1 }, /* LoadIdentityDeformationMapSGIX */
-   { 10989, -1 }, /* DeformationMap3dSGIX */
-   { 14589, -1 }, /* DeformSGIX */
-   { 22187, -1 }, /* DeformationMap3fSGIX */
+   { 14834, -1 }, /* DeformSGIX */
+   { 22440, -1 }, /* DeformationMap3fSGIX */
+   { 28857, -1 }, /* DeformationMap3dSGIX */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGIX_reference_plane)
 static const struct gl_function_remap GL_SGIX_reference_plane_functions[] = {
-   { 13242, -1 }, /* ReferencePlaneSGIX */
+   { 13487, -1 }, /* ReferencePlaneSGIX */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGIX_sprite)
 static const struct gl_function_remap GL_SGIX_sprite_functions[] = {
-   {  8631, -1 }, /* SpriteParameterfvSGIX */
-   { 18714, -1 }, /* SpriteParameteriSGIX */
-   { 24217, -1 }, /* SpriteParameterfSGIX */
-   { 26852, -1 }, /* SpriteParameterivSGIX */
+   {  8778, -1 }, /* SpriteParameterfvSGIX */
+   { 18959, -1 }, /* SpriteParameteriSGIX */
+   { 24532, -1 }, /* SpriteParameterfSGIX */
+   { 27137, -1 }, /* SpriteParameterivSGIX */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGIX_tag_sample_buffer)
 static const struct gl_function_remap GL_SGIX_tag_sample_buffer_functions[] = {
-   { 18773, -1 }, /* TagSampleBufferSGIX */
+   { 19018, -1 }, /* TagSampleBufferSGIX */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SGI_color_table)
 static const struct gl_function_remap GL_SGI_color_table_functions[] = {
-   {  6733, _gloffset_ColorTableParameteriv },
-   {  7445, _gloffset_ColorTable },
-   { 13738, _gloffset_GetColorTable },
-   { 13848, _gloffset_CopyColorTable },
-   { 17503, _gloffset_ColorTableParameterfv },
-   { 20901, _gloffset_GetColorTableParameterfv },
-   { 22894, _gloffset_GetColorTableParameteriv },
+   {  6852, _gloffset_ColorTableParameteriv },
+   {  7564, _gloffset_ColorTable },
+   { 13983, _gloffset_GetColorTable },
+   { 14093, _gloffset_CopyColorTable },
+   { 17748, _gloffset_ColorTableParameterfv },
+   { 21171, _gloffset_GetColorTableParameterfv },
+   { 23147, _gloffset_GetColorTableParameteriv },
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SUNX_constant_data)
 static const struct gl_function_remap GL_SUNX_constant_data_functions[] = {
-   { 28623, -1 }, /* FinishTextureSUNX */
+   { 28947, -1 }, /* FinishTextureSUNX */
    {    -1, -1 }
 };
 #endif
@@ -5906,19 +5975,19 @@ static const struct gl_function_remap GL_SUNX_constant_data_functions[] = {
 static const struct gl_function_remap GL_SUN_global_alpha_functions[] = {
    {  3035, -1 }, /* GlobalAlphaFactorubSUN */
    {  4224, -1 }, /* GlobalAlphaFactoriSUN */
-   {  5676, -1 }, /* GlobalAlphaFactordSUN */
-   {  8715, -1 }, /* GlobalAlphaFactoruiSUN */
-   {  9067, -1 }, /* GlobalAlphaFactorbSUN */
-   { 11982, -1 }, /* GlobalAlphaFactorfSUN */
-   { 12101, -1 }, /* GlobalAlphaFactorusSUN */
-   { 20601, -1 }, /* GlobalAlphaFactorsSUN */
+   {  5789, -1 }, /* GlobalAlphaFactordSUN */
+   {  8862, -1 }, /* GlobalAlphaFactoruiSUN */
+   {  9214, -1 }, /* GlobalAlphaFactorbSUN */
+   { 12126, -1 }, /* GlobalAlphaFactorfSUN */
+   { 12245, -1 }, /* GlobalAlphaFactorusSUN */
+   { 20871, -1 }, /* GlobalAlphaFactorsSUN */
    {    -1, -1 }
 };
 #endif
 
 #if defined(need_GL_SUN_mesh_array)
 static const struct gl_function_remap GL_SUN_mesh_array_functions[] = {
-   { 26664, -1 }, /* DrawMeshArraysSUN */
+   { 26949, -1 }, /* DrawMeshArraysSUN */
    {    -1, -1 }
 };
 #endif
@@ -5926,12 +5995,12 @@ static const struct gl_function_remap GL_SUN_mesh_array_functions[] = {
 #if defined(need_GL_SUN_triangle_list)
 static const struct gl_function_remap GL_SUN_triangle_list_functions[] = {
    {  3971, -1 }, /* ReplacementCodeubSUN */
-   {  5515, -1 }, /* ReplacementCodeubvSUN */
-   { 17224, -1 }, /* ReplacementCodeusvSUN */
-   { 17412, -1 }, /* ReplacementCodePointerSUN */
-   { 19583, -1 }, /* ReplacementCodeuiSUN */
-   { 20313, -1 }, /* ReplacementCodeusSUN */
-   { 27309, -1 }, /* ReplacementCodeuivSUN */
+   {  5600, -1 }, /* ReplacementCodeubvSUN */
+   { 17469, -1 }, /* ReplacementCodeusvSUN */
+   { 17657, -1 }, /* ReplacementCodePointerSUN */
+   { 19828, -1 }, /* ReplacementCodeuiSUN */
+   { 20583, -1 }, /* ReplacementCodeusSUN */
+   { 27594, -1 }, /* ReplacementCodeuivSUN */
    {    -1, -1 }
 };
 #endif
@@ -5947,37 +6016,37 @@ static const struct gl_function_remap GL_SUN_vertex_functions[] = {
    {  2642, -1 }, /* Color4ubVertex3fvSUN */
    {  4105, -1 }, /* Color4ubVertex3fSUN */
    {  4181, -1 }, /* TexCoord2fVertex3fSUN */
-   {  4480, -1 }, /* TexCoord2fColor4fNormal3fVertex3fSUN */
-   {  4810, -1 }, /* TexCoord2fNormal3fVertex3fvSUN */
-   {  5410, -1 }, /* ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN */
-   {  6480, -1 }, /* ReplacementCodeuiTexCoord2fVertex3fSUN */
-   {  7192, -1 }, /* TexCoord2fNormal3fVertex3fSUN */
-   {  7960, -1 }, /* Color3fVertex3fSUN */
-   {  9026, -1 }, /* Color3fVertex3fvSUN */
-   {  9441, -1 }, /* Color4fNormal3fVertex3fvSUN */
-   { 10178, -1 }, /* ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN */
-   { 11530, -1 }, /* ReplacementCodeuiColor4fNormal3fVertex3fvSUN */
-   { 12973, -1 }, /* ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN */
-   { 13384, -1 }, /* TexCoord2fColor3fVertex3fSUN */
-   { 14514, -1 }, /* TexCoord4fColor4fNormal3fVertex4fSUN */
-   { 14848, -1 }, /* Color4ubVertex2fvSUN */
-   { 15088, -1 }, /* Normal3fVertex3fSUN */
-   { 16084, -1 }, /* ReplacementCodeuiColor4fNormal3fVertex3fSUN */
-   { 16345, -1 }, /* TexCoord2fColor4fNormal3fVertex3fvSUN */
-   { 17053, -1 }, /* TexCoord2fVertex3fvSUN */
-   { 17829, -1 }, /* Color4ubVertex2fSUN */
-   { 18050, -1 }, /* ReplacementCodeuiColor4ubVertex3fSUN */
-   { 20008, -1 }, /* TexCoord2fColor4ubVertex3fSUN */
-   { 20381, -1 }, /* Normal3fVertex3fvSUN */
-   { 20810, -1 }, /* Color4fNormal3fVertex3fSUN */
-   { 21719, -1 }, /* ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN */
-   { 21939, -1 }, /* ReplacementCodeuiColor4ubVertex3fvSUN */
-   { 23669, -1 }, /* ReplacementCodeuiColor3fVertex3fSUN */
-   { 24926, -1 }, /* TexCoord4fVertex4fSUN */
-   { 25352, -1 }, /* TexCoord2fColor3fVertex3fvSUN */
-   { 25707, -1 }, /* ReplacementCodeuiNormal3fVertex3fvSUN */
-   { 25834, -1 }, /* TexCoord4fVertex4fvSUN */
-   { 26536, -1 }, /* ReplacementCodeuiVertex3fSUN */
+   {  4508, -1 }, /* TexCoord2fColor4fNormal3fVertex3fSUN */
+   {  4866, -1 }, /* TexCoord2fNormal3fVertex3fvSUN */
+   {  5495, -1 }, /* ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN */
+   {  6240, -1 }, /* ReplacementCodeuiColor4ubVertex3fvSUN */
+   {  6599, -1 }, /* ReplacementCodeuiTexCoord2fVertex3fSUN */
+   {  7311, -1 }, /* TexCoord2fNormal3fVertex3fSUN */
+   {  8079, -1 }, /* Color3fVertex3fSUN */
+   {  9173, -1 }, /* Color3fVertex3fvSUN */
+   {  9588, -1 }, /* Color4fNormal3fVertex3fvSUN */
+   { 10325, -1 }, /* ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN */
+   { 11674, -1 }, /* ReplacementCodeuiColor4fNormal3fVertex3fvSUN */
+   { 13218, -1 }, /* ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN */
+   { 13629, -1 }, /* TexCoord2fColor3fVertex3fSUN */
+   { 14759, -1 }, /* TexCoord4fColor4fNormal3fVertex4fSUN */
+   { 15093, -1 }, /* Color4ubVertex2fvSUN */
+   { 15333, -1 }, /* Normal3fVertex3fSUN */
+   { 16329, -1 }, /* ReplacementCodeuiColor4fNormal3fVertex3fSUN */
+   { 16590, -1 }, /* TexCoord2fColor4fNormal3fVertex3fvSUN */
+   { 17298, -1 }, /* TexCoord2fVertex3fvSUN */
+   { 18074, -1 }, /* Color4ubVertex2fSUN */
+   { 18295, -1 }, /* ReplacementCodeuiColor4ubVertex3fSUN */
+   { 20253, -1 }, /* TexCoord2fColor4ubVertex3fSUN */
+   { 20651, -1 }, /* Normal3fVertex3fvSUN */
+   { 21080, -1 }, /* Color4fNormal3fVertex3fSUN */
+   { 21989, -1 }, /* ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN */
+   { 23984, -1 }, /* ReplacementCodeuiColor3fVertex3fSUN */
+   { 25209, -1 }, /* TexCoord4fVertex4fSUN */
+   { 25635, -1 }, /* TexCoord2fColor3fVertex3fvSUN */
+   { 25986, -1 }, /* ReplacementCodeuiNormal3fVertex3fvSUN */
+   { 26113, -1 }, /* TexCoord4fVertex4fvSUN */
+   { 26821, -1 }, /* ReplacementCodeuiVertex3fSUN */
    {    -1, -1 }
 };
 #endif
@@ -5988,37 +6057,37 @@ static const struct gl_function_remap GL_VERSION_1_3_functions[] = {
    {   381, _gloffset_MultiTexCoord3sARB },
    {   613, _gloffset_ActiveTextureARB },
    {  3761, _gloffset_MultiTexCoord1fvARB },
-   {  5301, _gloffset_MultiTexCoord3dARB },
-   {  5346, _gloffset_MultiTexCoord2iARB },
-   {  5470, _gloffset_MultiTexCoord2svARB },
-   {  7401, _gloffset_MultiTexCoord2fARB },
-   {  9277, _gloffset_MultiTexCoord3fvARB },
-   {  9834, _gloffset_MultiTexCoord4sARB },
-   { 10468, _gloffset_MultiTexCoord2dvARB },
-   { 10850, _gloffset_MultiTexCoord1svARB },
-   { 11225, _gloffset_MultiTexCoord3svARB },
-   { 11286, _gloffset_MultiTexCoord4iARB },
-   { 12009, _gloffset_MultiTexCoord3iARB },
-   { 12711, _gloffset_MultiTexCoord1dARB },
-   { 12928, _gloffset_MultiTexCoord3dvARB },
-   { 14092, _gloffset_MultiTexCoord3ivARB },
-   { 14137, _gloffset_MultiTexCoord2sARB },
-   { 15435, _gloffset_MultiTexCoord4ivARB },
-   { 17153, _gloffset_ClientActiveTextureARB },
-   { 19436, _gloffset_MultiTexCoord2dARB },
-   { 19877, _gloffset_MultiTexCoord4dvARB },
-   { 20163, _gloffset_MultiTexCoord4fvARB },
-   { 21042, _gloffset_MultiTexCoord3fARB },
-   { 23422, _gloffset_MultiTexCoord4dARB },
-   { 23626, _gloffset_MultiTexCoord1sARB },
-   { 23830, _gloffset_MultiTexCoord1dvARB },
-   { 24672, _gloffset_MultiTexCoord1ivARB },
-   { 24765, _gloffset_MultiTexCoord2ivARB },
-   { 25104, _gloffset_MultiTexCoord1iARB },
-   { 26404, _gloffset_MultiTexCoord4svARB },
-   { 26922, _gloffset_MultiTexCoord1fARB },
-   { 27185, _gloffset_MultiTexCoord4fARB },
-   { 29450, _gloffset_MultiTexCoord2fvARB },
+   {  5386, _gloffset_MultiTexCoord3dARB },
+   {  5431, _gloffset_MultiTexCoord2iARB },
+   {  5555, _gloffset_MultiTexCoord2svARB },
+   {  7520, _gloffset_MultiTexCoord2fARB },
+   {  9424, _gloffset_MultiTexCoord3fvARB },
+   {  9981, _gloffset_MultiTexCoord4sARB },
+   { 10615, _gloffset_MultiTexCoord2dvARB },
+   { 10997, _gloffset_MultiTexCoord1svARB },
+   { 11369, _gloffset_MultiTexCoord3svARB },
+   { 11430, _gloffset_MultiTexCoord4iARB },
+   { 12153, _gloffset_MultiTexCoord3iARB },
+   { 12956, _gloffset_MultiTexCoord1dARB },
+   { 13173, _gloffset_MultiTexCoord3dvARB },
+   { 14337, _gloffset_MultiTexCoord3ivARB },
+   { 14382, _gloffset_MultiTexCoord2sARB },
+   { 15680, _gloffset_MultiTexCoord4ivARB },
+   { 17398, _gloffset_ClientActiveTextureARB },
+   { 19681, _gloffset_MultiTexCoord2dARB },
+   { 20122, _gloffset_MultiTexCoord4dvARB },
+   { 20433, _gloffset_MultiTexCoord4fvARB },
+   { 21312, _gloffset_MultiTexCoord3fARB },
+   { 23675, _gloffset_MultiTexCoord4dARB },
+   { 23941, _gloffset_MultiTexCoord1sARB },
+   { 24145, _gloffset_MultiTexCoord1dvARB },
+   { 24955, _gloffset_MultiTexCoord1ivARB },
+   { 25048, _gloffset_MultiTexCoord2ivARB },
+   { 25387, _gloffset_MultiTexCoord1iARB },
+   { 26689, _gloffset_MultiTexCoord4svARB },
+   { 27207, _gloffset_MultiTexCoord1fARB },
+   { 27470, _gloffset_MultiTexCoord4fARB },
+   { 29774, _gloffset_MultiTexCoord2fvARB },
    {    -1, -1 }
 };
 #endif
diff --git a/src/mesa/main/restart.c b/src/mesa/main/restart.c
new file mode 100644 (file)
index 0000000..ff36649
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010  VMware, 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
+ * 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 THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "glheader.h"
+#include "imports.h"
+#include "context.h"
+#include "restart.h"
+
+
+/**
+ */
+void GLAPIENTRY
+_mesa_PrimitiveRestart(void)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (ctx->VersionMajor * 10 + ctx->VersionMinor < 31) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestart()");
+      return;
+   }
+
+   /* XXX call into vbo module */
+}
+
+
+
+/**
+ */
+void GLAPIENTRY
+_mesa_PrimitiveRestartIndex(GLuint index)
+{
+   GET_CURRENT_CONTEXT(ctx);
+
+   if (ctx->VersionMajor * 10 + ctx->VersionMinor < 31) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestartIndex()");
+      return;
+   }
+
+   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+   FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
+
+   ctx->Array.RestartIndex = index;
+}
diff --git a/src/mesa/main/restart.h b/src/mesa/main/restart.h
new file mode 100644 (file)
index 0000000..931cd70
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.9
+ *
+ * Copyright (C) 2010  VMware, 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
+ * 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 THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION 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 RESTART_H
+#define RESTART_H
+
+
+extern void GLAPIENTRY
+_mesa_PrimitiveRestart(void);
+
+
+extern void GLAPIENTRY
+_mesa_PrimitiveRestartIndex(GLuint index);
+
+
+#endif
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
new file mode 100644 (file)
index 0000000..89b9557
--- /dev/null
@@ -0,0 +1,1640 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2004-2008  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2009-2010  VMware, 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
+ * 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 shaderapi.c
+ * \author Brian Paul
+ *
+ * Implementation of GLSL-related API functions.
+ * The glUniform* functions are in uniforms.c
+ *
+ *
+ * XXX things to do:
+ * 1. Check that the right error code is generated for all _mesa_error() calls.
+ * 2. Insert FLUSH_VERTICES calls in various places
+ */
+
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/dispatch.h"
+#include "main/enums.h"
+#include "main/hash.h"
+#include "main/shaderapi.h"
+#include "main/shaderobj.h"
+#include "program/program.h"
+#include "program/prog_parameter.h"
+#include "program/prog_uniform.h"
+#include "slang/slang_compile.h"
+#include "slang/slang_link.h"
+#include "talloc.h"
+
+
+/** Define this to enable shader substitution (see below) */
+#define SHADER_SUBST 0
+
+
+/**
+ * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
+ */
+static GLbitfield
+get_shader_flags(void)
+{
+   GLbitfield flags = 0x0;
+   const char *env = _mesa_getenv("MESA_GLSL");
+
+   if (env) {
+      if (strstr(env, "dump"))
+         flags |= GLSL_DUMP;
+      if (strstr(env, "log"))
+         flags |= GLSL_LOG;
+      if (strstr(env, "nopvert"))
+         flags |= GLSL_NOP_VERT;
+      if (strstr(env, "nopfrag"))
+         flags |= GLSL_NOP_FRAG;
+      if (strstr(env, "nopt"))
+         flags |= GLSL_NO_OPT;
+      else if (strstr(env, "opt"))
+         flags |= GLSL_OPT;
+      if (strstr(env, "uniform"))
+         flags |= GLSL_UNIFORMS;
+      if (strstr(env, "useprog"))
+         flags |= GLSL_USE_PROG;
+   }
+
+   return flags;
+}
+
+
+/**
+ * Initialize context's shader state.
+ */
+void
+_mesa_init_shader_state(GLcontext *ctx)
+{
+   /* Device drivers may override these to control what kind of instructions
+    * are generated by the GLSL compiler.
+    */
+   ctx->Shader.EmitHighLevelInstructions = GL_TRUE;
+   ctx->Shader.EmitContReturn = GL_TRUE;
+   ctx->Shader.EmitCondCodes = GL_FALSE;
+   ctx->Shader.EmitComments = GL_FALSE;
+   ctx->Shader.EmitNoIfs = GL_FALSE;
+   ctx->Shader.Flags = get_shader_flags();
+
+   /* Default pragma settings */
+   ctx->Shader.DefaultPragmas.IgnoreOptimize = GL_FALSE;
+   ctx->Shader.DefaultPragmas.IgnoreDebug = GL_FALSE;
+   ctx->Shader.DefaultPragmas.Optimize = GL_TRUE;
+   ctx->Shader.DefaultPragmas.Debug = GL_FALSE;
+}
+
+
+/**
+ * Free the per-context shader-related state.
+ */
+void
+_mesa_free_shader_state(GLcontext *ctx)
+{
+   _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, NULL);
+}
+
+
+/**
+ * Return the size of the given GLSL datatype, in floats (components).
+ */
+GLint
+_mesa_sizeof_glsl_type(GLenum type)
+{
+   switch (type) {
+   case GL_FLOAT:
+   case GL_INT:
+   case GL_BOOL:
+   case GL_SAMPLER_1D:
+   case GL_SAMPLER_2D:
+   case GL_SAMPLER_3D:
+   case GL_SAMPLER_CUBE:
+   case GL_SAMPLER_1D_SHADOW:
+   case GL_SAMPLER_2D_SHADOW:
+   case GL_SAMPLER_2D_RECT_ARB:
+   case GL_SAMPLER_2D_RECT_SHADOW_ARB:
+   case GL_SAMPLER_1D_ARRAY_EXT:
+   case GL_SAMPLER_2D_ARRAY_EXT:
+   case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
+   case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
+   case GL_SAMPLER_CUBE_SHADOW_EXT:
+      return 1;
+   case GL_FLOAT_VEC2:
+   case GL_INT_VEC2:
+   case GL_UNSIGNED_INT_VEC2:
+   case GL_BOOL_VEC2:
+      return 2;
+   case GL_FLOAT_VEC3:
+   case GL_INT_VEC3:
+   case GL_UNSIGNED_INT_VEC3:
+   case GL_BOOL_VEC3:
+      return 3;
+   case GL_FLOAT_VEC4:
+   case GL_INT_VEC4:
+   case GL_UNSIGNED_INT_VEC4:
+   case GL_BOOL_VEC4:
+      return 4;
+   case GL_FLOAT_MAT2:
+   case GL_FLOAT_MAT2x3:
+   case GL_FLOAT_MAT2x4:
+      return 8; /* two float[4] vectors */
+   case GL_FLOAT_MAT3:
+   case GL_FLOAT_MAT3x2:
+   case GL_FLOAT_MAT3x4:
+      return 12; /* three float[4] vectors */
+   case GL_FLOAT_MAT4:
+   case GL_FLOAT_MAT4x2:
+   case GL_FLOAT_MAT4x3:
+      return 16;  /* four float[4] vectors */
+   default:
+      _mesa_problem(NULL, "Invalid type in _mesa_sizeof_glsl_type()");
+      return 1;
+   }
+}
+
+
+/**
+ * Copy string from <src> to <dst>, up to maxLength characters, returning
+ * length of <dst> in <length>.
+ * \param src  the strings source
+ * \param maxLength  max chars to copy
+ * \param length  returns number of chars copied
+ * \param dst  the string destination
+ */
+void
+_mesa_copy_string(GLchar *dst, GLsizei maxLength,
+                  GLsizei *length, const GLchar *src)
+{
+   GLsizei len;
+   for (len = 0; len < maxLength - 1 && src && src[len]; len++)
+      dst[len] = src[len];
+   if (maxLength > 0)
+      dst[len] = 0;
+   if (length)
+      *length = len;
+}
+
+
+
+/**
+ * Find the length of the longest transform feedback varying name
+ * which was specified with glTransformFeedbackVaryings().
+ */
+static GLint
+longest_feedback_varying_name(const struct gl_shader_program *shProg)
+{
+   GLuint i;
+   GLint max = 0;
+   for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
+      GLint len = strlen(shProg->TransformFeedback.VaryingNames[i]);
+      if (len > max)
+         max = len;
+   }
+   return max;
+}
+
+
+
+static GLboolean
+is_program(GLcontext *ctx, GLuint name)
+{
+   struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
+   return shProg ? GL_TRUE : GL_FALSE;
+}
+
+
+static GLboolean
+is_shader(GLcontext *ctx, GLuint name)
+{
+   struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
+   return shader ? GL_TRUE : GL_FALSE;
+}
+
+
+/**
+ * Attach shader to a shader program.
+ */
+static void
+attach_shader(GLcontext *ctx, GLuint program, GLuint shader)
+{
+   struct gl_shader_program *shProg;
+   struct gl_shader *sh;
+   GLuint i, n;
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
+   if (!shProg)
+      return;
+
+   sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
+   if (!sh) {
+      return;
+   }
+
+   n = shProg->NumShaders;
+   for (i = 0; i < n; i++) {
+      if (shProg->Shaders[i] == sh) {
+         /* The shader is already attched to this program.  The
+          * GL_ARB_shader_objects spec says:
+          *
+          *     "The error INVALID_OPERATION is generated by AttachObjectARB
+          *     if <obj> is already attached to <containerObj>."
+          */
+         _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
+         return;
+      }
+   }
+
+   /* grow list */
+   shProg->Shaders = (struct gl_shader **)
+      _mesa_realloc(shProg->Shaders,
+                    n * sizeof(struct gl_shader *),
+                    (n + 1) * sizeof(struct gl_shader *));
+   if (!shProg->Shaders) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
+      return;
+   }
+
+   /* append */
+   shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
+   _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
+   shProg->NumShaders++;
+}
+
+
+static GLint
+get_attrib_location(GLcontext *ctx, GLuint program, const GLchar *name)
+{
+   struct gl_shader_program *shProg
+      = _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation");
+
+   if (!shProg) {
+      return -1;
+   }
+
+   if (!shProg->LinkStatus) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glGetAttribLocation(program not linked)");
+      return -1;
+   }
+
+   if (!name)
+      return -1;
+
+   if (shProg->VertexProgram) {
+      const struct gl_program_parameter_list *attribs =
+         shProg->VertexProgram->Base.Attributes;
+      if (attribs) {
+         GLint i = _mesa_lookup_parameter_index(attribs, -1, name);
+         if (i >= 0) {
+            return attribs->Parameters[i].StateIndexes[0];
+         }
+      }
+   }
+   return -1;
+}
+
+
+static void
+bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,
+                     const GLchar *name)
+{
+   struct gl_shader_program *shProg;
+   const GLint size = -1; /* unknown size */
+   GLint i, oldIndex;
+   GLenum datatype = GL_FLOAT_VEC4;
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program,
+                                            "glBindAttribLocation");
+   if (!shProg) {
+      return;
+   }
+
+   if (!name)
+      return;
+
+   if (strncmp(name, "gl_", 3) == 0) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glBindAttribLocation(illegal name)");
+      return;
+   }
+
+   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(index)");
+      return;
+   }
+
+   if (shProg->LinkStatus) {
+      /* get current index/location for the attribute */
+      oldIndex = get_attrib_location(ctx, program, name);
+   }
+   else {
+      oldIndex = -1;
+   }
+
+   /* this will replace the current value if it's already in the list */
+   i = _mesa_add_attribute(shProg->Attributes, name, size, datatype, index);
+   if (i < 0) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindAttribLocation");
+      return;
+   }
+
+   /*
+    * Note that this attribute binding won't go into effect until
+    * glLinkProgram is called again.
+    */
+}
+
+
+static GLuint
+create_shader(GLcontext *ctx, GLenum type)
+{
+   struct gl_shader *sh;
+   GLuint name;
+
+   name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
+
+   switch (type) {
+   case GL_FRAGMENT_SHADER:
+   case GL_VERTEX_SHADER:
+   case GL_GEOMETRY_SHADER_ARB:
+      sh = ctx->Driver.NewShader(ctx, name, type);
+      break;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)");
+      return 0;
+   }
+
+   _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh);
+
+   return name;
+}
+
+
+static GLuint 
+create_shader_program(GLcontext *ctx)
+{
+   GLuint name;
+   struct gl_shader_program *shProg;
+
+   name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
+
+   shProg = ctx->Driver.NewShaderProgram(ctx, name);
+
+   _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg);
+
+   assert(shProg->RefCount == 1);
+
+   return name;
+}
+
+
+/**
+ * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
+ * DeleteProgramARB.
+ */
+static void
+delete_shader_program(GLcontext *ctx, GLuint name)
+{
+   /*
+    * NOTE: deleting shaders/programs works a bit differently than
+    * texture objects (and buffer objects, etc).  Shader/program
+    * handles/IDs exist in the hash table until the object is really
+    * deleted (refcount==0).  With texture objects, the handle/ID is
+    * removed from the hash table in glDeleteTextures() while the tex
+    * object itself might linger until its refcount goes to zero.
+    */
+   struct gl_shader_program *shProg;
+
+   shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram");
+   if (!shProg)
+      return;
+
+   shProg->DeletePending = GL_TRUE;
+
+   /* effectively, decr shProg's refcount */
+   _mesa_reference_shader_program(ctx, &shProg, NULL);
+}
+
+
+static void
+delete_shader(GLcontext *ctx, GLuint shader)
+{
+   struct gl_shader *sh;
+
+   sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader");
+   if (!sh)
+      return;
+
+   sh->DeletePending = GL_TRUE;
+
+   /* effectively, decr sh's refcount */
+   _mesa_reference_shader(ctx, &sh, NULL);
+}
+
+
+static void
+detach_shader(GLcontext *ctx, GLuint program, GLuint shader)
+{
+   struct gl_shader_program *shProg;
+   GLuint n;
+   GLuint i, j;
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader");
+   if (!shProg)
+      return;
+
+   n = shProg->NumShaders;
+
+   for (i = 0; i < n; i++) {
+      if (shProg->Shaders[i]->Name == shader) {
+         /* found it */
+         struct gl_shader **newList;
+
+         /* release */
+         _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
+
+         /* alloc new, smaller array */
+         newList = (struct gl_shader **)
+            malloc((n - 1) * sizeof(struct gl_shader *));
+         if (!newList) {
+            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
+            return;
+         }
+         for (j = 0; j < i; j++) {
+            newList[j] = shProg->Shaders[j];
+         }
+         while (++i < n)
+            newList[j++] = shProg->Shaders[i];
+         free(shProg->Shaders);
+
+         shProg->Shaders = newList;
+         shProg->NumShaders = n - 1;
+
+#ifdef DEBUG
+         /* sanity check */
+         {
+            for (j = 0; j < shProg->NumShaders; j++) {
+               assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER ||
+                      shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER);
+               assert(shProg->Shaders[j]->RefCount > 0);
+            }
+         }
+#endif
+
+         return;
+      }
+   }
+
+   /* not found */
+   {
+      GLenum err;
+      if (is_shader(ctx, shader))
+         err = GL_INVALID_OPERATION;
+      else if (is_program(ctx, shader))
+         err = GL_INVALID_OPERATION;
+      else
+         err = GL_INVALID_VALUE;
+      _mesa_error(ctx, err, "glDetachProgram(shader)");
+      return;
+   }
+}
+
+
+static void
+get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
+                  GLsizei maxLength, GLsizei *length, GLint *size,
+                  GLenum *type, GLchar *nameOut)
+{
+   const struct gl_program_parameter_list *attribs = NULL;
+   struct gl_shader_program *shProg;
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib");
+   if (!shProg)
+      return;
+
+   if (shProg->VertexProgram)
+      attribs = shProg->VertexProgram->Base.Attributes;
+
+   if (!attribs || index >= attribs->NumParameters) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)");
+      return;
+   }
+
+   _mesa_copy_string(nameOut, maxLength, length,
+                     attribs->Parameters[index].Name);
+
+   if (size)
+      *size = attribs->Parameters[index].Size
+         / _mesa_sizeof_glsl_type(attribs->Parameters[index].DataType);
+
+   if (type)
+      *type = attribs->Parameters[index].DataType;
+}
+
+
+/**
+ * Return list of shaders attached to shader program.
+ */
+static void
+get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount,
+                     GLsizei *count, GLuint *obj)
+{
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
+   if (shProg) {
+      GLuint i;
+      for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
+         obj[i] = shProg->Shaders[i]->Name;
+      }
+      if (count)
+         *count = i;
+   }
+}
+
+
+/**
+ * glGetHandleARB() - return ID/name of currently bound shader program.
+ */
+static GLuint
+get_handle(GLcontext *ctx, GLenum pname)
+{
+   if (pname == GL_PROGRAM_OBJECT_ARB) {
+      if (ctx->Shader.CurrentProgram)
+         return ctx->Shader.CurrentProgram->Name;
+      else
+         return 0;
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
+      return 0;
+   }
+}
+
+
+/**
+ * glGetProgramiv() - get shader program state.
+ * Note that this is for GLSL shader programs, not ARB vertex/fragment
+ * programs (see glGetProgramivARB).
+ */
+static void
+get_programiv(GLcontext *ctx, GLuint program, GLenum pname, GLint *params)
+{
+   const struct gl_program_parameter_list *attribs;
+   struct gl_shader_program *shProg
+      = _mesa_lookup_shader_program(ctx, program);
+
+   if (!shProg) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)");
+      return;
+   }
+
+   if (shProg->VertexProgram)
+      attribs = shProg->VertexProgram->Base.Attributes;
+   else
+      attribs = NULL;
+
+   switch (pname) {
+   case GL_DELETE_STATUS:
+      *params = shProg->DeletePending;
+      break; 
+   case GL_LINK_STATUS:
+      *params = shProg->LinkStatus;
+      break;
+   case GL_VALIDATE_STATUS:
+      *params = shProg->Validated;
+      break;
+   case GL_INFO_LOG_LENGTH:
+      *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
+      break;
+   case GL_ATTACHED_SHADERS:
+      *params = shProg->NumShaders;
+      break;
+   case GL_ACTIVE_ATTRIBUTES:
+      *params = attribs ? attribs->NumParameters : 0;
+      break;
+   case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
+      *params = _mesa_longest_parameter_name(attribs, PROGRAM_INPUT) + 1;
+      break;
+   case GL_ACTIVE_UNIFORMS:
+      *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0;
+      break;
+   case GL_ACTIVE_UNIFORM_MAX_LENGTH:
+      *params = _mesa_longest_uniform_name(shProg->Uniforms);
+      if (*params > 0)
+         (*params)++;  /* add one for terminating zero */
+      break;
+   case GL_PROGRAM_BINARY_LENGTH_OES:
+      *params = 0;
+      break;
+#if FEATURE_EXT_transform_feedback
+   case GL_TRANSFORM_FEEDBACK_VARYINGS:
+      *params = shProg->TransformFeedback.NumVarying;
+      break;
+   case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
+      *params = longest_feedback_varying_name(shProg) + 1;
+      break;
+   case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
+      *params = shProg->TransformFeedback.BufferMode;
+      break;
+#endif
+#if FEATURE_ARB_geometry_shader4
+   case GL_GEOMETRY_VERTICES_OUT_ARB:
+      *params = shProg->Geom.VerticesOut;
+      break;
+   case GL_GEOMETRY_INPUT_TYPE_ARB:
+      *params = shProg->Geom.InputType;
+      break;
+   case GL_GEOMETRY_OUTPUT_TYPE_ARB:
+      *params = shProg->Geom.OutputType;
+      break;
+#endif
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
+      return;
+   }
+}
+
+
+/**
+ * glGetShaderiv() - get GLSL shader state
+ */
+static void
+get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params)
+{
+   struct gl_shader *shader =
+      _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
+
+   if (!shader) {
+      return;
+   }
+
+   switch (pname) {
+   case GL_SHADER_TYPE:
+      *params = shader->Type;
+      break;
+   case GL_DELETE_STATUS:
+      *params = shader->DeletePending;
+      break;
+   case GL_COMPILE_STATUS:
+      *params = shader->CompileStatus;
+      break;
+   case GL_INFO_LOG_LENGTH:
+      *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
+      break;
+   case GL_SHADER_SOURCE_LENGTH:
+      *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
+      break;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
+      return;
+   }
+}
+
+
+static void
+get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize,
+                     GLsizei *length, GLchar *infoLog)
+{
+   struct gl_shader_program *shProg
+      = _mesa_lookup_shader_program(ctx, program);
+   if (!shProg) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)");
+      return;
+   }
+   _mesa_copy_string(infoLog, bufSize, length, shProg->InfoLog);
+}
+
+
+static void
+get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize,
+                    GLsizei *length, GLchar *infoLog)
+{
+   struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
+   if (!sh) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)");
+      return;
+   }
+   _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog);
+}
+
+
+/**
+ * Return shader source code.
+ */
+static void
+get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
+                  GLsizei *length, GLchar *sourceOut)
+{
+   struct gl_shader *sh;
+   sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
+   if (!sh) {
+      return;
+   }
+   _mesa_copy_string(sourceOut, maxLength, length, sh->Source);
+}
+
+
+/**
+ * Set/replace shader source code.
+ */
+static void
+shader_source(GLcontext *ctx, GLuint shader, const GLchar *source)
+{
+   struct gl_shader *sh;
+
+   sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource");
+   if (!sh)
+      return;
+
+   /* free old shader source string and install new one */
+   if (sh->Source) {
+      free((void *) sh->Source);
+   }
+   sh->Source = source;
+   sh->CompileStatus = GL_FALSE;
+#ifdef DEBUG
+   sh->SourceChecksum = _mesa_str_checksum(sh->Source);
+#endif
+}
+
+
+/**
+ * Compile a shader.
+ */
+static void
+compile_shader(GLcontext *ctx, GLuint shaderObj)
+{
+   struct gl_shader *sh;
+
+   sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader");
+   if (!sh)
+      return;
+
+   /* set default pragma state for shader */
+   sh->Pragmas = ctx->Shader.DefaultPragmas;
+
+   /* this call will set the sh->CompileStatus field to indicate if
+    * compilation was successful.
+    */
+   _mesa_glsl_compile_shader(ctx, sh);
+}
+
+
+/**
+ * Link a program's shaders.
+ */
+static void
+link_program(GLcontext *ctx, GLuint program)
+{
+   struct gl_shader_program *shProg;
+   struct gl_transform_feedback_object *obj =
+      ctx->TransformFeedback.CurrentObject;
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram");
+   if (!shProg)
+      return;
+
+   if (obj->Active && shProg == ctx->Shader.CurrentProgram) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glLinkProgram(transform feedback active");
+      return;
+   }
+
+   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+
+   _mesa_glsl_link_shader(ctx, shProg);
+
+   /* debug code */
+   if (0) {
+      GLuint i;
+
+      printf("Link %u shaders in program %u: %s\n",
+                   shProg->NumShaders, shProg->Name,
+                   shProg->LinkStatus ? "Success" : "Failed");
+
+      for (i = 0; i < shProg->NumShaders; i++) {
+         printf(" shader %u, type 0x%x\n",
+                      shProg->Shaders[i]->Name,
+                      shProg->Shaders[i]->Type);
+      }
+   }
+}
+
+
+/**
+ * Print basic shader info (for debug).
+ */
+static void
+print_shader_info(const struct gl_shader_program *shProg)
+{
+   GLuint i;
+
+   printf("Mesa: glUseProgram(%u)\n", shProg->Name);
+   for (i = 0; i < shProg->NumShaders; i++) {
+      const char *s;
+      switch (shProg->Shaders[i]->Type) {
+      case GL_VERTEX_SHADER:
+         s = "vertex";
+         break;
+      case GL_FRAGMENT_SHADER:
+         s = "fragment";
+         break;
+      case GL_GEOMETRY_SHADER:
+         s = "geometry";
+         break;
+      default:
+         s = "";
+      }
+      printf("  %s shader %u, checksum %u\n", s, 
+            shProg->Shaders[i]->Name,
+            shProg->Shaders[i]->SourceChecksum);
+   }
+   if (shProg->VertexProgram)
+      printf("  vert prog %u\n", shProg->VertexProgram->Base.Id);
+   if (shProg->FragmentProgram)
+      printf("  frag prog %u\n", shProg->FragmentProgram->Base.Id);
+}
+
+
+/**
+ * Use the named shader program for subsequent rendering.
+ */
+void
+_mesa_use_program(GLcontext *ctx, GLuint program)
+{
+   struct gl_shader_program *shProg;
+   struct gl_transform_feedback_object *obj =
+      ctx->TransformFeedback.CurrentObject;
+
+   if (obj->Active) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glUseProgram(transform feedback active)");
+      return;
+   }
+
+   if (ctx->Shader.CurrentProgram &&
+       ctx->Shader.CurrentProgram->Name == program) {
+      /* no-op */
+      return;
+   }
+
+   if (program) {
+      shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
+      if (!shProg) {
+         return;
+      }
+      if (!shProg->LinkStatus) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "glUseProgram(program %u not linked)", program);
+         return;
+      }
+
+      /* debug code */
+      if (ctx->Shader.Flags & GLSL_USE_PROG) {
+         print_shader_info(shProg);
+      }
+   }
+   else {
+      shProg = NULL;
+   }
+
+   if (ctx->Shader.CurrentProgram != shProg) {
+      FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
+      _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, shProg);
+   }
+
+   if (ctx->Driver.UseProgram)
+      ctx->Driver.UseProgram(ctx, shProg);
+}
+
+
+/**
+ * Validate a program's samplers.
+ * Specifically, check that there aren't two samplers of different types
+ * pointing to the same texture unit.
+ * \return GL_TRUE if valid, GL_FALSE if invalid
+ */
+static GLboolean
+validate_samplers(GLcontext *ctx, const struct gl_program *prog, char *errMsg)
+{
+   static const char *targetName[] = {
+      "TEXTURE_2D_ARRAY",
+      "TEXTURE_1D_ARRAY",
+      "TEXTURE_CUBE",
+      "TEXTURE_3D",
+      "TEXTURE_RECT",
+      "TEXTURE_2D",
+      "TEXTURE_1D",
+   };
+   GLint targetUsed[MAX_TEXTURE_IMAGE_UNITS];
+   GLbitfield samplersUsed = prog->SamplersUsed;
+   GLuint i;
+
+   assert(Elements(targetName) == NUM_TEXTURE_TARGETS);
+
+   if (samplersUsed == 0x0)
+      return GL_TRUE;
+
+   for (i = 0; i < Elements(targetUsed); i++)
+      targetUsed[i] = -1;
+
+   /* walk over bits which are set in 'samplers' */
+   while (samplersUsed) {
+      GLuint unit;
+      gl_texture_index target;
+      GLint sampler = _mesa_ffs(samplersUsed) - 1;
+      assert(sampler >= 0);
+      assert(sampler < MAX_TEXTURE_IMAGE_UNITS);
+      unit = prog->SamplerUnits[sampler];
+      target = prog->SamplerTargets[sampler];
+      if (targetUsed[unit] != -1 && targetUsed[unit] != target) {
+         _mesa_snprintf(errMsg, 100,
+                 "Texture unit %d is accessed both as %s and %s",
+                 unit, targetName[targetUsed[unit]], targetName[target]);
+         return GL_FALSE;
+      }
+      targetUsed[unit] = target;
+      samplersUsed ^= (1 << sampler);
+   }
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Do validation of the given shader program.
+ * \param errMsg  returns error message if validation fails.
+ * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
+ */
+static GLboolean
+validate_shader_program(GLcontext *ctx,
+                        const struct gl_shader_program *shProg,
+                        char *errMsg)
+{
+   const struct gl_vertex_program *vp = shProg->VertexProgram;
+   const struct gl_fragment_program *fp = shProg->FragmentProgram;
+
+   if (!shProg->LinkStatus) {
+      return GL_FALSE;
+   }
+
+   /* From the GL spec, a program is invalid if any of these are true:
+
+     any two active samplers in the current program object are of
+     different types, but refer to the same texture image unit,
+
+     any active sampler in the current program object refers to a texture
+     image unit where fixed-function fragment processing accesses a
+     texture target that does not match the sampler type, or 
+
+     the sum of the number of active samplers in the program and the
+     number of texture image units enabled for fixed-function fragment
+     processing exceeds the combined limit on the total number of texture
+     image units allowed.
+   */
+
+
+   /*
+    * Check: any two active samplers in the current program object are of
+    * different types, but refer to the same texture image unit,
+    */
+   if (vp && !validate_samplers(ctx, &vp->Base, errMsg)) {
+      return GL_FALSE;
+   }
+   if (fp && !validate_samplers(ctx, &fp->Base, errMsg)) {
+      return GL_FALSE;
+   }
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Called via glValidateProgram()
+ */
+static void
+validate_program(GLcontext *ctx, GLuint program)
+{
+   struct gl_shader_program *shProg;
+   char errMsg[100];
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
+   if (!shProg) {
+      return;
+   }
+
+   shProg->Validated = validate_shader_program(ctx, shProg, errMsg);
+   if (!shProg->Validated) {
+      /* update info log */
+      if (shProg->InfoLog) {
+         talloc_free(shProg->InfoLog);
+      }
+      shProg->InfoLog = talloc_strdup(shProg, errMsg);
+   }
+}
+
+
+
+void GLAPIENTRY
+_mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   attach_shader(ctx, program, shader);
+}
+
+
+void GLAPIENTRY
+_mesa_AttachShader(GLuint program, GLuint shader)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   attach_shader(ctx, program, shader);
+}
+
+
+void GLAPIENTRY
+_mesa_BindAttribLocationARB(GLhandleARB program, GLuint index,
+                            const GLcharARB *name)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   bind_attrib_location(ctx, program, index, name);
+}
+
+
+void GLAPIENTRY
+_mesa_CompileShaderARB(GLhandleARB shaderObj)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   compile_shader(ctx, shaderObj);
+}
+
+
+GLuint GLAPIENTRY
+_mesa_CreateShader(GLenum type)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   return create_shader(ctx, type);
+}
+
+
+GLhandleARB GLAPIENTRY
+_mesa_CreateShaderObjectARB(GLenum type)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   return create_shader(ctx, type);
+}
+
+
+GLuint GLAPIENTRY
+_mesa_CreateProgram(void)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   return create_shader_program(ctx);
+}
+
+
+GLhandleARB GLAPIENTRY
+_mesa_CreateProgramObjectARB(void)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   return create_shader_program(ctx);
+}
+
+
+void GLAPIENTRY
+_mesa_DeleteObjectARB(GLhandleARB obj)
+{
+   if (obj) {
+      GET_CURRENT_CONTEXT(ctx);
+      if (is_program(ctx, obj)) {
+         delete_shader_program(ctx, obj);
+      }
+      else if (is_shader(ctx, obj)) {
+         delete_shader(ctx, obj);
+      }
+      else {
+         /* error? */
+      }
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_DeleteProgram(GLuint name)
+{
+   if (name) {
+      GET_CURRENT_CONTEXT(ctx);
+      delete_shader_program(ctx, name);
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_DeleteShader(GLuint name)
+{
+   if (name) {
+      GET_CURRENT_CONTEXT(ctx);
+      delete_shader(ctx, name);
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   detach_shader(ctx, program, shader);
+}
+
+
+void GLAPIENTRY
+_mesa_DetachShader(GLuint program, GLuint shader)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   detach_shader(ctx, program, shader);
+}
+
+
+void GLAPIENTRY
+_mesa_GetActiveAttribARB(GLhandleARB program, GLuint index,
+                         GLsizei maxLength, GLsizei * length, GLint * size,
+                         GLenum * type, GLcharARB * name)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   get_active_attrib(ctx, program, index, maxLength, length, size, type, name);
+}
+
+
+void GLAPIENTRY
+_mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
+                            GLsizei * count, GLhandleARB * obj)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   get_attached_shaders(ctx, container, maxCount, count, obj);
+}
+
+
+void GLAPIENTRY
+_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
+                         GLsizei *count, GLuint *obj)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   get_attached_shaders(ctx, program, maxCount, count, obj);
+}
+
+
+GLint GLAPIENTRY
+_mesa_GetAttribLocationARB(GLhandleARB program, const GLcharARB * name)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   return get_attrib_location(ctx, program, name);
+}
+
+
+void GLAPIENTRY
+_mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
+                    GLcharARB * infoLog)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   if (is_program(ctx, object)) {
+      get_program_info_log(ctx, object, maxLength, length, infoLog);
+   }
+   else if (is_shader(ctx, object)) {
+      get_shader_info_log(ctx, object, maxLength, length, infoLog);
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB");
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   /* Implement in terms of GetProgramiv, GetShaderiv */
+   if (is_program(ctx, object)) {
+      if (pname == GL_OBJECT_TYPE_ARB) {
+        *params = GL_PROGRAM_OBJECT_ARB;
+      }
+      else {
+        get_programiv(ctx, object, pname, params);
+      }
+   }
+   else if (is_shader(ctx, object)) {
+      if (pname == GL_OBJECT_TYPE_ARB) {
+        *params = GL_SHADER_OBJECT_ARB;
+      }
+      else {
+        get_shaderiv(ctx, object, pname, params);
+      }
+   }
+   else {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB");
+   }
+}
+
+
+void GLAPIENTRY
+_mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
+                              GLfloat *params)
+{
+   GLint iparams[1];  /* XXX is one element enough? */
+   _mesa_GetObjectParameterivARB(object, pname, iparams);
+   params[0] = (GLfloat) iparams[0];
+}
+
+
+void GLAPIENTRY
+_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   get_programiv(ctx, program, pname, params);
+}
+
+
+void GLAPIENTRY
+_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   get_shaderiv(ctx, shader, pname, params);
+}
+
+
+void GLAPIENTRY
+_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
+                        GLsizei *length, GLchar *infoLog)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   get_program_info_log(ctx, program, bufSize, length, infoLog);
+}
+
+
+void GLAPIENTRY
+_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
+                       GLsizei *length, GLchar *infoLog)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   get_shader_info_log(ctx, shader, bufSize, length, infoLog);
+}
+
+
+void GLAPIENTRY
+_mesa_GetShaderSourceARB(GLhandleARB shader, GLsizei maxLength,
+                         GLsizei *length, GLcharARB *sourceOut)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   get_shader_source(ctx, shader, maxLength, length, sourceOut);
+}
+
+
+GLhandleARB GLAPIENTRY
+_mesa_GetHandleARB(GLenum pname)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   return get_handle(ctx, pname);
+}
+
+
+GLboolean GLAPIENTRY
+_mesa_IsProgram(GLuint name)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   return is_program(ctx, name);
+}
+
+
+GLboolean GLAPIENTRY
+_mesa_IsShader(GLuint name)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   return is_shader(ctx, name);
+}
+
+
+void GLAPIENTRY
+_mesa_LinkProgramARB(GLhandleARB programObj)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   link_program(ctx, programObj);
+}
+
+
+
+/**
+ * Read shader source code from a file.
+ * Useful for debugging to override an app's shader.
+ */
+static GLcharARB *
+read_shader(const char *fname)
+{
+   const int max = 50*1000;
+   FILE *f = fopen(fname, "r");
+   GLcharARB *buffer, *shader;
+   int len;
+
+   if (!f) {
+      return NULL;
+   }
+
+   buffer = (char *) malloc(max);
+   len = fread(buffer, 1, max, f);
+   buffer[len] = 0;
+
+   fclose(f);
+
+   shader = _mesa_strdup(buffer);
+   free(buffer);
+
+   return shader;
+}
+
+
+/**
+ * Called via glShaderSource() and glShaderSourceARB() API functions.
+ * Basically, concatenate the source code strings into one long string
+ * and pass it to _mesa_shader_source().
+ */
+void GLAPIENTRY
+_mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
+                      const GLcharARB ** string, const GLint * length)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLint *offsets;
+   GLsizei i, totalLength;
+   GLcharARB *source;
+   GLuint checksum;
+
+   if (!shaderObj || string == NULL) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
+      return;
+   }
+
+   /*
+    * This array holds offsets of where the appropriate string ends, thus the
+    * last element will be set to the total length of the source code.
+    */
+   offsets = (GLint *) malloc(count * sizeof(GLint));
+   if (offsets == NULL) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
+      return;
+   }
+
+   for (i = 0; i < count; i++) {
+      if (string[i] == NULL) {
+         free((GLvoid *) offsets);
+         _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderSourceARB(null string)");
+         return;
+      }
+      if (length == NULL || length[i] < 0)
+         offsets[i] = strlen(string[i]);
+      else
+         offsets[i] = length[i];
+      /* accumulate string lengths */
+      if (i > 0)
+         offsets[i] += offsets[i - 1];
+   }
+
+   /* Total length of source string is sum off all strings plus two.
+    * One extra byte for terminating zero, another extra byte to silence
+    * valgrind warnings in the parser/grammer code.
+    */
+   totalLength = offsets[count - 1] + 2;
+   source = (GLcharARB *) malloc(totalLength * sizeof(GLcharARB));
+   if (source == NULL) {
+      free((GLvoid *) offsets);
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
+      return;
+   }
+
+   for (i = 0; i < count; i++) {
+      GLint start = (i > 0) ? offsets[i - 1] : 0;
+      memcpy(source + start, string[i],
+             (offsets[i] - start) * sizeof(GLcharARB));
+   }
+   source[totalLength - 1] = '\0';
+   source[totalLength - 2] = '\0';
+
+   if (SHADER_SUBST) {
+      /* Compute the shader's source code checksum then try to open a file
+       * named newshader_<CHECKSUM>.  If it exists, use it in place of the
+       * original shader source code.  For debugging.
+       */
+      char filename[100];
+      GLcharARB *newSource;
+
+      checksum = _mesa_str_checksum(source);
+
+      _mesa_snprintf(filename, sizeof(filename), "newshader_%d", checksum);
+
+      newSource = read_shader(filename);
+      if (newSource) {
+         fprintf(stderr, "Mesa: Replacing shader %u chksum=%d with %s\n",
+                       shaderObj, checksum, filename);
+         free(source);
+         source = newSource;
+      }
+   }      
+
+   shader_source(ctx, shaderObj, source);
+
+   if (SHADER_SUBST) {
+      struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj);
+      if (sh)
+         sh->SourceChecksum = checksum; /* save original checksum */
+   }
+
+   free(offsets);
+}
+
+
+void GLAPIENTRY
+_mesa_UseProgramObjectARB(GLhandleARB program)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+   _mesa_use_program(ctx, program);
+}
+
+
+void GLAPIENTRY
+_mesa_ValidateProgramARB(GLhandleARB program)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   validate_program(ctx, program);
+}
+
+#ifdef FEATURE_ES2
+
+void GLAPIENTRY
+_mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
+                               GLint* range, GLint* precision)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
+}
+
+
+void GLAPIENTRY
+_mesa_ReleaseShaderCompiler(void)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
+}
+
+
+void GLAPIENTRY
+_mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
+                   const void* binary, GLint length)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
+}
+
+#endif /* FEATURE_ES2 */
+
+
+#if FEATURE_ARB_geometry_shader4
+
+void GLAPIENTRY
+_mesa_ProgramParameteriARB(GLuint program, GLenum pname,
+                           GLint value)
+{
+   struct gl_shader_program *shProg;
+   GET_CURRENT_CONTEXT(ctx);
+
+   ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program,
+                                            "glProgramParameteri");
+   if (!shProg)
+      return;
+
+   switch (pname) {
+   case GL_GEOMETRY_VERTICES_OUT_ARB:
+      if (value < 1 ||
+          value > ctx->Const.GeometryProgram.MaxGeometryOutputVertices) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d",
+                     value);
+         return;
+      }
+      shProg->Geom.VerticesOut = value;
+      break;
+   case GL_GEOMETRY_INPUT_TYPE_ARB:
+      switch (value) {
+      case GL_POINTS:
+      case GL_LINES:
+      case GL_LINES_ADJACENCY_ARB:
+      case GL_TRIANGLES:
+      case GL_TRIANGLES_ADJACENCY_ARB:
+         shProg->Geom.InputType = value;
+         break;
+      default:
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glProgramParameteri(geometry input type = %s",
+                     _mesa_lookup_enum_by_nr(value));
+         return;
+      }
+      break;
+   case GL_GEOMETRY_OUTPUT_TYPE_ARB:
+      switch (value) {
+      case GL_POINTS:
+      case GL_LINE_STRIP:
+      case GL_TRIANGLE_STRIP:
+         shProg->Geom.OutputType = value;
+         break;
+      default:
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glProgramParameteri(geometry output type = %s",
+                     _mesa_lookup_enum_by_nr(value));
+         return;
+      }
+      break;
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameteriARB(pname=%s)",
+                  _mesa_lookup_enum_by_nr(pname));
+      break;
+   }
+}
+
+#endif
+
+
+/**
+ * Plug in shader-related functions into API dispatch table.
+ */
+void
+_mesa_init_shader_dispatch(struct _glapi_table *exec)
+{
+#if FEATURE_GL
+   /* GL_ARB_vertex/fragment_shader */
+   SET_DeleteObjectARB(exec, _mesa_DeleteObjectARB);
+   SET_GetHandleARB(exec, _mesa_GetHandleARB);
+   SET_DetachObjectARB(exec, _mesa_DetachObjectARB);
+   SET_CreateShaderObjectARB(exec, _mesa_CreateShaderObjectARB);
+   SET_ShaderSourceARB(exec, _mesa_ShaderSourceARB);
+   SET_CompileShaderARB(exec, _mesa_CompileShaderARB);
+   SET_CreateProgramObjectARB(exec, _mesa_CreateProgramObjectARB);
+   SET_AttachObjectARB(exec, _mesa_AttachObjectARB);
+   SET_LinkProgramARB(exec, _mesa_LinkProgramARB);
+   SET_UseProgramObjectARB(exec, _mesa_UseProgramObjectARB);
+   SET_ValidateProgramARB(exec, _mesa_ValidateProgramARB);
+   SET_GetObjectParameterfvARB(exec, _mesa_GetObjectParameterfvARB);
+   SET_GetObjectParameterivARB(exec, _mesa_GetObjectParameterivARB);
+   SET_GetInfoLogARB(exec, _mesa_GetInfoLogARB);
+   SET_GetAttachedObjectsARB(exec, _mesa_GetAttachedObjectsARB);
+   SET_GetShaderSourceARB(exec, _mesa_GetShaderSourceARB);
+
+   /* OpenGL 2.0 */
+   SET_AttachShader(exec, _mesa_AttachShader);
+   SET_CreateProgram(exec, _mesa_CreateProgram);
+   SET_CreateShader(exec, _mesa_CreateShader);
+   SET_DeleteProgram(exec, _mesa_DeleteProgram);
+   SET_DeleteShader(exec, _mesa_DeleteShader);
+   SET_DetachShader(exec, _mesa_DetachShader);
+   SET_GetAttachedShaders(exec, _mesa_GetAttachedShaders);
+   SET_GetProgramiv(exec, _mesa_GetProgramiv);
+   SET_GetProgramInfoLog(exec, _mesa_GetProgramInfoLog);
+   SET_GetShaderiv(exec, _mesa_GetShaderiv);
+   SET_GetShaderInfoLog(exec, _mesa_GetShaderInfoLog);
+   SET_IsProgram(exec, _mesa_IsProgram);
+   SET_IsShader(exec, _mesa_IsShader);
+
+#if FEATURE_ARB_vertex_shader
+   SET_BindAttribLocationARB(exec, _mesa_BindAttribLocationARB);
+   SET_GetActiveAttribARB(exec, _mesa_GetActiveAttribARB);
+   SET_GetAttribLocationARB(exec, _mesa_GetAttribLocationARB);
+#endif
+
+#if FEATURE_ARB_geometry_shader4
+   SET_ProgramParameteriARB(exec, _mesa_ProgramParameteriARB);
+#endif
+#endif /* FEATURE_GL */
+}
+
diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h
new file mode 100644 (file)
index 0000000..16e2253
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2004-2007  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2010  VMware, 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
+ * 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
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION 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 SHADERAPI_H
+#define SHADERAPI_H
+
+
+#include "glheader.h"
+#include "mtypes.h"
+
+
+extern GLint
+_mesa_sizeof_glsl_type(GLenum type);
+
+extern void
+_mesa_copy_string(GLchar *dst, GLsizei maxLength,
+                  GLsizei *length, const GLchar *src);
+
+extern void
+_mesa_use_program(GLcontext *ctx, GLuint program);
+
+
+extern void
+_mesa_init_shader_dispatch(struct _glapi_table *exec);
+
+
+
+extern void GLAPIENTRY
+_mesa_AttachObjectARB(GLhandleARB, GLhandleARB);
+
+extern void  GLAPIENTRY
+_mesa_CompileShaderARB(GLhandleARB);
+
+extern GLhandleARB GLAPIENTRY
+_mesa_CreateProgramObjectARB(void);
+
+extern GLhandleARB GLAPIENTRY
+_mesa_CreateShaderObjectARB(GLenum type);
+
+extern void GLAPIENTRY
+_mesa_DeleteObjectARB(GLhandleARB obj);
+
+extern void GLAPIENTRY
+_mesa_DetachObjectARB(GLhandleARB, GLhandleARB);
+
+extern void GLAPIENTRY
+_mesa_GetAttachedObjectsARB(GLhandleARB, GLsizei, GLsizei *, GLhandleARB *);
+
+extern GLhandleARB GLAPIENTRY
+_mesa_GetHandleARB(GLenum pname);
+
+extern void GLAPIENTRY
+_mesa_GetInfoLogARB(GLhandleARB, GLsizei, GLsizei *, GLcharARB *);
+
+extern void GLAPIENTRY
+_mesa_GetObjectParameterfvARB(GLhandleARB, GLenum, GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_GetObjectParameterivARB(GLhandleARB, GLenum, GLint *);
+
+extern void GLAPIENTRY
+_mesa_GetShaderSourceARB(GLhandleARB, GLsizei, GLsizei *, GLcharARB *);
+
+extern GLboolean GLAPIENTRY
+_mesa_IsProgram(GLuint name);
+
+extern GLboolean GLAPIENTRY
+_mesa_IsShader(GLuint name);
+
+extern void GLAPIENTRY
+_mesa_LinkProgramARB(GLhandleARB programObj);
+
+extern void GLAPIENTRY
+_mesa_ShaderSourceARB(GLhandleARB, GLsizei, const GLcharARB* *, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_UseProgramObjectARB(GLhandleARB);
+
+extern void GLAPIENTRY
+_mesa_ValidateProgramARB(GLhandleARB);
+
+
+extern void GLAPIENTRY
+_mesa_BindAttribLocationARB(GLhandleARB, GLuint, const GLcharARB *);
+
+extern void GLAPIENTRY
+_mesa_GetActiveAttribARB(GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *,
+                         GLenum *, GLcharARB *);
+
+extern GLint GLAPIENTRY
+_mesa_GetAttribLocationARB(GLhandleARB, const GLcharARB *);
+
+
+
+extern void GLAPIENTRY
+_mesa_AttachShader(GLuint program, GLuint shader);
+
+extern GLuint GLAPIENTRY
+_mesa_CreateShader(GLenum);
+
+extern GLuint GLAPIENTRY
+_mesa_CreateProgram(void);
+
+extern void GLAPIENTRY
+_mesa_DeleteProgram(GLuint program);
+
+extern void GLAPIENTRY
+_mesa_DeleteShader(GLuint shader);
+
+extern void GLAPIENTRY
+_mesa_DetachShader(GLuint program, GLuint shader);
+
+extern void GLAPIENTRY
+_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
+                         GLsizei *count, GLuint *obj);
+
+extern void GLAPIENTRY
+_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
+                        GLsizei *length, GLchar *infoLog);
+
+extern void GLAPIENTRY
+_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
+                       GLsizei *length, GLchar *infoLog);
+
+
+extern void GLAPIENTRY
+_mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
+                               GLint *range, GLint *precision);
+
+extern void GLAPIENTRY
+_mesa_ReleaseShaderCompiler(void);
+
+extern void GLAPIENTRY
+_mesa_ShaderBinary(GLint n, const GLuint *shaders, GLenum binaryformat,
+                   const void* binary, GLint length);
+
+extern void GLAPIENTRY
+_mesa_ProgramParameteriARB(GLuint program, GLenum pname,
+                           GLint value);
+
+#endif /* SHADERAPI_H */
diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c
new file mode 100644 (file)
index 0000000..129d974
--- /dev/null
@@ -0,0 +1,390 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2004-2008  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2009-2010  VMware, 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
+ * 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 shaderobj.c
+ * \author Brian Paul
+ *
+ */
+
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/hash.h"
+#include "main/shaderobj.h"
+#include "program/program.h"
+#include "program/prog_parameter.h"
+#include "program/prog_uniform.h"
+#include "talloc.h"
+
+/**********************************************************************/
+/*** Shader object functions                                        ***/
+/**********************************************************************/
+
+
+/**
+ * Set ptr to point to sh.
+ * If ptr is pointing to another shader, decrement its refcount (and delete
+ * if refcount hits zero).
+ * Then set ptr to point to sh, incrementing its refcount.
+ */
+void
+_mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr,
+                       struct gl_shader *sh)
+{
+   assert(ptr);
+   if (*ptr == sh) {
+      /* no-op */
+      return;
+   }
+   if (*ptr) {
+      /* Unreference the old shader */
+      GLboolean deleteFlag = GL_FALSE;
+      struct gl_shader *old = *ptr;
+
+      ASSERT(old->RefCount > 0);
+      old->RefCount--;
+      /*printf("SHADER DECR %p (%d) to %d\n",
+        (void*) old, old->Name, old->RefCount);*/
+      deleteFlag = (old->RefCount == 0);
+
+      if (deleteFlag) {
+         _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
+         ctx->Driver.DeleteShader(ctx, old);
+      }
+
+      *ptr = NULL;
+   }
+   assert(!*ptr);
+
+   if (sh) {
+      /* reference new */
+      sh->RefCount++;
+      /*printf("SHADER INCR %p (%d) to %d\n",
+        (void*) sh, sh->Name, sh->RefCount);*/
+      *ptr = sh;
+   }
+}
+
+
+/**
+ * Allocate a new gl_shader object, initialize it.
+ * Called via ctx->Driver.NewShader()
+ */
+struct gl_shader *
+_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type)
+{
+   struct gl_shader *shader;
+   assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER ||
+          type == GL_GEOMETRY_SHADER_ARB);
+   shader = talloc_zero(NULL, struct gl_shader);
+   if (shader) {
+      shader->Type = type;
+      shader->Name = name;
+      shader->RefCount = 1;
+   }
+   return shader;
+}
+
+
+/**
+ * Delete a shader object.
+ * Called via ctx->Driver.DeleteShader().
+ */
+static void
+__mesa_delete_shader(GLcontext *ctx, struct gl_shader *sh)
+{
+   if (sh->Source)
+      free((void *) sh->Source);
+   _mesa_reference_program(ctx, &sh->Program, NULL);
+   talloc_free(sh);
+}
+
+
+/**
+ * Lookup a GLSL shader object.
+ */
+struct gl_shader *
+_mesa_lookup_shader(GLcontext *ctx, GLuint name)
+{
+   if (name) {
+      struct gl_shader *sh = (struct gl_shader *)
+         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
+      /* Note that both gl_shader and gl_shader_program objects are kept
+       * in the same hash table.  Check the object's type to be sure it's
+       * what we're expecting.
+       */
+      if (sh && sh->Type == GL_SHADER_PROGRAM_MESA) {
+         return NULL;
+      }
+      return sh;
+   }
+   return NULL;
+}
+
+
+/**
+ * As above, but record an error if shader is not found.
+ */
+struct gl_shader *
+_mesa_lookup_shader_err(GLcontext *ctx, GLuint name, const char *caller)
+{
+   if (!name) {
+      _mesa_error(ctx, GL_INVALID_VALUE, caller);
+      return NULL;
+   }
+   else {
+      struct gl_shader *sh = (struct gl_shader *)
+         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
+      if (!sh) {
+         _mesa_error(ctx, GL_INVALID_VALUE, caller);
+         return NULL;
+      }
+      if (sh->Type == GL_SHADER_PROGRAM_MESA) {
+         _mesa_error(ctx, GL_INVALID_OPERATION, caller);
+         return NULL;
+      }
+      return sh;
+   }
+}
+
+
+
+/**********************************************************************/
+/*** Shader Program object functions                                ***/
+/**********************************************************************/
+
+
+/**
+ * Set ptr to point to shProg.
+ * If ptr is pointing to another object, decrement its refcount (and delete
+ * if refcount hits zero).
+ * Then set ptr to point to shProg, incrementing its refcount.
+ */
+void
+_mesa_reference_shader_program(GLcontext *ctx,
+                               struct gl_shader_program **ptr,
+                               struct gl_shader_program *shProg)
+{
+   assert(ptr);
+   if (*ptr == shProg) {
+      /* no-op */
+      return;
+   }
+   if (*ptr) {
+      /* Unreference the old shader program */
+      GLboolean deleteFlag = GL_FALSE;
+      struct gl_shader_program *old = *ptr;
+
+      ASSERT(old->RefCount > 0);
+      old->RefCount--;
+#if 0
+      printf("ShaderProgram %p ID=%u  RefCount-- to %d\n",
+             (void *) old, old->Name, old->RefCount);
+#endif
+      deleteFlag = (old->RefCount == 0);
+
+      if (deleteFlag) {
+         _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
+         ctx->Driver.DeleteShaderProgram(ctx, old);
+      }
+
+      *ptr = NULL;
+   }
+   assert(!*ptr);
+
+   if (shProg) {
+      shProg->RefCount++;
+#if 0
+      printf("ShaderProgram %p ID=%u  RefCount++ to %d\n",
+             (void *) shProg, shProg->Name, shProg->RefCount);
+#endif
+      *ptr = shProg;
+   }
+}
+
+
+/**
+ * Allocate a new gl_shader_program object, initialize it.
+ * Called via ctx->Driver.NewShaderProgram()
+ */
+static struct gl_shader_program *
+_mesa_new_shader_program(GLcontext *ctx, GLuint name)
+{
+   struct gl_shader_program *shProg;
+   shProg = talloc_zero(NULL, struct gl_shader_program);
+   if (shProg) {
+      shProg->Type = GL_SHADER_PROGRAM_MESA;
+      shProg->Name = name;
+      shProg->RefCount = 1;
+      shProg->Attributes = _mesa_new_parameter_list();
+#if FEATURE_ARB_geometry_shader4
+      shProg->Geom.VerticesOut = 0;
+      shProg->Geom.InputType = GL_TRIANGLES;
+      shProg->Geom.OutputType = GL_TRIANGLE_STRIP;
+#endif
+   }
+   return shProg;
+}
+
+
+/**
+ * Clear (free) the shader program state that gets produced by linking.
+ */
+void
+_mesa_clear_shader_program_data(GLcontext *ctx,
+                                struct gl_shader_program *shProg)
+{
+   _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
+   _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
+   _mesa_reference_geomprog(ctx, &shProg->GeometryProgram, NULL);
+
+   if (shProg->Uniforms) {
+      _mesa_free_uniform_list(shProg->Uniforms);
+      shProg->Uniforms = NULL;
+   }
+
+   if (shProg->Varying) {
+      _mesa_free_parameter_list(shProg->Varying);
+      shProg->Varying = NULL;
+   }
+}
+
+
+/**
+ * Free all the data that hangs off a shader program object, but not the
+ * object itself.
+ */
+void
+_mesa_free_shader_program_data(GLcontext *ctx,
+                               struct gl_shader_program *shProg)
+{
+   GLuint i;
+
+   assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
+
+   _mesa_clear_shader_program_data(ctx, shProg);
+
+   if (shProg->Attributes) {
+      _mesa_free_parameter_list(shProg->Attributes);
+      shProg->Attributes = NULL;
+   }
+
+   /* detach shaders */
+   for (i = 0; i < shProg->NumShaders; i++) {
+      _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
+   }
+   shProg->NumShaders = 0;
+
+   if (shProg->Shaders) {
+      free(shProg->Shaders);
+      shProg->Shaders = NULL;
+   }
+
+   if (shProg->InfoLog) {
+      talloc_free(shProg->InfoLog);
+      shProg->InfoLog = NULL;
+   }
+
+   /* Transform feedback varying vars */
+   for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
+      free(shProg->TransformFeedback.VaryingNames[i]);
+   }
+   free(shProg->TransformFeedback.VaryingNames);
+   shProg->TransformFeedback.VaryingNames = NULL;
+   shProg->TransformFeedback.NumVarying = 0;
+}
+
+
+/**
+ * Free/delete a shader program object.
+ * Called via ctx->Driver.DeleteShaderProgram().
+ */
+static void
+__mesa_delete_shader_program(GLcontext *ctx, struct gl_shader_program *shProg)
+{
+   _mesa_free_shader_program_data(ctx, shProg);
+
+   talloc_free(shProg);
+}
+
+
+/**
+ * Lookup a GLSL program object.
+ */
+struct gl_shader_program *
+_mesa_lookup_shader_program(GLcontext *ctx, GLuint name)
+{
+   struct gl_shader_program *shProg;
+   if (name) {
+      shProg = (struct gl_shader_program *)
+         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
+      /* Note that both gl_shader and gl_shader_program objects are kept
+       * in the same hash table.  Check the object's type to be sure it's
+       * what we're expecting.
+       */
+      if (shProg && shProg->Type != GL_SHADER_PROGRAM_MESA) {
+         return NULL;
+      }
+      return shProg;
+   }
+   return NULL;
+}
+
+
+/**
+ * As above, but record an error if program is not found.
+ */
+struct gl_shader_program *
+_mesa_lookup_shader_program_err(GLcontext *ctx, GLuint name,
+                                const char *caller)
+{
+   if (!name) {
+      _mesa_error(ctx, GL_INVALID_VALUE, caller);
+      return NULL;
+   }
+   else {
+      struct gl_shader_program *shProg = (struct gl_shader_program *)
+         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
+      if (!shProg) {
+         _mesa_error(ctx, GL_INVALID_VALUE, caller);
+         return NULL;
+      }
+      if (shProg->Type != GL_SHADER_PROGRAM_MESA) {
+         _mesa_error(ctx, GL_INVALID_OPERATION, caller);
+         return NULL;
+      }
+      return shProg;
+   }
+}
+
+
+void
+_mesa_init_shader_object_functions(struct dd_function_table *driver)
+{
+   driver->NewShader = _mesa_new_shader;
+   driver->DeleteShader = __mesa_delete_shader;
+   driver->NewShaderProgram = _mesa_new_shader_program;
+   driver->DeleteShaderProgram = __mesa_delete_shader_program;
+}
diff --git a/src/mesa/main/shaderobj.h b/src/mesa/main/shaderobj.h
new file mode 100644 (file)
index 0000000..b48244d
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.3
+ *
+ * Copyright (C) 2004-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.
+ */
+
+
+#ifndef SHADEROBJ_H
+#define SHADEROBJ_H
+
+
+#include "main/glheader.h"
+#include "main/mtypes.h"
+#include "program/ir_to_mesa.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * Internal functions
+ */
+
+extern void
+_mesa_init_shader_state(GLcontext * ctx);
+
+extern void
+_mesa_free_shader_state(GLcontext *ctx);
+
+
+extern void
+_mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr,
+                       struct gl_shader *sh);
+
+extern struct gl_shader *
+_mesa_lookup_shader(GLcontext *ctx, GLuint name);
+
+extern struct gl_shader *
+_mesa_lookup_shader_err(GLcontext *ctx, GLuint name, const char *caller);
+
+
+
+extern void
+_mesa_reference_shader_program(GLcontext *ctx,
+                               struct gl_shader_program **ptr,
+                               struct gl_shader_program *shProg);
+
+extern struct gl_shader *
+_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type);
+
+extern struct gl_shader_program *
+_mesa_lookup_shader_program(GLcontext *ctx, GLuint name);
+
+extern struct gl_shader_program *
+_mesa_lookup_shader_program_err(GLcontext *ctx, GLuint name,
+                                const char *caller);
+
+extern void
+_mesa_clear_shader_program_data(GLcontext *ctx,
+                                struct gl_shader_program *shProg);
+
+extern void
+_mesa_free_shader_program_data(GLcontext *ctx,
+                               struct gl_shader_program *shProg);
+
+
+
+extern void
+_mesa_init_shader_object_functions(struct dd_function_table *driver);
+
+extern void
+_mesa_init_shader_state(GLcontext *ctx);
+
+extern void
+_mesa_free_shader_state(GLcontext *ctx);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif /* SHADEROBJ_H */
diff --git a/src/mesa/main/shaders.c b/src/mesa/main/shaders.c
deleted file mode 100644 (file)
index 65f1ee3..0000000
+++ /dev/null
@@ -1,932 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.3
- *
- * Copyright (C) 2004-2008  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#include "glheader.h"
-#include "context.h"
-#include "shaders.h"
-#include "shader/shader_api.h"
-#include "main/dispatch.h"
-
-
-/** Define this to enable shader substitution (see below) */
-#define SHADER_SUBST 0
-
-
-
-/**
- * These are basically just wrappers/adaptors for calling the
- * ctx->Driver.foobar() GLSL-related functions.
- *
- * Things are biased toward the OpenGL 2.0 functions rather than the
- * ARB extensions (i.e. the ARB functions are layered on the 2.0 functions).
- *
- * The general idea here is to allow enough modularity such that a
- * completely different GLSL implemenation can be plugged in and co-exist
- * with Mesa's native GLSL code.
- */
-
-
-
-void GLAPIENTRY
-_mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.AttachShader(ctx, program, shader);
-}
-
-
-void GLAPIENTRY
-_mesa_AttachShader(GLuint program, GLuint shader)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.AttachShader(ctx, program, shader);
-}
-
-
-void GLAPIENTRY
-_mesa_BindAttribLocationARB(GLhandleARB program, GLuint index,
-                            const GLcharARB *name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.BindAttribLocation(ctx, program, index, name);
-}
-
-
-void GLAPIENTRY
-_mesa_CompileShaderARB(GLhandleARB shaderObj)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.CompileShader(ctx, shaderObj);
-}
-
-
-GLuint GLAPIENTRY
-_mesa_CreateShader(GLenum type)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return ctx->Driver.CreateShader(ctx, type);
-}
-
-
-GLhandleARB GLAPIENTRY
-_mesa_CreateShaderObjectARB(GLenum type)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return ctx->Driver.CreateShader(ctx, type);
-}
-
-
-GLuint GLAPIENTRY
-_mesa_CreateProgram(void)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return ctx->Driver.CreateProgram(ctx);
-}
-
-
-GLhandleARB GLAPIENTRY
-_mesa_CreateProgramObjectARB(void)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return ctx->Driver.CreateProgram(ctx);
-}
-
-
-void GLAPIENTRY
-_mesa_DeleteObjectARB(GLhandleARB obj)
-{
-   if (obj) {
-      GET_CURRENT_CONTEXT(ctx);
-      if (ctx->Driver.IsProgram(ctx, obj)) {
-         ctx->Driver.DeleteProgram2(ctx, obj);
-      }
-      else if (ctx->Driver.IsShader(ctx, obj)) {
-         ctx->Driver.DeleteShader(ctx, obj);
-      }
-      else {
-         /* error? */
-      }
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_DeleteProgram(GLuint name)
-{
-   if (name) {
-      GET_CURRENT_CONTEXT(ctx);
-      ctx->Driver.DeleteProgram2(ctx, name);
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_DeleteShader(GLuint name)
-{
-   if (name) {
-      GET_CURRENT_CONTEXT(ctx);
-      ctx->Driver.DeleteShader(ctx, name);
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.DetachShader(ctx, program, shader);
-}
-
-
-void GLAPIENTRY
-_mesa_DetachShader(GLuint program, GLuint shader)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.DetachShader(ctx, program, shader);
-}
-
-
-void GLAPIENTRY
-_mesa_GetActiveAttribARB(GLhandleARB program, GLuint index,
-                         GLsizei maxLength, GLsizei * length, GLint * size,
-                         GLenum * type, GLcharARB * name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetActiveAttrib(ctx, program, index, maxLength, length, size,
-                               type, name);
-}
-
-
-void GLAPIENTRY
-_mesa_GetActiveUniformARB(GLhandleARB program, GLuint index,
-                          GLsizei maxLength, GLsizei * length, GLint * size,
-                          GLenum * type, GLcharARB * name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetActiveUniform(ctx, program, index, maxLength, length, size,
-                                type, name);
-}
-
-
-void GLAPIENTRY
-_mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
-                            GLsizei * count, GLhandleARB * obj)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetAttachedShaders(ctx, container, maxCount, count, obj);
-}
-
-
-void GLAPIENTRY
-_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
-                         GLsizei *count, GLuint *obj)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetAttachedShaders(ctx, program, maxCount, count, obj);
-}
-
-
-GLint GLAPIENTRY
-_mesa_GetAttribLocationARB(GLhandleARB program, const GLcharARB * name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return ctx->Driver.GetAttribLocation(ctx, program, name);
-}
-
-
-void GLAPIENTRY
-_mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
-                    GLcharARB * infoLog)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   /* Implement in terms of GetProgramInfoLog, GetShaderInfoLog */
-   if (ctx->Driver.IsProgram(ctx, object)) {
-      ctx->Driver.GetProgramInfoLog(ctx, object, maxLength, length, infoLog);
-   }
-   else if (ctx->Driver.IsShader(ctx, object)) {
-      ctx->Driver.GetShaderInfoLog(ctx, object, maxLength, length, infoLog);
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB");
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   /* Implement in terms of GetProgramiv, GetShaderiv */
-   if (ctx->Driver.IsProgram(ctx, object)) {
-      if (pname == GL_OBJECT_TYPE_ARB) {
-        *params = GL_PROGRAM_OBJECT_ARB;
-      }
-      else {
-        ctx->Driver.GetProgramiv(ctx, object, pname, params);
-      }
-   }
-   else if (ctx->Driver.IsShader(ctx, object)) {
-      if (pname == GL_OBJECT_TYPE_ARB) {
-        *params = GL_SHADER_OBJECT_ARB;
-      }
-      else {
-        ctx->Driver.GetShaderiv(ctx, object, pname, params);
-      }
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB");
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
-                              GLfloat *params)
-{
-   GLint iparams[1];  /* XXX is one element enough? */
-   _mesa_GetObjectParameterivARB(object, pname, iparams);
-   params[0] = (GLfloat) iparams[0];
-}
-
-
-void GLAPIENTRY
-_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetProgramiv(ctx, program, pname, params);
-}
-
-
-void GLAPIENTRY
-_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetShaderiv(ctx, shader, pname, params);
-}
-
-
-void GLAPIENTRY
-_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
-                        GLsizei *length, GLchar *infoLog)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetProgramInfoLog(ctx, program, bufSize, length, infoLog);
-}
-
-
-void GLAPIENTRY
-_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
-                       GLsizei *length, GLchar *infoLog)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetShaderInfoLog(ctx, shader, bufSize, length, infoLog);
-}
-
-
-void GLAPIENTRY
-_mesa_GetShaderSourceARB(GLhandleARB shader, GLsizei maxLength,
-                         GLsizei *length, GLcharARB *sourceOut)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetShaderSource(ctx, shader, maxLength, length, sourceOut);
-}
-
-
-void GLAPIENTRY
-_mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat * params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetUniformfv(ctx, program, location, params);
-}
-
-
-void GLAPIENTRY
-_mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint * params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.GetUniformiv(ctx, program, location, params);
-}
-
-
-
-#if 0
-GLint GLAPIENTRY
-_mesa_GetUniformLocation(GLuint program, const GLcharARB *name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return ctx->Driver.GetUniformLocation(ctx, program, name);
-}
-#endif
-
-
-GLhandleARB GLAPIENTRY
-_mesa_GetHandleARB(GLenum pname)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return ctx->Driver.GetHandle(ctx, pname);
-}
-
-
-GLint GLAPIENTRY
-_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return ctx->Driver.GetUniformLocation(ctx, programObj, name);
-}
-
-
-GLboolean GLAPIENTRY
-_mesa_IsProgram(GLuint name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return ctx->Driver.IsProgram(ctx, name);
-}
-
-
-GLboolean GLAPIENTRY
-_mesa_IsShader(GLuint name)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   return ctx->Driver.IsShader(ctx, name);
-}
-
-
-void GLAPIENTRY
-_mesa_LinkProgramARB(GLhandleARB programObj)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.LinkProgram(ctx, programObj);
-}
-
-
-
-/**
- * Read shader source code from a file.
- * Useful for debugging to override an app's shader.
- */
-static GLcharARB *
-_mesa_read_shader(const char *fname)
-{
-   const int max = 50*1000;
-   FILE *f = fopen(fname, "r");
-   GLcharARB *buffer, *shader;
-   int len;
-
-   if (!f) {
-      return NULL;
-   }
-
-   buffer = (char *) malloc(max);
-   len = fread(buffer, 1, max, f);
-   buffer[len] = 0;
-
-   fclose(f);
-
-   shader = _mesa_strdup(buffer);
-   free(buffer);
-
-   return shader;
-}
-
-
-/**
- * Called via glShaderSource() and glShaderSourceARB() API functions.
- * Basically, concatenate the source code strings into one long string
- * and pass it to ctx->Driver.ShaderSource().
- */
-void GLAPIENTRY
-_mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
-                      const GLcharARB ** string, const GLint * length)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLint *offsets;
-   GLsizei i, totalLength;
-   GLcharARB *source;
-   GLuint checksum;
-
-   if (!shaderObj || string == NULL) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
-      return;
-   }
-
-   /*
-    * This array holds offsets of where the appropriate string ends, thus the
-    * last element will be set to the total length of the source code.
-    */
-   offsets = (GLint *) malloc(count * sizeof(GLint));
-   if (offsets == NULL) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
-      return;
-   }
-
-   for (i = 0; i < count; i++) {
-      if (string[i] == NULL) {
-         free((GLvoid *) offsets);
-         _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderSourceARB(null string)");
-         return;
-      }
-      if (length == NULL || length[i] < 0)
-         offsets[i] = strlen(string[i]);
-      else
-         offsets[i] = length[i];
-      /* accumulate string lengths */
-      if (i > 0)
-         offsets[i] += offsets[i - 1];
-   }
-
-   /* Total length of source string is sum off all strings plus two.
-    * One extra byte for terminating zero, another extra byte to silence
-    * valgrind warnings in the parser/grammer code.
-    */
-   totalLength = offsets[count - 1] + 2;
-   source = (GLcharARB *) malloc(totalLength * sizeof(GLcharARB));
-   if (source == NULL) {
-      free((GLvoid *) offsets);
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
-      return;
-   }
-
-   for (i = 0; i < count; i++) {
-      GLint start = (i > 0) ? offsets[i - 1] : 0;
-      memcpy(source + start, string[i],
-             (offsets[i] - start) * sizeof(GLcharARB));
-   }
-   source[totalLength - 1] = '\0';
-   source[totalLength - 2] = '\0';
-
-   if (SHADER_SUBST) {
-      /* Compute the shader's source code checksum then try to open a file
-       * named newshader_<CHECKSUM>.  If it exists, use it in place of the
-       * original shader source code.  For debugging.
-       */
-      char filename[100];
-      GLcharARB *newSource;
-
-      checksum = _mesa_str_checksum(source);
-
-      _mesa_snprintf(filename, sizeof(filename), "newshader_%d", checksum);
-
-      newSource = _mesa_read_shader(filename);
-      if (newSource) {
-         fprintf(stderr, "Mesa: Replacing shader %u chksum=%d with %s\n",
-                       shaderObj, checksum, filename);
-         free(source);
-         source = newSource;
-      }
-   }      
-
-   ctx->Driver.ShaderSource(ctx, shaderObj, source);
-
-   if (SHADER_SUBST) {
-      struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj);
-      if (sh)
-         sh->SourceChecksum = checksum; /* save original checksum */
-   }
-
-   free(offsets);
-}
-
-
-void GLAPIENTRY
-_mesa_Uniform1fARB(GLint location, GLfloat v0)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, 1, &v0, GL_FLOAT);
-}
-
-void GLAPIENTRY
-_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLfloat v[2];
-   v[0] = v0;
-   v[1] = v1;
-   ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC2);
-}
-
-void GLAPIENTRY
-_mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLfloat v[3];
-   v[0] = v0;
-   v[1] = v1;
-   v[2] = v2;
-   ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC3);
-}
-
-void GLAPIENTRY
-_mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
-                   GLfloat v3)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLfloat v[4];
-   v[0] = v0;
-   v[1] = v1;
-   v[2] = v2;
-   v[3] = v3;
-   ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC4);
-}
-
-void GLAPIENTRY
-_mesa_Uniform1iARB(GLint location, GLint v0)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, 1, &v0, GL_INT);
-}
-
-void GLAPIENTRY
-_mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLint v[2];
-   v[0] = v0;
-   v[1] = v1;
-   ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC2);
-}
-
-void GLAPIENTRY
-_mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLint v[3];
-   v[0] = v0;
-   v[1] = v1;
-   v[2] = v2;
-   ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC3);
-}
-
-void GLAPIENTRY
-_mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLint v[4];
-   v[0] = v0;
-   v[1] = v1;
-   v[2] = v2;
-   v[3] = v3;
-   ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC4);
-}
-
-void GLAPIENTRY
-_mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT);
-}
-
-void GLAPIENTRY
-_mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC2);
-}
-
-void GLAPIENTRY
-_mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC3);
-}
-
-void GLAPIENTRY
-_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC4);
-}
-
-void GLAPIENTRY
-_mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_INT);
-}
-
-void GLAPIENTRY
-_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC2);
-}
-
-void GLAPIENTRY
-_mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC3);
-}
-
-void GLAPIENTRY
-_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC4);
-}
-
-
-/** OpenGL 3.0 GLuint-valued functions **/
-void GLAPIENTRY
-_mesa_Uniform1ui(GLint location, GLuint v0)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, 1, &v0, GL_UNSIGNED_INT);
-}
-
-void GLAPIENTRY
-_mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLuint v[2];
-   v[0] = v0;
-   v[1] = v1;
-   ctx->Driver.Uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC2);
-}
-
-void GLAPIENTRY
-_mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLuint v[3];
-   v[0] = v0;
-   v[1] = v1;
-   v[2] = v2;
-   ctx->Driver.Uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC3);
-}
-
-void GLAPIENTRY
-_mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLuint v[4];
-   v[0] = v0;
-   v[1] = v1;
-   v[2] = v2;
-   v[3] = v3;
-   ctx->Driver.Uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC4);
-}
-
-void GLAPIENTRY
-_mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_UNSIGNED_INT);
-}
-
-void GLAPIENTRY
-_mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC2);
-}
-
-void GLAPIENTRY
-_mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC3);
-}
-
-void GLAPIENTRY
-_mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.Uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC4);
-}
-
-
-
-void GLAPIENTRY
-_mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
-                          const GLfloat * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 2, 2, location, count, transpose, value);
-}
-
-void GLAPIENTRY
-_mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
-                          const GLfloat * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 3, 3, location, count, transpose, value);
-}
-
-void GLAPIENTRY
-_mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
-                          const GLfloat * value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 4, 4, location, count, transpose, value);
-}
-
-
-/**
- * Non-square UniformMatrix are OpenGL 2.1
- */
-void GLAPIENTRY
-_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 2, 3, location, count, transpose, value);
-}
-
-void GLAPIENTRY
-_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 3, 2, location, count, transpose, value);
-}
-
-void GLAPIENTRY
-_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 2, 4, location, count, transpose, value);
-}
-
-void GLAPIENTRY
-_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 4, 2, location, count, transpose, value);
-}
-
-void GLAPIENTRY
-_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 3, 4, location, count, transpose, value);
-}
-
-void GLAPIENTRY
-_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.UniformMatrix(ctx, 4, 3, location, count, transpose, value);
-}
-
-
-void GLAPIENTRY
-_mesa_UseProgramObjectARB(GLhandleARB program)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
-   ctx->Driver.UseProgram(ctx, program);
-}
-
-
-void GLAPIENTRY
-_mesa_ValidateProgramARB(GLhandleARB program)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ctx->Driver.ValidateProgram(ctx, program);
-}
-
-#if FEATURE_ES2
-
-void GLAPIENTRY
-_mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
-                               GLint* range, GLint* precision)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
-}
-
-
-void GLAPIENTRY
-_mesa_ReleaseShaderCompiler(void)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
-}
-
-
-void GLAPIENTRY
-_mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
-                   const void* binary, GLint length)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   _mesa_error(ctx, GL_INVALID_OPERATION, __FUNCTION__);
-}
-
-#endif
-
-
-/**
- * Plug in shader-related functions into API dispatch table.
- */
-void
-_mesa_init_shader_dispatch(struct _glapi_table *exec)
-{
-#if FEATURE_GL
-   /* GL_ARB_vertex/fragment_shader */
-   SET_DeleteObjectARB(exec, _mesa_DeleteObjectARB);
-   SET_GetHandleARB(exec, _mesa_GetHandleARB);
-   SET_DetachObjectARB(exec, _mesa_DetachObjectARB);
-   SET_CreateShaderObjectARB(exec, _mesa_CreateShaderObjectARB);
-   SET_ShaderSourceARB(exec, _mesa_ShaderSourceARB);
-   SET_CompileShaderARB(exec, _mesa_CompileShaderARB);
-   SET_CreateProgramObjectARB(exec, _mesa_CreateProgramObjectARB);
-   SET_AttachObjectARB(exec, _mesa_AttachObjectARB);
-   SET_LinkProgramARB(exec, _mesa_LinkProgramARB);
-   SET_UseProgramObjectARB(exec, _mesa_UseProgramObjectARB);
-   SET_ValidateProgramARB(exec, _mesa_ValidateProgramARB);
-   SET_Uniform1fARB(exec, _mesa_Uniform1fARB);
-   SET_Uniform2fARB(exec, _mesa_Uniform2fARB);
-   SET_Uniform3fARB(exec, _mesa_Uniform3fARB);
-   SET_Uniform4fARB(exec, _mesa_Uniform4fARB);
-   SET_Uniform1iARB(exec, _mesa_Uniform1iARB);
-   SET_Uniform2iARB(exec, _mesa_Uniform2iARB);
-   SET_Uniform3iARB(exec, _mesa_Uniform3iARB);
-   SET_Uniform4iARB(exec, _mesa_Uniform4iARB);
-   SET_Uniform1fvARB(exec, _mesa_Uniform1fvARB);
-   SET_Uniform2fvARB(exec, _mesa_Uniform2fvARB);
-   SET_Uniform3fvARB(exec, _mesa_Uniform3fvARB);
-   SET_Uniform4fvARB(exec, _mesa_Uniform4fvARB);
-   SET_Uniform1ivARB(exec, _mesa_Uniform1ivARB);
-   SET_Uniform2ivARB(exec, _mesa_Uniform2ivARB);
-   SET_Uniform3ivARB(exec, _mesa_Uniform3ivARB);
-   SET_Uniform4ivARB(exec, _mesa_Uniform4ivARB);
-   SET_UniformMatrix2fvARB(exec, _mesa_UniformMatrix2fvARB);
-   SET_UniformMatrix3fvARB(exec, _mesa_UniformMatrix3fvARB);
-   SET_UniformMatrix4fvARB(exec, _mesa_UniformMatrix4fvARB);
-   SET_GetObjectParameterfvARB(exec, _mesa_GetObjectParameterfvARB);
-   SET_GetObjectParameterivARB(exec, _mesa_GetObjectParameterivARB);
-   SET_GetInfoLogARB(exec, _mesa_GetInfoLogARB);
-   SET_GetAttachedObjectsARB(exec, _mesa_GetAttachedObjectsARB);
-   SET_GetUniformLocationARB(exec, _mesa_GetUniformLocationARB);
-   SET_GetActiveUniformARB(exec, _mesa_GetActiveUniformARB);
-   SET_GetUniformfvARB(exec, _mesa_GetUniformfvARB);
-   SET_GetUniformivARB(exec, _mesa_GetUniformivARB);
-   SET_GetShaderSourceARB(exec, _mesa_GetShaderSourceARB);
-
-   /* OpenGL 2.0 */
-   SET_AttachShader(exec, _mesa_AttachShader);
-   SET_CreateProgram(exec, _mesa_CreateProgram);
-   SET_CreateShader(exec, _mesa_CreateShader);
-   SET_DeleteProgram(exec, _mesa_DeleteProgram);
-   SET_DeleteShader(exec, _mesa_DeleteShader);
-   SET_DetachShader(exec, _mesa_DetachShader);
-   SET_GetAttachedShaders(exec, _mesa_GetAttachedShaders);
-   SET_GetProgramiv(exec, _mesa_GetProgramiv);
-   SET_GetProgramInfoLog(exec, _mesa_GetProgramInfoLog);
-   SET_GetShaderiv(exec, _mesa_GetShaderiv);
-   SET_GetShaderInfoLog(exec, _mesa_GetShaderInfoLog);
-   SET_IsProgram(exec, _mesa_IsProgram);
-   SET_IsShader(exec, _mesa_IsShader);
-
-   /* OpenGL 2.1 */
-   SET_UniformMatrix2x3fv(exec, _mesa_UniformMatrix2x3fv);
-   SET_UniformMatrix3x2fv(exec, _mesa_UniformMatrix3x2fv);
-   SET_UniformMatrix2x4fv(exec, _mesa_UniformMatrix2x4fv);
-   SET_UniformMatrix4x2fv(exec, _mesa_UniformMatrix4x2fv);
-   SET_UniformMatrix3x4fv(exec, _mesa_UniformMatrix3x4fv);
-   SET_UniformMatrix4x3fv(exec, _mesa_UniformMatrix4x3fv);
-
-#if FEATURE_ARB_vertex_shader
-   SET_BindAttribLocationARB(exec, _mesa_BindAttribLocationARB);
-   SET_GetActiveAttribARB(exec, _mesa_GetActiveAttribARB);
-   SET_GetAttribLocationARB(exec, _mesa_GetAttribLocationARB);
-#endif
-
-   /* OpenGL 3.0 */
-   /* XXX finish dispatch */
-   (void) _mesa_Uniform1ui;
-   (void) _mesa_Uniform2ui;
-   (void) _mesa_Uniform3ui;
-   (void) _mesa_Uniform4ui;
-   (void) _mesa_Uniform1uiv;
-   (void) _mesa_Uniform2uiv;
-   (void) _mesa_Uniform3uiv;
-   (void) _mesa_Uniform4uiv;
-#endif /* FEATURE_GL */
-}
diff --git a/src/mesa/main/shaders.h b/src/mesa/main/shaders.h
deleted file mode 100644 (file)
index af65b2d..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.3
- *
- * Copyright (C) 2004-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.
- */
-
-
-#ifndef SHADERS_H
-#define SHADERS_H
-
-
-#include "glheader.h"
-#include "mtypes.h"
-
-extern void
-_mesa_init_shader_dispatch(struct _glapi_table *exec);
-
-extern void GLAPIENTRY
-_mesa_DeleteObjectARB(GLhandleARB obj);
-
-extern GLhandleARB GLAPIENTRY
-_mesa_GetHandleARB(GLenum pname);
-
-extern void GLAPIENTRY
-_mesa_DetachObjectARB (GLhandleARB, GLhandleARB);
-
-extern GLhandleARB GLAPIENTRY
-_mesa_CreateShaderObjectARB (GLenum);
-
-extern void GLAPIENTRY
-_mesa_ShaderSourceARB (GLhandleARB, GLsizei, const GLcharARB* *, const GLint *);
-
-extern void  GLAPIENTRY
-_mesa_CompileShaderARB (GLhandleARB);
-
-extern GLhandleARB GLAPIENTRY
-_mesa_CreateProgramObjectARB (void);
-
-extern void GLAPIENTRY
-_mesa_AttachObjectARB (GLhandleARB, GLhandleARB);
-
-extern void GLAPIENTRY
-_mesa_LinkProgramARB (GLhandleARB);
-
-extern void GLAPIENTRY
-_mesa_UseProgramObjectARB (GLhandleARB);
-
-extern void GLAPIENTRY
-_mesa_ValidateProgramARB (GLhandleARB);
-
-extern void GLAPIENTRY
-_mesa_Uniform1fARB (GLint, GLfloat);
-
-extern void GLAPIENTRY
-_mesa_Uniform2fARB (GLint, GLfloat, GLfloat);
-
-extern void GLAPIENTRY
-_mesa_Uniform3fARB (GLint, GLfloat, GLfloat, GLfloat);
-
-extern void GLAPIENTRY
-_mesa_Uniform4fARB (GLint, GLfloat, GLfloat, GLfloat, GLfloat);
-
-extern void GLAPIENTRY
-_mesa_Uniform1iARB (GLint, GLint);
-
-extern void GLAPIENTRY
-_mesa_Uniform2iARB (GLint, GLint, GLint);
-
-extern void GLAPIENTRY
-_mesa_Uniform3iARB (GLint, GLint, GLint, GLint);
-
-extern void GLAPIENTRY
-_mesa_Uniform4iARB (GLint, GLint, GLint, GLint, GLint);
-
-extern void GLAPIENTRY
-_mesa_Uniform1fvARB (GLint, GLsizei, const GLfloat *);
-
-extern void GLAPIENTRY
-_mesa_Uniform2fvARB (GLint, GLsizei, const GLfloat *);
-
-extern void GLAPIENTRY
-_mesa_Uniform3fvARB (GLint, GLsizei, const GLfloat *);
-
-extern void GLAPIENTRY
-_mesa_Uniform4fvARB (GLint, GLsizei, const GLfloat *);
-
-extern void GLAPIENTRY
-_mesa_Uniform1ivARB (GLint, GLsizei, const GLint *);
-
-extern void GLAPIENTRY
-_mesa_Uniform2ivARB (GLint, GLsizei, const GLint *);
-
-extern void GLAPIENTRY
-_mesa_Uniform3ivARB (GLint, GLsizei, const GLint *);
-
-extern void GLAPIENTRY
-_mesa_Uniform4ivARB (GLint, GLsizei, const GLint *);
-
-extern void GLAPIENTRY
-_mesa_Uniform1ui(GLint location, GLuint v0);
-
-extern void GLAPIENTRY
-_mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1);
-
-extern void GLAPIENTRY
-_mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2);
-
-extern void GLAPIENTRY
-_mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
-
-extern void GLAPIENTRY
-_mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value);
-
-extern void GLAPIENTRY
-_mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value);
-
-extern void GLAPIENTRY
-_mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value);
-
-extern void GLAPIENTRY
-_mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value);
-
-
-extern void GLAPIENTRY
-_mesa_UniformMatrix2fvARB (GLint, GLsizei, GLboolean, const GLfloat *);
-
-extern void GLAPIENTRY
-_mesa_UniformMatrix3fvARB (GLint, GLsizei, GLboolean, const GLfloat *);
-
-extern void GLAPIENTRY
-_mesa_UniformMatrix4fvARB (GLint, GLsizei, GLboolean, const GLfloat *);
-
-extern void GLAPIENTRY
-_mesa_GetObjectParameterfvARB (GLhandleARB, GLenum, GLfloat *);
-
-extern void GLAPIENTRY
-_mesa_GetObjectParameterivARB (GLhandleARB, GLenum, GLint *);
-
-extern void GLAPIENTRY
-_mesa_GetInfoLogARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *);
-
-extern void GLAPIENTRY
-_mesa_GetAttachedObjectsARB (GLhandleARB, GLsizei, GLsizei *, GLhandleARB *);
-
-extern GLint GLAPIENTRY
-_mesa_GetUniformLocationARB (GLhandleARB, const GLcharARB *);
-
-extern void GLAPIENTRY
-_mesa_GetActiveUniformARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *);
-
-extern void GLAPIENTRY
-_mesa_GetUniformfvARB (GLhandleARB, GLint, GLfloat *);
-
-extern void GLAPIENTRY
-_mesa_GetUniformivARB (GLhandleARB, GLint, GLint *);
-
-extern void GLAPIENTRY
-_mesa_GetShaderSourceARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *);
-
-#if FEATURE_ARB_vertex_shader
-
-extern void GLAPIENTRY
-_mesa_BindAttribLocationARB (GLhandleARB, GLuint, const GLcharARB *);
-
-extern void GLAPIENTRY
-_mesa_GetActiveAttribARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *);
-
-extern GLint GLAPIENTRY
-_mesa_GetAttribLocationARB (GLhandleARB, const GLcharARB *);
-
-#endif /* FEATURE_ARB_vertex_shader */
-
-
-/* 2.0 */
-extern void GLAPIENTRY
-_mesa_AttachShader(GLuint program, GLuint shader);
-
-extern GLuint GLAPIENTRY
-_mesa_CreateShader(GLenum);
-
-extern GLuint GLAPIENTRY
-_mesa_CreateProgram(void);
-
-extern void GLAPIENTRY
-_mesa_DeleteProgram(GLuint program);
-
-extern void GLAPIENTRY
-_mesa_DeleteShader(GLuint shader);
-
-extern void GLAPIENTRY
-_mesa_DetachShader(GLuint program, GLuint shader);
-
-extern void GLAPIENTRY
-_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
-                         GLsizei *count, GLuint *obj);
-
-extern void GLAPIENTRY
-_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params);
-
-extern void GLAPIENTRY
-_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
-                        GLsizei *length, GLchar *infoLog);
-
-extern void GLAPIENTRY
-_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params);
-
-extern void GLAPIENTRY
-_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
-                       GLsizei *length, GLchar *infoLog);
-
-extern GLboolean GLAPIENTRY
-_mesa_IsProgram(GLuint program);
-
-extern GLboolean GLAPIENTRY
-_mesa_IsShader(GLuint shader);
-
-
-
-/* 2.1 */
-extern void GLAPIENTRY
-_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value);
-
-extern void GLAPIENTRY
-_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value);
-
-extern void GLAPIENTRY
-_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value);
-
-extern void GLAPIENTRY
-_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value);
-
-extern void GLAPIENTRY
-_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value);
-
-extern void GLAPIENTRY
-_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
-                         const GLfloat *value);
-
-/* GLES 2.0 */
-extern void GLAPIENTRY
-_mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
-                               GLint* range, GLint* precision);
-
-extern void GLAPIENTRY
-_mesa_ReleaseShaderCompiler(void);
-
-extern void GLAPIENTRY
-_mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
-                   const void* binary, GLint length);
-
-#endif /* SHADERS_H */
index e364e24048ff97a83c53fd07f3f9e1a82d7a4fc0..f9d10f3bbea001d3045613c5fd4210eabb19bc69 100644 (file)
 #include "mtypes.h"
 #include "hash.h"
 #include "arrayobj.h"
+#if FEATURE_ATI_fragment_shader
+#include "atifragshader.h"
+#endif
 #include "bufferobj.h"
 #include "shared.h"
-#include "shader/program.h"
-#include "shader/shader_api.h"
+#include "program/program.h"
 #include "dlist.h"
-#if FEATURE_ATI_fragment_shader
-#include "shader/atifragshader.h"
-#endif
+#include "shaderobj.h"
 #if FEATURE_ARB_sync
 #include "syncobj.h"
 #endif
@@ -228,12 +228,12 @@ delete_shader_cb(GLuint id, void *data, void *userData)
    GLcontext *ctx = (GLcontext *) userData;
    struct gl_shader *sh = (struct gl_shader *) data;
    if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER) {
-      _mesa_free_shader(ctx, sh);
+      ctx->Driver.DeleteShader(ctx, sh);
    }
    else {
       struct gl_shader_program *shProg = (struct gl_shader_program *) data;
       ASSERT(shProg->Type == GL_SHADER_PROGRAM_MESA);
-      _mesa_free_shader_program(ctx, shProg);
+      ctx->Driver.DeleteShaderProgram(ctx, shProg);
    }
 }
 
index b971cc976eed7116a8a17c71432e0c13dd35d982..4a3dffe4cf82bf4ee126928b5fc72ce340bbc4c1 100644 (file)
@@ -41,8 +41,8 @@
 #include "light.h"
 #include "matrix.h"
 #include "pixel.h"
-#include "shader/program.h"
-#include "shader/prog_parameter.h"
+#include "program/program.h"
+#include "program/prog_parameter.h"
 #include "state.h"
 #include "stencil.h"
 #include "texenvprogram.h"
@@ -250,6 +250,7 @@ update_program(GLcontext *ctx)
    const struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
    const struct gl_vertex_program *prevVP = ctx->VertexProgram._Current;
    const struct gl_fragment_program *prevFP = ctx->FragmentProgram._Current;
+   const struct gl_geometry_program *prevGP = ctx->GeometryProgram._Current;
    GLbitfield new_state = 0x0;
 
    /*
@@ -291,6 +292,15 @@ update_program(GLcontext *ctx)
       _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL);
    }
 
+   if (shProg && shProg->LinkStatus && shProg->GeometryProgram) {
+      /* Use shader programs */
+      _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current,
+                               shProg->GeometryProgram);
+   } else {
+      /* no fragment program */
+      _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL);
+   }
+
    /* Examine vertex program after fragment program as
     * _mesa_get_fixed_func_vertex_program() needs to know active
     * fragprog inputs.
@@ -327,7 +337,15 @@ update_program(GLcontext *ctx)
                           (struct gl_program *) ctx->FragmentProgram._Current);
       }
    }
-   
+
+   if (ctx->GeometryProgram._Current != prevGP) {
+      new_state |= _NEW_PROGRAM;
+      if (ctx->Driver.BindProgram) {
+         ctx->Driver.BindProgram(ctx, MESA_GEOMETRY_PROGRAM,
+                            (struct gl_program *) ctx->GeometryProgram._Current);
+      }
+   }
+
    if (ctx->VertexProgram._Current != prevVP) {
       new_state |= _NEW_PROGRAM;
       if (ctx->Driver.BindProgram) {
@@ -356,6 +374,16 @@ update_program_constants(GLcontext *ctx)
       }
    }
 
+   if (ctx->GeometryProgram._Current) {
+      const struct gl_program_parameter_list *params =
+         ctx->GeometryProgram._Current->Base.Parameters;
+      /*FIXME: StateFlags is always 0 because we have unnamed constant
+       *       not state changes */
+      if (params /*&& params->StateFlags & ctx->NewState*/) {
+         new_state |= _NEW_PROGRAM_CONSTANTS;
+      }
+   }
+
    if (ctx->VertexProgram._Current) {
       const struct gl_program_parameter_list *params =
          ctx->VertexProgram._Current->Base.Parameters;
@@ -537,7 +565,7 @@ _mesa_update_state_locked( GLcontext *ctx )
 
    /* Determine which state flags effect vertex/fragment program state */
    if (ctx->FragmentProgram._MaintainTexEnvProgram) {
-      prog_flags |= (_NEW_TEXTURE | _NEW_FOG |
+      prog_flags |= (_NEW_BUFFERS | _NEW_TEXTURE | _NEW_FOG |
                     _NEW_ARRAY | _NEW_LIGHT | _NEW_POINT | _NEW_RENDERMODE |
                     _NEW_PROGRAM);
    }
index 964ba13c70068f95513c5c95fd1c1ee135cba7b0..9fa8f02a8b053ebba5d534d5894f61ec04f1baa9 100644 (file)
 
 #include "glheader.h"
 #include "imports.h"
-#include "shader/program.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_cache.h"
-#include "shader/prog_instruction.h"
-#include "shader/prog_print.h"
-#include "shader/prog_statevars.h"
-#include "shader/programopt.h"
+#include "program/program.h"
+#include "program/prog_parameter.h"
+#include "program/prog_cache.h"
+#include "program/prog_instruction.h"
+#include "program/prog_print.h"
+#include "program/prog_statevars.h"
+#include "program/programopt.h"
 #include "texenvprogram.h"
 
 
@@ -98,6 +98,7 @@ struct state_key {
    GLuint fog_enabled:1;
    GLuint fog_mode:2;          /**< FOG_x */
    GLuint inputs_available:12;
+   GLuint num_draw_buffers:4;
 
    /* NOTE: This array of structs must be last! (see "keySize" below) */
    struct {
@@ -485,6 +486,9 @@ static GLuint make_state_key( GLcontext *ctx,  struct state_key *key )
       inputs_referenced |= FRAG_BIT_FOGC; /* maybe */
    }
 
+   /* _NEW_BUFFERS */
+   key->num_draw_buffers = ctx->DrawBuffer->_NumColorDrawBuffers;
+
    key->inputs_available = (inputs_available & inputs_referenced);
 
    /* compute size of state key, ignoring unused texture units */
@@ -1199,11 +1203,14 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit)
    else
       alpha_saturate = GL_FALSE;
 
-   /* If this is the very last calculation, emit direct to output reg:
+   /* If this is the very last calculation (and various other conditions
+    * are met), emit directly to the color output register.  Otherwise,
+    * emit to a temporary register.
     */
    if (key->separate_specular ||
        unit != p->last_tex_stage ||
        alpha_shift ||
+       key->num_draw_buffers != 1 ||
        rgb_shift)
       dest = get_temp( p );
    else
@@ -1438,10 +1445,10 @@ create_new_program(GLcontext *ctx, struct state_key *key,
    p.program->Base.Parameters = _mesa_new_parameter_list();
    p.program->Base.InputsRead = 0x0;
 
-   if (ctx->DrawBuffer->_NumColorDrawBuffers == 1)
+   if (key->num_draw_buffers == 1)
       p.program->Base.OutputsWritten = 1 << FRAG_RESULT_COLOR;
    else {
-      for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++)
+      for (i = 0; i < key->num_draw_buffers; i++)
         p.program->Base.OutputsWritten |= (1 << (FRAG_RESULT_DATA0 + i));
    }
 
@@ -1493,8 +1500,8 @@ create_new_program(GLcontext *ctx, struct state_key *key,
 
    cf = get_source( &p, SRC_PREVIOUS, 0 );
 
-   for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
-      if (ctx->DrawBuffer->_NumColorDrawBuffers == 1)
+   for (i = 0; i < key->num_draw_buffers; i++) {
+      if (key->num_draw_buffers == 1)
         out = make_ureg( PROGRAM_OUTPUT, FRAG_RESULT_COLOR );
       else {
         out = make_ureg( PROGRAM_OUTPUT, FRAG_RESULT_DATA0 + i );
index 24d29137b0cadc571718d088693cae1f92f7c29c..fe002082cca7ceb404d297c900130e314f7e911f 100644 (file)
@@ -552,6 +552,54 @@ texfetch_funcs[MESA_FORMAT_COUNT] =
       fetch_texel_3d_f_intensity_f16,
       store_texel_intensity_f16
    },
+
+   /* non-normalized, signed int */
+   {
+      MESA_FORMAT_RGBA_INT8,
+      fetch_texel_1d_rgba_int8,
+      fetch_texel_2d_rgba_int8,
+      fetch_texel_3d_rgba_int8,
+      store_texel_rgba_int8
+   },
+   {
+      MESA_FORMAT_RGBA_INT16,
+      fetch_texel_1d_rgba_int16,
+      fetch_texel_2d_rgba_int16,
+      fetch_texel_3d_rgba_int16,
+      store_texel_rgba_int16
+   },
+   {
+      MESA_FORMAT_RGBA_INT32,
+      fetch_texel_1d_rgba_int32,
+      fetch_texel_2d_rgba_int32,
+      fetch_texel_3d_rgba_int32,
+      store_texel_rgba_int32
+   },
+
+   /* non-normalized, unsigned int */
+   {
+      MESA_FORMAT_RGBA_UINT8,
+      fetch_texel_1d_rgba_uint8,
+      fetch_texel_2d_rgba_uint8,
+      fetch_texel_3d_rgba_uint8,
+      store_texel_rgba_uint8
+   },
+   {
+      MESA_FORMAT_RGBA_UINT16,
+      fetch_texel_1d_rgba_uint16,
+      fetch_texel_2d_rgba_uint16,
+      fetch_texel_3d_rgba_uint16,
+      store_texel_rgba_uint16
+   },
+   {
+      MESA_FORMAT_RGBA_UINT32,
+      fetch_texel_1d_rgba_uint32,
+      fetch_texel_2d_rgba_uint32,
+      fetch_texel_3d_rgba_uint32,
+      store_texel_rgba_uint32
+   },
+
+   /* dudv */
    {
       MESA_FORMAT_DUDV8,
       fetch_texel_1d_dudv8,
@@ -559,6 +607,8 @@ texfetch_funcs[MESA_FORMAT_COUNT] =
       fetch_texel_3d_dudv8,
       NULL
    },
+
+   /* signed, normalized */
    {
       MESA_FORMAT_SIGNED_R8,
       fetch_texel_1d_signed_r8,
index e51fe3a577306e4eba173c0a1fc4a5ad06ea6a09..f943554370fc9e2f6562abcdf9b2e5b4ec4e5d3f 100644 (file)
@@ -1195,6 +1195,174 @@ static void store_texel_sla8(struct gl_texture_image *texImage,
 #endif
 
 
+/* MESA_FORMAT_RGBA_INT8 **************************************************/
+
+static void
+FETCH(rgba_int8)(const struct gl_texture_image *texImage,
+                 GLint i, GLint j, GLint k, GLfloat *texel )
+{
+   const GLbyte *src = TEXEL_ADDR(GLbyte, texImage, i, j, k, 4);
+   texel[RCOMP] = (GLfloat) src[0];
+   texel[GCOMP] = (GLfloat) src[1];
+   texel[BCOMP] = (GLfloat) src[2];
+   texel[ACOMP] = (GLfloat) src[3];
+}
+
+#if DIM == 3
+static void
+store_texel_rgba_int8(struct gl_texture_image *texImage,
+                      GLint i, GLint j, GLint k, const void *texel)
+{
+   const GLbyte *rgba = (const GLbyte *) texel;
+   GLbyte *dst = TEXEL_ADDR(GLbyte, texImage, i, j, k, 4);
+   dst[0] = rgba[RCOMP];
+   dst[1] = rgba[GCOMP];
+   dst[2] = rgba[BCOMP];
+   dst[3] = rgba[ACOMP];
+}
+#endif
+
+
+/* MESA_FORMAT_RGBA_INT16 **************************************************/
+
+static void
+FETCH(rgba_int16)(const struct gl_texture_image *texImage,
+                  GLint i, GLint j, GLint k, GLfloat *texel )
+{
+   const GLshort *src = TEXEL_ADDR(GLshort, texImage, i, j, k, 4);
+   texel[RCOMP] = (GLfloat) src[0];
+   texel[GCOMP] = (GLfloat) src[1];
+   texel[BCOMP] = (GLfloat) src[2];
+   texel[ACOMP] = (GLfloat) src[3];
+}
+
+#if DIM == 3
+static void
+store_texel_rgba_int16(struct gl_texture_image *texImage,
+                       GLint i, GLint j, GLint k, const void *texel)
+{
+   const GLshort *rgba = (const GLshort *) texel;
+   GLshort *dst = TEXEL_ADDR(GLshort, texImage, i, j, k, 4);
+   dst[0] = rgba[RCOMP];
+   dst[1] = rgba[GCOMP];
+   dst[2] = rgba[BCOMP];
+   dst[3] = rgba[ACOMP];
+}
+#endif
+
+
+/* MESA_FORMAT_RGBA_INT32 **************************************************/
+
+static void
+FETCH(rgba_int32)(const struct gl_texture_image *texImage,
+                  GLint i, GLint j, GLint k, GLfloat *texel )
+{
+   const GLint *src = TEXEL_ADDR(GLint, texImage, i, j, k, 4);
+   texel[RCOMP] = (GLfloat) src[0];
+   texel[GCOMP] = (GLfloat) src[1];
+   texel[BCOMP] = (GLfloat) src[2];
+   texel[ACOMP] = (GLfloat) src[3];
+}
+
+#if DIM == 3
+static void
+store_texel_rgba_int32(struct gl_texture_image *texImage,
+                       GLint i, GLint j, GLint k, const void *texel)
+{
+   const GLint *rgba = (const GLint *) texel;
+   GLint *dst = TEXEL_ADDR(GLint, texImage, i, j, k, 4);
+   dst[0] = rgba[RCOMP];
+   dst[1] = rgba[GCOMP];
+   dst[2] = rgba[BCOMP];
+   dst[3] = rgba[ACOMP];
+}
+#endif
+
+
+/* MESA_FORMAT_RGBA_UINT8 **************************************************/
+
+static void
+FETCH(rgba_uint8)(const struct gl_texture_image *texImage,
+                 GLint i, GLint j, GLint k, GLfloat *texel )
+{
+   const GLubyte *src = TEXEL_ADDR(GLubyte, texImage, i, j, k, 4);
+   texel[RCOMP] = (GLfloat) src[0];
+   texel[GCOMP] = (GLfloat) src[1];
+   texel[BCOMP] = (GLfloat) src[2];
+   texel[ACOMP] = (GLfloat) src[3];
+}
+
+#if DIM == 3
+static void
+store_texel_rgba_uint8(struct gl_texture_image *texImage,
+                      GLint i, GLint j, GLint k, const void *texel)
+{
+   const GLubyte *rgba = (const GLubyte *) texel;
+   GLubyte *dst = TEXEL_ADDR(GLubyte, texImage, i, j, k, 4);
+   dst[0] = rgba[RCOMP];
+   dst[1] = rgba[GCOMP];
+   dst[2] = rgba[BCOMP];
+   dst[3] = rgba[ACOMP];
+}
+#endif
+
+
+/* MESA_FORMAT_RGBA_UINT16 **************************************************/
+
+static void
+FETCH(rgba_uint16)(const struct gl_texture_image *texImage,
+                  GLint i, GLint j, GLint k, GLfloat *texel )
+{
+   const GLushort *src = TEXEL_ADDR(GLushort, texImage, i, j, k, 4);
+   texel[RCOMP] = (GLfloat) src[0];
+   texel[GCOMP] = (GLfloat) src[1];
+   texel[BCOMP] = (GLfloat) src[2];
+   texel[ACOMP] = (GLfloat) src[3];
+}
+
+#if DIM == 3
+static void
+store_texel_rgba_uint16(struct gl_texture_image *texImage,
+                       GLint i, GLint j, GLint k, const void *texel)
+{
+   const GLushort *rgba = (const GLushort *) texel;
+   GLushort *dst = TEXEL_ADDR(GLushort, texImage, i, j, k, 4);
+   dst[0] = rgba[RCOMP];
+   dst[1] = rgba[GCOMP];
+   dst[2] = rgba[BCOMP];
+   dst[3] = rgba[ACOMP];
+}
+#endif
+
+
+/* MESA_FORMAT_RGBA_UINT32 **************************************************/
+
+static void
+FETCH(rgba_uint32)(const struct gl_texture_image *texImage,
+                  GLint i, GLint j, GLint k, GLfloat *texel )
+{
+   const GLuint *src = TEXEL_ADDR(GLuint, texImage, i, j, k, 4);
+   texel[RCOMP] = (GLfloat) src[0];
+   texel[GCOMP] = (GLfloat) src[1];
+   texel[BCOMP] = (GLfloat) src[2];
+   texel[ACOMP] = (GLfloat) src[3];
+}
+
+#if DIM == 3
+static void
+store_texel_rgba_uint32(struct gl_texture_image *texImage,
+                       GLint i, GLint j, GLint k, const void *texel)
+{
+   const GLuint *rgba = (const GLuint *) texel;
+   GLuint *dst = TEXEL_ADDR(GLuint, texImage, i, j, k, 4);
+   dst[0] = rgba[RCOMP];
+   dst[1] = rgba[GCOMP];
+   dst[2] = rgba[BCOMP];
+   dst[3] = rgba[ACOMP];
+}
+#endif
+
+
 /* MESA_FORMAT_DUDV8 ********************************************************/
 
 /* this format by definition produces 0,0,0,1 as rgba values,
index d235485721a69507e414d55880bdbf706706c24b..b9271ef58ef7b94777bd2769ec17bd72691badc3 100644 (file)
@@ -382,6 +382,53 @@ _mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat,
    }
 #endif /* FEATURE_EXT_texture_sRGB */
 
+   if (ctx->Extensions.EXT_texture_integer) {
+      switch (internalFormat) {
+      case GL_RGBA32UI_EXT:
+      case GL_RGB32UI_EXT:
+      case GL_ALPHA32UI_EXT:
+      case GL_INTENSITY32UI_EXT:
+      case GL_LUMINANCE32UI_EXT:
+      case GL_LUMINANCE_ALPHA32UI_EXT:
+         return MESA_FORMAT_RGBA_UINT32;
+      case GL_RGBA16UI_EXT:
+      case GL_RGB16UI_EXT:
+      case GL_ALPHA16UI_EXT:
+      case GL_INTENSITY16UI_EXT:
+      case GL_LUMINANCE16UI_EXT:
+      case GL_LUMINANCE_ALPHA16UI_EXT:
+         return MESA_FORMAT_RGBA_UINT16;
+      case GL_RGBA8UI_EXT:
+      case GL_RGB8UI_EXT:
+      case GL_ALPHA8UI_EXT:
+      case GL_INTENSITY8UI_EXT:
+      case GL_LUMINANCE8UI_EXT:
+      case GL_LUMINANCE_ALPHA8UI_EXT:
+         return MESA_FORMAT_RGBA_UINT8;
+      case GL_RGBA32I_EXT:
+      case GL_RGB32I_EXT:
+      case GL_ALPHA32I_EXT:
+      case GL_INTENSITY32I_EXT:
+      case GL_LUMINANCE32I_EXT:
+      case GL_LUMINANCE_ALPHA32I_EXT:
+         return MESA_FORMAT_RGBA_INT32;
+      case GL_RGBA16I_EXT:
+      case GL_RGB16I_EXT:
+      case GL_ALPHA16I_EXT:
+      case GL_INTENSITY16I_EXT:
+      case GL_LUMINANCE16I_EXT:
+      case GL_LUMINANCE_ALPHA16I_EXT:
+         return MESA_FORMAT_RGBA_INT16;
+      case GL_RGBA8I_EXT:
+      case GL_RGB8I_EXT:
+      case GL_ALPHA8I_EXT:
+      case GL_INTENSITY8I_EXT:
+      case GL_LUMINANCE8I_EXT:
+      case GL_LUMINANCE_ALPHA8I_EXT:
+         return MESA_FORMAT_RGBA_INT8;
+      }
+   }
+
    _mesa_problem(ctx, "unexpected format in _mesa_choose_tex_format()");
    return MESA_FORMAT_NONE;
 }
index ff752155ea9a3ff374104da02903dcce04d5395a..9b7a021561908fd5946e0c488ee04b7b8e5b55ba 100644 (file)
@@ -348,12 +348,135 @@ _mesa_base_tex_format( GLcontext *ctx, GLint internalFormat )
       case GL_SLUMINANCE8_EXT:
          return GL_LUMINANCE;
       default:
-            ; /* fallthrough */
+         ; /* fallthrough */
       }
    }
-
 #endif /* FEATURE_EXT_texture_sRGB */
 
+   if (ctx->Extensions.EXT_texture_integer) {
+      switch (internalFormat) {
+      case GL_RGBA8UI_EXT:
+      case GL_RGBA16UI_EXT:
+      case GL_RGBA32UI_EXT:
+      case GL_RGBA8I_EXT:
+      case GL_RGBA16I_EXT:
+      case GL_RGBA32I_EXT:
+         return GL_RGBA;
+      case GL_RGB8UI_EXT:
+      case GL_RGB16UI_EXT:
+      case GL_RGB32UI_EXT:
+      case GL_RGB8I_EXT:
+      case GL_RGB16I_EXT:
+      case GL_RGB32I_EXT:
+         return GL_RGB;
+      case GL_ALPHA8UI_EXT:
+      case GL_ALPHA16UI_EXT:
+      case GL_ALPHA32UI_EXT:
+      case GL_ALPHA8I_EXT:
+      case GL_ALPHA16I_EXT:
+      case GL_ALPHA32I_EXT:
+         return GL_ALPHA;
+      case GL_INTENSITY8UI_EXT:
+      case GL_INTENSITY16UI_EXT:
+      case GL_INTENSITY32UI_EXT:
+      case GL_INTENSITY8I_EXT:
+      case GL_INTENSITY16I_EXT:
+      case GL_INTENSITY32I_EXT:
+         return GL_INTENSITY;
+      case GL_LUMINANCE8UI_EXT:
+      case GL_LUMINANCE16UI_EXT:
+      case GL_LUMINANCE32UI_EXT:
+      case GL_LUMINANCE8I_EXT:
+      case GL_LUMINANCE16I_EXT:
+      case GL_LUMINANCE32I_EXT:
+         return GL_LUMINANCE;
+      case GL_LUMINANCE_ALPHA8UI_EXT:
+      case GL_LUMINANCE_ALPHA16UI_EXT:
+      case GL_LUMINANCE_ALPHA32UI_EXT:
+      case GL_LUMINANCE_ALPHA8I_EXT:
+      case GL_LUMINANCE_ALPHA16I_EXT:
+      case GL_LUMINANCE_ALPHA32I_EXT:
+         return GL_LUMINANCE_ALPHA;
+      default:
+         ; /* fallthrough */
+      }
+   }
+
+   if (ctx->Extensions.ARB_texture_rg) {
+      switch (internalFormat) {
+      case GL_R8:
+      case GL_R16:
+      case GL_R16F:
+      case GL_R32F:
+      case GL_R8I:
+      case GL_R8UI:
+      case GL_R16I:
+      case GL_R16UI:
+      case GL_R32I:
+      case GL_R32UI:
+         return GL_R;
+      case GL_RG:
+      case GL_RG_INTEGER:
+      case GL_RG8:
+      case GL_RG16:
+      case GL_RG16F:
+      case GL_RG32F:
+      case GL_RG8I:
+      case GL_RG8UI:
+      case GL_RG16I:
+      case GL_RG16UI:
+      case GL_RG32I:
+      case GL_RG32UI:
+         return GL_RG;
+      default:
+         ; /* fallthrough */
+      }
+   }
+
+   if (ctx->Extensions.EXT_texture_shared_exponent) {
+      switch (internalFormat) {
+      case GL_RGB9_E5_EXT:
+         return GL_RGB;
+      default:
+         ; /* fallthrough */
+      }
+   }
+
+   if (ctx->Extensions.EXT_packed_float) {
+      switch (internalFormat) {
+      case GL_R11F_G11F_B10F_EXT:
+         return GL_RGB;
+      default:
+         ; /* fallthrough */
+      }
+   }
+
+   if (ctx->Extensions.ARB_depth_buffer_float) {
+      switch (internalFormat) {
+      case GL_DEPTH_COMPONENT32F:
+         return GL_DEPTH_COMPONENT;
+      case GL_DEPTH32F_STENCIL8:
+         return GL_DEPTH_STENCIL;
+      default:
+         ; /* fallthrough */
+      }
+   }
+
+   if (ctx->Extensions.EXT_texture_compression_rgtc) {
+      switch (internalFormat) {
+      case GL_COMPRESSED_RED:
+      case GL_COMPRESSED_RED_RGTC1_EXT:
+      case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:
+         return GL_RED;
+      case GL_COMPRESSED_RG:
+      case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:
+      case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:
+         return GL_RG;
+      default:
+         ; /* fallthrough */
+      }
+   }
+
    return -1; /* error */
 }
 
@@ -2060,6 +2183,45 @@ override_internal_format(GLenum internalFormat, GLint width, GLint height)
 }
 
 
+/**
+ * Choose the actual hardware format for a texture image.
+ * Try to use the same format as the previous image level when possible.
+ * Otherwise, ask the driver for the best format.
+ * It's important to try to choose a consistant format for all levels
+ * for efficient texture memory layout/allocation.  In particular, this
+ * comes up during automatic mipmap generation.
+ */
+void
+_mesa_choose_texture_format(GLcontext *ctx,
+                            struct gl_texture_object *texObj,
+                            struct gl_texture_image *texImage,
+                            GLenum target, GLint level,
+                            GLenum internalFormat, GLenum format, GLenum type)
+{
+   /* see if we've already chosen a format for the previous level */
+   if (level > 0) {
+      struct gl_texture_image *prevImage =
+        _mesa_select_tex_image(ctx, texObj, target, level - 1);
+      /* See if the prev level is defined and has an internal format which
+       * matches the new internal format.
+       */
+      if (prevImage &&
+          prevImage->Width > 0 &&
+          prevImage->InternalFormat == internalFormat) {
+         /* use the same format */
+         texImage->TexFormat = prevImage->TexFormat;
+         return;
+      }
+   }
+
+   /* choose format from scratch */
+   texImage->TexFormat = ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
+                                                         format, type);
+   ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
+}
+
+
+
 /*
  * Called from the API.  Note that width includes the border.
  */
@@ -2120,11 +2282,8 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
                                        postConvWidth, 1, 1,
                                        border, internalFormat);
 
-            /* Choose actual texture format */
-            texImage->TexFormat =
-               ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
-                                               format, type);
-            ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
+            _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
+                                        internalFormat, format, type);
 
             /* Give the texture to the driver.  <pixels> may be null. */
             ASSERT(ctx->Driver.TexImage1D);
@@ -2159,12 +2318,14 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
       }
       else {
          /* no error, set the tex image parameters */
+         struct gl_texture_object *texObj =
+            _mesa_get_current_tex_object(ctx, target);
          ASSERT(texImage);
          _mesa_init_teximage_fields(ctx, target, texImage,
                                     postConvWidth, 1, 1,
                                     border, internalFormat);
-         texImage->TexFormat =
-            ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
+         _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
+                                     internalFormat, format, type);
       }
    }
    else {
@@ -2240,11 +2401,8 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
                                        postConvWidth, postConvHeight, 1,
                                        border, internalFormat);
 
-            /* Choose actual texture format */
-            texImage->TexFormat =
-               ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
-                                               format, type);
-            ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
+            _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
+                                        internalFormat, format, type);
 
             /* Give the texture to the driver.  <pixels> may be null. */
             ASSERT(ctx->Driver.TexImage2D);
@@ -2286,11 +2444,13 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
       }
       else {
          /* no error, set the tex image parameters */
+         struct gl_texture_object *texObj =
+            _mesa_get_current_tex_object(ctx, target);
          _mesa_init_teximage_fields(ctx, target, texImage,
                                     postConvWidth, postConvHeight, 1,
                                     border, internalFormat);
-         texImage->TexFormat =
-            ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
+         _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
+                                     internalFormat, format, type);
       }
    }
    else {
@@ -2356,11 +2516,8 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
                                        width, height, depth,
                                        border, internalFormat);
 
-            /* Choose actual texture format */
-            texImage->TexFormat =
-               ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
-                                               format, type);
-            ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
+            _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
+                                        internalFormat, format, type);
 
             /* Give the texture to the driver.  <pixels> may be null. */
             ASSERT(ctx->Driver.TexImage3D);
@@ -2397,10 +2554,12 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
       }
       else {
          /* no error, set the tex image parameters */
+         struct gl_texture_object *texObj =
+            _mesa_get_current_tex_object(ctx, target);
          _mesa_init_teximage_fields(ctx, target, texImage, width, height,
                                     depth, border, internalFormat);
-         texImage->TexFormat =
-            ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
+         _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
+                                     internalFormat, format, type);
       }
    }
    else {
@@ -2713,11 +2872,8 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
          _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1,
                                     border, internalFormat);
 
-         /* Choose actual texture format */
-         texImage->TexFormat =
-            ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
-                                            GL_NONE, GL_NONE);
-         ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
+         _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
+                                     internalFormat, GL_NONE, GL_NONE);
 
          ASSERT(ctx->Driver.CopyTexImage1D);
          ctx->Driver.CopyTexImage1D(ctx, target, level, internalFormat,
@@ -2794,11 +2950,8 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
                                     postConvWidth, postConvHeight, 1,
                                     border, internalFormat);
 
-         /* Choose actual texture format */
-         texImage->TexFormat =
-            ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
-                                            GL_NONE, GL_NONE);
-         ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
+         _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
+                                     internalFormat, GL_NONE, GL_NONE);
 
          ASSERT(ctx->Driver.CopyTexImage2D);
          ctx->Driver.CopyTexImage2D(ctx, target, level, internalFormat,
@@ -3082,6 +3235,10 @@ compressed_texture_error_check(GLcontext *ctx, GLint dimensions,
       /* 3D compressed textures not allowed */
       return GL_INVALID_ENUM;
    }
+   else {
+      assert(0);
+      return GL_INVALID_ENUM;
+   }
 
    maxTextureSize = 1 << (maxLevels - 1);
 
@@ -3319,11 +3476,8 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
             _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
                                        border, internalFormat);
 
-            /* Choose actual texture format */
-            texImage->TexFormat =
-               ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
-                                               GL_NONE, GL_NONE);
-            ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
+            _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
+                                        internalFormat, GL_NONE, GL_NONE);
 
             ASSERT(ctx->Driver.CompressedTexImage1D);
             ctx->Driver.CompressedTexImage1D(ctx, target, level,
@@ -3371,6 +3525,8 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
            texImage = _mesa_select_tex_image(ctx, texObj, target, level);
            _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
                                       border, internalFormat);
+            _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
+                                        internalFormat, GL_NONE, GL_NONE);
         }
         _mesa_unlock_texture(ctx, texObj);
       }
@@ -3446,11 +3602,8 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
             _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
                                        border, internalFormat);
 
-            /* Choose actual texture format */
-            texImage->TexFormat =
-               ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
-                                               GL_NONE, GL_NONE);
-            ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
+            _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
+                                        internalFormat, GL_NONE, GL_NONE);
 
             ASSERT(ctx->Driver.CompressedTexImage2D);
             ctx->Driver.CompressedTexImage2D(ctx, target, level,
@@ -3500,6 +3653,8 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
            texImage = _mesa_select_tex_image(ctx, texObj, target, level);
            _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
                                       border, internalFormat);
+            _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
+                                        internalFormat, GL_NONE, GL_NONE);
         }
         _mesa_unlock_texture(ctx, texObj);
       }
@@ -3556,10 +3711,8 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
                                        border, internalFormat);
 
             /* Choose actual texture format */
-            texImage->TexFormat =
-               ctx->Driver.ChooseTextureFormat(ctx, internalFormat,
-                                               GL_NONE, GL_NONE);
-            ASSERT(texImage->TexFormat != MESA_FORMAT_NONE);
+            _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
+                                        internalFormat, GL_NONE, GL_NONE);
 
             ASSERT(ctx->Driver.CompressedTexImage3D);
             ctx->Driver.CompressedTexImage3D(ctx, target, level,
@@ -3608,6 +3761,8 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
            texImage = _mesa_select_tex_image(ctx, texObj, target, level);
            _mesa_init_teximage_fields(ctx, target, texImage, width, height,
                                       depth, border, internalFormat);
+            _mesa_choose_texture_format(ctx, texObj, texImage, target, level,
+                                        internalFormat, GL_NONE, GL_NONE);
         }
         _mesa_unlock_texture(ctx, texObj);
       }
index d82cc985211c2d6d34b9cd4d1981916a0c95e696..0dcacab3cd09ea4bd41bb23ae6c92e2b28898ede 100644 (file)
@@ -72,6 +72,14 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
                            GLint border, GLenum internalFormat);
 
 
+extern void
+_mesa_choose_texture_format(GLcontext *ctx,
+                            struct gl_texture_object *texObj,
+                            struct gl_texture_image *texImage,
+                            GLenum target, GLint level,
+                            GLenum internalFormat, GLenum format, GLenum type);
+
+
 extern void
 _mesa_clear_texture_image(GLcontext *ctx, struct gl_texture_image *texImage);
 
index de37e340393b172bf98011f97c6c9a4635ec92eb..1df165cf6a803ff1e6e2db01daafd2069d44890f 100644 (file)
@@ -40,7 +40,7 @@
 #include "teximage.h"
 #include "texobj.h"
 #include "mtypes.h"
-#include "shader/prog_instruction.h"
+#include "program/prog_instruction.h"
 
 
 
index ca03404f12f32566bef4b220423d0317bad8410a..745a0aeec9d3464659488341ac104a410a3e7430 100644 (file)
@@ -39,7 +39,7 @@
 #include "main/texparam.h"
 #include "main/teximage.h"
 #include "main/texstate.h"
-#include "shader/prog_instruction.h"
+#include "program/prog_instruction.h"
 
 
 /**
index fce17c2b66020e5d8f712f6d7b32e611e756ff5f..dae173d1bde047c3965325c5c7d8090611fabb2a 100644 (file)
@@ -528,7 +528,7 @@ update_texture_state( GLcontext *ctx )
       /* Get the bitmask of texture target enables.
        * enableBits will be a mask of the TEXTURE_*_BIT flags indicating
        * which texture targets are enabled (fixed function) or referenced
-       * by a fragment shader/program.  When multiple flags are set, we'll
+       * by a fragment program/program.  When multiple flags are set, we'll
        * settle on the one with highest priority (see below).
        */
       if (vprog) {
index ce05652c935f3c7e44cfd7f8f77fa6e6e71a0c4c..0f21395af399f25c3b722ac06adad32e17ddc352 100644 (file)
@@ -3278,6 +3278,392 @@ _mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
 }
 
 
+/* non-normalized, signed int8 */
+static GLboolean
+_mesa_texstore_rgba_int8(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+   const GLint components = _mesa_components_in_format(baseFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_RGBA_INT8);
+   ASSERT(baseInternalFormat == GL_RGBA ||
+          baseInternalFormat == GL_RGB ||
+          baseInternalFormat == GL_ALPHA ||
+          baseInternalFormat == GL_LUMINANCE ||
+          baseInternalFormat == GL_LUMINANCE_ALPHA ||
+          baseInternalFormat == GL_INTENSITY);
+   ASSERT(texelBytes == components * sizeof(GLbyte));
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       baseInternalFormat == srcFormat &&
+       srcType == GL_BYTE) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking);
+      const GLfloat *src = tempImage;
+      GLint img, row;
+      if (!tempImage)
+         return GL_FALSE;
+      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            GLbyte *dstTexel = (GLbyte *) dstRow;
+            GLint i;
+            for (i = 0; i < srcWidth * components; i++) {
+               dstTexel[i] = (GLbyte) src[i];
+            }
+            dstRow += dstRowStride;
+            src += srcWidth * components;
+         }
+      }
+
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+
+/* non-normalized, signed int16 */
+static GLboolean
+_mesa_texstore_rgba_int16(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+   const GLint components = _mesa_components_in_format(baseFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_RGBA_INT16);
+   ASSERT(baseInternalFormat == GL_RGBA ||
+          baseInternalFormat == GL_RGB ||
+          baseInternalFormat == GL_ALPHA ||
+          baseInternalFormat == GL_LUMINANCE ||
+          baseInternalFormat == GL_LUMINANCE_ALPHA ||
+          baseInternalFormat == GL_INTENSITY);
+   ASSERT(texelBytes == components * sizeof(GLshort));
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       baseInternalFormat == srcFormat &&
+       srcType == GL_INT) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking);
+      const GLfloat *src = tempImage;
+      GLint img, row;
+      if (!tempImage)
+         return GL_FALSE;
+      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            GLshort *dstTexel = (GLshort *) dstRow;
+            GLint i;
+            for (i = 0; i < srcWidth * components; i++) {
+               dstTexel[i] = (GLint) src[i];
+            }
+            dstRow += dstRowStride;
+            src += srcWidth * components;
+         }
+      }
+
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+
+/* non-normalized, signed int32 */
+static GLboolean
+_mesa_texstore_rgba_int32(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+   const GLint components = _mesa_components_in_format(baseFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_RGBA_INT32);
+   ASSERT(baseInternalFormat == GL_RGBA ||
+          baseInternalFormat == GL_RGB ||
+          baseInternalFormat == GL_ALPHA ||
+          baseInternalFormat == GL_LUMINANCE ||
+          baseInternalFormat == GL_LUMINANCE_ALPHA ||
+          baseInternalFormat == GL_INTENSITY);
+   ASSERT(texelBytes == components * sizeof(GLint));
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       baseInternalFormat == srcFormat &&
+       srcType == GL_INT) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking);
+      const GLfloat *src = tempImage;
+      GLint img, row;
+      if (!tempImage)
+         return GL_FALSE;
+      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            GLint *dstTexel = (GLint *) dstRow;
+            GLint i;
+            for (i = 0; i < srcWidth * components; i++) {
+               dstTexel[i] = (GLint) src[i];
+            }
+            dstRow += dstRowStride;
+            src += srcWidth * components;
+         }
+      }
+
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+
+/* non-normalized, unsigned int8 */
+static GLboolean
+_mesa_texstore_rgba_uint8(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+   const GLint components = _mesa_components_in_format(baseFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_RGBA_UINT8);
+   ASSERT(baseInternalFormat == GL_RGBA ||
+          baseInternalFormat == GL_RGB ||
+          baseInternalFormat == GL_ALPHA ||
+          baseInternalFormat == GL_LUMINANCE ||
+          baseInternalFormat == GL_LUMINANCE_ALPHA ||
+          baseInternalFormat == GL_INTENSITY);
+   ASSERT(texelBytes == components * sizeof(GLubyte));
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       baseInternalFormat == srcFormat &&
+       srcType == GL_UNSIGNED_BYTE) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking);
+      const GLfloat *src = tempImage;
+      GLint img, row;
+      if (!tempImage)
+         return GL_FALSE;
+      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            GLubyte *dstTexel = (GLubyte *) dstRow;
+            GLint i;
+            for (i = 0; i < srcWidth * components; i++) {
+               dstTexel[i] = (GLubyte) src[i];
+            }
+            dstRow += dstRowStride;
+            src += srcWidth * components;
+         }
+      }
+
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+
+/* non-normalized, unsigned int16 */
+static GLboolean
+_mesa_texstore_rgba_uint16(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+   const GLint components = _mesa_components_in_format(baseFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_RGBA_UINT16);
+   ASSERT(baseInternalFormat == GL_RGBA ||
+          baseInternalFormat == GL_RGB ||
+          baseInternalFormat == GL_ALPHA ||
+          baseInternalFormat == GL_LUMINANCE ||
+          baseInternalFormat == GL_LUMINANCE_ALPHA ||
+          baseInternalFormat == GL_INTENSITY);
+   ASSERT(texelBytes == components * sizeof(GLushort));
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       baseInternalFormat == srcFormat &&
+       srcType == GL_UNSIGNED_SHORT) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking);
+      const GLfloat *src = tempImage;
+      GLint img, row;
+      if (!tempImage)
+         return GL_FALSE;
+      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            GLushort *dstTexel = (GLushort *) dstRow;
+            GLint i;
+            for (i = 0; i < srcWidth * components; i++) {
+               dstTexel[i] = (GLushort) src[i];
+            }
+            dstRow += dstRowStride;
+            src += srcWidth * components;
+         }
+      }
+
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+
+/* non-normalized, unsigned int32 */
+static GLboolean
+_mesa_texstore_rgba_uint32(TEXSTORE_PARAMS)
+{
+   const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+   const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+   const GLint components = _mesa_components_in_format(baseFormat);
+
+   ASSERT(dstFormat == MESA_FORMAT_RGBA_UINT32);
+   ASSERT(baseInternalFormat == GL_RGBA ||
+          baseInternalFormat == GL_RGB ||
+          baseInternalFormat == GL_ALPHA ||
+          baseInternalFormat == GL_LUMINANCE ||
+          baseInternalFormat == GL_LUMINANCE_ALPHA ||
+          baseInternalFormat == GL_INTENSITY);
+   ASSERT(texelBytes == components * sizeof(GLuint));
+
+   if (!ctx->_ImageTransferState &&
+       !srcPacking->SwapBytes &&
+       baseInternalFormat == srcFormat &&
+       srcType == GL_UNSIGNED_INT) {
+      /* simple memcpy path */
+      memcpy_texture(ctx, dims,
+                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+                     dstRowStride,
+                     dstImageOffsets,
+                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+                     srcAddr, srcPacking);
+   }
+   else {
+      /* general path */
+      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+                                                 baseInternalFormat,
+                                                 baseFormat,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcFormat, srcType, srcAddr,
+                                                 srcPacking);
+      const GLfloat *src = tempImage;
+      GLint img, row;
+      if (!tempImage)
+         return GL_FALSE;
+      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+      for (img = 0; img < srcDepth; img++) {
+         GLubyte *dstRow = (GLubyte *) dstAddr
+            + dstImageOffsets[dstZoffset + img] * texelBytes
+            + dstYoffset * dstRowStride
+            + dstXoffset * texelBytes;
+         for (row = 0; row < srcHeight; row++) {
+            GLuint *dstTexel = (GLuint *) dstRow;
+            GLint i;
+            for (i = 0; i < srcWidth * components; i++) {
+               dstTexel[i] = (GLuint) src[i];
+            }
+            dstRow += dstRowStride;
+            src += srcWidth * components;
+         }
+      }
+
+      free((void *) tempImage);
+   }
+   return GL_TRUE;
+}
+
+
+
+
 #if FEATURE_EXT_texture_sRGB
 static GLboolean
 _mesa_texstore_srgb8(TEXSTORE_PARAMS)
@@ -3472,6 +3858,14 @@ texstore_funcs[MESA_FORMAT_COUNT] =
    { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16, _mesa_texstore_rgba_float16 },
    { MESA_FORMAT_INTENSITY_FLOAT32, _mesa_texstore_rgba_float32 },
    { MESA_FORMAT_INTENSITY_FLOAT16, _mesa_texstore_rgba_float16 },
+
+   { MESA_FORMAT_RGBA_INT8, _mesa_texstore_rgba_int8 },
+   { MESA_FORMAT_RGBA_INT16, _mesa_texstore_rgba_int16 },
+   { MESA_FORMAT_RGBA_INT32, _mesa_texstore_rgba_int32 },
+   { MESA_FORMAT_RGBA_UINT8, _mesa_texstore_rgba_uint8 },
+   { MESA_FORMAT_RGBA_UINT16, _mesa_texstore_rgba_uint16 },
+   { MESA_FORMAT_RGBA_UINT32, _mesa_texstore_rgba_uint32 },
+
    { MESA_FORMAT_DUDV8, _mesa_texstore_dudv8 },
 
    { MESA_FORMAT_SIGNED_R8, _mesa_texstore_signed_r8 },
index 050ebf02701684d58056c6fbae0f03a80340e83c..f86f1911d1daea8702d7eb61649f1c4d33210698 100644 (file)
 #include "context.h"
 #include "hash.h"
 #include "transformfeedback.h"
+#include "shaderapi.h"
+#include "shaderobj.h"
 #include "main/dispatch.h"
 
-#include "shader/prog_parameter.h"
-#include "shader/shader_api.h"
+#include "program/prog_parameter.h"
+//#include "program/shader_api.h"
 
 
 #if FEATURE_EXT_transform_feedback
@@ -132,10 +134,8 @@ _mesa_validate_transform_feedback_buffers(GLcontext *ctx)
 void
 _mesa_init_transform_feedback(GLcontext *ctx)
 {
-   if (!ctx->Driver.NewTransformFeedback) {
-      /* this feature/extension may not be supported by the driver */
-      return;
-   }
+   /* core mesa expects this, even a dummy one, to be available */
+   ASSERT(ctx->Driver.NewTransformFeedback);
 
    ctx->TransformFeedback.DefaultObject =
       ctx->Driver.NewTransformFeedback(ctx, 0);
@@ -176,10 +176,8 @@ delete_cb(GLuint key, void *data, void *userData)
 void
 _mesa_free_transform_feedback(GLcontext *ctx)
 {
-   if (!ctx->Driver.NewTransformFeedback) {
-      /* this feature/extension may not be supported by the driver */
-      return;
-   }
+   /* core mesa expects this, even a dummy one, to be available */
+   ASSERT(ctx->Driver.NewTransformFeedback);
 
    _mesa_reference_buffer_object(ctx,
                                  &ctx->TransformFeedback.CurrentBuffer,
@@ -187,6 +185,7 @@ _mesa_free_transform_feedback(GLcontext *ctx)
 
    /* Delete all feedback objects */
    _mesa_HashDeleteAll(ctx->TransformFeedback.Objects, delete_cb, ctx);
+   _mesa_DeleteHashTable(ctx->TransformFeedback.Objects);
 
    /* Delete the default feedback object */
    assert(ctx->Driver.DeleteTransformFeedback);
@@ -197,6 +196,40 @@ _mesa_free_transform_feedback(GLcontext *ctx)
 }
 
 
+#else /* FEATURE_EXT_transform_feedback */
+
+/* forward declarations */
+static struct gl_transform_feedback_object *
+new_transform_feedback(GLcontext *ctx, GLuint name);
+
+static void
+delete_transform_feedback(GLcontext *ctx,
+                          struct gl_transform_feedback_object *obj);
+
+/* dummy per-context init/clean-up for transform feedback */
+void
+_mesa_init_transform_feedback(GLcontext *ctx)
+{
+   ctx->TransformFeedback.DefaultObject = new_transform_feedback(ctx, 0);
+   ctx->TransformFeedback.CurrentObject = ctx->TransformFeedback.DefaultObject;
+   _mesa_reference_buffer_object(ctx,
+                                 &ctx->TransformFeedback.CurrentBuffer,
+                                 ctx->Shared->NullBufferObj);
+}
+
+void
+_mesa_free_transform_feedback(GLcontext *ctx)
+{
+   _mesa_reference_buffer_object(ctx,
+                                 &ctx->TransformFeedback.CurrentBuffer,
+                                 NULL);
+   ctx->TransformFeedback.CurrentObject = NULL;
+   delete_transform_feedback(ctx, ctx->TransformFeedback.DefaultObject);
+}
+
+#endif /* FEATURE_EXT_transform_feedback */
+
+
 /** Default fallback for ctx->Driver.NewTransformFeedback() */
 static struct gl_transform_feedback_object *
 new_transform_feedback(GLcontext *ctx, GLuint name)
@@ -224,6 +257,10 @@ delete_transform_feedback(GLcontext *ctx,
    free(obj);
 }
 
+
+#if FEATURE_EXT_transform_feedback
+
+
 /** Default fallback for ctx->Driver.BeginTransformFeedback() */
 static void
 begin_transform_feedback(GLcontext *ctx, GLenum mode,
index b806488abdd653d4628eb24443d9c7aa73710cc9..4d38522d6d96bc331f715a48e889aa5041b76679 100644 (file)
 #include "main/mtypes.h"
 
 
+extern void
+_mesa_init_transform_feedback(GLcontext *ctx);
+
+extern void
+_mesa_free_transform_feedback(GLcontext *ctx);
+
 #if FEATURE_EXT_transform_feedback
 
 extern GLboolean
@@ -36,12 +42,6 @@ _mesa_validate_primitive_mode(GLcontext *ctx, GLenum mode);
 extern GLboolean
 _mesa_validate_transform_feedback_buffers(GLcontext *ctx);
 
-extern void
-_mesa_init_transform_feedback(GLcontext *ctx);
-
-extern void
-_mesa_free_transform_feedback(GLcontext *ctx);
-
 
 extern void
 _mesa_init_transform_feedback_functions(struct dd_function_table *driver);
@@ -117,16 +117,6 @@ _mesa_validate_transform_feedback_buffers(GLcontext *ctx)
    return GL_TRUE;
 }
 
-static INLINE void
-_mesa_init_transform_feedback(GLcontext *ctx)
-{
-}
-
-static INLINE void
-_mesa_free_transform_feedback(GLcontext *ctx)
-{
-}
-
 static INLINE void
 _mesa_init_transform_feedback_functions(struct dd_function_table *driver)
 {
diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c
new file mode 100644 (file)
index 0000000..d68a776
--- /dev/null
@@ -0,0 +1,1370 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2004-2008  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2009-2010  VMware, 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
+ * 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 uniforms.c
+ * Functions related to GLSL uniform variables.
+ * \author Brian Paul
+ */
+
+/**
+ * XXX things to do:
+ * 1. Check that the right error code is generated for all _mesa_error() calls.
+ * 2. Insert FLUSH_VERTICES calls in various places
+ */
+
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/dispatch.h"
+#include "main/shaderapi.h"
+#include "main/shaderobj.h"
+#include "main/uniforms.h"
+#include "program/prog_parameter.h"
+#include "program/prog_statevars.h"
+#include "program/prog_uniform.h"
+
+
+
+static GLenum
+base_uniform_type(GLenum type)
+{
+   switch (type) {
+#if 0 /* not needed, for now */
+   case GL_BOOL:
+   case GL_BOOL_VEC2:
+   case GL_BOOL_VEC3:
+   case GL_BOOL_VEC4:
+      return GL_BOOL;
+#endif
+   case GL_FLOAT:
+   case GL_FLOAT_VEC2:
+   case GL_FLOAT_VEC3:
+   case GL_FLOAT_VEC4:
+      return GL_FLOAT;
+   case GL_UNSIGNED_INT:
+   case GL_UNSIGNED_INT_VEC2:
+   case GL_UNSIGNED_INT_VEC3:
+   case GL_UNSIGNED_INT_VEC4:
+      return GL_UNSIGNED_INT;
+   case GL_INT:
+   case GL_INT_VEC2:
+   case GL_INT_VEC3:
+   case GL_INT_VEC4:
+      return GL_INT;
+   default:
+      _mesa_problem(NULL, "Invalid type in base_uniform_type()");
+      return GL_FLOAT;
+   }
+}
+
+
+static GLboolean
+is_boolean_type(GLenum type)
+{
+   switch (type) {
+   case GL_BOOL:
+   case GL_BOOL_VEC2:
+   case GL_BOOL_VEC3:
+   case GL_BOOL_VEC4:
+      return GL_TRUE;
+   default:
+      return GL_FALSE;
+   }
+}
+
+
+static GLboolean
+is_sampler_type(GLenum type)
+{
+   switch (type) {
+   case GL_SAMPLER_1D:
+   case GL_SAMPLER_2D:
+   case GL_SAMPLER_3D:
+   case GL_SAMPLER_CUBE:
+   case GL_SAMPLER_1D_SHADOW:
+   case GL_SAMPLER_2D_SHADOW:
+   case GL_SAMPLER_2D_RECT_ARB:
+   case GL_SAMPLER_2D_RECT_SHADOW_ARB:
+   case GL_SAMPLER_1D_ARRAY_EXT:
+   case GL_SAMPLER_2D_ARRAY_EXT:
+   case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
+   case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
+      return GL_TRUE;
+   default:
+      return GL_FALSE;
+   }
+}
+
+
+static struct gl_program_parameter *
+get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index)
+{
+   const struct gl_program *prog = NULL;
+   GLint progPos;
+
+   progPos = shProg->Uniforms->Uniforms[index].VertPos;
+   if (progPos >= 0) {
+      prog = &shProg->VertexProgram->Base;
+   }
+   else {
+      progPos = shProg->Uniforms->Uniforms[index].FragPos;
+      if (progPos >= 0) {
+         prog = &shProg->FragmentProgram->Base;
+      } else {
+         progPos = shProg->Uniforms->Uniforms[index].GeomPos;
+         if (progPos >= 0) {
+            prog = &shProg->GeometryProgram->Base;
+         }
+      }
+   }
+
+   if (!prog || progPos < 0)
+      return NULL; /* should never happen */
+
+   return &prog->Parameters->Parameters[progPos];
+}
+
+
+/**
+ * Called by glGetActiveUniform().
+ */
+static void
+_mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index,
+                         GLsizei maxLength, GLsizei *length, GLint *size,
+                         GLenum *type, GLchar *nameOut)
+{
+   const struct gl_shader_program *shProg;
+   const struct gl_program *prog = NULL;
+   const struct gl_program_parameter *param;
+   GLint progPos;
+
+   shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
+   if (!shProg)
+      return;
+
+   if (!shProg->Uniforms || index >= shProg->Uniforms->NumUniforms) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
+      return;
+   }
+
+   progPos = shProg->Uniforms->Uniforms[index].VertPos;
+   if (progPos >= 0) {
+      prog = &shProg->VertexProgram->Base;
+   }
+   else {
+      progPos = shProg->Uniforms->Uniforms[index].FragPos;
+      if (progPos >= 0) {
+         prog = &shProg->FragmentProgram->Base;
+      } else {
+         progPos = shProg->Uniforms->Uniforms[index].GeomPos;
+         if (progPos >= 0) {
+            prog = &shProg->GeometryProgram->Base;
+         }
+      }
+   }
+
+   if (!prog || progPos < 0)
+      return; /* should never happen */
+
+   ASSERT(progPos < prog->Parameters->NumParameters);
+   param = &prog->Parameters->Parameters[progPos];
+
+   if (nameOut) {
+      _mesa_copy_string(nameOut, maxLength, length, param->Name);
+   }
+
+   if (size) {
+      GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
+      if ((GLint) param->Size > typeSize) {
+         /* This is an array.
+          * Array elements are placed on vector[4] boundaries so they're
+          * a multiple of four floats.  We round typeSize up to next multiple
+          * of four to get the right size below.
+          */
+         typeSize = (typeSize + 3) & ~3;
+      }
+      /* Note that the returned size is in units of the <type>, not bytes */
+      *size = param->Size / typeSize;
+   }
+
+   if (type) {
+      *type = param->DataType;
+   }
+}
+
+
+
+static void
+get_matrix_dims(GLenum type, GLint *rows, GLint *cols)
+{
+   switch (type) {
+   case GL_FLOAT_MAT2:
+      *rows = *cols = 2;
+      break;
+   case GL_FLOAT_MAT2x3:
+      *rows = 3;
+      *cols = 2;
+      break;
+   case GL_FLOAT_MAT2x4:
+      *rows = 4;
+      *cols = 2;
+      break;
+   case GL_FLOAT_MAT3:
+      *rows = 3;
+      *cols = 3;
+      break;
+   case GL_FLOAT_MAT3x2:
+      *rows = 2;
+      *cols = 3;
+      break;
+   case GL_FLOAT_MAT3x4:
+      *rows = 4;
+      *cols = 3;
+      break;
+   case GL_FLOAT_MAT4:
+      *rows = 4;
+      *cols = 4;
+      break;
+   case GL_FLOAT_MAT4x2:
+      *rows = 2;
+      *cols = 4;
+      break;
+   case GL_FLOAT_MAT4x3:
+      *rows = 3;
+      *cols = 4;
+      break;
+   default:
+      *rows = *cols = 0;
+   }
+}
+
+
+/**
+ * Determine the number of rows and columns occupied by a uniform
+ * according to its datatype.  For non-matrix types (such as GL_FLOAT_VEC4),
+ * the number of rows = 1 and cols = number of elements in the vector.
+ */
+static void
+get_uniform_rows_cols(const struct gl_program_parameter *p,
+                      GLint *rows, GLint *cols)
+{
+   get_matrix_dims(p->DataType, rows, cols);
+   if (*rows == 0 && *cols == 0) {
+      /* not a matrix type, probably a float or vector */
+      if (p->Size <= 4) {
+         *rows = 1;
+         *cols = p->Size;
+      }
+      else {
+         *rows = p->Size / 4 + 1;
+         if (p->Size % 4 == 0)
+            *cols = 4;
+         else
+            *cols = p->Size % 4;
+      }
+   }
+}
+
+
+/**
+ * Helper for get_uniform[fi]v() functions.
+ * Given a shader program name and uniform location, return a pointer
+ * to the shader program and return the program parameter position.
+ */
+static void
+lookup_uniform_parameter(GLcontext *ctx, GLuint program, GLint location,
+                         struct gl_program **progOut, GLint *paramPosOut)
+{
+   struct gl_shader_program *shProg
+      = _mesa_lookup_shader_program_err(ctx, program, "glGetUniform[if]v");
+   struct gl_program *prog = NULL;
+   GLint progPos = -1;
+
+   /* if shProg is NULL, we'll have already recorded an error */
+
+   if (shProg) {
+      if (!shProg->Uniforms ||
+          location < 0 ||
+          location >= (GLint) shProg->Uniforms->NumUniforms) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,  "glGetUniformfv(location)");
+      }
+      else {
+         /* OK, find the gl_program and program parameter location */
+         progPos = shProg->Uniforms->Uniforms[location].VertPos;
+         if (progPos >= 0) {
+            prog = &shProg->VertexProgram->Base;
+         }
+         else {
+            progPos = shProg->Uniforms->Uniforms[location].FragPos;
+            if (progPos >= 0) {
+               prog = &shProg->FragmentProgram->Base;
+            } else {
+               progPos = shProg->Uniforms->Uniforms[location].GeomPos;
+               if (progPos >= 0) {
+                  prog = &shProg->GeometryProgram->Base;
+               }
+            }
+         }
+      }
+   }
+
+   *progOut = prog;
+   *paramPosOut = progPos;
+}
+
+
+/**
+ * GLGL uniform arrays and structs require special handling.
+ *
+ * The GL_ARB_shader_objects spec says that if you use
+ * glGetUniformLocation to get the location of an array, you CANNOT
+ * access other elements of the array by adding an offset to the
+ * returned location.  For example, you must call
+ * glGetUniformLocation("foo[16]") if you want to set the 16th element
+ * of the array with glUniform().
+ *
+ * HOWEVER, some other OpenGL drivers allow accessing array elements
+ * by adding an offset to the returned array location.  And some apps
+ * seem to depend on that behaviour.
+ *
+ * Mesa's gl_uniform_list doesn't directly support this since each
+ * entry in the list describes one uniform variable, not one uniform
+ * element.  We could insert dummy entries in the list for each array
+ * element after [0] but that causes complications elsewhere.
+ *
+ * We solve this problem by encoding two values in the location that's
+ * returned by glGetUniformLocation():
+ *  a) index into gl_uniform_list::Uniforms[] for the uniform
+ *  b) an array/field offset (0 for simple types)
+ *
+ * These two values are encoded in the high and low halves of a GLint.
+ * By putting the uniform number in the high part and the offset in the
+ * low part, we can support the unofficial ability to index into arrays
+ * by adding offsets to the location value.
+ */
+static void
+merge_location_offset(GLint *location, GLint offset)
+{
+   *location = (*location << 16) | offset;
+}
+
+
+/**
+ * Separate the uniform location and parameter offset.  See above.
+ */
+static void
+split_location_offset(GLint *location, GLint *offset)
+{
+   *offset = *location & 0xffff;
+   *location = *location >> 16;
+}
+
+
+
+/**
+ * Called via glGetUniformfv().
+ */
+static void
+_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
+                    GLfloat *params)
+{
+   struct gl_program *prog;
+   GLint paramPos;
+   GLint offset;
+
+   split_location_offset(&location, &offset);
+
+   lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
+
+   if (prog) {
+      const struct gl_program_parameter *p =
+         &prog->Parameters->Parameters[paramPos];
+      GLint rows, cols, i, j, k;
+
+      get_uniform_rows_cols(p, &rows, &cols);
+
+      k = 0;
+      for (i = 0; i < rows; i++) {
+         for (j = 0; j < cols; j++ ) {
+            params[k++] = prog->Parameters->ParameterValues[paramPos+i][j];
+         }
+      }
+   }
+}
+
+
+/**
+ * Called via glGetUniformiv().
+ * \sa _mesa_get_uniformfv, only difference is a cast.
+ */
+static void
+_mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location,
+                    GLint *params)
+{
+   struct gl_program *prog;
+   GLint paramPos;
+   GLint offset;
+
+   split_location_offset(&location, &offset);
+
+   lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
+
+   if (prog) {
+      const struct gl_program_parameter *p =
+         &prog->Parameters->Parameters[paramPos];
+      GLint rows, cols, i, j, k;
+
+      get_uniform_rows_cols(p, &rows, &cols);
+
+      k = 0;
+      for (i = 0; i < rows; i++) {
+         for (j = 0; j < cols; j++ ) {
+            params[k++] = (GLint) prog->Parameters->ParameterValues[paramPos+i][j];
+         }
+      }
+   }
+}
+
+
+/**
+ * Called via glGetUniformLocation().
+ *
+ * The return value will encode two values, the uniform location and an
+ * offset (used for arrays, structs).
+ */
+static GLint
+_mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name)
+{
+   GLint offset = 0, location = -1;
+
+   struct gl_shader_program *shProg =
+      _mesa_lookup_shader_program_err(ctx, program, "glGetUniformLocation");
+
+   if (!shProg)
+      return -1;
+
+   if (shProg->LinkStatus == GL_FALSE) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
+      return -1;
+   }
+
+   /* XXX we should return -1 if the uniform was declared, but not
+    * actually used.
+    */
+
+   /* XXX we need to be able to parse uniform names for structs and arrays
+    * such as:
+    *   mymatrix[1]
+    *   mystruct.field1
+    */
+
+   {
+      /* handle 1-dimension arrays here... */
+      char *c = strchr(name, '[');
+      if (c) {
+         /* truncate name at [ */
+         const GLint len = c - name;
+         GLchar *newName = malloc(len + 1);
+         if (!newName)
+            return -1; /* out of mem */
+         memcpy(newName, name, len);
+         newName[len] = 0;
+
+         location = _mesa_lookup_uniform(shProg->Uniforms, newName);
+         if (location >= 0) {
+            const GLint element = atoi(c + 1);
+            if (element > 0) {
+               /* get type of the uniform array element */
+               struct gl_program_parameter *p;
+               p = get_uniform_parameter(shProg, location);
+               if (p) {
+                  GLint rows, cols;
+                  get_matrix_dims(p->DataType, &rows, &cols);
+                  if (rows < 1)
+                     rows = 1;
+                  offset = element * rows;
+               }
+            }
+         }
+
+         free(newName);
+      }
+   }
+
+   if (location < 0) {
+      location = _mesa_lookup_uniform(shProg->Uniforms, name);
+   }
+
+   if (location >= 0) {
+      merge_location_offset(&location, offset);
+   }
+
+   return location;
+}
+
+
+
+/**
+ * Update the vertex/fragment program's TexturesUsed array.
+ *
+ * This needs to be called after glUniform(set sampler var) is called.
+ * A call to glUniform(samplerVar, value) causes a sampler to point to a
+ * particular texture unit.  We know the sampler's texture target
+ * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
+ * set by glUniform() calls.
+ *
+ * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
+ * information to update the prog->TexturesUsed[] values.
+ * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
+ * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
+ * We'll use that info for state validation before rendering.
+ */
+void
+_mesa_update_shader_textures_used(struct gl_program *prog)
+{
+   GLuint s;
+
+   memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
+
+   for (s = 0; s < MAX_SAMPLERS; s++) {
+      if (prog->SamplersUsed & (1 << s)) {
+         GLuint unit = prog->SamplerUnits[s];
+         GLuint tgt = prog->SamplerTargets[s];
+         assert(unit < MAX_TEXTURE_IMAGE_UNITS);
+         assert(tgt < NUM_TEXTURE_TARGETS);
+         prog->TexturesUsed[unit] |= (1 << tgt);
+      }
+   }
+}
+
+
+/**
+ * Check if the type given by userType is allowed to set a uniform of the
+ * target type.  Generally, equivalence is required, but setting Boolean
+ * uniforms can be done with glUniformiv or glUniformfv.
+ */
+static GLboolean
+compatible_types(GLenum userType, GLenum targetType)
+{
+   if (userType == targetType)
+      return GL_TRUE;
+
+   if (targetType == GL_BOOL && (userType == GL_FLOAT ||
+                                 userType == GL_UNSIGNED_INT ||
+                                 userType == GL_INT))
+      return GL_TRUE;
+
+   if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 ||
+                                      userType == GL_UNSIGNED_INT_VEC2 ||
+                                      userType == GL_INT_VEC2))
+      return GL_TRUE;
+
+   if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 ||
+                                      userType == GL_UNSIGNED_INT_VEC3 ||
+                                      userType == GL_INT_VEC3))
+      return GL_TRUE;
+
+   if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 ||
+                                      userType == GL_UNSIGNED_INT_VEC4 ||
+                                      userType == GL_INT_VEC4))
+      return GL_TRUE;
+
+   if (is_sampler_type(targetType) && userType == GL_INT)
+      return GL_TRUE;
+
+   return GL_FALSE;
+}
+
+
+/**
+ * Set the value of a program's uniform variable.
+ * \param program  the program whose uniform to update
+ * \param index  the index of the program parameter for the uniform
+ * \param offset  additional parameter slot offset (for arrays)
+ * \param type  the incoming datatype of 'values'
+ * \param count  the number of uniforms to set
+ * \param elems  number of elements per uniform (1, 2, 3 or 4)
+ * \param values  the new values, of datatype 'type'
+ */
+static void
+set_program_uniform(GLcontext *ctx, struct gl_program *program,
+                    GLint index, GLint offset,
+                    GLenum type, GLsizei count, GLint elems,
+                    const void *values)
+{
+   const struct gl_program_parameter *param =
+      &program->Parameters->Parameters[index];
+
+   assert(offset >= 0);
+   assert(elems >= 1);
+   assert(elems <= 4);
+
+   if (!compatible_types(type, param->DataType)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
+      return;
+   }
+
+   if (index + offset > (GLint) program->Parameters->Size) {
+      /* out of bounds! */
+      return;
+   }
+
+   if (param->Type == PROGRAM_SAMPLER) {
+      /* This controls which texture unit which is used by a sampler */
+      GLboolean changed = GL_FALSE;
+      GLint i;
+
+      /* this should have been caught by the compatible_types() check */
+      ASSERT(type == GL_INT);
+
+      /* loop over number of samplers to change */
+      for (i = 0; i < count; i++) {
+         GLuint sampler =
+            (GLuint) program->Parameters->ParameterValues[index + offset + i][0];
+         GLuint texUnit = ((GLuint *) values)[i];
+
+         /* check that the sampler (tex unit index) is legal */
+         if (texUnit >= ctx->Const.MaxTextureImageUnits) {
+            _mesa_error(ctx, GL_INVALID_VALUE,
+                        "glUniform1(invalid sampler/tex unit index for '%s')",
+                        param->Name);
+            return;
+         }
+
+         /* This maps a sampler to a texture unit: */
+         if (sampler < MAX_SAMPLERS) {
+#if 0
+            printf("Set program %p sampler %d '%s' to unit %u\n",
+                  program, sampler, param->Name, texUnit);
+#endif
+            if (program->SamplerUnits[sampler] != texUnit) {
+               program->SamplerUnits[sampler] = texUnit;
+               changed = GL_TRUE;
+            }
+         }
+      }
+
+      if (changed) {
+         /* When a sampler's value changes it usually requires rewriting
+          * a GPU program's TEX instructions since there may not be a
+          * sampler->texture lookup table.  We signal this with the
+          * ProgramStringNotify() callback.
+          */
+         FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
+         _mesa_update_shader_textures_used(program);
+         /* Do we need to care about the return value here?
+          * This should not be the first time the driver was notified of
+          * this program.
+          */
+         (void) ctx->Driver.ProgramStringNotify(ctx, program->Target, program);
+      }
+   }
+   else {
+      /* ordinary uniform variable */
+      const GLboolean isUniformBool = is_boolean_type(param->DataType);
+      const GLenum basicType = base_uniform_type(type);
+      const GLint slots = (param->Size + 3) / 4;
+      const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
+      GLsizei k, i;
+
+      if ((GLint) param->Size > typeSize) {
+         /* an array */
+         /* we'll ignore extra data below */
+      }
+      else {
+         /* non-array: count must be at most one; count == 0 is handled by the loop below */
+         if (count > 1) {
+            _mesa_error(ctx, GL_INVALID_OPERATION,
+                        "glUniform(uniform '%s' is not an array)",
+                        param->Name);
+            return;
+         }
+      }
+
+      /* loop over number of array elements */
+      for (k = 0; k < count; k++) {
+         GLfloat *uniformVal;
+
+         if (offset + k >= slots) {
+            /* Extra array data is ignored */
+            break;
+         }
+
+         /* uniformVal (the destination) is always float[4] */
+         uniformVal = program->Parameters->ParameterValues[index + offset + k];
+
+         if (basicType == GL_INT) {
+            /* convert user's ints to floats */
+            const GLint *iValues = ((const GLint *) values) + k * elems;
+            for (i = 0; i < elems; i++) {
+               uniformVal[i] = (GLfloat) iValues[i];
+            }
+         }
+         else if (basicType == GL_UNSIGNED_INT) {
+            /* convert user's uints to floats */
+            const GLuint *iValues = ((const GLuint *) values) + k * elems;
+            for (i = 0; i < elems; i++) {
+               uniformVal[i] = (GLfloat) iValues[i];
+            }
+         }
+         else {
+            const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
+            assert(basicType == GL_FLOAT);
+            for (i = 0; i < elems; i++) {
+               uniformVal[i] = fValues[i];
+            }
+         }
+
+         /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
+         if (isUniformBool) {
+            for (i = 0; i < elems; i++) {
+               uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f;
+            }
+         }
+      }
+   }
+}
+
+
+/**
+ * Called via glUniform*() functions.
+ */
+static void
+_mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
+              const GLvoid *values, GLenum type)
+{
+   struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
+   struct gl_uniform *uniform;
+   GLint elems, offset;
+
+   if (!shProg || !shProg->LinkStatus) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
+      return;
+   }
+
+   if (location == -1)
+      return;   /* The standard specifies this as a no-op */
+
+   if (location < -1) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(location=%d)",
+                  location);
+      return;
+   }
+
+   split_location_offset(&location, &offset);
+
+   if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location=%d)", location);
+      return;
+   }
+
+   if (count < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)");
+      return;
+   }
+
+   elems = _mesa_sizeof_glsl_type(type);
+
+   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
+
+   uniform = &shProg->Uniforms->Uniforms[location];
+
+   if (ctx->Shader.Flags & GLSL_UNIFORMS) {
+      const GLenum basicType = base_uniform_type(type);
+      GLint i;
+      printf("Mesa: set program %u uniform %s (loc %d) to: ",
+            shProg->Name, uniform->Name, location);
+      if (basicType == GL_INT) {
+         const GLint *v = (const GLint *) values;
+         for (i = 0; i < count * elems; i++) {
+            printf("%d ", v[i]);
+         }
+      }
+      else if (basicType == GL_UNSIGNED_INT) {
+         const GLuint *v = (const GLuint *) values;
+         for (i = 0; i < count * elems; i++) {
+            printf("%u ", v[i]);
+         }
+      }
+      else {
+         const GLfloat *v = (const GLfloat *) values;
+         assert(basicType == GL_FLOAT);
+         for (i = 0; i < count * elems; i++) {
+            printf("%g ", v[i]);
+         }
+      }
+      printf("\n");
+   }
+
+   /* A uniform var may be used by both a vertex shader and a fragment
+    * shader.  We may need to update one or both shader's uniform here:
+    */
+   if (shProg->VertexProgram) {
+      /* convert uniform location to program parameter index */
+      GLint index = uniform->VertPos;
+      if (index >= 0) {
+         set_program_uniform(ctx, &shProg->VertexProgram->Base,
+                             index, offset, type, count, elems, values);
+      }
+   }
+
+   if (shProg->FragmentProgram) {
+      /* convert uniform location to program parameter index */
+      GLint index = uniform->FragPos;
+      if (index >= 0) {
+         set_program_uniform(ctx, &shProg->FragmentProgram->Base,
+                             index, offset, type, count, elems, values);
+      }
+   }
+
+   if (shProg->GeometryProgram) {
+      /* convert uniform location to program parameter index */
+      GLint index = uniform->GeomPos;
+      if (index >= 0) {
+         set_program_uniform(ctx, &shProg->GeometryProgram->Base,
+                             index, offset, type, count, elems, values);
+      }
+   }
+
+   uniform->Initialized = GL_TRUE;
+}
+
+
+/**
+ * Set a matrix-valued program parameter.
+ */
+static void
+set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
+                           GLuint index, GLuint offset,
+                           GLuint count, GLuint rows, GLuint cols,
+                           GLboolean transpose, const GLfloat *values)
+{
+   GLuint mat, row, col;
+   GLuint src = 0;
+   const struct gl_program_parameter * param = &program->Parameters->Parameters[index];
+   const GLuint slots = (param->Size + 3) / 4;
+   const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
+   GLint nr, nc;
+
+   /* check that the number of rows, columns is correct */
+   get_matrix_dims(param->DataType, &nr, &nc);
+   if (rows != nr || cols != nc) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glUniformMatrix(matrix size mismatch)");
+      return;
+   }
+
+   if ((GLint) param->Size <= typeSize) {
+      /* non-array: count must be at most one; count == 0 is handled by the loop below */
+      if (count > 1) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "glUniformMatrix(uniform is not an array)");
+         return;
+      }
+   }
+
+   /*
+    * Note: the _columns_ of a matrix are stored in program registers, not
+    * the rows.  So, the loops below look a little funny.
+    * XXX could optimize this a bit...
+    */
+
+   /* loop over matrices */
+   for (mat = 0; mat < count; mat++) {
+
+      /* each matrix: */
+      for (col = 0; col < cols; col++) {
+         GLfloat *v;
+         if (offset >= slots) {
+            /* Ignore writes beyond the end of (the used part of) an array */
+            return;
+         }
+         v = program->Parameters->ParameterValues[index + offset];
+         for (row = 0; row < rows; row++) {
+            if (transpose) {
+               v[row] = values[src + row * cols + col];
+            }
+            else {
+               v[row] = values[src + col * rows + row];
+            }
+         }
+
+         offset++;
+      }
+
+      src += rows * cols;  /* next matrix */
+   }
+}
+
+
+/**
+ * Called by glUniformMatrix*() functions.
+ * Note: cols=2, rows=4  ==>  array[2] of vec4
+ */
+static void
+_mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
+                     GLint location, GLsizei count,
+                     GLboolean transpose, const GLfloat *values)
+{
+   struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
+   struct gl_uniform *uniform;
+   GLint offset;
+
+   if (!shProg || !shProg->LinkStatus) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+         "glUniformMatrix(program not linked)");
+      return;
+   }
+
+   if (location == -1)
+      return;   /* The standard specifies this as a no-op */
+
+   if (location < -1) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(location)");
+      return;
+   }
+
+   split_location_offset(&location, &offset);
+
+   if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)");
+      return;
+   }
+   if (values == NULL) {
+      _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix");
+      return;
+   }
+
+   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
+
+   uniform = &shProg->Uniforms->Uniforms[location];
+
+   if (shProg->VertexProgram) {
+      /* convert uniform location to program parameter index */
+      GLint index = uniform->VertPos;
+      if (index >= 0) {
+         set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base,
+                                    index, offset,
+                                    count, rows, cols, transpose, values);
+      }
+   }
+
+   if (shProg->FragmentProgram) {
+      /* convert uniform location to program parameter index */
+      GLint index = uniform->FragPos;
+      if (index >= 0) {
+         set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base,
+                                    index, offset,
+                                    count, rows, cols, transpose, values);
+      }
+   }
+
+   if (shProg->GeometryProgram) {
+      /* convert uniform location to program parameter index */
+      GLint index = uniform->GeomPos;
+      if (index >= 0) {
+         set_program_uniform_matrix(ctx, &shProg->GeometryProgram->Base,
+                                    index, offset,
+                                    count, rows, cols, transpose, values);
+      }
+   }
+
+   uniform->Initialized = GL_TRUE;
+}
+
+
+void GLAPIENTRY
+_mesa_Uniform1fARB(GLint location, GLfloat v0)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, location, 1, &v0, GL_FLOAT);
+}
+
+void GLAPIENTRY
+_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLfloat v[2];
+   v[0] = v0;
+   v[1] = v1;
+   _mesa_uniform(ctx, location, 1, v, GL_FLOAT_VEC2);
+}
+
+void GLAPIENTRY
+_mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLfloat v[3];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   _mesa_uniform(ctx, location, 1, v, GL_FLOAT_VEC3);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
+                   GLfloat v3)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLfloat v[4];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   v[3] = v3;
+   _mesa_uniform(ctx, location, 1, v, GL_FLOAT_VEC4);
+}
+
+void GLAPIENTRY
+_mesa_Uniform1iARB(GLint location, GLint v0)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, location, 1, &v0, GL_INT);
+}
+
+void GLAPIENTRY
+_mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLint v[2];
+   v[0] = v0;
+   v[1] = v1;
+   _mesa_uniform(ctx, location, 1, v, GL_INT_VEC2);
+}
+
+void GLAPIENTRY
+_mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLint v[3];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   _mesa_uniform(ctx, location, 1, v, GL_INT_VEC3);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLint v[4];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   v[3] = v3;
+   _mesa_uniform(ctx, location, 1, v, GL_INT_VEC4);
+}
+
+void GLAPIENTRY
+_mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, location, count, value, GL_FLOAT);
+}
+
+void GLAPIENTRY
+_mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, location, count, value, GL_FLOAT_VEC2);
+}
+
+void GLAPIENTRY
+_mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, location, count, value, GL_FLOAT_VEC3);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, location, count, value, GL_FLOAT_VEC4);
+}
+
+void GLAPIENTRY
+_mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, location, count, value, GL_INT);
+}
+
+void GLAPIENTRY
+_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, location, count, value, GL_INT_VEC2);
+}
+
+void GLAPIENTRY
+_mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, location, count, value, GL_INT_VEC3);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, location, count, value, GL_INT_VEC4);
+}
+
+
+/** OpenGL 3.0 GLuint-valued functions **/
+void GLAPIENTRY
+_mesa_Uniform1ui(GLint location, GLuint v0)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, location, 1, &v0, GL_UNSIGNED_INT);
+}
+
+void GLAPIENTRY
+_mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLuint v[2];
+   v[0] = v0;
+   v[1] = v1;
+   _mesa_uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC2);
+}
+
+void GLAPIENTRY
+_mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLuint v[3];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   _mesa_uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC3);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLuint v[4];
+   v[0] = v0;
+   v[1] = v1;
+   v[2] = v2;
+   v[3] = v3;
+   _mesa_uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC4);
+}
+
+void GLAPIENTRY
+_mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, location, count, value, GL_UNSIGNED_INT);
+}
+
+void GLAPIENTRY
+_mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC2);
+}
+
+void GLAPIENTRY
+_mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC3);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC4);
+}
+
+
+
+void GLAPIENTRY
+_mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
+                          const GLfloat * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(ctx, 2, 2, location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
+                          const GLfloat * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(ctx, 3, 3, location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
+                          const GLfloat * value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(ctx, 4, 4, location, count, transpose, value);
+}
+
+
+/**
+ * Non-square UniformMatrix are OpenGL 2.1
+ */
+void GLAPIENTRY
+_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLfloat *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(ctx, 2, 3, location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLfloat *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(ctx, 3, 2, location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLfloat *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(ctx, 2, 4, location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLfloat *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(ctx, 4, 2, location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLfloat *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(ctx, 3, 4, location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLfloat *value)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_uniform_matrix(ctx, 4, 3, location, count, transpose, value);
+}
+
+
+void GLAPIENTRY
+_mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_get_uniformfv(ctx, program, location, params);
+}
+
+
+void GLAPIENTRY
+_mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint *params)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_get_uniformiv(ctx, program, location, params);
+}
+
+
+GLint GLAPIENTRY
+_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   return _mesa_get_uniform_location(ctx, programObj, name);
+}
+
+
+void GLAPIENTRY
+_mesa_GetActiveUniformARB(GLhandleARB program, GLuint index,
+                          GLsizei maxLength, GLsizei * length, GLint * size,
+                          GLenum * type, GLcharARB * name)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   _mesa_get_active_uniform(ctx, program, index, maxLength, length, size,
+                            type, name);
+}
+
+
+/**
+ * Plug in shader uniform-related functions into API dispatch table.
+ */
+void
+_mesa_init_shader_uniform_dispatch(struct _glapi_table *exec)
+{
+#if FEATURE_GL
+   SET_Uniform1fARB(exec, _mesa_Uniform1fARB);
+   SET_Uniform2fARB(exec, _mesa_Uniform2fARB);
+   SET_Uniform3fARB(exec, _mesa_Uniform3fARB);
+   SET_Uniform4fARB(exec, _mesa_Uniform4fARB);
+   SET_Uniform1iARB(exec, _mesa_Uniform1iARB);
+   SET_Uniform2iARB(exec, _mesa_Uniform2iARB);
+   SET_Uniform3iARB(exec, _mesa_Uniform3iARB);
+   SET_Uniform4iARB(exec, _mesa_Uniform4iARB);
+   SET_Uniform1fvARB(exec, _mesa_Uniform1fvARB);
+   SET_Uniform2fvARB(exec, _mesa_Uniform2fvARB);
+   SET_Uniform3fvARB(exec, _mesa_Uniform3fvARB);
+   SET_Uniform4fvARB(exec, _mesa_Uniform4fvARB);
+   SET_Uniform1ivARB(exec, _mesa_Uniform1ivARB);
+   SET_Uniform2ivARB(exec, _mesa_Uniform2ivARB);
+   SET_Uniform3ivARB(exec, _mesa_Uniform3ivARB);
+   SET_Uniform4ivARB(exec, _mesa_Uniform4ivARB);
+   SET_UniformMatrix2fvARB(exec, _mesa_UniformMatrix2fvARB);
+   SET_UniformMatrix3fvARB(exec, _mesa_UniformMatrix3fvARB);
+   SET_UniformMatrix4fvARB(exec, _mesa_UniformMatrix4fvARB);
+
+   SET_GetActiveUniformARB(exec, _mesa_GetActiveUniformARB);
+   SET_GetUniformLocationARB(exec, _mesa_GetUniformLocationARB);
+   SET_GetUniformfvARB(exec, _mesa_GetUniformfvARB);
+   SET_GetUniformivARB(exec, _mesa_GetUniformivARB);
+
+   /* OpenGL 2.1 */
+   SET_UniformMatrix2x3fv(exec, _mesa_UniformMatrix2x3fv);
+   SET_UniformMatrix3x2fv(exec, _mesa_UniformMatrix3x2fv);
+   SET_UniformMatrix2x4fv(exec, _mesa_UniformMatrix2x4fv);
+   SET_UniformMatrix4x2fv(exec, _mesa_UniformMatrix4x2fv);
+   SET_UniformMatrix3x4fv(exec, _mesa_UniformMatrix3x4fv);
+   SET_UniformMatrix4x3fv(exec, _mesa_UniformMatrix4x3fv);
+
+   /* OpenGL 3.0 */
+   /* XXX finish dispatch */
+   (void) _mesa_Uniform1ui;
+   (void) _mesa_Uniform2ui;
+   (void) _mesa_Uniform3ui;
+   (void) _mesa_Uniform4ui;
+   (void) _mesa_Uniform1uiv;
+   (void) _mesa_Uniform2uiv;
+   (void) _mesa_Uniform3uiv;
+   (void) _mesa_Uniform4uiv;
+#endif /* FEATURE_GL */
+}
diff --git a/src/mesa/main/uniforms.h b/src/mesa/main/uniforms.h
new file mode 100644 (file)
index 0000000..29f77cb
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2010  VMware, 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
+ * 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
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION 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 UNIFORMS_H
+#define UNIFORMS_H
+
+
+extern void GLAPIENTRY
+_mesa_Uniform1fARB(GLint, GLfloat);
+
+extern void GLAPIENTRY
+_mesa_Uniform2fARB(GLint, GLfloat, GLfloat);
+
+extern void GLAPIENTRY
+_mesa_Uniform3fARB(GLint, GLfloat, GLfloat, GLfloat);
+
+extern void GLAPIENTRY
+_mesa_Uniform4fARB(GLint, GLfloat, GLfloat, GLfloat, GLfloat);
+
+extern void GLAPIENTRY
+_mesa_Uniform1iARB(GLint, GLint);
+
+extern void GLAPIENTRY
+_mesa_Uniform2iARB(GLint, GLint, GLint);
+
+extern void GLAPIENTRY
+_mesa_Uniform3iARB(GLint, GLint, GLint, GLint);
+
+extern void GLAPIENTRY
+_mesa_Uniform4iARB(GLint, GLint, GLint, GLint, GLint);
+
+extern void GLAPIENTRY
+_mesa_Uniform1fvARB(GLint, GLsizei, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_Uniform2fvARB(GLint, GLsizei, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_Uniform3fvARB(GLint, GLsizei, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_Uniform4fvARB(GLint, GLsizei, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_Uniform1ivARB(GLint, GLsizei, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_Uniform2ivARB(GLint, GLsizei, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_Uniform3ivARB(GLint, GLsizei, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_Uniform4ivARB(GLint, GLsizei, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_Uniform1ui(GLint location, GLuint v0);
+
+extern void GLAPIENTRY
+_mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1);
+
+extern void GLAPIENTRY
+_mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2);
+
+extern void GLAPIENTRY
+_mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+
+extern void GLAPIENTRY
+_mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value);
+
+extern void GLAPIENTRY
+_mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value);
+
+extern void GLAPIENTRY
+_mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value);
+
+extern void GLAPIENTRY
+_mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value);
+
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix2fvARB(GLint, GLsizei, GLboolean, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix3fvARB(GLint, GLsizei, GLboolean, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix4fvARB(GLint, GLsizei, GLboolean, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
+                         const GLfloat *value);
+
+
+extern void GLAPIENTRY
+_mesa_GetActiveUniformARB(GLhandleARB, GLuint, GLsizei, GLsizei *,
+                          GLint *, GLenum *, GLcharARB *);
+
+extern void GLAPIENTRY
+_mesa_GetUniformfvARB(GLhandleARB, GLint, GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_GetUniformivARB(GLhandleARB, GLint, GLint *);
+
+extern GLint GLAPIENTRY
+_mesa_GetUniformLocationARB(GLhandleARB, const GLcharARB *);
+
+
+
+extern void
+_mesa_update_shader_textures_used(struct gl_program *prog);
+
+
+extern void
+_mesa_init_shader_uniform_dispatch(struct _glapi_table *exec);
+
+#endif /* UNIFORMS_H */
index da374acb5c841843f5c4a48770d9af21edb99370..6c0cfc4e3275a6bb90d23be535e137afcb355ef7 100644 (file)
@@ -1368,10 +1368,10 @@ print_array(const char *name, GLint index, const struct gl_client_array *array)
       printf("  %s[%d]: ", name, index);
    else
       printf("  %s: ", name);
-   printf("Ptr=%p, Type=0x%x, Size=%d, ElemSize=%u, Stride=%d, Buffer=%u(Size %u), MaxElem=%u\n",
+   printf("Ptr=%p, Type=0x%x, Size=%d, ElemSize=%u, Stride=%d, Buffer=%u(Size %lu), MaxElem=%u\n",
          array->Ptr, array->Type, array->Size,
          array->_ElementSize, array->StrideB,
-         array->BufferObj->Name, array->BufferObj->Size,
+         array->BufferObj->Name, (unsigned long) array->BufferObj->Size,
          array->_MaxElement);
 }
 
index dea3019d0bc01147c478a30639a70c6f0b9e4ae6..d833a160e9e55da858deec64703e48be9bbcbb76 100644 (file)
@@ -87,7 +87,71 @@ compute_version(GLcontext *ctx)
                               ctx->Extensions.ARB_shading_language_120 &&
                               ctx->Extensions.EXT_pixel_buffer_object &&
                               ctx->Extensions.EXT_texture_sRGB);
-   if (ver_2_1) {
+   const GLboolean ver_3_0 = (ver_2_1 &&
+                              ctx->Extensions.ARB_half_float_pixel &&
+                              ctx->Extensions.ARB_map_buffer_range &&
+                              ctx->Extensions.ARB_texture_float &&
+                              ctx->Extensions.ARB_texture_rg &&
+                              ctx->Extensions.APPLE_vertex_array_object &&
+                              ctx->Extensions.EXT_draw_buffers2 &&
+                              ctx->Extensions.EXT_framebuffer_blit &&
+                              ctx->Extensions.EXT_framebuffer_multisample &&
+                              ctx->Extensions.EXT_framebuffer_object &&
+                              ctx->Extensions.EXT_framebuffer_sRGB &&
+                              ctx->Extensions.EXT_packed_depth_stencil &&
+                              ctx->Extensions.EXT_packed_float &&
+                              ctx->Extensions.EXT_texture_array &&
+                              ctx->Extensions.EXT_texture_compression_rgtc &&
+                              ctx->Extensions.EXT_texture_integer &&
+                              ctx->Extensions.EXT_texture_shared_exponent &&
+                              ctx->Extensions.EXT_transform_feedback &&
+                              ctx->Extensions.NV_conditional_render);
+   const GLboolean ver_3_1 = (ver_3_0 &&
+                              ctx->Extensions.ARB_copy_buffer &&
+                              ctx->Extensions.ARB_draw_instanced &&
+                              ctx->Extensions.ARB_texture_buffer_object &&
+                              ctx->Extensions.ARB_uniform_buffer_object &&
+                              ctx->Extensions.NV_primitive_restart &&
+                              ctx->Extensions.NV_texture_rectangle &&
+                              ctx->Const.MaxVertexTextureImageUnits >= 16);
+   const GLboolean ver_3_2 = (ver_3_1 &&
+                              ctx->Extensions.ARB_depth_clamp &&
+                              ctx->Extensions.ARB_draw_elements_base_vertex &&
+                              ctx->Extensions.ARB_fragment_coord_conventions &&
+                              ctx->Extensions.ARB_geometry_shader4 &&
+                              ctx->Extensions.EXT_provoking_vertex &&
+                              ctx->Extensions.ARB_seamless_cube_map &&
+                              ctx->Extensions.ARB_sync &&
+                              ctx->Extensions.ARB_texture_multisample &&
+                              ctx->Extensions.EXT_vertex_array_bgra);
+   const GLboolean ver_3_3 = (ver_3_2 &&
+                              ctx->Extensions.ARB_blend_func_extended &&
+                              ctx->Extensions.ARB_explicit_attrib_location &&
+                              ctx->Extensions.ARB_instanced_arrays &&
+                              ctx->Extensions.ARB_occlusion_query2 &&
+                              ctx->Extensions.ARB_sampler_objects &&
+                              ctx->Extensions.ARB_texture_rgb10_a2ui &&
+                              ctx->Extensions.ARB_timer_query &&
+                              ctx->Extensions.ARB_vertex_type_2_10_10_10_rev &&
+                              ctx->Extensions.EXT_texture_swizzle);
+
+   if (ver_3_3) {
+      major = 3;
+      minor = 3;
+   }
+   else if (ver_3_2) {
+      major = 3;
+      minor = 2;
+   }
+   else if (ver_3_1) {
+      major = 3;
+      minor = 1;
+   }
+   else if (ver_3_0) {
+      major = 3;
+      minor = 0;
+   }
+   else if (ver_2_1) {
       major = 2;
       minor = 1;
    }
diff --git a/src/mesa/program/.gitignore b/src/mesa/program/.gitignore
new file mode 100644 (file)
index 0000000..086fd9a
--- /dev/null
@@ -0,0 +1 @@
+program_parse.output
diff --git a/src/mesa/program/Makefile b/src/mesa/program/Makefile
new file mode 100644 (file)
index 0000000..400a543
--- /dev/null
@@ -0,0 +1,7 @@
+all: program_parse.tab.c lex.yy.c
+
+program_parse.tab.c program_parse.tab.h: program_parse.y
+       bison -v -d $<
+
+lex.yy.c: program_lexer.l
+       flex --never-interactive $<
diff --git a/src/mesa/program/arbprogparse.c b/src/mesa/program/arbprogparse.c
new file mode 100644 (file)
index 0000000..6373529
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.1
+ *
+ * Copyright (C) 1999-2008  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.
+ */
+
+#define DEBUG_PARSING 0
+
+/**
+ * \file arbprogparse.c
+ * ARB_*_program parser core
+ * \author Karl Rasche
+ */
+
+/**
+Notes on program parameters, etc.
+
+The instructions we emit will use six kinds of source registers:
+
+  PROGRAM_INPUT      - input registers
+  PROGRAM_TEMPORARY  - temp registers
+  PROGRAM_ADDRESS    - address/indirect register
+  PROGRAM_SAMPLER    - texture sampler
+  PROGRAM_CONSTANT   - indexes into program->Parameters, a known constant/literal
+  PROGRAM_STATE_VAR  - indexes into program->Parameters, and may actually be:
+                       + a state variable, like "state.fog.color", or
+                       + a pointer to a "program.local[k]" parameter, or
+                       + a pointer to a "program.env[k]" parameter
+
+Basically, all the program.local[] and program.env[] values will get mapped
+into the unified gl_program->Parameters array.  This solves the problem of
+having three separate program parameter arrays.
+*/
+
+
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "main/context.h"
+#include "main/mtypes.h"
+#include "arbprogparse.h"
+#include "programopt.h"
+#include "prog_parameter.h"
+#include "prog_statevars.h"
+#include "prog_instruction.h"
+#include "program_parser.h"
+
+
+void
+_mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target,
+                                 const GLvoid *str, GLsizei len,
+                                 struct gl_fragment_program *program)
+{
+   struct gl_program prog;
+   struct asm_parser_state state;
+   GLuint i;
+
+   ASSERT(target == GL_FRAGMENT_PROGRAM_ARB);
+
+   memset(&prog, 0, sizeof(prog));
+   memset(&state, 0, sizeof(state));
+   state.prog = &prog;
+
+   if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len,
+                               &state)) {
+      /* Error in the program. Just return. */
+      return;
+   }
+
+   if (program->Base.String != NULL)
+      free(program->Base.String);
+
+   /* Copy the relevant contents of the arb_program struct into the
+    * fragment_program struct.
+    */
+   program->Base.String          = prog.String;
+   program->Base.NumInstructions = prog.NumInstructions;
+   program->Base.NumTemporaries  = prog.NumTemporaries;
+   program->Base.NumParameters   = prog.NumParameters;
+   program->Base.NumAttributes   = prog.NumAttributes;
+   program->Base.NumAddressRegs  = prog.NumAddressRegs;
+   program->Base.NumNativeInstructions = prog.NumNativeInstructions;
+   program->Base.NumNativeTemporaries = prog.NumNativeTemporaries;
+   program->Base.NumNativeParameters = prog.NumNativeParameters;
+   program->Base.NumNativeAttributes = prog.NumNativeAttributes;
+   program->Base.NumNativeAddressRegs = prog.NumNativeAddressRegs;
+   program->Base.NumAluInstructions   = prog.NumAluInstructions;
+   program->Base.NumTexInstructions   = prog.NumTexInstructions;
+   program->Base.NumTexIndirections   = prog.NumTexIndirections;
+   program->Base.NumNativeAluInstructions = prog.NumAluInstructions;
+   program->Base.NumNativeTexInstructions = prog.NumTexInstructions;
+   program->Base.NumNativeTexIndirections = prog.NumTexIndirections;
+   program->Base.InputsRead      = prog.InputsRead;
+   program->Base.OutputsWritten  = prog.OutputsWritten;
+   for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) {
+      program->Base.TexturesUsed[i] = prog.TexturesUsed[i];
+      if (prog.TexturesUsed[i])
+         program->Base.SamplersUsed |= (1 << i);
+   }
+   program->Base.ShadowSamplers = prog.ShadowSamplers;
+   switch (state.option.Fog) {
+   case OPTION_FOG_EXP:    program->FogOption = GL_EXP;    break;
+   case OPTION_FOG_EXP2:   program->FogOption = GL_EXP2;   break;
+   case OPTION_FOG_LINEAR: program->FogOption = GL_LINEAR; break;
+   default:                program->FogOption = GL_NONE;   break;
+   }
+   program->OriginUpperLeft = state.option.OriginUpperLeft;
+   program->PixelCenterInteger = state.option.PixelCenterInteger;
+
+   program->UsesKill            = state.fragment.UsesKill;
+
+   if (program->FogOption)
+      program->Base.InputsRead |= FRAG_BIT_FOGC;
+
+   if (program->Base.Instructions)
+      free(program->Base.Instructions);
+   program->Base.Instructions = prog.Instructions;
+
+   if (program->Base.Parameters)
+      _mesa_free_parameter_list(program->Base.Parameters);
+   program->Base.Parameters    = prog.Parameters;
+
+   /* Append fog instructions now if the program has "OPTION ARB_fog_exp"
+    * or similar.  We used to leave this up to drivers, but it appears
+    * there's no hardware that wants to do fog in a discrete stage separate
+    * from the fragment shader.
+    */
+   if (program->FogOption != GL_NONE) {
+      _mesa_append_fog_code(ctx, program);
+      program->FogOption = GL_NONE;
+   }
+
+#if DEBUG_FP
+   printf("____________Fragment program %u ________\n", program->Base.Id);
+   _mesa_print_program(&program->Base);
+#endif
+}
+
+
+
+/**
+ * Parse the vertex program string.  If success, update the given
+ * vertex_program object with the new program.  Else, leave the vertex_program
+ * object unchanged.
+ */
+void
+_mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target,
+                              const GLvoid *str, GLsizei len,
+                              struct gl_vertex_program *program)
+{
+   struct gl_program prog;
+   struct asm_parser_state state;
+
+   ASSERT(target == GL_VERTEX_PROGRAM_ARB);
+
+   memset(&prog, 0, sizeof(prog));
+   memset(&state, 0, sizeof(state));
+   state.prog = &prog;
+
+   if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len,
+                               &state)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramString(bad program)");
+      return;
+   }
+
+   if (program->Base.String != NULL)
+      free(program->Base.String);
+
+   /* Copy the relevant contents of the arb_program struct into the 
+    * vertex_program struct.
+    */
+   program->Base.String          = prog.String;
+   program->Base.NumInstructions = prog.NumInstructions;
+   program->Base.NumTemporaries  = prog.NumTemporaries;
+   program->Base.NumParameters   = prog.NumParameters;
+   program->Base.NumAttributes   = prog.NumAttributes;
+   program->Base.NumAddressRegs  = prog.NumAddressRegs;
+   program->Base.NumNativeInstructions = prog.NumNativeInstructions;
+   program->Base.NumNativeTemporaries = prog.NumNativeTemporaries;
+   program->Base.NumNativeParameters = prog.NumNativeParameters;
+   program->Base.NumNativeAttributes = prog.NumNativeAttributes;
+   program->Base.NumNativeAddressRegs = prog.NumNativeAddressRegs;
+   program->Base.InputsRead     = prog.InputsRead;
+   program->Base.OutputsWritten = prog.OutputsWritten;
+   program->IsPositionInvariant = (state.option.PositionInvariant)
+      ? GL_TRUE : GL_FALSE;
+
+   if (program->Base.Instructions)
+      free(program->Base.Instructions);
+   program->Base.Instructions = prog.Instructions;
+
+   if (program->Base.Parameters)
+      _mesa_free_parameter_list(program->Base.Parameters);
+   program->Base.Parameters = prog.Parameters; 
+
+#if DEBUG_VP
+   printf("____________Vertex program %u __________\n", program->Base.Id);
+   _mesa_print_program(&program->Base);
+#endif
+}
diff --git a/src/mesa/program/arbprogparse.h b/src/mesa/program/arbprogparse.h
new file mode 100644 (file)
index 0000000..980d39f
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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 ARBPROGPARSE_H
+#define ARBPROGPARSE_H
+
+#include "main/mtypes.h"
+
+extern void
+_mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target,
+                              const GLvoid *str, GLsizei len,
+                              struct gl_vertex_program *program);
+
+extern void
+_mesa_parse_arb_fragment_program(GLcontext *ctx, GLenum target,
+                                 const GLvoid *str, GLsizei len,
+                                 struct gl_fragment_program *program);
+
+#endif
diff --git a/src/mesa/program/descrip.mms b/src/mesa/program/descrip.mms
new file mode 100644 (file)
index 0000000..5973002
--- /dev/null
@@ -0,0 +1,93 @@
+# Makefile for core library for VMS
+# contributed by Jouk Jansen  joukj@hrem.nano.tudelft.nl
+# Last revision : 29 September 2008
+.first
+       define gl [---.include.gl]
+       define math [-.math]
+       define swrast [-.swrast]
+       define array_cache [-.array_cache]
+       define glapi [-.glapi]
+       define main [-.main]
+       define shader [-.shader]
+
+.include [---]mms-config.
+
+##### MACROS #####
+
+VPATH = RCS
+
+INCDIR = [---.include],[-.main],[-.glapi],[.slang]
+LIBDIR = [---.lib]
+CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1,"__extension__=")/name=(as_is,short)/float=ieee/ieee=denorm
+
+SOURCES = \
+       atifragshader.c \
+       arbprogparse.c \
+       arbprogram.c \
+       nvfragparse.c \
+       nvprogram.c \
+       nvvertparse.c \
+       program.c \
+       programopt.c \
+       prog_debug.c \
+       prog_execute.c \
+       prog_instruction.c \
+       prog_parameter.c \
+       prog_print.c \
+       prog_cache.c \
+       prog_statevars.c \
+       shader_api.c prog_uniform.c
+
+OBJECTS = \
+       atifragshader.obj,\
+       arbprogparse.obj,\
+       arbprogram.obj,\
+       nvfragparse.obj,\
+       nvprogram.obj,\
+       nvvertparse.obj,\
+       program.obj,\
+       programopt.obj,\
+       prog_debug.obj,\
+       prog_execute.obj,\
+       prog_instruction.obj,\
+       prog_parameter.obj,\
+       prog_print.obj,\
+       prog_statevars.obj,\
+       shader_api.obj,prog_uniform.obj,prog_cache.obj
+
+##### RULES #####
+
+VERSION=Mesa V3.4
+
+##### TARGETS #####
+all : 
+       $(MMS)$(MMSQUALIFIERS) $(LIBDIR)$(GL_LIB)
+       set def [.slang]
+       $(MMS)$(MMSQUALIFIERS)
+       set def [-]
+
+# Make the library
+$(LIBDIR)$(GL_LIB) : $(OBJECTS)
+  @ library $(LIBDIR)$(GL_LIB) $(OBJECTS)
+
+clean :
+       purge
+       delete *.obj;*
+
+atifragshader.obj : atifragshader.c
+arbprogparse.obj : arbprogparse.c
+arbprogram.obj : arbprogram.c
+nvfragparse.obj : nvfragparse.c
+nvprogram.obj : nvprogram.c
+nvvertparse.obj : nvvertparse.c
+program.obj : program.c
+programopt. obj : programopt.c
+prog_debug.obj : prog_debug.c
+prog_execute.obj : prog_execute.c
+prog_instruction.obj : prog_instruction.c
+prog_parameter.obj : prog_parameter.c
+prog_print.obj : prog_print.c
+prog_statevars.obj : prog_statevars.c
+shader_api.obj : shader_api.c
+prog_uniform.obj : prog_uniform.c
+prog_cache.obj : prog_cache.c
diff --git a/src/mesa/program/hash_table.c b/src/mesa/program/hash_table.c
new file mode 100644 (file)
index 0000000..f7ef366
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Copyright Â© 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION 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 hash_table.c
+ * \brief Implementation of a generic, opaque hash table data type.
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+#include "main/imports.h"
+#include "main/simple_list.h"
+#include "hash_table.h"
+
+struct node {
+   struct node *next;
+   struct node *prev;
+};
+
+struct hash_table {
+    hash_func_t    hash;
+    hash_compare_func_t  compare;
+
+    unsigned num_buckets;
+    struct node buckets[1];
+};
+
+
+struct hash_node {
+    struct node link;
+    const void *key;
+    void *data;
+};
+
+
+struct hash_table *
+hash_table_ctor(unsigned num_buckets, hash_func_t hash,
+                hash_compare_func_t compare)
+{
+    struct hash_table *ht;
+    unsigned i;
+
+
+    if (num_buckets < 16) {
+        num_buckets = 16;
+    }
+
+    ht = malloc(sizeof(*ht) + ((num_buckets - 1) 
+                                    * sizeof(ht->buckets[0])));
+    if (ht != NULL) {
+        ht->hash = hash;
+        ht->compare = compare;
+        ht->num_buckets = num_buckets;
+
+        for (i = 0; i < num_buckets; i++) {
+            make_empty_list(& ht->buckets[i]);
+        }
+    }
+
+    return ht;
+}
+
+
+void
+hash_table_dtor(struct hash_table *ht)
+{
+   hash_table_clear(ht);
+   free(ht);
+}
+
+
+void
+hash_table_clear(struct hash_table *ht)
+{
+   struct node *node;
+   struct node *temp;
+   unsigned i;
+
+
+   for (i = 0; i < ht->num_buckets; i++) {
+      foreach_s(node, temp, & ht->buckets[i]) {
+        remove_from_list(node);
+        free(node);
+      }
+
+      assert(is_empty_list(& ht->buckets[i]));
+   }
+}
+
+
+void *
+hash_table_find(struct hash_table *ht, const void *key)
+{
+    const unsigned hash_value = (*ht->hash)(key);
+    const unsigned bucket = hash_value % ht->num_buckets;
+    struct node *node;
+
+    foreach(node, & ht->buckets[bucket]) {
+       struct hash_node *hn = (struct hash_node *) node;
+
+       if ((*ht->compare)(hn->key, key) == 0) {
+         return hn->data;
+       }
+    }
+
+    return NULL;
+}
+
+
+void
+hash_table_insert(struct hash_table *ht, void *data, const void *key)
+{
+    const unsigned hash_value = (*ht->hash)(key);
+    const unsigned bucket = hash_value % ht->num_buckets;
+    struct hash_node *node;
+
+    node = calloc(1, sizeof(*node));
+
+    node->data = data;
+    node->key = key;
+
+    insert_at_head(& ht->buckets[bucket], & node->link);
+}
+
+void
+hash_table_remove(struct hash_table *ht, const void *key)
+{
+    const unsigned hash_value = (*ht->hash)(key);
+    const unsigned bucket = hash_value % ht->num_buckets;
+    struct node *node;
+
+    foreach(node, & ht->buckets[bucket]) {
+       struct hash_node *hn = (struct hash_node *) node;
+
+       if ((*ht->compare)(hn->key, key) == 0) {
+         remove_from_list(node);
+         free(node);
+         return;
+       }
+    }
+}
+
+unsigned
+hash_table_string_hash(const void *key)
+{
+    const char *str = (const char *) key;
+    unsigned hash = 5381;
+
+
+    while (*str != '\0') {
+        hash = (hash * 33) + *str;
+        str++;
+    }
+
+    return hash;
+}
+
+
+unsigned
+hash_table_pointer_hash(const void *key)
+{
+   return (unsigned)((uintptr_t) key / sizeof(void *));
+}
+
+
+int
+hash_table_pointer_compare(const void *key1, const void *key2)
+{
+   return key1 == key2 ? 0 : 1;
+}
diff --git a/src/mesa/program/hash_table.h b/src/mesa/program/hash_table.h
new file mode 100644 (file)
index 0000000..228ab94
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright Â© 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION 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 hash_table.h
+ * \brief Implementation of a generic, opaque hash table data type.
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+#ifndef HASH_TABLE_H
+#define HASH_TABLE_H
+
+#include <string.h>
+
+struct hash_table;
+
+typedef unsigned (*hash_func_t)(const void *key);
+typedef int (*hash_compare_func_t)(const void *key1, const void *key2);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Hash table constructor
+ *
+ * Creates a hash table with the specified number of buckets.  The supplied
+ * \c hash and \c compare routines are used when adding elements to the table
+ * and when searching for elements in the table.
+ *
+ * \param num_buckets  Number of buckets (bins) in the hash table.
+ * \param hash         Function used to compute hash value of input keys.
+ * \param compare      Function used to compare keys.
+ */
+extern struct hash_table *hash_table_ctor(unsigned num_buckets,
+    hash_func_t hash, hash_compare_func_t compare);
+
+
+/**
+ * Release all memory associated with a hash table
+ *
+ * \warning
+ * This function cannot release memory occupied either by keys or data.
+ */
+extern void hash_table_dtor(struct hash_table *ht);
+
+
+/**
+ * Flush all entries from a hash table
+ *
+ * \param ht  Table to be cleared of its entries.
+ */
+extern void hash_table_clear(struct hash_table *ht);
+
+
+/**
+ * Search a hash table for a specific element
+ *
+ * \param ht   Table to be searched
+ * \param key  Key of the desired element
+ *
+ * \return
+ * The \c data value supplied to \c hash_table_insert when the element with
+ * the matching key was added.  If no matching key exists in the table,
+ * \c NULL is returned.
+ */
+extern void *hash_table_find(struct hash_table *ht, const void *key);
+
+
+/**
+ * Add an element to a hash table
+ */
+extern void hash_table_insert(struct hash_table *ht, void *data,
+    const void *key);
+
+/**
+ * Remove a specific element from a hash table.
+ */
+extern void hash_table_remove(struct hash_table *ht, const void *key);
+
+/**
+ * Compute hash value of a string
+ *
+ * Computes the hash value of a string using the DJB2 algorithm developed by
+ * Professor Daniel J. Bernstein.  It was published on comp.lang.c once upon
+ * a time.  I was unable to find the original posting in the archives.
+ *
+ * \param key  Pointer to a NUL terminated string to be hashed.
+ *
+ * \sa hash_table_string_compare
+ */
+extern unsigned hash_table_string_hash(const void *key);
+
+
+/**
+ * Compare two strings used as keys
+ *
+ * This is just a macro wrapper around \c strcmp.
+ *
+ * \sa hash_table_string_hash
+ */
+#define hash_table_string_compare ((hash_compare_func_t) strcmp)
+
+
+/**
+ * Compute hash value of a pointer
+ *
+ * \param key  Pointer to be used as a hash key
+ *
+ * \note
+ * The memory pointed to by \c key is \b never accessed.  The value of \c key
+ * itself is used as the hash key
+ *
+ * \sa hash_table_pointer_compare
+ */
+unsigned
+hash_table_pointer_hash(const void *key);
+
+
+/**
+ * Compare two pointers used as keys
+ *
+ * \sa hash_table_pointer_hash
+ */
+int
+hash_table_pointer_compare(const void *key1, const void *key2);
+
+#ifdef __cplusplus
+};
+#endif
+#endif /* HASH_TABLE_H */
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
new file mode 100644 (file)
index 0000000..1903b8f
--- /dev/null
@@ -0,0 +1,2309 @@
+/*
+ * Copyright (C) 2005-2007  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2008  VMware, Inc.   All Rights Reserved.
+ * Copyright Â© 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION 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 ir_to_mesa.cpp
+ *
+ * Translates the IR to ARB_fragment_program text if possible,
+ * printing the result
+ */
+
+#include <stdio.h>
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_print_visitor.h"
+#include "ir_expression_flattening.h"
+#include "glsl_types.h"
+#include "glsl_parser_extras.h"
+#include "../glsl/program.h"
+#include "ir_optimization.h"
+#include "ast.h"
+
+extern "C" {
+#include "main/mtypes.h"
+#include "main/shaderobj.h"
+#include "main/uniforms.h"
+#include "program/prog_instruction.h"
+#include "program/prog_optimize.h"
+#include "program/prog_print.h"
+#include "program/program.h"
+#include "program/prog_uniform.h"
+#include "program/prog_parameter.h"
+}
+
+/**
+ * This struct is a corresponding struct to Mesa prog_src_register, with
+ * wider fields.
+ */
+typedef struct ir_to_mesa_src_reg {
+   int file; /**< PROGRAM_* from Mesa */
+   int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
+   GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
+   int negate; /**< NEGATE_XYZW mask from mesa */
+   /** Register index should be offset by the integer in this reg. */
+   ir_to_mesa_src_reg *reladdr;
+} ir_to_mesa_src_reg;
+
+typedef struct ir_to_mesa_dst_reg {
+   int file; /**< PROGRAM_* from Mesa */
+   int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
+   int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
+   GLuint cond_mask:4;
+   /** Register index should be offset by the integer in this reg. */
+   ir_to_mesa_src_reg *reladdr;
+} ir_to_mesa_dst_reg;
+
+extern ir_to_mesa_src_reg ir_to_mesa_undef;
+
+class ir_to_mesa_instruction : public exec_node {
+public:
+   enum prog_opcode op;
+   ir_to_mesa_dst_reg dst_reg;
+   ir_to_mesa_src_reg src_reg[3];
+   /** Pointer to the ir source this tree came from for debugging */
+   ir_instruction *ir;
+   GLboolean cond_update;
+   int sampler; /**< sampler index */
+   int tex_target; /**< One of TEXTURE_*_INDEX */
+   GLboolean tex_shadow;
+
+   class function_entry *function; /* Set on OPCODE_CAL or OPCODE_BGNSUB */
+};
+
+class variable_storage : public exec_node {
+public:
+   variable_storage(ir_variable *var, int file, int index)
+      : file(file), index(index), var(var)
+   {
+      /* empty */
+   }
+
+   int file;
+   int index;
+   ir_variable *var; /* variable that maps to this, if any */
+};
+
+class function_entry : public exec_node {
+public:
+   ir_function_signature *sig;
+
+   /**
+    * identifier of this function signature used by the program.
+    *
+    * At the point that Mesa instructions for function calls are
+    * generated, we don't know the address of the first instruction of
+    * the function body.  So we make the BranchTarget that is called a
+    * small integer and rewrite them during set_branchtargets().
+    */
+   int sig_id;
+
+   /**
+    * Pointer to first instruction of the function body.
+    *
+    * Set during function body emits after main() is processed.
+    */
+   ir_to_mesa_instruction *bgn_inst;
+
+   /**
+    * Index of the first instruction of the function body in actual
+    * Mesa IR.
+    *
+    * Set after convertion from ir_to_mesa_instruction to prog_instruction.
+    */
+   int inst;
+
+   /** Storage for the return value. */
+   ir_to_mesa_src_reg return_reg;
+};
+
+class ir_to_mesa_visitor : public ir_visitor {
+public:
+   ir_to_mesa_visitor();
+
+   function_entry *current_function;
+
+   GLcontext *ctx;
+   struct gl_program *prog;
+
+   int next_temp;
+
+   variable_storage *find_variable_storage(ir_variable *var);
+
+   function_entry *get_function_signature(ir_function_signature *sig);
+
+   ir_to_mesa_src_reg get_temp(const glsl_type *type);
+   void reladdr_to_temp(ir_instruction *ir,
+                       ir_to_mesa_src_reg *reg, int *num_reladdr);
+
+   struct ir_to_mesa_src_reg src_reg_for_float(float val);
+
+   /**
+    * \name Visit methods
+    *
+    * As typical for the visitor pattern, there must be one \c visit method for
+    * each concrete subclass of \c ir_instruction.  Virtual base classes within
+    * the hierarchy should not have \c visit methods.
+    */
+   /*@{*/
+   virtual void visit(ir_variable *);
+   virtual void visit(ir_loop *);
+   virtual void visit(ir_loop_jump *);
+   virtual void visit(ir_function_signature *);
+   virtual void visit(ir_function *);
+   virtual void visit(ir_expression *);
+   virtual void visit(ir_swizzle *);
+   virtual void visit(ir_dereference_variable  *);
+   virtual void visit(ir_dereference_array *);
+   virtual void visit(ir_dereference_record *);
+   virtual void visit(ir_assignment *);
+   virtual void visit(ir_constant *);
+   virtual void visit(ir_call *);
+   virtual void visit(ir_return *);
+   virtual void visit(ir_discard *);
+   virtual void visit(ir_texture *);
+   virtual void visit(ir_if *);
+   /*@}*/
+
+   struct ir_to_mesa_src_reg result;
+
+   /** List of variable_storage */
+   exec_list variables;
+
+   /** List of function_entry */
+   exec_list function_signatures;
+   int next_signature_id;
+
+   /** List of ir_to_mesa_instruction */
+   exec_list instructions;
+
+   ir_to_mesa_instruction *ir_to_mesa_emit_op0(ir_instruction *ir,
+                                              enum prog_opcode op);
+
+   ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir,
+                                              enum prog_opcode op,
+                                              ir_to_mesa_dst_reg dst,
+                                              ir_to_mesa_src_reg src0);
+
+   ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir,
+                                              enum prog_opcode op,
+                                              ir_to_mesa_dst_reg dst,
+                                              ir_to_mesa_src_reg src0,
+                                              ir_to_mesa_src_reg src1);
+
+   ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir,
+                                              enum prog_opcode op,
+                                              ir_to_mesa_dst_reg dst,
+                                              ir_to_mesa_src_reg src0,
+                                              ir_to_mesa_src_reg src1,
+                                              ir_to_mesa_src_reg src2);
+
+   void ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
+                                  enum prog_opcode op,
+                                  ir_to_mesa_dst_reg dst,
+                                  ir_to_mesa_src_reg src0);
+
+   void ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
+                                  enum prog_opcode op,
+                                  ir_to_mesa_dst_reg dst,
+                                  ir_to_mesa_src_reg src0,
+                                  ir_to_mesa_src_reg src1);
+
+   GLboolean try_emit_mad(ir_expression *ir,
+                         int mul_operand);
+
+   int *sampler_map;
+   int sampler_map_size;
+
+   void map_sampler(int location, int sampler);
+   int get_sampler_number(int location);
+
+   void *mem_ctx;
+};
+
+ir_to_mesa_src_reg ir_to_mesa_undef = {
+   PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, NEGATE_NONE, NULL,
+};
+
+ir_to_mesa_dst_reg ir_to_mesa_undef_dst = {
+   PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, COND_TR, NULL,
+};
+
+ir_to_mesa_dst_reg ir_to_mesa_address_reg = {
+   PROGRAM_ADDRESS, 0, WRITEMASK_X, COND_TR, NULL
+};
+
+static int swizzle_for_size(int size)
+{
+   int size_swizzles[4] = {
+      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
+      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
+      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
+      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
+   };
+
+   return size_swizzles[size - 1];
+}
+
+ir_to_mesa_instruction *
+ir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir,
+                                       enum prog_opcode op,
+                                       ir_to_mesa_dst_reg dst,
+                                       ir_to_mesa_src_reg src0,
+                                       ir_to_mesa_src_reg src1,
+                                       ir_to_mesa_src_reg src2)
+{
+   ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction();
+   int num_reladdr = 0;
+
+   /* If we have to do relative addressing, we want to load the ARL
+    * reg directly for one of the regs, and preload the other reladdr
+    * sources into temps.
+    */
+   num_reladdr += dst.reladdr != NULL;
+   num_reladdr += src0.reladdr != NULL;
+   num_reladdr += src1.reladdr != NULL;
+   num_reladdr += src2.reladdr != NULL;
+
+   reladdr_to_temp(ir, &src2, &num_reladdr);
+   reladdr_to_temp(ir, &src1, &num_reladdr);
+   reladdr_to_temp(ir, &src0, &num_reladdr);
+
+   if (dst.reladdr) {
+      ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg,
+                          *dst.reladdr);
+
+      num_reladdr--;
+   }
+   assert(num_reladdr == 0);
+
+   inst->op = op;
+   inst->dst_reg = dst;
+   inst->src_reg[0] = src0;
+   inst->src_reg[1] = src1;
+   inst->src_reg[2] = src2;
+   inst->ir = ir;
+
+   inst->function = NULL;
+
+   this->instructions.push_tail(inst);
+
+   return inst;
+}
+
+
+ir_to_mesa_instruction *
+ir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir,
+                                       enum prog_opcode op,
+                                       ir_to_mesa_dst_reg dst,
+                                       ir_to_mesa_src_reg src0,
+                                       ir_to_mesa_src_reg src1)
+{
+   return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef);
+}
+
+ir_to_mesa_instruction *
+ir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir,
+                                       enum prog_opcode op,
+                                       ir_to_mesa_dst_reg dst,
+                                       ir_to_mesa_src_reg src0)
+{
+   return ir_to_mesa_emit_op3(ir, op, dst,
+                             src0, ir_to_mesa_undef, ir_to_mesa_undef);
+}
+
+ir_to_mesa_instruction *
+ir_to_mesa_visitor::ir_to_mesa_emit_op0(ir_instruction *ir,
+                                       enum prog_opcode op)
+{
+   return ir_to_mesa_emit_op3(ir, op, ir_to_mesa_undef_dst,
+                             ir_to_mesa_undef,
+                             ir_to_mesa_undef,
+                             ir_to_mesa_undef);
+}
+
+void
+ir_to_mesa_visitor::map_sampler(int location, int sampler)
+{
+   if (this->sampler_map_size <= location) {
+      this->sampler_map = talloc_realloc(this->mem_ctx, this->sampler_map,
+                                        int, location + 1);
+      this->sampler_map_size = location + 1;
+   }
+
+   this->sampler_map[location] = sampler;
+}
+
+int
+ir_to_mesa_visitor::get_sampler_number(int location)
+{
+   assert(location < this->sampler_map_size);
+   return this->sampler_map[location];
+}
+
+inline ir_to_mesa_dst_reg
+ir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg)
+{
+   ir_to_mesa_dst_reg dst_reg;
+
+   dst_reg.file = reg.file;
+   dst_reg.index = reg.index;
+   dst_reg.writemask = WRITEMASK_XYZW;
+   dst_reg.cond_mask = COND_TR;
+   dst_reg.reladdr = reg.reladdr;
+
+   return dst_reg;
+}
+
+inline ir_to_mesa_src_reg
+ir_to_mesa_src_reg_from_dst(ir_to_mesa_dst_reg reg)
+{
+   ir_to_mesa_src_reg src_reg;
+
+   src_reg.file = reg.file;
+   src_reg.index = reg.index;
+   src_reg.swizzle = SWIZZLE_XYZW;
+   src_reg.negate = 0;
+   src_reg.reladdr = reg.reladdr;
+
+   return src_reg;
+}
+
+/**
+ * Emits Mesa scalar opcodes to produce unique answers across channels.
+ *
+ * Some Mesa opcodes are scalar-only, like ARB_fp/vp.  The src X
+ * channel determines the result across all channels.  So to do a vec4
+ * of this operation, we want to emit a scalar per source channel used
+ * to produce dest channels.
+ */
+void
+ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
+                                              enum prog_opcode op,
+                                              ir_to_mesa_dst_reg dst,
+                                              ir_to_mesa_src_reg orig_src0,
+                                              ir_to_mesa_src_reg orig_src1)
+{
+   int i, j;
+   int done_mask = ~dst.writemask;
+
+   /* Mesa RCP is a scalar operation splatting results to all channels,
+    * like ARB_fp/vp.  So emit as many RCPs as necessary to cover our
+    * dst channels.
+    */
+   for (i = 0; i < 4; i++) {
+      GLuint this_mask = (1 << i);
+      ir_to_mesa_instruction *inst;
+      ir_to_mesa_src_reg src0 = orig_src0;
+      ir_to_mesa_src_reg src1 = orig_src1;
+
+      if (done_mask & this_mask)
+        continue;
+
+      GLuint src0_swiz = GET_SWZ(src0.swizzle, i);
+      GLuint src1_swiz = GET_SWZ(src1.swizzle, i);
+      for (j = i + 1; j < 4; j++) {
+        if (!(done_mask & (1 << j)) &&
+            GET_SWZ(src0.swizzle, j) == src0_swiz &&
+            GET_SWZ(src1.swizzle, j) == src1_swiz) {
+           this_mask |= (1 << j);
+        }
+      }
+      src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
+                                  src0_swiz, src0_swiz);
+      src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz,
+                                 src1_swiz, src1_swiz);
+
+      inst = ir_to_mesa_emit_op2(ir, op,
+                                dst,
+                                src0,
+                                src1);
+      inst->dst_reg.writemask = this_mask;
+      done_mask |= this_mask;
+   }
+}
+
+void
+ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
+                                              enum prog_opcode op,
+                                              ir_to_mesa_dst_reg dst,
+                                              ir_to_mesa_src_reg src0)
+{
+   ir_to_mesa_src_reg undef = ir_to_mesa_undef;
+
+   undef.swizzle = SWIZZLE_XXXX;
+
+   ir_to_mesa_emit_scalar_op2(ir, op, dst, src0, undef);
+}
+
+struct ir_to_mesa_src_reg
+ir_to_mesa_visitor::src_reg_for_float(float val)
+{
+   ir_to_mesa_src_reg src_reg;
+
+   src_reg.file = PROGRAM_CONSTANT;
+   src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
+                                             &val, 1, &src_reg.swizzle);
+   src_reg.reladdr = NULL;
+   src_reg.negate = 0;
+
+   return src_reg;
+}
+
+static int
+type_size(const struct glsl_type *type)
+{
+   unsigned int i;
+   int size;
+
+   switch (type->base_type) {
+   case GLSL_TYPE_UINT:
+   case GLSL_TYPE_INT:
+   case GLSL_TYPE_FLOAT:
+   case GLSL_TYPE_BOOL:
+      if (type->is_matrix()) {
+        return type->matrix_columns;
+      } else {
+        /* Regardless of size of vector, it gets a vec4. This is bad
+         * packing for things like floats, but otherwise arrays become a
+         * mess.  Hopefully a later pass over the code can pack scalars
+         * down if appropriate.
+         */
+        return 1;
+      }
+   case GLSL_TYPE_ARRAY:
+      return type_size(type->fields.array) * type->length;
+   case GLSL_TYPE_STRUCT:
+      size = 0;
+      for (i = 0; i < type->length; i++) {
+        size += type_size(type->fields.structure[i].type);
+      }
+      return size;
+   default:
+      assert(0);
+   }
+}
+
+/**
+ * In the initial pass of codegen, we assign temporary numbers to
+ * intermediate results.  (not SSA -- variable assignments will reuse
+ * storage).  Actual register allocation for the Mesa VM occurs in a
+ * pass over the Mesa IR later.
+ */
+ir_to_mesa_src_reg
+ir_to_mesa_visitor::get_temp(const glsl_type *type)
+{
+   ir_to_mesa_src_reg src_reg;
+   int swizzle[4];
+   int i;
+
+   assert(!type->is_array());
+
+   src_reg.file = PROGRAM_TEMPORARY;
+   src_reg.index = next_temp;
+   src_reg.reladdr = NULL;
+   next_temp += type_size(type);
+
+   for (i = 0; i < type->vector_elements; i++)
+      swizzle[i] = i;
+   for (; i < 4; i++)
+      swizzle[i] = type->vector_elements - 1;
+   src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
+                                  swizzle[2], swizzle[3]);
+   src_reg.negate = 0;
+
+   return src_reg;
+}
+
+variable_storage *
+ir_to_mesa_visitor::find_variable_storage(ir_variable *var)
+{
+   
+   variable_storage *entry;
+
+   foreach_iter(exec_list_iterator, iter, this->variables) {
+      entry = (variable_storage *)iter.get();
+
+      if (entry->var == var)
+        return entry;
+   }
+
+   return NULL;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_variable *ir)
+{
+   (void)ir;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_loop *ir)
+{
+   assert(!ir->from);
+   assert(!ir->to);
+   assert(!ir->increment);
+   assert(!ir->counter);
+
+   ir_to_mesa_emit_op0(NULL, OPCODE_BGNLOOP);
+   visit_exec_list(&ir->body_instructions, this);
+   ir_to_mesa_emit_op0(NULL, OPCODE_ENDLOOP);
+}
+
+void
+ir_to_mesa_visitor::visit(ir_loop_jump *ir)
+{
+   switch (ir->mode) {
+   case ir_loop_jump::jump_break:
+      ir_to_mesa_emit_op0(NULL, OPCODE_BRK);
+      break;
+   case ir_loop_jump::jump_continue:
+      ir_to_mesa_emit_op0(NULL, OPCODE_CONT);
+      break;
+   }
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_function_signature *ir)
+{
+   assert(0);
+   (void)ir;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_function *ir)
+{
+   /* Ignore function bodies other than main() -- we shouldn't see calls to
+    * them since they should all be inlined before we get to ir_to_mesa.
+    */
+   if (strcmp(ir->name, "main") == 0) {
+      const ir_function_signature *sig;
+      exec_list empty;
+
+      sig = ir->matching_signature(&empty);
+
+      assert(sig);
+
+      foreach_iter(exec_list_iterator, iter, sig->body) {
+        ir_instruction *ir = (ir_instruction *)iter.get();
+
+        ir->accept(this);
+      }
+   }
+}
+
+GLboolean
+ir_to_mesa_visitor::try_emit_mad(ir_expression *ir, int mul_operand)
+{
+   int nonmul_operand = 1 - mul_operand;
+   ir_to_mesa_src_reg a, b, c;
+
+   ir_expression *expr = ir->operands[mul_operand]->as_expression();
+   if (!expr || expr->operation != ir_binop_mul)
+      return false;
+
+   expr->operands[0]->accept(this);
+   a = this->result;
+   expr->operands[1]->accept(this);
+   b = this->result;
+   ir->operands[nonmul_operand]->accept(this);
+   c = this->result;
+
+   this->result = get_temp(ir->type);
+   ir_to_mesa_emit_op3(ir, OPCODE_MAD,
+                      ir_to_mesa_dst_reg_from_src(this->result), a, b, c);
+
+   return true;
+}
+
+void
+ir_to_mesa_visitor::reladdr_to_temp(ir_instruction *ir,
+                                   ir_to_mesa_src_reg *reg, int *num_reladdr)
+{
+   if (!reg->reladdr)
+      return;
+
+   ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, *reg->reladdr);
+
+   if (*num_reladdr != 1) {
+      ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type);
+
+      ir_to_mesa_emit_op1(ir, OPCODE_MOV,
+                         ir_to_mesa_dst_reg_from_src(temp), *reg);
+      *reg = temp;
+   }
+
+   (*num_reladdr)--;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_expression *ir)
+{
+   unsigned int operand;
+   struct ir_to_mesa_src_reg op[2];
+   struct ir_to_mesa_src_reg result_src;
+   struct ir_to_mesa_dst_reg result_dst;
+   const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1);
+   const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1);
+   const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1);
+
+   /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c)
+    */
+   if (ir->operation == ir_binop_add) {
+      if (try_emit_mad(ir, 1))
+        return;
+      if (try_emit_mad(ir, 0))
+        return;
+   }
+
+   for (operand = 0; operand < ir->get_num_operands(); operand++) {
+      this->result.file = PROGRAM_UNDEFINED;
+      ir->operands[operand]->accept(this);
+      if (this->result.file == PROGRAM_UNDEFINED) {
+        ir_print_visitor v;
+        printf("Failed to get tree for expression operand:\n");
+        ir->operands[operand]->accept(&v);
+        exit(1);
+      }
+      op[operand] = this->result;
+
+      /* Matrix expression operands should have been broken down to vector
+       * operations already.
+       */
+      assert(!ir->operands[operand]->type->is_matrix());
+   }
+
+   this->result.file = PROGRAM_UNDEFINED;
+
+   /* Storage for our result.  Ideally for an assignment we'd be using
+    * the actual storage for the result here, instead.
+    */
+   result_src = get_temp(ir->type);
+   /* convenience for the emit functions below. */
+   result_dst = ir_to_mesa_dst_reg_from_src(result_src);
+   /* Limit writes to the channels that will be used by result_src later.
+    * This does limit this temp's use as a temporary for multi-instruction
+    * sequences.
+    */
+   result_dst.writemask = (1 << ir->type->vector_elements) - 1;
+
+   switch (ir->operation) {
+   case ir_unop_logic_not:
+      ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst,
+                         op[0], src_reg_for_float(0.0));
+      break;
+   case ir_unop_neg:
+      op[0].negate = ~op[0].negate;
+      result_src = op[0];
+      break;
+   case ir_unop_abs:
+      ir_to_mesa_emit_op1(ir, OPCODE_ABS, result_dst, op[0]);
+      break;
+   case ir_unop_sign:
+      ir_to_mesa_emit_op1(ir, OPCODE_SSG, result_dst, op[0]);
+      break;
+   case ir_unop_rcp:
+      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[0]);
+      break;
+
+   case ir_unop_exp:
+      ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst,
+                                src_reg_for_float(M_E), op[0]);
+      break;
+   case ir_unop_exp2:
+      ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]);
+      break;
+   case ir_unop_log:
+      ir_to_mesa_emit_scalar_op1(ir, OPCODE_LOG, result_dst, op[0]);
+      break;
+   case ir_unop_log2:
+      ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]);
+      break;
+   case ir_unop_sin:
+      ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]);
+      break;
+   case ir_unop_cos:
+      ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]);
+      break;
+
+   case ir_unop_dFdx:
+      ir_to_mesa_emit_op1(ir, OPCODE_DDX, result_dst, op[0]);
+      break;
+   case ir_unop_dFdy:
+      ir_to_mesa_emit_op1(ir, OPCODE_DDY, result_dst, op[0]);
+      break;
+
+   case ir_binop_add:
+      ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]);
+      break;
+   case ir_binop_sub:
+      ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]);
+      break;
+
+   case ir_binop_mul:
+      ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]);
+      break;
+   case ir_binop_div:
+      assert(!"not reached: should be handled by ir_div_to_mul_rcp");
+   case ir_binop_mod:
+      assert(!"ir_binop_mod should have been converted to b * fract(a/b)");
+      break;
+
+   case ir_binop_less:
+      ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]);
+      break;
+   case ir_binop_greater:
+      ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]);
+      break;
+   case ir_binop_lequal:
+      ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]);
+      break;
+   case ir_binop_gequal:
+      ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]);
+      break;
+   case ir_binop_equal:
+      ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
+      break;
+   case ir_binop_logic_xor:
+   case ir_binop_nequal:
+      ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
+      break;
+
+   case ir_binop_logic_or:
+      /* This could be a saturated add and skip the SNE. */
+      ir_to_mesa_emit_op2(ir, OPCODE_ADD,
+                         result_dst,
+                         op[0], op[1]);
+
+      ir_to_mesa_emit_op2(ir, OPCODE_SNE,
+                         result_dst,
+                         result_src, src_reg_for_float(0.0));
+      break;
+
+   case ir_binop_logic_and:
+      /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */
+      ir_to_mesa_emit_op2(ir, OPCODE_MUL,
+                         result_dst,
+                         op[0], op[1]);
+      break;
+
+   case ir_binop_dot:
+      if (ir->operands[0]->type == vec4_type) {
+        assert(ir->operands[1]->type == vec4_type);
+        ir_to_mesa_emit_op2(ir, OPCODE_DP4,
+                            result_dst,
+                            op[0], op[1]);
+      } else if (ir->operands[0]->type == vec3_type) {
+        assert(ir->operands[1]->type == vec3_type);
+        ir_to_mesa_emit_op2(ir, OPCODE_DP3,
+                            result_dst,
+                            op[0], op[1]);
+      } else if (ir->operands[0]->type == vec2_type) {
+        assert(ir->operands[1]->type == vec2_type);
+        ir_to_mesa_emit_op2(ir, OPCODE_DP2,
+                            result_dst,
+                            op[0], op[1]);
+      }
+      break;
+
+   case ir_binop_cross:
+      ir_to_mesa_emit_op2(ir, OPCODE_XPD, result_dst, op[0], op[1]);
+      break;
+
+   case ir_unop_sqrt:
+      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
+      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, result_src);
+      /* For incoming channels < 0, set the result to 0. */
+      ir_to_mesa_emit_op3(ir, OPCODE_CMP, result_dst,
+                         op[0], src_reg_for_float(0.0), result_src);
+      break;
+   case ir_unop_rsq:
+      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
+      break;
+   case ir_unop_i2f:
+   case ir_unop_b2f:
+   case ir_unop_b2i:
+      /* Mesa IR lacks types, ints are stored as truncated floats. */
+      result_src = op[0];
+      break;
+   case ir_unop_f2i:
+      ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
+      break;
+   case ir_unop_f2b:
+   case ir_unop_i2b:
+      ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst,
+                         result_src, src_reg_for_float(0.0));
+      break;
+   case ir_unop_trunc:
+      ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
+      break;
+   case ir_unop_ceil:
+      op[0].negate = ~op[0].negate;
+      ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
+      result_src.negate = ~result_src.negate;
+      break;
+   case ir_unop_floor:
+      ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
+      break;
+   case ir_unop_fract:
+      ir_to_mesa_emit_op1(ir, OPCODE_FRC, result_dst, op[0]);
+      break;
+
+   case ir_binop_min:
+      ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]);
+      break;
+   case ir_binop_max:
+      ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]);
+      break;
+   case ir_binop_pow:
+      ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, op[0], op[1]);
+      break;
+
+   case ir_unop_bit_not:
+   case ir_unop_u2f:
+   case ir_binop_lshift:
+   case ir_binop_rshift:
+   case ir_binop_bit_and:
+   case ir_binop_bit_xor:
+   case ir_binop_bit_or:
+      assert(!"GLSL 1.30 features unsupported");
+      break;
+   }
+
+   this->result = result_src;
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_swizzle *ir)
+{
+   ir_to_mesa_src_reg src_reg;
+   int i;
+   int swizzle[4];
+
+   /* Note that this is only swizzles in expressions, not those on the left
+    * hand side of an assignment, which do write masking.  See ir_assignment
+    * for that.
+    */
+
+   ir->val->accept(this);
+   src_reg = this->result;
+   assert(src_reg.file != PROGRAM_UNDEFINED);
+
+   for (i = 0; i < 4; i++) {
+      if (i < ir->type->vector_elements) {
+        switch (i) {
+        case 0:
+           swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.x);
+           break;
+        case 1:
+           swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.y);
+           break;
+        case 2:
+           swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.z);
+           break;
+        case 3:
+           swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.w);
+           break;
+        }
+      } else {
+        /* If the type is smaller than a vec4, replicate the last
+         * channel out.
+         */
+        swizzle[i] = swizzle[ir->type->vector_elements - 1];
+      }
+   }
+
+   src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0],
+                                  swizzle[1],
+                                  swizzle[2],
+                                  swizzle[3]);
+
+   this->result = src_reg;
+}
+
+static int
+add_matrix_ref(struct gl_program *prog, int *tokens)
+{
+   int base_pos = -1;
+   int i;
+
+   /* Add a ref for each column.  It looks like the reason we do
+    * it this way is that _mesa_add_state_reference doesn't work
+    * for things that aren't vec4s, so the tokens[2]/tokens[3]
+    * range has to be equal.
+    */
+   for (i = 0; i < 4; i++) {
+      tokens[2] = i;
+      tokens[3] = i;
+      int pos = _mesa_add_state_reference(prog->Parameters,
+                                         (gl_state_index *)tokens);
+      if (base_pos == -1)
+        base_pos = pos;
+      else
+        assert(base_pos + i == pos);
+   }
+
+   return base_pos;
+}
+
+static variable_storage *
+get_builtin_matrix_ref(void *mem_ctx, struct gl_program *prog, ir_variable *var,
+                      ir_rvalue *array_index)
+{
+   /*
+    * NOTE: The ARB_vertex_program extension specified that matrices get
+    * loaded in registers in row-major order.  With GLSL, we want column-
+    * major order.  So, we need to transpose all matrices here...
+    */
+   static const struct {
+      const char *name;
+      int matrix;
+      int modifier;
+   } matrices[] = {
+      { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE },
+      { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS },
+      { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 },
+      { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
+
+      { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE },
+      { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS },
+      { "gl_ProjectionMatrixTranspose", STATE_PROJECTION_MATRIX, 0 },
+      { "gl_ProjectionMatrixInverseTranspose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE },
+
+      { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE },
+      { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS },
+      { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 },
+      { "gl_ModelViewProjectionMatrixInverseTranspose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE },
+
+      { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE },
+      { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS },
+      { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 },
+      { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE },
+
+      { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
+
+   };
+   unsigned int i;
+   variable_storage *entry;
+
+   /* C++ gets angry when we try to use an int as a gl_state_index, so we use
+    * ints for gl_state_index.  Make sure they're compatible.
+    */
+   assert(sizeof(gl_state_index) == sizeof(int));
+
+   for (i = 0; i < Elements(matrices); i++) {
+      if (strcmp(var->name, matrices[i].name) == 0) {
+        int tokens[STATE_LENGTH];
+        int base_pos = -1;
+
+        tokens[0] = matrices[i].matrix;
+        tokens[4] = matrices[i].modifier;
+        if (matrices[i].matrix == STATE_TEXTURE_MATRIX) {
+           ir_constant *index = array_index->constant_expression_value();
+           if (index) {
+              tokens[1] = index->value.i[0];
+              base_pos = add_matrix_ref(prog, tokens);
+           } else {
+              for (i = 0; i < var->type->length; i++) {
+                 tokens[1] = i;
+                 int pos = add_matrix_ref(prog, tokens);
+                 if (base_pos == -1)
+                    base_pos = pos;
+                 else
+                    assert(base_pos + (int)i * 4 == pos);
+              }
+           }
+        } else {
+           tokens[1] = 0; /* unused array index */
+           base_pos = add_matrix_ref(prog, tokens);
+        }
+        tokens[4] = matrices[i].modifier;
+
+        entry = new(mem_ctx) variable_storage(var,
+                                              PROGRAM_STATE_VAR,
+                                              base_pos);
+
+        return entry;
+      }
+   }
+
+   return NULL;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
+{
+   ir_to_mesa_src_reg src_reg;
+   variable_storage *entry = find_variable_storage(ir->var);
+   unsigned int loc;
+
+   if (!entry) {
+      switch (ir->var->mode) {
+      case ir_var_uniform:
+        entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, ir->var,
+                                       NULL);
+        if (entry)
+           break;
+
+        /* FINISHME: Fix up uniform name for arrays and things */
+        if (ir->var->type->base_type == GLSL_TYPE_SAMPLER) {
+           /* FINISHME: we whack the location of the var here, which
+            * is probably not expected.  But we need to communicate
+            * mesa's sampler number to the tex instruction.
+            */
+           int sampler = _mesa_add_sampler(this->prog->Parameters,
+                                           ir->var->name,
+                                           ir->var->type->gl_type);
+           map_sampler(ir->var->location, sampler);
+
+           entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_SAMPLER,
+                                                 sampler);
+           this->variables.push_tail(entry);
+           break;
+        }
+
+        assert(ir->var->type->gl_type != 0 &&
+               ir->var->type->gl_type != GL_INVALID_ENUM);
+        loc = _mesa_add_uniform(this->prog->Parameters,
+                                ir->var->name,
+                                type_size(ir->var->type) * 4,
+                                ir->var->type->gl_type,
+                                NULL);
+
+        /* Always mark the uniform used at this point.  If it isn't
+         * used, dead code elimination should have nuked the decl already.
+         */
+        this->prog->Parameters->Parameters[loc].Used = GL_TRUE;
+
+        entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_UNIFORM, loc);
+        this->variables.push_tail(entry);
+        break;
+      case ir_var_in:
+      case ir_var_out:
+      case ir_var_inout:
+        /* The linker assigns locations for varyings and attributes,
+         * including deprecated builtins (like gl_Color), user-assign
+         * generic attributes (glBindVertexLocation), and
+         * user-defined varyings.
+         *
+         * FINISHME: We would hit this path for function arguments.  Fix!
+         */
+        assert(ir->var->location != -1);
+        if (ir->var->mode == ir_var_in ||
+            ir->var->mode == ir_var_inout) {
+           entry = new(mem_ctx) variable_storage(ir->var,
+                                                 PROGRAM_INPUT,
+                                                 ir->var->location);
+
+           if (this->prog->Target == GL_VERTEX_PROGRAM_ARB &&
+               ir->var->location >= VERT_ATTRIB_GENERIC0) {
+              _mesa_add_attribute(prog->Attributes,
+                                  ir->var->name,
+                                  type_size(ir->var->type) * 4,
+                                  ir->var->type->gl_type,
+                                  ir->var->location - VERT_ATTRIB_GENERIC0);
+           }
+        } else {
+           entry = new(mem_ctx) variable_storage(ir->var,
+                                                 PROGRAM_OUTPUT,
+                                                 ir->var->location);
+        }
+
+        break;
+      case ir_var_auto:
+      case ir_var_temporary:
+        entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_TEMPORARY,
+                                              this->next_temp);
+        this->variables.push_tail(entry);
+
+        next_temp += type_size(ir->var->type);
+        break;
+      }
+
+      if (!entry) {
+        printf("Failed to make storage for %s\n", ir->var->name);
+        exit(1);
+      }
+   }
+
+   src_reg.file = entry->file;
+   src_reg.index = entry->index;
+   /* If the type is smaller than a vec4, replicate the last channel out. */
+   if (ir->type->is_scalar() || ir->type->is_vector())
+      src_reg.swizzle = swizzle_for_size(ir->var->type->vector_elements);
+   else
+      src_reg.swizzle = SWIZZLE_NOOP;
+   src_reg.reladdr = NULL;
+   src_reg.negate = 0;
+
+   this->result = src_reg;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_dereference_array *ir)
+{
+   ir_constant *index;
+   ir_to_mesa_src_reg src_reg;
+   ir_dereference_variable *deref_var = ir->array->as_dereference_variable();
+   int element_size = type_size(ir->type);
+
+   index = ir->array_index->constant_expression_value();
+
+   if (deref_var && strncmp(deref_var->var->name,
+                           "gl_TextureMatrix",
+                           strlen("gl_TextureMatrix")) == 0) {
+      ir_to_mesa_src_reg src_reg;
+      struct variable_storage *entry;
+
+      entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, deref_var->var,
+                                    ir->array_index);
+      assert(entry);
+
+      src_reg.file = entry->file;
+      src_reg.index = entry->index;
+      src_reg.swizzle = swizzle_for_size(ir->type->vector_elements);
+      src_reg.negate = 0;
+
+      if (index) {
+        src_reg.reladdr = NULL;
+      } else {
+        ir_to_mesa_src_reg index_reg = get_temp(glsl_type::float_type);
+
+        ir->array_index->accept(this);
+        ir_to_mesa_emit_op2(ir, OPCODE_MUL,
+                            ir_to_mesa_dst_reg_from_src(index_reg),
+                            this->result, src_reg_for_float(element_size));
+
+        src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg);
+        memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg));
+      }
+
+      this->result = src_reg;
+      return;
+   }
+
+   ir->array->accept(this);
+   src_reg = this->result;
+
+   if (index) {
+      src_reg.index += index->value.i[0] * element_size;
+   } else {
+      ir_to_mesa_src_reg array_base = this->result;
+      /* Variable index array dereference.  It eats the "vec4" of the
+       * base of the array and an index that offsets the Mesa register
+       * index.
+       */
+      ir->array_index->accept(this);
+
+      ir_to_mesa_src_reg index_reg;
+
+      if (element_size == 1) {
+        index_reg = this->result;
+      } else {
+        index_reg = get_temp(glsl_type::float_type);
+
+        ir_to_mesa_emit_op2(ir, OPCODE_MUL,
+                            ir_to_mesa_dst_reg_from_src(index_reg),
+                            this->result, src_reg_for_float(element_size));
+      }
+
+      src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg);
+      memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg));
+   }
+
+   /* If the type is smaller than a vec4, replicate the last channel out. */
+   if (ir->type->is_scalar() || ir->type->is_vector())
+      src_reg.swizzle = swizzle_for_size(ir->type->vector_elements);
+   else
+      src_reg.swizzle = SWIZZLE_NOOP;
+
+   this->result = src_reg;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_dereference_record *ir)
+{
+   unsigned int i;
+   const glsl_type *struct_type = ir->record->type;
+   int offset = 0;
+
+   ir->record->accept(this);
+
+   for (i = 0; i < struct_type->length; i++) {
+      if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
+        break;
+      offset += type_size(struct_type->fields.structure[i].type);
+   }
+   this->result.swizzle = swizzle_for_size(ir->type->vector_elements);
+   this->result.index += offset;
+}
+
+/**
+ * We want to be careful in assignment setup to hit the actual storage
+ * instead of potentially using a temporary like we might with the
+ * ir_dereference handler.
+ *
+ * Thanks to ir_swizzle_swizzle, and ir_vec_index_to_swizzle, we
+ * should only see potentially one variable array index of a vector,
+ * and one swizzle, before getting to actual vec4 storage.  So handle
+ * those, then go use ir_dereference to handle the rest.
+ */
+static struct ir_to_mesa_dst_reg
+get_assignment_lhs(ir_instruction *ir, ir_to_mesa_visitor *v,
+                  ir_to_mesa_src_reg *r)
+{
+   struct ir_to_mesa_dst_reg dst_reg;
+   ir_swizzle *swiz;
+
+   ir_dereference_array *deref_array = ir->as_dereference_array();
+   /* This should have been handled by ir_vec_index_to_cond_assign */
+   if (deref_array) {
+      assert(!deref_array->array->type->is_vector());
+   }
+
+   /* Use the rvalue deref handler for the most part.  We'll ignore
+    * swizzles in it and write swizzles using writemask, though.
+    */
+   ir->accept(v);
+   dst_reg = ir_to_mesa_dst_reg_from_src(v->result);
+
+   if ((swiz = ir->as_swizzle())) {
+      int swizzles[4] = {
+        swiz->mask.x,
+        swiz->mask.y,
+        swiz->mask.z,
+        swiz->mask.w
+      };
+      int new_r_swizzle[4];
+      int orig_r_swizzle = r->swizzle;
+      int i;
+
+      for (i = 0; i < 4; i++) {
+        new_r_swizzle[i] = GET_SWZ(orig_r_swizzle, 0);
+      }
+
+      dst_reg.writemask = 0;
+      for (i = 0; i < 4; i++) {
+        if (i < swiz->mask.num_components) {
+           dst_reg.writemask |= 1 << swizzles[i];
+           new_r_swizzle[swizzles[i]] = GET_SWZ(orig_r_swizzle, i);
+        }
+      }
+
+      r->swizzle = MAKE_SWIZZLE4(new_r_swizzle[0],
+                                new_r_swizzle[1],
+                                new_r_swizzle[2],
+                                new_r_swizzle[3]);
+   }
+
+   return dst_reg;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_assignment *ir)
+{
+   struct ir_to_mesa_dst_reg l;
+   struct ir_to_mesa_src_reg r;
+   int i;
+
+   assert(!ir->lhs->type->is_array());
+
+   ir->rhs->accept(this);
+   r = this->result;
+
+   l = get_assignment_lhs(ir->lhs, this, &r);
+
+   assert(l.file != PROGRAM_UNDEFINED);
+   assert(r.file != PROGRAM_UNDEFINED);
+
+   if (ir->condition) {
+      ir_to_mesa_src_reg condition;
+
+      ir->condition->accept(this);
+      condition = this->result;
+
+      /* We use the OPCODE_CMP (a < 0 ? b : c) for conditional moves,
+       * and the condition we produced is 0.0 or 1.0.  By flipping the
+       * sign, we can choose which value OPCODE_CMP produces without
+       * an extra computing the condition.
+       */
+      condition.negate = ~condition.negate;
+      for (i = 0; i < type_size(ir->lhs->type); i++) {
+        ir_to_mesa_emit_op3(ir, OPCODE_CMP, l,
+                            condition, r, ir_to_mesa_src_reg_from_dst(l));
+        l.index++;
+        r.index++;
+      }
+   } else {
+      for (i = 0; i < type_size(ir->lhs->type); i++) {
+        ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
+        l.index++;
+        r.index++;
+      }
+   }
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_constant *ir)
+{
+   ir_to_mesa_src_reg src_reg;
+   GLfloat stack_vals[4];
+   GLfloat *values = stack_vals;
+   unsigned int i;
+
+   if (ir->type->is_array()) {
+      ir->print();
+      printf("\n");
+      assert(!"FINISHME: array constants");
+   }
+
+   if (ir->type->is_matrix()) {
+      /* Unfortunately, 4 floats is all we can get into
+       * _mesa_add_unnamed_constant.  So, make a temp to store the
+       * matrix and move each constant value into it.  If we get
+       * lucky, copy propagation will eliminate the extra moves.
+       */
+      ir_to_mesa_src_reg mat = get_temp(glsl_type::vec4_type);
+      ir_to_mesa_dst_reg mat_column = ir_to_mesa_dst_reg_from_src(mat);
+
+      for (i = 0; i < ir->type->matrix_columns; i++) {
+        src_reg.file = PROGRAM_CONSTANT;
+
+        assert(ir->type->base_type == GLSL_TYPE_FLOAT);
+        values = &ir->value.f[i * ir->type->vector_elements];
+
+        src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
+                                                   values,
+                                                   ir->type->vector_elements,
+                                                   &src_reg.swizzle);
+        src_reg.reladdr = NULL;
+        src_reg.negate = 0;
+        ir_to_mesa_emit_op1(ir, OPCODE_MOV, mat_column, src_reg);
+
+        mat_column.index++;
+      }
+
+      this->result = mat;
+   }
+
+   src_reg.file = PROGRAM_CONSTANT;
+   switch (ir->type->base_type) {
+   case GLSL_TYPE_FLOAT:
+      values = &ir->value.f[0];
+      break;
+   case GLSL_TYPE_UINT:
+      for (i = 0; i < ir->type->vector_elements; i++) {
+        values[i] = ir->value.u[i];
+      }
+      break;
+   case GLSL_TYPE_INT:
+      for (i = 0; i < ir->type->vector_elements; i++) {
+        values[i] = ir->value.i[i];
+      }
+      break;
+   case GLSL_TYPE_BOOL:
+      for (i = 0; i < ir->type->vector_elements; i++) {
+        values[i] = ir->value.b[i];
+      }
+      break;
+   default:
+      assert(!"Non-float/uint/int/bool constant");
+   }
+
+   src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
+                                             values, ir->type->vector_elements,
+                                             &src_reg.swizzle);
+   src_reg.reladdr = NULL;
+   src_reg.negate = 0;
+
+   this->result = src_reg;
+}
+
+function_entry *
+ir_to_mesa_visitor::get_function_signature(ir_function_signature *sig)
+{
+   function_entry *entry;
+
+   foreach_iter(exec_list_iterator, iter, this->function_signatures) {
+      entry = (function_entry *)iter.get();
+
+      if (entry->sig == sig)
+        return entry;
+   }
+
+   entry = talloc(mem_ctx, function_entry);
+   entry->sig = sig;
+   entry->sig_id = this->next_signature_id++;
+   entry->bgn_inst = NULL;
+
+   /* Allocate storage for all the parameters. */
+   foreach_iter(exec_list_iterator, iter, sig->parameters) {
+      ir_variable *param = (ir_variable *)iter.get();
+      variable_storage *storage;
+
+      storage = find_variable_storage(param);
+      assert(!storage);
+
+      storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY,
+                                             this->next_temp);
+      this->variables.push_tail(storage);
+
+      this->next_temp += type_size(param->type);
+      break;
+   }
+
+   if (sig->return_type) {
+      entry->return_reg = get_temp(sig->return_type);
+   } else {
+      entry->return_reg = ir_to_mesa_undef;
+   }
+
+   this->function_signatures.push_tail(entry);
+   return entry;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_call *ir)
+{
+   ir_to_mesa_instruction *call_inst;
+   ir_function_signature *sig = ir->get_callee();
+   function_entry *entry = get_function_signature(sig);
+   int i;
+
+   /* Process in parameters. */
+   exec_list_iterator sig_iter = sig->parameters.iterator();
+   foreach_iter(exec_list_iterator, iter, *ir) {
+      ir_rvalue *param_rval = (ir_rvalue *)iter.get();
+      ir_variable *param = (ir_variable *)sig_iter.get();
+
+      if (param->mode == ir_var_in ||
+         param->mode == ir_var_inout) {
+        variable_storage *storage = find_variable_storage(param);
+        assert(storage);
+
+        param_rval->accept(this);
+        ir_to_mesa_src_reg r = this->result;
+
+        ir_to_mesa_dst_reg l;
+        l.file = storage->file;
+        l.index = storage->index;
+        l.reladdr = NULL;
+        l.writemask = WRITEMASK_XYZW;
+        l.cond_mask = COND_TR;
+
+        for (i = 0; i < type_size(param->type); i++) {
+           ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
+           l.index++;
+           r.index++;
+        }
+      }
+
+      sig_iter.next();
+   }
+   assert(!sig_iter.has_next());
+
+   /* Emit call instruction */
+   call_inst = ir_to_mesa_emit_op1(ir, OPCODE_CAL,
+                                  ir_to_mesa_undef_dst, ir_to_mesa_undef);
+   call_inst->function = entry;
+
+   /* Process out parameters. */
+   sig_iter = sig->parameters.iterator();
+   foreach_iter(exec_list_iterator, iter, *ir) {
+      ir_rvalue *param_rval = (ir_rvalue *)iter.get();
+      ir_variable *param = (ir_variable *)sig_iter.get();
+
+      if (param->mode == ir_var_out ||
+         param->mode == ir_var_inout) {
+        variable_storage *storage = find_variable_storage(param);
+        assert(storage);
+
+        ir_to_mesa_src_reg r;
+        r.file = storage->file;
+        r.index = storage->index;
+        r.reladdr = NULL;
+        r.swizzle = SWIZZLE_NOOP;
+        r.negate = 0;
+
+        param_rval->accept(this);
+        ir_to_mesa_dst_reg l = ir_to_mesa_dst_reg_from_src(this->result);
+
+        for (i = 0; i < type_size(param->type); i++) {
+           ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
+           l.index++;
+           r.index++;
+        }
+      }
+
+      sig_iter.next();
+   }
+   assert(!sig_iter.has_next());
+
+   /* Process return value. */
+   this->result = entry->return_reg;
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_texture *ir)
+{
+   ir_to_mesa_src_reg result_src, coord, lod_info = { 0 }, projector;
+   ir_to_mesa_dst_reg result_dst, coord_dst;
+   ir_to_mesa_instruction *inst = NULL;
+   prog_opcode opcode = OPCODE_NOP;
+
+   ir->coordinate->accept(this);
+
+   /* Put our coords in a temp.  We'll need to modify them for shadow,
+    * projection, or LOD, so the only case we'd use it as is is if
+    * we're doing plain old texturing.  Mesa IR optimization should
+    * handle cleaning up our mess in that case.
+    */
+   coord = get_temp(glsl_type::vec4_type);
+   coord_dst = ir_to_mesa_dst_reg_from_src(coord);
+   ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst,
+                      this->result);
+
+   if (ir->projector) {
+      ir->projector->accept(this);
+      projector = this->result;
+   }
+
+   /* Storage for our result.  Ideally for an assignment we'd be using
+    * the actual storage for the result here, instead.
+    */
+   result_src = get_temp(glsl_type::vec4_type);
+   result_dst = ir_to_mesa_dst_reg_from_src(result_src);
+
+   switch (ir->op) {
+   case ir_tex:
+      opcode = OPCODE_TEX;
+      break;
+   case ir_txb:
+      opcode = OPCODE_TXB;
+      ir->lod_info.bias->accept(this);
+      lod_info = this->result;
+      break;
+   case ir_txl:
+      opcode = OPCODE_TXL;
+      ir->lod_info.lod->accept(this);
+      lod_info = this->result;
+      break;
+   case ir_txd:
+   case ir_txf:
+      assert(!"GLSL 1.30 features unsupported");
+      break;
+   }
+
+   if (ir->projector) {
+      if (opcode == OPCODE_TEX) {
+        /* Slot the projector in as the last component of the coord. */
+        coord_dst.writemask = WRITEMASK_W;
+        ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, projector);
+        coord_dst.writemask = WRITEMASK_XYZW;
+        opcode = OPCODE_TXP;
+      } else {
+        ir_to_mesa_src_reg coord_w = coord;
+        coord_w.swizzle = SWIZZLE_WWWW;
+
+        /* For the other TEX opcodes there's no projective version
+         * since the last slot is taken up by lod info.  Do the
+         * projective divide now.
+         */
+        coord_dst.writemask = WRITEMASK_W;
+        ir_to_mesa_emit_op1(ir, OPCODE_RCP, coord_dst, projector);
+
+        coord_dst.writemask = WRITEMASK_XYZ;
+        ir_to_mesa_emit_op2(ir, OPCODE_MUL, coord_dst, coord, coord_w);
+
+        coord_dst.writemask = WRITEMASK_XYZW;
+        coord.swizzle = SWIZZLE_XYZW;
+      }
+   }
+
+   if (ir->shadow_comparitor) {
+      /* Slot the shadow value in as the second to last component of the
+       * coord.
+       */
+      ir->shadow_comparitor->accept(this);
+      coord_dst.writemask = WRITEMASK_Z;
+      ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, this->result);
+      coord_dst.writemask = WRITEMASK_XYZW;
+   }
+
+   if (opcode == OPCODE_TXL || opcode == OPCODE_TXB) {
+      /* Mesa IR stores lod or lod bias in the last channel of the coords. */
+      coord_dst.writemask = WRITEMASK_W;
+      ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, lod_info);
+      coord_dst.writemask = WRITEMASK_XYZW;
+   }
+
+   inst = ir_to_mesa_emit_op1(ir, opcode, result_dst, coord);
+
+   if (ir->shadow_comparitor)
+      inst->tex_shadow = GL_TRUE;
+
+   ir_dereference_variable *sampler = ir->sampler->as_dereference_variable();
+   assert(sampler); /* FINISHME: sampler arrays */
+   /* generate the mapping, remove when we generate storage at
+    * declaration time
+    */
+   sampler->accept(this);
+
+   inst->sampler = get_sampler_number(sampler->var->location);
+
+   switch (sampler->type->sampler_dimensionality) {
+   case GLSL_SAMPLER_DIM_1D:
+      inst->tex_target = TEXTURE_1D_INDEX;
+      break;
+   case GLSL_SAMPLER_DIM_2D:
+      inst->tex_target = TEXTURE_2D_INDEX;
+      break;
+   case GLSL_SAMPLER_DIM_3D:
+      inst->tex_target = TEXTURE_3D_INDEX;
+      break;
+   case GLSL_SAMPLER_DIM_CUBE:
+      inst->tex_target = TEXTURE_CUBE_INDEX;
+      break;
+   default:
+      assert(!"FINISHME: other texture targets");
+   }
+
+   this->result = result_src;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_return *ir)
+{
+   assert(current_function);
+
+   if (ir->get_value()) {
+      ir_to_mesa_dst_reg l;
+      int i;
+
+      ir->get_value()->accept(this);
+      ir_to_mesa_src_reg r = this->result;
+
+      l = ir_to_mesa_dst_reg_from_src(current_function->return_reg);
+
+      for (i = 0; i < type_size(current_function->sig->return_type); i++) {
+        ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
+        l.index++;
+        r.index++;
+      }
+   }
+
+   ir_to_mesa_emit_op0(ir, OPCODE_RET);
+}
+
+void
+ir_to_mesa_visitor::visit(ir_discard *ir)
+{
+   assert(ir->condition == NULL); /* FINISHME */
+
+   ir_to_mesa_emit_op0(ir, OPCODE_KIL_NV);
+}
+
+void
+ir_to_mesa_visitor::visit(ir_if *ir)
+{
+   ir_to_mesa_instruction *cond_inst, *if_inst, *else_inst = NULL;
+   ir_to_mesa_instruction *prev_inst;
+
+   prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
+
+   ir->condition->accept(this);
+   assert(this->result.file != PROGRAM_UNDEFINED);
+
+   if (ctx->Shader.EmitCondCodes) {
+      cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
+
+      /* See if we actually generated any instruction for generating
+       * the condition.  If not, then cook up a move to a temp so we
+       * have something to set cond_update on.
+       */
+      if (cond_inst == prev_inst) {
+        ir_to_mesa_src_reg temp = get_temp(glsl_type::bool_type);
+        cond_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_MOV,
+                                        ir_to_mesa_dst_reg_from_src(temp),
+                                        result);
+      }
+      cond_inst->cond_update = GL_TRUE;
+
+      if_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_IF);
+      if_inst->dst_reg.cond_mask = COND_NE;
+   } else {
+      if_inst = ir_to_mesa_emit_op1(ir->condition,
+                                   OPCODE_IF, ir_to_mesa_undef_dst,
+                                   this->result);
+   }
+
+   this->instructions.push_tail(if_inst);
+
+   visit_exec_list(&ir->then_instructions, this);
+
+   if (!ir->else_instructions.is_empty()) {
+      else_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_ELSE);
+      visit_exec_list(&ir->else_instructions, this);
+   }
+
+   if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF,
+                                ir_to_mesa_undef_dst, ir_to_mesa_undef);
+}
+
+ir_to_mesa_visitor::ir_to_mesa_visitor()
+{
+   result.file = PROGRAM_UNDEFINED;
+   next_temp = 1;
+   next_signature_id = 1;
+   sampler_map = NULL;
+   sampler_map_size = 0;
+   current_function = NULL;
+}
+
+static struct prog_src_register
+mesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)
+{
+   struct prog_src_register mesa_reg;
+
+   mesa_reg.File = reg.file;
+   assert(reg.index < (1 << INST_INDEX_BITS) - 1);
+   mesa_reg.Index = reg.index;
+   mesa_reg.Swizzle = reg.swizzle;
+   mesa_reg.RelAddr = reg.reladdr != NULL;
+   mesa_reg.Negate = reg.negate;
+   mesa_reg.Abs = 0;
+
+   return mesa_reg;
+}
+
+static void
+set_branchtargets(ir_to_mesa_visitor *v,
+                 struct prog_instruction *mesa_instructions,
+                 int num_instructions)
+{
+   int if_count = 0, loop_count = 0;
+   int *if_stack, *loop_stack;
+   int if_stack_pos = 0, loop_stack_pos = 0;
+   int i, j;
+
+   for (i = 0; i < num_instructions; i++) {
+      switch (mesa_instructions[i].Opcode) {
+      case OPCODE_IF:
+        if_count++;
+        break;
+      case OPCODE_BGNLOOP:
+        loop_count++;
+        break;
+      case OPCODE_BRK:
+      case OPCODE_CONT:
+        mesa_instructions[i].BranchTarget = -1;
+        break;
+      default:
+        break;
+      }
+   }
+
+   if_stack = (int *)calloc(if_count, sizeof(*if_stack));
+   loop_stack = (int *)calloc(loop_count, sizeof(*loop_stack));
+
+   for (i = 0; i < num_instructions; i++) {
+      switch (mesa_instructions[i].Opcode) {
+      case OPCODE_IF:
+        if_stack[if_stack_pos] = i;
+        if_stack_pos++;
+        break;
+      case OPCODE_ELSE:
+        mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
+        if_stack[if_stack_pos - 1] = i;
+        break;
+      case OPCODE_ENDIF:
+        mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
+        if_stack_pos--;
+        break;
+      case OPCODE_BGNLOOP:
+        loop_stack[loop_stack_pos] = i;
+        loop_stack_pos++;
+        break;
+      case OPCODE_ENDLOOP:
+        loop_stack_pos--;
+        /* Rewrite any breaks/conts at this nesting level (haven't
+         * already had a BranchTarget assigned) to point to the end
+         * of the loop.
+         */
+        for (j = loop_stack[loop_stack_pos]; j < i; j++) {
+           if (mesa_instructions[j].Opcode == OPCODE_BRK ||
+               mesa_instructions[j].Opcode == OPCODE_CONT) {
+              if (mesa_instructions[j].BranchTarget == -1) {
+                 mesa_instructions[j].BranchTarget = i;
+              }
+           }
+        }
+        /* The loop ends point at each other. */
+        mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos];
+        mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i;
+        break;
+      case OPCODE_CAL:
+        foreach_iter(exec_list_iterator, iter, v->function_signatures) {
+           function_entry *entry = (function_entry *)iter.get();
+
+           if (entry->sig_id == mesa_instructions[i].BranchTarget) {
+              mesa_instructions[i].BranchTarget = entry->inst;
+              break;
+           }
+        }
+        break;
+      default:
+        break;
+      }
+   }
+
+   free(if_stack);
+}
+
+static void
+print_program(struct prog_instruction *mesa_instructions,
+             ir_instruction **mesa_instruction_annotation,
+             int num_instructions)
+{
+   ir_instruction *last_ir = NULL;
+   int i;
+   int indent = 0;
+
+   for (i = 0; i < num_instructions; i++) {
+      struct prog_instruction *mesa_inst = mesa_instructions + i;
+      ir_instruction *ir = mesa_instruction_annotation[i];
+
+      fprintf(stdout, "%3d: ", i);
+
+      if (last_ir != ir && ir) {
+        int j;
+
+        for (j = 0; j < indent; j++) {
+           fprintf(stdout, " ");
+        }
+        ir->print();
+        printf("\n");
+        last_ir = ir;
+
+        fprintf(stdout, "     "); /* line number spacing. */
+      }
+
+      indent = _mesa_fprint_instruction_opt(stdout, mesa_inst, indent,
+                                           PROG_PRINT_DEBUG, NULL);
+   }
+}
+
+static void
+mark_input(struct gl_program *prog,
+          int index,
+          GLboolean reladdr)
+{
+   prog->InputsRead |= BITFIELD64_BIT(index);
+   int i;
+
+   if (reladdr) {
+      if (index >= FRAG_ATTRIB_TEX0 && index <= FRAG_ATTRIB_TEX7) {
+        for (i = 0; i < 8; i++) {
+           prog->InputsRead |= BITFIELD64_BIT(FRAG_ATTRIB_TEX0 + i);
+        }
+      } else {
+        assert(!"FINISHME: Mark InputsRead for varying arrays");
+      }
+   }
+}
+
+static void
+mark_output(struct gl_program *prog,
+          int index,
+          GLboolean reladdr)
+{
+   prog->OutputsWritten |= BITFIELD64_BIT(index);
+   int i;
+
+   if (reladdr) {
+      if (index >= VERT_RESULT_TEX0 && index <= VERT_RESULT_TEX7) {
+        for (i = 0; i < 8; i++) {
+           prog->OutputsWritten |= BITFIELD64_BIT(FRAG_ATTRIB_TEX0 + i);
+        }
+      } else {
+        assert(!"FINISHME: Mark OutputsWritten for varying arrays");
+      }
+   }
+}
+
+static void
+count_resources(struct gl_program *prog)
+{
+   unsigned int i;
+
+   prog->InputsRead = 0;
+   prog->OutputsWritten = 0;
+   prog->SamplersUsed = 0;
+
+   for (i = 0; i < prog->NumInstructions; i++) {
+      struct prog_instruction *inst = &prog->Instructions[i];
+      unsigned int reg;
+
+      switch (inst->DstReg.File) {
+      case PROGRAM_OUTPUT:
+        mark_output(prog, inst->DstReg.Index, inst->DstReg.RelAddr);
+        break;
+      case PROGRAM_INPUT:
+        mark_input(prog, inst->DstReg.Index, inst->DstReg.RelAddr);
+        break;
+      default:
+        break;
+      }
+
+      for (reg = 0; reg < _mesa_num_inst_src_regs(inst->Opcode); reg++) {
+        switch (inst->SrcReg[reg].File) {
+        case PROGRAM_OUTPUT:
+           mark_output(prog, inst->SrcReg[reg].Index,
+                       inst->SrcReg[reg].RelAddr);
+           break;
+        case PROGRAM_INPUT:
+           mark_input(prog, inst->SrcReg[reg].Index, inst->SrcReg[reg].RelAddr);
+           break;
+        default:
+           break;
+        }
+      }
+
+      /* Instead of just using the uniform's value to map to a
+       * sampler, Mesa first allocates a separate number for the
+       * sampler (_mesa_add_sampler), then we reindex it down to a
+       * small integer (sampler_map[], SamplersUsed), then that gets
+       * mapped to the uniform's value, and we get an actual sampler.
+       */
+      if (_mesa_is_tex_instruction(inst->Opcode)) {
+        prog->SamplerTargets[inst->TexSrcUnit] =
+           (gl_texture_index)inst->TexSrcTarget;
+        prog->SamplersUsed |= 1 << inst->TexSrcUnit;
+        if (inst->TexShadow) {
+           prog->ShadowSamplers |= 1 << inst->TexSrcUnit;
+        }
+      }
+   }
+
+   _mesa_update_shader_textures_used(prog);
+}
+
+/* Each stage has some uniforms in its Parameters list.  The Uniforms
+ * list for the linked shader program has a pointer to these uniforms
+ * in each of the stage's Parameters list, so that their values can be
+ * updated when a uniform is set.
+ */
+static void
+link_uniforms_to_shared_uniform_list(struct gl_uniform_list *uniforms,
+                                    struct gl_program *prog)
+{
+   unsigned int i;
+
+   for (i = 0; i < prog->Parameters->NumParameters; i++) {
+      const struct gl_program_parameter *p = prog->Parameters->Parameters + i;
+
+      if (p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) {
+        struct gl_uniform *uniform =
+           _mesa_append_uniform(uniforms, p->Name, prog->Target, i);
+        if (uniform)
+           uniform->Initialized = p->Initialized;
+      }
+   }
+}
+
+struct gl_program *
+get_mesa_program(GLcontext *ctx, struct gl_shader_program *shader_program,
+                struct gl_shader *shader)
+{
+   void *mem_ctx = shader_program;
+   ir_to_mesa_visitor v;
+   struct prog_instruction *mesa_instructions, *mesa_inst;
+   ir_instruction **mesa_instruction_annotation;
+   int i;
+   struct gl_program *prog;
+   GLenum target;
+   const char *target_string;
+   GLboolean progress;
+
+   switch (shader->Type) {
+   case GL_VERTEX_SHADER:
+      target = GL_VERTEX_PROGRAM_ARB;
+      target_string = "vertex";
+      break;
+   case GL_FRAGMENT_SHADER:
+      target = GL_FRAGMENT_PROGRAM_ARB;
+      target_string = "fragment";
+      break;
+   default:
+      assert(!"should not be reached");
+      break;
+   }
+
+   validate_ir_tree(shader->ir);
+
+   prog = ctx->Driver.NewProgram(ctx, target, 1);
+   if (!prog)
+      return NULL;
+   prog->Parameters = _mesa_new_parameter_list();
+   prog->Varying = _mesa_new_parameter_list();
+   prog->Attributes = _mesa_new_parameter_list();
+   v.ctx = ctx;
+   v.prog = prog;
+
+   v.mem_ctx = talloc_new(NULL);
+
+   /* Emit Mesa IR for main(). */
+   visit_exec_list(shader->ir, &v);
+   v.ir_to_mesa_emit_op0(NULL, OPCODE_END);
+
+   /* Now emit bodies for any functions that were used. */
+   do {
+      progress = GL_FALSE;
+
+      foreach_iter(exec_list_iterator, iter, v.function_signatures) {
+        function_entry *entry = (function_entry *)iter.get();
+
+        if (!entry->bgn_inst) {
+           v.current_function = entry;
+
+           entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_BGNSUB);
+           entry->bgn_inst->function = entry;
+
+           visit_exec_list(&entry->sig->body, &v);
+
+           entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_RET);
+           entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_ENDSUB);
+           progress = GL_TRUE;
+        }
+      }
+   } while (progress);
+
+   prog->NumTemporaries = v.next_temp;
+
+   int num_instructions = 0;
+   foreach_iter(exec_list_iterator, iter, v.instructions) {
+      num_instructions++;
+   }
+
+   mesa_instructions =
+      (struct prog_instruction *)calloc(num_instructions,
+                                       sizeof(*mesa_instructions));
+   mesa_instruction_annotation = talloc_array(mem_ctx, ir_instruction *,
+                                             num_instructions);
+
+   mesa_inst = mesa_instructions;
+   i = 0;
+   foreach_iter(exec_list_iterator, iter, v.instructions) {
+      ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get();
+
+      mesa_inst->Opcode = inst->op;
+      mesa_inst->CondUpdate = inst->cond_update;
+      mesa_inst->DstReg.File = inst->dst_reg.file;
+      mesa_inst->DstReg.Index = inst->dst_reg.index;
+      mesa_inst->DstReg.CondMask = inst->dst_reg.cond_mask;
+      mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask;
+      mesa_inst->DstReg.RelAddr = inst->dst_reg.reladdr != NULL;
+      mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]);
+      mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]);
+      mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]);
+      mesa_inst->TexSrcUnit = inst->sampler;
+      mesa_inst->TexSrcTarget = inst->tex_target;
+      mesa_inst->TexShadow = inst->tex_shadow;
+      mesa_instruction_annotation[i] = inst->ir;
+
+      if (ctx->Shader.EmitNoIfs && mesa_inst->Opcode == OPCODE_IF) {
+        shader_program->InfoLog =
+           talloc_asprintf_append(shader_program->InfoLog,
+                                  "Couldn't flatten if statement\n");
+        shader_program->LinkStatus = false;
+      }
+
+      if (mesa_inst->Opcode == OPCODE_BGNSUB)
+        inst->function->inst = i;
+      else if (mesa_inst->Opcode == OPCODE_CAL)
+        mesa_inst->BranchTarget = inst->function->sig_id; /* rewritten later */
+      else if (mesa_inst->Opcode == OPCODE_ARL)
+        prog->NumAddressRegs = 1;
+
+      mesa_inst++;
+      i++;
+   }
+
+   set_branchtargets(&v, mesa_instructions, num_instructions);
+   if (ctx->Shader.Flags & GLSL_DUMP) {
+      printf("Mesa %s program:\n", target_string);
+      print_program(mesa_instructions, mesa_instruction_annotation,
+                   num_instructions);
+   }
+
+   prog->Instructions = mesa_instructions;
+   prog->NumInstructions = num_instructions;
+
+   _mesa_reference_program(ctx, &shader->Program, prog);
+
+   if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) {
+      _mesa_optimize_program(ctx, prog);
+   }
+
+   return prog;
+}
+
+extern "C" {
+
+void
+_mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader)
+{
+   struct _mesa_glsl_parse_state *state =
+      new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader);
+
+   const char *source = shader->Source;
+   state->error = preprocess(state, &source, &state->info_log,
+                            &ctx->Extensions);
+
+   if (!state->error) {
+     _mesa_glsl_lexer_ctor(state, source);
+     _mesa_glsl_parse(state);
+     _mesa_glsl_lexer_dtor(state);
+   }
+
+   shader->ir = new(shader) exec_list;
+   if (!state->error && !state->translation_unit.is_empty())
+      _mesa_ast_to_hir(shader->ir, state);
+
+   if (!state->error && !shader->ir->is_empty()) {
+      validate_ir_tree(shader->ir);
+
+      /* Lowering */
+      do_mat_op_to_vec(shader->ir);
+      do_mod_to_fract(shader->ir);
+      do_div_to_mul_rcp(shader->ir);
+
+      /* Optimization passes */
+      bool progress;
+      do {
+        progress = false;
+
+        progress = do_function_inlining(shader->ir) || progress;
+        progress = do_if_simplification(shader->ir) || progress;
+        progress = do_copy_propagation(shader->ir) || progress;
+        progress = do_dead_code_local(shader->ir) || progress;
+        progress = do_dead_code_unlinked(state, shader->ir) || progress;
+        progress = do_constant_variable_unlinked(shader->ir) || progress;
+        progress = do_constant_folding(shader->ir) || progress;
+        progress = do_if_return(shader->ir) || progress;
+        if (ctx->Shader.EmitNoIfs)
+           progress = do_if_to_cond_assign(shader->ir) || progress;
+
+        progress = do_vec_index_to_swizzle(shader->ir) || progress;
+        /* Do this one after the previous to let the easier pass handle
+         * constant vector indexing.
+         */
+        progress = do_vec_index_to_cond_assign(shader->ir) || progress;
+
+        progress = do_swizzle_swizzle(shader->ir) || progress;
+      } while (progress);
+
+      validate_ir_tree(shader->ir);
+   }
+
+   shader->symbols = state->symbols;
+
+   shader->CompileStatus = !state->error;
+   shader->InfoLog = state->info_log;
+   shader->Version = state->language_version;
+   memcpy(shader->builtins_to_link, state->builtins_to_link,
+         sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link);
+   shader->num_builtins_to_link = state->num_builtins_to_link;
+
+   /* Retain any live IR, but trash the rest. */
+   reparent_ir(shader->ir, shader);
+
+   talloc_free(state);
+ }
+
+void
+_mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
+{
+   unsigned int i;
+
+   _mesa_clear_shader_program_data(ctx, prog);
+
+   prog->LinkStatus = GL_TRUE;
+
+   for (i = 0; i < prog->NumShaders; i++) {
+      if (!prog->Shaders[i]->CompileStatus) {
+        prog->InfoLog =
+           talloc_asprintf_append(prog->InfoLog,
+                                  "linking with uncompiled shader");
+        prog->LinkStatus = GL_FALSE;
+      }
+   }
+
+   prog->Varying = _mesa_new_parameter_list();
+   _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL);
+   _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL);
+
+   if (prog->LinkStatus) {
+      link_shaders(prog);
+
+      /* We don't use the linker's uniforms list, and cook up our own at
+       * generate time.
+       */
+      free(prog->Uniforms);
+      prog->Uniforms = _mesa_new_uniform_list();
+   }
+
+   if (prog->LinkStatus) {
+      for (i = 0; i < prog->_NumLinkedShaders; i++) {
+        struct gl_program *linked_prog;
+
+        linked_prog = get_mesa_program(ctx, prog,
+                                       prog->_LinkedShaders[i]);
+        count_resources(linked_prog);
+
+        link_uniforms_to_shared_uniform_list(prog->Uniforms, linked_prog);
+
+        switch (prog->_LinkedShaders[i]->Type) {
+        case GL_VERTEX_SHADER:
+           _mesa_reference_vertprog(ctx, &prog->VertexProgram,
+                                    (struct gl_vertex_program *)linked_prog);
+           ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
+                                           linked_prog);
+           break;
+        case GL_FRAGMENT_SHADER:
+           _mesa_reference_fragprog(ctx, &prog->FragmentProgram,
+                                    (struct gl_fragment_program *)linked_prog);
+           ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
+                                           linked_prog);
+           break;
+        }
+      }
+   }
+}
+
+} /* extern "C" */
diff --git a/src/mesa/program/ir_to_mesa.h b/src/mesa/program/ir_to_mesa.h
new file mode 100644 (file)
index 0000000..e832f84
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright Â© 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "main/config.h"
+#include "main/mtypes.h"
+
+void _mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *sh);
+void _mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/mesa/program/lex.yy.c b/src/mesa/program/lex.yy.c
new file mode 100644 (file)
index 0000000..135eca6
--- /dev/null
@@ -0,0 +1,3681 @@
+
+#line 3 "lex.yy.c"
+
+#define  YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types. 
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t; 
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else  /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* For convenience, these vars (plus the bison vars far below)
+   are macros in the reentrant scanner. */
+#define yyin yyg->yyin_r
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug yyg->yy_flex_debug_r
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yyg->yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yyg->yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin ,yyscanner )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+    #define YY_LESS_LINENO(n)
+    
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+       do \
+               { \
+               /* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+               *yy_cp = yyg->yy_hold_char; \
+               YY_RESTORE_YY_MORE_OFFSET \
+               yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+               YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+               } \
+       while ( 0 )
+
+#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+       {
+       FILE *yy_input_file;
+
+       char *yy_ch_buf;                /* input buffer */
+       char *yy_buf_pos;               /* current position in input buffer */
+
+       /* Size of input buffer in bytes, not including room for EOB
+        * characters.
+        */
+       yy_size_t yy_buf_size;
+
+       /* Number of characters read into yy_ch_buf, not including EOB
+        * characters.
+        */
+       int yy_n_chars;
+
+       /* Whether we "own" the buffer - i.e., we know we created it,
+        * and can realloc() it to grow it, and should free() it to
+        * delete it.
+        */
+       int yy_is_our_buffer;
+
+       /* Whether this is an "interactive" input source; if so, and
+        * if we're using stdio for input, then we want to use getc()
+        * instead of fread(), to make sure we stop fetching input after
+        * each newline.
+        */
+       int yy_is_interactive;
+
+       /* Whether we're considered to be at the beginning of a line.
+        * If so, '^' rules will be active on the next match, otherwise
+        * not.
+        */
+       int yy_at_bol;
+
+    int yy_bs_lineno; /**< The line count. */
+    int yy_bs_column; /**< The column count. */
+    
+       /* Whether to try to fill the input buffer when we reach the
+        * end of it.
+        */
+       int yy_fill_buffer;
+
+       int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+       /* When an EOF's been seen but there's still some text to process
+        * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+        * shouldn't try reading from the input source any more.  We might
+        * still have a bunch of tokens to match, though, because of
+        * possible backing-up.
+        *
+        * When we actually see the EOF, we change the status to "new"
+        * (via yyrestart()), so that the user can continue scanning by
+        * just pointing yyin at a new input file.
+        */
+#define YY_BUFFER_EOF_PENDING 2
+
+       };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
+                          ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
+                          : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
+
+void yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void yypop_buffer_state (yyscan_t yyscanner );
+
+static void yyensure_buffer_stack (yyscan_t yyscanner );
+static void yy_load_buffer_state (yyscan_t yyscanner );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+
+void *yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void yyfree (void * ,yyscan_t yyscanner );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+       { \
+       if ( ! YY_CURRENT_BUFFER ){ \
+        yyensure_buffer_stack (yyscanner); \
+               YY_CURRENT_BUFFER_LVALUE =    \
+            yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+       } \
+       YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+       }
+
+#define yy_set_bol(at_bol) \
+       { \
+       if ( ! YY_CURRENT_BUFFER ){\
+        yyensure_buffer_stack (yyscanner); \
+               YY_CURRENT_BUFFER_LVALUE =    \
+            yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+       } \
+       YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+       }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define yywrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+typedef int yy_state_type;
+
+#define yytext_ptr yytext_r
+
+static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state  ,yyscan_t yyscanner);
+static int yy_get_next_buffer (yyscan_t yyscanner );
+static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+       yyg->yytext_ptr = yy_bp; \
+       yyleng = (size_t) (yy_cp - yy_bp); \
+       yyg->yy_hold_char = *yy_cp; \
+       *yy_cp = '\0'; \
+       yyg->yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 170
+#define YY_END_OF_BUFFER 171
+/* This struct is not used in this scanner,
+   but its presence is necessary. */
+struct yy_trans_info
+       {
+       flex_int32_t yy_verify;
+       flex_int32_t yy_nxt;
+       };
+static yyconst flex_int16_t yy_accept[850] =
+    {   0,
+        0,    0,  171,  169,  167,  166,  169,  169,  139,  165,
+      141,  141,  141,  141,  139,  139,  139,  139,  139,  139,
+      139,  139,  139,  139,  139,  139,  139,  139,  139,  139,
+      139,  139,  139,  139,  139,  167,    0,    0,  168,  139,
+        0,  140,  142,  162,  162,    0,    0,    0,    0,  162,
+        0,    0,    0,    0,    0,    0,    0,  119,  163,  120,
+      121,  153,  153,  153,  153,    0,  141,    0,  127,  128,
+      129,  139,  139,  139,  139,  139,  139,  139,  139,  139,
+      139,  139,  139,  139,  139,  139,  139,  139,  139,  139,
+      139,  139,  139,  139,  139,  139,  139,  139,  139,  139,
+
+      139,  139,  139,  139,  139,  139,  139,  139,  139,  139,
+      139,  139,  139,  139,  139,  139,  139,  139,  139,  139,
+      139,  139,  139,  139,  139,  139,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,  161,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,  160,  160,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+      159,  159,  159,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,  150,  150,  150,  151,  151,  152,  143,
+      142,  143,    0,  144,   11,   12,  139,   13,  139,  139,
+       14,   15,  139,   16,   17,   18,   19,   20,   21,    6,
+
+       22,   23,   24,   25,   26,   28,   27,   29,   30,   31,
+       32,   33,   34,   35,  139,  139,  139,  139,  139,   40,
+       41,  139,   42,   43,   44,   45,   46,   47,   48,  139,
+       49,   50,   51,   52,   53,   54,   55,  139,   56,   57,
+       58,   59,  139,  139,   64,   65,  139,  139,  139,  139,
+      139,  139,    0,    0,    0,    0,  142,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,   80,   81,   83,
+        0,  158,    0,    0,    0,    0,    0,    0,   97,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,  157,
+      156,  156,  109,    0,    0,    0,    0,    0,    0,    0,
+
+        0,    0,    0,  147,  147,  148,  149,    0,  145,   11,
+       11,  139,   12,   12,   12,  139,  139,  139,  139,  139,
+       15,   15,  139,  130,   16,   16,  139,   17,   17,  139,
+       18,   18,  139,   19,   19,  139,   20,   20,  139,   21,
+       21,  139,   22,   22,  139,   24,   24,  139,   25,   25,
+      139,   28,   28,  139,   27,   27,  139,   30,   30,  139,
+       31,   31,  139,   32,   32,  139,   33,   33,  139,   34,
+       34,  139,   35,   35,  139,  139,  139,  139,   36,  139,
+       38,  139,   40,   40,  139,   41,   41,  139,  131,   42,
+       42,  139,   43,   43,  139,  139,   45,   45,  139,   46,
+
+       46,  139,   47,   47,  139,   48,   48,  139,  139,   49,
+       49,  139,   50,   50,  139,   51,   51,  139,   52,   52,
+      139,   53,   53,  139,   54,   54,  139,  139,   10,   56,
+      139,   57,  139,   58,  139,   59,  139,   60,  139,   62,
+      139,   64,   64,  139,  139,  139,  139,  139,  139,  139,
+      139,    0,  164,    0,    0,    0,   73,   74,    0,    0,
+        0,    0,    0,    0,    0,   85,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,  155,    0,    0,    0,  113,    0,
+      115,    0,    0,    0,    0,    0,    0,  154,  146,  139,
+
+      139,  139,    4,  139,  139,  139,  139,  139,  139,  139,
+      139,  139,  139,  139,  139,  139,  139,  139,  139,  139,
+      139,  139,  139,  139,  139,  139,    9,   37,   39,  139,
+      139,  139,  139,  139,  139,  139,  139,  139,  139,  139,
+      139,  139,  139,  139,  139,  139,  139,  139,  139,  139,
+       60,  139,   61,   62,  139,   63,  139,  139,  139,  139,
+      139,   69,  139,  139,    0,    0,    0,    0,    0,   75,
+       76,    0,    0,    0,    0,   84,    0,    0,   88,   91,
+        0,    0,    0,    0,    0,    0,    0,  102,  103,    0,
+        0,    0,    0,  108,    0,    0,    0,    0,    0,    0,
+
+        0,    0,    0,    0,  139,  139,  139,  139,  139,  139,
+        5,  139,  139,  139,  139,  139,  139,  139,  139,  139,
+      139,  139,  139,  139,  139,  139,  139,  139,  139,  139,
+        7,    8,  139,  139,  139,  139,  139,  139,  139,  139,
+      139,  139,  139,  139,  139,  139,  139,  139,  139,  139,
+      139,  139,  139,  139,   61,  139,  139,   63,  139,  139,
+      139,  139,  139,   70,  139,   66,    0,    0,    0,    0,
+      124,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+       94,    0,   98,   99,    0,  101,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,  117,  118,    0,    0,
+
+      125,   11,    3,   12,  135,  136,  139,   14,   15,   16,
+       17,   18,   19,   20,   21,   22,   24,   25,   28,   27,
+       30,   31,   32,   33,   34,   35,   40,   41,   42,   43,
+       44,   45,   46,   47,   48,  139,  139,  139,   49,   50,
+       51,   52,   53,   54,   55,   56,   57,   58,   59,  139,
+      139,  139,  139,   64,   65,  139,   68,  126,    0,    0,
+       71,    0,   77,    0,    0,    0,   86,    0,    0,    0,
+        0,    0,    0,  100,    0,    0,  106,   93,    0,    0,
+        0,    0,    0,    0,  122,    0,  139,  132,  133,  139,
+       60,  139,   62,  139,   67,    0,    0,    0,    0,   79,
+
+       82,   87,    0,    0,   92,    0,    0,    0,  105,    0,
+        0,    0,    0,  114,  116,    0,  139,  139,   61,   63,
+        2,    1,    0,   78,    0,   90,    0,   96,  104,    0,
+        0,  111,  112,  123,  139,  134,    0,   89,    0,  107,
+      110,  139,   72,   95,  139,  139,  137,  138,    0
+    } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    4,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    5,    1,    6,    7,    1,    1,    1,    1,
+        1,    1,    8,    1,    8,    9,    1,   10,   11,   12,
+       13,   14,   15,   15,   15,   15,   15,    1,    1,    1,
+        1,    1,    1,    1,   16,   17,   18,   19,   20,   21,
+       22,   23,   24,    7,   25,   26,   27,   28,   29,   30,
+       31,   32,   33,   34,   35,   36,   37,   38,   39,   40,
+        1,    1,    1,    1,   41,    1,   42,   43,   44,   45,
+
+       46,   47,   48,   49,   50,   51,   52,   53,   54,   55,
+       56,   57,   58,   59,   60,   61,   62,   63,   64,   65,
+       66,   67,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int32_t yy_meta[68] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    2,    1,    3,    2,
+        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+        2,    2,    2,    2,    2,    2,    2
+    } ;
+
+static yyconst flex_int16_t yy_base[853] =
+    {   0,
+        0,    0, 1299, 1300,   66, 1300, 1293, 1294,    0,   69,
+       85,  128,  140,  152,  151,   58,   56,   63,   76, 1272,
+      158,  160,   39,  163,  173,  189,   52, 1265,   76, 1235,
+     1234, 1246, 1230, 1244, 1243,  105, 1272, 1284, 1300,    0,
+      225, 1300,  218,  160,  157,   20,  123,   66,  119,  192,
+     1244, 1230,   54,  162, 1228, 1240,  194, 1300,  200,  195,
+       98,  227,  196,  231,  235,  293,  305,  316, 1300, 1300,
+     1300, 1249, 1262, 1256,  223, 1245, 1248, 1244, 1259,  107,
+      298, 1241, 1255,  246, 1241, 1254, 1245, 1258, 1235, 1246,
+     1237,  182, 1238, 1229, 1238, 1229, 1228, 1229,  144, 1223,
+
+     1229, 1240, 1231, 1225, 1222, 1223, 1227,  289, 1236, 1223,
+      302, 1230, 1217, 1231, 1207,   65,  315,  276, 1227, 1226,
+     1202, 1187, 1182, 1199, 1175, 1180, 1206,  279, 1195,  293,
+     1190,  342,  299, 1192, 1173,  317, 1183, 1179, 1174,  207,
+     1180, 1166, 1182, 1179, 1170,  320,  324, 1172, 1161, 1175,
+     1178, 1160, 1175, 1162, 1159, 1166,  284, 1174,  227,  288,
+      327,  342,  345, 1151, 1168, 1169, 1162, 1144,  318, 1145,
+     1167, 1158,  330,  341,  345,  349,  353,  357,  361, 1300,
+      419,  430,  436,  442,  440,  441, 1191,    0, 1190, 1173,
+     1163,  443, 1183,  444,  451,  468,  470,  472,  471,    0,
+
+      496,    0,  497,  498,    0,  499,  500,    0,  524,  525,
+      526,  536,  537,  553, 1178, 1171, 1184,  354,  356,  561,
+      563, 1165,  564,  565, 1157,  580,  590,  591,  592, 1178,
+      593,  617,  618,  619,  629,  630, 1155, 1165,  330,  362,
+      419,  483,  445,  364,  646, 1153, 1145, 1144, 1129, 1129,
+     1128, 1127, 1170, 1142, 1130,  662,  669,  643, 1134,  487,
+     1131, 1125, 1125, 1119, 1132, 1132, 1117, 1300, 1300, 1132,
+     1120,  646, 1127,  135, 1124, 1130,  561, 1125, 1300, 1116,
+     1123, 1122, 1125, 1111, 1110, 1114, 1109,  448, 1114,  650,
+      653,  665, 1300, 1106, 1104, 1104, 1112, 1113, 1095,  670,
+
+     1100, 1106,  486,  579,  655,  661,  668,  726,  732, 1112,
+      682, 1119, 1110,  688,  730, 1117, 1116, 1109, 1123, 1113,
+     1104,  712, 1111,    0, 1102,  731, 1109, 1100,  733, 1107,
+     1098,  734, 1105, 1096,  736, 1103, 1094,  737, 1101, 1092,
+      738, 1099, 1090,  739, 1097, 1088,  740, 1095, 1086,  741,
+     1093, 1084,  742, 1091, 1082,  743, 1089, 1080,  744, 1087,
+     1078,  745, 1085, 1076,  746, 1083, 1074,  747, 1081, 1072,
+      748, 1079, 1070,  749, 1077, 1080, 1073, 1080,    0, 1073,
+        0, 1088, 1063,  750, 1070, 1061,  751, 1068,    0, 1059,
+      752, 1066, 1057,  755, 1064, 1063, 1054,  758, 1061, 1052,
+
+      776, 1059, 1050,  777, 1057, 1048,  779, 1055, 1058, 1045,
+      780, 1052, 1043,  782, 1050, 1041,  783, 1048, 1039,  784,
+     1046, 1037,  785, 1044, 1035,  786, 1042, 1041,    0, 1032,
+     1039, 1030, 1037, 1028, 1035, 1026, 1033,  787, 1032,  788,
+     1047, 1022,  789, 1029, 1028, 1006, 1000, 1005, 1011,  994,
+     1009,  424, 1300, 1008,  998, 1002, 1300, 1300,  992, 1001,
+      987, 1004,  987,  990,  984, 1300,  985,  984,  981,  988,
+      981,  989,  985,  995,  992,  974,  980,  987,  971,  970,
+      988,  970,  982,  981, 1300,  980,  970,  974, 1300,  961,
+     1300,  966,  966,  974,  957,  958,  968, 1300, 1300, 1000,
+
+      982,  998,    0,  798,  996,  996,  995,  994,  993,  992,
+      991,  990,  989,  988,  987,  986,  985,  984,  983,  982,
+      981,  980,  979,  978,  965,  958,    0,    0,    0,  975,
+      974,  973,  972,  971,  970,  969,  968,  967,  945,  965,
+      964,  963,  962,  961,  960,  959,  958,  957,  956,  955,
+      929,  936,  793,  927,  934,  794,  950,  949,  918,  921,
+      901,    0,  902,  895,  902,  901,  902,  894,  912, 1300,
+     1300,  894,  892,  902,  895, 1300,  890,  907,  516, 1300,
+      898,  882,  883,  892,  883,  882,  882, 1300,  881,  890,
+      880,  896,  893, 1300,  892,  890,  879,  880,  876,  868,
+
+      875,  870,  871,  866,  892,  892,  890,  904,  903,  898,
+        0,  886,  885,  884,  883,  882,  881,  880,  879,  878,
+      877,  876,  875,  874,  873,  872,  871,  870,  869,  868,
+        0,    0,  867,  866,  865,  864,  863,  862,  861,  860,
+      859,  804,  858,  857,  856,  855,  854,  853,  852,  851,
+      850,  849,  848,  865,  839,  846,  862,  836,  843,  841,
+      840,  818,  818,    0,  825,    0,  859,  858,  807,  825,
+     1300,  820,  815,  808,  804,  816,  806,  804,  800,  816,
+      807,  806, 1300, 1300,  809, 1300,  804,  797,  786,  797,
+      789,  793,  806,  801,  804,  786, 1300, 1300,  798,  787,
+
+     1300,    0,    0,    0,    0,    0,  826,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,  814,  813,  802,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,  785,
+      798,  779,  792,    0,    0,  656,    0,    0,  706,  702,
+     1300,  649, 1300,  648,  648,  654, 1300,  637,  645,  610,
+      612,  608,  608, 1300,  572,  583, 1300, 1300,  577,  573,
+      560,  557,  542,  555, 1300,  539,  573,    0,    0,  572,
+        0,  555,    0,  546,    0,  562,  551,  495,  479, 1300,
+
+     1300, 1300,  481,  481, 1300,  480,  443,   31, 1300,  141,
+      166,  171,  186, 1300, 1300,  211,  236,  276,    0,    0,
+     1300, 1300,  290, 1300,  325, 1300,  346, 1300, 1300,  343,
+      341, 1300, 1300, 1300,  365,    0,  380, 1300,  371, 1300,
+     1300,  486, 1300, 1300,  451,  458,    0,    0, 1300,  836,
+      503,  839
+    } ;
+
+static yyconst flex_int16_t yy_def[853] =
+    {   0,
+      849,    1,  849,  849,  849,  849,  849,  850,  851,  849,
+      849,  849,  849,  849,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  849,  849,  850,  849,  851,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  852,  849,  849,  849,  849,
+      849,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  851,
+
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+
+      849,  849,  849,  849,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+
+      849,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  851,  851,  851,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  851,  851,  851,  851,
+      851,  851,  851,  851,  851,  849,  849,  849,  849,  849,
+
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  851,  851,  851,  851,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  851,  851,  849,  849,  849,  849,
+      849,  851,  849,  849,  851,  851,  851,  851,    0,  849,
+      849,  849
+    } ;
+
+static yyconst flex_int16_t yy_nxt[1368] =
+    {   0,
+        4,    5,    6,    5,    7,    8,    9,    4,   10,   11,
+       12,   13,   14,   11,   11,   15,    9,   16,   17,   18,
+       19,    9,    9,    9,   20,   21,   22,    9,   23,   24,
+        9,   25,   26,   27,   28,    9,    9,   29,    9,    9,
+        9,    9,    9,    9,    9,    9,   30,    9,    9,    9,
+        9,    9,    9,    9,    9,    9,   31,    9,   32,   33,
+       34,    9,   35,    9,    9,    9,    9,   36,   96,   36,
+       41,  116,  137,   97,   80,  138,  829,   42,   43,   43,
+       43,   43,   43,   43,   77,   81,   78,  119,   82,  117,
+       83,  238,   79,   66,   67,   67,   67,   67,   67,   67,
+
+       84,   85,  239,  150,   68,  120,   36,   86,   36,  151,
+       44,   45,   46,   47,   48,   49,   50,   51,   52,  141,
+      142,   53,   54,   55,   56,   57,   58,   59,   60,   61,
+       68,  143,   62,   63,   64,   65,   66,   67,   67,   67,
+       67,   67,   67,  170,  194,  195,   69,   68,   66,   67,
+       67,   67,   67,   67,   67,  218,  171,  219,   70,   68,
+       66,   67,   67,   67,   67,   67,   67,   72,  139,   73,
+       71,   68,  140,   68,  144,   92,   74,  145,   98,   88,
+      467,   89,   75,   93,   76,   68,   90,   99,   94,   91,
+      101,  100,  102,  103,   95,  468,  830,   68,  136,  133,
+
+      210,  133,  133,  152,  133,  104,  105,  133,  106,  107,
+      108,  109,  110,  134,  111,  133,  112,  153,  133,  211,
+      135,  831,  113,  114,  154,  115,   41,   43,   43,   43,
+       43,   43,   43,  146,  147,  157,  832,  132,  165,  133,
+      166,  161,  162,  167,  168,  833,  158,  163,  188,  159,
+      133,  169,  160,  265,  189,  164,  834,  201,  133,  174,
+      173,  175,  176,  132,  835,  266,  128,  129,   46,   47,
+       48,   49,  172,   51,   52,  202,  285,   53,   54,   55,
+       56,   57,   58,  130,   60,   61,  286,  243,  131,  244,
+      173,  173,  173,  173,  177,  173,  173,  178,  179,  173,
+
+      173,  173,  181,  181,  181,  181,  181,  181,  228,  836,
+      196,  197,  182,   66,   67,   67,   67,   67,   67,   67,
+      198,  232,  229,  183,   68,  184,  184,  184,  184,  184,
+      184,  240,  134,  241,  255,  233,  282,  287,  182,  135,
+      258,  258,  283,  288,  242,  837,  258,  430,  164,  256,
+       68,  257,  257,  257,  257,  257,  257,  258,  258,  258,
+      261,  258,  258,  298,  258,  272,  258,  258,  258,  258,
+      431,  258,  381,  299,  258,  258,  379,  838,  258,  432,
+      440,  289,  258,  290,  258,  258,  291,  292,  380,  258,
+      382,  839,  258,  303,  303,  303,  303,  840,  441,  841,
+
+      258,  842,  433,  258,  303,  303,  303,  303,  304,  303,
+      303,  305,  306,  303,  303,  303,  303,  303,  303,  303,
+      307,  303,  303,  303,  303,  303,  303,  303,   43,   43,
+       43,   43,   43,   43,  843,  844,  434,  308,  132,  309,
+      309,  309,  309,  309,  309,  184,  184,  184,  184,  184,
+      184,  184,  184,  184,  184,  184,  184,  310,  313,  435,
+      321,  325,  311,  314,  132,  322,  326,  438,  328,  847,
+      565,  311,  315,  329,  322,  326,  848,  311,  314,  439,
+      312,  316,  329,  323,  327,  331,  566,  334,  340,  337,
+      332,  330,  335,  341,  338,  482,  845,  846,  483,  332,
+
+      436,  335,  341,  338,   40,  332,  828,  335,  333,  338,
+      336,  342,  339,  343,  346,  349,  352,  355,  344,  347,
+      350,  353,  356,  437,  827,  826,  825,  344,  347,  350,
+      353,  356,  455,  824,  347,  350,  345,  348,  351,  354,
+      357,  358,  361,  364,  823,  456,  359,  362,  365,  498,
+      498,  498,  498,  367,  370,  359,  362,  365,  368,  371,
+      822,  359,  362,  365,  360,  363,  366,  368,  371,  678,
+      373,  821,  679,  368,  371,  374,  369,  372,  383,  820,
+      386,  390,  393,  384,  374,  387,  391,  394,  819,  818,
+      374,  817,  384,  375,  387,  391,  394,  397,  816,  815,
+
+      814,  385,  398,  388,  392,  395,  471,  400,  403,  406,
+      410,  398,  401,  404,  407,  411,  813,  398,  812,  472,
+      399,  401,  404,  407,  411,  811,  810,  401,  404,  407,
+      402,  405,  408,  412,  413,  416,  419,  809,  808,  414,
+      417,  420,  498,  498,  498,  498,  422,  425,  414,  417,
+      420,  423,  426,  807,  414,  417,  420,  415,  418,  421,
+      423,  426,  806,  442,  805,  804,  423,  426,  443,  424,
+      427,  257,  257,  257,  257,  257,  257,  443,  257,  257,
+      257,  257,  257,  257,  453,  453,  444,  453,  453,  803,
+      453,  453,  453,  453,  453,  453,  802,  453,  801,  310,
+
+      453,  453,  800,  799,  453,  313,  485,  453,  453,  798,
+      797,  453,  453,  492,  796,  493,  795,  494,  499,  498,
+      498,  498,  312,  453,  498,  498,  498,  498,  316,  321,
+      495,  498,  498,  498,  498,  309,  309,  309,  309,  309,
+      309,  309,  309,  309,  309,  309,  309,  313,  325,  501,
+      328,  331,  323,  334,  337,  340,  343,  346,  349,  352,
+      355,  358,  361,  364,  367,  370,  373,  383,  386,  390,
+      316,  327,  393,  330,  333,  397,  336,  339,  342,  345,
+      348,  351,  354,  357,  360,  363,  366,  369,  372,  375,
+      385,  388,  392,  400,  403,  395,  406,  410,  399,  413,
+
+      416,  419,  422,  425,  551,  554,  442,  794,  608,  609,
+      655,  658,  793,  792,  736,  737,  402,  405,  791,  408,
+      412,  790,  415,  418,  421,  424,  427,  552,  555,  444,
+      610,  789,  788,  656,  659,  738,   38,   38,   38,  180,
+      180,  787,  786,  785,  784,  783,  782,  781,  780,  779,
+      778,  777,  776,  775,  774,  773,  772,  771,  770,  769,
+      768,  767,  766,  765,  764,  763,  762,  761,  760,  759,
+      758,  757,  756,  755,  754,  753,  659,  752,  751,  656,
+      750,  749,  748,  747,  746,  745,  744,  743,  742,  741,
+      740,  739,  735,  734,  733,  732,  731,  730,  729,  728,
+
+      727,  726,  725,  724,  723,  722,  721,  720,  719,  718,
+      717,  716,  715,  714,  713,  712,  711,  710,  709,  708,
+      707,  706,  705,  704,  703,  702,  701,  700,  699,  698,
+      697,  696,  695,  694,  693,  692,  691,  690,  689,  688,
+      687,  686,  685,  684,  683,  682,  681,  680,  677,  676,
+      675,  674,  673,  672,  671,  670,  669,  668,  667,  666,
+      665,  664,  663,  662,  661,  660,  657,  555,  654,  552,
+      653,  652,  651,  650,  649,  648,  647,  646,  645,  644,
+      643,  642,  641,  640,  639,  638,  637,  636,  635,  634,
+      633,  632,  631,  630,  629,  628,  627,  626,  625,  624,
+
+      623,  622,  621,  620,  619,  618,  617,  616,  615,  614,
+      613,  612,  611,  607,  606,  605,  604,  603,  602,  601,
+      600,  599,  598,  597,  596,  595,  594,  593,  592,  591,
+      590,  589,  588,  587,  586,  585,  584,  583,  582,  581,
+      580,  579,  578,  577,  576,  575,  574,  573,  572,  571,
+      570,  569,  568,  567,  564,  563,  562,  561,  560,  559,
+      558,  557,  444,  556,  553,  550,  437,  549,  435,  548,
+      433,  547,  431,  546,  545,  427,  544,  424,  543,  421,
+      542,  418,  541,  415,  540,  412,  539,  538,  408,  537,
+      405,  536,  402,  535,  399,  534,  533,  395,  532,  392,
+
+      531,  388,  530,  385,  529,  528,  527,  526,  525,  524,
+      375,  523,  372,  522,  369,  521,  366,  520,  363,  519,
+      360,  518,  357,  517,  354,  516,  351,  515,  348,  514,
+      345,  513,  342,  512,  339,  511,  336,  510,  333,  509,
+      330,  508,  327,  507,  323,  506,  505,  504,  503,  502,
+      316,  500,  312,  497,  496,  491,  490,  489,  488,  487,
+      486,  484,  481,  480,  479,  478,  477,  476,  475,  474,
+      473,  470,  469,  466,  465,  464,  463,  462,  461,  460,
+      459,  458,  457,  454,  289,  261,  452,  451,  450,  449,
+      448,  447,  446,  445,  429,  428,  409,  396,  389,  378,
+
+      377,  376,  324,  320,  319,  318,  317,  302,  301,  300,
+      297,  296,  295,  294,  293,  284,  281,  280,  279,  278,
+      277,  276,  275,  274,  273,  271,  270,  269,  268,  267,
+      264,  263,  262,  260,  259,  172,  254,  253,  252,  251,
+      250,  249,  248,  247,  246,  245,  237,  236,  235,  234,
+      231,  230,  227,  226,  225,  224,  223,  222,  221,  220,
+      217,  216,  215,  214,  213,  212,  209,  208,  207,  206,
+      205,  204,  203,  200,  199,  193,  192,  191,  190,  187,
+      186,  185,  156,  155,  149,  148,   39,  127,  126,  125,
+      124,  123,  122,  121,  118,   87,   39,   37,  849,    3,
+
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849
+    } ;
+
+static yyconst flex_int16_t yy_chk[1368] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    5,   23,    5,
+       10,   27,   46,   23,   17,   46,  808,   10,   10,   10,
+       10,   10,   10,   10,   16,   17,   16,   29,   17,   27,
+       18,  116,   16,   11,   11,   11,   11,   11,   11,   11,
+
+       18,   19,  116,   53,   11,   29,   36,   19,   36,   53,
+       10,   10,   10,   10,   10,   10,   10,   10,   10,   48,
+       48,   10,   10,   10,   10,   10,   10,   10,   10,   10,
+       11,   48,   10,   10,   10,   10,   12,   12,   12,   12,
+       12,   12,   12,   61,   80,   80,   12,   12,   13,   13,
+       13,   13,   13,   13,   13,   99,   61,   99,   13,   13,
+       14,   14,   14,   14,   14,   14,   14,   15,   47,   15,
+       14,   14,   47,   12,   49,   22,   15,   49,   24,   21,
+      274,   21,   15,   22,   15,   13,   21,   24,   22,   21,
+       25,   24,   25,   25,   22,  274,  810,   14,   45,   45,
+
+       92,   44,   44,   54,   45,   25,   26,   44,   26,   26,
+       26,   26,   26,   44,   26,   45,   26,   54,   44,   92,
+       44,  811,   26,   26,   54,   26,   41,   43,   43,   43,
+       43,   43,   43,   50,   50,   57,  812,   43,   60,   50,
+       60,   59,   59,   60,   60,  813,   57,   59,   75,   57,
+       50,   60,   57,  140,   75,   59,  816,   84,   59,   63,
+       63,   63,   63,   43,  817,  140,   41,   41,   41,   41,
+       41,   41,   62,   41,   41,   84,  159,   41,   41,   41,
+       41,   41,   41,   41,   41,   41,  159,  118,   41,  118,
+       62,   62,   62,   62,   64,   64,   64,   64,   65,   65,
+
+       65,   65,   66,   66,   66,   66,   66,   66,  108,  818,
+       81,   81,   66,   67,   67,   67,   67,   67,   67,   67,
+       81,  111,  108,   68,   67,   68,   68,   68,   68,   68,
+       68,  117,  128,  117,  130,  111,  157,  160,   66,  128,
+      133,  133,  157,  160,  117,  823,  133,  239,  130,  132,
+       67,  132,  132,  132,  132,  132,  132,  133,  136,  136,
+      136,  146,  146,  169,  136,  147,  147,  146,  161,  161,
+      239,  147,  219,  169,  161,  136,  218,  825,  146,  240,
+      244,  161,  147,  162,  162,  161,  163,  163,  218,  162,
+      219,  827,  163,  173,  173,  173,  173,  830,  244,  831,
+
+      162,  835,  240,  163,  174,  174,  174,  174,  175,  175,
+      175,  175,  176,  176,  176,  176,  177,  177,  177,  177,
+      178,  178,  178,  178,  179,  179,  179,  179,  181,  181,
+      181,  181,  181,  181,  837,  839,  241,  182,  181,  182,
+      182,  182,  182,  182,  182,  183,  183,  183,  183,  183,
+      183,  184,  184,  184,  184,  184,  184,  185,  186,  241,
+      192,  194,  185,  186,  181,  192,  194,  243,  195,  845,
+      452,  185,  186,  195,  192,  194,  846,  185,  186,  243,
+      185,  186,  195,  192,  194,  196,  452,  197,  199,  198,
+      196,  195,  197,  199,  198,  288,  842,  842,  288,  196,
+
+      242,  197,  199,  198,  851,  196,  807,  197,  196,  198,
+      197,  199,  198,  201,  203,  204,  206,  207,  201,  203,
+      204,  206,  207,  242,  806,  804,  803,  201,  203,  204,
+      206,  207,  260,  799,  203,  204,  201,  203,  204,  206,
+      207,  209,  210,  211,  798,  260,  209,  210,  211,  303,
+      303,  303,  303,  212,  213,  209,  210,  211,  212,  213,
+      797,  209,  210,  211,  209,  210,  211,  212,  213,  579,
+      214,  796,  579,  212,  213,  214,  212,  213,  220,  794,
+      221,  223,  224,  220,  214,  221,  223,  224,  792,  790,
+      214,  787,  220,  214,  221,  223,  224,  226,  786,  784,
+
+      783,  220,  226,  221,  223,  224,  277,  227,  228,  229,
+      231,  226,  227,  228,  229,  231,  782,  226,  781,  277,
+      226,  227,  228,  229,  231,  780,  779,  227,  228,  229,
+      227,  228,  229,  231,  232,  233,  234,  776,  775,  232,
+      233,  234,  304,  304,  304,  304,  235,  236,  232,  233,
+      234,  235,  236,  773,  232,  233,  234,  232,  233,  234,
+      235,  236,  772,  245,  771,  770,  235,  236,  245,  235,
+      236,  256,  256,  256,  256,  256,  256,  245,  257,  257,
+      257,  257,  257,  257,  258,  258,  245,  272,  272,  769,
+      258,  290,  290,  272,  291,  291,  768,  290,  766,  311,
+
+      291,  258,  765,  764,  272,  314,  292,  292,  290,  762,
+      760,  291,  292,  300,  759,  300,  756,  300,  305,  305,
+      305,  305,  311,  292,  306,  306,  306,  306,  314,  322,
+      300,  307,  307,  307,  307,  308,  308,  308,  308,  308,
+      308,  309,  309,  309,  309,  309,  309,  315,  326,  315,
+      329,  332,  322,  335,  338,  341,  344,  347,  350,  353,
+      356,  359,  362,  365,  368,  371,  374,  384,  387,  391,
+      315,  326,  394,  329,  332,  398,  335,  338,  341,  344,
+      347,  350,  353,  356,  359,  362,  365,  368,  371,  374,
+      384,  387,  391,  401,  404,  394,  407,  411,  398,  414,
+
+      417,  420,  423,  426,  438,  440,  443,  753,  504,  504,
+      553,  556,  752,  751,  642,  642,  401,  404,  750,  407,
+      411,  738,  414,  417,  420,  423,  426,  438,  440,  443,
+      504,  737,  736,  553,  556,  642,  850,  850,  850,  852,
+      852,  707,  700,  699,  696,  695,  694,  693,  692,  691,
+      690,  689,  688,  687,  685,  682,  681,  680,  679,  678,
+      677,  676,  675,  674,  673,  672,  670,  669,  668,  667,
+      665,  663,  662,  661,  660,  659,  658,  657,  656,  655,
+      654,  653,  652,  651,  650,  649,  648,  647,  646,  645,
+      644,  643,  641,  640,  639,  638,  637,  636,  635,  634,
+
+      633,  630,  629,  628,  627,  626,  625,  624,  623,  622,
+      621,  620,  619,  618,  617,  616,  615,  614,  613,  612,
+      610,  609,  608,  607,  606,  605,  604,  603,  602,  601,
+      600,  599,  598,  597,  596,  595,  593,  592,  591,  590,
+      589,  587,  586,  585,  584,  583,  582,  581,  578,  577,
+      575,  574,  573,  572,  569,  568,  567,  566,  565,  564,
+      563,  561,  560,  559,  558,  557,  555,  554,  552,  551,
+      550,  549,  548,  547,  546,  545,  544,  543,  542,  541,
+      540,  539,  538,  537,  536,  535,  534,  533,  532,  531,
+      530,  526,  525,  524,  523,  522,  521,  520,  519,  518,
+
+      517,  516,  515,  514,  513,  512,  511,  510,  509,  508,
+      507,  506,  505,  502,  501,  500,  497,  496,  495,  494,
+      493,  492,  490,  488,  487,  486,  484,  483,  482,  481,
+      480,  479,  478,  477,  476,  475,  474,  473,  472,  471,
+      470,  469,  468,  467,  465,  464,  463,  462,  461,  460,
+      459,  456,  455,  454,  451,  450,  449,  448,  447,  446,
+      445,  444,  442,  441,  439,  437,  436,  435,  434,  433,
+      432,  431,  430,  428,  427,  425,  424,  422,  421,  419,
+      418,  416,  415,  413,  412,  410,  409,  408,  406,  405,
+      403,  402,  400,  399,  397,  396,  395,  393,  392,  390,
+
+      388,  386,  385,  383,  382,  380,  378,  377,  376,  375,
+      373,  372,  370,  369,  367,  366,  364,  363,  361,  360,
+      358,  357,  355,  354,  352,  351,  349,  348,  346,  345,
+      343,  342,  340,  339,  337,  336,  334,  333,  331,  330,
+      328,  327,  325,  323,  321,  320,  319,  318,  317,  316,
+      313,  312,  310,  302,  301,  299,  298,  297,  296,  295,
+      294,  289,  287,  286,  285,  284,  283,  282,  281,  280,
+      278,  276,  275,  273,  271,  270,  267,  266,  265,  264,
+      263,  262,  261,  259,  255,  254,  253,  252,  251,  250,
+      249,  248,  247,  246,  238,  237,  230,  225,  222,  217,
+
+      216,  215,  193,  191,  190,  189,  187,  172,  171,  170,
+      168,  167,  166,  165,  164,  158,  156,  155,  154,  153,
+      152,  151,  150,  149,  148,  145,  144,  143,  142,  141,
+      139,  138,  137,  135,  134,  131,  129,  127,  126,  125,
+      124,  123,  122,  121,  120,  119,  115,  114,  113,  112,
+      110,  109,  107,  106,  105,  104,  103,  102,  101,  100,
+       98,   97,   96,   95,   94,   93,   91,   90,   89,   88,
+       87,   86,   85,   83,   82,   79,   78,   77,   76,   74,
+       73,   72,   56,   55,   52,   51,   38,   37,   35,   34,
+       33,   32,   31,   30,   28,   20,    8,    7,    3,  849,
+
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
+      849,  849,  849,  849,  849,  849,  849
+    } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+#line 1 "program_lexer.l"
+#line 2 "program_lexer.l"
+/*
+ * Copyright Â© 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION 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/imports.h"
+#include "program/prog_instruction.h"
+#include "program/prog_statevars.h"
+#include "program/symbol_table.h"
+#include "program/program_parser.h"
+#include "program/program_parse.tab.h"
+
+#define require_ARB_vp (yyextra->mode == ARB_vertex)
+#define require_ARB_fp (yyextra->mode == ARB_fragment)
+#define require_NV_fp  (yyextra->option.NV_fragment)
+#define require_shadow (yyextra->option.Shadow)
+#define require_rect   (yyextra->option.TexRect)
+#define require_texarray        (yyextra->option.TexArray)
+
+#ifndef HAVE_UNISTD_H
+#define YY_NO_UNISTD_H
+#endif
+
+#define return_token_or_IDENTIFIER(condition, token)   \
+   do {                                                        \
+      if (condition) {                                 \
+        return token;                                  \
+      } else {                                         \
+        return handle_ident(yyextra, yytext, yylval);  \
+      }                                                        \
+   } while (0)
+
+#define return_token_or_DOT(condition, token)          \
+   do {                                                        \
+      if (condition) {                                 \
+        return token;                                  \
+      } else {                                         \
+        yyless(1);                                     \
+        return DOT;                                    \
+      }                                                        \
+   } while (0)
+
+
+#define return_opcode(condition, token, opcode, len)   \
+   do {                                                        \
+      if (condition &&                                 \
+         _mesa_parse_instruction_suffix(yyextra,       \
+                                        yytext + len,  \
+                                        & yylval->temp_inst)) {        \
+        yylval->temp_inst.Opcode = OPCODE_ ## opcode;  \
+        return token;                                  \
+      } else {                                         \
+        return handle_ident(yyextra, yytext, yylval);  \
+      }                                                        \
+   } while (0)
+
+#define SWIZZLE_INVAL  MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
+                                    SWIZZLE_NIL, SWIZZLE_NIL)
+
+static unsigned
+mask_from_char(char c)
+{
+   switch (c) {
+   case 'x':
+   case 'r':
+      return WRITEMASK_X;
+   case 'y':
+   case 'g':
+      return WRITEMASK_Y;
+   case 'z':
+   case 'b':
+      return WRITEMASK_Z;
+   case 'w':
+   case 'a':
+      return WRITEMASK_W;
+   }
+
+   return 0;
+}
+
+static unsigned
+swiz_from_char(char c)
+{
+   switch (c) {
+   case 'x':
+   case 'r':
+      return SWIZZLE_X;
+   case 'y':
+   case 'g':
+      return SWIZZLE_Y;
+   case 'z':
+   case 'b':
+      return SWIZZLE_Z;
+   case 'w':
+   case 'a':
+      return SWIZZLE_W;
+   }
+
+   return 0;
+}
+
+static int
+handle_ident(struct asm_parser_state *state, const char *text, YYSTYPE *lval)
+{
+   lval->string = strdup(text);
+
+   return (_mesa_symbol_table_find_symbol(state->st, 0, text) == NULL)
+      ? IDENTIFIER : USED_IDENTIFIER;
+}
+
+#define YY_USER_ACTION                                                 \
+   do {                                                                        \
+      yylloc->first_column = yylloc->last_column;                      \
+      yylloc->last_column += yyleng;                                   \
+      if ((yylloc->first_line == 1)                                    \
+         && (yylloc->first_column == 1)) {                             \
+        yylloc->position = 1;                                          \
+      } else {                                                         \
+        yylloc->position += yylloc->last_column - yylloc->first_column; \
+      }                                                                        \
+   } while(0);
+
+#define YY_NO_INPUT
+
+/* Yes, this is intentionally doing nothing. We have this line of code
+here only to avoid the compiler complaining about an unput function
+that is defined, but never called. */
+#define YY_USER_INIT while (0) { unput(0); }
+
+#define YY_EXTRA_TYPE struct asm_parser_state *
+
+/* Flex defines a couple of functions with no declarations nor the
+static keyword. Declare them here to avoid a compiler warning. */
+int yyget_column  (yyscan_t yyscanner);
+void yyset_column (int  column_no , yyscan_t yyscanner);
+
+#line 1177 "lex.yy.c"
+
+#define INITIAL 0
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+/* Holds the entire state of the reentrant scanner. */
+struct yyguts_t
+    {
+
+    /* User-defined. Not touched by flex. */
+    YY_EXTRA_TYPE yyextra_r;
+
+    /* The rest are the same as the globals declared in the non-reentrant scanner. */
+    FILE *yyin_r, *yyout_r;
+    size_t yy_buffer_stack_top; /**< index of top of stack. */
+    size_t yy_buffer_stack_max; /**< capacity of stack. */
+    YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
+    char yy_hold_char;
+    int yy_n_chars;
+    int yyleng_r;
+    char *yy_c_buf_p;
+    int yy_init;
+    int yy_start;
+    int yy_did_buffer_switch_on_eof;
+    int yy_start_stack_ptr;
+    int yy_start_stack_depth;
+    int *yy_start_stack;
+    yy_state_type yy_last_accepting_state;
+    char* yy_last_accepting_cpos;
+
+    int yylineno_r;
+    int yy_flex_debug_r;
+
+    char *yytext_r;
+    int yy_more_flag;
+    int yy_more_len;
+
+    YYSTYPE * yylval_r;
+
+    YYLTYPE * yylloc_r;
+
+    }; /* end struct yyguts_t */
+
+static int yy_init_globals (yyscan_t yyscanner );
+
+    /* This must go here because YYSTYPE and YYLTYPE are included
+     * from bison output in section 1.*/
+    #    define yylval yyg->yylval_r
+    
+    #    define yylloc yyg->yylloc_r
+    
+int yylex_init (yyscan_t* scanner);
+
+int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+
+/* Accessor methods to globals.
+   These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (yyscan_t yyscanner );
+
+int yyget_debug (yyscan_t yyscanner );
+
+void yyset_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *yyget_in (yyscan_t yyscanner );
+
+void yyset_in  (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *yyget_out (yyscan_t yyscanner );
+
+void yyset_out  (FILE * out_str ,yyscan_t yyscanner );
+
+int yyget_leng (yyscan_t yyscanner );
+
+char *yyget_text (yyscan_t yyscanner );
+
+int yyget_lineno (yyscan_t yyscanner );
+
+void yyset_lineno (int line_number ,yyscan_t yyscanner );
+
+YYSTYPE * yyget_lval (yyscan_t yyscanner );
+
+void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
+
+       YYLTYPE *yyget_lloc (yyscan_t yyscanner );
+    
+        void yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );
+    
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap (yyscan_t yyscanner );
+#else
+extern int yywrap (yyscan_t yyscanner );
+#endif
+#endif
+
+    static void yyunput (int c,char *buf_ptr  ,yyscan_t yyscanner);
+    
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (yyscan_t yyscanner );
+#else
+static int input (yyscan_t yyscanner );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+       if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+               { \
+               int c = '*'; \
+               size_t n; \
+               for ( n = 0; n < max_size && \
+                            (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+                       buf[n] = (char) c; \
+               if ( c == '\n' ) \
+                       buf[n++] = (char) c; \
+               if ( c == EOF && ferror( yyin ) ) \
+                       YY_FATAL_ERROR( "input in flex scanner failed" ); \
+               result = n; \
+               } \
+       else \
+               { \
+               errno=0; \
+               while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+                       { \
+                       if( errno != EINTR) \
+                               { \
+                               YY_FATAL_ERROR( "input in flex scanner failed" ); \
+                               break; \
+                               } \
+                       errno=0; \
+                       clearerr(yyin); \
+                       } \
+               }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex \
+               (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
+
+#define YY_DECL int yylex \
+               (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+       YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+       register yy_state_type yy_current_state;
+       register char *yy_cp, *yy_bp;
+       register int yy_act;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+#line 169 "program_lexer.l"
+
+
+#line 1426 "lex.yy.c"
+
+    yylval = yylval_param;
+
+    yylloc = yylloc_param;
+
+       if ( !yyg->yy_init )
+               {
+               yyg->yy_init = 1;
+
+#ifdef YY_USER_INIT
+               YY_USER_INIT;
+#endif
+
+               if ( ! yyg->yy_start )
+                       yyg->yy_start = 1;      /* first start state */
+
+               if ( ! yyin )
+                       yyin = stdin;
+
+               if ( ! yyout )
+                       yyout = stdout;
+
+               if ( ! YY_CURRENT_BUFFER ) {
+                       yyensure_buffer_stack (yyscanner);
+                       YY_CURRENT_BUFFER_LVALUE =
+                               yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+               }
+
+               yy_load_buffer_state(yyscanner );
+               }
+
+       while ( 1 )             /* loops until end-of-file is reached */
+               {
+               yy_cp = yyg->yy_c_buf_p;
+
+               /* Support of yytext. */
+               *yy_cp = yyg->yy_hold_char;
+
+               /* yy_bp points to the position in yy_ch_buf of the start of
+                * the current run.
+                */
+               yy_bp = yy_cp;
+
+               yy_current_state = yyg->yy_start;
+yy_match:
+               do
+                       {
+                       register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+                       if ( yy_accept[yy_current_state] )
+                               {
+                               yyg->yy_last_accepting_state = yy_current_state;
+                               yyg->yy_last_accepting_cpos = yy_cp;
+                               }
+                       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+                               {
+                               yy_current_state = (int) yy_def[yy_current_state];
+                               if ( yy_current_state >= 850 )
+                                       yy_c = yy_meta[(unsigned int) yy_c];
+                               }
+                       yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+                       ++yy_cp;
+                       }
+               while ( yy_base[yy_current_state] != 1300 );
+
+yy_find_action:
+               yy_act = yy_accept[yy_current_state];
+               if ( yy_act == 0 )
+                       { /* have to back up */
+                       yy_cp = yyg->yy_last_accepting_cpos;
+                       yy_current_state = yyg->yy_last_accepting_state;
+                       yy_act = yy_accept[yy_current_state];
+                       }
+
+               YY_DO_BEFORE_ACTION;
+
+do_action:     /* This label is used only to access EOF actions. */
+
+               switch ( yy_act )
+       { /* beginning of action switch */
+                       case 0: /* must back up */
+                       /* undo the effects of YY_DO_BEFORE_ACTION */
+                       *yy_cp = yyg->yy_hold_char;
+                       yy_cp = yyg->yy_last_accepting_cpos;
+                       yy_current_state = yyg->yy_last_accepting_state;
+                       goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 171 "program_lexer.l"
+{ return ARBvp_10; }
+       YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 172 "program_lexer.l"
+{ return ARBfp_10; }
+       YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 173 "program_lexer.l"
+{
+   yylval->integer = at_address;
+   return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS);
+}
+       YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 177 "program_lexer.l"
+{ return ALIAS; }
+       YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 178 "program_lexer.l"
+{ return ATTRIB; }
+       YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 179 "program_lexer.l"
+{ return END; }
+       YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 180 "program_lexer.l"
+{ return OPTION; }
+       YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 181 "program_lexer.l"
+{ return OUTPUT; }
+       YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 182 "program_lexer.l"
+{ return PARAM; }
+       YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 183 "program_lexer.l"
+{ yylval->integer = at_temp; return TEMP; }
+       YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 185 "program_lexer.l"
+{ return_opcode(             1, VECTOR_OP, ABS, 3); }
+       YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 186 "program_lexer.l"
+{ return_opcode(             1, BIN_OP, ADD, 3); }
+       YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 187 "program_lexer.l"
+{ return_opcode(require_ARB_vp, ARL, ARL, 3); }
+       YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 189 "program_lexer.l"
+{ return_opcode(require_ARB_fp, TRI_OP, CMP, 3); }
+       YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 190 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SCALAR_OP, COS, 3); }
+       YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 192 "program_lexer.l"
+{ return_opcode(require_NV_fp,  VECTOR_OP, DDX, 3); }
+       YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 193 "program_lexer.l"
+{ return_opcode(require_NV_fp,  VECTOR_OP, DDY, 3); }
+       YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 194 "program_lexer.l"
+{ return_opcode(             1, BIN_OP, DP3, 3); }
+       YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 195 "program_lexer.l"
+{ return_opcode(             1, BIN_OP, DP4, 3); }
+       YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 196 "program_lexer.l"
+{ return_opcode(             1, BIN_OP, DPH, 3); }
+       YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 197 "program_lexer.l"
+{ return_opcode(             1, BIN_OP, DST, 3); }
+       YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 199 "program_lexer.l"
+{ return_opcode(             1, SCALAR_OP, EX2, 3); }
+       YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 200 "program_lexer.l"
+{ return_opcode(require_ARB_vp, SCALAR_OP, EXP, 3); }
+       YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 202 "program_lexer.l"
+{ return_opcode(             1, VECTOR_OP, FLR, 3); }
+       YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 203 "program_lexer.l"
+{ return_opcode(             1, VECTOR_OP, FRC, 3); }
+       YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 205 "program_lexer.l"
+{ return_opcode(require_ARB_fp, KIL, KIL, 3); }
+       YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 207 "program_lexer.l"
+{ return_opcode(             1, VECTOR_OP, LIT, 3); }
+       YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 208 "program_lexer.l"
+{ return_opcode(             1, SCALAR_OP, LG2, 3); }
+       YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 209 "program_lexer.l"
+{ return_opcode(require_ARB_vp, SCALAR_OP, LOG, 3); }
+       YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 210 "program_lexer.l"
+{ return_opcode(require_ARB_fp, TRI_OP, LRP, 3); }
+       YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 212 "program_lexer.l"
+{ return_opcode(             1, TRI_OP, MAD, 3); }
+       YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 213 "program_lexer.l"
+{ return_opcode(             1, BIN_OP, MAX, 3); }
+       YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 214 "program_lexer.l"
+{ return_opcode(             1, BIN_OP, MIN, 3); }
+       YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 215 "program_lexer.l"
+{ return_opcode(             1, VECTOR_OP, MOV, 3); }
+       YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 216 "program_lexer.l"
+{ return_opcode(             1, BIN_OP, MUL, 3); }
+       YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 218 "program_lexer.l"
+{ return_opcode(require_NV_fp,  VECTOR_OP, PK2H, 4); }
+       YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 219 "program_lexer.l"
+{ return_opcode(require_NV_fp,  VECTOR_OP, PK2US, 5); }
+       YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 220 "program_lexer.l"
+{ return_opcode(require_NV_fp,  VECTOR_OP, PK4B, 4); }
+       YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 221 "program_lexer.l"
+{ return_opcode(require_NV_fp,  VECTOR_OP, PK4UB, 5); }
+       YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 222 "program_lexer.l"
+{ return_opcode(             1, BINSC_OP, POW, 3); }
+       YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 224 "program_lexer.l"
+{ return_opcode(             1, SCALAR_OP, RCP, 3); }
+       YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 225 "program_lexer.l"
+{ return_opcode(require_NV_fp,  BIN_OP,    RFL, 3); }
+       YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 226 "program_lexer.l"
+{ return_opcode(             1, SCALAR_OP, RSQ, 3); }
+       YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 228 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SCALAR_OP, SCS, 3); }
+       YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 229 "program_lexer.l"
+{ return_opcode(require_NV_fp,  BIN_OP, SEQ, 3); }
+       YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 230 "program_lexer.l"
+{ return_opcode(require_NV_fp,  BIN_OP, SFL, 3); }
+       YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 231 "program_lexer.l"
+{ return_opcode(             1, BIN_OP, SGE, 3); }
+       YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 232 "program_lexer.l"
+{ return_opcode(require_NV_fp,  BIN_OP, SGT, 3); }
+       YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 233 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SCALAR_OP, SIN, 3); }
+       YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 234 "program_lexer.l"
+{ return_opcode(require_NV_fp,  BIN_OP, SLE, 3); }
+       YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 235 "program_lexer.l"
+{ return_opcode(             1, BIN_OP, SLT, 3); }
+       YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 236 "program_lexer.l"
+{ return_opcode(require_NV_fp,  BIN_OP, SNE, 3); }
+       YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 237 "program_lexer.l"
+{ return_opcode(require_NV_fp,  BIN_OP, STR, 3); }
+       YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 238 "program_lexer.l"
+{ return_opcode(             1, BIN_OP, SUB, 3); }
+       YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 239 "program_lexer.l"
+{ return_opcode(             1, SWZ, SWZ, 3); }
+       YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 241 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SAMPLE_OP, TEX, 3); }
+       YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 242 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SAMPLE_OP, TXB, 3); }
+       YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 243 "program_lexer.l"
+{ return_opcode(require_NV_fp,  TXD_OP, TXD, 3); }
+       YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 244 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SAMPLE_OP, TXP, 3); }
+       YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 246 "program_lexer.l"
+{ return_opcode(require_NV_fp,  SCALAR_OP, UP2H, 4); }
+       YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 247 "program_lexer.l"
+{ return_opcode(require_NV_fp,  SCALAR_OP, UP2US, 5); }
+       YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 248 "program_lexer.l"
+{ return_opcode(require_NV_fp,  SCALAR_OP, UP4B, 4); }
+       YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 249 "program_lexer.l"
+{ return_opcode(require_NV_fp,  SCALAR_OP, UP4UB, 5); }
+       YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 251 "program_lexer.l"
+{ return_opcode(require_NV_fp,  TRI_OP, X2D, 3); }
+       YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 252 "program_lexer.l"
+{ return_opcode(             1, BIN_OP, XPD, 3); }
+       YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 254 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); }
+       YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 255 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); }
+       YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 256 "program_lexer.l"
+{ return PROGRAM; }
+       YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 257 "program_lexer.l"
+{ return STATE; }
+       YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 258 "program_lexer.l"
+{ return RESULT; }
+       YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 260 "program_lexer.l"
+{ return AMBIENT; }
+       YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 261 "program_lexer.l"
+{ return ATTENUATION; }
+       YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 262 "program_lexer.l"
+{ return BACK; }
+       YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 263 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, CLIP); }
+       YY_BREAK
+case 75:
+YY_RULE_SETUP
+#line 264 "program_lexer.l"
+{ return COLOR; }
+       YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 265 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_fp, DEPTH); }
+       YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 266 "program_lexer.l"
+{ return DIFFUSE; }
+       YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 267 "program_lexer.l"
+{ return DIRECTION; }
+       YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 268 "program_lexer.l"
+{ return EMISSION; }
+       YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 269 "program_lexer.l"
+{ return ENV; }
+       YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 270 "program_lexer.l"
+{ return EYE; }
+       YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 271 "program_lexer.l"
+{ return FOGCOORD; }
+       YY_BREAK
+case 83:
+YY_RULE_SETUP
+#line 272 "program_lexer.l"
+{ return FOG; }
+       YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 273 "program_lexer.l"
+{ return FRONT; }
+       YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 274 "program_lexer.l"
+{ return HALF; }
+       YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 275 "program_lexer.l"
+{ return INVERSE; }
+       YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 276 "program_lexer.l"
+{ return INVTRANS; }
+       YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 277 "program_lexer.l"
+{ return LIGHT; }
+       YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 278 "program_lexer.l"
+{ return LIGHTMODEL; }
+       YY_BREAK
+case 90:
+YY_RULE_SETUP
+#line 279 "program_lexer.l"
+{ return LIGHTPROD; }
+       YY_BREAK
+case 91:
+YY_RULE_SETUP
+#line 280 "program_lexer.l"
+{ return LOCAL; }
+       YY_BREAK
+case 92:
+YY_RULE_SETUP
+#line 281 "program_lexer.l"
+{ return MATERIAL; }
+       YY_BREAK
+case 93:
+YY_RULE_SETUP
+#line 282 "program_lexer.l"
+{ return MAT_PROGRAM; }
+       YY_BREAK
+case 94:
+YY_RULE_SETUP
+#line 283 "program_lexer.l"
+{ return MATRIX; }
+       YY_BREAK
+case 95:
+YY_RULE_SETUP
+#line 284 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, MATRIXINDEX); }
+       YY_BREAK
+case 96:
+YY_RULE_SETUP
+#line 285 "program_lexer.l"
+{ return MODELVIEW; }
+       YY_BREAK
+case 97:
+YY_RULE_SETUP
+#line 286 "program_lexer.l"
+{ return MVP; }
+       YY_BREAK
+case 98:
+YY_RULE_SETUP
+#line 287 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, NORMAL); }
+       YY_BREAK
+case 99:
+YY_RULE_SETUP
+#line 288 "program_lexer.l"
+{ return OBJECT; }
+       YY_BREAK
+case 100:
+YY_RULE_SETUP
+#line 289 "program_lexer.l"
+{ return PALETTE; }
+       YY_BREAK
+case 101:
+YY_RULE_SETUP
+#line 290 "program_lexer.l"
+{ return PARAMS; }
+       YY_BREAK
+case 102:
+YY_RULE_SETUP
+#line 291 "program_lexer.l"
+{ return PLANE; }
+       YY_BREAK
+case 103:
+YY_RULE_SETUP
+#line 292 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, POINT_TOK); }
+       YY_BREAK
+case 104:
+YY_RULE_SETUP
+#line 293 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, POINTSIZE); }
+       YY_BREAK
+case 105:
+YY_RULE_SETUP
+#line 294 "program_lexer.l"
+{ return POSITION; }
+       YY_BREAK
+case 106:
+YY_RULE_SETUP
+#line 295 "program_lexer.l"
+{ return PRIMARY; }
+       YY_BREAK
+case 107:
+YY_RULE_SETUP
+#line 296 "program_lexer.l"
+{ return PROJECTION; }
+       YY_BREAK
+case 108:
+YY_RULE_SETUP
+#line 297 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_fp, RANGE); }
+       YY_BREAK
+case 109:
+YY_RULE_SETUP
+#line 298 "program_lexer.l"
+{ return ROW; }
+       YY_BREAK
+case 110:
+YY_RULE_SETUP
+#line 299 "program_lexer.l"
+{ return SCENECOLOR; }
+       YY_BREAK
+case 111:
+YY_RULE_SETUP
+#line 300 "program_lexer.l"
+{ return SECONDARY; }
+       YY_BREAK
+case 112:
+YY_RULE_SETUP
+#line 301 "program_lexer.l"
+{ return SHININESS; }
+       YY_BREAK
+case 113:
+YY_RULE_SETUP
+#line 302 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, SIZE_TOK); }
+       YY_BREAK
+case 114:
+YY_RULE_SETUP
+#line 303 "program_lexer.l"
+{ return SPECULAR; }
+       YY_BREAK
+case 115:
+YY_RULE_SETUP
+#line 304 "program_lexer.l"
+{ return SPOT; }
+       YY_BREAK
+case 116:
+YY_RULE_SETUP
+#line 305 "program_lexer.l"
+{ return TEXCOORD; }
+       YY_BREAK
+case 117:
+YY_RULE_SETUP
+#line 306 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_fp, TEXENV); }
+       YY_BREAK
+case 118:
+YY_RULE_SETUP
+#line 307 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, TEXGEN); }
+       YY_BREAK
+case 119:
+YY_RULE_SETUP
+#line 308 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, TEXGEN_Q); }
+       YY_BREAK
+case 120:
+YY_RULE_SETUP
+#line 309 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, TEXGEN_S); }
+       YY_BREAK
+case 121:
+YY_RULE_SETUP
+#line 310 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, TEXGEN_T); }
+       YY_BREAK
+case 122:
+YY_RULE_SETUP
+#line 311 "program_lexer.l"
+{ return TEXTURE; }
+       YY_BREAK
+case 123:
+YY_RULE_SETUP
+#line 312 "program_lexer.l"
+{ return TRANSPOSE; }
+       YY_BREAK
+case 124:
+YY_RULE_SETUP
+#line 313 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, VTXATTRIB); }
+       YY_BREAK
+case 125:
+YY_RULE_SETUP
+#line 314 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, WEIGHT); }
+       YY_BREAK
+case 126:
+YY_RULE_SETUP
+#line 316 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); }
+       YY_BREAK
+case 127:
+YY_RULE_SETUP
+#line 317 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); }
+       YY_BREAK
+case 128:
+YY_RULE_SETUP
+#line 318 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); }
+       YY_BREAK
+case 129:
+YY_RULE_SETUP
+#line 319 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); }
+       YY_BREAK
+case 130:
+YY_RULE_SETUP
+#line 320 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); }
+       YY_BREAK
+case 131:
+YY_RULE_SETUP
+#line 321 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_rect, TEX_RECT); }
+       YY_BREAK
+case 132:
+YY_RULE_SETUP
+#line 322 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW1D); }
+       YY_BREAK
+case 133:
+YY_RULE_SETUP
+#line 323 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW2D); }
+       YY_BREAK
+case 134:
+YY_RULE_SETUP
+#line 324 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_rect, TEX_SHADOWRECT); }
+       YY_BREAK
+case 135:
+YY_RULE_SETUP
+#line 325 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY1D); }
+       YY_BREAK
+case 136:
+YY_RULE_SETUP
+#line 326 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY2D); }
+       YY_BREAK
+case 137:
+YY_RULE_SETUP
+#line 327 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW1D); }
+       YY_BREAK
+case 138:
+YY_RULE_SETUP
+#line 328 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); }
+       YY_BREAK
+case 139:
+YY_RULE_SETUP
+#line 330 "program_lexer.l"
+{ return handle_ident(yyextra, yytext, yylval); }
+       YY_BREAK
+case 140:
+YY_RULE_SETUP
+#line 332 "program_lexer.l"
+{ return DOT_DOT; }
+       YY_BREAK
+case 141:
+YY_RULE_SETUP
+#line 334 "program_lexer.l"
+{
+   yylval->integer = strtol(yytext, NULL, 10);
+   return INTEGER;
+}
+       YY_BREAK
+case 142:
+YY_RULE_SETUP
+#line 338 "program_lexer.l"
+{
+   yylval->real = _mesa_strtof(yytext, NULL);
+   return REAL;
+}
+       YY_BREAK
+case 143:
+/* rule 143 can match eol */
+*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */
+yyg->yy_c_buf_p = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 342 "program_lexer.l"
+{
+   yylval->real = _mesa_strtof(yytext, NULL);
+   return REAL;
+}
+       YY_BREAK
+case 144:
+YY_RULE_SETUP
+#line 346 "program_lexer.l"
+{
+   yylval->real = _mesa_strtof(yytext, NULL);
+   return REAL;
+}
+       YY_BREAK
+case 145:
+YY_RULE_SETUP
+#line 350 "program_lexer.l"
+{
+   yylval->real = _mesa_strtof(yytext, NULL);
+   return REAL;
+}
+       YY_BREAK
+case 146:
+YY_RULE_SETUP
+#line 355 "program_lexer.l"
+{
+   yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
+   yylval->swiz_mask.mask = WRITEMASK_XYZW;
+   return MASK4;
+}
+       YY_BREAK
+case 147:
+YY_RULE_SETUP
+#line 361 "program_lexer.l"
+{
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_XY
+      | mask_from_char(yytext[3]);
+   return MASK3;
+}
+       YY_BREAK
+case 148:
+YY_RULE_SETUP
+#line 367 "program_lexer.l"
+{
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_XZW;
+   return MASK3;
+}
+       YY_BREAK
+case 149:
+YY_RULE_SETUP
+#line 372 "program_lexer.l"
+{
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_YZW;
+   return MASK3;
+}
+       YY_BREAK
+case 150:
+YY_RULE_SETUP
+#line 378 "program_lexer.l"
+{
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_X
+      | mask_from_char(yytext[2]);
+   return MASK2;
+}
+       YY_BREAK
+case 151:
+YY_RULE_SETUP
+#line 384 "program_lexer.l"
+{
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_Y
+      | mask_from_char(yytext[2]);
+   return MASK2;
+}
+       YY_BREAK
+case 152:
+YY_RULE_SETUP
+#line 390 "program_lexer.l"
+{
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_ZW;
+   return MASK2;
+}
+       YY_BREAK
+case 153:
+YY_RULE_SETUP
+#line 396 "program_lexer.l"
+{
+   const unsigned s = swiz_from_char(yytext[1]);
+   yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
+   yylval->swiz_mask.mask = mask_from_char(yytext[1]);
+   return MASK1; 
+}
+       YY_BREAK
+case 154:
+YY_RULE_SETUP
+#line 403 "program_lexer.l"
+{
+   yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
+                                           swiz_from_char(yytext[2]),
+                                           swiz_from_char(yytext[3]),
+                                           swiz_from_char(yytext[4]));
+   yylval->swiz_mask.mask = 0;
+   return SWIZZLE;
+}
+       YY_BREAK
+case 155:
+YY_RULE_SETUP
+#line 412 "program_lexer.l"
+{
+   yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
+   yylval->swiz_mask.mask = WRITEMASK_XYZW;
+   return_token_or_DOT(require_ARB_fp, MASK4);
+}
+       YY_BREAK
+case 156:
+YY_RULE_SETUP
+#line 418 "program_lexer.l"
+{
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_XY
+      | mask_from_char(yytext[3]);
+   return_token_or_DOT(require_ARB_fp, MASK3);
+}
+       YY_BREAK
+case 157:
+YY_RULE_SETUP
+#line 424 "program_lexer.l"
+{
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_XZW;
+   return_token_or_DOT(require_ARB_fp, MASK3);
+}
+       YY_BREAK
+case 158:
+YY_RULE_SETUP
+#line 429 "program_lexer.l"
+{
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_YZW;
+   return_token_or_DOT(require_ARB_fp, MASK3);
+}
+       YY_BREAK
+case 159:
+YY_RULE_SETUP
+#line 435 "program_lexer.l"
+{
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_X
+      | mask_from_char(yytext[2]);
+   return_token_or_DOT(require_ARB_fp, MASK2);
+}
+       YY_BREAK
+case 160:
+YY_RULE_SETUP
+#line 441 "program_lexer.l"
+{
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_Y
+      | mask_from_char(yytext[2]);
+   return_token_or_DOT(require_ARB_fp, MASK2);
+}
+       YY_BREAK
+case 161:
+YY_RULE_SETUP
+#line 447 "program_lexer.l"
+{
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_ZW;
+   return_token_or_DOT(require_ARB_fp, MASK2);
+}
+       YY_BREAK
+case 162:
+YY_RULE_SETUP
+#line 453 "program_lexer.l"
+{
+   const unsigned s = swiz_from_char(yytext[1]);
+   yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
+   yylval->swiz_mask.mask = mask_from_char(yytext[1]);
+   return_token_or_DOT(require_ARB_fp, MASK1);
+}
+       YY_BREAK
+case 163:
+YY_RULE_SETUP
+#line 461 "program_lexer.l"
+{
+   if (require_ARB_vp) {
+      return TEXGEN_R;
+   } else {
+      yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X,
+                                               SWIZZLE_X, SWIZZLE_X);
+      yylval->swiz_mask.mask = WRITEMASK_X;
+      return MASK1;
+   }
+}
+       YY_BREAK
+case 164:
+YY_RULE_SETUP
+#line 472 "program_lexer.l"
+{
+   yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
+                                           swiz_from_char(yytext[2]),
+                                           swiz_from_char(yytext[3]),
+                                           swiz_from_char(yytext[4]));
+   yylval->swiz_mask.mask = 0;
+   return_token_or_DOT(require_ARB_fp, SWIZZLE);
+}
+       YY_BREAK
+case 165:
+YY_RULE_SETUP
+#line 481 "program_lexer.l"
+{ return DOT; }
+       YY_BREAK
+case 166:
+/* rule 166 can match eol */
+YY_RULE_SETUP
+#line 483 "program_lexer.l"
+{
+   yylloc->first_line++;
+   yylloc->first_column = 1;
+   yylloc->last_line++;
+   yylloc->last_column = 1;
+   yylloc->position++;
+}
+       YY_BREAK
+case 167:
+YY_RULE_SETUP
+#line 490 "program_lexer.l"
+/* eat whitespace */ ;
+       YY_BREAK
+case 168:
+*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */
+yyg->yy_c_buf_p = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 491 "program_lexer.l"
+/* eat comments */ ;
+       YY_BREAK
+case 169:
+YY_RULE_SETUP
+#line 492 "program_lexer.l"
+{ return yytext[0]; }
+       YY_BREAK
+case 170:
+YY_RULE_SETUP
+#line 493 "program_lexer.l"
+ECHO;
+       YY_BREAK
+#line 2490 "lex.yy.c"
+case YY_STATE_EOF(INITIAL):
+       yyterminate();
+
+       case YY_END_OF_BUFFER:
+               {
+               /* Amount of text matched not including the EOB char. */
+               int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
+
+               /* Undo the effects of YY_DO_BEFORE_ACTION. */
+               *yy_cp = yyg->yy_hold_char;
+               YY_RESTORE_YY_MORE_OFFSET
+
+               if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+                       {
+                       /* We're scanning a new file or input source.  It's
+                        * possible that this happened because the user
+                        * just pointed yyin at a new source and called
+                        * yylex().  If so, then we have to assure
+                        * consistency between YY_CURRENT_BUFFER and our
+                        * globals.  Here is the right place to do so, because
+                        * this is the first action (other than possibly a
+                        * back-up) that will match for the new input source.
+                        */
+                       yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+                       YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+                       }
+
+               /* Note that here we test for yy_c_buf_p "<=" to the position
+                * of the first EOB in the buffer, since yy_c_buf_p will
+                * already have been incremented past the NUL character
+                * (since all states make transitions on EOB to the
+                * end-of-buffer state).  Contrast this with the test
+                * in input().
+                */
+               if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+                       { /* This was really a NUL. */
+                       yy_state_type yy_next_state;
+
+                       yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
+
+                       yy_current_state = yy_get_previous_state( yyscanner );
+
+                       /* Okay, we're now positioned to make the NUL
+                        * transition.  We couldn't have
+                        * yy_get_previous_state() go ahead and do it
+                        * for us because it doesn't know how to deal
+                        * with the possibility of jamming (and we don't
+                        * want to build jamming into it because then it
+                        * will run more slowly).
+                        */
+
+                       yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
+
+                       yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+
+                       if ( yy_next_state )
+                               {
+                               /* Consume the NUL. */
+                               yy_cp = ++yyg->yy_c_buf_p;
+                               yy_current_state = yy_next_state;
+                               goto yy_match;
+                               }
+
+                       else
+                               {
+                               yy_cp = yyg->yy_c_buf_p;
+                               goto yy_find_action;
+                               }
+                       }
+
+               else switch ( yy_get_next_buffer( yyscanner ) )
+                       {
+                       case EOB_ACT_END_OF_FILE:
+                               {
+                               yyg->yy_did_buffer_switch_on_eof = 0;
+
+                               if ( yywrap(yyscanner ) )
+                                       {
+                                       /* Note: because we've taken care in
+                                        * yy_get_next_buffer() to have set up
+                                        * yytext, we can now set up
+                                        * yy_c_buf_p so that if some total
+                                        * hoser (like flex itself) wants to
+                                        * call the scanner after we return the
+                                        * YY_NULL, it'll still work - another
+                                        * YY_NULL will get returned.
+                                        */
+                                       yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
+
+                                       yy_act = YY_STATE_EOF(YY_START);
+                                       goto do_action;
+                                       }
+
+                               else
+                                       {
+                                       if ( ! yyg->yy_did_buffer_switch_on_eof )
+                                               YY_NEW_FILE;
+                                       }
+                               break;
+                               }
+
+                       case EOB_ACT_CONTINUE_SCAN:
+                               yyg->yy_c_buf_p =
+                                       yyg->yytext_ptr + yy_amount_of_matched_text;
+
+                               yy_current_state = yy_get_previous_state( yyscanner );
+
+                               yy_cp = yyg->yy_c_buf_p;
+                               yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+                               goto yy_match;
+
+                       case EOB_ACT_LAST_MATCH:
+                               yyg->yy_c_buf_p =
+                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
+
+                               yy_current_state = yy_get_previous_state( yyscanner );
+
+                               yy_cp = yyg->yy_c_buf_p;
+                               yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+                               goto yy_find_action;
+                       }
+               break;
+               }
+
+       default:
+               YY_FATAL_ERROR(
+                       "fatal flex scanner internal error--no action found" );
+       } /* end of action switch */
+               } /* end of scanning one token */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *     EOB_ACT_LAST_MATCH -
+ *     EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *     EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+       register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+       register char *source = yyg->yytext_ptr;
+       register int number_to_move, i;
+       int ret_val;
+
+       if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
+               YY_FATAL_ERROR(
+               "fatal flex scanner internal error--end of buffer missed" );
+
+       if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+               { /* Don't try to fill the buffer, so this is an EOF. */
+               if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
+                       {
+                       /* We matched a single character, the EOB, so
+                        * treat this as a final EOF.
+                        */
+                       return EOB_ACT_END_OF_FILE;
+                       }
+
+               else
+                       {
+                       /* We matched some text prior to the EOB, first
+                        * process it.
+                        */
+                       return EOB_ACT_LAST_MATCH;
+                       }
+               }
+
+       /* Try to read more data. */
+
+       /* First move last chars to start of buffer. */
+       number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+
+       for ( i = 0; i < number_to_move; ++i )
+               *(dest++) = *(source++);
+
+       if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+               /* don't do the read, it's not guaranteed to return an EOF,
+                * just force an EOF
+                */
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
+
+       else
+               {
+                       int num_to_read =
+                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+               while ( num_to_read <= 0 )
+                       { /* Not enough room in the buffer - grow it. */
+
+                       /* just a shorter name for the current buffer */
+                       YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+                       int yy_c_buf_p_offset =
+                               (int) (yyg->yy_c_buf_p - b->yy_ch_buf);
+
+                       if ( b->yy_is_our_buffer )
+                               {
+                               int new_size = b->yy_buf_size * 2;
+
+                               if ( new_size <= 0 )
+                                       b->yy_buf_size += b->yy_buf_size / 8;
+                               else
+                                       b->yy_buf_size *= 2;
+
+                               b->yy_ch_buf = (char *)
+                                       /* Include room in for 2 EOB chars. */
+                                       yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
+                               }
+                       else
+                               /* Can't grow it, we don't own it. */
+                               b->yy_ch_buf = 0;
+
+                       if ( ! b->yy_ch_buf )
+                               YY_FATAL_ERROR(
+                               "fatal error - scanner input buffer overflow" );
+
+                       yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+                       num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+                                               number_to_move - 1;
+
+                       }
+
+               if ( num_to_read > YY_READ_BUF_SIZE )
+                       num_to_read = YY_READ_BUF_SIZE;
+
+               /* Read in more data. */
+               YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+                       yyg->yy_n_chars, (size_t) num_to_read );
+
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+               }
+
+       if ( yyg->yy_n_chars == 0 )
+               {
+               if ( number_to_move == YY_MORE_ADJ )
+                       {
+                       ret_val = EOB_ACT_END_OF_FILE;
+                       yyrestart(yyin  ,yyscanner);
+                       }
+
+               else
+                       {
+                       ret_val = EOB_ACT_LAST_MATCH;
+                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+                               YY_BUFFER_EOF_PENDING;
+                       }
+               }
+
+       else
+               ret_val = EOB_ACT_CONTINUE_SCAN;
+
+       if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+               /* Extend the array by 50%, plus the number we really need. */
+               yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+               YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+               if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+                       YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+       }
+
+       yyg->yy_n_chars += number_to_move;
+       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+       yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+       return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+    static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
+{
+       register yy_state_type yy_current_state;
+       register char *yy_cp;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+       yy_current_state = yyg->yy_start;
+
+       for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
+               {
+               register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+               if ( yy_accept[yy_current_state] )
+                       {
+                       yyg->yy_last_accepting_state = yy_current_state;
+                       yyg->yy_last_accepting_cpos = yy_cp;
+                       }
+               while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+                       {
+                       yy_current_state = (int) yy_def[yy_current_state];
+                       if ( yy_current_state >= 850 )
+                               yy_c = yy_meta[(unsigned int) yy_c];
+                       }
+               yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+               }
+
+       return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *     next_state = yy_try_NUL_trans( current_state );
+ */
+    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state , yyscan_t yyscanner)
+{
+       register int yy_is_jam;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
+       register char *yy_cp = yyg->yy_c_buf_p;
+
+       register YY_CHAR yy_c = 1;
+       if ( yy_accept[yy_current_state] )
+               {
+               yyg->yy_last_accepting_state = yy_current_state;
+               yyg->yy_last_accepting_cpos = yy_cp;
+               }
+       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+               {
+               yy_current_state = (int) yy_def[yy_current_state];
+               if ( yy_current_state >= 850 )
+                       yy_c = yy_meta[(unsigned int) yy_c];
+               }
+       yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+       yy_is_jam = (yy_current_state == 849);
+
+       return yy_is_jam ? 0 : yy_current_state;
+}
+
+    static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner)
+{
+       register char *yy_cp;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+    yy_cp = yyg->yy_c_buf_p;
+
+       /* undo effects of setting up yytext */
+       *yy_cp = yyg->yy_hold_char;
+
+       if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+               { /* need to shift things up to make room */
+               /* +2 for EOB chars. */
+               register int number_to_move = yyg->yy_n_chars + 2;
+               register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+                                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+               register char *source =
+                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+               while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+                       *--dest = *--source;
+
+               yy_cp += (int) (dest - source);
+               yy_bp += (int) (dest - source);
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+                       yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+               if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+                       YY_FATAL_ERROR( "flex scanner push-back overflow" );
+               }
+
+       *--yy_cp = (char) c;
+
+       yyg->yytext_ptr = yy_bp;
+       yyg->yy_hold_char = *yy_cp;
+       yyg->yy_c_buf_p = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+    static int yyinput (yyscan_t yyscanner)
+#else
+    static int input  (yyscan_t yyscanner)
+#endif
+
+{
+       int c;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+       *yyg->yy_c_buf_p = yyg->yy_hold_char;
+
+       if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+               {
+               /* yy_c_buf_p now points to the character we want to return.
+                * If this occurs *before* the EOB characters, then it's a
+                * valid NUL; if not, then we've hit the end of the buffer.
+                */
+               if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+                       /* This was really a NUL. */
+                       *yyg->yy_c_buf_p = '\0';
+
+               else
+                       { /* need more input */
+                       int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+                       ++yyg->yy_c_buf_p;
+
+                       switch ( yy_get_next_buffer( yyscanner ) )
+                               {
+                               case EOB_ACT_LAST_MATCH:
+                                       /* This happens because yy_g_n_b()
+                                        * sees that we've accumulated a
+                                        * token and flags that we need to
+                                        * try matching the token before
+                                        * proceeding.  But for input(),
+                                        * there's no matching to consider.
+                                        * So convert the EOB_ACT_LAST_MATCH
+                                        * to EOB_ACT_END_OF_FILE.
+                                        */
+
+                                       /* Reset buffer status. */
+                                       yyrestart(yyin ,yyscanner);
+
+                                       /*FALLTHROUGH*/
+
+                               case EOB_ACT_END_OF_FILE:
+                                       {
+                                       if ( yywrap(yyscanner ) )
+                                               return EOF;
+
+                                       if ( ! yyg->yy_did_buffer_switch_on_eof )
+                                               YY_NEW_FILE;
+#ifdef __cplusplus
+                                       return yyinput(yyscanner);
+#else
+                                       return input(yyscanner);
+#endif
+                                       }
+
+                               case EOB_ACT_CONTINUE_SCAN:
+                                       yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
+                                       break;
+                               }
+                       }
+               }
+
+       c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */
+       *yyg->yy_c_buf_p = '\0';        /* preserve yytext */
+       yyg->yy_hold_char = *++yyg->yy_c_buf_p;
+
+       return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * @param yyscanner The scanner object.
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+    void yyrestart  (FILE * input_file , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+       if ( ! YY_CURRENT_BUFFER ){
+        yyensure_buffer_stack (yyscanner);
+               YY_CURRENT_BUFFER_LVALUE =
+            yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+       }
+
+       yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
+       yy_load_buffer_state(yyscanner );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+       /* TODO. We should be able to replace this entire function body
+        * with
+        *              yypop_buffer_state();
+        *              yypush_buffer_state(new_buffer);
+     */
+       yyensure_buffer_stack (yyscanner);
+       if ( YY_CURRENT_BUFFER == new_buffer )
+               return;
+
+       if ( YY_CURRENT_BUFFER )
+               {
+               /* Flush out information for old buffer. */
+               *yyg->yy_c_buf_p = yyg->yy_hold_char;
+               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+               }
+
+       YY_CURRENT_BUFFER_LVALUE = new_buffer;
+       yy_load_buffer_state(yyscanner );
+
+       /* We don't actually know whether we did this switch during
+        * EOF (yywrap()) processing, but the only time this flag
+        * is looked at is after yywrap() is called, so it's safe
+        * to go ahead and always set it.
+        */
+       yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void yy_load_buffer_state  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+       yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+       yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+       yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+       yyg->yy_hold_char = *yyg->yy_c_buf_p;
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * @param yyscanner The scanner object.
+ * @return the allocated buffer state.
+ */
+    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size , yyscan_t yyscanner)
+{
+       YY_BUFFER_STATE b;
+    
+       b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+       if ( ! b )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+       b->yy_buf_size = size;
+
+       /* yy_ch_buf has to be 2 characters longer than the size given because
+        * we need to put in 2 end-of-buffer characters.
+        */
+       b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ,yyscanner );
+       if ( ! b->yy_ch_buf )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+       b->yy_is_our_buffer = 1;
+
+       yy_init_buffer(b,file ,yyscanner);
+
+       return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ * @param yyscanner The scanner object.
+ */
+    void yy_delete_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+       if ( ! b )
+               return;
+
+       if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+               YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+       if ( b->yy_is_our_buffer )
+               yyfree((void *) b->yy_ch_buf ,yyscanner );
+
+       yyfree((void *) b ,yyscanner );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file , yyscan_t yyscanner)
+
+{
+       int oerrno = errno;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+       yy_flush_buffer(b ,yyscanner);
+
+       b->yy_input_file = file;
+       b->yy_fill_buffer = 1;
+
+    /* If b is the current buffer, then yy_init_buffer was _probably_
+     * called from yyrestart() or through yy_get_next_buffer.
+     * In that case, we don't want to reset the lineno or column.
+     */
+    if (b != YY_CURRENT_BUFFER){
+        b->yy_bs_lineno = 1;
+        b->yy_bs_column = 0;
+    }
+
+        b->yy_is_interactive = 0;
+    
+       errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * @param yyscanner The scanner object.
+ */
+    void yy_flush_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+       if ( ! b )
+               return;
+
+       b->yy_n_chars = 0;
+
+       /* We always need two end-of-buffer characters.  The first causes
+        * a transition to the end-of-buffer state.  The second causes
+        * a jam in that state.
+        */
+       b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+       b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+       b->yy_buf_pos = &b->yy_ch_buf[0];
+
+       b->yy_at_bol = 1;
+       b->yy_buffer_status = YY_BUFFER_NEW;
+
+       if ( b == YY_CURRENT_BUFFER )
+               yy_load_buffer_state(yyscanner );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ *  the current state. This function will allocate the stack
+ *  if necessary.
+ *  @param new_buffer The new state.
+ *  @param yyscanner The scanner object.
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+       if (new_buffer == NULL)
+               return;
+
+       yyensure_buffer_stack(yyscanner);
+
+       /* This block is copied from yy_switch_to_buffer. */
+       if ( YY_CURRENT_BUFFER )
+               {
+               /* Flush out information for old buffer. */
+               *yyg->yy_c_buf_p = yyg->yy_hold_char;
+               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+               }
+
+       /* Only push if top exists. Otherwise, replace top. */
+       if (YY_CURRENT_BUFFER)
+               yyg->yy_buffer_stack_top++;
+       YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+       /* copied from yy_switch_to_buffer. */
+       yy_load_buffer_state(yyscanner );
+       yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ *  The next element becomes the new top.
+ *  @param yyscanner The scanner object.
+ */
+void yypop_buffer_state (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+       if (!YY_CURRENT_BUFFER)
+               return;
+
+       yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+       YY_CURRENT_BUFFER_LVALUE = NULL;
+       if (yyg->yy_buffer_stack_top > 0)
+               --yyg->yy_buffer_stack_top;
+
+       if (YY_CURRENT_BUFFER) {
+               yy_load_buffer_state(yyscanner );
+               yyg->yy_did_buffer_switch_on_eof = 1;
+       }
+}
+
+/* Allocates the stack if it does not exist.
+ *  Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (yyscan_t yyscanner)
+{
+       int num_to_alloc;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+       if (!yyg->yy_buffer_stack) {
+
+               /* First allocation is just for 2 elements, since we don't know if this
+                * scanner will even need a stack. We use 2 instead of 1 to avoid an
+                * immediate realloc on the next call.
+         */
+               num_to_alloc = 1;
+               yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc
+                                                               (num_to_alloc * sizeof(struct yy_buffer_state*)
+                                                               , yyscanner);
+               if ( ! yyg->yy_buffer_stack )
+                       YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+                                                                 
+               memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+                               
+               yyg->yy_buffer_stack_max = num_to_alloc;
+               yyg->yy_buffer_stack_top = 0;
+               return;
+       }
+
+       if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
+
+               /* Increase the buffer to prepare for a possible push. */
+               int grow_size = 8 /* arbitrary grow size */;
+
+               num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
+               yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc
+                                                               (yyg->yy_buffer_stack,
+                                                               num_to_alloc * sizeof(struct yy_buffer_state*)
+                                                               , yyscanner);
+               if ( ! yyg->yy_buffer_stack )
+                       YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+               /* zero only the new slots.*/
+               memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
+               yyg->yy_buffer_stack_max = num_to_alloc;
+       }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object. 
+ */
+YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size , yyscan_t yyscanner)
+{
+       YY_BUFFER_STATE b;
+    
+       if ( size < 2 ||
+            base[size-2] != YY_END_OF_BUFFER_CHAR ||
+            base[size-1] != YY_END_OF_BUFFER_CHAR )
+               /* They forgot to leave room for the EOB's. */
+               return 0;
+
+       b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+       if ( ! b )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+       b->yy_buf_size = size - 2;      /* "- 2" to take care of EOB's */
+       b->yy_buf_pos = b->yy_ch_buf = base;
+       b->yy_is_our_buffer = 0;
+       b->yy_input_file = 0;
+       b->yy_n_chars = b->yy_buf_size;
+       b->yy_is_interactive = 0;
+       b->yy_at_bol = 1;
+       b->yy_fill_buffer = 0;
+       b->yy_buffer_status = YY_BUFFER_NEW;
+
+       yy_switch_to_buffer(b ,yyscanner );
+
+       return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ *       yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
+{
+    
+       return yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len , yyscan_t yyscanner)
+{
+       YY_BUFFER_STATE b;
+       char *buf;
+       yy_size_t n;
+       int i;
+    
+       /* Get memory for full buffer, including space for trailing EOB's. */
+       n = _yybytes_len + 2;
+       buf = (char *) yyalloc(n ,yyscanner );
+       if ( ! buf )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+       for ( i = 0; i < _yybytes_len; ++i )
+               buf[i] = yybytes[i];
+
+       buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+       b = yy_scan_buffer(buf,n ,yyscanner);
+       if ( ! b )
+               YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+       /* It's okay to grow etc. this buffer, and we should throw it
+        * away when we're done.
+        */
+       b->yy_is_our_buffer = 1;
+
+       return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+{
+       (void) fprintf( stderr, "%s\n", msg );
+       exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+       do \
+               { \
+               /* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+               yytext[yyleng] = yyg->yy_hold_char; \
+               yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
+               yyg->yy_hold_char = *yyg->yy_c_buf_p; \
+               *yyg->yy_c_buf_p = '\0'; \
+               yyleng = yyless_macro_arg; \
+               } \
+       while ( 0 )
+
+/* Accessor  methods (get/set functions) to struct members. */
+
+/** Get the user-defined data for this scanner.
+ * @param yyscanner The scanner object.
+ */
+YY_EXTRA_TYPE yyget_extra  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yyextra;
+}
+
+/** Get the current line number.
+ * @param yyscanner The scanner object.
+ */
+int yyget_lineno  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    
+        if (! YY_CURRENT_BUFFER)
+            return 0;
+    
+    return yylineno;
+}
+
+/** Get the current column number.
+ * @param yyscanner The scanner object.
+ */
+int yyget_column  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    
+        if (! YY_CURRENT_BUFFER)
+            return 0;
+    
+    return yycolumn;
+}
+
+/** Get the input stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *yyget_in  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yyin;
+}
+
+/** Get the output stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *yyget_out  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yyout;
+}
+
+/** Get the length of the current token.
+ * @param yyscanner The scanner object.
+ */
+int yyget_leng  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yyleng;
+}
+
+/** Get the current token.
+ * @param yyscanner The scanner object.
+ */
+
+char *yyget_text  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yytext;
+}
+
+/** Set the user-defined data. This data is never touched by the scanner.
+ * @param user_defined The data to be associated with this scanner.
+ * @param yyscanner The scanner object.
+ */
+void yyset_extra (YY_EXTRA_TYPE  user_defined , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yyextra = user_defined ;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void yyset_lineno (int  line_number , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+        /* lineno is only valid if an input buffer exists. */
+        if (! YY_CURRENT_BUFFER )
+           yy_fatal_error( "yyset_lineno called with no buffer" , yyscanner); 
+    
+    yylineno = line_number;
+}
+
+/** Set the current column.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void yyset_column (int  column_no , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+        /* column is only valid if an input buffer exists. */
+        if (! YY_CURRENT_BUFFER )
+           yy_fatal_error( "yyset_column called with no buffer" , yyscanner); 
+    
+    yycolumn = column_no;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * @param yyscanner The scanner object.
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE *  in_str , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yyin = in_str ;
+}
+
+void yyset_out (FILE *  out_str , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yyout = out_str ;
+}
+
+int yyget_debug  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yy_flex_debug;
+}
+
+void yyset_debug (int  bdebug , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yy_flex_debug = bdebug ;
+}
+
+/* Accessor methods for yylval and yylloc */
+
+YYSTYPE * yyget_lval  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yylval;
+}
+
+void yyset_lval (YYSTYPE *  yylval_param , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yylval = yylval_param;
+}
+
+YYLTYPE *yyget_lloc  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yylloc;
+}
+    
+void yyset_lloc (YYLTYPE *  yylloc_param , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yylloc = yylloc_param;
+}
+    
+/* User-visible API */
+
+/* yylex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+
+int yylex_init(yyscan_t* ptr_yy_globals)
+
+{
+    if (ptr_yy_globals == NULL){
+        errno = EINVAL;
+        return 1;
+    }
+
+    *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL );
+
+    if (*ptr_yy_globals == NULL){
+        errno = ENOMEM;
+        return 1;
+    }
+
+    /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+    memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+    return yy_init_globals ( *ptr_yy_globals );
+}
+
+/* yylex_init_extra has the same functionality as yylex_init, but follows the
+ * convention of taking the scanner as the last argument. Note however, that
+ * this is a *pointer* to a scanner, as it will be allocated by this call (and
+ * is the reason, too, why this function also must handle its own declaration).
+ * The user defined value in the first argument will be available to yyalloc in
+ * the yyextra field.
+ */
+
+int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
+
+{
+    struct yyguts_t dummy_yyguts;
+
+    yyset_extra (yy_user_defined, &dummy_yyguts);
+
+    if (ptr_yy_globals == NULL){
+        errno = EINVAL;
+        return 1;
+    }
+       
+    *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+       
+    if (*ptr_yy_globals == NULL){
+        errno = ENOMEM;
+        return 1;
+    }
+    
+    /* By setting to 0xAA, we expose bugs in
+    yy_init_globals. Leave at 0x00 for releases. */
+    memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+    
+    yyset_extra (yy_user_defined, *ptr_yy_globals);
+    
+    return yy_init_globals ( *ptr_yy_globals );
+}
+
+static int yy_init_globals (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from yylex_destroy(), so don't allocate here.
+     */
+
+    yyg->yy_buffer_stack = 0;
+    yyg->yy_buffer_stack_top = 0;
+    yyg->yy_buffer_stack_max = 0;
+    yyg->yy_c_buf_p = (char *) 0;
+    yyg->yy_init = 0;
+    yyg->yy_start = 0;
+
+    yyg->yy_start_stack_ptr = 0;
+    yyg->yy_start_stack_depth = 0;
+    yyg->yy_start_stack =  NULL;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+    yyin = stdin;
+    yyout = stdout;
+#else
+    yyin = (FILE *) 0;
+    yyout = (FILE *) 0;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * yylex_init()
+     */
+    return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+    /* Pop the buffer stack, destroying each element. */
+       while(YY_CURRENT_BUFFER){
+               yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+               YY_CURRENT_BUFFER_LVALUE = NULL;
+               yypop_buffer_state(yyscanner);
+       }
+
+       /* Destroy the stack itself. */
+       yyfree(yyg->yy_buffer_stack ,yyscanner);
+       yyg->yy_buffer_stack = NULL;
+
+    /* Destroy the start condition stack. */
+        yyfree(yyg->yy_start_stack ,yyscanner );
+        yyg->yy_start_stack = NULL;
+
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * yylex() is called, initialization will occur. */
+    yy_init_globals( yyscanner);
+
+    /* Destroy the main struct (reentrant only). */
+    yyfree ( yyscanner , yyscanner );
+    yyscanner = NULL;
+    return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+{
+       register int i;
+       for ( i = 0; i < n; ++i )
+               s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
+{
+       register int n;
+       for ( n = 0; s[n]; ++n )
+               ;
+
+       return n;
+}
+#endif
+
+void *yyalloc (yy_size_t  size , yyscan_t yyscanner)
+{
+       return (void *) malloc( size );
+}
+
+void *yyrealloc  (void * ptr, yy_size_t  size , yyscan_t yyscanner)
+{
+       /* The cast to (char *) in the following accommodates both
+        * implementations that use char* generic pointers, and those
+        * that use void* generic pointers.  It works with the latter
+        * because both ANSI C and C++ allow castless assignment from
+        * any pointer type to void*, and deal with argument conversions
+        * as though doing an assignment.
+        */
+       return (void *) realloc( (char *) ptr, size );
+}
+
+void yyfree (void * ptr , yyscan_t yyscanner)
+{
+       free( (char *) ptr );   /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 493 "program_lexer.l"
+
+
+
+void
+_mesa_program_lexer_ctor(void **scanner, struct asm_parser_state *state,
+                        const char *string, size_t len)
+{
+   yylex_init_extra(state,scanner);
+   yy_scan_bytes(string,len,*scanner);
+}
+
+void
+_mesa_program_lexer_dtor(void *scanner)
+{
+   yylex_destroy(scanner);
+}
+
diff --git a/src/mesa/program/nvfragparse.c b/src/mesa/program/nvfragparse.c
new file mode 100644 (file)
index 0000000..0de3c58
--- /dev/null
@@ -0,0 +1,1588 @@
+/*
+ * 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.
+ */
+
+/**
+ * \file nvfragparse.c
+ * NVIDIA fragment program parser.
+ * \author Brian Paul
+ */
+
+/*
+ * Regarding GL_NV_fragment_program:
+ *
+ * Portions of this software may use or implement intellectual
+ * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims
+ * any and all warranties with respect to such intellectual property,
+ * including any use thereof or modifications thereto.
+ */
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/imports.h"
+#include "main/macros.h"
+#include "program.h"
+#include "prog_parameter.h"
+#include "prog_print.h"
+#include "prog_instruction.h"
+#include "nvfragparse.h"
+
+
+#define INPUT_1V     1
+#define INPUT_2V     2
+#define INPUT_3V     3
+#define INPUT_1S     4
+#define INPUT_2S     5
+#define INPUT_CC     6
+#define INPUT_1V_T   7  /* one source vector, plus textureId */
+#define INPUT_3V_T   8  /* one source vector, plus textureId */
+#define INPUT_NONE   9
+#define INPUT_1V_S  10  /* a string and a vector register */
+#define OUTPUT_V    20
+#define OUTPUT_S    21
+#define OUTPUT_NONE 22
+
+/* IRIX defines some of these */
+#undef _R
+#undef _H
+#undef _X
+#undef _C
+#undef _S
+
+/* Optional suffixes */
+#define _R  FLOAT32  /* float */
+#define _H  FLOAT16  /* half-float */
+#define _X  FIXED12  /* fixed */
+#define _C  0x08     /* set cond codes */
+#define _S  0x10     /* saturate, clamp result to [0,1] */
+
+struct instruction_pattern {
+   const char *name;
+   enum prog_opcode opcode;
+   GLuint inputs;
+   GLuint outputs;
+   GLuint suffixes;
+};
+
+static const struct instruction_pattern Instructions[] = {
+   { "ADD", OPCODE_ADD, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+   { "COS", OPCODE_COS, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
+   { "DDX", OPCODE_DDX, INPUT_1V, OUTPUT_V, _R | _H |      _C | _S },
+   { "DDY", OPCODE_DDY, INPUT_1V, OUTPUT_V, _R | _H |      _C | _S },
+   { "DP3", OPCODE_DP3, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S },
+   { "DP4", OPCODE_DP4, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S },
+   { "DST", OPCODE_DP4, INPUT_2V, OUTPUT_V, _R | _H |      _C | _S },
+   { "EX2", OPCODE_DP4, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
+   { "FLR", OPCODE_FLR, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
+   { "FRC", OPCODE_FRC, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
+   { "KIL", OPCODE_KIL_NV, INPUT_CC, OUTPUT_NONE, 0                },
+   { "LG2", OPCODE_LG2, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
+   { "LIT", OPCODE_LIT, INPUT_1V, OUTPUT_V, _R | _H |      _C | _S },
+   { "LRP", OPCODE_LRP, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S },
+   { "MAD", OPCODE_MAD, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S },
+   { "MAX", OPCODE_MAX, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+   { "MIN", OPCODE_MIN, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+   { "MOV", OPCODE_MOV, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
+   { "MUL", OPCODE_MUL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+   { "PK2H",  OPCODE_PK2H,  INPUT_1V, OUTPUT_S, 0                  },
+   { "PK2US", OPCODE_PK2US, INPUT_1V, OUTPUT_S, 0                  },
+   { "PK4B",  OPCODE_PK4B,  INPUT_1V, OUTPUT_S, 0                  },
+   { "PK4UB", OPCODE_PK4UB, INPUT_1V, OUTPUT_S, 0                  },
+   { "POW", OPCODE_POW, INPUT_2S, OUTPUT_S, _R | _H |      _C | _S },
+   { "RCP", OPCODE_RCP, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
+   { "RFL", OPCODE_RFL, INPUT_2V, OUTPUT_V, _R | _H |      _C | _S },
+   { "RSQ", OPCODE_RSQ, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
+   { "SEQ", OPCODE_SEQ, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+   { "SFL", OPCODE_SFL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+   { "SGE", OPCODE_SGE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+   { "SGT", OPCODE_SGT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+   { "SIN", OPCODE_SIN, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
+   { "SLE", OPCODE_SLE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+   { "SLT", OPCODE_SLT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+   { "SNE", OPCODE_SNE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+   { "STR", OPCODE_STR, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+   { "SUB", OPCODE_SUB, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+   { "TEX", OPCODE_TEX, INPUT_1V_T, OUTPUT_V,              _C | _S },
+   { "TXD", OPCODE_TXD, INPUT_3V_T, OUTPUT_V,              _C | _S },
+   { "TXP", OPCODE_TXP_NV, INPUT_1V_T, OUTPUT_V,           _C | _S },
+   { "UP2H",  OPCODE_UP2H,  INPUT_1S, OUTPUT_V,            _C | _S },
+   { "UP2US", OPCODE_UP2US, INPUT_1S, OUTPUT_V,            _C | _S },
+   { "UP4B",  OPCODE_UP4B,  INPUT_1S, OUTPUT_V,            _C | _S },
+   { "UP4UB", OPCODE_UP4UB, INPUT_1S, OUTPUT_V,            _C | _S },
+   { "X2D", OPCODE_X2D, INPUT_3V, OUTPUT_V, _R | _H |      _C | _S },
+   { "PRINT", OPCODE_PRINT, INPUT_1V_S, OUTPUT_NONE, 0               },
+   { NULL, (enum prog_opcode) -1, 0, 0, 0 }
+};
+
+
+/*
+ * Information needed or computed during parsing.
+ * Remember, we can't modify the target program object until we've
+ * _successfully_ parsed the program text.
+ */
+struct parse_state {
+   GLcontext *ctx;
+   const GLubyte *start;              /* start of program string */
+   const GLubyte *pos;                /* current position */
+   const GLubyte *curLine;
+   struct gl_fragment_program *program;  /* current program */
+
+   struct gl_program_parameter_list *parameters;
+
+   GLuint numInst;                    /* number of instructions parsed */
+   GLuint inputsRead;                 /* bitmask of input registers used */
+   GLuint outputsWritten;             /* bitmask of 1 << FRAG_OUTPUT_* bits */
+   GLuint texturesUsed[MAX_TEXTURE_IMAGE_UNITS];
+};
+
+
+
+/*
+ * Called whenever we find an error during parsing.
+ */
+static void
+record_error(struct parse_state *parseState, const char *msg, int lineNo)
+{
+#ifdef DEBUG
+   GLint line, column;
+   const GLubyte *lineStr;
+   lineStr = _mesa_find_line_column(parseState->start,
+                                    parseState->pos, &line, &column);
+   _mesa_debug(parseState->ctx,
+               "nvfragparse.c(%d): line %d, column %d:%s (%s)\n",
+               lineNo, line, column, (char *) lineStr, msg);
+   free((void *) lineStr);
+#else
+   (void) lineNo;
+#endif
+
+   /* Check that no error was already recorded.  Only record the first one. */
+   if (parseState->ctx->Program.ErrorString[0] == 0) {
+      _mesa_set_program_error(parseState->ctx,
+                              parseState->pos - parseState->start,
+                              msg);
+   }
+}
+
+
+#define RETURN_ERROR                                                   \
+do {                                                                   \
+   record_error(parseState, "Unexpected end of input.", __LINE__);     \
+   return GL_FALSE;                                                    \
+} while(0)
+
+#define RETURN_ERROR1(msg)                                             \
+do {                                                                   \
+   record_error(parseState, msg, __LINE__);                            \
+   return GL_FALSE;                                                    \
+} while(0)
+
+#define RETURN_ERROR2(msg1, msg2)                                      \
+do {                                                                   \
+   char err[1000];                                                     \
+   sprintf(err, "%s %s", msg1, msg2);                          \
+   record_error(parseState, err, __LINE__);                            \
+   return GL_FALSE;                                                    \
+} while(0)
+
+
+
+
+/*
+ * Search a list of instruction structures for a match.
+ */
+static struct instruction_pattern
+MatchInstruction(const GLubyte *token)
+{
+   const struct instruction_pattern *inst;
+   struct instruction_pattern result;
+
+   result.name = NULL;
+   result.opcode = MAX_OPCODE; /* i.e. invalid instruction */
+   result.inputs = 0;
+   result.outputs = 0;
+   result.suffixes = 0;
+
+   for (inst = Instructions; inst->name; inst++) {
+      if (strncmp((const char *) token, inst->name, 3) == 0) {
+         /* matched! */
+         int i = 3;
+         result = *inst;
+         result.suffixes = 0;
+         /* look at suffix */
+         if (token[i] == 'R') {
+            result.suffixes |= _R;
+            i++;
+         }
+         else if (token[i] == 'H') {
+            result.suffixes |= _H;
+            i++;
+         }
+         else if (token[i] == 'X') {
+            result.suffixes |= _X;
+            i++;
+         }
+         if (token[i] == 'C') {
+            result.suffixes |= _C;
+            i++;
+         }
+         if (token[i] == '_' && token[i+1] == 'S' &&
+             token[i+2] == 'A' && token[i+3] == 'T') {
+            result.suffixes |= _S;
+         }
+         return result;
+      }
+   }
+
+   return result;
+}
+
+
+
+
+/**********************************************************************/
+
+
+static GLboolean IsLetter(GLubyte b)
+{
+   return (b >= 'a' && b <= 'z') ||
+          (b >= 'A' && b <= 'Z') ||
+          (b == '_') ||
+          (b == '$');
+}
+
+
+static GLboolean IsDigit(GLubyte b)
+{
+   return b >= '0' && b <= '9';
+}
+
+
+static GLboolean IsWhitespace(GLubyte b)
+{
+   return b == ' ' || b == '\t' || b == '\n' || b == '\r';
+}
+
+
+/**
+ * Starting at 'str' find the next token.  A token can be an integer,
+ * an identifier or punctuation symbol.
+ * \return <= 0 we found an error, else, return number of characters parsed.
+ */
+static GLint
+GetToken(struct parse_state *parseState, GLubyte *token)
+{
+   const GLubyte *str = parseState->pos;
+   GLint i = 0, j = 0;
+
+   token[0] = 0;
+
+   /* skip whitespace and comments */
+   while (str[i] && (IsWhitespace(str[i]) || str[i] == '#')) {
+      if (str[i] == '#') {
+         /* skip comment */
+         while (str[i] && (str[i] != '\n' && str[i] != '\r')) {
+            i++;
+         }
+         if (str[i] == '\n' || str[i] == '\r')
+            parseState->curLine = str + i + 1;
+      }
+      else {
+         /* skip whitespace */
+         if (str[i] == '\n' || str[i] == '\r')
+            parseState->curLine = str + i + 1;
+         i++;
+      }
+   }
+
+   if (str[i] == 0)
+      return -i;
+
+   /* try matching an integer */
+   while (str[i] && IsDigit(str[i])) {
+      token[j++] = str[i++];
+   }
+   if (j > 0 || !str[i]) {
+      token[j] = 0;
+      return i;
+   }
+
+   /* try matching an identifier */
+   if (IsLetter(str[i])) {
+      while (str[i] && (IsLetter(str[i]) || IsDigit(str[i]))) {
+         token[j++] = str[i++];
+      }
+      token[j] = 0;
+      return i;
+   }
+
+   /* punctuation character */
+   if (str[i]) {
+      token[0] = str[i++];
+      token[1] = 0;
+      return i;
+   }
+
+   /* end of input */
+   token[0] = 0;
+   return i;
+}
+
+
+/**
+ * Get next token from input stream and increment stream pointer past token.
+ */
+static GLboolean
+Parse_Token(struct parse_state *parseState, GLubyte *token)
+{
+   GLint i;
+   i = GetToken(parseState, token);
+   if (i <= 0) {
+      parseState->pos += (-i);
+      return GL_FALSE;
+   }
+   parseState->pos += i;
+   return GL_TRUE;
+}
+
+
+/**
+ * Get next token from input stream but don't increment stream pointer.
+ */
+static GLboolean
+Peek_Token(struct parse_state *parseState, GLubyte *token)
+{
+   GLint i, len;
+   i = GetToken(parseState, token);
+   if (i <= 0) {
+      parseState->pos += (-i);
+      return GL_FALSE;
+   }
+   len = (GLint) strlen((const char *) token);
+   parseState->pos += (i - len);
+   return GL_TRUE;
+}
+
+
+/**********************************************************************/
+
+static const char *InputRegisters[MAX_NV_FRAGMENT_PROGRAM_INPUTS + 1] = {
+   "WPOS", "COL0", "COL1", "FOGC",
+   "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL
+};
+
+
+
+/**********************************************************************/
+
+/**
+ * Try to match 'pattern' as the next token after any whitespace/comments.
+ */
+static GLboolean
+Parse_String(struct parse_state *parseState, const char *pattern)
+{
+   const GLubyte *m;
+   GLint i;
+
+   /* skip whitespace and comments */
+   while (IsWhitespace(*parseState->pos) || *parseState->pos == '#') {
+      if (*parseState->pos == '#') {
+         while (*parseState->pos && (*parseState->pos != '\n' && *parseState->pos != '\r')) {
+            parseState->pos += 1;
+         }
+         if (*parseState->pos == '\n' || *parseState->pos == '\r')
+            parseState->curLine = parseState->pos + 1;
+      }
+      else {
+         /* skip whitespace */
+         if (*parseState->pos == '\n' || *parseState->pos == '\r')
+            parseState->curLine = parseState->pos + 1;
+         parseState->pos += 1;
+      }
+   }
+
+   /* Try to match the pattern */
+   m = parseState->pos;
+   for (i = 0; pattern[i]; i++) {
+      if (*m != (GLubyte) pattern[i])
+         return GL_FALSE;
+      m += 1;
+   }
+   parseState->pos = m;
+
+   return GL_TRUE; /* success */
+}
+
+
+static GLboolean
+Parse_Identifier(struct parse_state *parseState, GLubyte *ident)
+{
+   if (!Parse_Token(parseState, ident))
+      RETURN_ERROR;
+   if (IsLetter(ident[0]))
+      return GL_TRUE;
+   else
+      RETURN_ERROR1("Expected an identfier");
+}
+
+
+/**
+ * Parse a floating point constant, or a defined symbol name.
+ * [+/-]N[.N[eN]]
+ * Output:  number[0 .. 3] will get the value.
+ */
+static GLboolean
+Parse_ScalarConstant(struct parse_state *parseState, GLfloat *number)
+{
+   char *end = NULL;
+
+   *number = (GLfloat) _mesa_strtof((const char *) parseState->pos, &end);
+
+   if (end && end > (char *) parseState->pos) {
+      /* got a number */
+      parseState->pos = (GLubyte *) end;
+      number[1] = *number;
+      number[2] = *number;
+      number[3] = *number;
+      return GL_TRUE;
+   }
+   else {
+      /* should be an identifier */
+      GLubyte ident[100];
+      const GLfloat *constant;
+      if (!Parse_Identifier(parseState, ident))
+         RETURN_ERROR1("Expected an identifier");
+      constant = _mesa_lookup_parameter_value(parseState->parameters,
+                                              -1, (const char *) ident);
+      /* XXX Check that it's a constant and not a parameter */
+      if (!constant) {
+         RETURN_ERROR1("Undefined symbol");
+      }
+      else {
+         COPY_4V(number, constant);
+         return GL_TRUE;
+      }
+   }
+}
+
+
+
+/**
+ * Parse a vector constant, one of:
+ *   { float }
+ *   { float, float }
+ *   { float, float, float }
+ *   { float, float, float, float }
+ */
+static GLboolean
+Parse_VectorConstant(struct parse_state *parseState, GLfloat *vec)
+{
+   /* "{" was already consumed */
+
+   ASSIGN_4V(vec, 0.0, 0.0, 0.0, 1.0);
+
+   if (!Parse_ScalarConstant(parseState, vec+0))  /* X */
+      return GL_FALSE;
+
+   if (Parse_String(parseState, "}")) {
+      return GL_TRUE;
+   }
+
+   if (!Parse_String(parseState, ","))
+      RETURN_ERROR1("Expected comma in vector constant");
+
+   if (!Parse_ScalarConstant(parseState, vec+1))  /* Y */
+      return GL_FALSE;
+
+   if (Parse_String(parseState, "}")) {
+      return GL_TRUE;
+   }
+
+   if (!Parse_String(parseState, ","))
+      RETURN_ERROR1("Expected comma in vector constant");
+
+   if (!Parse_ScalarConstant(parseState, vec+2))  /* Z */
+      return GL_FALSE;
+
+   if (Parse_String(parseState, "}")) {
+      return GL_TRUE;
+   }
+
+   if (!Parse_String(parseState, ","))
+      RETURN_ERROR1("Expected comma in vector constant");
+
+   if (!Parse_ScalarConstant(parseState, vec+3))  /* W */
+      return GL_FALSE;
+
+   if (!Parse_String(parseState, "}"))
+      RETURN_ERROR1("Expected closing brace in vector constant");
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Parse <number>, <varname> or {a, b, c, d}.
+ * Return number of values in the vector or scalar, or zero if parse error.
+ */
+static GLuint
+Parse_VectorOrScalarConstant(struct parse_state *parseState, GLfloat *vec)
+{
+   if (Parse_String(parseState, "{")) {
+      return Parse_VectorConstant(parseState, vec);
+   }
+   else {
+      GLboolean b = Parse_ScalarConstant(parseState, vec);
+      if (b) {
+         vec[1] = vec[2] = vec[3] = vec[0];
+      }
+      return b;
+   }
+}
+
+
+/**
+ * Parse a texture image source:
+ *    [TEX0 | TEX1 | .. | TEX15] , [1D | 2D | 3D | CUBE | RECT]
+ */
+static GLboolean
+Parse_TextureImageId(struct parse_state *parseState,
+                     GLubyte *texUnit, GLubyte *texTargetBit)
+{
+   GLubyte imageSrc[100];
+   GLint unit;
+
+   if (!Parse_Token(parseState, imageSrc))
+      RETURN_ERROR;
+   
+   if (imageSrc[0] != 'T' ||
+       imageSrc[1] != 'E' ||
+       imageSrc[2] != 'X') {
+      RETURN_ERROR1("Expected TEX# source");
+   }
+   unit = atoi((const char *) imageSrc + 3);
+   if ((unit < 0 || unit > MAX_TEXTURE_IMAGE_UNITS) ||
+       (unit == 0 && (imageSrc[3] != '0' || imageSrc[4] != 0))) {
+      RETURN_ERROR1("Invalied TEX# source index");
+   }
+   *texUnit = unit;
+
+   if (!Parse_String(parseState, ","))
+      RETURN_ERROR1("Expected ,");
+
+   if (Parse_String(parseState, "1D")) {
+      *texTargetBit = TEXTURE_1D_BIT;
+   }
+   else if (Parse_String(parseState, "2D")) {
+      *texTargetBit = TEXTURE_2D_BIT;
+   }
+   else if (Parse_String(parseState, "3D")) {
+      *texTargetBit = TEXTURE_3D_BIT;
+   }
+   else if (Parse_String(parseState, "CUBE")) {
+      *texTargetBit = TEXTURE_CUBE_BIT;
+   }
+   else if (Parse_String(parseState, "RECT")) {
+      *texTargetBit = TEXTURE_RECT_BIT;
+   }
+   else {
+      RETURN_ERROR1("Invalid texture target token");
+   }
+
+   /* update record of referenced texture units */
+   parseState->texturesUsed[*texUnit] |= *texTargetBit;
+   if (_mesa_bitcount(parseState->texturesUsed[*texUnit]) > 1) {
+      RETURN_ERROR1("Only one texture target can be used per texture unit.");
+   }
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Parse a scalar suffix like .x, .y, .z or .w or parse a swizzle suffix
+ * like .wxyz, .xxyy, etc and return the swizzle indexes.
+ */
+static GLboolean
+Parse_SwizzleSuffix(const GLubyte *token, GLuint swizzle[4])
+{
+   if (token[1] == 0) {
+      /* single letter swizzle (scalar) */
+      if (token[0] == 'x')
+         ASSIGN_4V(swizzle, 0, 0, 0, 0);
+      else if (token[0] == 'y')
+         ASSIGN_4V(swizzle, 1, 1, 1, 1);
+      else if (token[0] == 'z')
+         ASSIGN_4V(swizzle, 2, 2, 2, 2);
+      else if (token[0] == 'w')
+         ASSIGN_4V(swizzle, 3, 3, 3, 3);
+      else
+         return GL_FALSE;
+   }
+   else {
+      /* 4-component swizzle (vector) */
+      GLint k;
+      for (k = 0; k < 4 && token[k]; k++) {
+         if (token[k] == 'x')
+            swizzle[k] = 0;
+         else if (token[k] == 'y')
+            swizzle[k] = 1;
+         else if (token[k] == 'z')
+            swizzle[k] = 2;
+         else if (token[k] == 'w')
+            swizzle[k] = 3;
+         else
+            return GL_FALSE;
+      }
+      if (k != 4)
+         return GL_FALSE;
+   }
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_CondCodeMask(struct parse_state *parseState,
+                   struct prog_dst_register *dstReg)
+{
+   if (Parse_String(parseState, "EQ"))
+      dstReg->CondMask = COND_EQ;
+   else if (Parse_String(parseState, "GE"))
+      dstReg->CondMask = COND_GE;
+   else if (Parse_String(parseState, "GT"))
+      dstReg->CondMask = COND_GT;
+   else if (Parse_String(parseState, "LE"))
+      dstReg->CondMask = COND_LE;
+   else if (Parse_String(parseState, "LT"))
+      dstReg->CondMask = COND_LT;
+   else if (Parse_String(parseState, "NE"))
+      dstReg->CondMask = COND_NE;
+   else if (Parse_String(parseState, "TR"))
+      dstReg->CondMask = COND_TR;
+   else if (Parse_String(parseState, "FL"))
+      dstReg->CondMask = COND_FL;
+   else
+      RETURN_ERROR1("Invalid condition code mask");
+
+   /* look for optional .xyzw swizzle */
+   if (Parse_String(parseState, ".")) {
+      GLubyte token[100];
+      GLuint swz[4];
+
+      if (!Parse_Token(parseState, token))  /* get xyzw suffix */
+         RETURN_ERROR;
+
+      if (!Parse_SwizzleSuffix(token, swz))
+         RETURN_ERROR1("Invalid swizzle suffix");
+
+      dstReg->CondSwizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
+   }
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Parse a temporary register: Rnn or Hnn
+ */
+static GLboolean
+Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum)
+{
+   GLubyte token[100];
+
+   /* Should be 'R##' or 'H##' */
+   if (!Parse_Token(parseState, token))
+      RETURN_ERROR;
+   if (token[0] != 'R' && token[0] != 'H')
+      RETURN_ERROR1("Expected R## or H##");
+
+   if (IsDigit(token[1])) {
+      GLint reg = atoi((const char *) (token + 1));
+      if (token[0] == 'H')
+         reg += 32;
+      if (reg >= MAX_NV_FRAGMENT_PROGRAM_TEMPS)
+         RETURN_ERROR1("Invalid temporary register name");
+      *tempRegNum = reg;
+   }
+   else {
+      RETURN_ERROR1("Invalid temporary register name");
+   }
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Parse a write-only dummy register: RC or HC.
+ */
+static GLboolean
+Parse_DummyReg(struct parse_state *parseState, GLint *regNum)
+{
+   if (Parse_String(parseState, "RC")) {
+       *regNum = 0;
+   }
+   else if (Parse_String(parseState, "HC")) {
+       *regNum = 1;
+   }
+   else {
+      RETURN_ERROR1("Invalid write-only register name");
+   }
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Parse a program local parameter register "p[##]"
+ */
+static GLboolean
+Parse_ProgramParamReg(struct parse_state *parseState, GLint *regNum)
+{
+   GLubyte token[100];
+
+   if (!Parse_String(parseState, "p["))
+      RETURN_ERROR1("Expected p[");
+
+   if (!Parse_Token(parseState, token))
+      RETURN_ERROR;
+
+   if (IsDigit(token[0])) {
+      /* a numbered program parameter register */
+      GLint reg = atoi((const char *) token);
+      if (reg >= MAX_NV_FRAGMENT_PROGRAM_PARAMS)
+         RETURN_ERROR1("Invalid constant program number");
+      *regNum = reg;
+   }
+   else {
+      RETURN_ERROR;
+   }
+
+   if (!Parse_String(parseState, "]"))
+      RETURN_ERROR1("Expected ]");
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Parse f[name]  - fragment input register
+ */
+static GLboolean
+Parse_FragReg(struct parse_state *parseState, GLint *tempRegNum)
+{
+   GLubyte token[100];
+   GLint j;
+
+   /* Match 'f[' */
+   if (!Parse_String(parseState, "f["))
+      RETURN_ERROR1("Expected f[");
+
+   /* get <name> and look for match */
+   if (!Parse_Token(parseState, token)) {
+      RETURN_ERROR;
+   }
+   for (j = 0; InputRegisters[j]; j++) {
+      if (strcmp((const char *) token, InputRegisters[j]) == 0) {
+         *tempRegNum = j;
+         parseState->inputsRead |= (1 << j);
+         break;
+      }
+   }
+   if (!InputRegisters[j]) {
+      /* unknown input register label */
+      RETURN_ERROR2("Invalid register name", token);
+   }
+
+   /* Match '[' */
+   if (!Parse_String(parseState, "]"))
+      RETURN_ERROR1("Expected ]");
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum)
+{
+   GLubyte token[100];
+
+   /* Match "o[" */
+   if (!Parse_String(parseState, "o["))
+      RETURN_ERROR1("Expected o[");
+
+   /* Get output reg name */
+   if (!Parse_Token(parseState, token))
+      RETURN_ERROR;
+
+   /* try to match an output register name */
+   if (strcmp((char *) token, "COLR") == 0 ||
+       strcmp((char *) token, "COLH") == 0) {
+      /* note that we don't distinguish between COLR and COLH */
+      *outputRegNum = FRAG_RESULT_COLOR;
+      parseState->outputsWritten |= (1 << FRAG_RESULT_COLOR);
+   }
+   else if (strcmp((char *) token, "DEPR") == 0) {
+      *outputRegNum = FRAG_RESULT_DEPTH;
+      parseState->outputsWritten |= (1 << FRAG_RESULT_DEPTH);
+   }
+   else {
+      RETURN_ERROR1("Invalid output register name");
+   }
+
+   /* Match ']' */
+   if (!Parse_String(parseState, "]"))
+      RETURN_ERROR1("Expected ]");
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_MaskedDstReg(struct parse_state *parseState,
+                   struct prog_dst_register *dstReg)
+{
+   GLubyte token[100];
+   GLint idx;
+
+   /* Dst reg can be R<n>, H<n>, o[n], RC or HC */
+   if (!Peek_Token(parseState, token))
+      RETURN_ERROR;
+
+   if (strcmp((const char *) token, "RC") == 0 ||
+       strcmp((const char *) token, "HC") == 0) {
+      /* a write-only register */
+      dstReg->File = PROGRAM_WRITE_ONLY;
+      if (!Parse_DummyReg(parseState, &idx))
+         RETURN_ERROR;
+      dstReg->Index = idx;
+   }
+   else if (token[0] == 'R' || token[0] == 'H') {
+      /* a temporary register */
+      dstReg->File = PROGRAM_TEMPORARY;
+      if (!Parse_TempReg(parseState, &idx))
+         RETURN_ERROR;
+      dstReg->Index = idx;
+   }
+   else if (token[0] == 'o') {
+      /* an output register */
+      dstReg->File = PROGRAM_OUTPUT;
+      if (!Parse_OutputReg(parseState, &idx))
+         RETURN_ERROR;
+      dstReg->Index = idx;
+   }
+   else {
+      RETURN_ERROR1("Invalid destination register name");
+   }
+
+   /* Parse optional write mask */
+   if (Parse_String(parseState, ".")) {
+      /* got a mask */
+      GLint k = 0;
+
+      if (!Parse_Token(parseState, token))  /* get xyzw writemask */
+         RETURN_ERROR;
+
+      dstReg->WriteMask = 0;
+
+      if (token[k] == 'x') {
+         dstReg->WriteMask |= WRITEMASK_X;
+         k++;
+      }
+      if (token[k] == 'y') {
+         dstReg->WriteMask |= WRITEMASK_Y;
+         k++;
+      }
+      if (token[k] == 'z') {
+         dstReg->WriteMask |= WRITEMASK_Z;
+         k++;
+      }
+      if (token[k] == 'w') {
+         dstReg->WriteMask |= WRITEMASK_W;
+         k++;
+      }
+      if (k == 0) {
+         RETURN_ERROR1("Invalid writemask character");
+      }
+
+   }
+   else {
+      dstReg->WriteMask = WRITEMASK_XYZW;
+   }
+
+   /* optional condition code mask */
+   if (Parse_String(parseState, "(")) {
+      /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".x|y|z|w) */
+      /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".[xyzw]) */
+      if (!Parse_CondCodeMask(parseState, dstReg))
+         RETURN_ERROR;
+
+      if (!Parse_String(parseState, ")"))  /* consume ")" */
+         RETURN_ERROR1("Expected )");
+
+      return GL_TRUE;
+   }
+   else {
+      /* no cond code mask */
+      dstReg->CondMask = COND_TR;
+      dstReg->CondSwizzle = SWIZZLE_NOOP;
+      return GL_TRUE;
+   }
+}
+
+
+/**
+ * Parse a vector source (register, constant, etc):
+ *   <vectorSrc>    ::= <absVectorSrc>
+ *                    | <baseVectorSrc>
+ *   <absVectorSrc> ::= <negate> "|" <baseVectorSrc> "|"
+ */
+static GLboolean
+Parse_VectorSrc(struct parse_state *parseState,
+                struct prog_src_register *srcReg)
+{
+   GLfloat sign = 1.0F;
+   GLubyte token[100];
+   GLint idx;
+   GLuint negateBase, negateAbs;
+
+   /*
+    * First, take care of +/- and absolute value stuff.
+    */
+   if (Parse_String(parseState, "-"))
+      sign = -1.0F;
+   else if (Parse_String(parseState, "+"))
+      sign = +1.0F;
+
+   if (Parse_String(parseState, "|")) {
+      srcReg->Abs = GL_TRUE;
+      negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
+
+      if (Parse_String(parseState, "-"))
+         negateBase = NEGATE_XYZW;
+      else if (Parse_String(parseState, "+"))
+         negateBase = NEGATE_NONE;
+      else
+         negateBase = NEGATE_NONE;
+   }
+   else {
+      srcReg->Abs = GL_FALSE;
+      negateAbs = NEGATE_NONE;
+      negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
+   }
+
+   srcReg->Negate = srcReg->Abs ? negateAbs : negateBase;
+
+   /* This should be the real src vector/register name */
+   if (!Peek_Token(parseState, token))
+      RETURN_ERROR;
+
+   /* Src reg can be Rn, Hn, f[n], p[n], a named parameter, a scalar
+    * literal or vector literal.
+    */
+   if (token[0] == 'R' || token[0] == 'H') {
+      srcReg->File = PROGRAM_TEMPORARY;
+      if (!Parse_TempReg(parseState, &idx))
+         RETURN_ERROR;
+      srcReg->Index = idx;
+   }
+   else if (token[0] == 'f') {
+      /* XXX this might be an identifier! */
+      srcReg->File = PROGRAM_INPUT;
+      if (!Parse_FragReg(parseState, &idx))
+         RETURN_ERROR;
+      srcReg->Index = idx;
+   }
+   else if (token[0] == 'p') {
+      /* XXX this might be an identifier! */
+      srcReg->File = PROGRAM_LOCAL_PARAM;
+      if (!Parse_ProgramParamReg(parseState, &idx))
+         RETURN_ERROR;
+      srcReg->Index = idx;
+   }
+   else if (IsLetter(token[0])){
+      GLubyte ident[100];
+      GLint paramIndex;
+      if (!Parse_Identifier(parseState, ident))
+         RETURN_ERROR;
+      paramIndex = _mesa_lookup_parameter_index(parseState->parameters,
+                                                -1, (const char *) ident);
+      if (paramIndex < 0) {
+         RETURN_ERROR2("Undefined constant or parameter: ", ident);
+      }
+      srcReg->File = PROGRAM_NAMED_PARAM;
+      srcReg->Index = paramIndex;      
+   }
+   else if (IsDigit(token[0]) || token[0] == '-' || token[0] == '+' || token[0] == '.'){
+      /* literal scalar constant */
+      GLfloat values[4];
+      GLuint paramIndex;
+      if (!Parse_ScalarConstant(parseState, values))
+         RETURN_ERROR;
+      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
+                                              values, 4, NULL);
+      srcReg->File = PROGRAM_NAMED_PARAM;
+      srcReg->Index = paramIndex;
+   }
+   else if (token[0] == '{'){
+      /* literal vector constant */
+      GLfloat values[4];
+      GLuint paramIndex;
+      (void) Parse_String(parseState, "{");
+      if (!Parse_VectorConstant(parseState, values))
+         RETURN_ERROR;
+      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
+                                              values, 4, NULL);
+      srcReg->File = PROGRAM_NAMED_PARAM;
+      srcReg->Index = paramIndex;      
+   }
+   else {
+      RETURN_ERROR2("Invalid source register name", token);
+   }
+
+   /* init swizzle fields */
+   srcReg->Swizzle = SWIZZLE_NOOP;
+
+   /* Look for optional swizzle suffix */
+   if (Parse_String(parseState, ".")) {
+      GLuint swz[4];
+
+      if (!Parse_Token(parseState, token))
+         RETURN_ERROR;
+
+      if (!Parse_SwizzleSuffix(token, swz))
+         RETURN_ERROR1("Invalid swizzle suffix");
+
+      srcReg->Swizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
+   }
+
+   /* Finish absolute value */
+   if (srcReg->Abs && !Parse_String(parseState, "|")) {
+      RETURN_ERROR1("Expected |");
+   }
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_ScalarSrcReg(struct parse_state *parseState,
+                   struct prog_src_register *srcReg)
+{
+   GLubyte token[100];
+   GLfloat sign = 1.0F;
+   GLboolean needSuffix = GL_TRUE;
+   GLint idx;
+   GLuint negateBase, negateAbs;
+
+   /*
+    * First, take care of +/- and absolute value stuff.
+    */
+   if (Parse_String(parseState, "-"))
+      sign = -1.0F;
+   else if (Parse_String(parseState, "+"))
+      sign = +1.0F;
+
+   if (Parse_String(parseState, "|")) {
+      srcReg->Abs = GL_TRUE;
+      negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
+
+      if (Parse_String(parseState, "-"))
+         negateBase = NEGATE_XYZW;
+      else if (Parse_String(parseState, "+"))
+         negateBase = NEGATE_NONE;
+      else
+         negateBase = NEGATE_NONE;
+   }
+   else {
+      srcReg->Abs = GL_FALSE;
+      negateAbs = NEGATE_NONE;
+      negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
+   }
+
+   srcReg->Negate = srcReg->Abs ? negateAbs : negateBase;
+
+   if (!Peek_Token(parseState, token))
+      RETURN_ERROR;
+
+   /* Src reg can be R<n>, H<n> or a named fragment attrib */
+   if (token[0] == 'R' || token[0] == 'H') {
+      srcReg->File = PROGRAM_TEMPORARY;
+      if (!Parse_TempReg(parseState, &idx))
+         RETURN_ERROR;
+      srcReg->Index = idx;
+   }
+   else if (token[0] == 'f') {
+      srcReg->File = PROGRAM_INPUT;
+      if (!Parse_FragReg(parseState, &idx))
+         RETURN_ERROR;
+      srcReg->Index = idx;
+   }
+   else if (token[0] == '{') {
+      /* vector literal */
+      GLfloat values[4];
+      GLuint paramIndex;
+      (void) Parse_String(parseState, "{");
+      if (!Parse_VectorConstant(parseState, values))
+         RETURN_ERROR;
+      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
+                                              values, 4, NULL);
+      srcReg->File = PROGRAM_NAMED_PARAM;
+      srcReg->Index = paramIndex;      
+   }
+   else if (IsLetter(token[0])){
+      /* named param/constant */
+      GLubyte ident[100];
+      GLint paramIndex;
+      if (!Parse_Identifier(parseState, ident))
+         RETURN_ERROR;
+      paramIndex = _mesa_lookup_parameter_index(parseState->parameters,
+                                                -1, (const char *) ident);
+      if (paramIndex < 0) {
+         RETURN_ERROR2("Undefined constant or parameter: ", ident);
+      }
+      srcReg->File = PROGRAM_NAMED_PARAM;
+      srcReg->Index = paramIndex;      
+   }
+   else if (IsDigit(token[0])) {
+      /* scalar literal */
+      GLfloat values[4];
+      GLuint paramIndex;
+      if (!Parse_ScalarConstant(parseState, values))
+         RETURN_ERROR;
+      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
+                                              values, 4, NULL);
+      srcReg->Index = paramIndex;      
+      srcReg->File = PROGRAM_NAMED_PARAM;
+      needSuffix = GL_FALSE;
+   }
+   else {
+      RETURN_ERROR2("Invalid scalar source argument", token);
+   }
+
+   srcReg->Swizzle = 0;
+   if (needSuffix) {
+      /* parse .[xyzw] suffix */
+      if (!Parse_String(parseState, "."))
+         RETURN_ERROR1("Expected .");
+
+      if (!Parse_Token(parseState, token))
+         RETURN_ERROR;
+
+      if (token[0] == 'x' && token[1] == 0) {
+         srcReg->Swizzle = 0;
+      }
+      else if (token[0] == 'y' && token[1] == 0) {
+         srcReg->Swizzle = 1;
+      }
+      else if (token[0] == 'z' && token[1] == 0) {
+         srcReg->Swizzle = 2;
+      }
+      else if (token[0] == 'w' && token[1] == 0) {
+         srcReg->Swizzle = 3;
+      }
+      else {
+         RETURN_ERROR1("Invalid scalar source suffix");
+      }
+   }
+
+   /* Finish absolute value */
+   if (srcReg->Abs && !Parse_String(parseState, "|")) {
+      RETURN_ERROR1("Expected |");
+   }
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_PrintInstruction(struct parse_state *parseState,
+                       struct prog_instruction *inst)
+{
+   const GLubyte *str;
+   GLubyte *msg;
+   GLuint len;
+   GLint idx;
+
+   /* The first argument is a literal string 'just like this' */
+   if (!Parse_String(parseState, "'"))
+      RETURN_ERROR1("Expected '");
+
+   str = parseState->pos;
+   for (len = 0; str[len] != '\''; len++) /* find closing quote */
+      ;
+   parseState->pos += len + 1;
+   msg = (GLubyte*) malloc(len + 1);
+
+   memcpy(msg, str, len);
+   msg[len] = 0;
+   inst->Data = msg;
+
+   if (Parse_String(parseState, ",")) {
+      /* got an optional register to print */
+      GLubyte token[100];
+      GetToken(parseState, token);
+      if (token[0] == 'o') {
+         /* dst reg */
+         if (!Parse_OutputReg(parseState, &idx))
+            RETURN_ERROR;
+        inst->SrcReg[0].Index = idx;
+         inst->SrcReg[0].File = PROGRAM_OUTPUT;
+      }
+      else {
+         /* src reg */
+         if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
+            RETURN_ERROR;
+      }
+   }
+   else {
+      inst->SrcReg[0].File = PROGRAM_UNDEFINED;
+   }
+
+   inst->SrcReg[0].Swizzle = SWIZZLE_NOOP;
+   inst->SrcReg[0].Abs = GL_FALSE;
+   inst->SrcReg[0].Negate = NEGATE_NONE;
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_InstructionSequence(struct parse_state *parseState,
+                          struct prog_instruction program[])
+{
+   while (1) {
+      struct prog_instruction *inst = program + parseState->numInst;
+      struct instruction_pattern instMatch;
+      GLubyte token[100];
+
+      /* Initialize the instruction */
+      _mesa_init_instructions(inst, 1);
+
+      /* special instructions */
+      if (Parse_String(parseState, "DEFINE")) {
+         GLubyte id[100];
+         GLfloat value[7];  /* yes, 7 to be safe */
+         if (!Parse_Identifier(parseState, id))
+            RETURN_ERROR;
+         /* XXX make sure id is not a reserved identifer, like R9 */
+         if (!Parse_String(parseState, "="))
+            RETURN_ERROR1("Expected =");
+         if (!Parse_VectorOrScalarConstant(parseState, value))
+            RETURN_ERROR;
+         if (!Parse_String(parseState, ";"))
+            RETURN_ERROR1("Expected ;");
+         if (_mesa_lookup_parameter_index(parseState->parameters,
+                                          -1, (const char *) id) >= 0) {
+            RETURN_ERROR2(id, "already defined");
+         }
+         _mesa_add_named_parameter(parseState->parameters,
+                                   (const char *) id, value);
+      }
+      else if (Parse_String(parseState, "DECLARE")) {
+         GLubyte id[100];
+         GLfloat value[7] = {0, 0, 0, 0, 0, 0, 0};  /* yes, to be safe */
+         if (!Parse_Identifier(parseState, id))
+            RETURN_ERROR;
+         /* XXX make sure id is not a reserved identifer, like R9 */
+         if (Parse_String(parseState, "=")) {
+            if (!Parse_VectorOrScalarConstant(parseState, value))
+               RETURN_ERROR;
+         }
+         if (!Parse_String(parseState, ";"))
+            RETURN_ERROR1("Expected ;");
+         if (_mesa_lookup_parameter_index(parseState->parameters,
+                                          -1, (const char *) id) >= 0) {
+            RETURN_ERROR2(id, "already declared");
+         }
+         _mesa_add_named_parameter(parseState->parameters,
+                                   (const char *) id, value);
+      }
+      else if (Parse_String(parseState, "END")) {
+         inst->Opcode = OPCODE_END;
+         parseState->numInst++;
+         if (Parse_Token(parseState, token)) {
+            RETURN_ERROR1("Code after END opcode.");
+         }
+         break;
+      }
+      else {
+         /* general/arithmetic instruction */
+
+         /* get token */
+         if (!Parse_Token(parseState, token)) {
+            RETURN_ERROR1("Missing END instruction.");
+         }
+
+         /* try to find matching instuction */
+         instMatch = MatchInstruction(token);
+         if (instMatch.opcode >= MAX_OPCODE) {
+            /* bad instruction name */
+            RETURN_ERROR2("Unexpected token: ", token);
+         }
+
+         inst->Opcode = instMatch.opcode;
+         inst->Precision = instMatch.suffixes & (_R | _H | _X);
+         inst->SaturateMode = (instMatch.suffixes & (_S))
+            ? SATURATE_ZERO_ONE : SATURATE_OFF;
+         inst->CondUpdate = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE;
+
+         /*
+          * parse the input and output operands
+          */
+         if (instMatch.outputs == OUTPUT_S || instMatch.outputs == OUTPUT_V) {
+            if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
+               RETURN_ERROR;
+            if (!Parse_String(parseState, ","))
+               RETURN_ERROR1("Expected ,");
+         }
+         else if (instMatch.outputs == OUTPUT_NONE) {
+            if (instMatch.opcode == OPCODE_KIL_NV) {
+               /* This is a little weird, the cond code info is in
+                * the dest register.
+                */
+               if (!Parse_CondCodeMask(parseState, &inst->DstReg))
+                  RETURN_ERROR;
+            }
+            else {
+               ASSERT(instMatch.opcode == OPCODE_PRINT);
+            }
+         }
+
+         if (instMatch.inputs == INPUT_1V) {
+            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
+               RETURN_ERROR;
+         }
+         else if (instMatch.inputs == INPUT_2V) {
+            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
+               RETURN_ERROR;
+            if (!Parse_String(parseState, ","))
+               RETURN_ERROR1("Expected ,");
+            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
+               RETURN_ERROR;
+         }
+         else if (instMatch.inputs == INPUT_3V) {
+            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
+               RETURN_ERROR;
+            if (!Parse_String(parseState, ","))
+               RETURN_ERROR1("Expected ,");
+            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
+               RETURN_ERROR;
+            if (!Parse_String(parseState, ","))
+               RETURN_ERROR1("Expected ,");
+            if (!Parse_VectorSrc(parseState, &inst->SrcReg[2]))
+               RETURN_ERROR;
+         }
+         else if (instMatch.inputs == INPUT_1S) {
+            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
+               RETURN_ERROR;
+         }
+         else if (instMatch.inputs == INPUT_2S) {
+            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
+               RETURN_ERROR;
+            if (!Parse_String(parseState, ","))
+               RETURN_ERROR1("Expected ,");
+            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[1]))
+               RETURN_ERROR;
+         }
+         else if (instMatch.inputs == INPUT_CC) {
+            /* XXX to-do */
+         }
+         else if (instMatch.inputs == INPUT_1V_T) {
+           GLubyte unit, idx;
+            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
+               RETURN_ERROR;
+            if (!Parse_String(parseState, ","))
+               RETURN_ERROR1("Expected ,");
+            if (!Parse_TextureImageId(parseState, &unit, &idx))
+               RETURN_ERROR;
+           inst->TexSrcUnit = unit;
+           inst->TexSrcTarget = idx;
+         }
+         else if (instMatch.inputs == INPUT_3V_T) {
+           GLubyte unit, idx;
+            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
+               RETURN_ERROR;
+            if (!Parse_String(parseState, ","))
+               RETURN_ERROR1("Expected ,");
+            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
+               RETURN_ERROR;
+            if (!Parse_String(parseState, ","))
+               RETURN_ERROR1("Expected ,");
+            if (!Parse_VectorSrc(parseState, &inst->SrcReg[2]))
+               RETURN_ERROR;
+            if (!Parse_String(parseState, ","))
+               RETURN_ERROR1("Expected ,");
+            if (!Parse_TextureImageId(parseState, &unit, &idx))
+               RETURN_ERROR;
+           inst->TexSrcUnit = unit;
+           inst->TexSrcTarget = idx;
+         }
+         else if (instMatch.inputs == INPUT_1V_S) {
+            if (!Parse_PrintInstruction(parseState, inst))
+               RETURN_ERROR;
+         }
+
+         /* end of statement semicolon */
+         if (!Parse_String(parseState, ";"))
+            RETURN_ERROR1("Expected ;");
+
+         parseState->numInst++;
+
+         if (parseState->numInst >= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS)
+            RETURN_ERROR1("Program too long");
+      }
+   }
+   return GL_TRUE;
+}
+
+
+
+/**
+ * Parse/compile the 'str' returning the compiled 'program'.
+ * ctx->Program.ErrorPos will be -1 if successful.  Otherwise, ErrorPos
+ * indicates the position of the error in 'str'.
+ */
+void
+_mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,
+                                const GLubyte *str, GLsizei len,
+                                struct gl_fragment_program *program)
+{
+   struct parse_state parseState;
+   struct prog_instruction instBuffer[MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS];
+   struct prog_instruction *newInst;
+   GLenum target;
+   GLubyte *programString;
+
+   /* Make a null-terminated copy of the program string */
+   programString = (GLubyte *) MALLOC(len + 1);
+   if (!programString) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
+      return;
+   }
+   memcpy(programString, str, len);
+   programString[len] = 0;
+
+   /* Get ready to parse */
+   memset(&parseState, 0, sizeof(struct parse_state));
+   parseState.ctx = ctx;
+   parseState.start = programString;
+   parseState.program = program;
+   parseState.numInst = 0;
+   parseState.curLine = programString;
+   parseState.parameters = _mesa_new_parameter_list();
+
+   /* Reset error state */
+   _mesa_set_program_error(ctx, -1, NULL);
+
+   /* check the program header */
+   if (strncmp((const char *) programString, "!!FP1.0", 7) == 0) {
+      target = GL_FRAGMENT_PROGRAM_NV;
+      parseState.pos = programString + 7;
+   }
+   else if (strncmp((const char *) programString, "!!FCP1.0", 8) == 0) {
+      /* fragment / register combiner program - not supported */
+      _mesa_set_program_error(ctx, 0, "Invalid fragment program header");
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
+      return;
+   }
+   else {
+      /* invalid header */
+      _mesa_set_program_error(ctx, 0, "Invalid fragment program header");
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
+      return;
+   }
+
+   /* make sure target and header match */
+   if (target != dstTarget) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glLoadProgramNV(target mismatch 0x%x != 0x%x)",
+                  target, dstTarget);
+      return;
+   }
+
+   if (Parse_InstructionSequence(&parseState, instBuffer)) {
+      GLuint u;
+      /* successful parse! */
+
+      if (parseState.outputsWritten == 0) {
+         /* must write at least one output! */
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "Invalid fragment program - no outputs written.");
+         return;
+      }
+
+      /* copy the compiled instructions */
+      assert(parseState.numInst <= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS);
+      newInst = _mesa_alloc_instructions(parseState.numInst);
+      if (!newInst) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
+         return;  /* out of memory */
+      }
+      _mesa_copy_instructions(newInst, instBuffer, parseState.numInst);
+
+      /* install the program */
+      program->Base.Target = target;
+      if (program->Base.String) {
+         FREE(program->Base.String);
+      }
+      program->Base.String = programString;
+      program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;
+      if (program->Base.Instructions) {
+         free(program->Base.Instructions);
+      }
+      program->Base.Instructions = newInst;
+      program->Base.NumInstructions = parseState.numInst;
+      program->Base.InputsRead = parseState.inputsRead;
+      program->Base.OutputsWritten = parseState.outputsWritten;
+      for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++)
+         program->Base.TexturesUsed[u] = parseState.texturesUsed[u];
+
+      /* save program parameters */
+      program->Base.Parameters = parseState.parameters;
+
+      /* allocate registers for declared program parameters */
+#if 00
+      _mesa_assign_program_registers(&(program->SymbolTable));
+#endif
+
+#ifdef DEBUG_foo
+      printf("--- glLoadProgramNV(%d) result ---\n", program->Base.Id);
+      _mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0);
+      printf("----------------------------------\n");
+#endif
+   }
+   else {
+      /* Error! */
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV");
+      /* NOTE: _mesa_set_program_error would have been called already */
+   }
+}
+
+
+const char *
+_mesa_nv_fragment_input_register_name(GLuint i)
+{
+   ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_INPUTS);
+   return InputRegisters[i];
+}
+
diff --git a/src/mesa/program/nvfragparse.h b/src/mesa/program/nvfragparse.h
new file mode 100644 (file)
index 0000000..544ab80
--- /dev/null
@@ -0,0 +1,43 @@
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  5.1
+ *
+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Brian Paul
+ */
+
+
+#ifndef NVFRAGPARSE_H
+#define NVFRAGPARSE_H
+
+
+extern void
+_mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum target,
+                                const GLubyte *str, GLsizei len,
+                                struct gl_fragment_program *program);
+
+
+extern const char *
+_mesa_nv_fragment_input_register_name(GLuint i);
+
+#endif
diff --git a/src/mesa/program/nvvertparse.c b/src/mesa/program/nvvertparse.c
new file mode 100644 (file)
index 0000000..e2afcfd
--- /dev/null
@@ -0,0 +1,1454 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.2
+ *
+ * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file nvvertparse.c
+ * NVIDIA vertex program parser.
+ * \author Brian Paul
+ */
+
+/*
+ * Regarding GL_NV_vertex_program, GL_NV_vertex_program1_1:
+ *
+ * Portions of this software may use or implement intellectual
+ * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims
+ * any and all warranties with respect to such intellectual property,
+ * including any use thereof or modifications thereto.
+ */
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/imports.h"
+#include "main/nvprogram.h"
+#include "nvvertparse.h"
+#include "prog_instruction.h"
+#include "prog_parameter.h"
+#include "prog_print.h"
+#include "program.h"
+
+
+/**
+ * Current parsing state.  This structure is passed among the parsing
+ * functions and keeps track of the current parser position and various
+ * program attributes.
+ */
+struct parse_state {
+   GLcontext *ctx;
+   const GLubyte *start;
+   const GLubyte *pos;
+   const GLubyte *curLine;
+   GLboolean isStateProgram;
+   GLboolean isPositionInvariant;
+   GLboolean isVersion1_1;
+   GLbitfield inputsRead;
+   GLbitfield outputsWritten;
+   GLboolean anyProgRegsWritten;
+   GLuint numInst;                 /* number of instructions parsed */
+};
+
+
+/*
+ * Called whenever we find an error during parsing.
+ */
+static void
+record_error(struct parse_state *parseState, const char *msg, int lineNo)
+{
+#ifdef DEBUG
+   GLint line, column;
+   const GLubyte *lineStr;
+   lineStr = _mesa_find_line_column(parseState->start,
+                                    parseState->pos, &line, &column);
+   _mesa_debug(parseState->ctx,
+               "nvfragparse.c(%d): line %d, column %d:%s (%s)\n",
+               lineNo, line, column, (char *) lineStr, msg);
+   free((void *) lineStr);
+#else
+   (void) lineNo;
+#endif
+
+   /* Check that no error was already recorded.  Only record the first one. */
+   if (parseState->ctx->Program.ErrorString[0] == 0) {
+      _mesa_set_program_error(parseState->ctx,
+                              parseState->pos - parseState->start,
+                              msg);
+   }
+}
+
+
+#define RETURN_ERROR                                                   \
+do {                                                                   \
+   record_error(parseState, "Unexpected end of input.", __LINE__);     \
+   return GL_FALSE;                                                    \
+} while(0)
+
+#define RETURN_ERROR1(msg)                                             \
+do {                                                                   \
+   record_error(parseState, msg, __LINE__);                            \
+   return GL_FALSE;                                                    \
+} while(0)
+
+#define RETURN_ERROR2(msg1, msg2)                                      \
+do {                                                                   \
+   char err[1000];                                                     \
+   sprintf(err, "%s %s", msg1, msg2);                          \
+   record_error(parseState, err, __LINE__);                            \
+   return GL_FALSE;                                                    \
+} while(0)
+
+
+
+
+
+static GLboolean IsLetter(GLubyte b)
+{
+   return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z');
+}
+
+
+static GLboolean IsDigit(GLubyte b)
+{
+   return b >= '0' && b <= '9';
+}
+
+
+static GLboolean IsWhitespace(GLubyte b)
+{
+   return b == ' ' || b == '\t' || b == '\n' || b == '\r';
+}
+
+
+/**
+ * Starting at 'str' find the next token.  A token can be an integer,
+ * an identifier or punctuation symbol.
+ * \return <= 0 we found an error, else, return number of characters parsed.
+ */
+static GLint
+GetToken(struct parse_state *parseState, GLubyte *token)
+{
+   const GLubyte *str = parseState->pos;
+   GLint i = 0, j = 0;
+
+   token[0] = 0;
+
+   /* skip whitespace and comments */
+   while (str[i] && (IsWhitespace(str[i]) || str[i] == '#')) {
+      if (str[i] == '#') {
+         /* skip comment */
+         while (str[i] && (str[i] != '\n' && str[i] != '\r')) {
+            i++;
+         }
+         if (str[i] == '\n' || str[i] == '\r')
+            parseState->curLine = str + i + 1;
+      }
+      else {
+         /* skip whitespace */
+         if (str[i] == '\n' || str[i] == '\r')
+            parseState->curLine = str + i + 1;
+         i++;
+      }
+   }
+
+   if (str[i] == 0)
+      return -i;
+
+   /* try matching an integer */
+   while (str[i] && IsDigit(str[i])) {
+      token[j++] = str[i++];
+   }
+   if (j > 0 || !str[i]) {
+      token[j] = 0;
+      return i;
+   }
+
+   /* try matching an identifier */
+   if (IsLetter(str[i])) {
+      while (str[i] && (IsLetter(str[i]) || IsDigit(str[i]))) {
+         token[j++] = str[i++];
+      }
+      token[j] = 0;
+      return i;
+   }
+
+   /* punctuation character */
+   if (str[i]) {
+      token[0] = str[i++];
+      token[1] = 0;
+      return i;
+   }
+
+   /* end of input */
+   token[0] = 0;
+   return i;
+}
+
+
+/**
+ * Get next token from input stream and increment stream pointer past token.
+ */
+static GLboolean
+Parse_Token(struct parse_state *parseState, GLubyte *token)
+{
+   GLint i;
+   i = GetToken(parseState, token);
+   if (i <= 0) {
+      parseState->pos += (-i);
+      return GL_FALSE;
+   }
+   parseState->pos += i;
+   return GL_TRUE;
+}
+
+
+/**
+ * Get next token from input stream but don't increment stream pointer.
+ */
+static GLboolean
+Peek_Token(struct parse_state *parseState, GLubyte *token)
+{
+   GLint i, len;
+   i = GetToken(parseState, token);
+   if (i <= 0) {
+      parseState->pos += (-i);
+      return GL_FALSE;
+   }
+   len = (GLint) strlen((const char *) token);
+   parseState->pos += (i - len);
+   return GL_TRUE;
+}
+
+
+/**
+ * Try to match 'pattern' as the next token after any whitespace/comments.
+ * Advance the current parsing position only if we match the pattern.
+ * \return GL_TRUE if pattern is matched, GL_FALSE otherwise.
+ */
+static GLboolean
+Parse_String(struct parse_state *parseState, const char *pattern)
+{
+   const GLubyte *m;
+   GLint i;
+
+   /* skip whitespace and comments */
+   while (IsWhitespace(*parseState->pos) || *parseState->pos == '#') {
+      if (*parseState->pos == '#') {
+         while (*parseState->pos && (*parseState->pos != '\n' && *parseState->pos != '\r')) {
+            parseState->pos += 1;
+         }
+         if (*parseState->pos == '\n' || *parseState->pos == '\r')
+            parseState->curLine = parseState->pos + 1;
+      }
+      else {
+         /* skip whitespace */
+         if (*parseState->pos == '\n' || *parseState->pos == '\r')
+            parseState->curLine = parseState->pos + 1;
+         parseState->pos += 1;
+      }
+   }
+
+   /* Try to match the pattern */
+   m = parseState->pos;
+   for (i = 0; pattern[i]; i++) {
+      if (*m != (GLubyte) pattern[i])
+         return GL_FALSE;
+      m += 1;
+   }
+   parseState->pos = m;
+
+   return GL_TRUE; /* success */
+}
+
+
+/**********************************************************************/
+
+static const char *InputRegisters[MAX_NV_VERTEX_PROGRAM_INPUTS + 1] = {
+   "OPOS", "WGHT", "NRML", "COL0", "COL1", "FOGC", "6", "7",
+   "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL
+};
+
+static const char *OutputRegisters[MAX_NV_VERTEX_PROGRAM_OUTPUTS + 1] = {
+   "HPOS", "COL0", "COL1", "FOGC", 
+   "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", 
+   "PSIZ", "BFC0", "BFC1", NULL
+};
+
+
+
+/**
+ * Parse a temporary register: Rnn
+ */
+static GLboolean
+Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum)
+{
+   GLubyte token[100];
+
+   /* Should be 'R##' */
+   if (!Parse_Token(parseState, token))
+      RETURN_ERROR;
+   if (token[0] != 'R')
+      RETURN_ERROR1("Expected R##");
+
+   if (IsDigit(token[1])) {
+      GLint reg = atoi((char *) (token + 1));
+      if (reg >= MAX_NV_VERTEX_PROGRAM_TEMPS)
+         RETURN_ERROR1("Bad temporary register name");
+      *tempRegNum = reg;
+   }
+   else {
+      RETURN_ERROR1("Bad temporary register name");
+   }
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Parse address register "A0.x"
+ */
+static GLboolean
+Parse_AddrReg(struct parse_state *parseState)
+{
+   /* match 'A0' */
+   if (!Parse_String(parseState, "A0"))
+      RETURN_ERROR;
+
+   /* match '.' */
+   if (!Parse_String(parseState, "."))
+      RETURN_ERROR;
+
+   /* match 'x' */
+   if (!Parse_String(parseState, "x"))
+      RETURN_ERROR;
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Parse absolute program parameter register "c[##]"
+ */
+static GLboolean
+Parse_AbsParamReg(struct parse_state *parseState, GLint *regNum)
+{
+   GLubyte token[100];
+
+   if (!Parse_String(parseState, "c"))
+      RETURN_ERROR;
+
+   if (!Parse_String(parseState, "["))
+      RETURN_ERROR;
+
+   if (!Parse_Token(parseState, token))
+      RETURN_ERROR;
+
+   if (IsDigit(token[0])) {
+      /* a numbered program parameter register */
+      GLint reg = atoi((char *) token);
+      if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS)
+         RETURN_ERROR1("Bad program parameter number");
+      *regNum = reg;
+   }
+   else {
+      RETURN_ERROR;
+   }
+
+   if (!Parse_String(parseState, "]"))
+      RETURN_ERROR;
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_ParamReg(struct parse_state *parseState, struct prog_src_register *srcReg)
+{
+   GLubyte token[100];
+
+   if (!Parse_String(parseState, "c"))
+      RETURN_ERROR;
+
+   if (!Parse_String(parseState, "["))
+      RETURN_ERROR;
+
+   if (!Peek_Token(parseState, token))
+      RETURN_ERROR;
+
+   if (IsDigit(token[0])) {
+      /* a numbered program parameter register */
+      GLint reg;
+      (void) Parse_Token(parseState, token);
+      reg = atoi((char *) token);
+      if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS)
+         RETURN_ERROR1("Bad program parameter number");
+      srcReg->File = PROGRAM_ENV_PARAM;
+      srcReg->Index = reg;
+   }
+   else if (strcmp((const char *) token, "A0") == 0) {
+      /* address register "A0.x" */
+      if (!Parse_AddrReg(parseState))
+         RETURN_ERROR;
+
+      srcReg->RelAddr = GL_TRUE;
+      srcReg->File = PROGRAM_ENV_PARAM;
+      /* Look for +/-N offset */
+      if (!Peek_Token(parseState, token))
+         RETURN_ERROR;
+
+      if (token[0] == '-' || token[0] == '+') {
+         const GLubyte sign = token[0];
+         (void) Parse_Token(parseState, token); /* consume +/- */
+
+         /* an integer should be next */
+         if (!Parse_Token(parseState, token))
+            RETURN_ERROR;
+
+         if (IsDigit(token[0])) {
+            const GLint k = atoi((char *) token);
+            if (sign == '-') {
+               if (k > 64)
+                  RETURN_ERROR1("Bad address offset");
+               srcReg->Index = -k;
+            }
+            else {
+               if (k > 63)
+                  RETURN_ERROR1("Bad address offset");
+               srcReg->Index = k;
+            }
+         }
+         else {
+            RETURN_ERROR;
+         }
+      }
+      else {
+         /* probably got a ']', catch it below */
+      }
+   }
+   else {
+      RETURN_ERROR;
+   }
+
+   /* Match closing ']' */
+   if (!Parse_String(parseState, "]"))
+      RETURN_ERROR;
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Parse v[#] or v[<name>]
+ */
+static GLboolean
+Parse_AttribReg(struct parse_state *parseState, GLint *tempRegNum)
+{
+   GLubyte token[100];
+   GLint j;
+
+   /* Match 'v' */
+   if (!Parse_String(parseState, "v"))
+      RETURN_ERROR;
+
+   /* Match '[' */
+   if (!Parse_String(parseState, "["))
+      RETURN_ERROR;
+
+   /* match number or named register */
+   if (!Parse_Token(parseState, token))
+      RETURN_ERROR;
+
+   if (parseState->isStateProgram && token[0] != '0')
+      RETURN_ERROR1("Only v[0] accessible in vertex state programs");
+
+   if (IsDigit(token[0])) {
+      GLint reg = atoi((char *) token);
+      if (reg >= MAX_NV_VERTEX_PROGRAM_INPUTS)
+         RETURN_ERROR1("Bad vertex attribute register name");
+      *tempRegNum = reg;
+   }
+   else {
+      for (j = 0; InputRegisters[j]; j++) {
+         if (strcmp((const char *) token, InputRegisters[j]) == 0) {
+            *tempRegNum = j;
+            break;
+         }
+      }
+      if (!InputRegisters[j]) {
+         /* unknown input register label */
+         RETURN_ERROR2("Bad register name", token);
+      }
+   }
+
+   /* Match '[' */
+   if (!Parse_String(parseState, "]"))
+      RETURN_ERROR;
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum)
+{
+   GLubyte token[100];
+   GLint start, j;
+
+   /* Match 'o' */
+   if (!Parse_String(parseState, "o"))
+      RETURN_ERROR;
+
+   /* Match '[' */
+   if (!Parse_String(parseState, "["))
+      RETURN_ERROR;
+
+   /* Get output reg name */
+   if (!Parse_Token(parseState, token))
+      RETURN_ERROR;
+
+   if (parseState->isPositionInvariant)
+      start = 1; /* skip HPOS register name */
+   else
+      start = 0;
+
+   /* try to match an output register name */
+   for (j = start; OutputRegisters[j]; j++) {
+      if (strcmp((const char *) token, OutputRegisters[j]) == 0) {
+         *outputRegNum = j;
+         break;
+      }
+   }
+   if (!OutputRegisters[j])
+      RETURN_ERROR1("Unrecognized output register name");
+
+   /* Match ']' */
+   if (!Parse_String(parseState, "]"))
+      RETURN_ERROR1("Expected ]");
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_MaskedDstReg(struct parse_state *parseState, struct prog_dst_register *dstReg)
+{
+   GLubyte token[100];
+   GLint idx;
+
+   /* Dst reg can be R<n> or o[n] */
+   if (!Peek_Token(parseState, token))
+      RETURN_ERROR;
+
+   if (token[0] == 'R') {
+      /* a temporary register */
+      dstReg->File = PROGRAM_TEMPORARY;
+      if (!Parse_TempReg(parseState, &idx))
+         RETURN_ERROR;
+      dstReg->Index = idx;
+   }
+   else if (!parseState->isStateProgram && token[0] == 'o') {
+      /* an output register */
+      dstReg->File = PROGRAM_OUTPUT;
+      if (!Parse_OutputReg(parseState, &idx))
+         RETURN_ERROR;
+      dstReg->Index = idx;
+   }
+   else if (parseState->isStateProgram && token[0] == 'c' &&
+            parseState->isStateProgram) {
+      /* absolute program parameter register */
+      /* Only valid for vertex state programs */
+      dstReg->File = PROGRAM_ENV_PARAM;
+      if (!Parse_AbsParamReg(parseState, &idx))
+         RETURN_ERROR;
+      dstReg->Index = idx;
+   }
+   else {
+      RETURN_ERROR1("Bad destination register name");
+   }
+
+   /* Parse optional write mask */
+   if (!Peek_Token(parseState, token))
+      RETURN_ERROR;
+
+   if (token[0] == '.') {
+      /* got a mask */
+      GLint k = 0;
+
+      if (!Parse_String(parseState, "."))
+         RETURN_ERROR;
+
+      if (!Parse_Token(parseState, token))
+         RETURN_ERROR;
+
+      dstReg->WriteMask = 0;
+
+      if (token[k] == 'x') {
+         dstReg->WriteMask |= WRITEMASK_X;
+         k++;
+      }
+      if (token[k] == 'y') {
+         dstReg->WriteMask |= WRITEMASK_Y;
+         k++;
+      }
+      if (token[k] == 'z') {
+         dstReg->WriteMask |= WRITEMASK_Z;
+         k++;
+      }
+      if (token[k] == 'w') {
+         dstReg->WriteMask |= WRITEMASK_W;
+         k++;
+      }
+      if (k == 0) {
+         RETURN_ERROR1("Bad writemask character");
+      }
+      return GL_TRUE;
+   }
+   else {
+      dstReg->WriteMask = WRITEMASK_XYZW;
+      return GL_TRUE;
+   }
+}
+
+
+static GLboolean
+Parse_SwizzleSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg)
+{
+   GLubyte token[100];
+   GLint idx;
+
+   srcReg->RelAddr = GL_FALSE;
+
+   /* check for '-' */
+   if (!Peek_Token(parseState, token))
+      RETURN_ERROR;
+   if (token[0] == '-') {
+      (void) Parse_String(parseState, "-");
+      srcReg->Negate = NEGATE_XYZW;
+      if (!Peek_Token(parseState, token))
+         RETURN_ERROR;
+   }
+   else {
+      srcReg->Negate = NEGATE_NONE;
+   }
+
+   /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
+   if (token[0] == 'R') {
+      srcReg->File = PROGRAM_TEMPORARY;
+      if (!Parse_TempReg(parseState, &idx))
+         RETURN_ERROR;
+      srcReg->Index = idx;
+   }
+   else if (token[0] == 'c') {
+      if (!Parse_ParamReg(parseState, srcReg))
+         RETURN_ERROR;
+   }
+   else if (token[0] == 'v') {
+      srcReg->File = PROGRAM_INPUT;
+      if (!Parse_AttribReg(parseState, &idx))
+         RETURN_ERROR;
+      srcReg->Index = idx;
+   }
+   else {
+      RETURN_ERROR2("Bad source register name", token);
+   }
+
+   /* init swizzle fields */
+   srcReg->Swizzle = SWIZZLE_NOOP;
+
+   /* Look for optional swizzle suffix */
+   if (!Peek_Token(parseState, token))
+      RETURN_ERROR;
+   if (token[0] == '.') {
+      (void) Parse_String(parseState, ".");  /* consume . */
+
+      if (!Parse_Token(parseState, token))
+         RETURN_ERROR;
+
+      if (token[1] == 0) {
+         /* single letter swizzle */
+         if (token[0] == 'x')
+            srcReg->Swizzle = SWIZZLE_XXXX;
+         else if (token[0] == 'y')
+            srcReg->Swizzle = SWIZZLE_YYYY;
+         else if (token[0] == 'z')
+            srcReg->Swizzle = SWIZZLE_ZZZZ;
+         else if (token[0] == 'w')
+            srcReg->Swizzle = SWIZZLE_WWWW;
+         else
+            RETURN_ERROR1("Expected x, y, z, or w");
+      }
+      else {
+         /* 2, 3 or 4-component swizzle */
+         GLint k;
+
+         srcReg->Swizzle = 0;
+
+         for (k = 0; token[k] && k < 5; k++) {
+            if (token[k] == 'x')
+               srcReg->Swizzle |= 0 << (k*3);
+            else if (token[k] == 'y')
+               srcReg->Swizzle |= 1 << (k*3);
+            else if (token[k] == 'z')
+               srcReg->Swizzle |= 2 << (k*3);
+            else if (token[k] == 'w')
+               srcReg->Swizzle |= 3 << (k*3);
+            else
+               RETURN_ERROR;
+         }
+         if (k >= 5)
+            RETURN_ERROR;
+      }
+   }
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_ScalarSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg)
+{
+   GLubyte token[100];
+   GLint idx;
+
+   srcReg->RelAddr = GL_FALSE;
+
+   /* check for '-' */
+   if (!Peek_Token(parseState, token))
+      RETURN_ERROR;
+   if (token[0] == '-') {
+      srcReg->Negate = NEGATE_XYZW;
+      (void) Parse_String(parseState, "-"); /* consume '-' */
+      if (!Peek_Token(parseState, token))
+         RETURN_ERROR;
+   }
+   else {
+      srcReg->Negate = NEGATE_NONE;
+   }
+
+   /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
+   if (token[0] == 'R') {
+      srcReg->File = PROGRAM_TEMPORARY;
+      if (!Parse_TempReg(parseState, &idx))
+         RETURN_ERROR;
+      srcReg->Index = idx;
+   }
+   else if (token[0] == 'c') {
+      if (!Parse_ParamReg(parseState, srcReg))
+         RETURN_ERROR;
+   }
+   else if (token[0] == 'v') {
+      srcReg->File = PROGRAM_INPUT;
+      if (!Parse_AttribReg(parseState, &idx))
+         RETURN_ERROR;
+      srcReg->Index = idx;
+   }
+   else {
+      RETURN_ERROR2("Bad source register name", token);
+   }
+
+   /* Look for .[xyzw] suffix */
+   if (!Parse_String(parseState, "."))
+      RETURN_ERROR;
+
+   if (!Parse_Token(parseState, token))
+      RETURN_ERROR;
+
+   if (token[0] == 'x' && token[1] == 0) {
+      srcReg->Swizzle = 0;
+   }
+   else if (token[0] == 'y' && token[1] == 0) {
+      srcReg->Swizzle = 1;
+   }
+   else if (token[0] == 'z' && token[1] == 0) {
+      srcReg->Swizzle = 2;
+   }
+   else if (token[0] == 'w' && token[1] == 0) {
+      srcReg->Swizzle = 3;
+   }
+   else {
+      RETURN_ERROR1("Bad scalar source suffix");
+   }
+
+   return GL_TRUE;
+}
+
+
+static GLint
+Parse_UnaryOpInstruction(struct parse_state *parseState,
+                         struct prog_instruction *inst,
+                         enum prog_opcode opcode)
+{
+   if (opcode == OPCODE_ABS && !parseState->isVersion1_1)
+      RETURN_ERROR1("ABS illegal for vertex program 1.0");
+
+   inst->Opcode = opcode;
+
+   /* dest reg */
+   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
+      RETURN_ERROR;
+
+   /* comma */
+   if (!Parse_String(parseState, ","))
+      RETURN_ERROR;
+
+   /* src arg */
+   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
+      RETURN_ERROR;
+
+   /* semicolon */
+   if (!Parse_String(parseState, ";"))
+      RETURN_ERROR;
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_BiOpInstruction(struct parse_state *parseState,
+                      struct prog_instruction *inst,
+                      enum prog_opcode opcode)
+{
+   if (opcode == OPCODE_DPH && !parseState->isVersion1_1)
+      RETURN_ERROR1("DPH illegal for vertex program 1.0");
+   if (opcode == OPCODE_SUB && !parseState->isVersion1_1)
+      RETURN_ERROR1("SUB illegal for vertex program 1.0");
+
+   inst->Opcode = opcode;
+
+   /* dest reg */
+   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
+      RETURN_ERROR;
+
+   /* comma */
+   if (!Parse_String(parseState, ","))
+      RETURN_ERROR;
+
+   /* first src arg */
+   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
+      RETURN_ERROR;
+
+   /* comma */
+   if (!Parse_String(parseState, ","))
+      RETURN_ERROR;
+
+   /* second src arg */
+   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1]))
+      RETURN_ERROR;
+
+   /* semicolon */
+   if (!Parse_String(parseState, ";"))
+      RETURN_ERROR;
+
+   /* make sure we don't reference more than one program parameter register */
+   if (inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
+       inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
+       inst->SrcReg[0].Index != inst->SrcReg[1].Index)
+      RETURN_ERROR1("Can't reference two program parameter registers");
+
+   /* make sure we don't reference more than one vertex attribute register */
+   if (inst->SrcReg[0].File == PROGRAM_INPUT &&
+       inst->SrcReg[1].File == PROGRAM_INPUT &&
+       inst->SrcReg[0].Index != inst->SrcReg[1].Index)
+      RETURN_ERROR1("Can't reference two vertex attribute registers");
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_TriOpInstruction(struct parse_state *parseState,
+                       struct prog_instruction *inst,
+                       enum prog_opcode opcode)
+{
+   inst->Opcode = opcode;
+
+   /* dest reg */
+   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
+      RETURN_ERROR;
+
+   /* comma */
+   if (!Parse_String(parseState, ","))
+      RETURN_ERROR;
+
+   /* first src arg */
+   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
+      RETURN_ERROR;
+
+   /* comma */
+   if (!Parse_String(parseState, ","))
+      RETURN_ERROR;
+
+   /* second src arg */
+   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1]))
+      RETURN_ERROR;
+
+   /* comma */
+   if (!Parse_String(parseState, ","))
+      RETURN_ERROR;
+
+   /* third src arg */
+   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[2]))
+      RETURN_ERROR;
+
+   /* semicolon */
+   if (!Parse_String(parseState, ";"))
+      RETURN_ERROR;
+
+   /* make sure we don't reference more than one program parameter register */
+   if ((inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
+        inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
+        inst->SrcReg[0].Index != inst->SrcReg[1].Index) ||
+       (inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
+        inst->SrcReg[2].File == PROGRAM_ENV_PARAM &&
+        inst->SrcReg[0].Index != inst->SrcReg[2].Index) ||
+       (inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
+        inst->SrcReg[2].File == PROGRAM_ENV_PARAM &&
+        inst->SrcReg[1].Index != inst->SrcReg[2].Index))
+      RETURN_ERROR1("Can only reference one program register");
+
+   /* make sure we don't reference more than one vertex attribute register */
+   if ((inst->SrcReg[0].File == PROGRAM_INPUT &&
+        inst->SrcReg[1].File == PROGRAM_INPUT &&
+        inst->SrcReg[0].Index != inst->SrcReg[1].Index) ||
+       (inst->SrcReg[0].File == PROGRAM_INPUT &&
+        inst->SrcReg[2].File == PROGRAM_INPUT &&
+        inst->SrcReg[0].Index != inst->SrcReg[2].Index) ||
+       (inst->SrcReg[1].File == PROGRAM_INPUT &&
+        inst->SrcReg[2].File == PROGRAM_INPUT &&
+        inst->SrcReg[1].Index != inst->SrcReg[2].Index))
+      RETURN_ERROR1("Can only reference one input register");
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_ScalarInstruction(struct parse_state *parseState,
+                        struct prog_instruction *inst,
+                        enum prog_opcode opcode)
+{
+   if (opcode == OPCODE_RCC && !parseState->isVersion1_1)
+      RETURN_ERROR1("RCC illegal for vertex program 1.0");
+
+   inst->Opcode = opcode;
+
+   /* dest reg */
+   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
+      RETURN_ERROR;
+
+   /* comma */
+   if (!Parse_String(parseState, ","))
+      RETURN_ERROR;
+
+   /* first src arg */
+   if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
+      RETURN_ERROR;
+
+   /* semicolon */
+   if (!Parse_String(parseState, ";"))
+      RETURN_ERROR;
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_AddressInstruction(struct parse_state *parseState, struct prog_instruction *inst)
+{
+   inst->Opcode = OPCODE_ARL;
+
+   /* Make ARB_vp backends happy */
+   inst->DstReg.File = PROGRAM_ADDRESS;
+   inst->DstReg.WriteMask = WRITEMASK_X;
+   inst->DstReg.Index = 0;
+
+   /* dest A0 reg */
+   if (!Parse_AddrReg(parseState))
+      RETURN_ERROR;
+
+   /* comma */
+   if (!Parse_String(parseState, ","))
+      RETURN_ERROR;
+
+   /* parse src reg */
+   if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
+      RETURN_ERROR;
+
+   /* semicolon */
+   if (!Parse_String(parseState, ";"))
+      RETURN_ERROR;
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_EndInstruction(struct parse_state *parseState, struct prog_instruction *inst)
+{
+   GLubyte token[100];
+
+   inst->Opcode = OPCODE_END;
+
+   /* this should fail! */
+   if (Parse_Token(parseState, token))
+      RETURN_ERROR2("Unexpected token after END:", token);
+   else
+      return GL_TRUE;
+}
+
+
+/**
+ * The PRINT instruction is Mesa-specific and is meant as a debugging aid for
+ * the vertex program developer.
+ * The NV_vertex_program extension grammar is modified as follows:
+ *
+ *  <instruction>        ::= <ARL-instruction>
+ *                         | ...
+ *                         | <PRINT-instruction>
+ *
+ *  <PRINT-instruction>  ::= "PRINT" <string literal>
+ *                         | "PRINT" <string literal> "," <srcReg>
+ *                         | "PRINT" <string literal> "," <dstReg>
+ */
+static GLboolean
+Parse_PrintInstruction(struct parse_state *parseState, struct prog_instruction *inst)
+{
+   const GLubyte *str;
+   GLubyte *msg;
+   GLuint len;
+   GLubyte token[100];
+   struct prog_src_register *srcReg = &inst->SrcReg[0];
+   GLint idx;
+
+   inst->Opcode = OPCODE_PRINT;
+
+   /* The first argument is a literal string 'just like this' */
+   if (!Parse_String(parseState, "'"))
+      RETURN_ERROR;
+
+   str = parseState->pos;
+   for (len = 0; str[len] != '\''; len++) /* find closing quote */
+      ;
+   parseState->pos += len + 1;
+   msg = (GLubyte*) malloc(len + 1);
+
+   memcpy(msg, str, len);
+   msg[len] = 0;
+   inst->Data = msg;
+
+   /* comma */
+   if (Parse_String(parseState, ",")) {
+
+      /* The second argument is a register name */
+      if (!Peek_Token(parseState, token))
+         RETURN_ERROR;
+
+      srcReg->RelAddr = GL_FALSE;
+      srcReg->Negate = NEGATE_NONE;
+      srcReg->Swizzle = SWIZZLE_NOOP;
+
+      /* Register can be R<n>, c[n], c[n +/- offset], a named vertex attrib,
+       * or an o[n] output register.
+       */
+      if (token[0] == 'R') {
+         srcReg->File = PROGRAM_TEMPORARY;
+         if (!Parse_TempReg(parseState, &idx))
+            RETURN_ERROR;
+        srcReg->Index = idx;
+      }
+      else if (token[0] == 'c') {
+         srcReg->File = PROGRAM_ENV_PARAM;
+         if (!Parse_ParamReg(parseState, srcReg))
+            RETURN_ERROR;
+      }
+      else if (token[0] == 'v') {
+         srcReg->File = PROGRAM_INPUT;
+         if (!Parse_AttribReg(parseState, &idx))
+            RETURN_ERROR;
+        srcReg->Index = idx;
+      }
+      else if (token[0] == 'o') {
+         srcReg->File = PROGRAM_OUTPUT;
+         if (!Parse_OutputReg(parseState, &idx))
+            RETURN_ERROR;
+        srcReg->Index = idx;
+      }
+      else {
+         RETURN_ERROR2("Bad source register name", token);
+      }
+   }
+   else {
+      srcReg->File = PROGRAM_UNDEFINED;
+   }
+
+   /* semicolon */
+   if (!Parse_String(parseState, ";"))
+      RETURN_ERROR;
+
+   return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_OptionSequence(struct parse_state *parseState,
+                     struct prog_instruction program[])
+{
+   (void) program;
+   while (1) {
+      if (!Parse_String(parseState, "OPTION"))
+         return GL_TRUE;  /* ok, not an OPTION statement */
+      if (Parse_String(parseState, "NV_position_invariant")) {
+         parseState->isPositionInvariant = GL_TRUE;
+      }
+      else {
+         RETURN_ERROR1("unexpected OPTION statement");
+      }
+      if (!Parse_String(parseState, ";"))
+         return GL_FALSE;
+   }
+}
+
+
+static GLboolean
+Parse_InstructionSequence(struct parse_state *parseState,
+                          struct prog_instruction program[])
+{
+   while (1) {
+      struct prog_instruction *inst = program + parseState->numInst;
+
+      /* Initialize the instruction */
+      _mesa_init_instructions(inst, 1);
+
+      if (Parse_String(parseState, "MOV")) {
+         if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_MOV))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "LIT")) {
+         if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_LIT))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "ABS")) {
+         if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_ABS))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "MUL")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MUL))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "ADD")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_ADD))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "DP3")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP3))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "DP4")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP4))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "DST")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DST))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "MIN")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MIN))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "MAX")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MAX))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "SLT")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SLT))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "SGE")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SGE))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "DPH")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DPH))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "SUB")) {
+         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SUB))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "MAD")) {
+         if (!Parse_TriOpInstruction(parseState, inst, OPCODE_MAD))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "RCP")) {
+         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCP))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "RSQ")) {
+         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RSQ))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "EXP")) {
+         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_EXP))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "LOG")) {
+         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_LOG))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "RCC")) {
+         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCC))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "ARL")) {
+         if (!Parse_AddressInstruction(parseState, inst))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "PRINT")) {
+         if (!Parse_PrintInstruction(parseState, inst))
+            RETURN_ERROR;
+      }
+      else if (Parse_String(parseState, "END")) {
+         if (!Parse_EndInstruction(parseState, inst))
+            RETURN_ERROR;
+         else {
+            parseState->numInst++;
+            return GL_TRUE;  /* all done */
+         }
+      }
+      else {
+         /* bad instruction name */
+         RETURN_ERROR1("Unexpected token");
+      }
+
+      /* examine input/output registers */
+      if (inst->DstReg.File == PROGRAM_OUTPUT)
+         parseState->outputsWritten |= (1 << inst->DstReg.Index);
+      else if (inst->DstReg.File == PROGRAM_ENV_PARAM)
+         parseState->anyProgRegsWritten = GL_TRUE;
+
+      if (inst->SrcReg[0].File == PROGRAM_INPUT)
+         parseState->inputsRead |= (1 << inst->SrcReg[0].Index);
+      if (inst->SrcReg[1].File == PROGRAM_INPUT)
+         parseState->inputsRead |= (1 << inst->SrcReg[1].Index);
+      if (inst->SrcReg[2].File == PROGRAM_INPUT)
+         parseState->inputsRead |= (1 << inst->SrcReg[2].Index);
+
+      parseState->numInst++;
+
+      if (parseState->numInst >= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS)
+         RETURN_ERROR1("Program too long");
+   }
+
+   RETURN_ERROR;
+}
+
+
+static GLboolean
+Parse_Program(struct parse_state *parseState,
+              struct prog_instruction instBuffer[])
+{
+   if (parseState->isVersion1_1) {
+      if (!Parse_OptionSequence(parseState, instBuffer)) {
+         return GL_FALSE;
+      }
+   }
+   return Parse_InstructionSequence(parseState, instBuffer);
+}
+
+
+/**
+ * Parse/compile the 'str' returning the compiled 'program'.
+ * ctx->Program.ErrorPos will be -1 if successful.  Otherwise, ErrorPos
+ * indicates the position of the error in 'str'.
+ */
+void
+_mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget,
+                              const GLubyte *str, GLsizei len,
+                              struct gl_vertex_program *program)
+{
+   struct parse_state parseState;
+   struct prog_instruction instBuffer[MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS];
+   struct prog_instruction *newInst;
+   GLenum target;
+   GLubyte *programString;
+
+   /* Make a null-terminated copy of the program string */
+   programString = (GLubyte *) MALLOC(len + 1);
+   if (!programString) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
+      return;
+   }
+   memcpy(programString, str, len);
+   programString[len] = 0;
+
+   /* Get ready to parse */
+   parseState.ctx = ctx;
+   parseState.start = programString;
+   parseState.isPositionInvariant = GL_FALSE;
+   parseState.isVersion1_1 = GL_FALSE;
+   parseState.numInst = 0;
+   parseState.inputsRead = 0;
+   parseState.outputsWritten = 0;
+   parseState.anyProgRegsWritten = GL_FALSE;
+
+   /* Reset error state */
+   _mesa_set_program_error(ctx, -1, NULL);
+
+   /* check the program header */
+   if (strncmp((const char *) programString, "!!VP1.0", 7) == 0) {
+      target = GL_VERTEX_PROGRAM_NV;
+      parseState.pos = programString + 7;
+      parseState.isStateProgram = GL_FALSE;
+   }
+   else if (strncmp((const char *) programString, "!!VP1.1", 7) == 0) {
+      target = GL_VERTEX_PROGRAM_NV;
+      parseState.pos = programString + 7;
+      parseState.isStateProgram = GL_FALSE;
+      parseState.isVersion1_1 = GL_TRUE;
+   }
+   else if (strncmp((const char *) programString, "!!VSP1.0", 8) == 0) {
+      target = GL_VERTEX_STATE_PROGRAM_NV;
+      parseState.pos = programString + 8;
+      parseState.isStateProgram = GL_TRUE;
+   }
+   else {
+      /* invalid header */
+      ctx->Program.ErrorPos = 0;
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
+      return;
+   }
+
+   /* make sure target and header match */
+   if (target != dstTarget) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glLoadProgramNV(target mismatch)");
+      return;
+   }
+
+
+   if (Parse_Program(&parseState, instBuffer)) {
+      gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0};
+      int i;
+
+      /* successful parse! */
+
+      if (parseState.isStateProgram) {
+         if (!parseState.anyProgRegsWritten) {
+            _mesa_error(ctx, GL_INVALID_OPERATION,
+                        "glLoadProgramNV(c[#] not written)");
+            return;
+         }
+      }
+      else {
+         if (!parseState.isPositionInvariant &&
+             !(parseState.outputsWritten & (1 << VERT_RESULT_HPOS))) {
+            /* bit 1 = HPOS register */
+            _mesa_error(ctx, GL_INVALID_OPERATION,
+                        "glLoadProgramNV(HPOS not written)");
+            return;
+         }
+      }
+
+      /* copy the compiled instructions */
+      assert(parseState.numInst <= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS);
+      newInst = _mesa_alloc_instructions(parseState.numInst);
+      if (!newInst) {
+         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
+         free(programString);
+         return;  /* out of memory */
+      }
+      _mesa_copy_instructions(newInst, instBuffer, parseState.numInst);
+
+      /* install the program */
+      program->Base.Target = target;
+      if (program->Base.String) {
+         free(program->Base.String);
+      }
+      program->Base.String = programString;
+      program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;
+      if (program->Base.Instructions) {
+         free(program->Base.Instructions);
+      }
+      program->Base.Instructions = newInst;
+      program->Base.InputsRead = parseState.inputsRead;
+      if (parseState.isPositionInvariant)
+         program->Base.InputsRead |= VERT_BIT_POS;
+      program->Base.NumInstructions = parseState.numInst;
+      program->Base.OutputsWritten = parseState.outputsWritten;
+      program->IsPositionInvariant = parseState.isPositionInvariant;
+      program->IsNVProgram = GL_TRUE;
+
+#ifdef DEBUG_foo
+      printf("--- glLoadProgramNV result ---\n");
+      _mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0);
+      printf("------------------------------\n");
+#endif
+
+      if (program->Base.Parameters)
+        _mesa_free_parameter_list(program->Base.Parameters);
+
+      program->Base.Parameters = _mesa_new_parameter_list ();
+      program->Base.NumParameters = 0;
+
+      state_tokens[0] = STATE_VERTEX_PROGRAM;
+      state_tokens[1] = STATE_ENV;
+      /* Add refs to all of the potential params, in order.  If we want to not
+       * upload everything, _mesa_layout_parameters is the answer.
+       */
+      for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS; i++) {
+        GLint index;
+        state_tokens[2] = i;
+        index = _mesa_add_state_reference(program->Base.Parameters,
+                                          state_tokens);
+        assert(index == i);
+      }
+      program->Base.NumParameters = program->Base.Parameters->NumParameters;
+
+      _mesa_setup_nv_temporary_count(ctx, &program->Base);
+      _mesa_emit_nv_temp_initialization(ctx, &program->Base);
+   }
+   else {
+      /* Error! */
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV");
+      /* NOTE: _mesa_set_program_error would have been called already */
+      /* GL_NV_vertex_program isn't supposed to set the error string
+       * so we reset it here.
+       */
+      _mesa_set_program_error(ctx, ctx->Program.ErrorPos, NULL);
+   }
+}
+
+
+const char *
+_mesa_nv_vertex_input_register_name(GLuint i)
+{
+   ASSERT(i < MAX_NV_VERTEX_PROGRAM_INPUTS);
+   return InputRegisters[i];
+}
+
+
+const char *
+_mesa_nv_vertex_output_register_name(GLuint i)
+{
+   ASSERT(i < MAX_NV_VERTEX_PROGRAM_OUTPUTS);
+   return OutputRegisters[i];
+}
+
diff --git a/src/mesa/program/nvvertparse.h b/src/mesa/program/nvvertparse.h
new file mode 100644 (file)
index 0000000..9919e22
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  5.1
+ *
+ * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Brian Paul
+ */
+
+
+#ifndef NVVERTPARSE_H
+#define NVVERTPARSE_H
+
+
+extern void
+_mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum target,
+                              const GLubyte *str, GLsizei len,
+                              struct gl_vertex_program *program);
+
+
+extern const char *
+_mesa_nv_vertex_input_register_name(GLuint i);
+
+extern const char *
+_mesa_nv_vertex_output_register_name(GLuint i);
+
+#endif
diff --git a/src/mesa/program/prog_cache.c b/src/mesa/program/prog_cache.c
new file mode 100644 (file)
index 0000000..8af6897
--- /dev/null
@@ -0,0 +1,206 @@
+/**************************************************************************
+ * 
+ * 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/mtypes.h"
+#include "main/imports.h"
+#include "program/prog_cache.h"
+#include "program/program.h"
+
+
+struct cache_item
+{
+   GLuint hash;
+   void *key;
+   struct gl_program *program;
+   struct cache_item *next;
+};
+
+struct gl_program_cache
+{
+   struct cache_item **items;
+   struct cache_item *last;
+   GLuint size, n_items;
+};
+
+
+
+/**
+ * Compute hash index from state key.
+ */
+static GLuint
+hash_key(const void *key, GLuint key_size)
+{
+   const GLuint *ikey = (const GLuint *) key;
+   GLuint hash = 0, i;
+
+   assert(key_size >= 4);
+
+   /* Make a slightly better attempt at a hash function:
+    */
+   for (i = 0; i < key_size / sizeof(*ikey); i++)
+   {
+      hash += ikey[i];
+      hash += (hash << 10);
+      hash ^= (hash >> 6);
+   }
+
+   return hash;
+}
+
+
+/**
+ * Rebuild/expand the hash table to accomodate more entries
+ */
+static void
+rehash(struct gl_program_cache *cache)
+{
+   struct cache_item **items;
+   struct cache_item *c, *next;
+   GLuint size, i;
+
+   cache->last = NULL;
+
+   size = cache->size * 3;
+   items = (struct cache_item**) malloc(size * sizeof(*items));
+   memset(items, 0, size * sizeof(*items));
+
+   for (i = 0; i < cache->size; i++)
+      for (c = cache->items[i]; c; c = next) {
+        next = c->next;
+        c->next = items[c->hash % size];
+        items[c->hash % size] = c;
+      }
+
+   free(cache->items);
+   cache->items = items;
+   cache->size = size;
+}
+
+
+static void
+clear_cache(GLcontext *ctx, struct gl_program_cache *cache)
+{
+   struct cache_item *c, *next;
+   GLuint i;
+   
+   cache->last = NULL;
+
+   for (i = 0; i < cache->size; i++) {
+      for (c = cache->items[i]; c; c = next) {
+        next = c->next;
+        free(c->key);
+         _mesa_reference_program(ctx, &c->program, NULL);
+        free(c);
+      }
+      cache->items[i] = NULL;
+   }
+
+
+   cache->n_items = 0;
+}
+
+
+
+struct gl_program_cache *
+_mesa_new_program_cache(void)
+{
+   struct gl_program_cache *cache = CALLOC_STRUCT(gl_program_cache);
+   if (cache) {
+      cache->size = 17;
+      cache->items = (struct cache_item **)
+         calloc(1, cache->size * sizeof(struct cache_item));
+      if (!cache->items) {
+         free(cache);
+         return NULL;
+      }
+   }
+   return cache;
+}
+
+
+void
+_mesa_delete_program_cache(GLcontext *ctx, struct gl_program_cache *cache)
+{
+   clear_cache(ctx, cache);
+   free(cache->items);
+   free(cache);
+}
+
+
+struct gl_program *
+_mesa_search_program_cache(struct gl_program_cache *cache,
+                           const void *key, GLuint keysize)
+{
+   if (cache->last && 
+       memcmp(cache->last->key, key, keysize) == 0) {
+      return cache->last->program;
+   }
+   else {
+      const GLuint hash = hash_key(key, keysize);
+      struct cache_item *c;
+
+      for (c = cache->items[hash % cache->size]; c; c = c->next) {
+         if (c->hash == hash && memcmp(c->key, key, keysize) == 0) {
+            cache->last = c;
+            return c->program;
+         }
+      }
+
+      return NULL;
+   }
+}
+
+
+void
+_mesa_program_cache_insert(GLcontext *ctx,
+                           struct gl_program_cache *cache,
+                           const void *key, GLuint keysize,
+                           struct gl_program *program)
+{
+   const GLuint hash = hash_key(key, keysize);
+   struct cache_item *c = CALLOC_STRUCT(cache_item);
+
+   c->hash = hash;
+
+   c->key = malloc(keysize);
+   memcpy(c->key, key, keysize);
+
+   c->program = program;  /* no refcount change */
+
+   if (cache->n_items > cache->size * 1.5) {
+      if (cache->size < 1000)
+        rehash(cache);
+      else 
+        clear_cache(ctx, cache);
+   }
+
+   cache->n_items++;
+   c->next = cache->items[hash % cache->size];
+   cache->items[hash % cache->size] = c;
+}
diff --git a/src/mesa/program/prog_cache.h b/src/mesa/program/prog_cache.h
new file mode 100644 (file)
index 0000000..4e1ccac
--- /dev/null
@@ -0,0 +1,55 @@
+/**************************************************************************
+ * 
+ * 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 PROG_CACHE_H
+#define PROG_CACHE_H
+
+
+/** Opaque type */
+struct gl_program_cache;
+
+
+extern struct gl_program_cache *
+_mesa_new_program_cache(void);
+
+extern void
+_mesa_delete_program_cache(GLcontext *ctx, struct gl_program_cache *pc);
+
+
+extern struct gl_program *
+_mesa_search_program_cache(struct gl_program_cache *cache,
+                           const void *key, GLuint keysize);
+
+extern void
+_mesa_program_cache_insert(GLcontext *ctx,
+                           struct gl_program_cache *cache,
+                           const void *key, GLuint keysize,
+                           struct gl_program *program);
+
+
+#endif /* PROG_CACHE_H */
diff --git a/src/mesa/program/prog_execute.c b/src/mesa/program/prog_execute.c
new file mode 100644 (file)
index 0000000..b6da344
--- /dev/null
@@ -0,0 +1,1802 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.3
+ *
+ * Copyright (C) 1999-2008  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 prog_execute.c
+ * Software interpreter for vertex/fragment programs.
+ * \author Brian Paul
+ */
+
+/*
+ * NOTE: we do everything in single-precision floating point; we don't
+ * currently observe the single/half/fixed-precision qualifiers.
+ *
+ */
+
+
+#include "main/glheader.h"
+#include "main/colormac.h"
+#include "main/context.h"
+#include "prog_execute.h"
+#include "prog_instruction.h"
+#include "prog_parameter.h"
+#include "prog_print.h"
+#include "prog_noise.h"
+
+
+/* debug predicate */
+#define DEBUG_PROG 0
+
+
+/**
+ * Set x to positive or negative infinity.
+ */
+#if defined(USE_IEEE) || defined(_WIN32)
+#define SET_POS_INFINITY(x)                  \
+   do {                                      \
+         fi_type fi;                         \
+         fi.i = 0x7F800000;                  \
+         x = fi.f;                           \
+   } while (0)
+#define SET_NEG_INFINITY(x)                  \
+   do {                                      \
+         fi_type fi;                         \
+         fi.i = 0xFF800000;                  \
+         x = fi.f;                           \
+   } while (0)
+#elif defined(VMS)
+#define SET_POS_INFINITY(x)  x = __MAXFLOAT
+#define SET_NEG_INFINITY(x)  x = -__MAXFLOAT
+#else
+#define SET_POS_INFINITY(x)  x = (GLfloat) HUGE_VAL
+#define SET_NEG_INFINITY(x)  x = (GLfloat) -HUGE_VAL
+#endif
+
+#define SET_FLOAT_BITS(x, bits) ((fi_type *) (void *) &(x))->i = bits
+
+
+static const GLfloat ZeroVec[4] = { 0.0F, 0.0F, 0.0F, 0.0F };
+
+
+
+/**
+ * Return a pointer to the 4-element float vector specified by the given
+ * source register.
+ */
+static INLINE const GLfloat *
+get_src_register_pointer(const struct prog_src_register *source,
+                         const struct gl_program_machine *machine)
+{
+   const struct gl_program *prog = machine->CurProgram;
+   GLint reg = source->Index;
+
+   if (source->RelAddr) {
+      /* add address register value to src index/offset */
+      reg += machine->AddressReg[0][0];
+      if (reg < 0) {
+         return ZeroVec;
+      }
+   }
+
+   switch (source->File) {
+   case PROGRAM_TEMPORARY:
+      if (reg >= MAX_PROGRAM_TEMPS)
+         return ZeroVec;
+      return machine->Temporaries[reg];
+
+   case PROGRAM_INPUT:
+      if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
+         if (reg >= VERT_ATTRIB_MAX)
+            return ZeroVec;
+         return machine->VertAttribs[reg];
+      }
+      else {
+         if (reg >= FRAG_ATTRIB_MAX)
+            return ZeroVec;
+         return machine->Attribs[reg][machine->CurElement];
+      }
+
+   case PROGRAM_OUTPUT:
+      if (reg >= MAX_PROGRAM_OUTPUTS)
+         return ZeroVec;
+      return machine->Outputs[reg];
+
+   case PROGRAM_LOCAL_PARAM:
+      if (reg >= MAX_PROGRAM_LOCAL_PARAMS)
+         return ZeroVec;
+      return machine->CurProgram->LocalParams[reg];
+
+   case PROGRAM_ENV_PARAM:
+      if (reg >= MAX_PROGRAM_ENV_PARAMS)
+         return ZeroVec;
+      return machine->EnvParams[reg];
+
+   case PROGRAM_STATE_VAR:
+      /* Fallthrough */
+   case PROGRAM_CONSTANT:
+      /* Fallthrough */
+   case PROGRAM_UNIFORM:
+      /* Fallthrough */
+   case PROGRAM_NAMED_PARAM:
+      if (reg >= (GLint) prog->Parameters->NumParameters)
+         return ZeroVec;
+      return prog->Parameters->ParameterValues[reg];
+
+   default:
+      _mesa_problem(NULL,
+         "Invalid src register file %d in get_src_register_pointer()",
+         source->File);
+      return NULL;
+   }
+}
+
+
+/**
+ * Return a pointer to the 4-element float vector specified by the given
+ * destination register.
+ */
+static INLINE GLfloat *
+get_dst_register_pointer(const struct prog_dst_register *dest,
+                         struct gl_program_machine *machine)
+{
+   static GLfloat dummyReg[4];
+   GLint reg = dest->Index;
+
+   if (dest->RelAddr) {
+      /* add address register value to src index/offset */
+      reg += machine->AddressReg[0][0];
+      if (reg < 0) {
+         return dummyReg;
+      }
+   }
+
+   switch (dest->File) {
+   case PROGRAM_TEMPORARY:
+      if (reg >= MAX_PROGRAM_TEMPS)
+         return dummyReg;
+      return machine->Temporaries[reg];
+
+   case PROGRAM_OUTPUT:
+      if (reg >= MAX_PROGRAM_OUTPUTS)
+         return dummyReg;
+      return machine->Outputs[reg];
+
+   case PROGRAM_WRITE_ONLY:
+      return dummyReg;
+
+   default:
+      _mesa_problem(NULL,
+         "Invalid dest register file %d in get_dst_register_pointer()",
+         dest->File);
+      return NULL;
+   }
+}
+
+
+
+/**
+ * Fetch a 4-element float vector from the given source register.
+ * Apply swizzling and negating as needed.
+ */
+static void
+fetch_vector4(const struct prog_src_register *source,
+              const struct gl_program_machine *machine, GLfloat result[4])
+{
+   const GLfloat *src = get_src_register_pointer(source, machine);
+   ASSERT(src);
+
+   if (source->Swizzle == SWIZZLE_NOOP) {
+      /* no swizzling */
+      COPY_4V(result, src);
+   }
+   else {
+      ASSERT(GET_SWZ(source->Swizzle, 0) <= 3);
+      ASSERT(GET_SWZ(source->Swizzle, 1) <= 3);
+      ASSERT(GET_SWZ(source->Swizzle, 2) <= 3);
+      ASSERT(GET_SWZ(source->Swizzle, 3) <= 3);
+      result[0] = src[GET_SWZ(source->Swizzle, 0)];
+      result[1] = src[GET_SWZ(source->Swizzle, 1)];
+      result[2] = src[GET_SWZ(source->Swizzle, 2)];
+      result[3] = src[GET_SWZ(source->Swizzle, 3)];
+   }
+
+   if (source->Abs) {
+      result[0] = FABSF(result[0]);
+      result[1] = FABSF(result[1]);
+      result[2] = FABSF(result[2]);
+      result[3] = FABSF(result[3]);
+   }
+   if (source->Negate) {
+      ASSERT(source->Negate == NEGATE_XYZW);
+      result[0] = -result[0];
+      result[1] = -result[1];
+      result[2] = -result[2];
+      result[3] = -result[3];
+   }
+
+#ifdef NAN_CHECK
+   assert(!IS_INF_OR_NAN(result[0]));
+   assert(!IS_INF_OR_NAN(result[0]));
+   assert(!IS_INF_OR_NAN(result[0]));
+   assert(!IS_INF_OR_NAN(result[0]));
+#endif
+}
+
+
+/**
+ * Fetch a 4-element uint vector from the given source register.
+ * Apply swizzling but not negation/abs.
+ */
+static void
+fetch_vector4ui(const struct prog_src_register *source,
+                const struct gl_program_machine *machine, GLuint result[4])
+{
+   const GLuint *src = (GLuint *) get_src_register_pointer(source, machine);
+   ASSERT(src);
+
+   if (source->Swizzle == SWIZZLE_NOOP) {
+      /* no swizzling */
+      COPY_4V(result, src);
+   }
+   else {
+      ASSERT(GET_SWZ(source->Swizzle, 0) <= 3);
+      ASSERT(GET_SWZ(source->Swizzle, 1) <= 3);
+      ASSERT(GET_SWZ(source->Swizzle, 2) <= 3);
+      ASSERT(GET_SWZ(source->Swizzle, 3) <= 3);
+      result[0] = src[GET_SWZ(source->Swizzle, 0)];
+      result[1] = src[GET_SWZ(source->Swizzle, 1)];
+      result[2] = src[GET_SWZ(source->Swizzle, 2)];
+      result[3] = src[GET_SWZ(source->Swizzle, 3)];
+   }
+
+   /* Note: no Negate or Abs here */
+}
+
+
+
+/**
+ * Fetch the derivative with respect to X or Y for the given register.
+ * XXX this currently only works for fragment program input attribs.
+ */
+static void
+fetch_vector4_deriv(GLcontext * ctx,
+                    const struct prog_src_register *source,
+                    const struct gl_program_machine *machine,
+                    char xOrY, GLfloat result[4])
+{
+   if (source->File == PROGRAM_INPUT &&
+       source->Index < (GLint) machine->NumDeriv) {
+      const GLint col = machine->CurElement;
+      const GLfloat w = machine->Attribs[FRAG_ATTRIB_WPOS][col][3];
+      const GLfloat invQ = 1.0f / w;
+      GLfloat deriv[4];
+
+      if (xOrY == 'X') {
+         deriv[0] = machine->DerivX[source->Index][0] * invQ;
+         deriv[1] = machine->DerivX[source->Index][1] * invQ;
+         deriv[2] = machine->DerivX[source->Index][2] * invQ;
+         deriv[3] = machine->DerivX[source->Index][3] * invQ;
+      }
+      else {
+         deriv[0] = machine->DerivY[source->Index][0] * invQ;
+         deriv[1] = machine->DerivY[source->Index][1] * invQ;
+         deriv[2] = machine->DerivY[source->Index][2] * invQ;
+         deriv[3] = machine->DerivY[source->Index][3] * invQ;
+      }
+
+      result[0] = deriv[GET_SWZ(source->Swizzle, 0)];
+      result[1] = deriv[GET_SWZ(source->Swizzle, 1)];
+      result[2] = deriv[GET_SWZ(source->Swizzle, 2)];
+      result[3] = deriv[GET_SWZ(source->Swizzle, 3)];
+      
+      if (source->Abs) {
+         result[0] = FABSF(result[0]);
+         result[1] = FABSF(result[1]);
+         result[2] = FABSF(result[2]);
+         result[3] = FABSF(result[3]);
+      }
+      if (source->Negate) {
+         ASSERT(source->Negate == NEGATE_XYZW);
+         result[0] = -result[0];
+         result[1] = -result[1];
+         result[2] = -result[2];
+         result[3] = -result[3];
+      }
+   }
+   else {
+      ASSIGN_4V(result, 0.0, 0.0, 0.0, 0.0);
+   }
+}
+
+
+/**
+ * As above, but only return result[0] element.
+ */
+static void
+fetch_vector1(const struct prog_src_register *source,
+              const struct gl_program_machine *machine, GLfloat result[4])
+{
+   const GLfloat *src = get_src_register_pointer(source, machine);
+   ASSERT(src);
+
+   result[0] = src[GET_SWZ(source->Swizzle, 0)];
+
+   if (source->Abs) {
+      result[0] = FABSF(result[0]);
+   }
+   if (source->Negate) {
+      result[0] = -result[0];
+   }
+}
+
+
+static GLuint
+fetch_vector1ui(const struct prog_src_register *source,
+                const struct gl_program_machine *machine)
+{
+   const GLuint *src = (GLuint *) get_src_register_pointer(source, machine);
+   return src[GET_SWZ(source->Swizzle, 0)];
+}
+
+
+/**
+ * Fetch texel from texture.  Use partial derivatives when possible.
+ */
+static INLINE void
+fetch_texel(GLcontext *ctx,
+            const struct gl_program_machine *machine,
+            const struct prog_instruction *inst,
+            const GLfloat texcoord[4], GLfloat lodBias,
+            GLfloat color[4])
+{
+   const GLuint unit = machine->Samplers[inst->TexSrcUnit];
+
+   /* Note: we only have the right derivatives for fragment input attribs.
+    */
+   if (machine->NumDeriv > 0 &&
+       inst->SrcReg[0].File == PROGRAM_INPUT &&
+       inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit) {
+      /* simple texture fetch for which we should have derivatives */
+      GLuint attr = inst->SrcReg[0].Index;
+      machine->FetchTexelDeriv(ctx, texcoord,
+                               machine->DerivX[attr],
+                               machine->DerivY[attr],
+                               lodBias, unit, color);
+   }
+   else {
+      machine->FetchTexelLod(ctx, texcoord, lodBias, unit, color);
+   }
+}
+
+
+/**
+ * Test value against zero and return GT, LT, EQ or UN if NaN.
+ */
+static INLINE GLuint
+generate_cc(float value)
+{
+   if (value != value)
+      return COND_UN;           /* NaN */
+   if (value > 0.0F)
+      return COND_GT;
+   if (value < 0.0F)
+      return COND_LT;
+   return COND_EQ;
+}
+
+
+/**
+ * Test if the ccMaskRule is satisfied by the given condition code.
+ * Used to mask destination writes according to the current condition code.
+ */
+static INLINE GLboolean
+test_cc(GLuint condCode, GLuint ccMaskRule)
+{
+   switch (ccMaskRule) {
+   case COND_EQ: return (condCode == COND_EQ);
+   case COND_NE: return (condCode != COND_EQ);
+   case COND_LT: return (condCode == COND_LT);
+   case COND_GE: return (condCode == COND_GT || condCode == COND_EQ);
+   case COND_LE: return (condCode == COND_LT || condCode == COND_EQ);
+   case COND_GT: return (condCode == COND_GT);
+   case COND_TR: return GL_TRUE;
+   case COND_FL: return GL_FALSE;
+   default:      return GL_TRUE;
+   }
+}
+
+
+/**
+ * Evaluate the 4 condition codes against a predicate and return GL_TRUE
+ * or GL_FALSE to indicate result.
+ */
+static INLINE GLboolean
+eval_condition(const struct gl_program_machine *machine,
+               const struct prog_instruction *inst)
+{
+   const GLuint swizzle = inst->DstReg.CondSwizzle;
+   const GLuint condMask = inst->DstReg.CondMask;
+   if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
+       test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
+       test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
+       test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
+      return GL_TRUE;
+   }
+   else {
+      return GL_FALSE;
+   }
+}
+
+
+
+/**
+ * Store 4 floats into a register.  Observe the instructions saturate and
+ * set-condition-code flags.
+ */
+static void
+store_vector4(const struct prog_instruction *inst,
+              struct gl_program_machine *machine, const GLfloat value[4])
+{
+   const struct prog_dst_register *dstReg = &(inst->DstReg);
+   const GLboolean clamp = inst->SaturateMode == SATURATE_ZERO_ONE;
+   GLuint writeMask = dstReg->WriteMask;
+   GLfloat clampedValue[4];
+   GLfloat *dst = get_dst_register_pointer(dstReg, machine);
+
+#if 0
+   if (value[0] > 1.0e10 ||
+       IS_INF_OR_NAN(value[0]) ||
+       IS_INF_OR_NAN(value[1]) ||
+       IS_INF_OR_NAN(value[2]) || IS_INF_OR_NAN(value[3]))
+      printf("store %g %g %g %g\n", value[0], value[1], value[2], value[3]);
+#endif
+
+   if (clamp) {
+      clampedValue[0] = CLAMP(value[0], 0.0F, 1.0F);
+      clampedValue[1] = CLAMP(value[1], 0.0F, 1.0F);
+      clampedValue[2] = CLAMP(value[2], 0.0F, 1.0F);
+      clampedValue[3] = CLAMP(value[3], 0.0F, 1.0F);
+      value = clampedValue;
+   }
+
+   if (dstReg->CondMask != COND_TR) {
+      /* condition codes may turn off some writes */
+      if (writeMask & WRITEMASK_X) {
+         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 0)],
+                      dstReg->CondMask))
+            writeMask &= ~WRITEMASK_X;
+      }
+      if (writeMask & WRITEMASK_Y) {
+         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 1)],
+                      dstReg->CondMask))
+            writeMask &= ~WRITEMASK_Y;
+      }
+      if (writeMask & WRITEMASK_Z) {
+         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 2)],
+                      dstReg->CondMask))
+            writeMask &= ~WRITEMASK_Z;
+      }
+      if (writeMask & WRITEMASK_W) {
+         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 3)],
+                      dstReg->CondMask))
+            writeMask &= ~WRITEMASK_W;
+      }
+   }
+
+#ifdef NAN_CHECK
+   assert(!IS_INF_OR_NAN(value[0]));
+   assert(!IS_INF_OR_NAN(value[0]));
+   assert(!IS_INF_OR_NAN(value[0]));
+   assert(!IS_INF_OR_NAN(value[0]));
+#endif
+
+   if (writeMask & WRITEMASK_X)
+      dst[0] = value[0];
+   if (writeMask & WRITEMASK_Y)
+      dst[1] = value[1];
+   if (writeMask & WRITEMASK_Z)
+      dst[2] = value[2];
+   if (writeMask & WRITEMASK_W)
+      dst[3] = value[3];
+
+   if (inst->CondUpdate) {
+      if (writeMask & WRITEMASK_X)
+         machine->CondCodes[0] = generate_cc(value[0]);
+      if (writeMask & WRITEMASK_Y)
+         machine->CondCodes[1] = generate_cc(value[1]);
+      if (writeMask & WRITEMASK_Z)
+         machine->CondCodes[2] = generate_cc(value[2]);
+      if (writeMask & WRITEMASK_W)
+         machine->CondCodes[3] = generate_cc(value[3]);
+#if DEBUG_PROG
+      printf("CondCodes=(%s,%s,%s,%s) for:\n",
+             _mesa_condcode_string(machine->CondCodes[0]),
+             _mesa_condcode_string(machine->CondCodes[1]),
+             _mesa_condcode_string(machine->CondCodes[2]),
+             _mesa_condcode_string(machine->CondCodes[3]));
+#endif
+   }
+}
+
+
+/**
+ * Store 4 uints into a register.  Observe the set-condition-code flags.
+ */
+static void
+store_vector4ui(const struct prog_instruction *inst,
+                struct gl_program_machine *machine, const GLuint value[4])
+{
+   const struct prog_dst_register *dstReg = &(inst->DstReg);
+   GLuint writeMask = dstReg->WriteMask;
+   GLuint *dst = (GLuint *) get_dst_register_pointer(dstReg, machine);
+
+   if (dstReg->CondMask != COND_TR) {
+      /* condition codes may turn off some writes */
+      if (writeMask & WRITEMASK_X) {
+         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 0)],
+                      dstReg->CondMask))
+            writeMask &= ~WRITEMASK_X;
+      }
+      if (writeMask & WRITEMASK_Y) {
+         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 1)],
+                      dstReg->CondMask))
+            writeMask &= ~WRITEMASK_Y;
+      }
+      if (writeMask & WRITEMASK_Z) {
+         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 2)],
+                      dstReg->CondMask))
+            writeMask &= ~WRITEMASK_Z;
+      }
+      if (writeMask & WRITEMASK_W) {
+         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 3)],
+                      dstReg->CondMask))
+            writeMask &= ~WRITEMASK_W;
+      }
+   }
+
+   if (writeMask & WRITEMASK_X)
+      dst[0] = value[0];
+   if (writeMask & WRITEMASK_Y)
+      dst[1] = value[1];
+   if (writeMask & WRITEMASK_Z)
+      dst[2] = value[2];
+   if (writeMask & WRITEMASK_W)
+      dst[3] = value[3];
+
+   if (inst->CondUpdate) {
+      if (writeMask & WRITEMASK_X)
+         machine->CondCodes[0] = generate_cc((float)value[0]);
+      if (writeMask & WRITEMASK_Y)
+         machine->CondCodes[1] = generate_cc((float)value[1]);
+      if (writeMask & WRITEMASK_Z)
+         machine->CondCodes[2] = generate_cc((float)value[2]);
+      if (writeMask & WRITEMASK_W)
+         machine->CondCodes[3] = generate_cc((float)value[3]);
+#if DEBUG_PROG
+      printf("CondCodes=(%s,%s,%s,%s) for:\n",
+             _mesa_condcode_string(machine->CondCodes[0]),
+             _mesa_condcode_string(machine->CondCodes[1]),
+             _mesa_condcode_string(machine->CondCodes[2]),
+             _mesa_condcode_string(machine->CondCodes[3]));
+#endif
+   }
+}
+
+
+
+/**
+ * Execute the given vertex/fragment program.
+ *
+ * \param ctx  rendering context
+ * \param program  the program to execute
+ * \param machine  machine state (must be initialized)
+ * \return GL_TRUE if program completed or GL_FALSE if program executed KIL.
+ */
+GLboolean
+_mesa_execute_program(GLcontext * ctx,
+                      const struct gl_program *program,
+                      struct gl_program_machine *machine)
+{
+   const GLuint numInst = program->NumInstructions;
+   const GLuint maxExec = 10000;
+   GLuint pc, numExec = 0;
+
+   machine->CurProgram = program;
+
+   if (DEBUG_PROG) {
+      printf("execute program %u --------------------\n", program->Id);
+   }
+
+   if (program->Target == GL_VERTEX_PROGRAM_ARB) {
+      machine->EnvParams = ctx->VertexProgram.Parameters;
+   }
+   else {
+      machine->EnvParams = ctx->FragmentProgram.Parameters;
+   }
+
+   for (pc = 0; pc < numInst; pc++) {
+      const struct prog_instruction *inst = program->Instructions + pc;
+
+      if (DEBUG_PROG) {
+         _mesa_print_instruction(inst);
+      }
+
+      switch (inst->Opcode) {
+      case OPCODE_ABS:
+         {
+            GLfloat a[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            result[0] = FABSF(a[0]);
+            result[1] = FABSF(a[1]);
+            result[2] = FABSF(a[2]);
+            result[3] = FABSF(a[3]);
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_ADD:
+         {
+            GLfloat a[4], b[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            result[0] = a[0] + b[0];
+            result[1] = a[1] + b[1];
+            result[2] = a[2] + b[2];
+            result[3] = a[3] + b[3];
+            store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("ADD (%g %g %g %g) = (%g %g %g %g) + (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
+            }
+         }
+         break;
+      case OPCODE_AND:     /* bitwise AND */
+         {
+            GLuint a[4], b[4], result[4];
+            fetch_vector4ui(&inst->SrcReg[0], machine, a);
+            fetch_vector4ui(&inst->SrcReg[1], machine, b);
+            result[0] = a[0] & b[0];
+            result[1] = a[1] & b[1];
+            result[2] = a[2] & b[2];
+            result[3] = a[3] & b[3];
+            store_vector4ui(inst, machine, result);
+         }
+         break;
+      case OPCODE_ARL:
+         {
+            GLfloat t[4];
+            fetch_vector4(&inst->SrcReg[0], machine, t);
+            machine->AddressReg[0][0] = IFLOOR(t[0]);
+            if (DEBUG_PROG) {
+               printf("ARL %d\n", machine->AddressReg[0][0]);
+            }
+         }
+         break;
+      case OPCODE_BGNLOOP:
+         /* no-op */
+         ASSERT(program->Instructions[inst->BranchTarget].Opcode
+                == OPCODE_ENDLOOP);
+         break;
+      case OPCODE_ENDLOOP:
+         /* subtract 1 here since pc is incremented by for(pc) loop */
+         ASSERT(program->Instructions[inst->BranchTarget].Opcode
+                == OPCODE_BGNLOOP);
+         pc = inst->BranchTarget - 1;   /* go to matching BNGLOOP */
+         break;
+      case OPCODE_BGNSUB:      /* begin subroutine */
+         break;
+      case OPCODE_ENDSUB:      /* end subroutine */
+         break;
+      case OPCODE_BRA:         /* branch (conditional) */
+         if (eval_condition(machine, inst)) {
+            /* take branch */
+            /* Subtract 1 here since we'll do pc++ below */
+            pc = inst->BranchTarget - 1;
+         }
+         break;
+      case OPCODE_BRK:         /* break out of loop (conditional) */
+         ASSERT(program->Instructions[inst->BranchTarget].Opcode
+                == OPCODE_ENDLOOP);
+         if (eval_condition(machine, inst)) {
+            /* break out of loop */
+            /* pc++ at end of for-loop will put us after the ENDLOOP inst */
+            pc = inst->BranchTarget;
+         }
+         break;
+      case OPCODE_CONT:        /* continue loop (conditional) */
+         ASSERT(program->Instructions[inst->BranchTarget].Opcode
+                == OPCODE_ENDLOOP);
+         if (eval_condition(machine, inst)) {
+            /* continue at ENDLOOP */
+            /* Subtract 1 here since we'll do pc++ at end of for-loop */
+            pc = inst->BranchTarget - 1;
+         }
+         break;
+      case OPCODE_CAL:         /* Call subroutine (conditional) */
+         if (eval_condition(machine, inst)) {
+            /* call the subroutine */
+            if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) {
+               return GL_TRUE;  /* Per GL_NV_vertex_program2 spec */
+            }
+            machine->CallStack[machine->StackDepth++] = pc + 1; /* next inst */
+            /* Subtract 1 here since we'll do pc++ at end of for-loop */
+            pc = inst->BranchTarget - 1;
+         }
+         break;
+      case OPCODE_CMP:
+         {
+            GLfloat a[4], b[4], c[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[2], machine, c);
+            result[0] = a[0] < 0.0F ? b[0] : c[0];
+            result[1] = a[1] < 0.0F ? b[1] : c[1];
+            result[2] = a[2] < 0.0F ? b[2] : c[2];
+            result[3] = a[3] < 0.0F ? b[3] : c[3];
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_COS:
+         {
+            GLfloat a[4], result[4];
+            fetch_vector1(&inst->SrcReg[0], machine, a);
+            result[0] = result[1] = result[2] = result[3]
+               = (GLfloat) cos(a[0]);
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_DDX:         /* Partial derivative with respect to X */
+         {
+            GLfloat result[4];
+            fetch_vector4_deriv(ctx, &inst->SrcReg[0], machine,
+                                'X', result);
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_DDY:         /* Partial derivative with respect to Y */
+         {
+            GLfloat result[4];
+            fetch_vector4_deriv(ctx, &inst->SrcReg[0], machine,
+                                'Y', result);
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_DP2:
+         {
+            GLfloat a[4], b[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            result[0] = result[1] = result[2] = result[3] = DOT2(a, b);
+            store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("DP2 %g = (%g %g) . (%g %g)\n",
+                      result[0], a[0], a[1], b[0], b[1]);
+            }
+         }
+         break;
+      case OPCODE_DP2A:
+         {
+            GLfloat a[4], b[4], c, result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            fetch_vector1(&inst->SrcReg[1], machine, &c);
+            result[0] = result[1] = result[2] = result[3] = DOT2(a, b) + c;
+            store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("DP2A %g = (%g %g) . (%g %g) + %g\n",
+                      result[0], a[0], a[1], b[0], b[1], c);
+            }
+         }
+         break;
+      case OPCODE_DP3:
+         {
+            GLfloat a[4], b[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            result[0] = result[1] = result[2] = result[3] = DOT3(a, b);
+            store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("DP3 %g = (%g %g %g) . (%g %g %g)\n",
+                      result[0], a[0], a[1], a[2], b[0], b[1], b[2]);
+            }
+         }
+         break;
+      case OPCODE_DP4:
+         {
+            GLfloat a[4], b[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            result[0] = result[1] = result[2] = result[3] = DOT4(a, b);
+            store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("DP4 %g = (%g, %g %g %g) . (%g, %g %g %g)\n",
+                      result[0], a[0], a[1], a[2], a[3],
+                      b[0], b[1], b[2], b[3]);
+            }
+         }
+         break;
+      case OPCODE_DPH:
+         {
+            GLfloat a[4], b[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            result[0] = result[1] = result[2] = result[3] = DOT3(a, b) + b[3];
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_DST:         /* Distance vector */
+         {
+            GLfloat a[4], b[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            result[0] = 1.0F;
+            result[1] = a[1] * b[1];
+            result[2] = a[2];
+            result[3] = b[3];
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_EXP:
+         {
+            GLfloat t[4], q[4], floor_t0;
+            fetch_vector1(&inst->SrcReg[0], machine, t);
+            floor_t0 = FLOORF(t[0]);
+            if (floor_t0 > FLT_MAX_EXP) {
+               SET_POS_INFINITY(q[0]);
+               SET_POS_INFINITY(q[2]);
+            }
+            else if (floor_t0 < FLT_MIN_EXP) {
+               q[0] = 0.0F;
+               q[2] = 0.0F;
+            }
+            else {
+               q[0] = LDEXPF(1.0, (int) floor_t0);
+               /* Note: GL_NV_vertex_program expects 
+                * result.z = result.x * APPX(result.y)
+                * We do what the ARB extension says.
+                */
+               q[2] = (GLfloat) pow(2.0, t[0]);
+            }
+            q[1] = t[0] - floor_t0;
+            q[3] = 1.0F;
+            store_vector4( inst, machine, q );
+         }
+         break;
+      case OPCODE_EX2:         /* Exponential base 2 */
+         {
+            GLfloat a[4], result[4], val;
+            fetch_vector1(&inst->SrcReg[0], machine, a);
+            val = (GLfloat) pow(2.0, a[0]);
+            /*
+            if (IS_INF_OR_NAN(val))
+               val = 1.0e10;
+            */
+            result[0] = result[1] = result[2] = result[3] = val;
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_FLR:
+         {
+            GLfloat a[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            result[0] = FLOORF(a[0]);
+            result[1] = FLOORF(a[1]);
+            result[2] = FLOORF(a[2]);
+            result[3] = FLOORF(a[3]);
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_FRC:
+         {
+            GLfloat a[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            result[0] = a[0] - FLOORF(a[0]);
+            result[1] = a[1] - FLOORF(a[1]);
+            result[2] = a[2] - FLOORF(a[2]);
+            result[3] = a[3] - FLOORF(a[3]);
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_IF:
+         {
+            GLboolean cond;
+            ASSERT(program->Instructions[inst->BranchTarget].Opcode
+                   == OPCODE_ELSE ||
+                   program->Instructions[inst->BranchTarget].Opcode
+                   == OPCODE_ENDIF);
+            /* eval condition */
+            if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
+               GLfloat a[4];
+               fetch_vector1(&inst->SrcReg[0], machine, a);
+               cond = (a[0] != 0.0);
+            }
+            else {
+               cond = eval_condition(machine, inst);
+            }
+            if (DEBUG_PROG) {
+               printf("IF: %d\n", cond);
+            }
+            /* do if/else */
+            if (cond) {
+               /* do if-clause (just continue execution) */
+            }
+            else {
+               /* go to the instruction after ELSE or ENDIF */
+               assert(inst->BranchTarget >= 0);
+               pc = inst->BranchTarget;
+            }
+         }
+         break;
+      case OPCODE_ELSE:
+         /* goto ENDIF */
+         ASSERT(program->Instructions[inst->BranchTarget].Opcode
+                == OPCODE_ENDIF);
+         assert(inst->BranchTarget >= 0);
+         pc = inst->BranchTarget;
+         break;
+      case OPCODE_ENDIF:
+         /* nothing */
+         break;
+      case OPCODE_KIL_NV:      /* NV_f_p only (conditional) */
+         if (eval_condition(machine, inst)) {
+            return GL_FALSE;
+         }
+         break;
+      case OPCODE_KIL:         /* ARB_f_p only */
+         {
+            GLfloat a[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            if (DEBUG_PROG) {
+               printf("KIL if (%g %g %g %g) <= 0.0\n",
+                      a[0], a[1], a[2], a[3]);
+            }
+
+            if (a[0] < 0.0F || a[1] < 0.0F || a[2] < 0.0F || a[3] < 0.0F) {
+               return GL_FALSE;
+            }
+         }
+         break;
+      case OPCODE_LG2:         /* log base 2 */
+         {
+            GLfloat a[4], result[4], val;
+            fetch_vector1(&inst->SrcReg[0], machine, a);
+           /* The fast LOG2 macro doesn't meet the precision requirements.
+            */
+            if (a[0] == 0.0F) {
+               val = -FLT_MAX;
+            }
+            else {
+               val = (float)(log(a[0]) * 1.442695F);
+            }
+            result[0] = result[1] = result[2] = result[3] = val;
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_LIT:
+         {
+            const GLfloat epsilon = 1.0F / 256.0F;      /* from NV VP spec */
+            GLfloat a[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            a[0] = MAX2(a[0], 0.0F);
+            a[1] = MAX2(a[1], 0.0F);
+            /* XXX ARB version clamps a[3], NV version doesn't */
+            a[3] = CLAMP(a[3], -(128.0F - epsilon), (128.0F - epsilon));
+            result[0] = 1.0F;
+            result[1] = a[0];
+            /* XXX we could probably just use pow() here */
+            if (a[0] > 0.0F) {
+               if (a[1] == 0.0 && a[3] == 0.0)
+                  result[2] = 1.0F;
+               else
+                  result[2] = (GLfloat) pow(a[1], a[3]);
+            }
+            else {
+               result[2] = 0.0F;
+            }
+            result[3] = 1.0F;
+            store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("LIT (%g %g %g %g) : (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], a[3]);
+            }
+         }
+         break;
+      case OPCODE_LOG:
+         {
+            GLfloat t[4], q[4], abs_t0;
+            fetch_vector1(&inst->SrcReg[0], machine, t);
+            abs_t0 = FABSF(t[0]);
+            if (abs_t0 != 0.0F) {
+               /* Since we really can't handle infinite values on VMS
+                * like other OSes we'll use __MAXFLOAT to represent
+                * infinity.  This may need some tweaking.
+                */
+#ifdef VMS
+               if (abs_t0 == __MAXFLOAT)
+#else
+               if (IS_INF_OR_NAN(abs_t0))
+#endif
+               {
+                  SET_POS_INFINITY(q[0]);
+                  q[1] = 1.0F;
+                  SET_POS_INFINITY(q[2]);
+               }
+               else {
+                  int exponent;
+                  GLfloat mantissa = FREXPF(t[0], &exponent);
+                  q[0] = (GLfloat) (exponent - 1);
+                  q[1] = (GLfloat) (2.0 * mantissa); /* map [.5, 1) -> [1, 2) */
+
+                 /* The fast LOG2 macro doesn't meet the precision
+                  * requirements.
+                  */
+                  q[2] = (float)(log(t[0]) * 1.442695F);
+               }
+            }
+            else {
+               SET_NEG_INFINITY(q[0]);
+               q[1] = 1.0F;
+               SET_NEG_INFINITY(q[2]);
+            }
+            q[3] = 1.0;
+            store_vector4(inst, machine, q);
+         }
+         break;
+      case OPCODE_LRP:
+         {
+            GLfloat a[4], b[4], c[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[2], machine, c);
+            result[0] = a[0] * b[0] + (1.0F - a[0]) * c[0];
+            result[1] = a[1] * b[1] + (1.0F - a[1]) * c[1];
+            result[2] = a[2] * b[2] + (1.0F - a[2]) * c[2];
+            result[3] = a[3] * b[3] + (1.0F - a[3]) * c[3];
+            store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("LRP (%g %g %g %g) = (%g %g %g %g), "
+                      "(%g %g %g %g), (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], a[3],
+                      b[0], b[1], b[2], b[3], c[0], c[1], c[2], c[3]);
+            }
+         }
+         break;
+      case OPCODE_MAD:
+         {
+            GLfloat a[4], b[4], c[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[2], machine, c);
+            result[0] = a[0] * b[0] + c[0];
+            result[1] = a[1] * b[1] + c[1];
+            result[2] = a[2] * b[2] + c[2];
+            result[3] = a[3] * b[3] + c[3];
+            store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("MAD (%g %g %g %g) = (%g %g %g %g) * "
+                      "(%g %g %g %g) + (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], a[3],
+                      b[0], b[1], b[2], b[3], c[0], c[1], c[2], c[3]);
+            }
+         }
+         break;
+      case OPCODE_MAX:
+         {
+            GLfloat a[4], b[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            result[0] = MAX2(a[0], b[0]);
+            result[1] = MAX2(a[1], b[1]);
+            result[2] = MAX2(a[2], b[2]);
+            result[3] = MAX2(a[3], b[3]);
+            store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("MAX (%g %g %g %g) = (%g %g %g %g), (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
+            }
+         }
+         break;
+      case OPCODE_MIN:
+         {
+            GLfloat a[4], b[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            result[0] = MIN2(a[0], b[0]);
+            result[1] = MIN2(a[1], b[1]);
+            result[2] = MIN2(a[2], b[2]);
+            result[3] = MIN2(a[3], b[3]);
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_MOV:
+         {
+            GLfloat result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, result);
+            store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("MOV (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3]);
+            }
+         }
+         break;
+      case OPCODE_MUL:
+         {
+            GLfloat a[4], b[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            result[0] = a[0] * b[0];
+            result[1] = a[1] * b[1];
+            result[2] = a[2] * b[2];
+            result[3] = a[3] * b[3];
+            store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("MUL (%g %g %g %g) = (%g %g %g %g) * (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
+            }
+         }
+         break;
+      case OPCODE_NOISE1:
+         {
+            GLfloat a[4], result[4];
+            fetch_vector1(&inst->SrcReg[0], machine, a);
+            result[0] =
+               result[1] =
+               result[2] =
+               result[3] = _mesa_noise1(a[0]);
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_NOISE2:
+         {
+            GLfloat a[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            result[0] =
+               result[1] =
+               result[2] = result[3] = _mesa_noise2(a[0], a[1]);
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_NOISE3:
+         {
+            GLfloat a[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            result[0] =
+               result[1] =
+               result[2] =
+               result[3] = _mesa_noise3(a[0], a[1], a[2]);
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_NOISE4:
+         {
+            GLfloat a[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            result[0] =
+               result[1] =
+               result[2] =
+               result[3] = _mesa_noise4(a[0], a[1], a[2], a[3]);
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_NOP:
+         break;
+      case OPCODE_NOT:         /* bitwise NOT */
+         {
+            GLuint a[4], result[4];
+            fetch_vector4ui(&inst->SrcReg[0], machine, a);
+            result[0] = ~a[0];
+            result[1] = ~a[1];
+            result[2] = ~a[2];
+            result[3] = ~a[3];
+            store_vector4ui(inst, machine, result);
+         }
+         break;
+      case OPCODE_NRM3:        /* 3-component normalization */
+         {
+            GLfloat a[4], result[4];
+            GLfloat tmp;
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            tmp = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
+            if (tmp != 0.0F)
+               tmp = INV_SQRTF(tmp);
+            result[0] = tmp * a[0];
+            result[1] = tmp * a[1];
+            result[2] = tmp * a[2];
+            result[3] = 0.0;  /* undefined, but prevent valgrind warnings */
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_NRM4:        /* 4-component normalization */
+         {
+            GLfloat a[4], result[4];
+            GLfloat tmp;
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            tmp = a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3];
+            if (tmp != 0.0F)
+               tmp = INV_SQRTF(tmp);
+            result[0] = tmp * a[0];
+            result[1] = tmp * a[1];
+            result[2] = tmp * a[2];
+            result[3] = tmp * a[3];
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_OR:          /* bitwise OR */
+         {
+            GLuint a[4], b[4], result[4];
+            fetch_vector4ui(&inst->SrcReg[0], machine, a);
+            fetch_vector4ui(&inst->SrcReg[1], machine, b);
+            result[0] = a[0] | b[0];
+            result[1] = a[1] | b[1];
+            result[2] = a[2] | b[2];
+            result[3] = a[3] | b[3];
+            store_vector4ui(inst, machine, result);
+         }
+         break;
+      case OPCODE_PK2H:        /* pack two 16-bit floats in one 32-bit float */
+         {
+            GLfloat a[4];
+            GLuint result[4];
+            GLhalfNV hx, hy;
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            hx = _mesa_float_to_half(a[0]);
+            hy = _mesa_float_to_half(a[1]);
+            result[0] =
+            result[1] =
+            result[2] =
+            result[3] = hx | (hy << 16);
+            store_vector4ui(inst, machine, result);
+         }
+         break;
+      case OPCODE_PK2US:       /* pack two GLushorts into one 32-bit float */
+         {
+            GLfloat a[4];
+            GLuint result[4], usx, usy;
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            a[0] = CLAMP(a[0], 0.0F, 1.0F);
+            a[1] = CLAMP(a[1], 0.0F, 1.0F);
+            usx = IROUND(a[0] * 65535.0F);
+            usy = IROUND(a[1] * 65535.0F);
+            result[0] =
+            result[1] =
+            result[2] =
+            result[3] = usx | (usy << 16);
+            store_vector4ui(inst, machine, result);
+         }
+         break;
+      case OPCODE_PK4B:        /* pack four GLbytes into one 32-bit float */
+         {
+            GLfloat a[4];
+            GLuint result[4], ubx, uby, ubz, ubw;
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            a[0] = CLAMP(a[0], -128.0F / 127.0F, 1.0F);
+            a[1] = CLAMP(a[1], -128.0F / 127.0F, 1.0F);
+            a[2] = CLAMP(a[2], -128.0F / 127.0F, 1.0F);
+            a[3] = CLAMP(a[3], -128.0F / 127.0F, 1.0F);
+            ubx = IROUND(127.0F * a[0] + 128.0F);
+            uby = IROUND(127.0F * a[1] + 128.0F);
+            ubz = IROUND(127.0F * a[2] + 128.0F);
+            ubw = IROUND(127.0F * a[3] + 128.0F);
+            result[0] =
+            result[1] =
+            result[2] =
+            result[3] = ubx | (uby << 8) | (ubz << 16) | (ubw << 24);
+            store_vector4ui(inst, machine, result);
+         }
+         break;
+      case OPCODE_PK4UB:       /* pack four GLubytes into one 32-bit float */
+         {
+            GLfloat a[4];
+            GLuint result[4], ubx, uby, ubz, ubw;
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            a[0] = CLAMP(a[0], 0.0F, 1.0F);
+            a[1] = CLAMP(a[1], 0.0F, 1.0F);
+            a[2] = CLAMP(a[2], 0.0F, 1.0F);
+            a[3] = CLAMP(a[3], 0.0F, 1.0F);
+            ubx = IROUND(255.0F * a[0]);
+            uby = IROUND(255.0F * a[1]);
+            ubz = IROUND(255.0F * a[2]);
+            ubw = IROUND(255.0F * a[3]);
+            result[0] =
+            result[1] =
+            result[2] =
+            result[3] = ubx | (uby << 8) | (ubz << 16) | (ubw << 24);
+            store_vector4ui(inst, machine, result);
+         }
+         break;
+      case OPCODE_POW:
+         {
+            GLfloat a[4], b[4], result[4];
+            fetch_vector1(&inst->SrcReg[0], machine, a);
+            fetch_vector1(&inst->SrcReg[1], machine, b);
+            result[0] = result[1] = result[2] = result[3]
+               = (GLfloat) pow(a[0], b[0]);
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_RCP:
+         {
+            GLfloat a[4], result[4];
+            fetch_vector1(&inst->SrcReg[0], machine, a);
+            if (DEBUG_PROG) {
+               if (a[0] == 0)
+                  printf("RCP(0)\n");
+               else if (IS_INF_OR_NAN(a[0]))
+                  printf("RCP(inf)\n");
+            }
+            result[0] = result[1] = result[2] = result[3] = 1.0F / a[0];
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_RET:         /* return from subroutine (conditional) */
+         if (eval_condition(machine, inst)) {
+            if (machine->StackDepth == 0) {
+               return GL_TRUE;  /* Per GL_NV_vertex_program2 spec */
+            }
+            /* subtract one because of pc++ in the for loop */
+            pc = machine->CallStack[--machine->StackDepth] - 1;
+         }
+         break;
+      case OPCODE_RFL:         /* reflection vector */
+         {
+            GLfloat axis[4], dir[4], result[4], tmpX, tmpW;
+            fetch_vector4(&inst->SrcReg[0], machine, axis);
+            fetch_vector4(&inst->SrcReg[1], machine, dir);
+            tmpW = DOT3(axis, axis);
+            tmpX = (2.0F * DOT3(axis, dir)) / tmpW;
+            result[0] = tmpX * axis[0] - dir[0];
+            result[1] = tmpX * axis[1] - dir[1];
+            result[2] = tmpX * axis[2] - dir[2];
+            /* result[3] is never written! XXX enforce in parser! */
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_RSQ:         /* 1 / sqrt() */
+         {
+            GLfloat a[4], result[4];
+            fetch_vector1(&inst->SrcReg[0], machine, a);
+            a[0] = FABSF(a[0]);
+            result[0] = result[1] = result[2] = result[3] = INV_SQRTF(a[0]);
+            store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("RSQ %g = 1/sqrt(|%g|)\n", result[0], a[0]);
+            }
+         }
+         break;
+      case OPCODE_SCS:         /* sine and cos */
+         {
+            GLfloat a[4], result[4];
+            fetch_vector1(&inst->SrcReg[0], machine, a);
+            result[0] = (GLfloat) cos(a[0]);
+            result[1] = (GLfloat) sin(a[0]);
+            result[2] = 0.0;    /* undefined! */
+            result[3] = 0.0;    /* undefined! */
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_SEQ:         /* set on equal */
+         {
+            GLfloat a[4], b[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            result[0] = (a[0] == b[0]) ? 1.0F : 0.0F;
+            result[1] = (a[1] == b[1]) ? 1.0F : 0.0F;
+            result[2] = (a[2] == b[2]) ? 1.0F : 0.0F;
+            result[3] = (a[3] == b[3]) ? 1.0F : 0.0F;
+            store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("SEQ (%g %g %g %g) = (%g %g %g %g) == (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], a[3],
+                      b[0], b[1], b[2], b[3]);
+            }
+         }
+         break;
+      case OPCODE_SFL:         /* set false, operands ignored */
+         {
+            static const GLfloat result[4] = { 0.0F, 0.0F, 0.0F, 0.0F };
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_SGE:         /* set on greater or equal */
+         {
+            GLfloat a[4], b[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            result[0] = (a[0] >= b[0]) ? 1.0F : 0.0F;
+            result[1] = (a[1] >= b[1]) ? 1.0F : 0.0F;
+            result[2] = (a[2] >= b[2]) ? 1.0F : 0.0F;
+            result[3] = (a[3] >= b[3]) ? 1.0F : 0.0F;
+            store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("SGE (%g %g %g %g) = (%g %g %g %g) >= (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], a[3],
+                      b[0], b[1], b[2], b[3]);
+            }
+         }
+         break;
+      case OPCODE_SGT:         /* set on greater */
+         {
+            GLfloat a[4], b[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            result[0] = (a[0] > b[0]) ? 1.0F : 0.0F;
+            result[1] = (a[1] > b[1]) ? 1.0F : 0.0F;
+            result[2] = (a[2] > b[2]) ? 1.0F : 0.0F;
+            result[3] = (a[3] > b[3]) ? 1.0F : 0.0F;
+            store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("SGT (%g %g %g %g) = (%g %g %g %g) > (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], a[3],
+                      b[0], b[1], b[2], b[3]);
+            }
+         }
+         break;
+      case OPCODE_SIN:
+         {
+            GLfloat a[4], result[4];
+            fetch_vector1(&inst->SrcReg[0], machine, a);
+            result[0] = result[1] = result[2] = result[3]
+               = (GLfloat) sin(a[0]);
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_SLE:         /* set on less or equal */
+         {
+            GLfloat a[4], b[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            result[0] = (a[0] <= b[0]) ? 1.0F : 0.0F;
+            result[1] = (a[1] <= b[1]) ? 1.0F : 0.0F;
+            result[2] = (a[2] <= b[2]) ? 1.0F : 0.0F;
+            result[3] = (a[3] <= b[3]) ? 1.0F : 0.0F;
+            store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("SLE (%g %g %g %g) = (%g %g %g %g) <= (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], a[3],
+                      b[0], b[1], b[2], b[3]);
+            }
+         }
+         break;
+      case OPCODE_SLT:         /* set on less */
+         {
+            GLfloat a[4], b[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            result[0] = (a[0] < b[0]) ? 1.0F : 0.0F;
+            result[1] = (a[1] < b[1]) ? 1.0F : 0.0F;
+            result[2] = (a[2] < b[2]) ? 1.0F : 0.0F;
+            result[3] = (a[3] < b[3]) ? 1.0F : 0.0F;
+            store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("SLT (%g %g %g %g) = (%g %g %g %g) < (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], a[3],
+                      b[0], b[1], b[2], b[3]);
+            }
+         }
+         break;
+      case OPCODE_SNE:         /* set on not equal */
+         {
+            GLfloat a[4], b[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            result[0] = (a[0] != b[0]) ? 1.0F : 0.0F;
+            result[1] = (a[1] != b[1]) ? 1.0F : 0.0F;
+            result[2] = (a[2] != b[2]) ? 1.0F : 0.0F;
+            result[3] = (a[3] != b[3]) ? 1.0F : 0.0F;
+            store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("SNE (%g %g %g %g) = (%g %g %g %g) != (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], a[3],
+                      b[0], b[1], b[2], b[3]);
+            }
+         }
+         break;
+      case OPCODE_SSG:         /* set sign (-1, 0 or +1) */
+         {
+            GLfloat a[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            result[0] = (GLfloat) ((a[0] > 0.0F) - (a[0] < 0.0F));
+            result[1] = (GLfloat) ((a[1] > 0.0F) - (a[1] < 0.0F));
+            result[2] = (GLfloat) ((a[2] > 0.0F) - (a[2] < 0.0F));
+            result[3] = (GLfloat) ((a[3] > 0.0F) - (a[3] < 0.0F));
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_STR:         /* set true, operands ignored */
+         {
+            static const GLfloat result[4] = { 1.0F, 1.0F, 1.0F, 1.0F };
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_SUB:
+         {
+            GLfloat a[4], b[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            result[0] = a[0] - b[0];
+            result[1] = a[1] - b[1];
+            result[2] = a[2] - b[2];
+            result[3] = a[3] - b[3];
+            store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("SUB (%g %g %g %g) = (%g %g %g %g) - (%g %g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
+            }
+         }
+         break;
+      case OPCODE_SWZ:         /* extended swizzle */
+         {
+            const struct prog_src_register *source = &inst->SrcReg[0];
+            const GLfloat *src = get_src_register_pointer(source, machine);
+            GLfloat result[4];
+            GLuint i;
+            for (i = 0; i < 4; i++) {
+               const GLuint swz = GET_SWZ(source->Swizzle, i);
+               if (swz == SWIZZLE_ZERO)
+                  result[i] = 0.0;
+               else if (swz == SWIZZLE_ONE)
+                  result[i] = 1.0;
+               else {
+                  ASSERT(swz >= 0);
+                  ASSERT(swz <= 3);
+                  result[i] = src[swz];
+               }
+               if (source->Negate & (1 << i))
+                  result[i] = -result[i];
+            }
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_TEX:         /* Both ARB and NV frag prog */
+         /* Simple texel lookup */
+         {
+            GLfloat texcoord[4], color[4];
+            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
+
+            fetch_texel(ctx, machine, inst, texcoord, 0.0, color);
+
+            if (DEBUG_PROG) {
+               printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g]\n",
+                      color[0], color[1], color[2], color[3],
+                      inst->TexSrcUnit,
+                      texcoord[0], texcoord[1], texcoord[2], texcoord[3]);
+            }
+            store_vector4(inst, machine, color);
+         }
+         break;
+      case OPCODE_TXB:         /* GL_ARB_fragment_program only */
+         /* Texel lookup with LOD bias */
+         {
+            GLfloat texcoord[4], color[4], lodBias;
+
+            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
+
+            /* texcoord[3] is the bias to add to lambda */
+            lodBias = texcoord[3];
+
+            fetch_texel(ctx, machine, inst, texcoord, lodBias, color);
+
+            store_vector4(inst, machine, color);
+         }
+         break;
+      case OPCODE_TXD:         /* GL_NV_fragment_program only */
+         /* Texture lookup w/ partial derivatives for LOD */
+         {
+            GLfloat texcoord[4], dtdx[4], dtdy[4], color[4];
+            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
+            fetch_vector4(&inst->SrcReg[1], machine, dtdx);
+            fetch_vector4(&inst->SrcReg[2], machine, dtdy);
+            machine->FetchTexelDeriv(ctx, texcoord, dtdx, dtdy,
+                                     0.0, /* lodBias */
+                                     inst->TexSrcUnit, color);
+            store_vector4(inst, machine, color);
+         }
+         break;
+      case OPCODE_TXP:         /* GL_ARB_fragment_program only */
+         /* Texture lookup w/ projective divide */
+         {
+            GLfloat texcoord[4], color[4];
+
+            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
+            /* Not so sure about this test - if texcoord[3] is
+             * zero, we'd probably be fine except for an ASSERT in
+             * IROUND_POS() which gets triggered by the inf values created.
+             */
+            if (texcoord[3] != 0.0) {
+               texcoord[0] /= texcoord[3];
+               texcoord[1] /= texcoord[3];
+               texcoord[2] /= texcoord[3];
+            }
+
+            fetch_texel(ctx, machine, inst, texcoord, 0.0, color);
+
+            store_vector4(inst, machine, color);
+         }
+         break;
+      case OPCODE_TXP_NV:      /* GL_NV_fragment_program only */
+         /* Texture lookup w/ projective divide, as above, but do not
+          * do the divide by w if sampling from a cube map.
+          */
+         {
+            GLfloat texcoord[4], color[4];
+
+            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
+            if (inst->TexSrcTarget != TEXTURE_CUBE_INDEX &&
+                texcoord[3] != 0.0) {
+               texcoord[0] /= texcoord[3];
+               texcoord[1] /= texcoord[3];
+               texcoord[2] /= texcoord[3];
+            }
+
+            fetch_texel(ctx, machine, inst, texcoord, 0.0, color);
+
+            store_vector4(inst, machine, color);
+         }
+         break;
+      case OPCODE_TRUNC:       /* truncate toward zero */
+         {
+            GLfloat a[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            result[0] = (GLfloat) (GLint) a[0];
+            result[1] = (GLfloat) (GLint) a[1];
+            result[2] = (GLfloat) (GLint) a[2];
+            result[3] = (GLfloat) (GLint) a[3];
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_UP2H:        /* unpack two 16-bit floats */
+         {
+            const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine);
+            GLfloat result[4];
+            GLushort hx, hy;
+            hx = raw & 0xffff;
+            hy = raw >> 16;
+            result[0] = result[2] = _mesa_half_to_float(hx);
+            result[1] = result[3] = _mesa_half_to_float(hy);
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_UP2US:       /* unpack two GLushorts */
+         {
+            const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine);
+            GLfloat result[4];
+            GLushort usx, usy;
+            usx = raw & 0xffff;
+            usy = raw >> 16;
+            result[0] = result[2] = usx * (1.0f / 65535.0f);
+            result[1] = result[3] = usy * (1.0f / 65535.0f);
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_UP4B:        /* unpack four GLbytes */
+         {
+            const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine);
+            GLfloat result[4];
+            result[0] = (((raw >> 0) & 0xff) - 128) / 127.0F;
+            result[1] = (((raw >> 8) & 0xff) - 128) / 127.0F;
+            result[2] = (((raw >> 16) & 0xff) - 128) / 127.0F;
+            result[3] = (((raw >> 24) & 0xff) - 128) / 127.0F;
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_UP4UB:       /* unpack four GLubytes */
+         {
+            const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine);
+            GLfloat result[4];
+            result[0] = ((raw >> 0) & 0xff) / 255.0F;
+            result[1] = ((raw >> 8) & 0xff) / 255.0F;
+            result[2] = ((raw >> 16) & 0xff) / 255.0F;
+            result[3] = ((raw >> 24) & 0xff) / 255.0F;
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_XOR:         /* bitwise XOR */
+         {
+            GLuint a[4], b[4], result[4];
+            fetch_vector4ui(&inst->SrcReg[0], machine, a);
+            fetch_vector4ui(&inst->SrcReg[1], machine, b);
+            result[0] = a[0] ^ b[0];
+            result[1] = a[1] ^ b[1];
+            result[2] = a[2] ^ b[2];
+            result[3] = a[3] ^ b[3];
+            store_vector4ui(inst, machine, result);
+         }
+         break;
+      case OPCODE_XPD:         /* cross product */
+         {
+            GLfloat a[4], b[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            result[0] = a[1] * b[2] - a[2] * b[1];
+            result[1] = a[2] * b[0] - a[0] * b[2];
+            result[2] = a[0] * b[1] - a[1] * b[0];
+            result[3] = 1.0;
+            store_vector4(inst, machine, result);
+            if (DEBUG_PROG) {
+               printf("XPD (%g %g %g %g) = (%g %g %g) X (%g %g %g)\n",
+                      result[0], result[1], result[2], result[3],
+                      a[0], a[1], a[2], b[0], b[1], b[2]);
+            }
+         }
+         break;
+      case OPCODE_X2D:         /* 2-D matrix transform */
+         {
+            GLfloat a[4], b[4], c[4], result[4];
+            fetch_vector4(&inst->SrcReg[0], machine, a);
+            fetch_vector4(&inst->SrcReg[1], machine, b);
+            fetch_vector4(&inst->SrcReg[2], machine, c);
+            result[0] = a[0] + b[0] * c[0] + b[1] * c[1];
+            result[1] = a[1] + b[0] * c[2] + b[1] * c[3];
+            result[2] = a[2] + b[0] * c[0] + b[1] * c[1];
+            result[3] = a[3] + b[0] * c[2] + b[1] * c[3];
+            store_vector4(inst, machine, result);
+         }
+         break;
+      case OPCODE_PRINT:
+         {
+            if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
+               GLfloat a[4];
+               fetch_vector4(&inst->SrcReg[0], machine, a);
+               printf("%s%g, %g, %g, %g\n", (const char *) inst->Data,
+                            a[0], a[1], a[2], a[3]);
+            }
+            else {
+               printf("%s\n", (const char *) inst->Data);
+            }
+         }
+         break;
+      case OPCODE_END:
+         return GL_TRUE;
+      default:
+         _mesa_problem(ctx, "Bad opcode %d in _mesa_execute_program",
+                       inst->Opcode);
+         return GL_TRUE;        /* return value doesn't matter */
+      }
+
+      numExec++;
+      if (numExec > maxExec) {
+        static GLboolean reported = GL_FALSE;
+        if (!reported) {
+           _mesa_problem(ctx, "Infinite loop detected in fragment program");
+           reported = GL_TRUE;
+        }
+         return GL_TRUE;
+      }
+
+   } /* for pc */
+
+   return GL_TRUE;
+}
diff --git a/src/mesa/program/prog_execute.h b/src/mesa/program/prog_execute.h
new file mode 100644 (file)
index 0000000..adefc54
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.0.3
+ *
+ * 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.
+ */
+
+#ifndef PROG_EXECUTE_H
+#define PROG_EXECUTE_H
+
+#include "main/config.h"
+
+
+typedef void (*FetchTexelLodFunc)(GLcontext *ctx, const GLfloat texcoord[4],
+                                  GLfloat lambda, GLuint unit, GLfloat color[4]);
+
+typedef void (*FetchTexelDerivFunc)(GLcontext *ctx, const GLfloat texcoord[4],
+                                    const GLfloat texdx[4],
+                                    const GLfloat texdy[4],
+                                    GLfloat lodBias,
+                                    GLuint unit, GLfloat color[4]);
+
+
+/**
+ * Virtual machine state used during execution of vertex/fragment programs.
+ */
+struct gl_program_machine
+{
+   const struct gl_program *CurProgram;
+
+   /** Fragment Input attributes */
+   GLfloat (*Attribs)[MAX_WIDTH][4];
+   GLfloat (*DerivX)[4];
+   GLfloat (*DerivY)[4];
+   GLuint NumDeriv; /**< Max index into DerivX/Y arrays */
+   GLuint CurElement; /**< Index into Attribs arrays */
+
+   /** Vertex Input attribs */
+   GLfloat VertAttribs[VERT_ATTRIB_MAX][4];
+
+   GLfloat Temporaries[MAX_PROGRAM_TEMPS][4];
+   GLfloat Outputs[MAX_PROGRAM_OUTPUTS][4];
+   GLfloat (*EnvParams)[4]; /**< Vertex or Fragment env parameters */
+   GLuint CondCodes[4];  /**< COND_* value for x/y/z/w */
+   GLint AddressReg[MAX_PROGRAM_ADDRESS_REGS][4];
+
+   const GLubyte *Samplers;  /** Array mapping sampler var to tex unit */
+
+   GLuint CallStack[MAX_PROGRAM_CALL_DEPTH]; /**< For CAL/RET instructions */
+   GLuint StackDepth; /**< Index/ptr to top of CallStack[] */
+
+   /** Texture fetch functions */
+   FetchTexelLodFunc FetchTexelLod;
+   FetchTexelDerivFunc FetchTexelDeriv;
+};
+
+
+extern void
+_mesa_get_program_register(GLcontext *ctx, gl_register_file file,
+                           GLuint index, GLfloat val[4]);
+
+extern GLboolean
+_mesa_execute_program(GLcontext *ctx,
+                      const struct gl_program *program,
+                      struct gl_program_machine *machine);
+
+
+#endif /* PROG_EXECUTE_H */
diff --git a/src/mesa/program/prog_instruction.c b/src/mesa/program/prog_instruction.c
new file mode 100644 (file)
index 0000000..5d6cb47
--- /dev/null
@@ -0,0 +1,354 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.3
+ *
+ * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2009  VMware, 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
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "main/mtypes.h"
+#include "prog_instruction.h"
+
+
+/**
+ * Initialize program instruction fields to defaults.
+ * \param inst  first instruction to initialize
+ * \param count  number of instructions to initialize
+ */
+void
+_mesa_init_instructions(struct prog_instruction *inst, GLuint count)
+{
+   GLuint i;
+
+   memset(inst, 0, count * sizeof(struct prog_instruction));
+
+   for (i = 0; i < count; i++) {
+      inst[i].SrcReg[0].File = PROGRAM_UNDEFINED;
+      inst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP;
+      inst[i].SrcReg[1].File = PROGRAM_UNDEFINED;
+      inst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP;
+      inst[i].SrcReg[2].File = PROGRAM_UNDEFINED;
+      inst[i].SrcReg[2].Swizzle = SWIZZLE_NOOP;
+
+      inst[i].DstReg.File = PROGRAM_UNDEFINED;
+      inst[i].DstReg.WriteMask = WRITEMASK_XYZW;
+      inst[i].DstReg.CondMask = COND_TR;
+      inst[i].DstReg.CondSwizzle = SWIZZLE_NOOP;
+
+      inst[i].SaturateMode = SATURATE_OFF;
+      inst[i].Precision = FLOAT32;
+   }
+}
+
+
+/**
+ * Allocate an array of program instructions.
+ * \param numInst  number of instructions
+ * \return pointer to instruction memory
+ */
+struct prog_instruction *
+_mesa_alloc_instructions(GLuint numInst)
+{
+   return (struct prog_instruction *)
+      calloc(1, numInst * sizeof(struct prog_instruction));
+}
+
+
+/**
+ * Reallocate memory storing an array of program instructions.
+ * This is used when we need to append additional instructions onto an
+ * program.
+ * \param oldInst  pointer to first of old/src instructions
+ * \param numOldInst  number of instructions at <oldInst>
+ * \param numNewInst  desired size of new instruction array.
+ * \return  pointer to start of new instruction array.
+ */
+struct prog_instruction *
+_mesa_realloc_instructions(struct prog_instruction *oldInst,
+                           GLuint numOldInst, GLuint numNewInst)
+{
+   struct prog_instruction *newInst;
+
+   newInst = (struct prog_instruction *)
+      _mesa_realloc(oldInst,
+                    numOldInst * sizeof(struct prog_instruction),
+                    numNewInst * sizeof(struct prog_instruction));
+
+   return newInst;
+}
+
+
+/**
+ * Copy an array of program instructions.
+ * \param dest  pointer to destination.
+ * \param src  pointer to source.
+ * \param n  number of instructions to copy.
+ * \return pointer to destination.
+ */
+struct prog_instruction *
+_mesa_copy_instructions(struct prog_instruction *dest,
+                        const struct prog_instruction *src, GLuint n)
+{
+   GLuint i;
+   memcpy(dest, src, n * sizeof(struct prog_instruction));
+   for (i = 0; i < n; i++) {
+      if (src[i].Comment)
+         dest[i].Comment = _mesa_strdup(src[i].Comment);
+   }
+   return dest;
+}
+
+
+/**
+ * Free an array of instructions
+ */
+void
+_mesa_free_instructions(struct prog_instruction *inst, GLuint count)
+{
+   GLuint i;
+   for (i = 0; i < count; i++) {
+      if (inst[i].Data)
+         free(inst[i].Data);
+      if (inst[i].Comment)
+         free((char *) inst[i].Comment);
+   }
+   free(inst);
+}
+
+
+/**
+ * Basic info about each instruction
+ */
+struct instruction_info
+{
+   gl_inst_opcode Opcode;
+   const char *Name;
+   GLuint NumSrcRegs;
+   GLuint NumDstRegs;
+};
+
+/**
+ * Instruction info
+ * \note Opcode should equal array index!
+ */
+static const struct instruction_info InstInfo[MAX_OPCODE] = {
+   { OPCODE_NOP,    "NOP",     0, 0 },
+   { OPCODE_ABS,    "ABS",     1, 1 },
+   { OPCODE_ADD,    "ADD",     2, 1 },
+   { OPCODE_AND,    "AND",     2, 1 },
+   { OPCODE_ARA,    "ARA",     1, 1 },
+   { OPCODE_ARL,    "ARL",     1, 1 },
+   { OPCODE_ARL_NV, "ARL_NV",  1, 1 },
+   { OPCODE_ARR,    "ARL",     1, 1 },
+   { OPCODE_BGNLOOP,"BGNLOOP", 0, 0 },
+   { OPCODE_BGNSUB, "BGNSUB",  0, 0 },
+   { OPCODE_BRA,    "BRA",     0, 0 },
+   { OPCODE_BRK,    "BRK",     0, 0 },
+   { OPCODE_CAL,    "CAL",     0, 0 },
+   { OPCODE_CMP,    "CMP",     3, 1 },
+   { OPCODE_CONT,   "CONT",    0, 0 },
+   { OPCODE_COS,    "COS",     1, 1 },
+   { OPCODE_DDX,    "DDX",     1, 1 },
+   { OPCODE_DDY,    "DDY",     1, 1 },
+   { OPCODE_DP2,    "DP2",     2, 1 },
+   { OPCODE_DP2A,   "DP2A",    3, 1 },
+   { OPCODE_DP3,    "DP3",     2, 1 },
+   { OPCODE_DP4,    "DP4",     2, 1 },
+   { OPCODE_DPH,    "DPH",     2, 1 },
+   { OPCODE_DST,    "DST",     2, 1 },
+   { OPCODE_ELSE,   "ELSE",    0, 0 },
+   { OPCODE_EMIT_VERTEX,   "EMIT_VERTEX",    0, 0 },
+   { OPCODE_END,    "END",     0, 0 },
+   { OPCODE_END_PRIMITIVE,    "END_PRIMITIVE",     0, 0 },
+   { OPCODE_ENDIF,  "ENDIF",   0, 0 },
+   { OPCODE_ENDLOOP,"ENDLOOP", 0, 0 },
+   { OPCODE_ENDSUB, "ENDSUB",  0, 0 },
+   { OPCODE_EX2,    "EX2",     1, 1 },
+   { OPCODE_EXP,    "EXP",     1, 1 },
+   { OPCODE_FLR,    "FLR",     1, 1 },
+   { OPCODE_FRC,    "FRC",     1, 1 },
+   { OPCODE_IF,     "IF",      1, 0 },
+   { OPCODE_KIL,    "KIL",     1, 0 },
+   { OPCODE_KIL_NV, "KIL_NV",  0, 0 },
+   { OPCODE_LG2,    "LG2",     1, 1 },
+   { OPCODE_LIT,    "LIT",     1, 1 },
+   { OPCODE_LOG,    "LOG",     1, 1 },
+   { OPCODE_LRP,    "LRP",     3, 1 },
+   { OPCODE_MAD,    "MAD",     3, 1 },
+   { OPCODE_MAX,    "MAX",     2, 1 },
+   { OPCODE_MIN,    "MIN",     2, 1 },
+   { OPCODE_MOV,    "MOV",     1, 1 },
+   { OPCODE_MUL,    "MUL",     2, 1 },
+   { OPCODE_NOISE1, "NOISE1",  1, 1 },
+   { OPCODE_NOISE2, "NOISE2",  1, 1 },
+   { OPCODE_NOISE3, "NOISE3",  1, 1 },
+   { OPCODE_NOISE4, "NOISE4",  1, 1 },
+   { OPCODE_NOT,    "NOT",     1, 1 },
+   { OPCODE_NRM3,   "NRM3",    1, 1 },
+   { OPCODE_NRM4,   "NRM4",    1, 1 },
+   { OPCODE_OR,     "OR",      2, 1 },
+   { OPCODE_PK2H,   "PK2H",    1, 1 },
+   { OPCODE_PK2US,  "PK2US",   1, 1 },
+   { OPCODE_PK4B,   "PK4B",    1, 1 },
+   { OPCODE_PK4UB,  "PK4UB",   1, 1 },
+   { OPCODE_POW,    "POW",     2, 1 },
+   { OPCODE_POPA,   "POPA",    0, 0 },
+   { OPCODE_PRINT,  "PRINT",   1, 0 },
+   { OPCODE_PUSHA,  "PUSHA",   0, 0 },
+   { OPCODE_RCC,    "RCC",     1, 1 },
+   { OPCODE_RCP,    "RCP",     1, 1 },
+   { OPCODE_RET,    "RET",     0, 0 },
+   { OPCODE_RFL,    "RFL",     1, 1 },
+   { OPCODE_RSQ,    "RSQ",     1, 1 },
+   { OPCODE_SCS,    "SCS",     1, 1 },
+   { OPCODE_SEQ,    "SEQ",     2, 1 },
+   { OPCODE_SFL,    "SFL",     0, 1 },
+   { OPCODE_SGE,    "SGE",     2, 1 },
+   { OPCODE_SGT,    "SGT",     2, 1 },
+   { OPCODE_SIN,    "SIN",     1, 1 },
+   { OPCODE_SLE,    "SLE",     2, 1 },
+   { OPCODE_SLT,    "SLT",     2, 1 },
+   { OPCODE_SNE,    "SNE",     2, 1 },
+   { OPCODE_SSG,    "SSG",     1, 1 },
+   { OPCODE_STR,    "STR",     0, 1 },
+   { OPCODE_SUB,    "SUB",     2, 1 },
+   { OPCODE_SWZ,    "SWZ",     1, 1 },
+   { OPCODE_TEX,    "TEX",     1, 1 },
+   { OPCODE_TXB,    "TXB",     1, 1 },
+   { OPCODE_TXD,    "TXD",     3, 1 },
+   { OPCODE_TXL,    "TXL",     1, 1 },
+   { OPCODE_TXP,    "TXP",     1, 1 },
+   { OPCODE_TXP_NV, "TXP_NV",  1, 1 },
+   { OPCODE_TRUNC,  "TRUNC",   1, 1 },
+   { OPCODE_UP2H,   "UP2H",    1, 1 },
+   { OPCODE_UP2US,  "UP2US",   1, 1 },
+   { OPCODE_UP4B,   "UP4B",    1, 1 },
+   { OPCODE_UP4UB,  "UP4UB",   1, 1 },
+   { OPCODE_X2D,    "X2D",     3, 1 },
+   { OPCODE_XOR,    "XOR",     2, 1 },
+   { OPCODE_XPD,    "XPD",     2, 1 }
+};
+
+
+/**
+ * Return the number of src registers for the given instruction/opcode.
+ */
+GLuint
+_mesa_num_inst_src_regs(gl_inst_opcode opcode)
+{
+   ASSERT(opcode < MAX_OPCODE);
+   ASSERT(opcode == InstInfo[opcode].Opcode);
+   ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode);
+   return InstInfo[opcode].NumSrcRegs;
+}
+
+
+/**
+ * Return the number of dst registers for the given instruction/opcode.
+ */
+GLuint
+_mesa_num_inst_dst_regs(gl_inst_opcode opcode)
+{
+   ASSERT(opcode < MAX_OPCODE);
+   ASSERT(opcode == InstInfo[opcode].Opcode);
+   ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode);
+   return InstInfo[opcode].NumDstRegs;
+}
+
+
+GLboolean
+_mesa_is_tex_instruction(gl_inst_opcode opcode)
+{
+   return (opcode == OPCODE_TEX ||
+           opcode == OPCODE_TXB ||
+           opcode == OPCODE_TXD ||
+           opcode == OPCODE_TXL ||
+           opcode == OPCODE_TXP);
+}
+
+
+/**
+ * Check if there's a potential src/dst register data dependency when
+ * using SOA execution.
+ * Example:
+ *   MOV T, T.yxwz;
+ * This would expand into:
+ *   MOV t0, t1;
+ *   MOV t1, t0;
+ *   MOV t2, t3;
+ *   MOV t3, t2;
+ * The second instruction will have the wrong value for t0 if executed as-is.
+ */
+GLboolean
+_mesa_check_soa_dependencies(const struct prog_instruction *inst)
+{
+   GLuint i, chan;
+
+   if (inst->DstReg.WriteMask == WRITEMASK_X ||
+       inst->DstReg.WriteMask == WRITEMASK_Y ||
+       inst->DstReg.WriteMask == WRITEMASK_Z ||
+       inst->DstReg.WriteMask == WRITEMASK_W ||
+       inst->DstReg.WriteMask == 0x0) {
+      /* no chance of data dependency */
+      return GL_FALSE;
+   }
+
+   /* loop over src regs */
+   for (i = 0; i < 3; i++) {
+      if (inst->SrcReg[i].File == inst->DstReg.File &&
+          inst->SrcReg[i].Index == inst->DstReg.Index) {
+         /* loop over dest channels */
+         GLuint channelsWritten = 0x0;
+         for (chan = 0; chan < 4; chan++) {
+            if (inst->DstReg.WriteMask & (1 << chan)) {
+               /* check if we're reading a channel that's been written */
+               GLuint swizzle = GET_SWZ(inst->SrcReg[i].Swizzle, chan);
+               if (swizzle <= SWIZZLE_W &&
+                   (channelsWritten & (1 << swizzle))) {
+                  return GL_TRUE;
+               }
+
+               channelsWritten |= (1 << chan);
+            }
+         }
+      }
+   }
+   return GL_FALSE;
+}
+
+
+/**
+ * Return string name for given program opcode.
+ */
+const char *
+_mesa_opcode_string(gl_inst_opcode opcode)
+{
+   if (opcode < MAX_OPCODE)
+      return InstInfo[opcode].Name;
+   else {
+      static char s[20];
+      _mesa_snprintf(s, sizeof(s), "OP%u", opcode);
+      return s;
+   }
+}
+
diff --git a/src/mesa/program/prog_instruction.h b/src/mesa/program/prog_instruction.h
new file mode 100644 (file)
index 0000000..02df208
--- /dev/null
@@ -0,0 +1,454 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.3
+ *
+ * Copyright (C) 1999-2008  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 prog_instruction.h
+ *
+ * Vertex/fragment program instruction datatypes and constants.
+ *
+ * \author Brian Paul
+ * \author Keith Whitwell
+ * \author Ian Romanick <idr@us.ibm.com>
+ */
+
+
+#ifndef PROG_INSTRUCTION_H
+#define PROG_INSTRUCTION_H
+
+
+#include "main/mfeatures.h"
+
+
+/**
+ * Swizzle indexes.
+ * Do not change!
+ */
+/*@{*/
+#define SWIZZLE_X    0
+#define SWIZZLE_Y    1
+#define SWIZZLE_Z    2
+#define SWIZZLE_W    3
+#define SWIZZLE_ZERO 4   /**< For SWZ instruction only */
+#define SWIZZLE_ONE  5   /**< For SWZ instruction only */
+#define SWIZZLE_NIL  7   /**< used during shader code gen (undefined value) */
+/*@}*/
+
+#define MAKE_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<3) | ((c)<<6) | ((d)<<9))
+#define SWIZZLE_NOOP           MAKE_SWIZZLE4(0,1,2,3)
+#define GET_SWZ(swz, idx)      (((swz) >> ((idx)*3)) & 0x7)
+#define GET_BIT(msk, idx)      (((msk) >> (idx)) & 0x1)
+
+#define SWIZZLE_XYZW MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W)
+#define SWIZZLE_XXXX MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X)
+#define SWIZZLE_YYYY MAKE_SWIZZLE4(SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y)
+#define SWIZZLE_ZZZZ MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z)
+#define SWIZZLE_WWWW MAKE_SWIZZLE4(SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W)
+
+
+/**
+ * Writemask values, 1 bit per component.
+ */
+/*@{*/
+#define WRITEMASK_X     0x1
+#define WRITEMASK_Y     0x2
+#define WRITEMASK_XY    0x3
+#define WRITEMASK_Z     0x4
+#define WRITEMASK_XZ    0x5
+#define WRITEMASK_YZ    0x6
+#define WRITEMASK_XYZ   0x7
+#define WRITEMASK_W     0x8
+#define WRITEMASK_XW    0x9
+#define WRITEMASK_YW    0xa
+#define WRITEMASK_XYW   0xb
+#define WRITEMASK_ZW    0xc
+#define WRITEMASK_XZW   0xd
+#define WRITEMASK_YZW   0xe
+#define WRITEMASK_XYZW  0xf
+/*@}*/
+
+
+/**
+ * Condition codes
+ */
+/*@{*/
+#define COND_GT  1  /**< greater than zero */
+#define COND_EQ  2  /**< equal to zero */
+#define COND_LT  3  /**< less than zero */
+#define COND_UN  4  /**< unordered (NaN) */
+#define COND_GE  5  /**< greater than or equal to zero */
+#define COND_LE  6  /**< less than or equal to zero */
+#define COND_NE  7  /**< not equal to zero */
+#define COND_TR  8  /**< always true */
+#define COND_FL  9  /**< always false */
+/*@}*/
+
+
+/**
+ * Instruction precision for GL_NV_fragment_program
+ */
+/*@{*/
+#define FLOAT32  0x1
+#define FLOAT16  0x2
+#define FIXED12  0x4
+/*@}*/
+
+
+/**
+ * Saturation modes when storing values.
+ */
+/*@{*/
+#define SATURATE_OFF            0
+#define SATURATE_ZERO_ONE       1
+/*@}*/
+
+
+/**
+ * Per-component negation masks
+ */
+/*@{*/
+#define NEGATE_X    0x1
+#define NEGATE_Y    0x2
+#define NEGATE_Z    0x4
+#define NEGATE_W    0x8
+#define NEGATE_XYZ  0x7
+#define NEGATE_XYZW 0xf
+#define NEGATE_NONE 0x0
+/*@}*/
+
+
+/**
+ * Program instruction opcodes for vertex, fragment and geometry programs.
+ */
+typedef enum prog_opcode {
+                     /* ARB_vp   ARB_fp   NV_vp   NV_fp     GLSL */
+                     /*------------------------------------------*/
+   OPCODE_NOP = 0,   /*                                      X   */
+   OPCODE_ABS,       /*   X        X       1.1               X   */
+   OPCODE_ADD,       /*   X        X       X       X         X   */
+   OPCODE_AND,       /*                                          */
+   OPCODE_ARA,       /*                    2                     */
+   OPCODE_ARL,       /*   X                X                     */
+   OPCODE_ARL_NV,    /*                    2                     */
+   OPCODE_ARR,       /*                    2                     */
+   OPCODE_BGNLOOP,   /*                                     opt  */
+   OPCODE_BGNSUB,    /*                                     opt  */
+   OPCODE_BRA,       /*                    2                 X   */
+   OPCODE_BRK,       /*                    2                opt  */
+   OPCODE_CAL,       /*                    2       2             */
+   OPCODE_CMP,       /*            X                             */
+   OPCODE_CONT,      /*                                     opt  */
+   OPCODE_COS,       /*            X       2       X         X   */
+   OPCODE_DDX,       /*                            X         X   */
+   OPCODE_DDY,       /*                            X         X   */
+   OPCODE_DP2,       /*                            2             */
+   OPCODE_DP2A,      /*                            2             */
+   OPCODE_DP3,       /*   X        X       X       X         X   */
+   OPCODE_DP4,       /*   X        X       X       X         X   */
+   OPCODE_DPH,       /*   X        X       1.1                   */
+   OPCODE_DST,       /*   X        X       X       X             */
+   OPCODE_ELSE,      /*                                      X   */
+   OPCODE_EMIT_VERTEX,/*                                     X   */
+   OPCODE_END,       /*   X        X       X       X        opt  */
+   OPCODE_END_PRIMITIVE,/*                                   X   */
+   OPCODE_ENDIF,     /*                                     opt  */
+   OPCODE_ENDLOOP,   /*                                     opt  */
+   OPCODE_ENDSUB,    /*                                     opt  */
+   OPCODE_EX2,       /*   X        X       2       X         X   */
+   OPCODE_EXP,       /*   X                X                 X   */
+   OPCODE_FLR,       /*   X        X       2       X         X   */
+   OPCODE_FRC,       /*   X        X       2       X         X   */
+   OPCODE_IF,        /*                                     opt  */
+   OPCODE_KIL,       /*            X                             */
+   OPCODE_KIL_NV,    /*                            X         X   */
+   OPCODE_LG2,       /*   X        X       2       X         X   */
+   OPCODE_LIT,       /*   X        X       X       X             */
+   OPCODE_LOG,       /*   X                X                 X   */
+   OPCODE_LRP,       /*            X               X             */
+   OPCODE_MAD,       /*   X        X       X       X         X   */
+   OPCODE_MAX,       /*   X        X       X       X         X   */
+   OPCODE_MIN,       /*   X        X       X       X         X   */
+   OPCODE_MOV,       /*   X        X       X       X         X   */
+   OPCODE_MUL,       /*   X        X       X       X         X   */
+   OPCODE_NOISE1,    /*                                      X   */
+   OPCODE_NOISE2,    /*                                      X   */
+   OPCODE_NOISE3,    /*                                      X   */
+   OPCODE_NOISE4,    /*                                      X   */
+   OPCODE_NOT,       /*                                          */
+   OPCODE_NRM3,      /*                                          */
+   OPCODE_NRM4,      /*                                          */
+   OPCODE_OR,        /*                                          */
+   OPCODE_PK2H,      /*                            X             */
+   OPCODE_PK2US,     /*                            X             */
+   OPCODE_PK4B,      /*                            X             */
+   OPCODE_PK4UB,     /*                            X             */
+   OPCODE_POW,       /*   X        X               X         X   */
+   OPCODE_POPA,      /*                    3                     */
+   OPCODE_PRINT,     /*                    X       X             */
+   OPCODE_PUSHA,     /*                    3                     */
+   OPCODE_RCC,       /*                    1.1                   */
+   OPCODE_RCP,       /*   X        X       X       X         X   */
+   OPCODE_RET,       /*                    2       2             */
+   OPCODE_RFL,       /*            X               X             */
+   OPCODE_RSQ,       /*   X        X       X       X         X   */
+   OPCODE_SCS,       /*            X                             */
+   OPCODE_SEQ,       /*                    2       X         X   */
+   OPCODE_SFL,       /*                    2       X             */
+   OPCODE_SGE,       /*   X        X       X       X         X   */
+   OPCODE_SGT,       /*                    2       X         X   */
+   OPCODE_SIN,       /*            X       2       X         X   */
+   OPCODE_SLE,       /*                    2       X         X   */
+   OPCODE_SLT,       /*   X        X       X       X         X   */
+   OPCODE_SNE,       /*                    2       X         X   */
+   OPCODE_SSG,       /*                    2                     */
+   OPCODE_STR,       /*                    2       X             */
+   OPCODE_SUB,       /*   X        X       1.1     X         X   */
+   OPCODE_SWZ,       /*   X        X                             */
+   OPCODE_TEX,       /*            X       3       X         X   */
+   OPCODE_TXB,       /*            X       3                 X   */
+   OPCODE_TXD,       /*                            X         X   */
+   OPCODE_TXL,       /*                    3       2         X   */
+   OPCODE_TXP,       /*            X                         X   */
+   OPCODE_TXP_NV,    /*                    3       X             */
+   OPCODE_TRUNC,     /*                                      X   */
+   OPCODE_UP2H,      /*                            X             */
+   OPCODE_UP2US,     /*                            X             */
+   OPCODE_UP4B,      /*                            X             */
+   OPCODE_UP4UB,     /*                            X             */
+   OPCODE_X2D,       /*                            X             */
+   OPCODE_XOR,       /*                                          */
+   OPCODE_XPD,       /*   X        X                         X   */
+   MAX_OPCODE
+} gl_inst_opcode;
+
+
+/**
+ * Number of bits for the src/dst register Index field.
+ * This limits the size of temp/uniform register files.
+ */
+#define INST_INDEX_BITS 10
+
+
+/**
+ * Instruction source register.
+ */
+struct prog_src_register
+{
+   GLuint File:4;      /**< One of the PROGRAM_* register file values. */
+   GLint Index:(INST_INDEX_BITS+1); /**< Extra bit here for sign bit.
+                                     * May be negative for relative addressing.
+                                     */
+   GLuint Swizzle:12;
+   GLuint RelAddr:1;
+
+   /** Take the component-wise absolute value */
+   GLuint Abs:1;
+
+   /**
+    * Post-Abs negation.
+    * This will either be NEGATE_NONE or NEGATE_XYZW, except for the SWZ
+    * instruction which allows per-component negation.
+    */
+   GLuint Negate:4;
+
+   /**
+    * Is the register two-dimensional.
+    * Two dimensional registers are of the
+    * REGISTER[index][index2] format.
+    * They are used by the geometry shaders where
+    * the first index is the index within an array
+    * and the second index is the semantic of the
+    * array, e.g. gl_PositionIn[index] would become
+    * INPUT[index][gl_PositionIn]
+    */
+   GLuint HasIndex2:1;
+   GLuint RelAddr2:1;
+   GLint Index2:(INST_INDEX_BITS+1); /**< Extra bit here for sign bit.
+                                       * May be negative for relative
+                                       * addressing. */
+};
+
+
+/**
+ * Instruction destination register.
+ */
+struct prog_dst_register
+{
+   GLuint File:4;      /**< One of the PROGRAM_* register file values */
+   GLuint Index:INST_INDEX_BITS;  /**< Unsigned, never negative */
+   GLuint WriteMask:4;
+   GLuint RelAddr:1;
+
+   /**
+    * \name Conditional destination update control.
+    *
+    * \since
+    * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
+    * NV_vertex_program2_option.
+    */
+   /*@{*/
+   /**
+    * Takes one of the 9 possible condition values (EQ, FL, GT, GE, LE, LT,
+    * NE, TR, or UN).  Dest reg is only written to if the matching
+    * (swizzled) condition code value passes.  When a conditional update mask
+    * is not specified, this will be \c COND_TR.
+    */
+   GLuint CondMask:4;
+
+   /**
+    * Condition code swizzle value.
+    */
+   GLuint CondSwizzle:12;
+
+   /**
+    * Selects the condition code register to use for conditional destination
+    * update masking.  In NV_fragmnet_program or NV_vertex_program2 mode, only
+    * condition code register 0 is available.  In NV_vertex_program3 mode,
+    * condition code registers 0 and 1 are available.
+    */
+   GLuint CondSrc:1;
+   /*@}*/
+};
+
+
+/**
+ * Vertex/fragment program instruction.
+ */
+struct prog_instruction
+{
+   gl_inst_opcode Opcode;
+   struct prog_src_register SrcReg[3];
+   struct prog_dst_register DstReg;
+
+   /**
+    * Indicates that the instruction should update the condition code
+    * register.
+    *
+    * \since
+    * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
+    * NV_vertex_program2_option.
+    */
+   GLuint CondUpdate:1;
+
+   /**
+    * If prog_instruction::CondUpdate is \c GL_TRUE, this value selects the
+    * condition code register that is to be updated.
+    *
+    * In GL_NV_fragment_program or GL_NV_vertex_program2 mode, only condition
+    * code register 0 is available.  In GL_NV_vertex_program3 mode, condition
+    * code registers 0 and 1 are available.
+    *
+    * \since
+    * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
+    * NV_vertex_program2_option.
+    */
+   GLuint CondDst:1;
+
+   /**
+    * Saturate each value of the vectored result to the range [0,1] or the
+    * range [-1,1].  \c SSAT mode (i.e., saturation to the range [-1,1]) is
+    * only available in NV_fragment_program2 mode.
+    * Value is one of the SATURATE_* tokens.
+    *
+    * \since
+    * NV_fragment_program, NV_fragment_program_option, NV_vertex_program3.
+    */
+   GLuint SaturateMode:2;
+
+   /**
+    * Per-instruction selectable precision: FLOAT32, FLOAT16, FIXED12.
+    *
+    * \since
+    * NV_fragment_program, NV_fragment_program_option.
+    */
+   GLuint Precision:3;
+
+   /**
+    * \name Extra fields for TEX, TXB, TXD, TXL, TXP instructions.
+    */
+   /*@{*/
+   /** Source texture unit. */
+   GLuint TexSrcUnit:5;
+
+   /** Source texture target, one of TEXTURE_{1D,2D,3D,CUBE,RECT}_INDEX */
+   GLuint TexSrcTarget:3;
+
+   /** True if tex instruction should do shadow comparison */
+   GLuint TexShadow:1;
+   /*@}*/
+
+   /**
+    * For BRA and CAL instructions, the location to jump to.
+    * For BGNLOOP, points to ENDLOOP (and vice-versa).
+    * For BRK, points to ENDLOOP
+    * For IF, points to ELSE or ENDIF.
+    * For ELSE, points to ENDIF.
+    */
+   GLint BranchTarget;
+
+   /** for debugging purposes */
+   const char *Comment;
+
+   /** Arbitrary data.  Used for OPCODE_PRINT and some drivers */
+   void *Data;
+
+   /** for driver use (try to remove someday) */
+   GLint Aux;
+};
+
+
+extern void
+_mesa_init_instructions(struct prog_instruction *inst, GLuint count);
+
+extern struct prog_instruction *
+_mesa_alloc_instructions(GLuint numInst);
+
+extern struct prog_instruction *
+_mesa_realloc_instructions(struct prog_instruction *oldInst,
+                           GLuint numOldInst, GLuint numNewInst);
+
+extern struct prog_instruction *
+_mesa_copy_instructions(struct prog_instruction *dest,
+                        const struct prog_instruction *src, GLuint n);
+
+extern void
+_mesa_free_instructions(struct prog_instruction *inst, GLuint count);
+
+extern GLuint
+_mesa_num_inst_src_regs(gl_inst_opcode opcode);
+
+extern GLuint
+_mesa_num_inst_dst_regs(gl_inst_opcode opcode);
+
+extern GLboolean
+_mesa_is_tex_instruction(gl_inst_opcode opcode);
+
+extern GLboolean
+_mesa_check_soa_dependencies(const struct prog_instruction *inst);
+
+extern const char *
+_mesa_opcode_string(gl_inst_opcode opcode);
+
+
+#endif /* PROG_INSTRUCTION_H */
diff --git a/src/mesa/program/prog_noise.c b/src/mesa/program/prog_noise.c
new file mode 100644 (file)
index 0000000..1713ddb
--- /dev/null
@@ -0,0 +1,638 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * SimplexNoise1234
+ * Copyright (c) 2003-2005, Stefan Gustavson
+ *
+ * Contact: stegu@itn.liu.se
+ */
+
+/**
+ * \file
+ * \brief C implementation of Perlin Simplex Noise over 1, 2, 3 and 4 dims.
+ * \author Stefan Gustavson (stegu@itn.liu.se)
+ *
+ *
+ * This implementation is "Simplex Noise" as presented by
+ * Ken Perlin at a relatively obscure and not often cited course
+ * session "Real-Time Shading" at Siggraph 2001 (before real
+ * time shading actually took on), under the title "hardware noise".
+ * The 3D function is numerically equivalent to his Java reference
+ * code available in the PDF course notes, although I re-implemented
+ * it from scratch to get more readable code. The 1D, 2D and 4D cases
+ * were implemented from scratch by me from Ken Perlin's text.
+ *
+ * This file has no dependencies on any other file, not even its own
+ * header file. The header file is made for use by external code only.
+ */
+
+
+#include "main/imports.h"
+#include "prog_noise.h"
+
+#define FASTFLOOR(x) ( ((x)>0) ? ((int)x) : (((int)x)-1) )
+
+/*
+ * ---------------------------------------------------------------------
+ * Static data
+ */
+
+/**
+ * Permutation table. This is just a random jumble of all numbers 0-255,
+ * repeated twice to avoid wrapping the index at 255 for each lookup.
+ * This needs to be exactly the same for all instances on all platforms,
+ * so it's easiest to just keep it as static explicit data.
+ * This also removes the need for any initialisation of this class.
+ *
+ * Note that making this an int[] instead of a char[] might make the
+ * code run faster on platforms with a high penalty for unaligned single
+ * byte addressing. Intel x86 is generally single-byte-friendly, but
+ * some other CPUs are faster with 4-aligned reads.
+ * However, a char[] is smaller, which avoids cache trashing, and that
+ * is probably the most important aspect on most architectures.
+ * This array is accessed a *lot* by the noise functions.
+ * A vector-valued noise over 3D accesses it 96 times, and a
+ * float-valued 4D noise 64 times. We want this to fit in the cache!
+ */
+unsigned char perm[512] = { 151, 160, 137, 91, 90, 15,
+   131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8,
+      99, 37, 240, 21, 10, 23,
+   190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35,
+      11, 32, 57, 177, 33,
+   88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71,
+      134, 139, 48, 27, 166,
+   77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41,
+      55, 46, 245, 40, 244,
+   102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89,
+      18, 169, 200, 196,
+   135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217,
+      226, 250, 124, 123,
+   5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58,
+      17, 182, 189, 28, 42,
+   223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155,
+      167, 43, 172, 9,
+   129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104,
+      218, 246, 97, 228,
+   251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235,
+      249, 14, 239, 107,
+   49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45,
+      127, 4, 150, 254,
+   138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66,
+      215, 61, 156, 180,
+   151, 160, 137, 91, 90, 15,
+   131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8,
+      99, 37, 240, 21, 10, 23,
+   190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35,
+      11, 32, 57, 177, 33,
+   88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71,
+      134, 139, 48, 27, 166,
+   77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41,
+      55, 46, 245, 40, 244,
+   102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89,
+      18, 169, 200, 196,
+   135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217,
+      226, 250, 124, 123,
+   5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58,
+      17, 182, 189, 28, 42,
+   223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155,
+      167, 43, 172, 9,
+   129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104,
+      218, 246, 97, 228,
+   251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235,
+      249, 14, 239, 107,
+   49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45,
+      127, 4, 150, 254,
+   138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66,
+      215, 61, 156, 180
+};
+
+/*
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * Helper functions to compute gradients-dot-residualvectors (1D to 4D)
+ * Note that these generate gradients of more than unit length. To make
+ * a close match with the value range of classic Perlin noise, the final
+ * noise values need to be rescaled to fit nicely within [-1,1].
+ * (The simplex noise functions as such also have different scaling.)
+ * Note also that these noise functions are the most practical and useful
+ * signed version of Perlin noise. To return values according to the
+ * RenderMan specification from the SL noise() and pnoise() functions,
+ * the noise values need to be scaled and offset to [0,1], like this:
+ * float SLnoise = (SimplexNoise1234::noise(x,y,z) + 1.0) * 0.5;
+ */
+
+static float
+grad1(int hash, float x)
+{
+   int h = hash & 15;
+   float grad = 1.0f + (h & 7); /* Gradient value 1.0, 2.0, ..., 8.0 */
+   if (h & 8)
+      grad = -grad;             /* Set a random sign for the gradient */
+   return (grad * x);           /* Multiply the gradient with the distance */
+}
+
+static float
+grad2(int hash, float x, float y)
+{
+   int h = hash & 7;            /* Convert low 3 bits of hash code */
+   float u = h < 4 ? x : y;     /* into 8 simple gradient directions, */
+   float v = h < 4 ? y : x;     /* and compute the dot product with (x,y). */
+   return ((h & 1) ? -u : u) + ((h & 2) ? -2.0f * v : 2.0f * v);
+}
+
+static float
+grad3(int hash, float x, float y, float z)
+{
+   int h = hash & 15;           /* Convert low 4 bits of hash code into 12 simple */
+   float u = h < 8 ? x : y;     /* gradient directions, and compute dot product. */
+   float v = h < 4 ? y : h == 12 || h == 14 ? x : z;    /* Fix repeats at h = 12 to 15 */
+   return ((h & 1) ? -u : u) + ((h & 2) ? -v : v);
+}
+
+static float
+grad4(int hash, float x, float y, float z, float t)
+{
+   int h = hash & 31;           /* Convert low 5 bits of hash code into 32 simple */
+   float u = h < 24 ? x : y;    /* gradient directions, and compute dot product. */
+   float v = h < 16 ? y : z;
+   float w = h < 8 ? z : t;
+   return ((h & 1) ? -u : u) + ((h & 2) ? -v : v) + ((h & 4) ? -w : w);
+}
+
+/**
+ * A lookup table to traverse the simplex around a given point in 4D.
+ * Details can be found where this table is used, in the 4D noise method.
+ * TODO: This should not be required, backport it from Bill's GLSL code!
+ */
+static unsigned char simplex[64][4] = {
+   {0, 1, 2, 3}, {0, 1, 3, 2}, {0, 0, 0, 0}, {0, 2, 3, 1},
+   {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {1, 2, 3, 0},
+   {0, 2, 1, 3}, {0, 0, 0, 0}, {0, 3, 1, 2}, {0, 3, 2, 1},
+   {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {1, 3, 2, 0},
+   {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
+   {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
+   {1, 2, 0, 3}, {0, 0, 0, 0}, {1, 3, 0, 2}, {0, 0, 0, 0},
+   {0, 0, 0, 0}, {0, 0, 0, 0}, {2, 3, 0, 1}, {2, 3, 1, 0},
+   {1, 0, 2, 3}, {1, 0, 3, 2}, {0, 0, 0, 0}, {0, 0, 0, 0},
+   {0, 0, 0, 0}, {2, 0, 3, 1}, {0, 0, 0, 0}, {2, 1, 3, 0},
+   {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
+   {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
+   {2, 0, 1, 3}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
+   {3, 0, 1, 2}, {3, 0, 2, 1}, {0, 0, 0, 0}, {3, 1, 2, 0},
+   {2, 1, 0, 3}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
+   {3, 1, 0, 2}, {0, 0, 0, 0}, {3, 2, 0, 1}, {3, 2, 1, 0}
+};
+
+
+/** 1D simplex noise */
+GLfloat
+_mesa_noise1(GLfloat x)
+{
+   int i0 = FASTFLOOR(x);
+   int i1 = i0 + 1;
+   float x0 = x - i0;
+   float x1 = x0 - 1.0f;
+   float t1 = 1.0f - x1 * x1;
+   float n0, n1;
+
+   float t0 = 1.0f - x0 * x0;
+/*  if(t0 < 0.0f) t0 = 0.0f; // this never happens for the 1D case */
+   t0 *= t0;
+   n0 = t0 * t0 * grad1(perm[i0 & 0xff], x0);
+
+/*  if(t1 < 0.0f) t1 = 0.0f; // this never happens for the 1D case */
+   t1 *= t1;
+   n1 = t1 * t1 * grad1(perm[i1 & 0xff], x1);
+   /* The maximum value of this noise is 8*(3/4)^4 = 2.53125 */
+   /* A factor of 0.395 would scale to fit exactly within [-1,1], but */
+   /* we want to match PRMan's 1D noise, so we scale it down some more. */
+   return 0.25f * (n0 + n1);
+}
+
+
+/** 2D simplex noise */
+GLfloat
+_mesa_noise2(GLfloat x, GLfloat y)
+{
+#define F2 0.366025403f         /* F2 = 0.5*(sqrt(3.0)-1.0) */
+#define G2 0.211324865f         /* G2 = (3.0-Math.sqrt(3.0))/6.0 */
+
+   float n0, n1, n2;            /* Noise contributions from the three corners */
+
+   /* Skew the input space to determine which simplex cell we're in */
+   float s = (x + y) * F2;      /* Hairy factor for 2D */
+   float xs = x + s;
+   float ys = y + s;
+   int i = FASTFLOOR(xs);
+   int j = FASTFLOOR(ys);
+
+   float t = (float) (i + j) * G2;
+   float X0 = i - t;            /* Unskew the cell origin back to (x,y) space */
+   float Y0 = j - t;
+   float x0 = x - X0;           /* The x,y distances from the cell origin */
+   float y0 = y - Y0;
+
+   float x1, y1, x2, y2;
+   int ii, jj;
+   float t0, t1, t2;
+
+   /* For the 2D case, the simplex shape is an equilateral triangle. */
+   /* Determine which simplex we are in. */
+   int i1, j1;                  /* Offsets for second (middle) corner of simplex in (i,j) coords */
+   if (x0 > y0) {
+      i1 = 1;
+      j1 = 0;
+   }                            /* lower triangle, XY order: (0,0)->(1,0)->(1,1) */
+   else {
+      i1 = 0;
+      j1 = 1;
+   }                            /* upper triangle, YX order: (0,0)->(0,1)->(1,1) */
+
+   /* A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and */
+   /* a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where */
+   /* c = (3-sqrt(3))/6 */
+
+   x1 = x0 - i1 + G2;           /* Offsets for middle corner in (x,y) unskewed coords */
+   y1 = y0 - j1 + G2;
+   x2 = x0 - 1.0f + 2.0f * G2;  /* Offsets for last corner in (x,y) unskewed coords */
+   y2 = y0 - 1.0f + 2.0f * G2;
+
+   /* Wrap the integer indices at 256, to avoid indexing perm[] out of bounds */
+   ii = i % 256;
+   jj = j % 256;
+
+   /* Calculate the contribution from the three corners */
+   t0 = 0.5f - x0 * x0 - y0 * y0;
+   if (t0 < 0.0f)
+      n0 = 0.0f;
+   else {
+      t0 *= t0;
+      n0 = t0 * t0 * grad2(perm[ii + perm[jj]], x0, y0);
+   }
+
+   t1 = 0.5f - x1 * x1 - y1 * y1;
+   if (t1 < 0.0f)
+      n1 = 0.0f;
+   else {
+      t1 *= t1;
+      n1 = t1 * t1 * grad2(perm[ii + i1 + perm[jj + j1]], x1, y1);
+   }
+
+   t2 = 0.5f - x2 * x2 - y2 * y2;
+   if (t2 < 0.0f)
+      n2 = 0.0f;
+   else {
+      t2 *= t2;
+      n2 = t2 * t2 * grad2(perm[ii + 1 + perm[jj + 1]], x2, y2);
+   }
+
+   /* Add contributions from each corner to get the final noise value. */
+   /* The result is scaled to return values in the interval [-1,1]. */
+   return 40.0f * (n0 + n1 + n2);       /* TODO: The scale factor is preliminary! */
+}
+
+
+/** 3D simplex noise */
+GLfloat
+_mesa_noise3(GLfloat x, GLfloat y, GLfloat z)
+{
+/* Simple skewing factors for the 3D case */
+#define F3 0.333333333f
+#define G3 0.166666667f
+
+   float n0, n1, n2, n3;        /* Noise contributions from the four corners */
+
+   /* Skew the input space to determine which simplex cell we're in */
+   float s = (x + y + z) * F3;  /* Very nice and simple skew factor for 3D */
+   float xs = x + s;
+   float ys = y + s;
+   float zs = z + s;
+   int i = FASTFLOOR(xs);
+   int j = FASTFLOOR(ys);
+   int k = FASTFLOOR(zs);
+
+   float t = (float) (i + j + k) * G3;
+   float X0 = i - t;            /* Unskew the cell origin back to (x,y,z) space */
+   float Y0 = j - t;
+   float Z0 = k - t;
+   float x0 = x - X0;           /* The x,y,z distances from the cell origin */
+   float y0 = y - Y0;
+   float z0 = z - Z0;
+
+   float x1, y1, z1, x2, y2, z2, x3, y3, z3;
+   int ii, jj, kk;
+   float t0, t1, t2, t3;
+
+   /* For the 3D case, the simplex shape is a slightly irregular tetrahedron. */
+   /* Determine which simplex we are in. */
+   int i1, j1, k1;              /* Offsets for second corner of simplex in (i,j,k) coords */
+   int i2, j2, k2;              /* Offsets for third corner of simplex in (i,j,k) coords */
+
+/* This code would benefit from a backport from the GLSL version! */
+   if (x0 >= y0) {
+      if (y0 >= z0) {
+         i1 = 1;
+         j1 = 0;
+         k1 = 0;
+         i2 = 1;
+         j2 = 1;
+         k2 = 0;
+      }                         /* X Y Z order */
+      else if (x0 >= z0) {
+         i1 = 1;
+         j1 = 0;
+         k1 = 0;
+         i2 = 1;
+         j2 = 0;
+         k2 = 1;
+      }                         /* X Z Y order */
+      else {
+         i1 = 0;
+         j1 = 0;
+         k1 = 1;
+         i2 = 1;
+         j2 = 0;
+         k2 = 1;
+      }                         /* Z X Y order */
+   }
+   else {                       /* x0<y0 */
+      if (y0 < z0) {
+         i1 = 0;
+         j1 = 0;
+         k1 = 1;
+         i2 = 0;
+         j2 = 1;
+         k2 = 1;
+      }                         /* Z Y X order */
+      else if (x0 < z0) {
+         i1 = 0;
+         j1 = 1;
+         k1 = 0;
+         i2 = 0;
+         j2 = 1;
+         k2 = 1;
+      }                         /* Y Z X order */
+      else {
+         i1 = 0;
+         j1 = 1;
+         k1 = 0;
+         i2 = 1;
+         j2 = 1;
+         k2 = 0;
+      }                         /* Y X Z order */
+   }
+
+   /* A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in
+    * (x,y,z), a step of (0,1,0) in (i,j,k) means a step of
+    * (-c,1-c,-c) in (x,y,z), and a step of (0,0,1) in (i,j,k) means a
+    * step of (-c,-c,1-c) in (x,y,z), where c = 1/6.
+    */
+
+   x1 = x0 - i1 + G3;         /* Offsets for second corner in (x,y,z) coords */
+   y1 = y0 - j1 + G3;
+   z1 = z0 - k1 + G3;
+   x2 = x0 - i2 + 2.0f * G3;  /* Offsets for third corner in (x,y,z) coords */
+   y2 = y0 - j2 + 2.0f * G3;
+   z2 = z0 - k2 + 2.0f * G3;
+   x3 = x0 - 1.0f + 3.0f * G3;/* Offsets for last corner in (x,y,z) coords */
+   y3 = y0 - 1.0f + 3.0f * G3;
+   z3 = z0 - 1.0f + 3.0f * G3;
+
+   /* Wrap the integer indices at 256 to avoid indexing perm[] out of bounds */
+   ii = i % 256;
+   jj = j % 256;
+   kk = k % 256;
+
+   /* Calculate the contribution from the four corners */
+   t0 = 0.6f - x0 * x0 - y0 * y0 - z0 * z0;
+   if (t0 < 0.0f)
+      n0 = 0.0f;
+   else {
+      t0 *= t0;
+      n0 = t0 * t0 * grad3(perm[ii + perm[jj + perm[kk]]], x0, y0, z0);
+   }
+
+   t1 = 0.6f - x1 * x1 - y1 * y1 - z1 * z1;
+   if (t1 < 0.0f)
+      n1 = 0.0f;
+   else {
+      t1 *= t1;
+      n1 =
+         t1 * t1 * grad3(perm[ii + i1 + perm[jj + j1 + perm[kk + k1]]], x1,
+                         y1, z1);
+   }
+
+   t2 = 0.6f - x2 * x2 - y2 * y2 - z2 * z2;
+   if (t2 < 0.0f)
+      n2 = 0.0f;
+   else {
+      t2 *= t2;
+      n2 =
+         t2 * t2 * grad3(perm[ii + i2 + perm[jj + j2 + perm[kk + k2]]], x2,
+                         y2, z2);
+   }
+
+   t3 = 0.6f - x3 * x3 - y3 * y3 - z3 * z3;
+   if (t3 < 0.0f)
+      n3 = 0.0f;
+   else {
+      t3 *= t3;
+      n3 =
+         t3 * t3 * grad3(perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]], x3, y3,
+                         z3);
+   }
+
+   /* Add contributions from each corner to get the final noise value.
+    * The result is scaled to stay just inside [-1,1]
+    */
+   return 32.0f * (n0 + n1 + n2 + n3);  /* TODO: The scale factor is preliminary! */
+}
+
+
+/** 4D simplex noise */
+GLfloat
+_mesa_noise4(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+   /* The skewing and unskewing factors are hairy again for the 4D case */
+#define F4 0.309016994f         /* F4 = (Math.sqrt(5.0)-1.0)/4.0 */
+#define G4 0.138196601f         /* G4 = (5.0-Math.sqrt(5.0))/20.0 */
+
+   float n0, n1, n2, n3, n4;    /* Noise contributions from the five corners */
+
+   /* Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in */
+   float s = (x + y + z + w) * F4;      /* Factor for 4D skewing */
+   float xs = x + s;
+   float ys = y + s;
+   float zs = z + s;
+   float ws = w + s;
+   int i = FASTFLOOR(xs);
+   int j = FASTFLOOR(ys);
+   int k = FASTFLOOR(zs);
+   int l = FASTFLOOR(ws);
+
+   float t = (i + j + k + l) * G4;      /* Factor for 4D unskewing */
+   float X0 = i - t;            /* Unskew the cell origin back to (x,y,z,w) space */
+   float Y0 = j - t;
+   float Z0 = k - t;
+   float W0 = l - t;
+
+   float x0 = x - X0;           /* The x,y,z,w distances from the cell origin */
+   float y0 = y - Y0;
+   float z0 = z - Z0;
+   float w0 = w - W0;
+
+   /* For the 4D case, the simplex is a 4D shape I won't even try to describe.
+    * To find out which of the 24 possible simplices we're in, we need to
+    * determine the magnitude ordering of x0, y0, z0 and w0.
+    * The method below is a good way of finding the ordering of x,y,z,w and
+    * then find the correct traversal order for the simplex we're in.
+    * First, six pair-wise comparisons are performed between each possible pair
+    * of the four coordinates, and the results are used to add up binary bits
+    * for an integer index.
+    */
+   int c1 = (x0 > y0) ? 32 : 0;
+   int c2 = (x0 > z0) ? 16 : 0;
+   int c3 = (y0 > z0) ? 8 : 0;
+   int c4 = (x0 > w0) ? 4 : 0;
+   int c5 = (y0 > w0) ? 2 : 0;
+   int c6 = (z0 > w0) ? 1 : 0;
+   int c = c1 + c2 + c3 + c4 + c5 + c6;
+
+   int i1, j1, k1, l1;  /* The integer offsets for the second simplex corner */
+   int i2, j2, k2, l2;  /* The integer offsets for the third simplex corner */
+   int i3, j3, k3, l3;  /* The integer offsets for the fourth simplex corner */
+
+   float x1, y1, z1, w1, x2, y2, z2, w2, x3, y3, z3, w3, x4, y4, z4, w4;
+   int ii, jj, kk, ll;
+   float t0, t1, t2, t3, t4;
+
+   /*
+    * simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some
+    * order.  Many values of c will never occur, since e.g. x>y>z>w
+    * makes x<z, y<w and x<w impossible. Only the 24 indices which
+    * have non-zero entries make any sense.  We use a thresholding to
+    * set the coordinates in turn from the largest magnitude.  The
+    * number 3 in the "simplex" array is at the position of the
+    * largest coordinate.
+    */
+   i1 = simplex[c][0] >= 3 ? 1 : 0;
+   j1 = simplex[c][1] >= 3 ? 1 : 0;
+   k1 = simplex[c][2] >= 3 ? 1 : 0;
+   l1 = simplex[c][3] >= 3 ? 1 : 0;
+   /* The number 2 in the "simplex" array is at the second largest coordinate. */
+   i2 = simplex[c][0] >= 2 ? 1 : 0;
+   j2 = simplex[c][1] >= 2 ? 1 : 0;
+   k2 = simplex[c][2] >= 2 ? 1 : 0;
+   l2 = simplex[c][3] >= 2 ? 1 : 0;
+   /* The number 1 in the "simplex" array is at the second smallest coordinate. */
+   i3 = simplex[c][0] >= 1 ? 1 : 0;
+   j3 = simplex[c][1] >= 1 ? 1 : 0;
+   k3 = simplex[c][2] >= 1 ? 1 : 0;
+   l3 = simplex[c][3] >= 1 ? 1 : 0;
+   /* The fifth corner has all coordinate offsets = 1, so no need to look that up. */
+
+   x1 = x0 - i1 + G4;           /* Offsets for second corner in (x,y,z,w) coords */
+   y1 = y0 - j1 + G4;
+   z1 = z0 - k1 + G4;
+   w1 = w0 - l1 + G4;
+   x2 = x0 - i2 + 2.0f * G4;    /* Offsets for third corner in (x,y,z,w) coords */
+   y2 = y0 - j2 + 2.0f * G4;
+   z2 = z0 - k2 + 2.0f * G4;
+   w2 = w0 - l2 + 2.0f * G4;
+   x3 = x0 - i3 + 3.0f * G4;    /* Offsets for fourth corner in (x,y,z,w) coords */
+   y3 = y0 - j3 + 3.0f * G4;
+   z3 = z0 - k3 + 3.0f * G4;
+   w3 = w0 - l3 + 3.0f * G4;
+   x4 = x0 - 1.0f + 4.0f * G4;  /* Offsets for last corner in (x,y,z,w) coords */
+   y4 = y0 - 1.0f + 4.0f * G4;
+   z4 = z0 - 1.0f + 4.0f * G4;
+   w4 = w0 - 1.0f + 4.0f * G4;
+
+   /* Wrap the integer indices at 256, to avoid indexing perm[] out of bounds */
+   ii = i % 256;
+   jj = j % 256;
+   kk = k % 256;
+   ll = l % 256;
+
+   /* Calculate the contribution from the five corners */
+   t0 = 0.6f - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0;
+   if (t0 < 0.0f)
+      n0 = 0.0f;
+   else {
+      t0 *= t0;
+      n0 =
+         t0 * t0 * grad4(perm[ii + perm[jj + perm[kk + perm[ll]]]], x0, y0,
+                         z0, w0);
+   }
+
+   t1 = 0.6f - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1;
+   if (t1 < 0.0f)
+      n1 = 0.0f;
+   else {
+      t1 *= t1;
+      n1 =
+         t1 * t1 *
+         grad4(perm[ii + i1 + perm[jj + j1 + perm[kk + k1 + perm[ll + l1]]]],
+               x1, y1, z1, w1);
+   }
+
+   t2 = 0.6f - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2;
+   if (t2 < 0.0f)
+      n2 = 0.0f;
+   else {
+      t2 *= t2;
+      n2 =
+         t2 * t2 *
+         grad4(perm[ii + i2 + perm[jj + j2 + perm[kk + k2 + perm[ll + l2]]]],
+               x2, y2, z2, w2);
+   }
+
+   t3 = 0.6f - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3;
+   if (t3 < 0.0f)
+      n3 = 0.0f;
+   else {
+      t3 *= t3;
+      n3 =
+         t3 * t3 *
+         grad4(perm[ii + i3 + perm[jj + j3 + perm[kk + k3 + perm[ll + l3]]]],
+               x3, y3, z3, w3);
+   }
+
+   t4 = 0.6f - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4;
+   if (t4 < 0.0f)
+      n4 = 0.0f;
+   else {
+      t4 *= t4;
+      n4 =
+         t4 * t4 *
+         grad4(perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]], x4,
+               y4, z4, w4);
+   }
+
+   /* Sum up and scale the result to cover the range [-1,1] */
+   return 27.0f * (n0 + n1 + n2 + n3 + n4);     /* TODO: The scale factor is preliminary! */
+}
diff --git a/src/mesa/program/prog_noise.h b/src/mesa/program/prog_noise.h
new file mode 100644 (file)
index 0000000..c477947
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef PROG_NOISE
+#define PROG_NOISE
+
+extern GLfloat _mesa_noise1(GLfloat);
+extern GLfloat _mesa_noise2(GLfloat, GLfloat);
+extern GLfloat _mesa_noise3(GLfloat, GLfloat, GLfloat);
+extern GLfloat _mesa_noise4(GLfloat, GLfloat, GLfloat, GLfloat);
+
+#endif
+
diff --git a/src/mesa/program/prog_optimize.c b/src/mesa/program/prog_optimize.c
new file mode 100644 (file)
index 0000000..bd120b8
--- /dev/null
@@ -0,0 +1,1041 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.5
+ *
+ * Copyright (C) 2009  VMware, 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
+ * 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
+ * VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION 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/context.h"
+#include "main/macros.h"
+#include "program.h"
+#include "prog_instruction.h"
+#include "prog_optimize.h"
+#include "prog_print.h"
+
+
+#define MAX_LOOP_NESTING 50
+
+
+static GLboolean dbg = GL_FALSE;
+
+/* Returns the mask of channels read from the given srcreg in this instruction.
+ */
+static GLuint
+get_src_arg_mask(const struct prog_instruction *inst, int arg)
+{
+   int writemask = inst->DstReg.WriteMask;
+
+   if (inst->CondUpdate)
+      writemask = WRITEMASK_XYZW;
+
+   switch (inst->Opcode) {
+   case OPCODE_MOV:
+   case OPCODE_ABS:
+   case OPCODE_ADD:
+   case OPCODE_MUL:
+   case OPCODE_SUB:
+      return writemask;
+   case OPCODE_RCP:
+   case OPCODE_SIN:
+   case OPCODE_COS:
+   case OPCODE_RSQ:
+   case OPCODE_POW:
+   case OPCODE_EX2:
+      return WRITEMASK_X;
+   case OPCODE_DP2:
+      return WRITEMASK_XY;
+   case OPCODE_DP3:
+   case OPCODE_XPD:
+      return WRITEMASK_XYZ;
+   default:
+      return WRITEMASK_XYZW;
+   }
+}
+
+/**
+ * In 'prog' remove instruction[i] if removeFlags[i] == TRUE.
+ * \return number of instructions removed
+ */
+static GLuint
+remove_instructions(struct gl_program *prog, const GLboolean *removeFlags)
+{
+   GLint i, removeEnd = 0, removeCount = 0;
+   GLuint totalRemoved = 0;
+
+   /* go backward */
+   for (i = prog->NumInstructions - 1; i >= 0; i--) {
+      if (removeFlags[i]) {
+         totalRemoved++;
+         if (removeCount == 0) {
+            /* begin a run of instructions to remove */
+            removeEnd = i;
+            removeCount = 1;
+         }
+         else {
+            /* extend the run of instructions to remove */
+            removeCount++;
+         }
+      }
+      else {
+         /* don't remove this instruction, but check if the preceeding
+          * instructions are to be removed.
+          */
+         if (removeCount > 0) {
+            GLint removeStart = removeEnd - removeCount + 1;
+            _mesa_delete_instructions(prog, removeStart, removeCount);
+            removeStart = removeCount = 0; /* reset removal info */
+         }
+      }
+   }
+   /* Finish removing if the first instruction was to be removed. */
+   if (removeCount > 0) {
+      GLint removeStart = removeEnd - removeCount + 1;
+      _mesa_delete_instructions(prog, removeStart, removeCount);
+   }
+   return totalRemoved;
+}
+
+
+/**
+ * Remap register indexes according to map.
+ * \param prog  the program to search/replace
+ * \param file  the type of register file to search/replace
+ * \param map  maps old register indexes to new indexes
+ */
+static void
+replace_regs(struct gl_program *prog, gl_register_file file, const GLint map[])
+{
+   GLuint i;
+
+   for (i = 0; i < prog->NumInstructions; i++) {
+      struct prog_instruction *inst = prog->Instructions + i;
+      const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
+      GLuint j;
+      for (j = 0; j < numSrc; j++) {
+         if (inst->SrcReg[j].File == file) {
+            GLuint index = inst->SrcReg[j].Index;
+            ASSERT(map[index] >= 0);
+            inst->SrcReg[j].Index = map[index];
+         }
+      }
+      if (inst->DstReg.File == file) {
+         const GLuint index = inst->DstReg.Index;
+         ASSERT(map[index] >= 0);
+         inst->DstReg.Index = map[index];
+      }
+   }
+}
+
+
+/**
+ * Consolidate temporary registers to use low numbers.  For example, if the
+ * shader only uses temps 4, 5, 8, replace them with 0, 1, 2.
+ */
+static void
+_mesa_consolidate_registers(struct gl_program *prog)
+{
+   GLboolean tempUsed[MAX_PROGRAM_TEMPS];
+   GLint tempMap[MAX_PROGRAM_TEMPS];
+   GLuint tempMax = 0, i;
+
+   if (dbg) {
+      printf("Optimize: Begin register consolidation\n");
+   }
+
+   memset(tempUsed, 0, sizeof(tempUsed));
+
+   for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
+      tempMap[i] = -1;
+   }
+
+   /* set tempUsed[i] if temporary [i] is referenced */
+   for (i = 0; i < prog->NumInstructions; i++) {
+      const struct prog_instruction *inst = prog->Instructions + i;
+      const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
+      GLuint j;
+      for (j = 0; j < numSrc; j++) {
+         if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) {
+            const GLuint index = inst->SrcReg[j].Index;
+            ASSERT(index < MAX_PROGRAM_TEMPS);
+            tempUsed[index] = GL_TRUE;
+            tempMax = MAX2(tempMax, index);
+            break;
+         }
+      }
+      if (inst->DstReg.File == PROGRAM_TEMPORARY) {
+         const GLuint index = inst->DstReg.Index;
+         ASSERT(index < MAX_PROGRAM_TEMPS);
+         tempUsed[index] = GL_TRUE;
+         tempMax = MAX2(tempMax, index);
+      }
+   }
+
+   /* allocate a new index for each temp that's used */
+   {
+      GLuint freeTemp = 0;
+      for (i = 0; i <= tempMax; i++) {
+         if (tempUsed[i]) {
+            tempMap[i] = freeTemp++;
+            /*printf("replace %u with %u\n", i, tempMap[i]);*/
+         }
+      }
+      if (freeTemp == tempMax + 1) {
+         /* no consolidation possible */
+         return;
+      }         
+      if (dbg) {
+         printf("Replace regs 0..%u with 0..%u\n", tempMax, freeTemp-1);
+      }
+   }
+
+   replace_regs(prog, PROGRAM_TEMPORARY, tempMap);
+
+   if (dbg) {
+      printf("Optimize: End register consolidation\n");
+   }
+}
+
+
+/**
+ * Remove dead instructions from the given program.
+ * This is very primitive for now.  Basically look for temp registers
+ * that are written to but never read.  Remove any instructions that
+ * write to such registers.  Be careful with condition code setters.
+ */
+static void
+_mesa_remove_dead_code(struct gl_program *prog)
+{
+   GLboolean tempRead[MAX_PROGRAM_TEMPS][4];
+   GLboolean *removeInst; /* per-instruction removal flag */
+   GLuint i, rem = 0, comp;
+
+   memset(tempRead, 0, sizeof(tempRead));
+
+   if (dbg) {
+      printf("Optimize: Begin dead code removal\n");
+      /*_mesa_print_program(prog);*/
+   }
+
+   removeInst = (GLboolean *)
+      calloc(1, prog->NumInstructions * sizeof(GLboolean));
+
+   /* Determine which temps are read and written */
+   for (i = 0; i < prog->NumInstructions; i++) {
+      const struct prog_instruction *inst = prog->Instructions + i;
+      const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
+      GLuint j;
+
+      /* check src regs */
+      for (j = 0; j < numSrc; j++) {
+         if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) {
+            const GLuint index = inst->SrcReg[j].Index;
+            GLuint read_mask;
+            ASSERT(index < MAX_PROGRAM_TEMPS);
+           read_mask = get_src_arg_mask(inst, j);
+
+            if (inst->SrcReg[j].RelAddr) {
+               if (dbg)
+                  printf("abort remove dead code (indirect temp)\n");
+               goto done;
+            }
+
+           for (comp = 0; comp < 4; comp++) {
+              GLuint swz = (inst->SrcReg[j].Swizzle >> (3 * comp)) & 0x7;
+
+              if ((read_mask & (1 << comp)) == 0)
+                 continue;
+
+              switch (swz) {
+              case SWIZZLE_X:
+                 tempRead[index][0] = GL_TRUE;
+                 break;
+              case SWIZZLE_Y:
+                 tempRead[index][1] = GL_TRUE;
+                 break;
+              case SWIZZLE_Z:
+                 tempRead[index][2] = GL_TRUE;
+                 break;
+              case SWIZZLE_W:
+                 tempRead[index][3] = GL_TRUE;
+                 break;
+              }
+           }
+         }
+      }
+
+      /* check dst reg */
+      if (inst->DstReg.File == PROGRAM_TEMPORARY) {
+         const GLuint index = inst->DstReg.Index;
+         ASSERT(index < MAX_PROGRAM_TEMPS);
+
+         if (inst->DstReg.RelAddr) {
+            if (dbg)
+               printf("abort remove dead code (indirect temp)\n");
+            goto done;
+         }
+
+         if (inst->CondUpdate) {
+            /* If we're writing to this register and setting condition
+             * codes we cannot remove the instruction.  Prevent removal
+             * by setting the 'read' flag.
+             */
+            tempRead[index][0] = GL_TRUE;
+            tempRead[index][1] = GL_TRUE;
+            tempRead[index][2] = GL_TRUE;
+            tempRead[index][3] = GL_TRUE;
+         }
+      }
+   }
+
+   /* find instructions that write to dead registers, flag for removal */
+   for (i = 0; i < prog->NumInstructions; i++) {
+      struct prog_instruction *inst = prog->Instructions + i;
+      const GLuint numDst = _mesa_num_inst_dst_regs(inst->Opcode);
+
+      if (numDst != 0 && inst->DstReg.File == PROGRAM_TEMPORARY) {
+         GLint chan, index = inst->DstReg.Index;
+
+        for (chan = 0; chan < 4; chan++) {
+           if (!tempRead[index][chan] &&
+               inst->DstReg.WriteMask & (1 << chan)) {
+              if (dbg) {
+                 printf("Remove writemask on %u.%c\n", i,
+                              chan == 3 ? 'w' : 'x' + chan);
+              }
+              inst->DstReg.WriteMask &= ~(1 << chan);
+              rem++;
+           }
+        }
+
+        if (inst->DstReg.WriteMask == 0) {
+           /* If we cleared all writes, the instruction can be removed. */
+           if (dbg)
+              printf("Remove instruction %u: \n", i);
+           removeInst[i] = GL_TRUE;
+        }
+      }
+   }
+
+   /* now remove the instructions which aren't needed */
+   rem = remove_instructions(prog, removeInst);
+
+   if (dbg) {
+      printf("Optimize: End dead code removal.\n");
+      printf("  %u channel writes removed\n", rem);
+      printf("  %u instructions removed\n", rem);
+      /*_mesa_print_program(prog);*/
+   }
+
+done:
+   free(removeInst);
+}
+
+
+enum temp_use
+{
+   READ,
+   WRITE,
+   FLOW,
+   END
+};
+
+/**
+ * Scan forward in program from 'start' for the next occurance of TEMP[index].
+ * Return READ, WRITE, FLOW or END to indicate the next usage or an indicator
+ * that we can't look further.
+ */
+static enum temp_use
+find_next_temp_use(const struct gl_program *prog, GLuint start, GLuint index)
+{
+   GLuint i;
+
+   for (i = start; i < prog->NumInstructions; i++) {
+      const struct prog_instruction *inst = prog->Instructions + i;
+      switch (inst->Opcode) {
+      case OPCODE_BGNLOOP:
+      case OPCODE_ENDLOOP:
+      case OPCODE_BGNSUB:
+      case OPCODE_ENDSUB:
+         return FLOW;
+      default:
+         {
+            const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
+            GLuint j;
+            for (j = 0; j < numSrc; j++) {
+               if (inst->SrcReg[j].File == PROGRAM_TEMPORARY &&
+                   inst->SrcReg[j].Index == index)
+                  return READ;
+            }
+            if (inst->DstReg.File == PROGRAM_TEMPORARY &&
+                inst->DstReg.Index == index)
+               return WRITE;
+         }
+      }
+   }
+
+   return END;
+}
+
+static GLboolean _mesa_is_flow_control_opcode(enum prog_opcode opcode)
+{
+   switch (opcode) {
+   case OPCODE_BGNLOOP:
+   case OPCODE_BGNSUB:
+   case OPCODE_BRA:
+   case OPCODE_CAL:
+   case OPCODE_CONT:
+   case OPCODE_IF:
+   case OPCODE_ELSE:
+   case OPCODE_END:
+   case OPCODE_ENDIF:
+   case OPCODE_ENDLOOP:
+   case OPCODE_ENDSUB:
+   case OPCODE_RET:
+      return GL_TRUE;
+   default:
+      return GL_FALSE;
+   }
+}
+
+/**
+ * Try to remove use of extraneous MOV instructions, to free them up for dead
+ * code removal.
+ */
+static void
+_mesa_remove_extra_move_use(struct gl_program *prog)
+{
+   GLuint i, j;
+
+   if (dbg) {
+      printf("Optimize: Begin remove extra move use\n");
+      _mesa_print_program(prog);
+   }
+
+   /*
+    * Look for sequences such as this:
+    *    MOV tmpX, arg0;
+    *    ...
+    *    FOO tmpY, tmpX, arg1;
+    * and convert into:
+    *    MOV tmpX, arg0;
+    *    ...
+    *    FOO tmpY, arg0, arg1;
+    */
+
+   for (i = 0; i + 1 < prog->NumInstructions; i++) {
+      const struct prog_instruction *mov = prog->Instructions + i;
+
+      if (mov->Opcode != OPCODE_MOV ||
+         mov->DstReg.File != PROGRAM_TEMPORARY ||
+         mov->DstReg.RelAddr ||
+         mov->DstReg.CondMask != COND_TR ||
+         mov->SaturateMode != SATURATE_OFF ||
+         mov->SrcReg[0].RelAddr)
+        continue;
+
+      /* Walk through remaining instructions until the or src reg gets
+       * rewritten or we get into some flow-control, eliminating the use of
+       * this MOV.
+       */
+      for (j = i + 1; j < prog->NumInstructions; j++) {
+        struct prog_instruction *inst2 = prog->Instructions + j;
+        GLuint arg;
+
+        if (_mesa_is_flow_control_opcode(inst2->Opcode))
+            break;
+
+        /* First rewrite this instruction's args if appropriate. */
+        for (arg = 0; arg < _mesa_num_inst_src_regs(inst2->Opcode); arg++) {
+           int comp;
+           int read_mask = get_src_arg_mask(inst2, arg);
+
+           if (inst2->SrcReg[arg].File != mov->DstReg.File ||
+               inst2->SrcReg[arg].Index != mov->DstReg.Index ||
+               inst2->SrcReg[arg].RelAddr ||
+               inst2->SrcReg[arg].Abs)
+              continue;
+
+           /* Check that all the sources for this arg of inst2 come from inst1
+            * or constants.
+            */
+           for (comp = 0; comp < 4; comp++) {
+              int src_swz = GET_SWZ(inst2->SrcReg[arg].Swizzle, comp);
+
+              /* If the MOV didn't write that channel, can't use it. */
+              if ((read_mask & (1 << comp)) &&
+                  src_swz <= SWIZZLE_W &&
+                  (mov->DstReg.WriteMask & (1 << src_swz)) == 0)
+                 break;
+           }
+           if (comp != 4)
+              continue;
+
+           /* Adjust the swizzles of inst2 to point at MOV's source */
+           for (comp = 0; comp < 4; comp++) {
+              int inst2_swz = GET_SWZ(inst2->SrcReg[arg].Swizzle, comp);
+
+              if (inst2_swz <= SWIZZLE_W) {
+                 GLuint s = GET_SWZ(mov->SrcReg[0].Swizzle, inst2_swz);
+                 inst2->SrcReg[arg].Swizzle &= ~(7 << (3 * comp));
+                 inst2->SrcReg[arg].Swizzle |= s << (3 * comp);
+                 inst2->SrcReg[arg].Negate ^= (((mov->SrcReg[0].Negate >>
+                                                 inst2_swz) & 0x1) << comp);
+              }
+           }
+           inst2->SrcReg[arg].File = mov->SrcReg[0].File;
+           inst2->SrcReg[arg].Index = mov->SrcReg[0].Index;
+        }
+
+        /* If this instruction overwrote part of the move, our time is up. */
+        if ((inst2->DstReg.File == mov->DstReg.File &&
+             (inst2->DstReg.RelAddr ||
+              inst2->DstReg.Index == mov->DstReg.Index)) ||
+            (inst2->DstReg.File == mov->SrcReg[0].File &&
+             (inst2->DstReg.RelAddr ||
+              inst2->DstReg.Index == mov->SrcReg[0].Index)))
+           break;
+      }
+   }
+
+   if (dbg) {
+      printf("Optimize: End remove extra move use.\n");
+      /*_mesa_print_program(prog);*/
+   }
+}
+
+/**
+ * Try to remove extraneous MOV instructions from the given program.
+ */
+static void
+_mesa_remove_extra_moves(struct gl_program *prog)
+{
+   GLboolean *removeInst; /* per-instruction removal flag */
+   GLuint i, rem, loopNesting = 0, subroutineNesting = 0;
+
+   if (dbg) {
+      printf("Optimize: Begin remove extra moves\n");
+      _mesa_print_program(prog);
+   }
+
+   removeInst = (GLboolean *)
+      calloc(1, prog->NumInstructions * sizeof(GLboolean));
+
+   /*
+    * Look for sequences such as this:
+    *    FOO tmpX, arg0, arg1;
+    *    MOV tmpY, tmpX;
+    * and convert into:
+    *    FOO tmpY, arg0, arg1;
+    */
+
+   for (i = 0; i < prog->NumInstructions; i++) {
+      const struct prog_instruction *inst = prog->Instructions + i;
+
+      switch (inst->Opcode) {
+      case OPCODE_BGNLOOP:
+         loopNesting++;
+         break;
+      case OPCODE_ENDLOOP:
+         loopNesting--;
+         break;
+      case OPCODE_BGNSUB:
+         subroutineNesting++;
+         break;
+      case OPCODE_ENDSUB:
+         subroutineNesting--;
+         break;
+      case OPCODE_MOV:
+         if (i > 0 &&
+             loopNesting == 0 &&
+             subroutineNesting == 0 &&
+             inst->SrcReg[0].File == PROGRAM_TEMPORARY &&
+             inst->SrcReg[0].Swizzle == SWIZZLE_XYZW) {
+            /* see if this MOV can be removed */
+            const GLuint tempIndex = inst->SrcReg[0].Index;
+            struct prog_instruction *prevInst;
+            GLuint prevI;
+
+            /* get pointer to previous instruction */
+            prevI = i - 1;
+            while (prevI > 0 && removeInst[prevI])
+               prevI--;
+            prevInst = prog->Instructions + prevI;
+
+            if (prevInst->DstReg.File == PROGRAM_TEMPORARY &&
+                prevInst->DstReg.Index == tempIndex &&
+                prevInst->DstReg.WriteMask == WRITEMASK_XYZW) {
+
+               enum temp_use next_use =
+                  find_next_temp_use(prog, i + 1, tempIndex);
+
+               if (next_use == WRITE || next_use == END) {
+                  /* OK, we can safely remove this MOV instruction.
+                   * Transform:
+                   *   prevI: FOO tempIndex, x, y;
+                   *       i: MOV z, tempIndex;
+                   * Into:
+                   *   prevI: FOO z, x, y;
+                   */
+
+                  /* patch up prev inst */
+                  prevInst->DstReg.File = inst->DstReg.File;
+                  prevInst->DstReg.Index = inst->DstReg.Index;
+
+                  /* flag this instruction for removal */
+                  removeInst[i] = GL_TRUE;
+
+                  if (dbg) {
+                     printf("Remove MOV at %u\n", i);
+                     printf("new prev inst %u: ", prevI);
+                     _mesa_print_instruction(prevInst);
+                  }
+               }
+            }
+         }
+         break;
+      default:
+         ; /* nothing */
+      }
+   }
+
+   /* now remove the instructions which aren't needed */
+   rem = remove_instructions(prog, removeInst);
+
+   free(removeInst);
+
+   if (dbg) {
+      printf("Optimize: End remove extra moves.  %u instructions removed\n", rem);
+      /*_mesa_print_program(prog);*/
+   }
+}
+
+
+/** A live register interval */
+struct interval
+{
+   GLuint Reg;         /** The temporary register index */
+   GLuint Start, End;  /** Start/end instruction numbers */
+};
+
+
+/** A list of register intervals */
+struct interval_list
+{
+   GLuint Num;
+   struct interval Intervals[MAX_PROGRAM_TEMPS];
+};
+
+
+static void
+append_interval(struct interval_list *list, const struct interval *inv)
+{
+   list->Intervals[list->Num++] = *inv;
+}
+
+
+/** Insert interval inv into list, sorted by interval end */
+static void
+insert_interval_by_end(struct interval_list *list, const struct interval *inv)
+{
+   /* XXX we could do a binary search insertion here since list is sorted */
+   GLint i = list->Num - 1;
+   while (i >= 0 && list->Intervals[i].End > inv->End) {
+      list->Intervals[i + 1] = list->Intervals[i];
+      i--;
+   }
+   list->Intervals[i + 1] = *inv;
+   list->Num++;
+
+#ifdef DEBUG
+   {
+      GLuint i;
+      for (i = 0; i + 1 < list->Num; i++) {
+         ASSERT(list->Intervals[i].End <= list->Intervals[i + 1].End);
+      }
+   }
+#endif
+}
+
+
+/** Remove the given interval from the interval list */
+static void
+remove_interval(struct interval_list *list, const struct interval *inv)
+{
+   /* XXX we could binary search since list is sorted */
+   GLuint k;
+   for (k = 0; k < list->Num; k++) {
+      if (list->Intervals[k].Reg == inv->Reg) {
+         /* found, remove it */
+         ASSERT(list->Intervals[k].Start == inv->Start);
+         ASSERT(list->Intervals[k].End == inv->End);
+         while (k < list->Num - 1) {
+            list->Intervals[k] = list->Intervals[k + 1];
+            k++;
+         }
+         list->Num--;
+         return;
+      }
+   }
+}
+
+
+/** called by qsort() */
+static int
+compare_start(const void *a, const void *b)
+{
+   const struct interval *ia = (const struct interval *) a;
+   const struct interval *ib = (const struct interval *) b;
+   if (ia->Start < ib->Start)
+      return -1;
+   else if (ia->Start > ib->Start)
+      return +1;
+   else
+      return 0;
+}
+
+/** sort the interval list according to interval starts */
+static void
+sort_interval_list_by_start(struct interval_list *list)
+{
+   qsort(list->Intervals, list->Num, sizeof(struct interval), compare_start);
+#ifdef DEBUG
+   {
+      GLuint i;
+      for (i = 0; i + 1 < list->Num; i++) {
+         ASSERT(list->Intervals[i].Start <= list->Intervals[i + 1].Start);
+      }
+   }
+#endif
+}
+
+struct loop_info
+{
+   GLuint Start, End;  /**< Start, end instructions of loop */
+};
+
+/**
+ * Update the intermediate interval info for register 'index' and
+ * instruction 'ic'.
+ */
+static void
+update_interval(GLint intBegin[], GLint intEnd[],
+               struct loop_info *loopStack, GLuint loopStackDepth,
+               GLuint index, GLuint ic)
+{
+   int i;
+
+   /* If the register is used in a loop, extend its lifetime through the end
+    * of the outermost loop that doesn't contain its definition.
+    */
+   for (i = 0; i < loopStackDepth; i++) {
+      if (intBegin[index] < loopStack[i].Start) {
+        ic = loopStack[i].End;
+        break;
+      }
+   }
+
+   ASSERT(index < MAX_PROGRAM_TEMPS);
+   if (intBegin[index] == -1) {
+      ASSERT(intEnd[index] == -1);
+      intBegin[index] = intEnd[index] = ic;
+   }
+   else {
+      intEnd[index] = ic;
+   }
+}
+
+
+/**
+ * Find first/last instruction that references each temporary register.
+ */
+GLboolean
+_mesa_find_temp_intervals(const struct prog_instruction *instructions,
+                          GLuint numInstructions,
+                          GLint intBegin[MAX_PROGRAM_TEMPS],
+                          GLint intEnd[MAX_PROGRAM_TEMPS])
+{
+   struct loop_info loopStack[MAX_LOOP_NESTING];
+   GLuint loopStackDepth = 0;
+   GLuint i;
+
+   for (i = 0; i < MAX_PROGRAM_TEMPS; i++){
+      intBegin[i] = intEnd[i] = -1;
+   }
+
+   /* Scan instructions looking for temporary registers */
+   for (i = 0; i < numInstructions; i++) {
+      const struct prog_instruction *inst = instructions + i;
+      if (inst->Opcode == OPCODE_BGNLOOP) {
+         loopStack[loopStackDepth].Start = i;
+         loopStack[loopStackDepth].End = inst->BranchTarget;
+         loopStackDepth++;
+      }
+      else if (inst->Opcode == OPCODE_ENDLOOP) {
+         loopStackDepth--;
+      }
+      else if (inst->Opcode == OPCODE_CAL) {
+         return GL_FALSE;
+      }
+      else {
+         const GLuint numSrc = 3;/*_mesa_num_inst_src_regs(inst->Opcode);*/
+         GLuint j;
+         for (j = 0; j < numSrc; j++) {
+            if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) {
+               const GLuint index = inst->SrcReg[j].Index;
+               if (inst->SrcReg[j].RelAddr)
+                  return GL_FALSE;
+               update_interval(intBegin, intEnd, loopStack, loopStackDepth,
+                              index, i);
+            }
+         }
+         if (inst->DstReg.File == PROGRAM_TEMPORARY) {
+            const GLuint index = inst->DstReg.Index;
+            if (inst->DstReg.RelAddr)
+               return GL_FALSE;
+            update_interval(intBegin, intEnd, loopStack, loopStackDepth,
+                           index, i);
+         }
+      }
+   }
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Find the live intervals for each temporary register in the program.
+ * For register R, the interval [A,B] indicates that R is referenced
+ * from instruction A through instruction B.
+ * Special consideration is needed for loops and subroutines.
+ * \return GL_TRUE if success, GL_FALSE if we cannot proceed for some reason
+ */
+static GLboolean
+find_live_intervals(struct gl_program *prog,
+                    struct interval_list *liveIntervals)
+{
+   GLint intBegin[MAX_PROGRAM_TEMPS], intEnd[MAX_PROGRAM_TEMPS];
+   GLuint i;
+
+   /*
+    * Note: we'll return GL_FALSE below if we find relative indexing
+    * into the TEMP register file.  We can't handle that yet.
+    * We also give up on subroutines for now.
+    */
+
+   if (dbg) {
+      printf("Optimize: Begin find intervals\n");
+   }
+
+   /* build intermediate arrays */
+   if (!_mesa_find_temp_intervals(prog->Instructions, prog->NumInstructions,
+                                  intBegin, intEnd))
+      return GL_FALSE;
+
+   /* Build live intervals list from intermediate arrays */
+   liveIntervals->Num = 0;
+   for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
+      if (intBegin[i] >= 0) {
+         struct interval inv;
+         inv.Reg = i;
+         inv.Start = intBegin[i];
+         inv.End = intEnd[i];
+         append_interval(liveIntervals, &inv);
+      }
+   }
+
+   /* Sort the list according to interval starts */
+   sort_interval_list_by_start(liveIntervals);
+
+   if (dbg) {
+      /* print interval info */
+      for (i = 0; i < liveIntervals->Num; i++) {
+         const struct interval *inv = liveIntervals->Intervals + i;
+         printf("Reg[%d] live [%d, %d]:",
+                      inv->Reg, inv->Start, inv->End);
+         if (1) {
+            GLuint j;
+            for (j = 0; j < inv->Start; j++)
+               printf(" ");
+            for (j = inv->Start; j <= inv->End; j++)
+               printf("x");
+         }
+         printf("\n");
+      }
+   }
+
+   return GL_TRUE;
+}
+
+
+/** Scan the array of used register flags to find free entry */
+static GLint
+alloc_register(GLboolean usedRegs[MAX_PROGRAM_TEMPS])
+{
+   GLuint k;
+   for (k = 0; k < MAX_PROGRAM_TEMPS; k++) {
+      if (!usedRegs[k]) {
+         usedRegs[k] = GL_TRUE;
+         return k;
+      }
+   }
+   return -1;
+}
+
+
+/**
+ * This function implements "Linear Scan Register Allocation" to reduce
+ * the number of temporary registers used by the program.
+ *
+ * We compute the "live interval" for all temporary registers then
+ * examine the overlap of the intervals to allocate new registers.
+ * Basically, if two intervals do not overlap, they can use the same register.
+ */
+static void
+_mesa_reallocate_registers(struct gl_program *prog)
+{
+   struct interval_list liveIntervals;
+   GLint registerMap[MAX_PROGRAM_TEMPS];
+   GLboolean usedRegs[MAX_PROGRAM_TEMPS];
+   GLuint i;
+   GLint maxTemp = -1;
+
+   if (dbg) {
+      printf("Optimize: Begin live-interval register reallocation\n");
+      _mesa_print_program(prog);
+   }
+
+   for (i = 0; i < MAX_PROGRAM_TEMPS; i++){
+      registerMap[i] = -1;
+      usedRegs[i] = GL_FALSE;
+   }
+
+   if (!find_live_intervals(prog, &liveIntervals)) {
+      if (dbg)
+         printf("Aborting register reallocation\n");
+      return;
+   }
+
+   {
+      struct interval_list activeIntervals;
+      activeIntervals.Num = 0;
+
+      /* loop over live intervals, allocating a new register for each */
+      for (i = 0; i < liveIntervals.Num; i++) {
+         const struct interval *live = liveIntervals.Intervals + i;
+
+         if (dbg)
+            printf("Consider register %u\n", live->Reg);
+
+         /* Expire old intervals.  Intervals which have ended with respect
+          * to the live interval can have their remapped registers freed.
+          */
+         {
+            GLint j;
+            for (j = 0; j < (GLint) activeIntervals.Num; j++) {
+               const struct interval *inv = activeIntervals.Intervals + j;
+               if (inv->End >= live->Start) {
+                  /* Stop now.  Since the activeInterval list is sorted
+                   * we know we don't have to go further.
+                   */
+                  break;
+               }
+               else {
+                  /* Interval 'inv' has expired */
+                  const GLint regNew = registerMap[inv->Reg];
+                  ASSERT(regNew >= 0);
+
+                  if (dbg)
+                     printf("  expire interval for reg %u\n", inv->Reg);
+
+                  /* remove interval j from active list */
+                  remove_interval(&activeIntervals, inv);
+                  j--;  /* counter-act j++ in for-loop above */
+
+                  /* return register regNew to the free pool */
+                  if (dbg)
+                     printf("  free reg %d\n", regNew);
+                  ASSERT(usedRegs[regNew] == GL_TRUE);
+                  usedRegs[regNew] = GL_FALSE;
+               }
+            }
+         }
+
+         /* find a free register for this live interval */
+         {
+            const GLint k = alloc_register(usedRegs);
+            if (k < 0) {
+               /* out of registers, give up */
+               return;
+            }
+            registerMap[live->Reg] = k;
+            maxTemp = MAX2(maxTemp, k);
+            if (dbg)
+               printf("  remap register %u -> %d\n", live->Reg, k);
+         }
+
+         /* Insert this live interval into the active list which is sorted
+          * by increasing end points.
+          */
+         insert_interval_by_end(&activeIntervals, live);
+      }
+   }
+
+   if (maxTemp + 1 < (GLint) liveIntervals.Num) {
+      /* OK, we've reduced the number of registers needed.
+       * Scan the program and replace all the old temporary register
+       * indexes with the new indexes.
+       */
+      replace_regs(prog, PROGRAM_TEMPORARY, registerMap);
+
+      prog->NumTemporaries = maxTemp + 1;
+   }
+
+   if (dbg) {
+      printf("Optimize: End live-interval register reallocation\n");
+      printf("Num temp regs before: %u  after: %u\n",
+                   liveIntervals.Num, maxTemp + 1);
+      _mesa_print_program(prog);
+   }
+}
+
+
+/**
+ * Apply optimizations to the given program to eliminate unnecessary
+ * instructions, temp regs, etc.
+ */
+void
+_mesa_optimize_program(GLcontext *ctx, struct gl_program *program)
+{
+   _mesa_remove_extra_move_use(program);
+
+   if (1)
+      _mesa_remove_dead_code(program);
+
+   if (0) /* not tested much yet */
+      _mesa_remove_extra_moves(program);
+
+   if (0)
+      _mesa_consolidate_registers(program);
+   else
+      _mesa_reallocate_registers(program);
+}
diff --git a/src/mesa/program/prog_optimize.h b/src/mesa/program/prog_optimize.h
new file mode 100644 (file)
index 0000000..43894a2
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.5
+ *
+ * Copyright (C) 2009  VMware, 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
+ * 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
+ * VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION 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 PROG_OPT_H
+#define PROG_OPT_H
+
+
+#include "main/config.h"
+
+
+struct gl_program;
+struct prog_instruction;
+
+
+extern GLboolean
+_mesa_find_temp_intervals(const struct prog_instruction *instructions,
+                          GLuint numInstructions,
+                          GLint intBegin[MAX_PROGRAM_TEMPS],
+                          GLint intEnd[MAX_PROGRAM_TEMPS]);
+
+extern void
+_mesa_optimize_program(GLcontext *ctx, struct gl_program *program);
+
+#endif
diff --git a/src/mesa/program/prog_parameter.c b/src/mesa/program/prog_parameter.c
new file mode 100644 (file)
index 0000000..ddbfe95
--- /dev/null
@@ -0,0 +1,751 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.3
+ *
+ * Copyright (C) 1999-2008  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 prog_parameter.c
+ * Program parameter lists and functions.
+ * \author Brian Paul
+ */
+
+
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "main/macros.h"
+#include "prog_instruction.h"
+#include "prog_parameter.h"
+#include "prog_statevars.h"
+
+
+struct gl_program_parameter_list *
+_mesa_new_parameter_list(void)
+{
+   return CALLOC_STRUCT(gl_program_parameter_list);
+}
+
+
+struct gl_program_parameter_list *
+_mesa_new_parameter_list_sized(unsigned size)
+{
+   struct gl_program_parameter_list *p = _mesa_new_parameter_list();
+
+   if ((p != NULL) && (size != 0)) {
+      p->Size = size;
+
+      /* alloc arrays */
+      p->Parameters = (struct gl_program_parameter *)
+        calloc(1, size * sizeof(struct gl_program_parameter));
+
+      p->ParameterValues = (GLfloat (*)[4])
+         _mesa_align_malloc(size * 4 *sizeof(GLfloat), 16);
+
+
+      if ((p->Parameters == NULL) || (p->ParameterValues == NULL)) {
+        free(p->Parameters);
+        _mesa_align_free(p->ParameterValues);
+        free(p);
+        p = NULL;
+      }
+   }
+
+   return p;
+}
+
+
+/**
+ * Free a parameter list and all its parameters
+ */
+void
+_mesa_free_parameter_list(struct gl_program_parameter_list *paramList)
+{
+   GLuint i;
+   for (i = 0; i < paramList->NumParameters; i++) {
+      if (paramList->Parameters[i].Name)
+        free((void *) paramList->Parameters[i].Name);
+   }
+   free(paramList->Parameters);
+   if (paramList->ParameterValues)
+      _mesa_align_free(paramList->ParameterValues);
+   free(paramList);
+}
+
+
+/**
+ * Add a new parameter to a parameter list.
+ * Note that parameter values are usually 4-element GLfloat vectors.
+ * When size > 4 we'll allocate a sequential block of parameters to
+ * store all the values (in blocks of 4).
+ *
+ * \param paramList  the list to add the parameter to
+ * \param type  type of parameter, such as 
+ * \param name  the parameter name, will be duplicated/copied!
+ * \param size  number of elements in 'values' vector (1..4, or more)
+ * \param datatype  GL_FLOAT, GL_FLOAT_VECx, GL_INT, GL_INT_VECx or GL_NONE.
+ * \param values  initial parameter value, up to 4 GLfloats, or NULL
+ * \param state  state indexes, or NULL
+ * \return  index of new parameter in the list, or -1 if error (out of mem)
+ */
+GLint
+_mesa_add_parameter(struct gl_program_parameter_list *paramList,
+                    gl_register_file type, const char *name,
+                    GLuint size, GLenum datatype, const GLfloat *values,
+                    const gl_state_index state[STATE_LENGTH],
+                    GLbitfield flags)
+{
+   const GLuint oldNum = paramList->NumParameters;
+   const GLuint sz4 = (size + 3) / 4; /* no. of new param slots needed */
+
+   assert(size > 0);
+
+   if (oldNum + sz4 > paramList->Size) {
+      /* Need to grow the parameter list array (alloc some extra) */
+      paramList->Size = paramList->Size + 4 * sz4;
+
+      /* realloc arrays */
+      paramList->Parameters = (struct gl_program_parameter *)
+        _mesa_realloc(paramList->Parameters,
+                      oldNum * sizeof(struct gl_program_parameter),
+                      paramList->Size * sizeof(struct gl_program_parameter));
+
+      paramList->ParameterValues = (GLfloat (*)[4])
+         _mesa_align_realloc(paramList->ParameterValues,         /* old buf */
+                             oldNum * 4 * sizeof(GLfloat),      /* old size */
+                             paramList->Size * 4 *sizeof(GLfloat), /* new sz */
+                             16);
+   }
+
+   if (!paramList->Parameters ||
+       !paramList->ParameterValues) {
+      /* out of memory */
+      paramList->NumParameters = 0;
+      paramList->Size = 0;
+      return -1;
+   }
+   else {
+      GLuint i;
+
+      paramList->NumParameters = oldNum + sz4;
+
+      memset(&paramList->Parameters[oldNum], 0,
+             sz4 * sizeof(struct gl_program_parameter));
+
+      for (i = 0; i < sz4; i++) {
+         struct gl_program_parameter *p = paramList->Parameters + oldNum + i;
+         p->Name = name ? _mesa_strdup(name) : NULL;
+         p->Type = type;
+         p->Size = size;
+         p->DataType = datatype;
+         p->Flags = flags;
+         if (values) {
+            COPY_4V(paramList->ParameterValues[oldNum + i], values);
+            values += 4;
+            p->Initialized = GL_TRUE;
+         }
+         else {
+            /* silence valgrind */
+            ASSIGN_4V(paramList->ParameterValues[oldNum + i], 0, 0, 0, 0);
+         }
+         size -= 4;
+      }
+
+      if (state) {
+         for (i = 0; i < STATE_LENGTH; i++)
+            paramList->Parameters[oldNum].StateIndexes[i] = state[i];
+      }
+
+      return (GLint) oldNum;
+   }
+}
+
+
+/**
+ * Add a new named program parameter (Ex: NV_fragment_program DEFINE statement)
+ * \return index of the new entry in the parameter list
+ */
+GLint
+_mesa_add_named_parameter(struct gl_program_parameter_list *paramList,
+                          const char *name, const GLfloat values[4])
+{
+   return _mesa_add_parameter(paramList, PROGRAM_NAMED_PARAM, name,
+                              4, GL_NONE, values, NULL, 0x0);
+                              
+}
+
+
+/**
+ * Add a new named constant to the parameter list.
+ * This will be used when the program contains something like this:
+ *    PARAM myVals = { 0, 1, 2, 3 };
+ *
+ * \param paramList  the parameter list
+ * \param name  the name for the constant
+ * \param values  four float values
+ * \return index/position of the new parameter in the parameter list
+ */
+GLint
+_mesa_add_named_constant(struct gl_program_parameter_list *paramList,
+                         const char *name, const GLfloat values[4],
+                         GLuint size)
+{
+   /* first check if this is a duplicate constant */
+   GLint pos;
+   for (pos = 0; pos < (GLint)paramList->NumParameters; pos++) {
+      const GLfloat *pvals = paramList->ParameterValues[pos];
+      if (pvals[0] == values[0] &&
+          pvals[1] == values[1] &&
+          pvals[2] == values[2] &&
+          pvals[3] == values[3] &&
+          strcmp(paramList->Parameters[pos].Name, name) == 0) {
+         /* Same name and value is already in the param list - reuse it */
+         return pos;
+      }
+   }
+   /* not found, add new parameter */
+   return _mesa_add_parameter(paramList, PROGRAM_CONSTANT, name,
+                              size, GL_NONE, values, NULL, 0x0);
+}
+
+
+/**
+ * Add a new unnamed constant to the parameter list.  This will be used
+ * when a fragment/vertex program contains something like this:
+ *    MOV r, { 0, 1, 2, 3 };
+ * If swizzleOut is non-null we'll search the parameter list for an
+ * existing instance of the constant which matches with a swizzle.
+ *
+ * \param paramList  the parameter list
+ * \param values  four float values
+ * \param swizzleOut  returns swizzle mask for accessing the constant
+ * \return index/position of the new parameter in the parameter list.
+ */
+GLint
+_mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList,
+                           const GLfloat values[4], GLuint size,
+                           GLuint *swizzleOut)
+{
+   GLint pos;
+   ASSERT(size >= 1);
+   ASSERT(size <= 4);
+
+   if (swizzleOut &&
+       _mesa_lookup_parameter_constant(paramList, values,
+                                       size, &pos, swizzleOut)) {
+      return pos;
+   }
+
+   /* Look for empty space in an already unnamed constant parameter
+    * to add this constant.  This will only work for single-element
+    * constants because we rely on smearing (i.e. .yyyy or .zzzz).
+    */
+   if (size == 1 && swizzleOut) {
+      for (pos = 0; pos < (GLint) paramList->NumParameters; pos++) {
+         struct gl_program_parameter *p = paramList->Parameters + pos;
+         if (p->Type == PROGRAM_CONSTANT && p->Size + size <= 4) {
+            /* ok, found room */
+            GLfloat *pVal = paramList->ParameterValues[pos];
+            GLuint swz = p->Size; /* 1, 2 or 3 for Y, Z, W */
+            pVal[p->Size] = values[0];
+            p->Size++;
+            *swizzleOut = MAKE_SWIZZLE4(swz, swz, swz, swz);
+            return pos;
+         }
+      }
+   }
+
+   /* add a new parameter to store this constant */
+   pos = _mesa_add_parameter(paramList, PROGRAM_CONSTANT, NULL,
+                             size, GL_NONE, values, NULL, 0x0);
+   if (pos >= 0 && swizzleOut) {
+      if (size == 1)
+         *swizzleOut = SWIZZLE_XXXX;
+      else
+         *swizzleOut = SWIZZLE_NOOP;
+   }
+   return pos;
+}
+
+
+/**
+ * Add a uniform to the parameter list.
+ * Note that if the uniform is an array, size may be greater than
+ * what's implied by the datatype.
+ * \param name  uniform's name
+ * \param size  number of floats to allocate
+ * \param datatype  GL_FLOAT_VEC3, GL_FLOAT_MAT4, etc.
+ */
+GLint
+_mesa_add_uniform(struct gl_program_parameter_list *paramList,
+                  const char *name, GLuint size, GLenum datatype,
+                  const GLfloat *values)
+{
+   GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
+   ASSERT(datatype != GL_NONE);
+   if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_UNIFORM) {
+      ASSERT(paramList->Parameters[i].Size == size);
+      ASSERT(paramList->Parameters[i].DataType == datatype);
+      /* already in list */
+      return i;
+   }
+   else {
+      i = _mesa_add_parameter(paramList, PROGRAM_UNIFORM, name,
+                              size, datatype, values, NULL, 0x0);
+      return i;
+   }
+}
+
+
+/**
+ * Mark the named uniform as 'used'.
+ */
+void
+_mesa_use_uniform(struct gl_program_parameter_list *paramList,
+                  const char *name)
+{
+   GLuint i;
+   for (i = 0; i < paramList->NumParameters; i++) {
+      struct gl_program_parameter *p = paramList->Parameters + i;
+      if ((p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) &&
+          strcmp(p->Name, name) == 0) {
+         p->Used = GL_TRUE;
+         /* Note that large uniforms may occupy several slots so we're
+          * not done searching yet.
+          */
+      }
+   }
+}
+
+
+/**
+ * Add a sampler to the parameter list.
+ * \param name  uniform's name
+ * \param datatype  GL_SAMPLER_2D, GL_SAMPLER_2D_RECT_ARB, etc.
+ * \param index  the sampler number (as seen in TEX instructions)
+ * \return  sampler index (starting at zero) or -1 if error
+ */
+GLint
+_mesa_add_sampler(struct gl_program_parameter_list *paramList,
+                  const char *name, GLenum datatype)
+{
+   GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
+   if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_SAMPLER) {
+      ASSERT(paramList->Parameters[i].Size == 1);
+      ASSERT(paramList->Parameters[i].DataType == datatype);
+      /* already in list */
+      return (GLint) paramList->ParameterValues[i][0];
+   }
+   else {
+      GLuint i;
+      const GLint size = 1; /* a sampler is basically a texture unit number */
+      GLfloat value[4];
+      GLint numSamplers = 0;
+      for (i = 0; i < paramList->NumParameters; i++) {
+         if (paramList->Parameters[i].Type == PROGRAM_SAMPLER)
+            numSamplers++;
+      }
+      value[0] = (GLfloat) numSamplers;
+      value[1] = value[2] = value[3] = 0.0F;
+      (void) _mesa_add_parameter(paramList, PROGRAM_SAMPLER, name,
+                                 size, datatype, value, NULL, 0x0);
+      return numSamplers;
+   }
+}
+
+
+/**
+ * Add parameter representing a varying variable.
+ */
+GLint
+_mesa_add_varying(struct gl_program_parameter_list *paramList,
+                  const char *name, GLuint size, GLenum datatype,
+                  GLbitfield flags)
+{
+   GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
+   if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_VARYING) {
+      /* already in list */
+      return i;
+   }
+   else {
+      /*assert(size == 4);*/
+      i = _mesa_add_parameter(paramList, PROGRAM_VARYING, name,
+                              size, datatype, NULL, NULL, flags);
+      return i;
+   }
+}
+
+
+/**
+ * Add parameter representing a vertex program attribute.
+ * \param size  size of attribute (in floats), may be -1 if unknown
+ * \param attrib  the attribute index, or -1 if unknown
+ */
+GLint
+_mesa_add_attribute(struct gl_program_parameter_list *paramList,
+                    const char *name, GLint size, GLenum datatype, GLint attrib)
+{
+   GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
+   if (i >= 0) {
+      /* replace */
+      if (attrib < 0)
+         attrib = i;
+      paramList->Parameters[i].StateIndexes[0] = attrib;
+   }
+   else {
+      /* add */
+      gl_state_index state[STATE_LENGTH];
+      state[0] = (gl_state_index) attrib;
+      if (size < 0)
+         size = 4;
+      i = _mesa_add_parameter(paramList, PROGRAM_INPUT, name,
+                              size, datatype, NULL, state, 0x0);
+   }
+   return i;
+}
+
+
+
+#if 0 /* not used yet */
+/**
+ * Returns the number of 4-component registers needed to store a piece
+ * of GL state.  For matrices this may be as many as 4 registers,
+ * everything else needs
+ * just 1 register.
+ */
+static GLuint
+sizeof_state_reference(const GLint *stateTokens)
+{
+   if (stateTokens[0] == STATE_MATRIX) {
+      GLuint rows = stateTokens[4] - stateTokens[3] + 1;
+      assert(rows >= 1);
+      assert(rows <= 4);
+      return rows;
+   }
+   else {
+      return 1;
+   }
+}
+#endif
+
+
+/**
+ * Add a new state reference to the parameter list.
+ * This will be used when the program contains something like this:
+ *    PARAM ambient = state.material.front.ambient;
+ *
+ * \param paramList  the parameter list
+ * \param stateTokens  an array of 5 (STATE_LENGTH) state tokens
+ * \return index of the new parameter.
+ */
+GLint
+_mesa_add_state_reference(struct gl_program_parameter_list *paramList,
+                          const gl_state_index stateTokens[STATE_LENGTH])
+{
+   const GLuint size = 4; /* XXX fix */
+   char *name;
+   GLint index;
+
+   /* Check if the state reference is already in the list */
+   for (index = 0; index < (GLint) paramList->NumParameters; index++) {
+      GLuint i, match = 0;
+      for (i = 0; i < STATE_LENGTH; i++) {
+         if (paramList->Parameters[index].StateIndexes[i] == stateTokens[i]) {
+            match++;
+         }
+         else {
+            break;
+         }
+      }
+      if (match == STATE_LENGTH) {
+         /* this state reference is already in the parameter list */
+         return index;
+      }
+   }
+
+   name = _mesa_program_state_string(stateTokens);
+   index = _mesa_add_parameter(paramList, PROGRAM_STATE_VAR, name,
+                               size, GL_NONE,
+                               NULL, (gl_state_index *) stateTokens, 0x0);
+   paramList->StateFlags |= _mesa_program_state_flags(stateTokens);
+
+   /* free name string here since we duplicated it in add_parameter() */
+   free(name);
+
+   return index;
+}
+
+
+/**
+ * Lookup a parameter value by name in the given parameter list.
+ * \return pointer to the float[4] values.
+ */
+GLfloat *
+_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList,
+                             GLsizei nameLen, const char *name)
+{
+   GLint i = _mesa_lookup_parameter_index(paramList, nameLen, name);
+   if (i < 0)
+      return NULL;
+   else
+      return paramList->ParameterValues[i];
+}
+
+
+/**
+ * Given a program parameter name, find its position in the list of parameters.
+ * \param paramList  the parameter list to search
+ * \param nameLen  length of name (in chars).
+ *                 If length is negative, assume that name is null-terminated.
+ * \param name  the name to search for
+ * \return index of parameter in the list.
+ */
+GLint
+_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList,
+                             GLsizei nameLen, const char *name)
+{
+   GLint i;
+
+   if (!paramList)
+      return -1;
+
+   if (nameLen == -1) {
+      /* name is null-terminated */
+      for (i = 0; i < (GLint) paramList->NumParameters; i++) {
+         if (paramList->Parameters[i].Name &&
+            strcmp(paramList->Parameters[i].Name, name) == 0)
+            return i;
+      }
+   }
+   else {
+      /* name is not null-terminated, use nameLen */
+      for (i = 0; i < (GLint) paramList->NumParameters; i++) {
+         if (paramList->Parameters[i].Name &&
+            strncmp(paramList->Parameters[i].Name, name, nameLen) == 0
+             && strlen(paramList->Parameters[i].Name) == (size_t)nameLen)
+            return i;
+      }
+   }
+   return -1;
+}
+
+
+/**
+ * Look for a float vector in the given parameter list.  The float vector
+ * may be of length 1, 2, 3 or 4.  If swizzleOut is non-null, we'll try
+ * swizzling to find a match.
+ * \param list  the parameter list to search
+ * \param v  the float vector to search for
+ * \param vSize  number of element in v
+ * \param posOut  returns the position of the constant, if found
+ * \param swizzleOut  returns a swizzle mask describing location of the
+ *                    vector elements if found.
+ * \return GL_TRUE if found, GL_FALSE if not found
+ */
+GLboolean
+_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list,
+                                const GLfloat v[], GLuint vSize,
+                                GLint *posOut, GLuint *swizzleOut)
+{
+   GLuint i;
+
+   assert(vSize >= 1);
+   assert(vSize <= 4);
+
+   if (!list)
+      return -1;
+
+   for (i = 0; i < list->NumParameters; i++) {
+      if (list->Parameters[i].Type == PROGRAM_CONSTANT) {
+         if (!swizzleOut) {
+            /* swizzle not allowed */
+            GLuint j, match = 0;
+            for (j = 0; j < vSize; j++) {
+               if (v[j] == list->ParameterValues[i][j])
+                  match++;
+            }
+            if (match == vSize) {
+               *posOut = i;
+               return GL_TRUE;
+            }
+         }
+         else {
+            /* try matching w/ swizzle */
+             if (vSize == 1) {
+                /* look for v[0] anywhere within float[4] value */
+                GLuint j;
+                for (j = 0; j < list->Parameters[i].Size; j++) {
+                   if (list->ParameterValues[i][j] == v[0]) {
+                      /* found it */
+                      *posOut = i;
+                      *swizzleOut = MAKE_SWIZZLE4(j, j, j, j);
+                      return GL_TRUE;
+                   }
+                }
+             }
+             else if (vSize <= list->Parameters[i].Size) {
+                /* see if we can match this constant (with a swizzle) */
+                GLuint swz[4];
+                GLuint match = 0, j, k;
+                for (j = 0; j < vSize; j++) {
+                   if (v[j] == list->ParameterValues[i][j]) {
+                      swz[j] = j;
+                      match++;
+                   }
+                   else {
+                      for (k = 0; k < list->Parameters[i].Size; k++) {
+                         if (v[j] == list->ParameterValues[i][k]) {
+                            swz[j] = k;
+                            match++;
+                            break;
+                         }
+                      }
+                   }
+                }
+                /* smear last value to remaining positions */
+                for (; j < 4; j++)
+                   swz[j] = swz[j-1];
+
+                if (match == vSize) {
+                   *posOut = i;
+                   *swizzleOut = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
+                   return GL_TRUE;
+                }
+             }
+         }
+      }
+   }
+
+   *posOut = -1;
+   return GL_FALSE;
+}
+
+
+struct gl_program_parameter_list *
+_mesa_clone_parameter_list(const struct gl_program_parameter_list *list)
+{
+   struct gl_program_parameter_list *clone;
+   GLuint i;
+
+   clone = _mesa_new_parameter_list();
+   if (!clone)
+      return NULL;
+
+   /** Not too efficient, but correct */
+   for (i = 0; i < list->NumParameters; i++) {
+      struct gl_program_parameter *p = list->Parameters + i;
+      struct gl_program_parameter *pCopy;
+      GLuint size = MIN2(p->Size, 4);
+      GLint j = _mesa_add_parameter(clone, p->Type, p->Name, size, p->DataType,
+                                    list->ParameterValues[i], NULL, 0x0);
+      ASSERT(j >= 0);
+      pCopy = clone->Parameters + j;
+      pCopy->Used = p->Used;
+      pCopy->Flags = p->Flags;
+      /* copy state indexes */
+      if (p->Type == PROGRAM_STATE_VAR) {
+         GLint k;
+         for (k = 0; k < STATE_LENGTH; k++) {
+            pCopy->StateIndexes[k] = p->StateIndexes[k];
+         }
+      }
+      else {
+         clone->Parameters[j].Size = p->Size;
+      }
+      
+   }
+
+   clone->StateFlags = list->StateFlags;
+
+   return clone;
+}
+
+
+/**
+ * Return a new parameter list which is listA + listB.
+ */
+struct gl_program_parameter_list *
+_mesa_combine_parameter_lists(const struct gl_program_parameter_list *listA,
+                              const struct gl_program_parameter_list *listB)
+{
+   struct gl_program_parameter_list *list;
+
+   if (listA) {
+      list = _mesa_clone_parameter_list(listA);
+      if (list && listB) {
+         GLuint i;
+         for (i = 0; i < listB->NumParameters; i++) {
+            struct gl_program_parameter *param = listB->Parameters + i;
+            _mesa_add_parameter(list, param->Type, param->Name, param->Size,
+                                param->DataType,
+                                listB->ParameterValues[i],
+                                param->StateIndexes,
+                                param->Flags);
+         }
+      }
+   }
+   else if (listB) {
+      list = _mesa_clone_parameter_list(listB);
+   }
+   else {
+      list = NULL;
+   }
+   return list;
+}
+
+
+
+/**
+ * Find longest name of all uniform parameters in list.
+ */
+GLuint
+_mesa_longest_parameter_name(const struct gl_program_parameter_list *list,
+                             gl_register_file type)
+{
+   GLuint i, maxLen = 0;
+   if (!list)
+      return 0;
+   for (i = 0; i < list->NumParameters; i++) {
+      if (list->Parameters[i].Type == type) {
+         GLuint len = strlen(list->Parameters[i].Name);
+         if (len > maxLen)
+            maxLen = len;
+      }
+   }
+   return maxLen;
+}
+
+
+/**
+ * Count the number of parameters in the last that match the given type.
+ */
+GLuint
+_mesa_num_parameters_of_type(const struct gl_program_parameter_list *list,
+                             gl_register_file type)
+{
+   GLuint i, count = 0;
+   if (list) {
+      for (i = 0; i < list->NumParameters; i++) {
+         if (list->Parameters[i].Type == type)
+            count++;
+      }
+   }
+   return count;
+}
diff --git a/src/mesa/program/prog_parameter.h b/src/mesa/program/prog_parameter.h
new file mode 100644 (file)
index 0000000..cc3378a
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.3
+ *
+ * Copyright (C) 1999-2008  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 prog_parameter.c
+ * Program parameter lists and functions.
+ * \author Brian Paul
+ */
+
+#ifndef PROG_PARAMETER_H
+#define PROG_PARAMETER_H
+
+#include "main/mtypes.h"
+#include "prog_statevars.h"
+
+
+/**
+ * Program parameter flags
+ */
+/*@{*/
+#define PROG_PARAM_BIT_CENTROID   0x1  /**< for varying vars (GLSL 1.20) */
+#define PROG_PARAM_BIT_INVARIANT  0x2  /**< for varying vars (GLSL 1.20) */
+#define PROG_PARAM_BIT_FLAT       0x4  /**< for varying vars (GLSL 1.30) */
+#define PROG_PARAM_BIT_LINEAR     0x8  /**< for varying vars (GLSL 1.30) */
+#define PROG_PARAM_BIT_CYL_WRAP  0x10  /**< XXX gallium debug */
+/*@}*/
+
+
+
+/**
+ * Program parameter.
+ * Used by shaders/programs for uniforms, constants, varying vars, etc.
+ */
+struct gl_program_parameter
+{
+   const char *Name;        /**< Null-terminated string */
+   gl_register_file Type;   /**< PROGRAM_NAMED_PARAM, CONSTANT or STATE_VAR */
+   GLenum DataType;         /**< GL_FLOAT, GL_FLOAT_VEC2, etc */
+   /**
+    * Number of components (1..4), or more.
+    * If the number of components is greater than 4,
+    * this parameter is part of a larger uniform like a GLSL matrix or array.
+    * The next program parameter's Size will be Size-4 of this parameter.
+    */
+   GLuint Size;
+   GLboolean Used;          /**< Helper flag for GLSL uniform tracking */
+   GLboolean Initialized;   /**< Has the ParameterValue[] been set? */
+   GLbitfield Flags;        /**< Bitmask of PROG_PARAM_*_BIT */
+   /**
+    * A sequence of STATE_* tokens and integers to identify GL state.
+    */
+   gl_state_index StateIndexes[STATE_LENGTH];
+};
+
+
+/**
+ * List of gl_program_parameter instances.
+ */
+struct gl_program_parameter_list
+{
+   GLuint Size;           /**< allocated size of Parameters, ParameterValues */
+   GLuint NumParameters;  /**< number of parameters in arrays */
+   struct gl_program_parameter *Parameters; /**< Array [Size] */
+   GLfloat (*ParameterValues)[4];        /**< Array [Size] of GLfloat[4] */
+   GLbitfield StateFlags; /**< _NEW_* flags indicating which state changes
+                               might invalidate ParameterValues[] */
+};
+
+
+extern struct gl_program_parameter_list *
+_mesa_new_parameter_list(void);
+
+extern struct gl_program_parameter_list *
+_mesa_new_parameter_list_sized(unsigned size);
+
+extern void
+_mesa_free_parameter_list(struct gl_program_parameter_list *paramList);
+
+extern struct gl_program_parameter_list *
+_mesa_clone_parameter_list(const struct gl_program_parameter_list *list);
+
+extern struct gl_program_parameter_list *
+_mesa_combine_parameter_lists(const struct gl_program_parameter_list *a,
+                              const struct gl_program_parameter_list *b);
+
+static INLINE GLuint
+_mesa_num_parameters(const struct gl_program_parameter_list *list)
+{
+   return list ? list->NumParameters : 0;
+}
+
+extern GLint
+_mesa_add_parameter(struct gl_program_parameter_list *paramList,
+                    gl_register_file type, const char *name,
+                    GLuint size, GLenum datatype, const GLfloat *values,
+                    const gl_state_index state[STATE_LENGTH],
+                    GLbitfield flags);
+
+extern GLint
+_mesa_add_named_parameter(struct gl_program_parameter_list *paramList,
+                          const char *name, const GLfloat values[4]);
+
+extern GLint
+_mesa_add_named_constant(struct gl_program_parameter_list *paramList,
+                         const char *name, const GLfloat values[4],
+                         GLuint size);
+
+extern GLint
+_mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList,
+                           const GLfloat values[4], GLuint size,
+                           GLuint *swizzleOut);
+
+extern GLint
+_mesa_add_uniform(struct gl_program_parameter_list *paramList,
+                  const char *name, GLuint size, GLenum datatype,
+                  const GLfloat *values);
+
+extern void
+_mesa_use_uniform(struct gl_program_parameter_list *paramList,
+                  const char *name);
+
+extern GLint
+_mesa_add_sampler(struct gl_program_parameter_list *paramList,
+                  const char *name, GLenum datatype);
+
+extern GLint
+_mesa_add_varying(struct gl_program_parameter_list *paramList,
+                  const char *name, GLuint size, GLenum datatype,
+                  GLbitfield flags);
+
+extern GLint
+_mesa_add_attribute(struct gl_program_parameter_list *paramList,
+                    const char *name, GLint size, GLenum datatype, GLint attrib);
+
+extern GLint
+_mesa_add_state_reference(struct gl_program_parameter_list *paramList,
+                          const gl_state_index stateTokens[STATE_LENGTH]);
+
+extern GLfloat *
+_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList,
+                             GLsizei nameLen, const char *name);
+
+extern GLint
+_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList,
+                             GLsizei nameLen, const char *name);
+
+extern GLboolean
+_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list,
+                                const GLfloat v[], GLuint vSize,
+                                GLint *posOut, GLuint *swizzleOut);
+
+extern GLuint
+_mesa_longest_parameter_name(const struct gl_program_parameter_list *list,
+                             gl_register_file type);
+
+extern GLuint
+_mesa_num_parameters_of_type(const struct gl_program_parameter_list *list,
+                             gl_register_file type);
+
+
+#endif /* PROG_PARAMETER_H */
diff --git a/src/mesa/program/prog_parameter_layout.c b/src/mesa/program/prog_parameter_layout.c
new file mode 100644 (file)
index 0000000..a888573
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * Copyright Â© 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION 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 prog_parameter_layout.c
+ * \brief Helper functions to layout storage for program parameters
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+#include "main/mtypes.h"
+#include "prog_parameter.h"
+#include "prog_parameter_layout.h"
+#include "prog_instruction.h"
+#include "program_parser.h"
+
+unsigned
+_mesa_combine_swizzles(unsigned base, unsigned applied)
+{
+   unsigned swiz = 0;
+   unsigned i;
+
+   for (i = 0; i < 4; i++) {
+      const unsigned s = GET_SWZ(applied, i);
+
+      swiz |= ((s <= SWIZZLE_W) ? GET_SWZ(base, s) : s) << (i * 3);
+   }
+
+   return swiz;
+}
+
+
+/**
+ * Copy indirect access array from one parameter list to another
+ *
+ * \param src   Parameter array copied from
+ * \param dst   Parameter array copied to
+ * \param first Index of first element in \c src to copy
+ * \param count Number of elements to copy
+ *
+ * \return
+ * The location in \c dst of the first element copied from \c src on
+ * success.  -1 on failure.
+ *
+ * \warning
+ * This function assumes that there is already enough space available in
+ * \c dst to hold all of the elements that will be copied over.
+ */
+static int
+copy_indirect_accessed_array(struct gl_program_parameter_list *src,
+                            struct gl_program_parameter_list *dst,
+                            unsigned first, unsigned count)
+{
+   const int base = dst->NumParameters;
+   unsigned i, j;
+
+   for (i = first; i < (first + count); i++) {
+      struct gl_program_parameter *curr = & src->Parameters[i];
+
+      if (curr->Type == PROGRAM_CONSTANT) {
+        j = dst->NumParameters;
+      } else {
+        for (j = 0; j < dst->NumParameters; j++) {
+           if (memcmp(dst->Parameters[j].StateIndexes, curr->StateIndexes, 
+                      sizeof(curr->StateIndexes)) == 0) {
+              return -1;
+           }
+        }
+      }
+
+      assert(j == dst->NumParameters);
+
+      /* copy src parameter [i] to dest parameter [j] */
+      memcpy(& dst->Parameters[j], curr,
+            sizeof(dst->Parameters[j]));
+      memcpy(dst->ParameterValues[j], src->ParameterValues[i],
+            sizeof(GLfloat) * 4);
+
+      /* Pointer to the string name was copied.  Null-out src param name
+       * to prevent double free later.
+       */
+      curr->Name = NULL;
+
+      dst->NumParameters++;
+   }
+
+   return base;
+}
+
+
+/**
+ * XXX description???
+ * \return GL_TRUE for success, GL_FALSE for failure
+ */
+GLboolean
+_mesa_layout_parameters(struct asm_parser_state *state)
+{
+   struct gl_program_parameter_list *layout;
+   struct asm_instruction *inst;
+   unsigned i;
+
+   layout =
+      _mesa_new_parameter_list_sized(state->prog->Parameters->NumParameters);
+
+   /* PASS 1:  Move any parameters that are accessed indirectly from the
+    * original parameter list to the new parameter list.
+    */
+   for (inst = state->inst_head; inst != NULL; inst = inst->next) {
+      for (i = 0; i < 3; i++) {
+        if (inst->SrcReg[i].Base.RelAddr) {
+           /* Only attempt to add the to the new parameter list once.
+            */
+           if (!inst->SrcReg[i].Symbol->pass1_done) {
+              const int new_begin =
+                 copy_indirect_accessed_array(state->prog->Parameters, layout,
+                     inst->SrcReg[i].Symbol->param_binding_begin,
+                     inst->SrcReg[i].Symbol->param_binding_length);
+
+              if (new_begin < 0) {
+                 return GL_FALSE;
+              }
+
+              inst->SrcReg[i].Symbol->param_binding_begin = new_begin;
+              inst->SrcReg[i].Symbol->pass1_done = 1;
+           }
+
+           /* Previously the Index was just the offset from the parameter
+            * array.  Now that the base of the parameter array is known, the
+            * index can be updated to its actual value.
+            */
+           inst->Base.SrcReg[i] = inst->SrcReg[i].Base;
+           inst->Base.SrcReg[i].Index +=
+              inst->SrcReg[i].Symbol->param_binding_begin;
+        }
+      }
+   }
+
+   /* PASS 2:  Move any parameters that are not accessed indirectly from the
+    * original parameter list to the new parameter list.
+    */
+   for (inst = state->inst_head; inst != NULL; inst = inst->next) {
+      for (i = 0; i < 3; i++) {
+        const struct gl_program_parameter *p;
+        const int idx = inst->SrcReg[i].Base.Index;
+        unsigned swizzle = SWIZZLE_NOOP;
+
+        /* All relative addressed operands were processed on the first
+         * pass.  Just skip them here.
+         */
+        if (inst->SrcReg[i].Base.RelAddr) {
+           continue;
+        }
+
+        if ((inst->SrcReg[i].Base.File <= PROGRAM_VARYING )
+            || (inst->SrcReg[i].Base.File >= PROGRAM_WRITE_ONLY)) {
+           continue;
+        }
+
+        inst->Base.SrcReg[i] = inst->SrcReg[i].Base;
+        p = & state->prog->Parameters->Parameters[idx];
+
+        switch (p->Type) {
+        case PROGRAM_CONSTANT: {
+           const float *const v =
+              state->prog->Parameters->ParameterValues[idx];
+
+           inst->Base.SrcReg[i].Index =
+              _mesa_add_unnamed_constant(layout, v, p->Size, & swizzle);
+
+           inst->Base.SrcReg[i].Swizzle = 
+              _mesa_combine_swizzles(swizzle, inst->Base.SrcReg[i].Swizzle);
+           break;
+        }
+
+        case PROGRAM_STATE_VAR:
+           inst->Base.SrcReg[i].Index =
+              _mesa_add_state_reference(layout, p->StateIndexes);
+           break;
+
+        default:
+           break;
+        }
+
+        inst->SrcReg[i].Base.File = p->Type;
+        inst->Base.SrcReg[i].File = p->Type;
+      }
+   }
+
+   _mesa_free_parameter_list(state->prog->Parameters);
+   state->prog->Parameters = layout;
+
+   return GL_TRUE;
+}
diff --git a/src/mesa/program/prog_parameter_layout.h b/src/mesa/program/prog_parameter_layout.h
new file mode 100644 (file)
index 0000000..99a7b6c
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright Â© 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION 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 prog_parameter_layout.h
+ * \brief Helper functions to layout storage for program parameters
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+#pragma once
+
+#ifndef PROG_PARAMETER_LAYOUT_H
+#define PROG_PARAMETER_LAYOUT_H
+
+extern unsigned _mesa_combine_swizzles(unsigned base, unsigned applied);
+
+struct asm_parser_state;
+
+extern GLboolean _mesa_layout_parameters(struct asm_parser_state *state);
+
+#endif /* PROG_PARAMETER_LAYOUT_H */
diff --git a/src/mesa/program/prog_print.c b/src/mesa/program/prog_print.c
new file mode 100644 (file)
index 0000000..6ab199a
--- /dev/null
@@ -0,0 +1,1084 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.3
+ *
+ * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2009  VMware, 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
+ * 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 prog_print.c
+ * Print vertex/fragment programs - for debugging.
+ * \author Brian Paul
+ */
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/imports.h"
+#include "prog_instruction.h"
+#include "prog_parameter.h"
+#include "prog_print.h"
+#include "prog_statevars.h"
+
+
+
+/**
+ * Return string name for given program/register file.
+ */
+static const char *
+file_string(gl_register_file f, gl_prog_print_mode mode)
+{
+   switch (f) {
+   case PROGRAM_TEMPORARY:
+      return "TEMP";
+   case PROGRAM_LOCAL_PARAM:
+      return "LOCAL";
+   case PROGRAM_ENV_PARAM:
+      return "ENV";
+   case PROGRAM_STATE_VAR:
+      return "STATE";
+   case PROGRAM_INPUT:
+      return "INPUT";
+   case PROGRAM_OUTPUT:
+      return "OUTPUT";
+   case PROGRAM_NAMED_PARAM:
+      return "NAMED";
+   case PROGRAM_CONSTANT:
+      return "CONST";
+   case PROGRAM_UNIFORM:
+      return "UNIFORM";
+   case PROGRAM_VARYING:
+      return "VARYING";
+   case PROGRAM_WRITE_ONLY:
+      return "WRITE_ONLY";
+   case PROGRAM_ADDRESS:
+      return "ADDR";
+   case PROGRAM_SAMPLER:
+      return "SAMPLER";
+   case PROGRAM_UNDEFINED:
+      return "UNDEFINED";
+   default:
+      {
+         static char s[20];
+         _mesa_snprintf(s, sizeof(s), "FILE%u", f);
+         return s;
+      }
+   }
+}
+
+
+/**
+ * Return ARB_v/f_prog-style input attrib string.
+ */
+static const char *
+arb_input_attrib_string(GLint index, GLenum progType)
+{
+   /*
+    * These strings should match the VERT_ATTRIB_x and FRAG_ATTRIB_x tokens.
+    */
+   const char *vertAttribs[] = {
+      "vertex.position",
+      "vertex.weight",
+      "vertex.normal",
+      "vertex.color.primary",
+      "vertex.color.secondary",
+      "vertex.fogcoord",
+      "vertex.(six)",
+      "vertex.(seven)",
+      "vertex.texcoord[0]",
+      "vertex.texcoord[1]",
+      "vertex.texcoord[2]",
+      "vertex.texcoord[3]",
+      "vertex.texcoord[4]",
+      "vertex.texcoord[5]",
+      "vertex.texcoord[6]",
+      "vertex.texcoord[7]",
+      "vertex.attrib[0]",
+      "vertex.attrib[1]",
+      "vertex.attrib[2]",
+      "vertex.attrib[3]",
+      "vertex.attrib[4]",
+      "vertex.attrib[5]",
+      "vertex.attrib[6]",
+      "vertex.attrib[7]",
+      "vertex.attrib[8]",
+      "vertex.attrib[9]",
+      "vertex.attrib[10]",
+      "vertex.attrib[11]",
+      "vertex.attrib[12]",
+      "vertex.attrib[13]",
+      "vertex.attrib[14]",
+      "vertex.attrib[15]"
+   };
+   const char *fragAttribs[] = {
+      "fragment.position",
+      "fragment.color.primary",
+      "fragment.color.secondary",
+      "fragment.fogcoord",
+      "fragment.texcoord[0]",
+      "fragment.texcoord[1]",
+      "fragment.texcoord[2]",
+      "fragment.texcoord[3]",
+      "fragment.texcoord[4]",
+      "fragment.texcoord[5]",
+      "fragment.texcoord[6]",
+      "fragment.texcoord[7]",
+      "fragment.varying[0]",
+      "fragment.varying[1]",
+      "fragment.varying[2]",
+      "fragment.varying[3]",
+      "fragment.varying[4]",
+      "fragment.varying[5]",
+      "fragment.varying[6]",
+      "fragment.varying[7]"
+   };
+
+   /* sanity checks */
+   assert(strcmp(vertAttribs[VERT_ATTRIB_TEX0], "vertex.texcoord[0]") == 0);
+   assert(strcmp(vertAttribs[VERT_ATTRIB_GENERIC15], "vertex.attrib[15]") == 0);
+
+   if (progType == GL_VERTEX_PROGRAM_ARB) {
+      assert(index < sizeof(vertAttribs) / sizeof(vertAttribs[0]));
+      return vertAttribs[index];
+   }
+   else {
+      assert(index < sizeof(fragAttribs) / sizeof(fragAttribs[0]));
+      return fragAttribs[index];
+   }
+}
+
+
+/**
+ * Print a vertex program's InputsRead field in human-readable format.
+ * For debugging.
+ */
+void
+_mesa_print_vp_inputs(GLbitfield inputs)
+{
+   printf("VP Inputs 0x%x: \n", inputs);
+   while (inputs) {
+      GLint attr = _mesa_ffs(inputs) - 1;
+      const char *name = arb_input_attrib_string(attr,
+                                                 GL_VERTEX_PROGRAM_ARB);
+      printf("  %d: %s\n", attr, name);
+      inputs &= ~(1 << attr);
+   }
+}
+
+
+/**
+ * Print a fragment program's InputsRead field in human-readable format.
+ * For debugging.
+ */
+void
+_mesa_print_fp_inputs(GLbitfield inputs)
+{
+   printf("FP Inputs 0x%x: \n", inputs);
+   while (inputs) {
+      GLint attr = _mesa_ffs(inputs) - 1;
+      const char *name = arb_input_attrib_string(attr,
+                                                 GL_FRAGMENT_PROGRAM_ARB);
+      printf("  %d: %s\n", attr, name);
+      inputs &= ~(1 << attr);
+   }
+}
+
+
+
+/**
+ * Return ARB_v/f_prog-style output attrib string.
+ */
+static const char *
+arb_output_attrib_string(GLint index, GLenum progType)
+{
+   /*
+    * These strings should match the VERT_RESULT_x and FRAG_RESULT_x tokens.
+    */
+   const char *vertResults[] = {
+      "result.position",
+      "result.color.primary",
+      "result.color.secondary",
+      "result.fogcoord",
+      "result.texcoord[0]",
+      "result.texcoord[1]",
+      "result.texcoord[2]",
+      "result.texcoord[3]",
+      "result.texcoord[4]",
+      "result.texcoord[5]",
+      "result.texcoord[6]",
+      "result.texcoord[7]",
+      "result.varying[0]",
+      "result.varying[1]",
+      "result.varying[2]",
+      "result.varying[3]",
+      "result.varying[4]",
+      "result.varying[5]",
+      "result.varying[6]",
+      "result.varying[7]"
+   };
+   const char *fragResults[] = {
+      "result.color",
+      "result.color(half)",
+      "result.depth",
+      "result.color[0]",
+      "result.color[1]",
+      "result.color[2]",
+      "result.color[3]"
+   };
+
+   if (progType == GL_VERTEX_PROGRAM_ARB) {
+      assert(index < sizeof(vertResults) / sizeof(vertResults[0]));
+      return vertResults[index];
+   }
+   else {
+      assert(index < sizeof(fragResults) / sizeof(fragResults[0]));
+      return fragResults[index];
+   }
+}
+
+
+/**
+ * Return string representation of the given register.
+ * Note that some types of registers (like PROGRAM_UNIFORM) aren't defined
+ * by the ARB/NV program languages so we've taken some liberties here.
+ * \param f  the register file (PROGRAM_INPUT, PROGRAM_TEMPORARY, etc)
+ * \param index  number of the register in the register file
+ * \param mode  the output format/mode/style
+ * \param prog  pointer to containing program
+ */
+static const char *
+reg_string(gl_register_file f, GLint index, gl_prog_print_mode mode,
+           GLboolean relAddr, const struct gl_program *prog,
+           GLboolean hasIndex2, GLboolean relAddr2, GLint index2)
+{
+   static char str[100];
+   const char *addr = relAddr ? "ADDR+" : "";
+
+   str[0] = 0;
+
+   switch (mode) {
+   case PROG_PRINT_DEBUG:
+      sprintf(str, "%s[%s%d]", file_string(f, mode), addr, index);
+      if (hasIndex2) {
+         int offset = strlen(str);
+         const char *addr2 = relAddr2 ? "ADDR+" : "";
+         sprintf(str+offset, "[%s%d]", addr2, index2);
+      }
+      break;
+
+   case PROG_PRINT_ARB:
+      switch (f) {
+      case PROGRAM_INPUT:
+         sprintf(str, "%s", arb_input_attrib_string(index, prog->Target));
+         break;
+      case PROGRAM_OUTPUT:
+         sprintf(str, "%s", arb_output_attrib_string(index, prog->Target));
+         break;
+      case PROGRAM_TEMPORARY:
+         sprintf(str, "temp%d", index);
+         break;
+      case PROGRAM_ENV_PARAM:
+         sprintf(str, "program.env[%s%d]", addr, index);
+         break;
+      case PROGRAM_LOCAL_PARAM:
+         sprintf(str, "program.local[%s%d]", addr, index);
+         break;
+      case PROGRAM_VARYING: /* extension */
+         sprintf(str, "varying[%s%d]", addr, index);
+         break;
+      case PROGRAM_CONSTANT: /* extension */
+         sprintf(str, "constant[%s%d]", addr, index);
+         break;
+      case PROGRAM_UNIFORM: /* extension */
+         sprintf(str, "uniform[%s%d]", addr, index);
+         break;
+      case PROGRAM_STATE_VAR:
+         {
+            struct gl_program_parameter *param
+               = prog->Parameters->Parameters + index;
+            char *state = _mesa_program_state_string(param->StateIndexes);
+            sprintf(str, "%s", state);
+            free(state);
+         }
+         break;
+      case PROGRAM_ADDRESS:
+         sprintf(str, "A%d", index);
+         break;
+      default:
+         _mesa_problem(NULL, "bad file in reg_string()");
+      }
+      break;
+
+   case PROG_PRINT_NV:
+      switch (f) {
+      case PROGRAM_INPUT:
+         if (prog->Target == GL_VERTEX_PROGRAM_ARB)
+            sprintf(str, "v[%d]", index);
+         else
+            sprintf(str, "f[%d]", index);
+         break;
+      case PROGRAM_OUTPUT:
+         sprintf(str, "o[%d]", index);
+         break;
+      case PROGRAM_TEMPORARY:
+         sprintf(str, "R%d", index);
+         break;
+      case PROGRAM_ENV_PARAM:
+         sprintf(str, "c[%d]", index);
+         break;
+      case PROGRAM_VARYING: /* extension */
+         sprintf(str, "varying[%s%d]", addr, index);
+         break;
+      case PROGRAM_UNIFORM: /* extension */
+         sprintf(str, "uniform[%s%d]", addr, index);
+         break;
+      case PROGRAM_CONSTANT: /* extension */
+         sprintf(str, "constant[%s%d]", addr, index);
+         break;
+      case PROGRAM_STATE_VAR: /* extension */
+         sprintf(str, "state[%s%d]", addr, index);
+         break;
+      default:
+         _mesa_problem(NULL, "bad file in reg_string()");
+      }
+      break;
+
+   default:
+      _mesa_problem(NULL, "bad mode in reg_string()");
+   }
+
+   return str;
+}
+
+
+/**
+ * Return a string representation of the given swizzle word.
+ * If extended is true, use extended (comma-separated) format.
+ * \param swizzle  the swizzle field
+ * \param negateBase  4-bit negation vector
+ * \param extended  if true, also allow 0, 1 values
+ */
+const char *
+_mesa_swizzle_string(GLuint swizzle, GLuint negateMask, GLboolean extended)
+{
+   static const char swz[] = "xyzw01!?";  /* See SWIZZLE_x definitions */
+   static char s[20];
+   GLuint i = 0;
+
+   if (!extended && swizzle == SWIZZLE_NOOP && negateMask == 0)
+      return ""; /* no swizzle/negation */
+
+   if (!extended)
+      s[i++] = '.';
+
+   if (negateMask & NEGATE_X)
+      s[i++] = '-';
+   s[i++] = swz[GET_SWZ(swizzle, 0)];
+
+   if (extended) {
+      s[i++] = ',';
+   }
+
+   if (negateMask & NEGATE_Y)
+      s[i++] = '-';
+   s[i++] = swz[GET_SWZ(swizzle, 1)];
+
+   if (extended) {
+      s[i++] = ',';
+   }
+
+   if (negateMask & NEGATE_Z)
+      s[i++] = '-';
+   s[i++] = swz[GET_SWZ(swizzle, 2)];
+
+   if (extended) {
+      s[i++] = ',';
+   }
+
+   if (negateMask & NEGATE_W)
+      s[i++] = '-';
+   s[i++] = swz[GET_SWZ(swizzle, 3)];
+
+   s[i] = 0;
+   return s;
+}
+
+
+void
+_mesa_print_swizzle(GLuint swizzle)
+{
+   if (swizzle == SWIZZLE_XYZW) {
+      printf(".xyzw\n");
+   }
+   else {
+      const char *s = _mesa_swizzle_string(swizzle, 0, 0);
+      printf("%s\n", s);
+   }
+}
+
+
+const char *
+_mesa_writemask_string(GLuint writeMask)
+{
+   static char s[10];
+   GLuint i = 0;
+
+   if (writeMask == WRITEMASK_XYZW)
+      return "";
+
+   s[i++] = '.';
+   if (writeMask & WRITEMASK_X)
+      s[i++] = 'x';
+   if (writeMask & WRITEMASK_Y)
+      s[i++] = 'y';
+   if (writeMask & WRITEMASK_Z)
+      s[i++] = 'z';
+   if (writeMask & WRITEMASK_W)
+      s[i++] = 'w';
+
+   s[i] = 0;
+   return s;
+}
+
+
+const char *
+_mesa_condcode_string(GLuint condcode)
+{
+   switch (condcode) {
+   case COND_GT:  return "GT";
+   case COND_EQ:  return "EQ";
+   case COND_LT:  return "LT";
+   case COND_UN:  return "UN";
+   case COND_GE:  return "GE";
+   case COND_LE:  return "LE";
+   case COND_NE:  return "NE";
+   case COND_TR:  return "TR";
+   case COND_FL:  return "FL";
+   default: return "cond???";
+   }
+}
+
+
+static void
+fprint_dst_reg(FILE * f,
+               const struct prog_dst_register *dstReg,
+               gl_prog_print_mode mode,
+               const struct gl_program *prog)
+{
+   fprintf(f, "%s%s",
+          reg_string((gl_register_file) dstReg->File,
+                     dstReg->Index, mode, dstReg->RelAddr, prog,
+                      GL_FALSE, GL_FALSE, 0),
+          _mesa_writemask_string(dstReg->WriteMask));
+   
+   if (dstReg->CondMask != COND_TR) {
+      fprintf(f, " (%s.%s)",
+             _mesa_condcode_string(dstReg->CondMask),
+             _mesa_swizzle_string(dstReg->CondSwizzle,
+                                  GL_FALSE, GL_FALSE));
+   }
+
+#if 0
+   fprintf(f, "%s[%d]%s",
+          file_string((gl_register_file) dstReg->File, mode),
+          dstReg->Index,
+          _mesa_writemask_string(dstReg->WriteMask));
+#endif
+}
+
+
+static void
+fprint_src_reg(FILE *f,
+               const struct prog_src_register *srcReg, 
+               gl_prog_print_mode mode,
+               const struct gl_program *prog)
+{
+   const char *abs = srcReg->Abs ? "|" : "";
+
+   fprintf(f, "%s%s%s%s",
+          abs,
+          reg_string((gl_register_file) srcReg->File,
+                     srcReg->Index, mode, srcReg->RelAddr, prog,
+                      srcReg->HasIndex2, srcReg->RelAddr2, srcReg->Index2),
+          _mesa_swizzle_string(srcReg->Swizzle,
+                               srcReg->Negate, GL_FALSE),
+          abs);
+#if 0
+   fprintf(f, "%s[%d]%s",
+          file_string((gl_register_file) srcReg->File, mode),
+          srcReg->Index,
+          _mesa_swizzle_string(srcReg->Swizzle,
+                               srcReg->Negate, GL_FALSE));
+#endif
+}
+
+
+static void
+fprint_comment(FILE *f, const struct prog_instruction *inst)
+{
+   if (inst->Comment)
+      fprintf(f, ";  # %s\n", inst->Comment);
+   else
+      fprintf(f, ";\n");
+}
+
+
+static void
+fprint_alu_instruction(FILE *f,
+                       const struct prog_instruction *inst,
+                       const char *opcode_string, GLuint numRegs,
+                       gl_prog_print_mode mode,
+                       const struct gl_program *prog)
+{
+   GLuint j;
+
+   fprintf(f, "%s", opcode_string);
+   if (inst->CondUpdate)
+      fprintf(f, ".C");
+
+   /* frag prog only */
+   if (inst->SaturateMode == SATURATE_ZERO_ONE)
+      fprintf(f, "_SAT");
+
+   fprintf(f, " ");
+   if (inst->DstReg.File != PROGRAM_UNDEFINED) {
+      fprint_dst_reg(f, &inst->DstReg, mode, prog);
+   }
+   else {
+      fprintf(f, " ???");
+   }
+
+   if (numRegs > 0)
+      fprintf(f, ", ");
+
+   for (j = 0; j < numRegs; j++) {
+      fprint_src_reg(f, inst->SrcReg + j, mode, prog);
+      if (j + 1 < numRegs)
+        fprintf(f, ", ");
+   }
+
+   fprint_comment(f, inst);
+}
+
+
+void
+_mesa_print_alu_instruction(const struct prog_instruction *inst,
+                            const char *opcode_string, GLuint numRegs)
+{
+   fprint_alu_instruction(stderr, inst, opcode_string,
+                          numRegs, PROG_PRINT_DEBUG, NULL);
+}
+
+
+/**
+ * Print a single vertex/fragment program instruction.
+ */
+GLint
+_mesa_fprint_instruction_opt(FILE *f,
+                            const struct prog_instruction *inst,
+                            GLint indent,
+                            gl_prog_print_mode mode,
+                            const struct gl_program *prog)
+{
+   GLint i;
+
+   if (inst->Opcode == OPCODE_ELSE ||
+       inst->Opcode == OPCODE_ENDIF ||
+       inst->Opcode == OPCODE_ENDLOOP ||
+       inst->Opcode == OPCODE_ENDSUB) {
+      indent -= 3;
+   }
+   for (i = 0; i < indent; i++) {
+      fprintf(f, " ");
+   }
+
+   switch (inst->Opcode) {
+   case OPCODE_PRINT:
+      fprintf(f, "PRINT '%s'", (char *) inst->Data);
+      if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
+         fprintf(f, ", ");
+         fprintf(f, "%s[%d]%s",
+                file_string((gl_register_file) inst->SrcReg[0].File,
+                            mode),
+                inst->SrcReg[0].Index,
+                _mesa_swizzle_string(inst->SrcReg[0].Swizzle,
+                                     inst->SrcReg[0].Negate, GL_FALSE));
+      }
+      if (inst->Comment)
+         fprintf(f, "  # %s", inst->Comment);
+      fprint_comment(f, inst);
+      break;
+   case OPCODE_SWZ:
+      fprintf(f, "SWZ");
+      if (inst->SaturateMode == SATURATE_ZERO_ONE)
+         fprintf(f, "_SAT");
+      fprintf(f, " ");
+      fprint_dst_reg(f, &inst->DstReg, mode, prog);
+      fprintf(f, ", %s[%d], %s",
+             file_string((gl_register_file) inst->SrcReg[0].File,
+                         mode),
+             inst->SrcReg[0].Index,
+             _mesa_swizzle_string(inst->SrcReg[0].Swizzle,
+                                  inst->SrcReg[0].Negate, GL_TRUE));
+      fprint_comment(f, inst);
+      break;
+   case OPCODE_TEX:
+   case OPCODE_TXP:
+   case OPCODE_TXL:
+   case OPCODE_TXB:
+      fprintf(f, "%s", _mesa_opcode_string(inst->Opcode));
+      if (inst->SaturateMode == SATURATE_ZERO_ONE)
+         fprintf(f, "_SAT");
+      fprintf(f, " ");
+      fprint_dst_reg(f, &inst->DstReg, mode, prog);
+      fprintf(f, ", ");
+      fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
+      fprintf(f, ", texture[%d], ", inst->TexSrcUnit);
+      switch (inst->TexSrcTarget) {
+      case TEXTURE_1D_INDEX:   fprintf(f, "1D");    break;
+      case TEXTURE_2D_INDEX:   fprintf(f, "2D");    break;
+      case TEXTURE_3D_INDEX:   fprintf(f, "3D");    break;
+      case TEXTURE_CUBE_INDEX: fprintf(f, "CUBE");  break;
+      case TEXTURE_RECT_INDEX: fprintf(f, "RECT");  break;
+      case TEXTURE_1D_ARRAY_INDEX: fprintf(f, "1D_ARRAY"); break;
+      case TEXTURE_2D_ARRAY_INDEX: fprintf(f, "2D_ARRAY"); break;
+      default:
+         ;
+      }
+      if (inst->TexShadow)
+         fprintf(f, " SHADOW");
+      fprint_comment(f, inst);
+      break;
+
+   case OPCODE_KIL:
+      fprintf(f, "%s", _mesa_opcode_string(inst->Opcode));
+      fprintf(f, " ");
+      fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
+      fprint_comment(f, inst);
+      break;
+   case OPCODE_KIL_NV:
+      fprintf(f, "%s", _mesa_opcode_string(inst->Opcode));
+      fprintf(f, " ");
+      fprintf(f, "%s.%s",
+             _mesa_condcode_string(inst->DstReg.CondMask),
+             _mesa_swizzle_string(inst->DstReg.CondSwizzle,
+                                  GL_FALSE, GL_FALSE));
+      fprint_comment(f, inst);
+      break;
+
+   case OPCODE_ARL:
+      fprintf(f, "ARL ");
+      fprint_dst_reg(f, &inst->DstReg, mode, prog);
+      fprintf(f, ", ");
+      fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
+      fprint_comment(f, inst);
+      break;
+   case OPCODE_BRA:
+      fprintf(f, "BRA %d (%s%s)",
+             inst->BranchTarget,
+             _mesa_condcode_string(inst->DstReg.CondMask),
+             _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
+      fprint_comment(f, inst);
+      break;
+   case OPCODE_IF:
+      if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
+         /* Use ordinary register */
+         fprintf(f, "IF ");
+         fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
+         fprintf(f, "; ");
+      }
+      else {
+         /* Use cond codes */
+         fprintf(f, "IF (%s%s);",
+                _mesa_condcode_string(inst->DstReg.CondMask),
+                _mesa_swizzle_string(inst->DstReg.CondSwizzle,
+                                     0, GL_FALSE));
+      }
+      fprintf(f, " # (if false, goto %d)", inst->BranchTarget);
+      fprint_comment(f, inst);
+      return indent + 3;
+   case OPCODE_ELSE:
+      fprintf(f, "ELSE; # (goto %d)\n", inst->BranchTarget);
+      return indent + 3;
+   case OPCODE_ENDIF:
+      fprintf(f, "ENDIF;\n");
+      break;
+   case OPCODE_BGNLOOP:
+      fprintf(f, "BGNLOOP; # (end at %d)\n", inst->BranchTarget);
+      return indent + 3;
+   case OPCODE_ENDLOOP:
+      fprintf(f, "ENDLOOP; # (goto %d)\n", inst->BranchTarget);
+      break;
+   case OPCODE_BRK:
+   case OPCODE_CONT:
+      fprintf(f, "%s (%s%s); # (goto %d)",
+             _mesa_opcode_string(inst->Opcode),
+             _mesa_condcode_string(inst->DstReg.CondMask),
+             _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE),
+             inst->BranchTarget);
+      fprint_comment(f, inst);
+      break;
+
+   case OPCODE_BGNSUB:
+      if (mode == PROG_PRINT_NV) {
+         fprintf(f, "%s:\n", inst->Comment); /* comment is label */
+         return indent;
+      }
+      else {
+         fprintf(f, "BGNSUB");
+         fprint_comment(f, inst);
+         return indent + 3;
+      }
+   case OPCODE_ENDSUB:
+      if (mode == PROG_PRINT_DEBUG) {
+         fprintf(f, "ENDSUB");
+         fprint_comment(f, inst);
+      }
+      break;
+   case OPCODE_CAL:
+      if (mode == PROG_PRINT_NV) {
+         fprintf(f, "CAL %s;  # (goto %d)\n", inst->Comment, inst->BranchTarget);
+      }
+      else {
+         fprintf(f, "CAL %u", inst->BranchTarget);
+         fprint_comment(f, inst);
+      }
+      break;
+   case OPCODE_RET:
+      fprintf(f, "RET (%s%s)",
+             _mesa_condcode_string(inst->DstReg.CondMask),
+             _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
+      fprint_comment(f, inst);
+      break;
+
+   case OPCODE_END:
+      fprintf(f, "END\n");
+      break;
+   case OPCODE_NOP:
+      if (mode == PROG_PRINT_DEBUG) {
+         fprintf(f, "NOP");
+         fprint_comment(f, inst);
+      }
+      else if (inst->Comment) {
+         /* ARB/NV extensions don't have NOP instruction */
+         fprintf(f, "# %s\n", inst->Comment);
+      }
+      break;
+   case OPCODE_EMIT_VERTEX:
+      fprintf(f, "EMIT_VERTEX\n");
+      break;
+   case OPCODE_END_PRIMITIVE:
+      fprintf(f, "END_PRIMITIVE\n");
+      break;
+   /* XXX may need other special-case instructions */
+   default:
+      if (inst->Opcode < MAX_OPCODE) {
+         /* typical alu instruction */
+         fprint_alu_instruction(f, inst,
+                                _mesa_opcode_string(inst->Opcode),
+                                _mesa_num_inst_src_regs(inst->Opcode),
+                                mode, prog);
+      }
+      else {
+         fprint_alu_instruction(f, inst,
+                                _mesa_opcode_string(inst->Opcode),
+                                3/*_mesa_num_inst_src_regs(inst->Opcode)*/,
+                                mode, prog);
+      }
+      break;
+   }
+   return indent;
+}
+
+
+GLint
+_mesa_print_instruction_opt(const struct prog_instruction *inst,
+                            GLint indent,
+                            gl_prog_print_mode mode,
+                            const struct gl_program *prog)
+{
+   return _mesa_fprint_instruction_opt(stderr, inst, indent, mode, prog);
+}
+
+
+void
+_mesa_print_instruction(const struct prog_instruction *inst)
+{
+   /* note: 4th param should be ignored for PROG_PRINT_DEBUG */
+   _mesa_fprint_instruction_opt(stderr, inst, 0, PROG_PRINT_DEBUG, NULL);
+}
+
+
+
+/**
+ * Print program, with options.
+ */
+void
+_mesa_fprint_program_opt(FILE *f,
+                         const struct gl_program *prog,
+                         gl_prog_print_mode mode,
+                         GLboolean lineNumbers)
+{
+   GLuint i, indent = 0;
+
+   switch (prog->Target) {
+   case GL_VERTEX_PROGRAM_ARB:
+      if (mode == PROG_PRINT_ARB)
+         fprintf(f, "!!ARBvp1.0\n");
+      else if (mode == PROG_PRINT_NV)
+         fprintf(f, "!!VP1.0\n");
+      else
+         fprintf(f, "# Vertex Program/Shader %u\n", prog->Id);
+      break;
+   case GL_FRAGMENT_PROGRAM_ARB:
+   case GL_FRAGMENT_PROGRAM_NV:
+      if (mode == PROG_PRINT_ARB)
+         fprintf(f, "!!ARBfp1.0\n");
+      else if (mode == PROG_PRINT_NV)
+         fprintf(f, "!!FP1.0\n");
+      else
+         fprintf(f, "# Fragment Program/Shader %u\n", prog->Id);
+      break;
+   case MESA_GEOMETRY_PROGRAM:
+      fprintf(f, "# Geometry Shader\n");
+   }
+
+   for (i = 0; i < prog->NumInstructions; i++) {
+      if (lineNumbers)
+         fprintf(f, "%3d: ", i);
+      indent = _mesa_fprint_instruction_opt(f, prog->Instructions + i,
+                                           indent, mode, prog);
+   }
+}
+
+
+/**
+ * Print program to stderr, default options.
+ */
+void
+_mesa_print_program(const struct gl_program *prog)
+{
+   _mesa_fprint_program_opt(stderr, prog, PROG_PRINT_DEBUG, GL_TRUE);
+}
+
+
+/**
+ * Return binary representation of 64-bit value (as a string).
+ * Insert a comma to separate each group of 8 bits.
+ * Note we return a pointer to local static storage so this is not
+ * re-entrant, etc.
+ * XXX move to imports.[ch] if useful elsewhere.
+ */
+static const char *
+binary(GLbitfield64 val)
+{
+   static char buf[80];
+   GLint i, len = 0;
+   for (i = 63; i >= 0; --i) {
+      if (val & (BITFIELD64_BIT(i)))
+         buf[len++] = '1';
+      else if (len > 0 || i == 0)
+         buf[len++] = '0';
+      if (len > 0 && ((i-1) % 8) == 7)
+         buf[len++] = ',';
+   }
+   buf[len] = '\0';
+   return buf;
+}
+
+
+/**
+ * Print all of a program's parameters/fields to given file.
+ */
+static void
+_mesa_fprint_program_parameters(FILE *f,
+                                GLcontext *ctx,
+                                const struct gl_program *prog)
+{
+   GLuint i;
+
+   fprintf(f, "InputsRead: 0x%x (0b%s)\n",
+                 prog->InputsRead, binary(prog->InputsRead));
+   fprintf(f, "OutputsWritten: 0x%llx (0b%s)\n",
+                 (unsigned long long)prog->OutputsWritten, 
+                binary(prog->OutputsWritten));
+   fprintf(f, "NumInstructions=%d\n", prog->NumInstructions);
+   fprintf(f, "NumTemporaries=%d\n", prog->NumTemporaries);
+   fprintf(f, "NumParameters=%d\n", prog->NumParameters);
+   fprintf(f, "NumAttributes=%d\n", prog->NumAttributes);
+   fprintf(f, "NumAddressRegs=%d\n", prog->NumAddressRegs);
+   fprintf(f, "SamplersUsed: 0x%x (0b%s)\n",
+                 prog->SamplersUsed, binary(prog->SamplersUsed));
+   fprintf(f, "Samplers=[ ");
+   for (i = 0; i < MAX_SAMPLERS; i++) {
+      fprintf(f, "%d ", prog->SamplerUnits[i]);
+   }
+   fprintf(f, "]\n");
+
+   _mesa_load_state_parameters(ctx, prog->Parameters);
+
+#if 0
+   fprintf(f, "Local Params:\n");
+   for (i = 0; i < MAX_PROGRAM_LOCAL_PARAMS; i++){
+      const GLfloat *p = prog->LocalParams[i];
+      fprintf(f, "%2d: %f, %f, %f, %f\n", i, p[0], p[1], p[2], p[3]);
+   }
+#endif 
+   _mesa_print_parameter_list(prog->Parameters);
+}
+
+
+/**
+ * Print all of a program's parameters/fields to stderr.
+ */
+void
+_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog)
+{
+   _mesa_fprint_program_parameters(stderr, ctx, prog);
+}
+
+
+/**
+ * Print a program parameter list to given file.
+ */
+static void
+_mesa_fprint_parameter_list(FILE *f,
+                            const struct gl_program_parameter_list *list)
+{
+   const gl_prog_print_mode mode = PROG_PRINT_DEBUG;
+   GLuint i;
+
+   if (!list)
+      return;
+
+   if (0)
+      fprintf(f, "param list %p\n", (void *) list);
+   fprintf(f, "dirty state flags: 0x%x\n", list->StateFlags);
+   for (i = 0; i < list->NumParameters; i++){
+      struct gl_program_parameter *param = list->Parameters + i;
+      const GLfloat *v = list->ParameterValues[i];
+      fprintf(f, "param[%d] sz=%d %s %s = {%.3g, %.3g, %.3g, %.3g}",
+             i, param->Size,
+             file_string(list->Parameters[i].Type, mode),
+             param->Name, v[0], v[1], v[2], v[3]);
+      if (param->Flags & PROG_PARAM_BIT_CENTROID)
+         fprintf(f, " Centroid");
+      if (param->Flags & PROG_PARAM_BIT_INVARIANT)
+         fprintf(f, " Invariant");
+      if (param->Flags & PROG_PARAM_BIT_FLAT)
+         fprintf(f, " Flat");
+      if (param->Flags & PROG_PARAM_BIT_LINEAR)
+         fprintf(f, " Linear");
+      fprintf(f, "\n");
+   }
+}
+
+
+/**
+ * Print a program parameter list to stderr.
+ */
+void
+_mesa_print_parameter_list(const struct gl_program_parameter_list *list)
+{
+   _mesa_fprint_parameter_list(stderr, list);
+}
+
+
+/**
+ * Write shader and associated info to a file.
+ */
+void
+_mesa_write_shader_to_file(const struct gl_shader *shader)
+{
+   const char *type;
+   char filename[100];
+   FILE *f;
+
+   if (shader->Type == GL_FRAGMENT_SHADER)
+      type = "frag";
+   else if (shader->Type == GL_VERTEX_SHADER)
+      type = "vert";
+   else
+      type = "geom";
+
+   _mesa_snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type);
+   f = fopen(filename, "w");
+   if (!f) {
+      fprintf(stderr, "Unable to open %s for writing\n", filename);
+      return;
+   }
+
+   fprintf(f, "/* Shader %u source, checksum %u */\n", shader->Name, shader->SourceChecksum);
+   fputs(shader->Source, f);
+   fprintf(f, "\n");
+
+   fprintf(f, "/* Compile status: %s */\n",
+           shader->CompileStatus ? "ok" : "fail");
+   if (!shader->CompileStatus) {
+      fprintf(f, "/* Log Info: */\n");
+      fputs(shader->InfoLog, f);
+   }
+   else {
+      fprintf(f, "/* GPU code */\n");
+      fprintf(f, "/*\n");
+      _mesa_fprint_program_opt(f, shader->Program, PROG_PRINT_DEBUG, GL_TRUE);
+      fprintf(f, "*/\n");
+      fprintf(f, "/* Parameters / constants */\n");
+      fprintf(f, "/*\n");
+      _mesa_fprint_parameter_list(f, shader->Program->Parameters);
+      fprintf(f, "*/\n");
+   }
+
+   fclose(f);
+}
+
+
+/**
+ * Append the shader's uniform info/values to the shader log file.
+ * The log file will typically have been created by the
+ * _mesa_write_shader_to_file function.
+ */
+void
+_mesa_append_uniforms_to_file(const struct gl_shader *shader,
+                              const struct gl_program *prog)
+{
+   const char *type;
+   char filename[100];
+   FILE *f;
+
+   if (shader->Type == GL_FRAGMENT_SHADER)
+      type = "frag";
+   else
+      type = "vert";
+
+   _mesa_snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type);
+   f = fopen(filename, "a"); /* append */
+   if (!f) {
+      fprintf(stderr, "Unable to open %s for appending\n", filename);
+      return;
+   }
+
+   fprintf(f, "/* First-draw parameters / constants */\n");
+   fprintf(f, "/*\n");
+   _mesa_fprint_parameter_list(f, prog->Parameters);
+   fprintf(f, "*/\n");
+
+   fclose(f);
+}
diff --git a/src/mesa/program/prog_print.h b/src/mesa/program/prog_print.h
new file mode 100644 (file)
index 0000000..9ab7456
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.3
+ *
+ * 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.
+ */
+
+
+#ifndef PROG_PRINT_H
+#define PROG_PRINT_H
+
+
+/**
+ * The output style to use when printing programs.
+ */
+typedef enum {
+   PROG_PRINT_ARB,
+   PROG_PRINT_NV,
+   PROG_PRINT_DEBUG
+} gl_prog_print_mode;
+
+
+extern void
+_mesa_print_vp_inputs(GLbitfield inputs);
+
+extern void
+_mesa_print_fp_inputs(GLbitfield inputs);
+
+extern const char *
+_mesa_condcode_string(GLuint condcode);
+
+extern const char *
+_mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended);
+
+const char *
+_mesa_writemask_string(GLuint writeMask);
+
+extern void
+_mesa_print_swizzle(GLuint swizzle);
+
+extern void
+_mesa_print_alu_instruction(const struct prog_instruction *inst,
+                            const char *opcode_string, GLuint numRegs);
+
+extern void
+_mesa_print_instruction(const struct prog_instruction *inst);
+
+extern GLint
+_mesa_fprint_instruction_opt(FILE *f,
+                            const struct prog_instruction *inst,
+                            GLint indent,
+                            gl_prog_print_mode mode,
+                            const struct gl_program *prog);
+
+extern GLint
+_mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent,
+                            gl_prog_print_mode mode,
+                            const struct gl_program *prog);
+
+extern void
+_mesa_print_program(const struct gl_program *prog);
+
+extern void
+_mesa_fprint_program_opt(FILE *f,
+                         const struct gl_program *prog, gl_prog_print_mode mode,
+                         GLboolean lineNumbers);
+
+extern void
+_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog);
+
+extern void
+_mesa_print_parameter_list(const struct gl_program_parameter_list *list);
+
+
+extern void
+_mesa_write_shader_to_file(const struct gl_shader *shader);
+
+extern void
+_mesa_append_uniforms_to_file(const struct gl_shader *shader,
+                              const struct gl_program *prog);
+
+
+#endif /* PROG_PRINT_H */
diff --git a/src/mesa/program/prog_statevars.c b/src/mesa/program/prog_statevars.c
new file mode 100644 (file)
index 0000000..ead3ece
--- /dev/null
@@ -0,0 +1,1187 @@
+/*
+ * 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 prog_statevars.c
+ * Program state variable management.
+ * \author Brian Paul
+ */
+
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/imports.h"
+#include "main/macros.h"
+#include "main/mtypes.h"
+#include "prog_statevars.h"
+#include "prog_parameter.h"
+
+
+/**
+ * Use the list of tokens in the state[] array to find global GL state
+ * and return it in <value>.  Usually, four values are returned in <value>
+ * but matrix queries may return as many as 16 values.
+ * This function is used for ARB vertex/fragment programs.
+ * The program parser will produce the state[] values.
+ */
+static void
+_mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
+                  GLfloat *value)
+{
+   switch (state[0]) {
+   case STATE_MATERIAL:
+      {
+         /* state[1] is either 0=front or 1=back side */
+         const GLuint face = (GLuint) state[1];
+         const struct gl_material *mat = &ctx->Light.Material;
+         ASSERT(face == 0 || face == 1);
+         /* we rely on tokens numbered so that _BACK_ == _FRONT_+ 1 */
+         ASSERT(MAT_ATTRIB_FRONT_AMBIENT + 1 == MAT_ATTRIB_BACK_AMBIENT);
+         /* XXX we could get rid of this switch entirely with a little
+          * work in arbprogparse.c's parse_state_single_item().
+          */
+         /* state[2] is the material attribute */
+         switch (state[2]) {
+         case STATE_AMBIENT:
+            COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_AMBIENT + face]);
+            return;
+         case STATE_DIFFUSE:
+            COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_DIFFUSE + face]);
+            return;
+         case STATE_SPECULAR:
+            COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_SPECULAR + face]);
+            return;
+         case STATE_EMISSION:
+            COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_EMISSION + face]);
+            return;
+         case STATE_SHININESS:
+            value[0] = mat->Attrib[MAT_ATTRIB_FRONT_SHININESS + face][0];
+            value[1] = 0.0F;
+            value[2] = 0.0F;
+            value[3] = 1.0F;
+            return;
+         default:
+            _mesa_problem(ctx, "Invalid material state in fetch_state");
+            return;
+         }
+      }
+   case STATE_LIGHT:
+      {
+         /* state[1] is the light number */
+         const GLuint ln = (GLuint) state[1];
+         /* state[2] is the light attribute */
+         switch (state[2]) {
+         case STATE_AMBIENT:
+            COPY_4V(value, ctx->Light.Light[ln].Ambient);
+            return;
+         case STATE_DIFFUSE:
+            COPY_4V(value, ctx->Light.Light[ln].Diffuse);
+            return;
+         case STATE_SPECULAR:
+            COPY_4V(value, ctx->Light.Light[ln].Specular);
+            return;
+         case STATE_POSITION:
+            COPY_4V(value, ctx->Light.Light[ln].EyePosition);
+            return;
+         case STATE_ATTENUATION:
+            value[0] = ctx->Light.Light[ln].ConstantAttenuation;
+            value[1] = ctx->Light.Light[ln].LinearAttenuation;
+            value[2] = ctx->Light.Light[ln].QuadraticAttenuation;
+            value[3] = ctx->Light.Light[ln].SpotExponent;
+            return;
+         case STATE_SPOT_DIRECTION:
+            COPY_3V(value, ctx->Light.Light[ln].SpotDirection);
+            value[3] = ctx->Light.Light[ln]._CosCutoff;
+            return;
+         case STATE_SPOT_CUTOFF:
+            value[0] = ctx->Light.Light[ln].SpotCutoff;
+            return;
+         case STATE_HALF_VECTOR:
+            {
+               static const GLfloat eye_z[] = {0, 0, 1};
+               GLfloat p[3];
+               /* Compute infinite half angle vector:
+                *   halfVector = normalize(normalize(lightPos) + (0, 0, 1))
+               * light.EyePosition.w should be 0 for infinite lights.
+                */
+               COPY_3V(p, ctx->Light.Light[ln].EyePosition);
+               NORMALIZE_3FV(p);
+              ADD_3V(value, p, eye_z);
+              NORMALIZE_3FV(value);
+              value[3] = 1.0;
+            }
+            return;
+         default:
+            _mesa_problem(ctx, "Invalid light state in fetch_state");
+            return;
+         }
+      }
+   case STATE_LIGHTMODEL_AMBIENT:
+      COPY_4V(value, ctx->Light.Model.Ambient);
+      return;
+   case STATE_LIGHTMODEL_SCENECOLOR:
+      if (state[1] == 0) {
+         /* front */
+         GLint i;
+         for (i = 0; i < 3; i++) {
+            value[i] = ctx->Light.Model.Ambient[i]
+               * ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT][i]
+               + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION][i];
+         }
+        value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
+      }
+      else {
+         /* back */
+         GLint i;
+         for (i = 0; i < 3; i++) {
+            value[i] = ctx->Light.Model.Ambient[i]
+               * ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_AMBIENT][i]
+               + ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_EMISSION][i];
+         }
+        value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
+      }
+      return;
+   case STATE_LIGHTPROD:
+      {
+         const GLuint ln = (GLuint) state[1];
+         const GLuint face = (GLuint) state[2];
+         GLint i;
+         ASSERT(face == 0 || face == 1);
+         switch (state[3]) {
+            case STATE_AMBIENT:
+               for (i = 0; i < 3; i++) {
+                  value[i] = ctx->Light.Light[ln].Ambient[i] *
+                     ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][i];
+               }
+               /* [3] = material alpha */
+               value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][3];
+               return;
+            case STATE_DIFFUSE:
+               for (i = 0; i < 3; i++) {
+                  value[i] = ctx->Light.Light[ln].Diffuse[i] *
+                     ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][i];
+               }
+               /* [3] = material alpha */
+               value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3];
+               return;
+            case STATE_SPECULAR:
+               for (i = 0; i < 3; i++) {
+                  value[i] = ctx->Light.Light[ln].Specular[i] *
+                     ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][i];
+               }
+               /* [3] = material alpha */
+               value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][3];
+               return;
+            default:
+               _mesa_problem(ctx, "Invalid lightprod state in fetch_state");
+               return;
+         }
+      }
+   case STATE_TEXGEN:
+      {
+         /* state[1] is the texture unit */
+         const GLuint unit = (GLuint) state[1];
+         /* state[2] is the texgen attribute */
+         switch (state[2]) {
+         case STATE_TEXGEN_EYE_S:
+            COPY_4V(value, ctx->Texture.Unit[unit].GenS.EyePlane);
+            return;
+         case STATE_TEXGEN_EYE_T:
+            COPY_4V(value, ctx->Texture.Unit[unit].GenT.EyePlane);
+            return;
+         case STATE_TEXGEN_EYE_R:
+            COPY_4V(value, ctx->Texture.Unit[unit].GenR.EyePlane);
+            return;
+         case STATE_TEXGEN_EYE_Q:
+            COPY_4V(value, ctx->Texture.Unit[unit].GenQ.EyePlane);
+            return;
+         case STATE_TEXGEN_OBJECT_S:
+            COPY_4V(value, ctx->Texture.Unit[unit].GenS.ObjectPlane);
+            return;
+         case STATE_TEXGEN_OBJECT_T:
+            COPY_4V(value, ctx->Texture.Unit[unit].GenT.ObjectPlane);
+            return;
+         case STATE_TEXGEN_OBJECT_R:
+            COPY_4V(value, ctx->Texture.Unit[unit].GenR.ObjectPlane);
+            return;
+         case STATE_TEXGEN_OBJECT_Q:
+            COPY_4V(value, ctx->Texture.Unit[unit].GenQ.ObjectPlane);
+            return;
+         default:
+            _mesa_problem(ctx, "Invalid texgen state in fetch_state");
+            return;
+         }
+      }
+   case STATE_TEXENV_COLOR:
+      {
+         /* state[1] is the texture unit */
+         const GLuint unit = (GLuint) state[1];
+         COPY_4V(value, ctx->Texture.Unit[unit].EnvColor);
+      }
+      return;
+   case STATE_FOG_COLOR:
+      COPY_4V(value, ctx->Fog.Color);
+      return;
+   case STATE_FOG_PARAMS:
+      value[0] = ctx->Fog.Density;
+      value[1] = ctx->Fog.Start;
+      value[2] = ctx->Fog.End;
+      value[3] = (ctx->Fog.End == ctx->Fog.Start)
+         ? 1.0f : (GLfloat)(1.0 / (ctx->Fog.End - ctx->Fog.Start));
+      return;
+   case STATE_CLIPPLANE:
+      {
+         const GLuint plane = (GLuint) state[1];
+         COPY_4V(value, ctx->Transform.EyeUserPlane[plane]);
+      }
+      return;
+   case STATE_POINT_SIZE:
+      value[0] = ctx->Point.Size;
+      value[1] = ctx->Point.MinSize;
+      value[2] = ctx->Point.MaxSize;
+      value[3] = ctx->Point.Threshold;
+      return;
+   case STATE_POINT_ATTENUATION:
+      value[0] = ctx->Point.Params[0];
+      value[1] = ctx->Point.Params[1];
+      value[2] = ctx->Point.Params[2];
+      value[3] = 1.0F;
+      return;
+   case STATE_MODELVIEW_MATRIX:
+   case STATE_PROJECTION_MATRIX:
+   case STATE_MVP_MATRIX:
+   case STATE_TEXTURE_MATRIX:
+   case STATE_PROGRAM_MATRIX:
+   case STATE_COLOR_MATRIX:
+      {
+         /* state[0] = modelview, projection, texture, etc. */
+         /* state[1] = which texture matrix or program matrix */
+         /* state[2] = first row to fetch */
+         /* state[3] = last row to fetch */
+         /* state[4] = transpose, inverse or invtrans */
+         const GLmatrix *matrix;
+         const gl_state_index mat = state[0];
+         const GLuint index = (GLuint) state[1];
+         const GLuint firstRow = (GLuint) state[2];
+         const GLuint lastRow = (GLuint) state[3];
+         const gl_state_index modifier = state[4];
+         const GLfloat *m;
+         GLuint row, i;
+         ASSERT(firstRow >= 0);
+         ASSERT(firstRow < 4);
+         ASSERT(lastRow >= 0);
+         ASSERT(lastRow < 4);
+         if (mat == STATE_MODELVIEW_MATRIX) {
+            matrix = ctx->ModelviewMatrixStack.Top;
+         }
+         else if (mat == STATE_PROJECTION_MATRIX) {
+            matrix = ctx->ProjectionMatrixStack.Top;
+         }
+         else if (mat == STATE_MVP_MATRIX) {
+            matrix = &ctx->_ModelProjectMatrix;
+         }
+         else if (mat == STATE_TEXTURE_MATRIX) {
+            ASSERT(index < Elements(ctx->TextureMatrixStack));
+            matrix = ctx->TextureMatrixStack[index].Top;
+         }
+         else if (mat == STATE_PROGRAM_MATRIX) {
+            ASSERT(index < Elements(ctx->ProgramMatrixStack));
+            matrix = ctx->ProgramMatrixStack[index].Top;
+         }
+         else if (mat == STATE_COLOR_MATRIX) {
+            matrix = ctx->ColorMatrixStack.Top;
+         }
+         else {
+            _mesa_problem(ctx, "Bad matrix name in _mesa_fetch_state()");
+            return;
+         }
+         if (modifier == STATE_MATRIX_INVERSE ||
+             modifier == STATE_MATRIX_INVTRANS) {
+            /* Be sure inverse is up to date:
+            */
+            _math_matrix_alloc_inv( (GLmatrix *) matrix );
+           _math_matrix_analyse( (GLmatrix*) matrix );
+            m = matrix->inv;
+         }
+         else {
+            m = matrix->m;
+         }
+         if (modifier == STATE_MATRIX_TRANSPOSE ||
+             modifier == STATE_MATRIX_INVTRANS) {
+            for (i = 0, row = firstRow; row <= lastRow; row++) {
+               value[i++] = m[row * 4 + 0];
+               value[i++] = m[row * 4 + 1];
+               value[i++] = m[row * 4 + 2];
+               value[i++] = m[row * 4 + 3];
+            }
+         }
+         else {
+            for (i = 0, row = firstRow; row <= lastRow; row++) {
+               value[i++] = m[row + 0];
+               value[i++] = m[row + 4];
+               value[i++] = m[row + 8];
+               value[i++] = m[row + 12];
+            }
+         }
+      }
+      return;
+   case STATE_DEPTH_RANGE:
+      value[0] = ctx->Viewport.Near;                     /* near       */
+      value[1] = ctx->Viewport.Far;                      /* far        */
+      value[2] = ctx->Viewport.Far - ctx->Viewport.Near; /* far - near */
+      value[3] = 1.0;
+      return;
+   case STATE_FRAGMENT_PROGRAM:
+      {
+         /* state[1] = {STATE_ENV, STATE_LOCAL} */
+         /* state[2] = parameter index          */
+         const int idx = (int) state[2];
+         switch (state[1]) {
+            case STATE_ENV:
+               COPY_4V(value, ctx->FragmentProgram.Parameters[idx]);
+               return;
+            case STATE_LOCAL:
+               COPY_4V(value, ctx->FragmentProgram.Current->Base.LocalParams[idx]);
+               return;
+            default:
+               _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()");
+               return;
+         }
+      }
+      return;
+
+   case STATE_VERTEX_PROGRAM:
+      {
+         /* state[1] = {STATE_ENV, STATE_LOCAL} */
+         /* state[2] = parameter index          */
+         const int idx = (int) state[2];
+         switch (state[1]) {
+            case STATE_ENV:
+               COPY_4V(value, ctx->VertexProgram.Parameters[idx]);
+               return;
+            case STATE_LOCAL:
+               COPY_4V(value, ctx->VertexProgram.Current->Base.LocalParams[idx]);
+               return;
+            default:
+               _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()");
+               return;
+         }
+      }
+      return;
+
+   case STATE_NORMAL_SCALE:
+      ASSIGN_4V(value, ctx->_ModelViewInvScale, 0, 0, 1);
+      return;
+
+   case STATE_INTERNAL:
+      switch (state[1]) {
+      case STATE_CURRENT_ATTRIB:
+         {
+            const GLuint idx = (GLuint) state[2];
+            COPY_4V(value, ctx->Current.Attrib[idx]);
+         }
+         return;
+
+      case STATE_NORMAL_SCALE:
+         ASSIGN_4V(value, 
+                   ctx->_ModelViewInvScale, 
+                   ctx->_ModelViewInvScale, 
+                   ctx->_ModelViewInvScale, 
+                   1);
+         return;
+
+      case STATE_TEXRECT_SCALE:
+         /* Value = { 1/texWidth, 1/texHeight, 0, 1 }.
+          * Used to convert unnormalized texcoords to normalized texcoords.
+          */
+         {
+            const int unit = (int) state[2];
+            const struct gl_texture_object *texObj
+               = ctx->Texture.Unit[unit]._Current;
+            if (texObj) {
+               struct gl_texture_image *texImage = texObj->Image[0][0];
+               ASSIGN_4V(value,
+                         (GLfloat) (1.0 / texImage->Width),
+                         (GLfloat) (1.0 / texImage->Height),
+                         0.0f, 1.0f);
+            }
+         }
+         return;
+
+      case STATE_FOG_PARAMS_OPTIMIZED:
+         /* for simpler per-vertex/pixel fog calcs. POW (for EXP/EXP2 fog)
+          * might be more expensive than EX2 on some hw, plus it needs
+          * another constant (e) anyway. Linear fog can now be done with a
+          * single MAD.
+          * linear: fogcoord * -1/(end-start) + end/(end-start)
+          * exp: 2^-(density/ln(2) * fogcoord)
+          * exp2: 2^-((density/(ln(2)^2) * fogcoord)^2)
+          */
+         value[0] = (ctx->Fog.End == ctx->Fog.Start)
+            ? 1.0f : (GLfloat)(-1.0F / (ctx->Fog.End - ctx->Fog.Start));
+         value[1] = ctx->Fog.End * -value[0];
+         value[2] = (GLfloat)(ctx->Fog.Density * ONE_DIV_LN2);
+         value[3] = (GLfloat)(ctx->Fog.Density * ONE_DIV_SQRT_LN2);
+         return;
+
+      case STATE_POINT_SIZE_CLAMPED:
+         {
+           /* this includes implementation dependent limits, to avoid
+            * another potentially necessary clamp.
+            * Note: for sprites, point smooth (point AA) is ignored
+            * and we'll clamp to MinPointSizeAA and MaxPointSize, because we
+            * expect drivers will want to say their minimum for AA size is 0.0
+            * but for non-AA it's 1.0 (because normal points with size below 1.0
+            * need to get rounded up to 1.0, hence never disappear). GL does
+            * not specify max clamp size for sprites, other than it needs to be
+            * at least as large as max AA size, hence use non-AA size there.
+            */
+            GLfloat minImplSize;
+            GLfloat maxImplSize;
+            if (ctx->Point.PointSprite) {
+               minImplSize = ctx->Const.MinPointSizeAA;
+               maxImplSize = ctx->Const.MaxPointSize;
+            }
+            else if (ctx->Point.SmoothFlag || ctx->Multisample._Enabled) {
+               minImplSize = ctx->Const.MinPointSizeAA;
+               maxImplSize = ctx->Const.MaxPointSizeAA;
+            }
+            else {
+               minImplSize = ctx->Const.MinPointSize;
+               maxImplSize = ctx->Const.MaxPointSize;
+            }
+            value[0] = ctx->Point.Size;
+            value[1] = ctx->Point.MinSize >= minImplSize ? ctx->Point.MinSize : minImplSize;
+            value[2] = ctx->Point.MaxSize <= maxImplSize ? ctx->Point.MaxSize : maxImplSize;
+            value[3] = ctx->Point.Threshold;
+         }
+         return;
+      case STATE_POINT_SIZE_IMPL_CLAMP:
+         {
+           /* for implementation clamp only in vs */
+            GLfloat minImplSize;
+            GLfloat maxImplSize;
+            if (ctx->Point.PointSprite) {
+               minImplSize = ctx->Const.MinPointSizeAA;
+               maxImplSize = ctx->Const.MaxPointSize;
+            }
+            else if (ctx->Point.SmoothFlag || ctx->Multisample._Enabled) {
+               minImplSize = ctx->Const.MinPointSizeAA;
+               maxImplSize = ctx->Const.MaxPointSizeAA;
+            }
+            else {
+               minImplSize = ctx->Const.MinPointSize;
+               maxImplSize = ctx->Const.MaxPointSize;
+            }
+            value[0] = ctx->Point.Size;
+            value[1] = minImplSize;
+            value[2] = maxImplSize;
+            value[3] = ctx->Point.Threshold;
+         }
+         return;
+      case STATE_LIGHT_SPOT_DIR_NORMALIZED:
+         {
+            /* here, state[2] is the light number */
+            /* pre-normalize spot dir */
+            const GLuint ln = (GLuint) state[2];
+            COPY_3V(value, ctx->Light.Light[ln]._NormSpotDirection);
+            value[3] = ctx->Light.Light[ln]._CosCutoff;
+         }
+         return;
+
+      case STATE_LIGHT_POSITION:
+         {
+            const GLuint ln = (GLuint) state[2];
+            COPY_4V(value, ctx->Light.Light[ln]._Position);
+         }
+         return;
+
+      case STATE_LIGHT_POSITION_NORMALIZED:
+         {
+            const GLuint ln = (GLuint) state[2];
+            COPY_4V(value, ctx->Light.Light[ln]._Position);
+            NORMALIZE_3FV( value );
+         }
+         return;
+
+      case STATE_LIGHT_HALF_VECTOR:
+         {
+            const GLuint ln = (GLuint) state[2];
+            GLfloat p[3];
+            /* Compute infinite half angle vector:
+             *   halfVector = normalize(normalize(lightPos) + (0, 0, 1))
+             * light.EyePosition.w should be 0 for infinite lights.
+             */
+            COPY_3V(p, ctx->Light.Light[ln]._Position);
+            NORMALIZE_3FV(p);
+            ADD_3V(value, p, ctx->_EyeZDir);
+            NORMALIZE_3FV(value);
+            value[3] = 1.0;
+         }
+         return;
+
+      case STATE_PT_SCALE:
+         value[0] = ctx->Pixel.RedScale;
+         value[1] = ctx->Pixel.GreenScale;
+         value[2] = ctx->Pixel.BlueScale;
+         value[3] = ctx->Pixel.AlphaScale;
+         return;
+
+      case STATE_PT_BIAS:
+         value[0] = ctx->Pixel.RedBias;
+         value[1] = ctx->Pixel.GreenBias;
+         value[2] = ctx->Pixel.BlueBias;
+         value[3] = ctx->Pixel.AlphaBias;
+         return;
+
+      case STATE_PCM_SCALE:
+         COPY_4V(value, ctx->Pixel.PostColorMatrixScale);
+         return;
+
+      case STATE_PCM_BIAS:
+         COPY_4V(value, ctx->Pixel.PostColorMatrixBias);
+         return;
+
+      case STATE_SHADOW_AMBIENT:
+         {
+            const int unit = (int) state[2];
+            const struct gl_texture_object *texObj
+               = ctx->Texture.Unit[unit]._Current;
+            if (texObj) {
+               value[0] =
+               value[1] =
+               value[2] =
+               value[3] = texObj->CompareFailValue;
+            }
+         }
+         return;
+
+      case STATE_FB_SIZE:
+         value[0] = (GLfloat) (ctx->DrawBuffer->Width - 1);
+         value[1] = (GLfloat) (ctx->DrawBuffer->Height - 1);
+         value[2] = 0.0F;
+         value[3] = 0.0F;
+         return;
+
+      case STATE_ROT_MATRIX_0:
+         {
+            const int unit = (int) state[2];
+            GLfloat *rotMat22 = ctx->Texture.Unit[unit].RotMatrix;
+            value[0] = rotMat22[0]; 
+            value[1] = rotMat22[2];
+            value[2] = 0.0;
+            value[3] = 0.0;
+         }
+         return;
+
+      case STATE_ROT_MATRIX_1:
+         {
+            const int unit = (int) state[2];
+            GLfloat *rotMat22 = ctx->Texture.Unit[unit].RotMatrix;
+            value[0] = rotMat22[1];
+            value[1] = rotMat22[3];
+            value[2] = 0.0;
+            value[3] = 0.0;
+         }
+         return;
+
+      /* XXX: make sure new tokens added here are also handled in the 
+       * _mesa_program_state_flags() switch, below.
+       */
+      default:
+         /* Unknown state indexes are silently ignored here.
+          * Drivers may do something special.
+          */
+         return;
+      }
+      return;
+
+   default:
+      _mesa_problem(ctx, "Invalid state in _mesa_fetch_state");
+      return;
+   }
+}
+
+
+/**
+ * Return a bitmask of the Mesa state flags (_NEW_* values) which would
+ * indicate that the given context state may have changed.
+ * The bitmask is used during validation to determine if we need to update
+ * vertex/fragment program parameters (like "state.material.color") when
+ * some GL state has changed.
+ */
+GLbitfield
+_mesa_program_state_flags(const gl_state_index state[STATE_LENGTH])
+{
+   switch (state[0]) {
+   case STATE_MATERIAL:
+   case STATE_LIGHT:
+   case STATE_LIGHTMODEL_AMBIENT:
+   case STATE_LIGHTMODEL_SCENECOLOR:
+   case STATE_LIGHTPROD:
+      return _NEW_LIGHT;
+
+   case STATE_TEXGEN:
+   case STATE_TEXENV_COLOR:
+      return _NEW_TEXTURE;
+
+   case STATE_FOG_COLOR:
+   case STATE_FOG_PARAMS:
+      return _NEW_FOG;
+
+   case STATE_CLIPPLANE:
+      return _NEW_TRANSFORM;
+
+   case STATE_POINT_SIZE:
+   case STATE_POINT_ATTENUATION:
+      return _NEW_POINT;
+
+   case STATE_MODELVIEW_MATRIX:
+      return _NEW_MODELVIEW;
+   case STATE_PROJECTION_MATRIX:
+      return _NEW_PROJECTION;
+   case STATE_MVP_MATRIX:
+      return _NEW_MODELVIEW | _NEW_PROJECTION;
+   case STATE_TEXTURE_MATRIX:
+      return _NEW_TEXTURE_MATRIX;
+   case STATE_PROGRAM_MATRIX:
+      return _NEW_TRACK_MATRIX;
+   case STATE_COLOR_MATRIX:
+      return _NEW_COLOR_MATRIX;
+
+   case STATE_DEPTH_RANGE:
+      return _NEW_VIEWPORT;
+
+   case STATE_FRAGMENT_PROGRAM:
+   case STATE_VERTEX_PROGRAM:
+      return _NEW_PROGRAM;
+
+   case STATE_NORMAL_SCALE:
+      return _NEW_MODELVIEW;
+
+   case STATE_INTERNAL:
+      switch (state[1]) {
+      case STATE_CURRENT_ATTRIB:
+         return _NEW_CURRENT_ATTRIB;
+
+      case STATE_NORMAL_SCALE:
+         return _NEW_MODELVIEW;
+
+      case STATE_TEXRECT_SCALE:
+      case STATE_SHADOW_AMBIENT:
+      case STATE_ROT_MATRIX_0:
+      case STATE_ROT_MATRIX_1:
+        return _NEW_TEXTURE;
+      case STATE_FOG_PARAMS_OPTIMIZED:
+        return _NEW_FOG;
+      case STATE_POINT_SIZE_CLAMPED:
+      case STATE_POINT_SIZE_IMPL_CLAMP:
+         return _NEW_POINT | _NEW_MULTISAMPLE;
+      case STATE_LIGHT_SPOT_DIR_NORMALIZED:
+      case STATE_LIGHT_POSITION:
+      case STATE_LIGHT_POSITION_NORMALIZED:
+      case STATE_LIGHT_HALF_VECTOR:
+         return _NEW_LIGHT;
+
+      case STATE_PT_SCALE:
+      case STATE_PT_BIAS:
+      case STATE_PCM_SCALE:
+      case STATE_PCM_BIAS:
+         return _NEW_PIXEL;
+
+      case STATE_FB_SIZE:
+         return _NEW_BUFFERS;
+
+      default:
+         /* unknown state indexes are silently ignored and
+         *  no flag set, since it is handled by the driver.
+         */
+        return 0;
+      }
+
+   default:
+      _mesa_problem(NULL, "unexpected state[0] in make_state_flags()");
+      return 0;
+   }
+}
+
+
+static void
+append(char *dst, const char *src)
+{
+   while (*dst)
+      dst++;
+   while (*src)
+     *dst++ = *src++;
+   *dst = 0;
+}
+
+
+/**
+ * Convert token 'k' to a string, append it onto 'dst' string.
+ */
+static void
+append_token(char *dst, gl_state_index k)
+{
+   switch (k) {
+   case STATE_MATERIAL:
+      append(dst, "material");
+      break;
+   case STATE_LIGHT:
+      append(dst, "light");
+      break;
+   case STATE_LIGHTMODEL_AMBIENT:
+      append(dst, "lightmodel.ambient");
+      break;
+   case STATE_LIGHTMODEL_SCENECOLOR:
+      break;
+   case STATE_LIGHTPROD:
+      append(dst, "lightprod");
+      break;
+   case STATE_TEXGEN:
+      append(dst, "texgen");
+      break;
+   case STATE_FOG_COLOR:
+      append(dst, "fog.color");
+      break;
+   case STATE_FOG_PARAMS:
+      append(dst, "fog.params");
+      break;
+   case STATE_CLIPPLANE:
+      append(dst, "clip");
+      break;
+   case STATE_POINT_SIZE:
+      append(dst, "point.size");
+      break;
+   case STATE_POINT_ATTENUATION:
+      append(dst, "point.attenuation");
+      break;
+   case STATE_MODELVIEW_MATRIX:
+      append(dst, "matrix.modelview");
+      break;
+   case STATE_PROJECTION_MATRIX:
+      append(dst, "matrix.projection");
+      break;
+   case STATE_MVP_MATRIX:
+      append(dst, "matrix.mvp");
+      break;
+   case STATE_TEXTURE_MATRIX:
+      append(dst, "matrix.texture");
+      break;
+   case STATE_PROGRAM_MATRIX:
+      append(dst, "matrix.program");
+      break;
+   case STATE_COLOR_MATRIX:
+      append(dst, "matrix.color");
+      break;
+   case STATE_MATRIX_INVERSE:
+      append(dst, ".inverse");
+      break;
+   case STATE_MATRIX_TRANSPOSE:
+      append(dst, ".transpose");
+      break;
+   case STATE_MATRIX_INVTRANS:
+      append(dst, ".invtrans");
+      break;
+   case STATE_AMBIENT:
+      append(dst, ".ambient");
+      break;
+   case STATE_DIFFUSE:
+      append(dst, ".diffuse");
+      break;
+   case STATE_SPECULAR:
+      append(dst, ".specular");
+      break;
+   case STATE_EMISSION:
+      append(dst, ".emission");
+      break;
+   case STATE_SHININESS:
+      append(dst, "lshininess");
+      break;
+   case STATE_HALF_VECTOR:
+      append(dst, ".half");
+      break;
+   case STATE_POSITION:
+      append(dst, ".position");
+      break;
+   case STATE_ATTENUATION:
+      append(dst, ".attenuation");
+      break;
+   case STATE_SPOT_DIRECTION:
+      append(dst, ".spot.direction");
+      break;
+   case STATE_SPOT_CUTOFF:
+      append(dst, ".spot.cutoff");
+      break;
+   case STATE_TEXGEN_EYE_S:
+      append(dst, ".eye.s");
+      break;
+   case STATE_TEXGEN_EYE_T:
+      append(dst, ".eye.t");
+      break;
+   case STATE_TEXGEN_EYE_R:
+      append(dst, ".eye.r");
+      break;
+   case STATE_TEXGEN_EYE_Q:
+      append(dst, ".eye.q");
+      break;
+   case STATE_TEXGEN_OBJECT_S:
+      append(dst, ".object.s");
+      break;
+   case STATE_TEXGEN_OBJECT_T:
+      append(dst, ".object.t");
+      break;
+   case STATE_TEXGEN_OBJECT_R:
+      append(dst, ".object.r");
+      break;
+   case STATE_TEXGEN_OBJECT_Q:
+      append(dst, ".object.q");
+      break;
+   case STATE_TEXENV_COLOR:
+      append(dst, "texenv");
+      break;
+   case STATE_DEPTH_RANGE:
+      append(dst, "depth.range");
+      break;
+   case STATE_VERTEX_PROGRAM:
+   case STATE_FRAGMENT_PROGRAM:
+      break;
+   case STATE_ENV:
+      append(dst, "env");
+      break;
+   case STATE_LOCAL:
+      append(dst, "local");
+      break;
+   /* BEGIN internal state vars */
+   case STATE_INTERNAL:
+      append(dst, ".internal.");
+      break;
+   case STATE_CURRENT_ATTRIB:
+      append(dst, "current");
+      break;
+   case STATE_NORMAL_SCALE:
+      append(dst, "normalScale");
+      break;
+   case STATE_TEXRECT_SCALE:
+      append(dst, "texrectScale");
+      break;
+   case STATE_FOG_PARAMS_OPTIMIZED:
+      append(dst, "fogParamsOptimized");
+      break;
+   case STATE_POINT_SIZE_CLAMPED:
+      append(dst, "pointSizeClamped");
+      break;
+   case STATE_POINT_SIZE_IMPL_CLAMP:
+      append(dst, "pointSizeImplClamp");
+      break;
+   case STATE_LIGHT_SPOT_DIR_NORMALIZED:
+      append(dst, "lightSpotDirNormalized");
+      break;
+   case STATE_LIGHT_POSITION:
+      append(dst, "lightPosition");
+      break;
+   case STATE_LIGHT_POSITION_NORMALIZED:
+      append(dst, "light.position.normalized");
+      break;
+   case STATE_LIGHT_HALF_VECTOR:
+      append(dst, "lightHalfVector");
+      break;
+   case STATE_PT_SCALE:
+      append(dst, "PTscale");
+      break;
+   case STATE_PT_BIAS:
+      append(dst, "PTbias");
+      break;
+   case STATE_PCM_SCALE:
+      append(dst, "PCMscale");
+      break;
+   case STATE_PCM_BIAS:
+      append(dst, "PCMbias");
+      break;
+   case STATE_SHADOW_AMBIENT:
+      append(dst, "CompareFailValue");
+      break;
+   case STATE_FB_SIZE:
+      append(dst, "FbSize");
+      break;
+   case STATE_ROT_MATRIX_0:
+      append(dst, "rotMatrixRow0");
+      break;
+   case STATE_ROT_MATRIX_1:
+      append(dst, "rotMatrixRow1");
+      break;
+   default:
+      /* probably STATE_INTERNAL_DRIVER+i (driver private state) */
+      append(dst, "driverState");
+   }
+}
+
+static void
+append_face(char *dst, GLint face)
+{
+   if (face == 0)
+      append(dst, "front.");
+   else
+      append(dst, "back.");
+}
+
+static void
+append_index(char *dst, GLint index)
+{
+   char s[20];
+   sprintf(s, "[%d]", index);
+   append(dst, s);
+}
+
+/**
+ * Make a string from the given state vector.
+ * For example, return "state.matrix.texture[2].inverse".
+ * Use free() to deallocate the string.
+ */
+char *
+_mesa_program_state_string(const gl_state_index state[STATE_LENGTH])
+{
+   char str[1000] = "";
+   char tmp[30];
+
+   append(str, "state.");
+   append_token(str, state[0]);
+
+   switch (state[0]) {
+   case STATE_MATERIAL:
+      append_face(str, state[1]);
+      append_token(str, state[2]);
+      break;
+   case STATE_LIGHT:
+      append_index(str, state[1]); /* light number [i]. */
+      append_token(str, state[2]); /* coefficients */
+      break;
+   case STATE_LIGHTMODEL_AMBIENT:
+      append(str, "lightmodel.ambient");
+      break;
+   case STATE_LIGHTMODEL_SCENECOLOR:
+      if (state[1] == 0) {
+         append(str, "lightmodel.front.scenecolor");
+      }
+      else {
+         append(str, "lightmodel.back.scenecolor");
+      }
+      break;
+   case STATE_LIGHTPROD:
+      append_index(str, state[1]); /* light number [i]. */
+      append_face(str, state[2]);
+      append_token(str, state[3]);
+      break;
+   case STATE_TEXGEN:
+      append_index(str, state[1]); /* tex unit [i] */
+      append_token(str, state[2]); /* plane coef */
+      break;
+   case STATE_TEXENV_COLOR:
+      append_index(str, state[1]); /* tex unit [i] */
+      append(str, "color");
+      break;
+   case STATE_CLIPPLANE:
+      append_index(str, state[1]); /* plane [i] */
+      append(str, ".plane");
+      break;
+   case STATE_MODELVIEW_MATRIX:
+   case STATE_PROJECTION_MATRIX:
+   case STATE_MVP_MATRIX:
+   case STATE_TEXTURE_MATRIX:
+   case STATE_PROGRAM_MATRIX:
+   case STATE_COLOR_MATRIX:
+      {
+         /* state[0] = modelview, projection, texture, etc. */
+         /* state[1] = which texture matrix or program matrix */
+         /* state[2] = first row to fetch */
+         /* state[3] = last row to fetch */
+         /* state[4] = transpose, inverse or invtrans */
+         const gl_state_index mat = state[0];
+         const GLuint index = (GLuint) state[1];
+         const GLuint firstRow = (GLuint) state[2];
+         const GLuint lastRow = (GLuint) state[3];
+         const gl_state_index modifier = state[4];
+         if (index ||
+             mat == STATE_TEXTURE_MATRIX ||
+             mat == STATE_PROGRAM_MATRIX)
+            append_index(str, index);
+         if (modifier)
+            append_token(str, modifier);
+         if (firstRow == lastRow)
+            sprintf(tmp, ".row[%d]", firstRow);
+         else
+            sprintf(tmp, ".row[%d..%d]", firstRow, lastRow);
+         append(str, tmp);
+      }
+      break;
+   case STATE_POINT_SIZE:
+      break;
+   case STATE_POINT_ATTENUATION:
+      break;
+   case STATE_FOG_PARAMS:
+      break;
+   case STATE_FOG_COLOR:
+      break;
+   case STATE_DEPTH_RANGE:
+      break;
+   case STATE_FRAGMENT_PROGRAM:
+   case STATE_VERTEX_PROGRAM:
+      /* state[1] = {STATE_ENV, STATE_LOCAL} */
+      /* state[2] = parameter index          */
+      append_token(str, state[1]);
+      append_index(str, state[2]);
+      break;
+   case STATE_INTERNAL:
+      append_token(str, state[1]);
+      if (state[1] == STATE_CURRENT_ATTRIB)
+         append_index(str, state[2]);
+       break;
+   default:
+      _mesa_problem(NULL, "Invalid state in _mesa_program_state_string");
+      break;
+   }
+
+   return _mesa_strdup(str);
+}
+
+
+/**
+ * Loop over all the parameters in a parameter list.  If the parameter
+ * is a GL state reference, look up the current value of that state
+ * variable and put it into the parameter's Value[4] array.
+ * This would be called at glBegin time when using a fragment program.
+ */
+void
+_mesa_load_state_parameters(GLcontext *ctx,
+                            struct gl_program_parameter_list *paramList)
+{
+   GLuint i;
+
+   if (!paramList)
+      return;
+
+   /*assert(ctx->Driver.NeedFlush == 0);*/
+
+   for (i = 0; i < paramList->NumParameters; i++) {
+      if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) {
+         _mesa_fetch_state(ctx,
+                          (gl_state_index *) paramList->Parameters[i].StateIndexes,
+                           paramList->ParameterValues[i]);
+      }
+   }
+}
+
+
+/**
+ * Copy the 16 elements of a matrix into four consecutive program
+ * registers starting at 'pos'.
+ */
+static void
+load_matrix(GLfloat registers[][4], GLuint pos, const GLfloat mat[16])
+{
+   GLuint i;
+   for (i = 0; i < 4; i++) {
+      registers[pos + i][0] = mat[0 + i];
+      registers[pos + i][1] = mat[4 + i];
+      registers[pos + i][2] = mat[8 + i];
+      registers[pos + i][3] = mat[12 + i];
+   }
+}
+
+
+/**
+ * As above, but transpose the matrix.
+ */
+static void
+load_transpose_matrix(GLfloat registers[][4], GLuint pos,
+                      const GLfloat mat[16])
+{
+   memcpy(registers[pos], mat, 16 * sizeof(GLfloat));
+}
+
+
+/**
+ * Load current vertex program's parameter registers with tracked
+ * matrices (if NV program).  This only needs to be done per
+ * glBegin/glEnd, not per-vertex.
+ */
+void
+_mesa_load_tracked_matrices(GLcontext *ctx)
+{
+   GLuint i;
+
+   for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) {
+      /* point 'mat' at source matrix */
+      GLmatrix *mat;
+      if (ctx->VertexProgram.TrackMatrix[i] == GL_MODELVIEW) {
+         mat = ctx->ModelviewMatrixStack.Top;
+      }
+      else if (ctx->VertexProgram.TrackMatrix[i] == GL_PROJECTION) {
+         mat = ctx->ProjectionMatrixStack.Top;
+      }
+      else if (ctx->VertexProgram.TrackMatrix[i] == GL_TEXTURE) {
+         GLuint unit = MIN2(ctx->Texture.CurrentUnit,
+                            Elements(ctx->TextureMatrixStack) - 1);
+         mat = ctx->TextureMatrixStack[unit].Top;
+      }
+      else if (ctx->VertexProgram.TrackMatrix[i] == GL_COLOR) {
+         mat = ctx->ColorMatrixStack.Top;
+      }
+      else if (ctx->VertexProgram.TrackMatrix[i]==GL_MODELVIEW_PROJECTION_NV) {
+         /* XXX verify the combined matrix is up to date */
+         mat = &ctx->_ModelProjectMatrix;
+      }
+      else if (ctx->VertexProgram.TrackMatrix[i] >= GL_MATRIX0_NV &&
+               ctx->VertexProgram.TrackMatrix[i] <= GL_MATRIX7_NV) {
+         GLuint n = ctx->VertexProgram.TrackMatrix[i] - GL_MATRIX0_NV;
+         ASSERT(n < Elements(ctx->ProgramMatrixStack));
+         mat = ctx->ProgramMatrixStack[n].Top;
+      }
+      else {
+         /* no matrix is tracked, but we leave the register values as-is */
+         assert(ctx->VertexProgram.TrackMatrix[i] == GL_NONE);
+         continue;
+      }
+
+      /* load the matrix values into sequential registers */
+      if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_IDENTITY_NV) {
+         load_matrix(ctx->VertexProgram.Parameters, i*4, mat->m);
+      }
+      else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_INVERSE_NV) {
+         _math_matrix_analyse(mat); /* update the inverse */
+         ASSERT(!_math_matrix_is_dirty(mat));
+         load_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv);
+      }
+      else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_TRANSPOSE_NV) {
+         load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->m);
+      }
+      else {
+         assert(ctx->VertexProgram.TrackMatrixTransform[i]
+                == GL_INVERSE_TRANSPOSE_NV);
+         _math_matrix_analyse(mat); /* update the inverse */
+         ASSERT(!_math_matrix_is_dirty(mat));
+         load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv);
+      }
+   }
+}
diff --git a/src/mesa/program/prog_statevars.h b/src/mesa/program/prog_statevars.h
new file mode 100644 (file)
index 0000000..1753471
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * 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.
+ */
+
+#ifndef PROG_STATEVARS_H
+#define PROG_STATEVARS_H
+
+#include "main/mtypes.h"
+
+
+/**
+ * Number of STATE_* values we need to address any GL state.
+ * Used to dimension arrays.
+ */
+#define STATE_LENGTH 5
+
+
+/**
+ * Used for describing GL state referenced from inside ARB vertex and
+ * fragment programs.
+ * A string such as "state.light[0].ambient" gets translated into a
+ * sequence of tokens such as [ STATE_LIGHT, 0, STATE_AMBIENT ].
+ *
+ * For state that's an array, like STATE_CLIPPLANE, the 2nd token [1] should
+ * always be the array index.
+ */
+typedef enum gl_state_index_ {
+   STATE_MATERIAL = 100,  /* start at 100 so small ints are seen as ints */
+
+   STATE_LIGHT,
+   STATE_LIGHTMODEL_AMBIENT,
+   STATE_LIGHTMODEL_SCENECOLOR,
+   STATE_LIGHTPROD,
+
+   STATE_TEXGEN,
+
+   STATE_FOG_COLOR,
+   STATE_FOG_PARAMS,
+
+   STATE_CLIPPLANE,
+
+   STATE_POINT_SIZE,
+   STATE_POINT_ATTENUATION,
+
+   STATE_MODELVIEW_MATRIX,
+   STATE_PROJECTION_MATRIX,
+   STATE_MVP_MATRIX,
+   STATE_TEXTURE_MATRIX,
+   STATE_PROGRAM_MATRIX,
+   STATE_COLOR_MATRIX,
+   STATE_MATRIX_INVERSE,
+   STATE_MATRIX_TRANSPOSE,
+   STATE_MATRIX_INVTRANS,
+
+   STATE_AMBIENT,
+   STATE_DIFFUSE,
+   STATE_SPECULAR,
+   STATE_EMISSION,
+   STATE_SHININESS,
+   STATE_HALF_VECTOR,
+
+   STATE_POSITION,       /**< xyzw = position */
+   STATE_ATTENUATION,    /**< xyz = attenuation, w = spot exponent */
+   STATE_SPOT_DIRECTION, /**< xyz = direction, w = cos(cutoff) */
+   STATE_SPOT_CUTOFF,    /**< x = cutoff, yzw = undefined */
+
+   STATE_TEXGEN_EYE_S,
+   STATE_TEXGEN_EYE_T,
+   STATE_TEXGEN_EYE_R,
+   STATE_TEXGEN_EYE_Q,
+   STATE_TEXGEN_OBJECT_S,
+   STATE_TEXGEN_OBJECT_T,
+   STATE_TEXGEN_OBJECT_R,
+   STATE_TEXGEN_OBJECT_Q,
+
+   STATE_TEXENV_COLOR,
+
+   STATE_DEPTH_RANGE,
+
+   STATE_VERTEX_PROGRAM,
+   STATE_FRAGMENT_PROGRAM,
+
+   STATE_ENV,
+   STATE_LOCAL,
+
+   STATE_INTERNAL,             /* Mesa additions */
+   STATE_CURRENT_ATTRIB,        /* ctx->Current vertex attrib value */
+   STATE_NORMAL_SCALE,
+   STATE_TEXRECT_SCALE,
+   STATE_FOG_PARAMS_OPTIMIZED,  /* for faster fog calc */
+   STATE_POINT_SIZE_CLAMPED,    /* includes implementation dependent size clamp */
+   STATE_POINT_SIZE_IMPL_CLAMP, /* for implementation clamp only in vs */
+   STATE_LIGHT_SPOT_DIR_NORMALIZED,   /* pre-normalized spot dir */
+   STATE_LIGHT_POSITION,              /* object vs eye space */
+   STATE_LIGHT_POSITION_NORMALIZED,   /* object vs eye space */
+   STATE_LIGHT_HALF_VECTOR,           /* object vs eye space */
+   STATE_PT_SCALE,              /**< Pixel transfer RGBA scale */
+   STATE_PT_BIAS,               /**< Pixel transfer RGBA bias */
+   STATE_PCM_SCALE,             /**< Post color matrix RGBA scale */
+   STATE_PCM_BIAS,              /**< Post color matrix RGBA bias */
+   STATE_SHADOW_AMBIENT,        /**< ARB_shadow_ambient fail value; token[2] is texture unit index */
+   STATE_FB_SIZE,               /**< (width-1, height-1, 0, 0) */
+   STATE_ROT_MATRIX_0,          /**< ATI_envmap_bumpmap, rot matrix row 0 */
+   STATE_ROT_MATRIX_1,          /**< ATI_envmap_bumpmap, rot matrix row 1 */
+   STATE_INTERNAL_DRIVER       /* first available state index for drivers (must be last) */
+} gl_state_index;
+
+
+
+extern void
+_mesa_load_state_parameters(GLcontext *ctx,
+                            struct gl_program_parameter_list *paramList);
+
+
+extern GLbitfield
+_mesa_program_state_flags(const gl_state_index state[STATE_LENGTH]);
+
+
+extern char *
+_mesa_program_state_string(const gl_state_index state[STATE_LENGTH]);
+
+
+extern void
+_mesa_load_tracked_matrices(GLcontext *ctx);
+
+
+#endif /* PROG_STATEVARS_H */
diff --git a/src/mesa/program/prog_uniform.c b/src/mesa/program/prog_uniform.c
new file mode 100644 (file)
index 0000000..5aa9878
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.1
+ *
+ * Copyright (C) 1999-2008  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 prog_uniform.c
+ * Shader uniform functions.
+ * \author Brian Paul
+ */
+
+#include "main/imports.h"
+#include "main/mtypes.h"
+#include "prog_uniform.h"
+
+
+struct gl_uniform_list *
+_mesa_new_uniform_list(void)
+{
+   return CALLOC_STRUCT(gl_uniform_list);
+}
+
+
+void
+_mesa_free_uniform_list(struct gl_uniform_list *list)
+{
+   GLuint i;
+   for (i = 0; i < list->NumUniforms; i++) {
+      free((void *) list->Uniforms[i].Name);
+   }
+   free(list->Uniforms);
+   free(list);
+}
+
+
+struct gl_uniform *
+_mesa_append_uniform(struct gl_uniform_list *list,
+                     const char *name, GLenum target, GLuint progPos)
+{
+   const GLuint oldNum = list->NumUniforms;
+   struct gl_uniform *uniform;
+   GLint index;
+
+   assert(target == GL_VERTEX_PROGRAM_ARB ||
+          target == GL_FRAGMENT_PROGRAM_ARB ||
+          target == MESA_GEOMETRY_PROGRAM);
+
+   index = _mesa_lookup_uniform(list, name);
+   if (index < 0) {
+      /* not found - append to list */
+
+      if (oldNum + 1 > list->Size) {
+         /* Need to grow the list array (alloc some extra) */
+         list->Size += 4;
+
+         /* realloc arrays */
+         list->Uniforms = (struct gl_uniform *)
+            _mesa_realloc(list->Uniforms,
+                          oldNum * sizeof(struct gl_uniform),
+                          list->Size * sizeof(struct gl_uniform));
+      }
+
+      if (!list->Uniforms) {
+         /* out of memory */
+         list->NumUniforms = 0;
+         list->Size = 0;
+         return GL_FALSE;
+      }
+
+      uniform = list->Uniforms + oldNum;
+
+      uniform->Name = _mesa_strdup(name);
+      uniform->VertPos = -1;
+      uniform->FragPos = -1;
+      uniform->GeomPos = -1;
+      uniform->Initialized = GL_FALSE;
+
+      list->NumUniforms++;
+   }
+   else {
+      /* found */
+      uniform = list->Uniforms + index;
+   }
+
+   /* update position for the vertex or fragment program */
+   if (target == GL_VERTEX_PROGRAM_ARB) {
+      if (uniform->VertPos != -1) {
+         /* this uniform is already in the list - that shouldn't happen */
+         return GL_FALSE;
+      }
+      uniform->VertPos = progPos;
+   } else if (target == GL_FRAGMENT_PROGRAM_ARB) {
+      if (uniform->FragPos != -1) {
+         /* this uniform is already in the list - that shouldn't happen */
+         return GL_FALSE;
+      }
+      uniform->FragPos = progPos;
+   } else {
+      if (uniform->GeomPos != -1) {
+         /* this uniform is already in the list - that shouldn't happen */
+         return GL_FALSE;
+      }
+      uniform->GeomPos = progPos;
+   }
+
+   return uniform;
+}
+
+
+/**
+ * Return the location/index of the named uniform in the uniform list,
+ * or -1 if not found.
+ */
+GLint
+_mesa_lookup_uniform(const struct gl_uniform_list *list, const char *name)
+{
+   GLuint i;
+   for (i = 0; list && i < list->NumUniforms; i++) {
+      if (!strcmp(list->Uniforms[i].Name, name)) {
+         return i;
+      }
+   }
+   return -1;
+}
+
+
+GLint
+_mesa_longest_uniform_name(const struct gl_uniform_list *list)
+{
+   GLint max = 0;
+   GLuint i;
+   for (i = 0; list && i < list->NumUniforms; i++) {
+      GLint len = (GLint) strlen(list->Uniforms[i].Name);
+      if (len > max)
+         max = len;
+   }
+   return max;
+}
+
+
+void
+_mesa_print_uniforms(const struct gl_uniform_list *list)
+{
+   GLuint i;
+   printf("Uniform list %p:\n", (void *) list);
+   for (i = 0; i < list->NumUniforms; i++) {
+      printf("%d: %s %d %d %d\n",
+             i,
+             list->Uniforms[i].Name,
+             list->Uniforms[i].VertPos,
+             list->Uniforms[i].FragPos,
+             list->Uniforms[i].GeomPos);
+   }
+}
diff --git a/src/mesa/program/prog_uniform.h b/src/mesa/program/prog_uniform.h
new file mode 100644 (file)
index 0000000..a671d30
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.1
+ *
+ * Copyright (C) 1999-2008  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 prog_uniform.c
+ * Shader uniform functions.
+ * \author Brian Paul
+ */
+
+#ifndef PROG_UNIFORM_H
+#define PROG_UNIFORM_H
+
+#include "main/mtypes.h"
+#include "prog_statevars.h"
+
+
+/**
+ * Shader program uniform variable.
+ * The glGetUniformLocation() and glUniform() commands will use this
+ * information.
+ * Note that a uniform such as "binormal" might be used in both the
+ * vertex shader and the fragment shader.  When glUniform() is called to
+ * set the uniform's value, it must be updated in both the vertex and
+ * fragment shaders.  The uniform may be in different locations in the
+ * two shaders so we keep track of that here.
+ */
+struct gl_uniform
+{
+   const char *Name;        /**< Null-terminated string */
+   GLint VertPos;
+   GLint FragPos;
+   GLint GeomPos;
+   GLboolean Initialized;   /**< For debug.  Has this uniform been set? */
+#if 0
+   GLenum DataType;         /**< GL_FLOAT, GL_FLOAT_VEC2, etc */
+   GLuint Size;             /**< Number of components (1..4) */
+#endif
+};
+
+
+/**
+ * List of gl_uniforms
+ */
+struct gl_uniform_list
+{
+   GLuint Size;                 /**< allocated size of Uniforms array */
+   GLuint NumUniforms;          /**< number of uniforms in the array */
+   struct gl_uniform *Uniforms; /**< Array [Size] */
+};
+
+
+extern struct gl_uniform_list *
+_mesa_new_uniform_list(void);
+
+extern void
+_mesa_free_uniform_list(struct gl_uniform_list *list);
+
+extern struct gl_uniform *
+_mesa_append_uniform(struct gl_uniform_list *list,
+                     const char *name, GLenum target, GLuint progPos);
+
+extern GLint
+_mesa_lookup_uniform(const struct gl_uniform_list *list, const char *name);
+
+extern GLint
+_mesa_longest_uniform_name(const struct gl_uniform_list *list);
+
+extern void
+_mesa_print_uniforms(const struct gl_uniform_list *list);
+
+
+#endif /* PROG_UNIFORM_H */
diff --git a/src/mesa/program/program.c b/src/mesa/program/program.c
new file mode 100644 (file)
index 0000000..cf46095
--- /dev/null
@@ -0,0 +1,963 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.3
+ *
+ * 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 program.c
+ * Vertex and fragment program support functions.
+ * \author Brian Paul
+ */
+
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/hash.h"
+#include "program.h"
+#include "prog_cache.h"
+#include "prog_parameter.h"
+#include "prog_instruction.h"
+
+
+/**
+ * A pointer to this dummy program is put into the hash table when
+ * glGenPrograms is called.
+ */
+struct gl_program _mesa_DummyProgram;
+
+
+/**
+ * Init context's vertex/fragment program state
+ */
+void
+_mesa_init_program(GLcontext *ctx)
+{
+   GLuint i;
+
+   /*
+    * If this assertion fails, we need to increase the field
+    * size for register indexes.
+    */
+   ASSERT(ctx->Const.VertexProgram.MaxUniformComponents / 4
+          <= (1 << INST_INDEX_BITS));
+   ASSERT(ctx->Const.FragmentProgram.MaxUniformComponents / 4
+          <= (1 << INST_INDEX_BITS));
+
+   /* If this fails, increase prog_instruction::TexSrcUnit size */
+   ASSERT(MAX_TEXTURE_UNITS < (1 << 5));
+
+   /* If this fails, increase prog_instruction::TexSrcTarget size */
+   ASSERT(NUM_TEXTURE_TARGETS < (1 << 3));
+
+   ctx->Program.ErrorPos = -1;
+   ctx->Program.ErrorString = _mesa_strdup("");
+
+#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
+   ctx->VertexProgram.Enabled = GL_FALSE;
+#if FEATURE_es2_glsl
+   ctx->VertexProgram.PointSizeEnabled =
+      (ctx->API == API_OPENGLES2) ? GL_TRUE : GL_FALSE;
+#else
+   ctx->VertexProgram.PointSizeEnabled = GL_FALSE;
+#endif
+   ctx->VertexProgram.TwoSideEnabled = GL_FALSE;
+   _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
+                            ctx->Shared->DefaultVertexProgram);
+   assert(ctx->VertexProgram.Current);
+   for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) {
+      ctx->VertexProgram.TrackMatrix[i] = GL_NONE;
+      ctx->VertexProgram.TrackMatrixTransform[i] = GL_IDENTITY_NV;
+   }
+   ctx->VertexProgram.Cache = _mesa_new_program_cache();
+#endif
+
+#if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program
+   ctx->FragmentProgram.Enabled = GL_FALSE;
+   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
+                            ctx->Shared->DefaultFragmentProgram);
+   assert(ctx->FragmentProgram.Current);
+   ctx->FragmentProgram.Cache = _mesa_new_program_cache();
+#endif
+
+#if FEATURE_ARB_geometry_shader4
+   ctx->GeometryProgram.Enabled = GL_FALSE;
+   /* right now by default we don't have a geometry program */
+   _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current,
+                            NULL);
+   ctx->GeometryProgram.Cache = _mesa_new_program_cache();
+#endif
+
+   /* XXX probably move this stuff */
+#if FEATURE_ATI_fragment_shader
+   ctx->ATIFragmentShader.Enabled = GL_FALSE;
+   ctx->ATIFragmentShader.Current = ctx->Shared->DefaultFragmentShader;
+   assert(ctx->ATIFragmentShader.Current);
+   ctx->ATIFragmentShader.Current->RefCount++;
+#endif
+}
+
+
+/**
+ * Free a context's vertex/fragment program state
+ */
+void
+_mesa_free_program_data(GLcontext *ctx)
+{
+#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
+   _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
+   _mesa_delete_program_cache(ctx, ctx->VertexProgram.Cache);
+#endif
+#if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program
+   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
+   _mesa_delete_program_cache(ctx, ctx->FragmentProgram.Cache);
+#endif
+#if FEATURE_ARB_geometry_shader4
+   _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current, NULL);
+   _mesa_delete_program_cache(ctx, ctx->GeometryProgram.Cache);
+#endif
+   /* XXX probably move this stuff */
+#if FEATURE_ATI_fragment_shader
+   if (ctx->ATIFragmentShader.Current) {
+      ctx->ATIFragmentShader.Current->RefCount--;
+      if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
+         free(ctx->ATIFragmentShader.Current);
+      }
+   }
+#endif
+   free((void *) ctx->Program.ErrorString);
+}
+
+
+/**
+ * Update the default program objects in the given context to reference those
+ * specified in the shared state and release those referencing the old
+ * shared state.
+ */
+void
+_mesa_update_default_objects_program(GLcontext *ctx)
+{
+#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
+   _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
+                            (struct gl_vertex_program *)
+                            ctx->Shared->DefaultVertexProgram);
+   assert(ctx->VertexProgram.Current);
+#endif
+
+#if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program
+   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
+                            (struct gl_fragment_program *)
+                            ctx->Shared->DefaultFragmentProgram);
+   assert(ctx->FragmentProgram.Current);
+#endif
+
+#if FEATURE_ARB_geometry_shader4
+   _mesa_reference_geomprog(ctx, &ctx->GeometryProgram.Current,
+                            (struct gl_geometry_program *)
+                            ctx->Shared->DefaultGeometryProgram);
+#endif
+
+   /* XXX probably move this stuff */
+#if FEATURE_ATI_fragment_shader
+   if (ctx->ATIFragmentShader.Current) {
+      ctx->ATIFragmentShader.Current->RefCount--;
+      if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
+         free(ctx->ATIFragmentShader.Current);
+      }
+   }
+   ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) ctx->Shared->DefaultFragmentShader;
+   assert(ctx->ATIFragmentShader.Current);
+   ctx->ATIFragmentShader.Current->RefCount++;
+#endif
+}
+
+
+/**
+ * Set the vertex/fragment program error state (position and error string).
+ * This is generally called from within the parsers.
+ */
+void
+_mesa_set_program_error(GLcontext *ctx, GLint pos, const char *string)
+{
+   ctx->Program.ErrorPos = pos;
+   free((void *) ctx->Program.ErrorString);
+   if (!string)
+      string = "";
+   ctx->Program.ErrorString = _mesa_strdup(string);
+}
+
+
+/**
+ * Find the line number and column for 'pos' within 'string'.
+ * Return a copy of the line which contains 'pos'.  Free the line with
+ * free().
+ * \param string  the program string
+ * \param pos     the position within the string
+ * \param line    returns the line number corresponding to 'pos'.
+ * \param col     returns the column number corresponding to 'pos'.
+ * \return copy of the line containing 'pos'.
+ */
+const GLubyte *
+_mesa_find_line_column(const GLubyte *string, const GLubyte *pos,
+                       GLint *line, GLint *col)
+{
+   const GLubyte *lineStart = string;
+   const GLubyte *p = string;
+   GLubyte *s;
+   int len;
+
+   *line = 1;
+
+   while (p != pos) {
+      if (*p == (GLubyte) '\n') {
+         (*line)++;
+         lineStart = p + 1;
+      }
+      p++;
+   }
+
+   *col = (pos - lineStart) + 1;
+
+   /* return copy of this line */
+   while (*p != 0 && *p != '\n')
+      p++;
+   len = p - lineStart;
+   s = (GLubyte *) malloc(len + 1);
+   memcpy(s, lineStart, len);
+   s[len] = 0;
+
+   return s;
+}
+
+
+/**
+ * Initialize a new vertex/fragment program object.
+ */
+static struct gl_program *
+_mesa_init_program_struct( GLcontext *ctx, struct gl_program *prog,
+                           GLenum target, GLuint id)
+{
+   (void) ctx;
+   if (prog) {
+      GLuint i;
+      memset(prog, 0, sizeof(*prog));
+      prog->Id = id;
+      prog->Target = target;
+      prog->Resident = GL_TRUE;
+      prog->RefCount = 1;
+      prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB;
+
+      /* default mapping from samplers to texture units */
+      for (i = 0; i < MAX_SAMPLERS; i++)
+         prog->SamplerUnits[i] = i;
+   }
+
+   return prog;
+}
+
+
+/**
+ * Initialize a new fragment program object.
+ */
+struct gl_program *
+_mesa_init_fragment_program( GLcontext *ctx, struct gl_fragment_program *prog,
+                             GLenum target, GLuint id)
+{
+   if (prog)
+      return _mesa_init_program_struct( ctx, &prog->Base, target, id );
+   else
+      return NULL;
+}
+
+
+/**
+ * Initialize a new vertex program object.
+ */
+struct gl_program *
+_mesa_init_vertex_program( GLcontext *ctx, struct gl_vertex_program *prog,
+                           GLenum target, GLuint id)
+{
+   if (prog)
+      return _mesa_init_program_struct( ctx, &prog->Base, target, id );
+   else
+      return NULL;
+}
+
+
+/**
+ * Initialize a new geometry program object.
+ */
+struct gl_program *
+_mesa_init_geometry_program( GLcontext *ctx, struct gl_geometry_program *prog,
+                             GLenum target, GLuint id)
+{
+   if (prog)
+      return _mesa_init_program_struct( ctx, &prog->Base, target, id );
+   else
+      return NULL;
+}
+
+
+/**
+ * Allocate and initialize a new fragment/vertex program object but
+ * don't put it into the program hash table.  Called via
+ * ctx->Driver.NewProgram.  May be overridden (ie. replaced) by a
+ * device driver function to implement OO deriviation with additional
+ * types not understood by this function.
+ *
+ * \param ctx  context
+ * \param id   program id/number
+ * \param target  program target/type
+ * \return  pointer to new program object
+ */
+struct gl_program *
+_mesa_new_program(GLcontext *ctx, GLenum target, GLuint id)
+{
+   struct gl_program *prog;
+   switch (target) {
+   case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */
+   case GL_VERTEX_STATE_PROGRAM_NV:
+      prog = _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program),
+                                       target, id );
+      break;
+   case GL_FRAGMENT_PROGRAM_NV:
+   case GL_FRAGMENT_PROGRAM_ARB:
+      prog =_mesa_init_fragment_program(ctx,
+                                         CALLOC_STRUCT(gl_fragment_program),
+                                         target, id );
+      break;
+   case MESA_GEOMETRY_PROGRAM:
+      prog = _mesa_init_geometry_program(ctx,
+                                         CALLOC_STRUCT(gl_geometry_program),
+                                         target, id);
+      break;
+   default:
+      _mesa_problem(ctx, "bad target in _mesa_new_program");
+      prog = NULL;
+   }
+   return prog;
+}
+
+
+/**
+ * Delete a program and remove it from the hash table, ignoring the
+ * reference count.
+ * Called via ctx->Driver.DeleteProgram.  May be wrapped (OO deriviation)
+ * by a device driver function.
+ */
+void
+_mesa_delete_program(GLcontext *ctx, struct gl_program *prog)
+{
+   (void) ctx;
+   ASSERT(prog);
+   ASSERT(prog->RefCount==0);
+
+   if (prog == &_mesa_DummyProgram)
+      return;
+
+   if (prog->String)
+      free(prog->String);
+
+   _mesa_free_instructions(prog->Instructions, prog->NumInstructions);
+
+   if (prog->Parameters) {
+      _mesa_free_parameter_list(prog->Parameters);
+   }
+   if (prog->Varying) {
+      _mesa_free_parameter_list(prog->Varying);
+   }
+   if (prog->Attributes) {
+      _mesa_free_parameter_list(prog->Attributes);
+   }
+
+   free(prog);
+}
+
+
+/**
+ * Return the gl_program object for a given ID.
+ * Basically just a wrapper for _mesa_HashLookup() to avoid a lot of
+ * casts elsewhere.
+ */
+struct gl_program *
+_mesa_lookup_program(GLcontext *ctx, GLuint id)
+{
+   if (id)
+      return (struct gl_program *) _mesa_HashLookup(ctx->Shared->Programs, id);
+   else
+      return NULL;
+}
+
+
+/**
+ * Reference counting for vertex/fragment programs
+ */
+void
+_mesa_reference_program(GLcontext *ctx,
+                        struct gl_program **ptr,
+                        struct gl_program *prog)
+{
+   assert(ptr);
+   if (*ptr && prog) {
+      /* sanity check */
+      if ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB)
+         ASSERT(prog->Target == GL_VERTEX_PROGRAM_ARB);
+      else if ((*ptr)->Target == GL_FRAGMENT_PROGRAM_ARB)
+         ASSERT(prog->Target == GL_FRAGMENT_PROGRAM_ARB ||
+                prog->Target == GL_FRAGMENT_PROGRAM_NV);
+      else if ((*ptr)->Target == MESA_GEOMETRY_PROGRAM)
+         ASSERT(prog->Target == MESA_GEOMETRY_PROGRAM);
+   }
+   if (*ptr == prog) {
+      return;  /* no change */
+   }
+   if (*ptr) {
+      GLboolean deleteFlag;
+
+      /*_glthread_LOCK_MUTEX((*ptr)->Mutex);*/
+#if 0
+      printf("Program %p ID=%u Target=%s  Refcount-- to %d\n",
+             *ptr, (*ptr)->Id,
+             ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB ? "VP" :
+              ((*ptr)->Target == MESA_GEOMETRY_PROGRAM ? "GP" : "FP")),
+             (*ptr)->RefCount - 1);
+#endif
+      ASSERT((*ptr)->RefCount > 0);
+      (*ptr)->RefCount--;
+
+      deleteFlag = ((*ptr)->RefCount == 0);
+      /*_glthread_UNLOCK_MUTEX((*ptr)->Mutex);*/
+
+      if (deleteFlag) {
+         ASSERT(ctx);
+         ctx->Driver.DeleteProgram(ctx, *ptr);
+      }
+
+      *ptr = NULL;
+   }
+
+   assert(!*ptr);
+   if (prog) {
+      /*_glthread_LOCK_MUTEX(prog->Mutex);*/
+      prog->RefCount++;
+#if 0
+      printf("Program %p ID=%u Target=%s  Refcount++ to %d\n",
+             prog, prog->Id,
+             (prog->Target == GL_VERTEX_PROGRAM_ARB ? "VP" :
+              (prog->Target == MESA_GEOMETRY_PROGRAM ? "GP" : "FP")),
+             prog->RefCount);
+#endif
+      /*_glthread_UNLOCK_MUTEX(prog->Mutex);*/
+   }
+
+   *ptr = prog;
+}
+
+
+/**
+ * Return a copy of a program.
+ * XXX Problem here if the program object is actually OO-derivation
+ * made by a device driver.
+ */
+struct gl_program *
+_mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)
+{
+   struct gl_program *clone;
+
+   clone = ctx->Driver.NewProgram(ctx, prog->Target, prog->Id);
+   if (!clone)
+      return NULL;
+
+   assert(clone->Target == prog->Target);
+   assert(clone->RefCount == 1);
+
+   clone->String = (GLubyte *) _mesa_strdup((char *) prog->String);
+   clone->Format = prog->Format;
+   clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions);
+   if (!clone->Instructions) {
+      _mesa_reference_program(ctx, &clone, NULL);
+      return NULL;
+   }
+   _mesa_copy_instructions(clone->Instructions, prog->Instructions,
+                           prog->NumInstructions);
+   clone->InputsRead = prog->InputsRead;
+   clone->OutputsWritten = prog->OutputsWritten;
+   clone->SamplersUsed = prog->SamplersUsed;
+   clone->ShadowSamplers = prog->ShadowSamplers;
+   memcpy(clone->TexturesUsed, prog->TexturesUsed, sizeof(prog->TexturesUsed));
+
+   if (prog->Parameters)
+      clone->Parameters = _mesa_clone_parameter_list(prog->Parameters);
+   memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams));
+   if (prog->Varying)
+      clone->Varying = _mesa_clone_parameter_list(prog->Varying);
+   if (prog->Attributes)
+      clone->Attributes = _mesa_clone_parameter_list(prog->Attributes);
+   memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams));
+   clone->NumInstructions = prog->NumInstructions;
+   clone->NumTemporaries = prog->NumTemporaries;
+   clone->NumParameters = prog->NumParameters;
+   clone->NumAttributes = prog->NumAttributes;
+   clone->NumAddressRegs = prog->NumAddressRegs;
+   clone->NumNativeInstructions = prog->NumNativeInstructions;
+   clone->NumNativeTemporaries = prog->NumNativeTemporaries;
+   clone->NumNativeParameters = prog->NumNativeParameters;
+   clone->NumNativeAttributes = prog->NumNativeAttributes;
+   clone->NumNativeAddressRegs = prog->NumNativeAddressRegs;
+   clone->NumAluInstructions = prog->NumAluInstructions;
+   clone->NumTexInstructions = prog->NumTexInstructions;
+   clone->NumTexIndirections = prog->NumTexIndirections;
+   clone->NumNativeAluInstructions = prog->NumNativeAluInstructions;
+   clone->NumNativeTexInstructions = prog->NumNativeTexInstructions;
+   clone->NumNativeTexIndirections = prog->NumNativeTexIndirections;
+
+   switch (prog->Target) {
+   case GL_VERTEX_PROGRAM_ARB:
+      {
+         const struct gl_vertex_program *vp
+            = (const struct gl_vertex_program *) prog;
+         struct gl_vertex_program *vpc = (struct gl_vertex_program *) clone;
+         vpc->IsPositionInvariant = vp->IsPositionInvariant;
+         vpc->IsNVProgram = vp->IsNVProgram;
+      }
+      break;
+   case GL_FRAGMENT_PROGRAM_ARB:
+      {
+         const struct gl_fragment_program *fp
+            = (const struct gl_fragment_program *) prog;
+         struct gl_fragment_program *fpc = (struct gl_fragment_program *) clone;
+         fpc->FogOption = fp->FogOption;
+         fpc->UsesKill = fp->UsesKill;
+         fpc->OriginUpperLeft = fp->OriginUpperLeft;
+         fpc->PixelCenterInteger = fp->PixelCenterInteger;
+      }
+      break;
+   case MESA_GEOMETRY_PROGRAM:
+      {
+         const struct gl_geometry_program *gp
+            = (const struct gl_geometry_program *) prog;
+         struct gl_geometry_program *gpc = (struct gl_geometry_program *) clone;
+         gpc->VerticesOut = gp->VerticesOut;
+         gpc->InputType = gp->InputType;
+         gpc->OutputType = gp->OutputType;
+      }
+      break;
+   default:
+      _mesa_problem(NULL, "Unexpected target in _mesa_clone_program");
+   }
+
+   return clone;
+}
+
+
+/**
+ * Insert 'count' NOP instructions at 'start' in the given program.
+ * Adjust branch targets accordingly.
+ */
+GLboolean
+_mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count)
+{
+   const GLuint origLen = prog->NumInstructions;
+   const GLuint newLen = origLen + count;
+   struct prog_instruction *newInst;
+   GLuint i;
+
+   /* adjust branches */
+   for (i = 0; i < prog->NumInstructions; i++) {
+      struct prog_instruction *inst = prog->Instructions + i;
+      if (inst->BranchTarget > 0) {
+         if ((GLuint)inst->BranchTarget >= start) {
+            inst->BranchTarget += count;
+         }
+      }
+   }
+
+   /* Alloc storage for new instructions */
+   newInst = _mesa_alloc_instructions(newLen);
+   if (!newInst) {
+      return GL_FALSE;
+   }
+
+   /* Copy 'start' instructions into new instruction buffer */
+   _mesa_copy_instructions(newInst, prog->Instructions, start);
+
+   /* init the new instructions */
+   _mesa_init_instructions(newInst + start, count);
+
+   /* Copy the remaining/tail instructions to new inst buffer */
+   _mesa_copy_instructions(newInst + start + count,
+                           prog->Instructions + start,
+                           origLen - start);
+
+   /* free old instructions */
+   _mesa_free_instructions(prog->Instructions, origLen);
+
+   /* install new instructions */
+   prog->Instructions = newInst;
+   prog->NumInstructions = newLen;
+
+   return GL_TRUE;
+}
+
+/**
+ * Delete 'count' instructions at 'start' in the given program.
+ * Adjust branch targets accordingly.
+ */
+GLboolean
+_mesa_delete_instructions(struct gl_program *prog, GLuint start, GLuint count)
+{
+   const GLuint origLen = prog->NumInstructions;
+   const GLuint newLen = origLen - count;
+   struct prog_instruction *newInst;
+   GLuint i;
+
+   /* adjust branches */
+   for (i = 0; i < prog->NumInstructions; i++) {
+      struct prog_instruction *inst = prog->Instructions + i;
+      if (inst->BranchTarget > 0) {
+         if (inst->BranchTarget > (GLint) start) {
+            inst->BranchTarget -= count;
+         }
+      }
+   }
+
+   /* Alloc storage for new instructions */
+   newInst = _mesa_alloc_instructions(newLen);
+   if (!newInst) {
+      return GL_FALSE;
+   }
+
+   /* Copy 'start' instructions into new instruction buffer */
+   _mesa_copy_instructions(newInst, prog->Instructions, start);
+
+   /* Copy the remaining/tail instructions to new inst buffer */
+   _mesa_copy_instructions(newInst + start,
+                           prog->Instructions + start + count,
+                           newLen - start);
+
+   /* free old instructions */
+   _mesa_free_instructions(prog->Instructions, origLen);
+
+   /* install new instructions */
+   prog->Instructions = newInst;
+   prog->NumInstructions = newLen;
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Search instructions for registers that match (oldFile, oldIndex),
+ * replacing them with (newFile, newIndex).
+ */
+static void
+replace_registers(struct prog_instruction *inst, GLuint numInst,
+                  GLuint oldFile, GLuint oldIndex,
+                  GLuint newFile, GLuint newIndex)
+{
+   GLuint i, j;
+   for (i = 0; i < numInst; i++) {
+      /* src regs */
+      for (j = 0; j < _mesa_num_inst_src_regs(inst[i].Opcode); j++) {
+         if (inst[i].SrcReg[j].File == oldFile &&
+             inst[i].SrcReg[j].Index == oldIndex) {
+            inst[i].SrcReg[j].File = newFile;
+            inst[i].SrcReg[j].Index = newIndex;
+         }
+      }
+      /* dst reg */
+      if (inst[i].DstReg.File == oldFile && inst[i].DstReg.Index == oldIndex) {
+         inst[i].DstReg.File = newFile;
+         inst[i].DstReg.Index = newIndex;
+      }
+   }
+}
+
+
+/**
+ * Search instructions for references to program parameters.  When found,
+ * increment the parameter index by 'offset'.
+ * Used when combining programs.
+ */
+static void
+adjust_param_indexes(struct prog_instruction *inst, GLuint numInst,
+                     GLuint offset)
+{
+   GLuint i, j;
+   for (i = 0; i < numInst; i++) {
+      for (j = 0; j < _mesa_num_inst_src_regs(inst[i].Opcode); j++) {
+         GLuint f = inst[i].SrcReg[j].File;
+         if (f == PROGRAM_CONSTANT ||
+             f == PROGRAM_UNIFORM ||
+             f == PROGRAM_STATE_VAR) {
+            inst[i].SrcReg[j].Index += offset;
+         }
+      }
+   }
+}
+
+
+/**
+ * Combine two programs into one.  Fix instructions so the outputs of
+ * the first program go to the inputs of the second program.
+ */
+struct gl_program *
+_mesa_combine_programs(GLcontext *ctx,
+                       const struct gl_program *progA,
+                       const struct gl_program *progB)
+{
+   struct prog_instruction *newInst;
+   struct gl_program *newProg;
+   const GLuint lenA = progA->NumInstructions - 1; /* omit END instr */
+   const GLuint lenB = progB->NumInstructions;
+   const GLuint numParamsA = _mesa_num_parameters(progA->Parameters);
+   const GLuint newLength = lenA + lenB;
+   GLboolean usedTemps[MAX_PROGRAM_TEMPS];
+   GLuint firstTemp = 0;
+   GLbitfield inputsB;
+   GLuint i;
+
+   ASSERT(progA->Target == progB->Target);
+
+   newInst = _mesa_alloc_instructions(newLength);
+   if (!newInst)
+      return GL_FALSE;
+
+   _mesa_copy_instructions(newInst, progA->Instructions, lenA);
+   _mesa_copy_instructions(newInst + lenA, progB->Instructions, lenB);
+
+   /* adjust branch / instruction addresses for B's instructions */
+   for (i = 0; i < lenB; i++) {
+      newInst[lenA + i].BranchTarget += lenA;
+   }
+
+   newProg = ctx->Driver.NewProgram(ctx, progA->Target, 0);
+   newProg->Instructions = newInst;
+   newProg->NumInstructions = newLength;
+
+   /* find used temp regs (we may need new temps below) */
+   _mesa_find_used_registers(newProg, PROGRAM_TEMPORARY,
+                             usedTemps, MAX_PROGRAM_TEMPS);
+
+   if (newProg->Target == GL_FRAGMENT_PROGRAM_ARB) {
+      struct gl_fragment_program *fprogA, *fprogB, *newFprog;
+      GLbitfield progB_inputsRead = progB->InputsRead;
+      GLint progB_colorFile, progB_colorIndex;
+
+      fprogA = (struct gl_fragment_program *) progA;
+      fprogB = (struct gl_fragment_program *) progB;
+      newFprog = (struct gl_fragment_program *) newProg;
+
+      newFprog->UsesKill = fprogA->UsesKill || fprogB->UsesKill;
+
+      /* We'll do a search and replace for instances
+       * of progB_colorFile/progB_colorIndex below...
+       */
+      progB_colorFile = PROGRAM_INPUT;
+      progB_colorIndex = FRAG_ATTRIB_COL0;
+
+      /*
+       * The fragment program may get color from a state var rather than
+       * a fragment input (vertex output) if it's constant.
+       * See the texenvprogram.c code.
+       * So, search the program's parameter list now to see if the program
+       * gets color from a state var instead of a conventional fragment
+       * input register.
+       */
+      for (i = 0; i < progB->Parameters->NumParameters; i++) {
+         struct gl_program_parameter *p = &progB->Parameters->Parameters[i];
+         if (p->Type == PROGRAM_STATE_VAR &&
+             p->StateIndexes[0] == STATE_INTERNAL &&
+             p->StateIndexes[1] == STATE_CURRENT_ATTRIB &&
+             p->StateIndexes[2] == VERT_ATTRIB_COLOR0) {
+            progB_inputsRead |= FRAG_BIT_COL0;
+            progB_colorFile = PROGRAM_STATE_VAR;
+            progB_colorIndex = i;
+            break;
+         }
+      }
+
+      /* Connect color outputs of fprogA to color inputs of fprogB, via a
+       * new temporary register.
+       */
+      if ((progA->OutputsWritten & (1 << FRAG_RESULT_COLOR)) &&
+          (progB_inputsRead & FRAG_BIT_COL0)) {
+         GLint tempReg = _mesa_find_free_register(usedTemps, MAX_PROGRAM_TEMPS,
+                                                  firstTemp);
+         if (tempReg < 0) {
+            _mesa_problem(ctx, "No free temp regs found in "
+                          "_mesa_combine_programs(), using 31");
+            tempReg = 31;
+         }
+         firstTemp = tempReg + 1;
+
+         /* replace writes to result.color[0] with tempReg */
+         replace_registers(newInst, lenA,
+                           PROGRAM_OUTPUT, FRAG_RESULT_COLOR,
+                           PROGRAM_TEMPORARY, tempReg);
+         /* replace reads from the input color with tempReg */
+         replace_registers(newInst + lenA, lenB,
+                           progB_colorFile, progB_colorIndex, /* search for */
+                           PROGRAM_TEMPORARY, tempReg  /* replace with */ );
+      }
+
+      /* compute combined program's InputsRead */
+      inputsB = progB_inputsRead;
+      if (progA->OutputsWritten & (1 << FRAG_RESULT_COLOR)) {
+         inputsB &= ~(1 << FRAG_ATTRIB_COL0);
+      }
+      newProg->InputsRead = progA->InputsRead | inputsB;
+      newProg->OutputsWritten = progB->OutputsWritten;
+      newProg->SamplersUsed = progA->SamplersUsed | progB->SamplersUsed;
+   }
+   else {
+      /* vertex program */
+      assert(0);      /* XXX todo */
+   }
+
+   /*
+    * Merge parameters (uniforms, constants, etc)
+    */
+   newProg->Parameters = _mesa_combine_parameter_lists(progA->Parameters,
+                                                       progB->Parameters);
+
+   adjust_param_indexes(newInst + lenA, lenB, numParamsA);
+
+
+   return newProg;
+}
+
+
+/**
+ * Populate the 'used' array with flags indicating which registers (TEMPs,
+ * INPUTs, OUTPUTs, etc, are used by the given program.
+ * \param file  type of register to scan for
+ * \param used  returns true/false flags for in use / free
+ * \param usedSize  size of the 'used' array
+ */
+void
+_mesa_find_used_registers(const struct gl_program *prog,
+                          gl_register_file file,
+                          GLboolean used[], GLuint usedSize)
+{
+   GLuint i, j;
+
+   memset(used, 0, usedSize);
+
+   for (i = 0; i < prog->NumInstructions; i++) {
+      const struct prog_instruction *inst = prog->Instructions + i;
+      const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
+
+      if (inst->DstReg.File == file) {
+         used[inst->DstReg.Index] = GL_TRUE;
+      }
+
+      for (j = 0; j < n; j++) {
+         if (inst->SrcReg[j].File == file) {
+            used[inst->SrcReg[j].Index] = GL_TRUE;
+         }
+      }
+   }
+}
+
+
+/**
+ * Scan the given 'used' register flag array for the first entry
+ * that's >= firstReg.
+ * \param used  vector of flags indicating registers in use (as returned
+ *              by _mesa_find_used_registers())
+ * \param usedSize  size of the 'used' array
+ * \param firstReg  first register to start searching at
+ * \return index of unused register, or -1 if none.
+ */
+GLint
+_mesa_find_free_register(const GLboolean used[],
+                         GLuint usedSize, GLuint firstReg)
+{
+   GLuint i;
+
+   assert(firstReg < usedSize);
+
+   for (i = firstReg; i < usedSize; i++)
+      if (!used[i])
+         return i;
+
+   return -1;
+}
+
+
+/**
+ * "Post-process" a GPU program.  This is intended to be used for debugging.
+ * Example actions include no-op'ing instructions or changing instruction
+ * behaviour.
+ */
+void
+_mesa_postprocess_program(GLcontext *ctx, struct gl_program *prog)
+{
+   static const GLfloat white[4] = { 0.5, 0.5, 0.5, 0.5 };
+   GLuint i;
+   GLuint whiteSwizzle;
+   GLint whiteIndex = _mesa_add_unnamed_constant(prog->Parameters,
+                                                 white, 4, &whiteSwizzle);
+
+   (void) whiteIndex;
+
+   for (i = 0; i < prog->NumInstructions; i++) {
+      struct prog_instruction *inst = prog->Instructions + i;
+      const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
+
+      (void) n;
+
+      if (_mesa_is_tex_instruction(inst->Opcode)) {
+#if 0
+         /* replace TEX/TXP/TXB with MOV */
+         inst->Opcode = OPCODE_MOV;
+         inst->DstReg.WriteMask = WRITEMASK_XYZW;
+         inst->SrcReg[0].Swizzle = SWIZZLE_XYZW;
+         inst->SrcReg[0].Negate = NEGATE_NONE;
+#endif
+
+#if 0
+         /* disable shadow texture mode */
+         inst->TexShadow = 0;
+#endif
+      }
+
+      if (inst->Opcode == OPCODE_TXP) {
+#if 0
+         inst->Opcode = OPCODE_MOV;
+         inst->DstReg.WriteMask = WRITEMASK_XYZW;
+         inst->SrcReg[0].File = PROGRAM_CONSTANT;
+         inst->SrcReg[0].Index = whiteIndex;
+         inst->SrcReg[0].Swizzle = SWIZZLE_XYZW;
+         inst->SrcReg[0].Negate = NEGATE_NONE;
+#endif
+#if 0
+         inst->TexShadow = 0;
+#endif
+#if 0
+         inst->Opcode = OPCODE_TEX;
+         inst->TexShadow = 0;
+#endif
+      }
+
+   }
+}
diff --git a/src/mesa/program/program.h b/src/mesa/program/program.h
new file mode 100644 (file)
index 0000000..286573d
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.3
+ *
+ * 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 program.c
+ * Vertex and fragment program support functions.
+ * \author Brian Paul
+ */
+
+
+/**
+ * \mainpage Mesa vertex and fragment program module
+ *
+ * This module or directory contains most of the code for vertex and
+ * fragment programs and shaders, including state management, parsers,
+ * and (some) software routines for executing programs
+ */
+
+#ifndef PROGRAM_H
+#define PROGRAM_H
+
+#include "main/mtypes.h"
+
+
+extern struct gl_program _mesa_DummyProgram;
+
+
+extern void
+_mesa_init_program(GLcontext *ctx);
+
+extern void
+_mesa_free_program_data(GLcontext *ctx);
+
+extern void
+_mesa_update_default_objects_program(GLcontext *ctx);
+
+extern void
+_mesa_set_program_error(GLcontext *ctx, GLint pos, const char *string);
+
+extern const GLubyte *
+_mesa_find_line_column(const GLubyte *string, const GLubyte *pos,
+                       GLint *line, GLint *col);
+
+
+extern struct gl_program *
+_mesa_init_vertex_program(GLcontext *ctx,
+                          struct gl_vertex_program *prog,
+                          GLenum target, GLuint id);
+
+extern struct gl_program *
+_mesa_init_fragment_program(GLcontext *ctx,
+                            struct gl_fragment_program *prog,
+                            GLenum target, GLuint id);
+
+extern struct gl_program *
+_mesa_init_geometry_program(GLcontext *ctx,
+                            struct gl_geometry_program *prog,
+                            GLenum target, GLuint id);
+
+extern struct gl_program *
+_mesa_new_program(GLcontext *ctx, GLenum target, GLuint id);
+
+extern void
+_mesa_delete_program(GLcontext *ctx, struct gl_program *prog);
+
+extern struct gl_program *
+_mesa_lookup_program(GLcontext *ctx, GLuint id);
+
+extern void
+_mesa_reference_program(GLcontext *ctx,
+                        struct gl_program **ptr,
+                        struct gl_program *prog);
+
+static INLINE void
+_mesa_reference_vertprog(GLcontext *ctx,
+                         struct gl_vertex_program **ptr,
+                         struct gl_vertex_program *prog)
+{
+   _mesa_reference_program(ctx, (struct gl_program **) ptr,
+                           (struct gl_program *) prog);
+}
+
+static INLINE void
+_mesa_reference_fragprog(GLcontext *ctx,
+                         struct gl_fragment_program **ptr,
+                         struct gl_fragment_program *prog)
+{
+   _mesa_reference_program(ctx, (struct gl_program **) ptr,
+                           (struct gl_program *) prog);
+}
+
+static INLINE void
+_mesa_reference_geomprog(GLcontext *ctx,
+                         struct gl_geometry_program **ptr,
+                         struct gl_geometry_program *prog)
+{
+   _mesa_reference_program(ctx, (struct gl_program **) ptr,
+                           (struct gl_program *) prog);
+}
+
+extern struct gl_program *
+_mesa_clone_program(GLcontext *ctx, const struct gl_program *prog);
+
+static INLINE struct gl_vertex_program *
+_mesa_clone_vertex_program(GLcontext *ctx,
+                           const struct gl_vertex_program *prog)
+{
+   return (struct gl_vertex_program *) _mesa_clone_program(ctx, &prog->Base);
+}
+
+static INLINE struct gl_geometry_program *
+_mesa_clone_geometry_program(GLcontext *ctx,
+                             const struct gl_geometry_program *prog)
+{
+   return (struct gl_geometry_program *) _mesa_clone_program(ctx, &prog->Base);
+}
+
+static INLINE struct gl_fragment_program *
+_mesa_clone_fragment_program(GLcontext *ctx,
+                             const struct gl_fragment_program *prog)
+{
+   return (struct gl_fragment_program *) _mesa_clone_program(ctx, &prog->Base);
+}
+
+
+extern  GLboolean
+_mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count);
+
+extern  GLboolean
+_mesa_delete_instructions(struct gl_program *prog, GLuint start, GLuint count);
+
+extern struct gl_program *
+_mesa_combine_programs(GLcontext *ctx,
+                       const struct gl_program *progA,
+                       const struct gl_program *progB);
+
+extern void
+_mesa_find_used_registers(const struct gl_program *prog,
+                          gl_register_file file,
+                          GLboolean used[], GLuint usedSize);
+
+extern GLint
+_mesa_find_free_register(const GLboolean used[],
+                         GLuint maxRegs, GLuint firstReg);
+
+extern void
+_mesa_postprocess_program(GLcontext *ctx, struct gl_program *prog);
+
+
+#endif /* PROGRAM_H */
diff --git a/src/mesa/program/program_lexer.l b/src/mesa/program/program_lexer.l
new file mode 100644 (file)
index 0000000..0a50dab
--- /dev/null
@@ -0,0 +1,507 @@
+%{
+/*
+ * Copyright Â© 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION 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/imports.h"
+#include "program/prog_instruction.h"
+#include "program/prog_statevars.h"
+#include "program/symbol_table.h"
+#include "program/program_parser.h"
+#include "program/program_parse.tab.h"
+
+#define require_ARB_vp (yyextra->mode == ARB_vertex)
+#define require_ARB_fp (yyextra->mode == ARB_fragment)
+#define require_NV_fp  (yyextra->option.NV_fragment)
+#define require_shadow (yyextra->option.Shadow)
+#define require_rect   (yyextra->option.TexRect)
+#define require_texarray        (yyextra->option.TexArray)
+
+#ifndef HAVE_UNISTD_H
+#define YY_NO_UNISTD_H
+#endif
+
+#define return_token_or_IDENTIFIER(condition, token)   \
+   do {                                                        \
+      if (condition) {                                 \
+        return token;                                  \
+      } else {                                         \
+        return handle_ident(yyextra, yytext, yylval);  \
+      }                                                        \
+   } while (0)
+
+#define return_token_or_DOT(condition, token)          \
+   do {                                                        \
+      if (condition) {                                 \
+        return token;                                  \
+      } else {                                         \
+        yyless(1);                                     \
+        return DOT;                                    \
+      }                                                        \
+   } while (0)
+
+
+#define return_opcode(condition, token, opcode, len)   \
+   do {                                                        \
+      if (condition &&                                 \
+         _mesa_parse_instruction_suffix(yyextra,       \
+                                        yytext + len,  \
+                                        & yylval->temp_inst)) {        \
+        yylval->temp_inst.Opcode = OPCODE_ ## opcode;  \
+        return token;                                  \
+      } else {                                         \
+        return handle_ident(yyextra, yytext, yylval);  \
+      }                                                        \
+   } while (0)
+
+#define SWIZZLE_INVAL  MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
+                                    SWIZZLE_NIL, SWIZZLE_NIL)
+
+static unsigned
+mask_from_char(char c)
+{
+   switch (c) {
+   case 'x':
+   case 'r':
+      return WRITEMASK_X;
+   case 'y':
+   case 'g':
+      return WRITEMASK_Y;
+   case 'z':
+   case 'b':
+      return WRITEMASK_Z;
+   case 'w':
+   case 'a':
+      return WRITEMASK_W;
+   }
+
+   return 0;
+}
+
+static unsigned
+swiz_from_char(char c)
+{
+   switch (c) {
+   case 'x':
+   case 'r':
+      return SWIZZLE_X;
+   case 'y':
+   case 'g':
+      return SWIZZLE_Y;
+   case 'z':
+   case 'b':
+      return SWIZZLE_Z;
+   case 'w':
+   case 'a':
+      return SWIZZLE_W;
+   }
+
+   return 0;
+}
+
+static int
+handle_ident(struct asm_parser_state *state, const char *text, YYSTYPE *lval)
+{
+   lval->string = strdup(text);
+
+   return (_mesa_symbol_table_find_symbol(state->st, 0, text) == NULL)
+      ? IDENTIFIER : USED_IDENTIFIER;
+}
+
+#define YY_USER_ACTION                                                 \
+   do {                                                                        \
+      yylloc->first_column = yylloc->last_column;                      \
+      yylloc->last_column += yyleng;                                   \
+      if ((yylloc->first_line == 1)                                    \
+         && (yylloc->first_column == 1)) {                             \
+        yylloc->position = 1;                                          \
+      } else {                                                         \
+        yylloc->position += yylloc->last_column - yylloc->first_column; \
+      }                                                                        \
+   } while(0);
+
+#define YY_NO_INPUT
+
+/* Yes, this is intentionally doing nothing. We have this line of code
+here only to avoid the compiler complaining about an unput function
+that is defined, but never called. */
+#define YY_USER_INIT while (0) { unput(0); }
+
+#define YY_EXTRA_TYPE struct asm_parser_state *
+
+/* Flex defines a couple of functions with no declarations nor the
+static keyword. Declare them here to avoid a compiler warning. */
+int yyget_column  (yyscan_t yyscanner);
+void yyset_column (int  column_no , yyscan_t yyscanner);
+
+%}
+
+num    [0-9]+
+exp    [Ee][-+]?[0-9]+
+frac   "."[0-9]+
+dot    "."[ \t]*
+
+sz     [HRX]?
+szf    [HR]?
+cc     C?
+sat    (_SAT)?
+
+%option bison-bridge bison-locations reentrant noyywrap
+%%
+
+"!!ARBvp1.0"              { return ARBvp_10; }
+"!!ARBfp1.0"              { return ARBfp_10; }
+ADDRESS                   {
+   yylval->integer = at_address;
+   return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS);
+}
+ALIAS                     { return ALIAS; }
+ATTRIB                    { return ATTRIB; }
+END                       { return END; }
+OPTION                    { return OPTION; }
+OUTPUT                    { return OUTPUT; }
+PARAM                     { return PARAM; }
+TEMP                      { yylval->integer = at_temp; return TEMP; }
+
+ABS{sz}{cc}{sat}   { return_opcode(             1, VECTOR_OP, ABS, 3); }
+ADD{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, ADD, 3); }
+ARL                { return_opcode(require_ARB_vp, ARL, ARL, 3); }
+
+CMP{sat}           { return_opcode(require_ARB_fp, TRI_OP, CMP, 3); }
+COS{szf}{cc}{sat}  { return_opcode(require_ARB_fp, SCALAR_OP, COS, 3); }
+
+DDX{szf}{cc}{sat}  { return_opcode(require_NV_fp,  VECTOR_OP, DDX, 3); }
+DDY{szf}{cc}{sat}  { return_opcode(require_NV_fp,  VECTOR_OP, DDY, 3); }
+DP3{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, DP3, 3); }
+DP4{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, DP4, 3); }
+DPH{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, DPH, 3); }
+DST{szf}{cc}{sat}  { return_opcode(             1, BIN_OP, DST, 3); }
+
+EX2{szf}{cc}{sat}  { return_opcode(             1, SCALAR_OP, EX2, 3); }
+EXP                { return_opcode(require_ARB_vp, SCALAR_OP, EXP, 3); }
+
+FLR{sz}{cc}{sat}   { return_opcode(             1, VECTOR_OP, FLR, 3); }
+FRC{sz}{cc}{sat}   { return_opcode(             1, VECTOR_OP, FRC, 3); }
+
+KIL                { return_opcode(require_ARB_fp, KIL, KIL, 3); }
+
+LIT{szf}{cc}{sat}  { return_opcode(             1, VECTOR_OP, LIT, 3); }
+LG2{szf}{cc}{sat}  { return_opcode(             1, SCALAR_OP, LG2, 3); }
+LOG                { return_opcode(require_ARB_vp, SCALAR_OP, LOG, 3); }
+LRP{sz}{cc}{sat}   { return_opcode(require_ARB_fp, TRI_OP, LRP, 3); }
+
+MAD{sz}{cc}{sat}   { return_opcode(             1, TRI_OP, MAD, 3); }
+MAX{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, MAX, 3); }
+MIN{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, MIN, 3); }
+MOV{sz}{cc}{sat}   { return_opcode(             1, VECTOR_OP, MOV, 3); }
+MUL{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, MUL, 3); }
+
+PK2H               { return_opcode(require_NV_fp,  VECTOR_OP, PK2H, 4); }
+PK2US              { return_opcode(require_NV_fp,  VECTOR_OP, PK2US, 5); }
+PK4B               { return_opcode(require_NV_fp,  VECTOR_OP, PK4B, 4); }
+PK4UB              { return_opcode(require_NV_fp,  VECTOR_OP, PK4UB, 5); }
+POW{szf}{cc}{sat}  { return_opcode(             1, BINSC_OP, POW, 3); }
+
+RCP{szf}{cc}{sat}  { return_opcode(             1, SCALAR_OP, RCP, 3); }
+RFL{szf}{cc}{sat}  { return_opcode(require_NV_fp,  BIN_OP,    RFL, 3); }
+RSQ{szf}{cc}{sat}  { return_opcode(             1, SCALAR_OP, RSQ, 3); }
+
+SCS{sat}           { return_opcode(require_ARB_fp, SCALAR_OP, SCS, 3); }
+SEQ{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SEQ, 3); }
+SFL{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SFL, 3); }
+SGE{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, SGE, 3); }
+SGT{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SGT, 3); }
+SIN{szf}{cc}{sat}  { return_opcode(require_ARB_fp, SCALAR_OP, SIN, 3); }
+SLE{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SLE, 3); }
+SLT{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, SLT, 3); }
+SNE{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SNE, 3); }
+STR{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, STR, 3); }
+SUB{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, SUB, 3); }
+SWZ{sat}           { return_opcode(             1, SWZ, SWZ, 3); }
+
+TEX{cc}{sat}       { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, 3); }
+TXB{cc}{sat}       { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, 3); }
+TXD{cc}{sat}       { return_opcode(require_NV_fp,  TXD_OP, TXD, 3); }
+TXP{cc}{sat}       { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, 3); }
+
+UP2H{cc}{sat}      { return_opcode(require_NV_fp,  SCALAR_OP, UP2H, 4); }
+UP2US{cc}{sat}     { return_opcode(require_NV_fp,  SCALAR_OP, UP2US, 5); }
+UP4B{cc}{sat}      { return_opcode(require_NV_fp,  SCALAR_OP, UP4B, 4); }
+UP4UB{cc}{sat}     { return_opcode(require_NV_fp,  SCALAR_OP, UP4UB, 5); }
+
+X2D{szf}{cc}{sat}  { return_opcode(require_NV_fp,  TRI_OP, X2D, 3); }
+XPD{sat}           { return_opcode(             1, BIN_OP, XPD, 3); }
+
+vertex                    { return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); }
+fragment                  { return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); }
+program                   { return PROGRAM; }
+state                     { return STATE; }
+result                    { return RESULT; }
+
+{dot}ambient              { return AMBIENT; }
+{dot}attenuation          { return ATTENUATION; }
+{dot}back                 { return BACK; }
+{dot}clip                 { return_token_or_DOT(require_ARB_vp, CLIP); }
+{dot}color                { return COLOR; }
+{dot}depth                { return_token_or_DOT(require_ARB_fp, DEPTH); }
+{dot}diffuse              { return DIFFUSE; }
+{dot}direction            { return DIRECTION; }
+{dot}emission             { return EMISSION; }
+{dot}env                  { return ENV; }
+{dot}eye                  { return EYE; }
+{dot}fogcoord             { return FOGCOORD; }
+{dot}fog                  { return FOG; }
+{dot}front                { return FRONT; }
+{dot}half                 { return HALF; }
+{dot}inverse              { return INVERSE; }
+{dot}invtrans             { return INVTRANS; }
+{dot}light                { return LIGHT; }
+{dot}lightmodel           { return LIGHTMODEL; }
+{dot}lightprod            { return LIGHTPROD; }
+{dot}local                { return LOCAL; }
+{dot}material             { return MATERIAL; }
+{dot}program              { return MAT_PROGRAM; }
+{dot}matrix               { return MATRIX; }
+{dot}matrixindex          { return_token_or_DOT(require_ARB_vp, MATRIXINDEX); }
+{dot}modelview            { return MODELVIEW; }
+{dot}mvp                  { return MVP; }
+{dot}normal               { return_token_or_DOT(require_ARB_vp, NORMAL); }
+{dot}object               { return OBJECT; }
+{dot}palette              { return PALETTE; }
+{dot}params               { return PARAMS; }
+{dot}plane                { return PLANE; }
+{dot}point                { return_token_or_DOT(require_ARB_vp, POINT_TOK); }
+{dot}pointsize            { return_token_or_DOT(require_ARB_vp, POINTSIZE); }
+{dot}position             { return POSITION; }
+{dot}primary              { return PRIMARY; }
+{dot}projection           { return PROJECTION; }
+{dot}range                { return_token_or_DOT(require_ARB_fp, RANGE); }
+{dot}row                  { return ROW; }
+{dot}scenecolor           { return SCENECOLOR; }
+{dot}secondary            { return SECONDARY; }
+{dot}shininess            { return SHININESS; }
+{dot}size                 { return_token_or_DOT(require_ARB_vp, SIZE_TOK); }
+{dot}specular             { return SPECULAR; }
+{dot}spot                 { return SPOT; }
+{dot}texcoord             { return TEXCOORD; }
+{dot}texenv               { return_token_or_DOT(require_ARB_fp, TEXENV); }
+{dot}texgen               { return_token_or_DOT(require_ARB_vp, TEXGEN); }
+{dot}q                    { return_token_or_DOT(require_ARB_vp, TEXGEN_Q); }
+{dot}s                    { return_token_or_DOT(require_ARB_vp, TEXGEN_S); }
+{dot}t                    { return_token_or_DOT(require_ARB_vp, TEXGEN_T); }
+{dot}texture              { return TEXTURE; }
+{dot}transpose            { return TRANSPOSE; }
+{dot}attrib               { return_token_or_DOT(require_ARB_vp, VTXATTRIB); }
+{dot}weight               { return_token_or_DOT(require_ARB_vp, WEIGHT); }
+
+texture                   { return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); }
+1D                        { return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); }
+2D                        { return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); }
+3D                        { return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); }
+CUBE                      { return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); }
+RECT                      { return_token_or_IDENTIFIER(require_ARB_fp && require_rect, TEX_RECT); }
+SHADOW1D                  { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW1D); }
+SHADOW2D                  { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW2D); }
+SHADOWRECT                { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_rect, TEX_SHADOWRECT); }
+ARRAY1D                   { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY1D); }
+ARRAY2D                   { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY2D); }
+ARRAYSHADOW1D             { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW1D); }
+ARRAYSHADOW2D             { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); }
+
+[_a-zA-Z$][_a-zA-Z0-9$]*  { return handle_ident(yyextra, yytext, yylval); }
+
+".."                      { return DOT_DOT; }
+
+{num}                     {
+   yylval->integer = strtol(yytext, NULL, 10);
+   return INTEGER;
+}
+{num}?{frac}{exp}?        {
+   yylval->real = _mesa_strtof(yytext, NULL);
+   return REAL;
+}
+{num}"."/[^.]             {
+   yylval->real = _mesa_strtof(yytext, NULL);
+   return REAL;
+}
+{num}{exp}                {
+   yylval->real = _mesa_strtof(yytext, NULL);
+   return REAL;
+}
+{num}"."{exp}             {
+   yylval->real = _mesa_strtof(yytext, NULL);
+   return REAL;
+}
+
+".xyzw"                   {
+   yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
+   yylval->swiz_mask.mask = WRITEMASK_XYZW;
+   return MASK4;
+}
+
+".xy"[zw]                 {
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_XY
+      | mask_from_char(yytext[3]);
+   return MASK3;
+}
+".xzw"                    {
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_XZW;
+   return MASK3;
+}
+".yzw"                    {
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_YZW;
+   return MASK3;
+}
+
+".x"[yzw]                 {
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_X
+      | mask_from_char(yytext[2]);
+   return MASK2;
+}
+".y"[zw]                  {
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_Y
+      | mask_from_char(yytext[2]);
+   return MASK2;
+}
+".zw"                     {
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_ZW;
+   return MASK2;
+}
+
+"."[xyzw]                 {
+   const unsigned s = swiz_from_char(yytext[1]);
+   yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
+   yylval->swiz_mask.mask = mask_from_char(yytext[1]);
+   return MASK1; 
+}
+
+"."[xyzw]{4}              {
+   yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
+                                           swiz_from_char(yytext[2]),
+                                           swiz_from_char(yytext[3]),
+                                           swiz_from_char(yytext[4]));
+   yylval->swiz_mask.mask = 0;
+   return SWIZZLE;
+}
+
+".rgba"                   {
+   yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
+   yylval->swiz_mask.mask = WRITEMASK_XYZW;
+   return_token_or_DOT(require_ARB_fp, MASK4);
+}
+
+".rg"[ba]                 {
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_XY
+      | mask_from_char(yytext[3]);
+   return_token_or_DOT(require_ARB_fp, MASK3);
+}
+".rba"                    {
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_XZW;
+   return_token_or_DOT(require_ARB_fp, MASK3);
+}
+".gba"                    {
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_YZW;
+   return_token_or_DOT(require_ARB_fp, MASK3);
+}
+
+".r"[gba]                 {
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_X
+      | mask_from_char(yytext[2]);
+   return_token_or_DOT(require_ARB_fp, MASK2);
+}
+".g"[ba]                  {
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_Y
+      | mask_from_char(yytext[2]);
+   return_token_or_DOT(require_ARB_fp, MASK2);
+}
+".ba"                     {
+   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+   yylval->swiz_mask.mask = WRITEMASK_ZW;
+   return_token_or_DOT(require_ARB_fp, MASK2);
+}
+
+"."[gba]                  {
+   const unsigned s = swiz_from_char(yytext[1]);
+   yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
+   yylval->swiz_mask.mask = mask_from_char(yytext[1]);
+   return_token_or_DOT(require_ARB_fp, MASK1);
+}
+
+
+".r"                      {
+   if (require_ARB_vp) {
+      return TEXGEN_R;
+   } else {
+      yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X,
+                                               SWIZZLE_X, SWIZZLE_X);
+      yylval->swiz_mask.mask = WRITEMASK_X;
+      return MASK1;
+   }
+}
+
+"."[rgba]{4}              {
+   yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
+                                           swiz_from_char(yytext[2]),
+                                           swiz_from_char(yytext[3]),
+                                           swiz_from_char(yytext[4]));
+   yylval->swiz_mask.mask = 0;
+   return_token_or_DOT(require_ARB_fp, SWIZZLE);
+}
+
+"."                       { return DOT; }
+
+\n                        {
+   yylloc->first_line++;
+   yylloc->first_column = 1;
+   yylloc->last_line++;
+   yylloc->last_column = 1;
+   yylloc->position++;
+}
+[ \t\r]+                  /* eat whitespace */ ;
+#.*$                      /* eat comments */ ;
+.                         { return yytext[0]; }
+%%
+
+void
+_mesa_program_lexer_ctor(void **scanner, struct asm_parser_state *state,
+                        const char *string, size_t len)
+{
+   yylex_init_extra(state, scanner);
+   yy_scan_bytes(string, len, *scanner);
+}
+
+void
+_mesa_program_lexer_dtor(void *scanner)
+{
+   yylex_destroy(scanner);
+}
diff --git a/src/mesa/program/program_parse.tab.c b/src/mesa/program/program_parse.tab.c
new file mode 100644 (file)
index 0000000..6421d1f
--- /dev/null
@@ -0,0 +1,5729 @@
+
+/* A Bison parser, made by GNU Bison 2.4.1.  */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+   
+      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+   
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+   
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+   simplifying the original so-called "semantic" parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION "2.4.1"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 1
+
+/* Push parsers.  */
+#define YYPUSH 0
+
+/* Pull parsers.  */
+#define YYPULL 1
+
+/* Using locations.  */
+#define YYLSP_NEEDED 1
+
+
+
+/* Copy the first part of user declarations.  */
+
+/* Line 189 of yacc.c  */
+#line 1 "program_parse.y"
+
+/*
+ * Copyright Â© 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "main/mtypes.h"
+#include "main/imports.h"
+#include "program/program.h"
+#include "program/prog_parameter.h"
+#include "program/prog_parameter_layout.h"
+#include "program/prog_statevars.h"
+#include "program/prog_instruction.h"
+
+#include "program/symbol_table.h"
+#include "program/program_parser.h"
+
+extern void *yy_scan_string(char *);
+extern void yy_delete_buffer(void *);
+
+static struct asm_symbol *declare_variable(struct asm_parser_state *state,
+    char *name, enum asm_type t, struct YYLTYPE *locp);
+
+static int add_state_reference(struct gl_program_parameter_list *param_list,
+    const gl_state_index tokens[STATE_LENGTH]);
+
+static int initialize_symbol_from_state(struct gl_program *prog,
+    struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
+
+static int initialize_symbol_from_param(struct gl_program *prog,
+    struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
+
+static int initialize_symbol_from_const(struct gl_program *prog,
+    struct asm_symbol *param_var, const struct asm_vector *vec,
+    GLboolean allowSwizzle);
+
+static int yyparse(struct asm_parser_state *state);
+
+static char *make_error_string(const char *fmt, ...);
+
+static void yyerror(struct YYLTYPE *locp, struct asm_parser_state *state,
+    const char *s);
+
+static int validate_inputs(struct YYLTYPE *locp,
+    struct asm_parser_state *state);
+
+static void init_dst_reg(struct prog_dst_register *r);
+
+static void set_dst_reg(struct prog_dst_register *r,
+                        gl_register_file file, GLint index);
+
+static void init_src_reg(struct asm_src_register *r);
+
+static void set_src_reg(struct asm_src_register *r,
+                        gl_register_file file, GLint index);
+
+static void set_src_reg_swz(struct asm_src_register *r,
+                            gl_register_file file, GLint index, GLuint swizzle);
+
+static void asm_instruction_set_operands(struct asm_instruction *inst,
+    const struct prog_dst_register *dst, const struct asm_src_register *src0,
+    const struct asm_src_register *src1, const struct asm_src_register *src2);
+
+static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op,
+    const struct prog_dst_register *dst, const struct asm_src_register *src0,
+    const struct asm_src_register *src1, const struct asm_src_register *src2);
+
+static struct asm_instruction *asm_instruction_copy_ctor(
+    const struct prog_instruction *base, const struct prog_dst_register *dst,
+    const struct asm_src_register *src0, const struct asm_src_register *src1,
+    const struct asm_src_register *src2);
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE (!FALSE)
+#endif
+
+#define YYLLOC_DEFAULT(Current, Rhs, N)                                        \
+   do {                                                                        \
+      if (YYID(N)) {                                                   \
+        (Current).first_line = YYRHSLOC(Rhs, 1).first_line;            \
+        (Current).first_column = YYRHSLOC(Rhs, 1).first_column;        \
+        (Current).position = YYRHSLOC(Rhs, 1).position;                \
+        (Current).last_line = YYRHSLOC(Rhs, N).last_line;              \
+        (Current).last_column = YYRHSLOC(Rhs, N).last_column;          \
+      } else {                                                         \
+        (Current).first_line = YYRHSLOC(Rhs, 0).last_line;             \
+        (Current).last_line = (Current).first_line;                    \
+        (Current).first_column = YYRHSLOC(Rhs, 0).last_column;         \
+        (Current).last_column = (Current).first_column;                \
+        (Current).position = YYRHSLOC(Rhs, 0).position                 \
+           + (Current).first_column;                                   \
+      }                                                                        \
+   } while(YYID(0))
+
+#define YYLEX_PARAM state->scanner
+
+
+/* Line 189 of yacc.c  */
+#line 193 "program_parse.tab.c"
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 1
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     ARBvp_10 = 258,
+     ARBfp_10 = 259,
+     ADDRESS = 260,
+     ALIAS = 261,
+     ATTRIB = 262,
+     OPTION = 263,
+     OUTPUT = 264,
+     PARAM = 265,
+     TEMP = 266,
+     END = 267,
+     BIN_OP = 268,
+     BINSC_OP = 269,
+     SAMPLE_OP = 270,
+     SCALAR_OP = 271,
+     TRI_OP = 272,
+     VECTOR_OP = 273,
+     ARL = 274,
+     KIL = 275,
+     SWZ = 276,
+     TXD_OP = 277,
+     INTEGER = 278,
+     REAL = 279,
+     AMBIENT = 280,
+     ATTENUATION = 281,
+     BACK = 282,
+     CLIP = 283,
+     COLOR = 284,
+     DEPTH = 285,
+     DIFFUSE = 286,
+     DIRECTION = 287,
+     EMISSION = 288,
+     ENV = 289,
+     EYE = 290,
+     FOG = 291,
+     FOGCOORD = 292,
+     FRAGMENT = 293,
+     FRONT = 294,
+     HALF = 295,
+     INVERSE = 296,
+     INVTRANS = 297,
+     LIGHT = 298,
+     LIGHTMODEL = 299,
+     LIGHTPROD = 300,
+     LOCAL = 301,
+     MATERIAL = 302,
+     MAT_PROGRAM = 303,
+     MATRIX = 304,
+     MATRIXINDEX = 305,
+     MODELVIEW = 306,
+     MVP = 307,
+     NORMAL = 308,
+     OBJECT = 309,
+     PALETTE = 310,
+     PARAMS = 311,
+     PLANE = 312,
+     POINT_TOK = 313,
+     POINTSIZE = 314,
+     POSITION = 315,
+     PRIMARY = 316,
+     PROGRAM = 317,
+     PROJECTION = 318,
+     RANGE = 319,
+     RESULT = 320,
+     ROW = 321,
+     SCENECOLOR = 322,
+     SECONDARY = 323,
+     SHININESS = 324,
+     SIZE_TOK = 325,
+     SPECULAR = 326,
+     SPOT = 327,
+     STATE = 328,
+     TEXCOORD = 329,
+     TEXENV = 330,
+     TEXGEN = 331,
+     TEXGEN_Q = 332,
+     TEXGEN_R = 333,
+     TEXGEN_S = 334,
+     TEXGEN_T = 335,
+     TEXTURE = 336,
+     TRANSPOSE = 337,
+     TEXTURE_UNIT = 338,
+     TEX_1D = 339,
+     TEX_2D = 340,
+     TEX_3D = 341,
+     TEX_CUBE = 342,
+     TEX_RECT = 343,
+     TEX_SHADOW1D = 344,
+     TEX_SHADOW2D = 345,
+     TEX_SHADOWRECT = 346,
+     TEX_ARRAY1D = 347,
+     TEX_ARRAY2D = 348,
+     TEX_ARRAYSHADOW1D = 349,
+     TEX_ARRAYSHADOW2D = 350,
+     VERTEX = 351,
+     VTXATTRIB = 352,
+     WEIGHT = 353,
+     IDENTIFIER = 354,
+     USED_IDENTIFIER = 355,
+     MASK4 = 356,
+     MASK3 = 357,
+     MASK2 = 358,
+     MASK1 = 359,
+     SWIZZLE = 360,
+     DOT_DOT = 361,
+     DOT = 362
+   };
+#endif
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+
+/* Line 214 of yacc.c  */
+#line 126 "program_parse.y"
+
+   struct asm_instruction *inst;
+   struct asm_symbol *sym;
+   struct asm_symbol temp_sym;
+   struct asm_swizzle_mask swiz_mask;
+   struct asm_src_register src_reg;
+   struct prog_dst_register dst_reg;
+   struct prog_instruction temp_inst;
+   char *string;
+   unsigned result;
+   unsigned attrib;
+   int integer;
+   float real;
+   gl_state_index state[STATE_LENGTH];
+   int negate;
+   struct asm_vector vector;
+   gl_inst_opcode opcode;
+
+   struct {
+      unsigned swz;
+      unsigned rgba_valid:1;
+      unsigned xyzw_valid:1;
+      unsigned negate:1;
+   } ext_swizzle;
+
+
+
+/* Line 214 of yacc.c  */
+#line 364 "program_parse.tab.c"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+  int first_line;
+  int first_column;
+  int last_line;
+  int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+/* Copy the second part of user declarations.  */
+
+/* Line 264 of yacc.c  */
+#line 271 "program_parse.y"
+
+extern int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
+    void *yyscanner);
+
+
+/* Line 264 of yacc.c  */
+#line 395 "program_parse.tab.c"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+#  define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E.  */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions.  */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int yyi)
+#else
+static int
+YYID (yyi)
+    int yyi;
+#endif
+{
+  return yyi;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   elif defined __BUILTIN_VA_ARG_INCR
+#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+#   elif defined _AIX
+#    define YYSTACK_ALLOC __alloca
+#   elif defined _MSC_VER
+#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+#    define alloca _alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#     ifndef _STDLIB_H
+#      define _STDLIB_H 1
+#     endif
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+#  endif
+#  if (defined __cplusplus && ! defined _STDLIB_H \
+       && ! ((defined YYMALLOC || defined malloc) \
+            && (defined YYFREE || defined free)))
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   ifndef _STDLIB_H
+#    define _STDLIB_H 1
+#   endif
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+     && (! defined __cplusplus \
+        || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+            && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yytype_int16 yyss_alloc;
+  YYSTYPE yyvs_alloc;
+  YYLTYPE yyls_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+      + 2 * YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)             \
+      do                                       \
+       {                                       \
+         YYSIZE_T yyi;                         \
+         for (yyi = 0; yyi < (Count); yyi++)   \
+           (To)[yyi] = (From)[yyi];            \
+       }                                       \
+      while (YYID (0))
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack)                          \
+    do                                                                 \
+      {                                                                        \
+       YYSIZE_T yynewbytes;                                            \
+       YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
+       Stack = &yyptr->Stack_alloc;                                    \
+       yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+       yyptr += yynewbytes / sizeof (*yyptr);                          \
+      }                                                                        \
+    while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state.  */
+#define YYFINAL  5
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   396
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  120
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  143
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  282
+/* YYNRULES -- Number of states.  */
+#define YYNSTATES  475
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   362
+
+#define YYTRANSLATE(YYX)                                               \
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const yytype_uint8 yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+     115,   116,     2,   113,   109,   114,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,   108,
+       2,   117,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,   111,     2,   112,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,   118,   110,   119,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
+      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
+      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
+      65,    66,    67,    68,    69,    70,    71,    72,    73,    74,
+      75,    76,    77,    78,    79,    80,    81,    82,    83,    84,
+      85,    86,    87,    88,    89,    90,    91,    92,    93,    94,
+      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
+     105,   106,   107
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const yytype_uint16 yyprhs[] =
+{
+       0,     0,     3,     8,    10,    12,    15,    16,    20,    23,
+      24,    27,    30,    32,    34,    36,    38,    40,    42,    44,
+      46,    48,    50,    52,    54,    59,    64,    69,    76,    83,
+      92,   101,   104,   107,   120,   123,   125,   127,   129,   131,
+     133,   135,   137,   139,   141,   143,   145,   147,   154,   157,
+     162,   165,   167,   171,   177,   181,   184,   192,   195,   197,
+     199,   201,   203,   208,   210,   212,   214,   216,   218,   220,
+     222,   226,   227,   230,   233,   235,   237,   239,   241,   243,
+     245,   247,   249,   251,   252,   254,   256,   258,   260,   261,
+     265,   269,   270,   273,   276,   278,   280,   282,   284,   286,
+     288,   290,   292,   297,   300,   303,   305,   308,   310,   313,
+     315,   318,   323,   328,   330,   331,   335,   337,   339,   342,
+     344,   347,   349,   351,   355,   362,   363,   365,   368,   373,
+     375,   379,   381,   383,   385,   387,   389,   391,   393,   395,
+     397,   399,   402,   405,   408,   411,   414,   417,   420,   423,
+     426,   429,   432,   435,   439,   441,   443,   445,   451,   453,
+     455,   457,   460,   462,   464,   467,   469,   472,   479,   481,
+     485,   487,   489,   491,   493,   495,   500,   502,   504,   506,
+     508,   510,   512,   515,   517,   519,   525,   527,   530,   532,
+     534,   540,   543,   544,   551,   555,   556,   558,   560,   562,
+     564,   566,   569,   571,   573,   576,   581,   586,   587,   591,
+     593,   595,   597,   600,   602,   604,   606,   608,   614,   616,
+     620,   626,   632,   634,   638,   644,   646,   648,   650,   652,
+     654,   656,   658,   660,   662,   666,   672,   680,   690,   693,
+     696,   698,   700,   701,   702,   707,   709,   710,   711,   715,
+     719,   721,   727,   730,   733,   736,   739,   743,   746,   750,
+     751,   753,   755,   756,   758,   760,   761,   763,   765,   766,
+     768,   770,   771,   775,   776,   780,   781,   785,   787,   789,
+     791,   796,   798
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int16 yyrhs[] =
+{
+     121,     0,    -1,   122,   123,   125,    12,    -1,     3,    -1,
+       4,    -1,   123,   124,    -1,    -1,     8,   262,   108,    -1,
+     125,   126,    -1,    -1,   127,   108,    -1,   170,   108,    -1,
+     128,    -1,   129,    -1,   130,    -1,   131,    -1,   132,    -1,
+     133,    -1,   134,    -1,   135,    -1,   141,    -1,   136,    -1,
+     137,    -1,   138,    -1,    19,   146,   109,   142,    -1,    18,
+     145,   109,   144,    -1,    16,   145,   109,   142,    -1,    14,
+     145,   109,   142,   109,   142,    -1,    13,   145,   109,   144,
+     109,   144,    -1,    17,   145,   109,   144,   109,   144,   109,
+     144,    -1,    15,   145,   109,   144,   109,   139,   109,   140,
+      -1,    20,   144,    -1,    20,   166,    -1,    22,   145,   109,
+     144,   109,   144,   109,   144,   109,   139,   109,   140,    -1,
+      83,   256,    -1,    84,    -1,    85,    -1,    86,    -1,    87,
+      -1,    88,    -1,    89,    -1,    90,    -1,    91,    -1,    92,
+      -1,    93,    -1,    94,    -1,    95,    -1,    21,   145,   109,
+     150,   109,   147,    -1,   241,   143,    -1,   241,   110,   143,
+     110,    -1,   150,   162,    -1,   238,    -1,   241,   150,   163,
+      -1,   241,   110,   150,   163,   110,    -1,   151,   164,   165,
+      -1,   159,   161,    -1,   148,   109,   148,   109,   148,   109,
+     148,    -1,   241,   149,    -1,    23,    -1,   262,    -1,   100,
+      -1,   172,    -1,   152,   111,   153,   112,    -1,   186,    -1,
+     249,    -1,   100,    -1,   100,    -1,   154,    -1,   155,    -1,
+      23,    -1,   159,   160,   156,    -1,    -1,   113,   157,    -1,
+     114,   158,    -1,    23,    -1,    23,    -1,   100,    -1,   104,
+      -1,   104,    -1,   104,    -1,   104,    -1,   101,    -1,   105,
+      -1,    -1,   101,    -1,   102,    -1,   103,    -1,   104,    -1,
+      -1,   115,   166,   116,    -1,   115,   167,   116,    -1,    -1,
+     168,   163,    -1,   169,   163,    -1,    99,    -1,   100,    -1,
+     171,    -1,   178,    -1,   242,    -1,   245,    -1,   248,    -1,
+     261,    -1,     7,    99,   117,   172,    -1,    96,   173,    -1,
+      38,   177,    -1,    60,    -1,    98,   175,    -1,    53,    -1,
+      29,   254,    -1,    37,    -1,    74,   255,    -1,    50,   111,
+     176,   112,    -1,    97,   111,   174,   112,    -1,    23,    -1,
+      -1,   111,   176,   112,    -1,    23,    -1,    60,    -1,    29,
+     254,    -1,    37,    -1,    74,   255,    -1,   179,    -1,   180,
+      -1,    10,    99,   182,    -1,    10,    99,   111,   181,   112,
+     183,    -1,    -1,    23,    -1,   117,   185,    -1,   117,   118,
+     184,   119,    -1,   187,    -1,   184,   109,   187,    -1,   189,
+      -1,   225,    -1,   235,    -1,   189,    -1,   225,    -1,   236,
+      -1,   188,    -1,   226,    -1,   235,    -1,   189,    -1,    73,
+     213,    -1,    73,   190,    -1,    73,   192,    -1,    73,   195,
+      -1,    73,   197,    -1,    73,   203,    -1,    73,   199,    -1,
+      73,   206,    -1,    73,   208,    -1,    73,   210,    -1,    73,
+     212,    -1,    73,   224,    -1,    47,   253,   191,    -1,   201,
+      -1,    33,    -1,    69,    -1,    43,   111,   202,   112,   193,
+      -1,   201,    -1,    60,    -1,    26,    -1,    72,   194,    -1,
+      40,    -1,    32,    -1,    44,   196,    -1,    25,    -1,   253,
+      67,    -1,    45,   111,   202,   112,   253,   198,    -1,   201,
+      -1,    75,   257,   200,    -1,    29,    -1,    25,    -1,    31,
+      -1,    71,    -1,    23,    -1,    76,   255,   204,   205,    -1,
+      35,    -1,    54,    -1,    79,    -1,    80,    -1,    78,    -1,
+      77,    -1,    36,   207,    -1,    29,    -1,    56,    -1,    28,
+     111,   209,   112,    57,    -1,    23,    -1,    58,   211,    -1,
+      70,    -1,    26,    -1,   215,    66,   111,   218,   112,    -1,
+     215,   214,    -1,    -1,    66,   111,   218,   106,   218,   112,
+      -1,    49,   219,   216,    -1,    -1,   217,    -1,    41,    -1,
+      82,    -1,    42,    -1,    23,    -1,    51,   220,    -1,    63,
+      -1,    52,    -1,    81,   255,    -1,    55,   111,   222,   112,
+      -1,    48,   111,   223,   112,    -1,    -1,   111,   221,   112,
+      -1,    23,    -1,    23,    -1,    23,    -1,    30,    64,    -1,
+     229,    -1,   232,    -1,   227,    -1,   230,    -1,    62,    34,
+     111,   228,   112,    -1,   233,    -1,   233,   106,   233,    -1,
+      62,    34,   111,   233,   112,    -1,    62,    46,   111,   231,
+     112,    -1,   234,    -1,   234,   106,   234,    -1,    62,    46,
+     111,   234,   112,    -1,    23,    -1,    23,    -1,   237,    -1,
+     239,    -1,   238,    -1,   239,    -1,   240,    -1,    24,    -1,
+      23,    -1,   118,   240,   119,    -1,   118,   240,   109,   240,
+     119,    -1,   118,   240,   109,   240,   109,   240,   119,    -1,
+     118,   240,   109,   240,   109,   240,   109,   240,   119,    -1,
+     241,    24,    -1,   241,    23,    -1,   113,    -1,   114,    -1,
+      -1,    -1,   244,    11,   243,   247,    -1,   262,    -1,    -1,
+      -1,     5,   246,   247,    -1,   247,   109,    99,    -1,    99,
+      -1,   244,     9,    99,   117,   249,    -1,    65,    60,    -1,
+      65,    37,    -1,    65,   250,    -1,    65,    59,    -1,    65,
+      74,   255,    -1,    65,    30,    -1,    29,   251,   252,    -1,
+      -1,    39,    -1,    27,    -1,    -1,    61,    -1,    68,    -1,
+      -1,    39,    -1,    27,    -1,    -1,    61,    -1,    68,    -1,
+      -1,   111,   258,   112,    -1,    -1,   111,   259,   112,    -1,
+      -1,   111,   260,   112,    -1,    23,    -1,    23,    -1,    23,
+      -1,     6,    99,   117,   100,    -1,    99,    -1,   100,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const yytype_uint16 yyrline[] =
+{
+       0,   278,   278,   281,   289,   301,   302,   305,   329,   330,
+     333,   348,   351,   356,   363,   364,   365,   366,   367,   368,
+     369,   372,   373,   374,   377,   383,   389,   395,   402,   408,
+     415,   459,   464,   474,   518,   524,   525,   526,   527,   528,
+     529,   530,   531,   532,   533,   534,   535,   538,   550,   558,
+     575,   582,   601,   612,   632,   657,   664,   697,   704,   719,
+     774,   817,   826,   847,   857,   861,   890,   909,   909,   911,
+     918,   930,   931,   932,   935,   949,   963,   983,   994,  1006,
+    1008,  1009,  1010,  1011,  1014,  1014,  1014,  1014,  1015,  1018,
+    1022,  1027,  1034,  1041,  1048,  1071,  1094,  1095,  1096,  1097,
+    1098,  1099,  1102,  1121,  1125,  1131,  1135,  1139,  1143,  1152,
+    1161,  1165,  1170,  1176,  1187,  1187,  1188,  1190,  1194,  1198,
+    1202,  1208,  1208,  1210,  1228,  1254,  1257,  1268,  1274,  1280,
+    1281,  1288,  1294,  1300,  1308,  1314,  1320,  1328,  1334,  1340,
+    1348,  1349,  1352,  1353,  1354,  1355,  1356,  1357,  1358,  1359,
+    1360,  1361,  1362,  1365,  1374,  1378,  1382,  1388,  1397,  1401,
+    1405,  1414,  1418,  1424,  1430,  1437,  1442,  1450,  1460,  1462,
+    1470,  1476,  1480,  1484,  1490,  1501,  1510,  1514,  1519,  1523,
+    1527,  1531,  1537,  1544,  1548,  1554,  1562,  1573,  1580,  1584,
+    1590,  1600,  1611,  1615,  1633,  1642,  1645,  1651,  1655,  1659,
+    1665,  1676,  1681,  1686,  1691,  1696,  1701,  1709,  1712,  1717,
+    1730,  1738,  1749,  1757,  1757,  1759,  1759,  1761,  1771,  1776,
+    1783,  1793,  1802,  1807,  1814,  1824,  1834,  1846,  1846,  1847,
+    1847,  1849,  1859,  1867,  1877,  1885,  1893,  1902,  1913,  1917,
+    1923,  1924,  1925,  1928,  1928,  1931,  1966,  1970,  1970,  1973,
+    1980,  1989,  2003,  2012,  2021,  2025,  2034,  2043,  2054,  2061,
+    2066,  2075,  2087,  2090,  2099,  2110,  2111,  2112,  2115,  2116,
+    2117,  2120,  2121,  2124,  2125,  2128,  2129,  2132,  2143,  2154,
+    2165,  2191,  2192
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "ARBvp_10", "ARBfp_10", "ADDRESS",
+  "ALIAS", "ATTRIB", "OPTION", "OUTPUT", "PARAM", "TEMP", "END", "BIN_OP",
+  "BINSC_OP", "SAMPLE_OP", "SCALAR_OP", "TRI_OP", "VECTOR_OP", "ARL",
+  "KIL", "SWZ", "TXD_OP", "INTEGER", "REAL", "AMBIENT", "ATTENUATION",
+  "BACK", "CLIP", "COLOR", "DEPTH", "DIFFUSE", "DIRECTION", "EMISSION",
+  "ENV", "EYE", "FOG", "FOGCOORD", "FRAGMENT", "FRONT", "HALF", "INVERSE",
+  "INVTRANS", "LIGHT", "LIGHTMODEL", "LIGHTPROD", "LOCAL", "MATERIAL",
+  "MAT_PROGRAM", "MATRIX", "MATRIXINDEX", "MODELVIEW", "MVP", "NORMAL",
+  "OBJECT", "PALETTE", "PARAMS", "PLANE", "POINT_TOK", "POINTSIZE",
+  "POSITION", "PRIMARY", "PROGRAM", "PROJECTION", "RANGE", "RESULT", "ROW",
+  "SCENECOLOR", "SECONDARY", "SHININESS", "SIZE_TOK", "SPECULAR", "SPOT",
+  "STATE", "TEXCOORD", "TEXENV", "TEXGEN", "TEXGEN_Q", "TEXGEN_R",
+  "TEXGEN_S", "TEXGEN_T", "TEXTURE", "TRANSPOSE", "TEXTURE_UNIT", "TEX_1D",
+  "TEX_2D", "TEX_3D", "TEX_CUBE", "TEX_RECT", "TEX_SHADOW1D",
+  "TEX_SHADOW2D", "TEX_SHADOWRECT", "TEX_ARRAY1D", "TEX_ARRAY2D",
+  "TEX_ARRAYSHADOW1D", "TEX_ARRAYSHADOW2D", "VERTEX", "VTXATTRIB",
+  "WEIGHT", "IDENTIFIER", "USED_IDENTIFIER", "MASK4", "MASK3", "MASK2",
+  "MASK1", "SWIZZLE", "DOT_DOT", "DOT", "';'", "','", "'|'", "'['", "']'",
+  "'+'", "'-'", "'('", "')'", "'='", "'{'", "'}'", "$accept", "program",
+  "language", "optionSequence", "option", "statementSequence", "statement",
+  "instruction", "ALU_instruction", "TexInstruction", "ARL_instruction",
+  "VECTORop_instruction", "SCALARop_instruction", "BINSCop_instruction",
+  "BINop_instruction", "TRIop_instruction", "SAMPLE_instruction",
+  "KIL_instruction", "TXD_instruction", "texImageUnit", "texTarget",
+  "SWZ_instruction", "scalarSrcReg", "scalarUse", "swizzleSrcReg",
+  "maskedDstReg", "maskedAddrReg", "extendedSwizzle", "extSwizComp",
+  "extSwizSel", "srcReg", "dstReg", "progParamArray", "progParamArrayMem",
+  "progParamArrayAbs", "progParamArrayRel", "addrRegRelOffset",
+  "addrRegPosOffset", "addrRegNegOffset", "addrReg", "addrComponent",
+  "addrWriteMask", "scalarSuffix", "swizzleSuffix", "optionalMask",
+  "optionalCcMask", "ccTest", "ccTest2", "ccMaskRule", "ccMaskRule2",
+  "namingStatement", "ATTRIB_statement", "attribBinding", "vtxAttribItem",
+  "vtxAttribNum", "vtxOptWeightNum", "vtxWeightNum", "fragAttribItem",
+  "PARAM_statement", "PARAM_singleStmt", "PARAM_multipleStmt",
+  "optArraySize", "paramSingleInit", "paramMultipleInit",
+  "paramMultInitList", "paramSingleItemDecl", "paramSingleItemUse",
+  "paramMultipleItem", "stateMultipleItem", "stateSingleItem",
+  "stateMaterialItem", "stateMatProperty", "stateLightItem",
+  "stateLightProperty", "stateSpotProperty", "stateLightModelItem",
+  "stateLModProperty", "stateLightProdItem", "stateLProdProperty",
+  "stateTexEnvItem", "stateTexEnvProperty", "ambDiffSpecProperty",
+  "stateLightNumber", "stateTexGenItem", "stateTexGenType",
+  "stateTexGenCoord", "stateFogItem", "stateFogProperty",
+  "stateClipPlaneItem", "stateClipPlaneNum", "statePointItem",
+  "statePointProperty", "stateMatrixRow", "stateMatrixRows",
+  "optMatrixRows", "stateMatrixItem", "stateOptMatModifier",
+  "stateMatModifier", "stateMatrixRowNum", "stateMatrixName",
+  "stateOptModMatNum", "stateModMatNum", "statePaletteMatNum",
+  "stateProgramMatNum", "stateDepthItem", "programSingleItem",
+  "programMultipleItem", "progEnvParams", "progEnvParamNums",
+  "progEnvParam", "progLocalParams", "progLocalParamNums",
+  "progLocalParam", "progEnvParamNum", "progLocalParamNum",
+  "paramConstDecl", "paramConstUse", "paramConstScalarDecl",
+  "paramConstScalarUse", "paramConstVector", "signedFloatConstant",
+  "optionalSign", "TEMP_statement", "@1", "optVarSize",
+  "ADDRESS_statement", "@2", "varNameList", "OUTPUT_statement",
+  "resultBinding", "resultColBinding", "optResultFaceType",
+  "optResultColorType", "optFaceType", "optColorType",
+  "optTexCoordUnitNum", "optTexImageUnitNum", "optLegacyTexUnitNum",
+  "texCoordUnitNum", "texImageUnitNum", "legacyTexUnitNum",
+  "ALIAS_statement", "string", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const yytype_uint16 yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
+     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
+     295,   296,   297,   298,   299,   300,   301,   302,   303,   304,
+     305,   306,   307,   308,   309,   310,   311,   312,   313,   314,
+     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
+     325,   326,   327,   328,   329,   330,   331,   332,   333,   334,
+     335,   336,   337,   338,   339,   340,   341,   342,   343,   344,
+     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
+     355,   356,   357,   358,   359,   360,   361,   362,    59,    44,
+     124,    91,    93,    43,    45,    40,    41,    61,   123,   125
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint16 yyr1[] =
+{
+       0,   120,   121,   122,   122,   123,   123,   124,   125,   125,
+     126,   126,   127,   127,   128,   128,   128,   128,   128,   128,
+     128,   129,   129,   129,   130,   131,   132,   133,   134,   135,
+     136,   137,   137,   138,   139,   140,   140,   140,   140,   140,
+     140,   140,   140,   140,   140,   140,   140,   141,   142,   142,
+     143,   143,   144,   144,   145,   146,   147,   148,   149,   149,
+     150,   150,   150,   150,   151,   151,   152,   153,   153,   154,
+     155,   156,   156,   156,   157,   158,   159,   160,   161,   162,
+     163,   163,   163,   163,   164,   164,   164,   164,   164,   165,
+     165,   165,   166,   167,   168,   169,   170,   170,   170,   170,
+     170,   170,   171,   172,   172,   173,   173,   173,   173,   173,
+     173,   173,   173,   174,   175,   175,   176,   177,   177,   177,
+     177,   178,   178,   179,   180,   181,   181,   182,   183,   184,
+     184,   185,   185,   185,   186,   186,   186,   187,   187,   187,
+     188,   188,   189,   189,   189,   189,   189,   189,   189,   189,
+     189,   189,   189,   190,   191,   191,   191,   192,   193,   193,
+     193,   193,   193,   194,   195,   196,   196,   197,   198,   199,
+     200,   201,   201,   201,   202,   203,   204,   204,   205,   205,
+     205,   205,   206,   207,   207,   208,   209,   210,   211,   211,
+     212,   213,   214,   214,   215,   216,   216,   217,   217,   217,
+     218,   219,   219,   219,   219,   219,   219,   220,   220,   221,
+     222,   223,   224,   225,   225,   226,   226,   227,   228,   228,
+     229,   230,   231,   231,   232,   233,   234,   235,   235,   236,
+     236,   237,   238,   238,   239,   239,   239,   239,   240,   240,
+     241,   241,   241,   243,   242,   244,   244,   246,   245,   247,
+     247,   248,   249,   249,   249,   249,   249,   249,   250,   251,
+     251,   251,   252,   252,   252,   253,   253,   253,   254,   254,
+     254,   255,   255,   256,   256,   257,   257,   258,   259,   260,
+     261,   262,   262
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     4,     1,     1,     2,     0,     3,     2,     0,
+       2,     2,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     4,     4,     4,     6,     6,     8,
+       8,     2,     2,    12,     2,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     6,     2,     4,
+       2,     1,     3,     5,     3,     2,     7,     2,     1,     1,
+       1,     1,     4,     1,     1,     1,     1,     1,     1,     1,
+       3,     0,     2,     2,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     0,     1,     1,     1,     1,     0,     3,
+       3,     0,     2,     2,     1,     1,     1,     1,     1,     1,
+       1,     1,     4,     2,     2,     1,     2,     1,     2,     1,
+       2,     4,     4,     1,     0,     3,     1,     1,     2,     1,
+       2,     1,     1,     3,     6,     0,     1,     2,     4,     1,
+       3,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     3,     1,     1,     1,     5,     1,     1,
+       1,     2,     1,     1,     2,     1,     2,     6,     1,     3,
+       1,     1,     1,     1,     1,     4,     1,     1,     1,     1,
+       1,     1,     2,     1,     1,     5,     1,     2,     1,     1,
+       5,     2,     0,     6,     3,     0,     1,     1,     1,     1,
+       1,     2,     1,     1,     2,     4,     4,     0,     3,     1,
+       1,     1,     2,     1,     1,     1,     1,     5,     1,     3,
+       5,     5,     1,     3,     5,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     3,     5,     7,     9,     2,     2,
+       1,     1,     0,     0,     4,     1,     0,     0,     3,     3,
+       1,     5,     2,     2,     2,     2,     3,     2,     3,     0,
+       1,     1,     0,     1,     1,     0,     1,     1,     0,     1,
+       1,     0,     3,     0,     3,     0,     3,     1,     1,     1,
+       4,     1,     1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const yytype_uint16 yydefact[] =
+{
+       0,     3,     4,     0,     6,     1,     9,     0,     5,   246,
+     281,   282,     0,   247,     0,     0,     0,     2,     0,     0,
+       0,     0,     0,     0,     0,   242,     0,     0,     8,     0,
+      12,    13,    14,    15,    16,    17,    18,    19,    21,    22,
+      23,    20,     0,    96,    97,   121,   122,    98,     0,    99,
+     100,   101,   245,     7,     0,     0,     0,     0,     0,    65,
+       0,    88,    64,     0,     0,     0,     0,     0,    76,     0,
+       0,    94,   240,   241,    31,    32,    83,     0,     0,     0,
+      10,    11,     0,   243,   250,   248,     0,     0,   125,   242,
+     123,   259,   257,   253,   255,   252,   271,   254,   242,    84,
+      85,    86,    87,    91,   242,   242,   242,   242,   242,   242,
+      78,    55,    81,    80,    82,    92,   233,   232,     0,     0,
+       0,     0,    60,     0,   242,    83,     0,    61,    63,   134,
+     135,   213,   214,   136,   229,   230,     0,   242,     0,     0,
+       0,   280,   102,   126,     0,   127,   131,   132,   133,   227,
+     228,   231,     0,   261,   260,   262,     0,   256,     0,     0,
+      54,     0,     0,     0,    26,     0,    25,    24,   268,   119,
+     117,   271,   104,     0,     0,     0,     0,     0,     0,   265,
+       0,   265,     0,     0,   275,   271,   142,   143,   144,   145,
+     147,   146,   148,   149,   150,   151,     0,   152,   268,   109,
+       0,   107,   105,   271,     0,   114,   103,    83,     0,    52,
+       0,     0,     0,     0,   244,   249,     0,   239,   238,   263,
+     264,   258,   277,     0,   242,    95,     0,     0,    83,   242,
+       0,    48,     0,    51,     0,   242,   269,   270,   118,   120,
+       0,     0,     0,   212,   183,   184,   182,     0,   165,   267,
+     266,   164,     0,     0,     0,     0,   207,   203,     0,   202,
+     271,   195,   189,   188,   187,     0,     0,     0,     0,   108,
+       0,   110,     0,     0,   106,     0,   242,   234,    69,     0,
+      67,    68,     0,   242,   242,   251,     0,   124,   272,    28,
+      89,    90,    93,    27,     0,    79,    50,   273,     0,     0,
+     225,     0,   226,     0,   186,     0,   174,     0,   166,     0,
+     171,   172,   155,   156,   173,   153,   154,     0,     0,   201,
+       0,   204,   197,   199,   198,   194,   196,   279,     0,   170,
+     169,   176,   177,     0,     0,   116,     0,   113,     0,     0,
+      53,     0,    62,    77,    71,    47,     0,     0,     0,   242,
+      49,     0,    34,     0,   242,   220,   224,     0,     0,   265,
+     211,     0,   209,     0,   210,     0,   276,   181,   180,   178,
+     179,   175,   200,     0,   111,   112,   115,   242,   235,     0,
+       0,    70,   242,    58,    57,    59,   242,     0,     0,     0,
+     129,   137,   140,   138,   215,   216,   139,   278,     0,    35,
+      36,    37,    38,    39,    40,    41,    42,    43,    44,    45,
+      46,    30,    29,   185,   160,   162,   159,     0,   157,   158,
+       0,   206,   208,   205,   190,     0,    74,    72,    75,    73,
+       0,     0,     0,     0,   141,   192,   242,   128,   274,   163,
+     161,   167,   168,   242,   236,   242,     0,     0,     0,     0,
+     191,   130,     0,     0,     0,     0,   218,     0,   222,     0,
+     237,   242,     0,   217,     0,   221,     0,     0,    56,    33,
+     219,   223,     0,     0,   193
+};
+
+/* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int16 yydefgoto[] =
+{
+      -1,     3,     4,     6,     8,     9,    28,    29,    30,    31,
+      32,    33,    34,    35,    36,    37,    38,    39,    40,   298,
+     411,    41,   161,   231,    74,    60,    69,   345,   346,   384,
+     232,    61,   126,   279,   280,   281,   381,   427,   429,    70,
+     344,   111,   296,   115,   103,   160,    75,   227,    76,   228,
+      42,    43,   127,   206,   338,   274,   336,   172,    44,    45,
+      46,   144,    90,   287,   389,   145,   128,   390,   391,   129,
+     186,   315,   187,   418,   440,   188,   251,   189,   441,   190,
+     330,   316,   307,   191,   333,   371,   192,   246,   193,   305,
+     194,   264,   195,   434,   450,   196,   325,   326,   373,   261,
+     319,   363,   365,   361,   197,   130,   393,   394,   455,   131,
+     395,   457,   132,   301,   303,   396,   133,   149,   134,   135,
+     151,    77,    47,   139,    48,    49,    54,    85,    50,    62,
+      97,   155,   221,   252,   238,   157,   352,   266,   223,   398,
+     328,    51,    12
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -401
+static const yytype_int16 yypact[] =
+{
+     193,  -401,  -401,    27,  -401,  -401,    62,   143,  -401,    24,
+    -401,  -401,   -30,  -401,   -18,    12,    83,  -401,    15,    15,
+      15,    15,    15,    15,    67,    61,    15,    15,  -401,   127,
+    -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,
+    -401,  -401,   144,  -401,  -401,  -401,  -401,  -401,   204,  -401,
+    -401,  -401,  -401,  -401,   155,   136,   138,    34,   140,  -401,
+     147,   108,  -401,   150,   156,   157,   158,   160,  -401,   162,
+     159,  -401,  -401,  -401,  -401,  -401,   102,   -13,   163,   164,
+    -401,  -401,   165,  -401,  -401,   166,   170,    10,   235,     0,
+    -401,   141,  -401,  -401,  -401,  -401,   167,  -401,   131,  -401,
+    -401,  -401,  -401,   168,   131,   131,   131,   131,   131,   131,
+    -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,   104,    97,
+     114,    38,   169,    30,   131,   102,   171,  -401,  -401,  -401,
+    -401,  -401,  -401,  -401,  -401,  -401,    30,   131,   172,   155,
+     175,  -401,  -401,  -401,   173,  -401,  -401,  -401,  -401,  -401,
+    -401,  -401,   223,  -401,  -401,   123,   253,  -401,   177,   149,
+    -401,   178,   -10,   181,  -401,   182,  -401,  -401,   134,  -401,
+    -401,   167,  -401,   183,   184,   185,   213,    99,   186,   154,
+     187,   146,   153,     7,   188,   167,  -401,  -401,  -401,  -401,
+    -401,  -401,  -401,  -401,  -401,  -401,   215,  -401,   134,  -401,
+     190,  -401,  -401,   167,   191,   192,  -401,   102,   -48,  -401,
+       1,   195,   196,   214,   166,  -401,   189,  -401,  -401,  -401,
+    -401,  -401,  -401,   180,   131,  -401,   194,   197,   102,   131,
+      30,  -401,   203,   205,   201,   131,  -401,  -401,  -401,  -401,
+     285,   288,   289,  -401,  -401,  -401,  -401,   291,  -401,  -401,
+    -401,  -401,   248,   291,    33,   206,   207,  -401,   208,  -401,
+     167,    14,  -401,  -401,  -401,   293,   292,    92,   209,  -401,
+     299,  -401,   301,   299,  -401,   216,   131,  -401,  -401,   217,
+    -401,  -401,   221,   131,   131,  -401,   212,  -401,  -401,  -401,
+    -401,  -401,  -401,  -401,   218,  -401,  -401,   220,   224,   225,
+    -401,   226,  -401,   227,  -401,   228,  -401,   230,  -401,   231,
+    -401,  -401,  -401,  -401,  -401,  -401,  -401,   304,   309,  -401,
+     312,  -401,  -401,  -401,  -401,  -401,  -401,  -401,   232,  -401,
+    -401,  -401,  -401,   161,   313,  -401,   233,  -401,   234,   238,
+    -401,    13,  -401,  -401,   137,  -401,   242,   -15,   243,     3,
+    -401,   314,  -401,   133,   131,  -401,  -401,   296,    94,   146,
+    -401,   245,  -401,   246,  -401,   247,  -401,  -401,  -401,  -401,
+    -401,  -401,  -401,   249,  -401,  -401,  -401,   131,  -401,   332,
+     337,  -401,   131,  -401,  -401,  -401,   131,   142,   114,    28,
+    -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,   250,  -401,
+    -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,
+    -401,  -401,  -401,  -401,  -401,  -401,  -401,   331,  -401,  -401,
+      68,  -401,  -401,  -401,  -401,    43,  -401,  -401,  -401,  -401,
+     255,   256,   257,   258,  -401,   300,     3,  -401,  -401,  -401,
+    -401,  -401,  -401,   131,  -401,   131,   201,   285,   288,   259,
+    -401,  -401,   252,   264,   265,   263,   261,   266,   270,   313,
+    -401,   131,   133,  -401,   285,  -401,   288,    80,  -401,  -401,
+    -401,  -401,   313,   267,  -401
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yytype_int16 yypgoto[] =
+{
+    -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,
+    -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,   -69,
+     -82,  -401,  -100,   151,   -86,   210,  -401,  -401,  -366,  -401,
+     -54,  -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,   174,
+    -401,  -401,  -401,  -118,  -401,  -401,   229,  -401,  -401,  -401,
+    -401,  -401,   295,  -401,  -401,  -401,   110,  -401,  -401,  -401,
+    -401,  -401,  -401,  -401,  -401,  -401,  -401,   -51,  -401,   -88,
+    -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,
+    -401,  -311,   139,  -401,  -401,  -401,  -401,  -401,  -401,  -401,
+    -401,  -401,  -401,  -401,  -401,    -2,  -401,  -401,  -400,  -401,
+    -401,  -401,  -401,  -401,  -401,   298,  -401,  -401,  -401,  -401,
+    -401,  -401,  -401,  -390,  -295,   302,  -401,  -401,  -136,   -87,
+    -120,   -89,  -401,  -401,  -401,  -401,  -401,   251,  -401,   176,
+    -401,  -401,  -401,  -176,   198,  -153,  -401,  -401,  -401,  -401,
+    -401,  -401,    -6
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -230
+static const yytype_int16 yytable[] =
+{
+     152,   146,   150,    52,   208,   254,   164,   209,   383,   167,
+     116,   117,   158,   116,   117,   162,   430,   162,   239,   163,
+     162,   165,   166,   125,   278,   118,   233,     5,   118,    13,
+      14,    15,   267,   262,    16,   152,    17,    18,    19,    20,
+      21,    22,    23,    24,    25,    26,    27,   419,   118,   119,
+     271,   212,   119,   116,   117,   322,   323,   456,   310,   467,
+     120,   276,   119,   120,   311,   387,   312,   198,   118,   207,
+       7,   277,   473,   120,   470,   199,   388,   263,    53,   453,
+      58,    55,   211,   121,    10,    11,   121,   122,   200,   275,
+     122,   201,   119,   310,   233,   468,   324,   123,   202,   311,
+     230,    68,   313,   120,   314,   124,   121,   321,   124,   442,
+     292,    56,   203,    72,    73,    59,    72,    73,   124,   310,
+     414,   124,   377,    10,    11,   311,   121,   331,   244,   293,
+     122,   173,   378,   168,   415,   204,   205,   436,   289,   314,
+     162,   169,   175,   174,   176,    88,   332,   437,   124,   299,
+     177,    89,   443,   458,   416,   245,   341,   178,   179,   180,
+      71,   181,   444,   182,   170,   314,   417,    68,   153,    91,
+      92,   471,   183,   249,    72,    73,   432,    93,   171,   248,
+     154,   249,    57,   420,   219,   250,   472,   152,   433,   184,
+     185,   220,   424,   250,   347,   236,     1,     2,   348,    94,
+      95,   255,   237,   112,   256,   257,   113,   114,   258,    99,
+     100,   101,   102,    82,    96,    83,   259,   399,   400,   401,
+     402,   403,   404,   405,   406,   407,   408,   409,   410,    63,
+      64,    65,    66,    67,   260,    80,    78,    79,   367,   368,
+     369,   370,    10,    11,    72,    73,   217,   218,    71,   225,
+     379,   380,    81,    86,    84,    87,    98,   425,   143,   104,
+     152,   392,   150,   110,   138,   105,   106,   107,   412,   108,
+     141,   109,   136,   137,   215,   140,   222,   243,   156,    58,
+     -66,   268,   210,   159,   297,   216,   224,   229,   152,   213,
+     234,   235,   288,   347,   240,   241,   242,   247,   253,   265,
+     431,   270,   272,   273,   283,   284,   286,   295,   300,  -229,
+     290,   302,   304,   291,   306,   308,   327,   317,   318,   320,
+     334,   329,   335,   452,   337,   343,   340,   360,   350,   342,
+     349,   351,   362,   353,   354,   364,   372,   397,   355,   356,
+     357,   385,   358,   359,   366,   374,   375,   152,   392,   150,
+     376,   382,   386,   413,   152,   426,   347,   421,   422,   423,
+     428,   424,   438,   439,   445,   446,   449,   464,   447,   448,
+     459,   460,   347,   461,   462,   463,   466,   454,   465,   474,
+     469,   294,   142,   339,   282,   451,   435,   147,   226,   285,
+     214,   148,   309,     0,     0,     0,   269
+};
+
+static const yytype_int16 yycheck[] =
+{
+      89,    89,    89,     9,   124,   181,   106,   125,    23,   109,
+      23,    24,    98,    23,    24,   104,   382,   106,   171,   105,
+     109,   107,   108,    77,    23,    38,   162,     0,    38,     5,
+       6,     7,   185,    26,    10,   124,    12,    13,    14,    15,
+      16,    17,    18,    19,    20,    21,    22,   358,    38,    62,
+     203,   137,    62,    23,    24,    41,    42,   447,    25,   459,
+      73,   109,    62,    73,    31,    62,    33,    29,    38,   123,
+       8,   119,   472,    73,   464,    37,    73,    70,   108,   445,
+      65,    99,   136,    96,    99,   100,    96,   100,    50,   207,
+     100,    53,    62,    25,   230,   461,    82,   110,    60,    31,
+     110,   100,    69,    73,    71,   118,    96,   260,   118,   420,
+     228,    99,    74,   113,   114,   100,   113,   114,   118,    25,
+      26,   118,   109,    99,   100,    31,    96,    35,    29,   229,
+     100,    34,   119,    29,    40,    97,    98,   109,   224,    71,
+     229,    37,    28,    46,    30,   111,    54,   119,   118,   235,
+      36,   117,   109,   448,    60,    56,   276,    43,    44,    45,
+      99,    47,   119,    49,    60,    71,    72,   100,    27,    29,
+      30,   466,    58,    27,   113,   114,    34,    37,    74,    25,
+      39,    27,    99,   359,    61,    39,   106,   276,    46,    75,
+      76,    68,   112,    39,   283,    61,     3,     4,   284,    59,
+      60,    48,    68,   101,    51,    52,   104,   105,    55,   101,
+     102,   103,   104,     9,    74,    11,    63,    84,    85,    86,
+      87,    88,    89,    90,    91,    92,    93,    94,    95,    19,
+      20,    21,    22,    23,    81,   108,    26,    27,    77,    78,
+      79,    80,    99,   100,   113,   114,    23,    24,    99,   100,
+     113,   114,   108,   117,    99,   117,   109,   377,    23,   109,
+     349,   349,   349,   104,    99,   109,   109,   109,   354,   109,
+     100,   109,   109,   109,    99,   109,    23,    64,   111,    65,
+     111,    66,   111,   115,    83,   112,   109,   109,   377,   117,
+     109,   109,   112,   382,   111,   111,   111,   111,   111,   111,
+     386,   111,   111,   111,   109,   109,   117,   104,    23,   104,
+     116,    23,    23,   116,    23,    67,    23,   111,   111,   111,
+     111,    29,    23,   443,    23,   104,   110,    23,   110,   112,
+     118,   111,    23,   109,   109,    23,    23,    23,   112,   112,
+     112,   347,   112,   112,   112,   112,   112,   436,   436,   436,
+     112,   109,   109,    57,   443,    23,   445,   112,   112,   112,
+      23,   112,   112,    32,   109,   109,    66,   106,   111,   111,
+     111,   119,   461,   109,   109,   112,   106,   446,   112,   112,
+     462,   230,    87,   273,   210,   436,   388,    89,   159,   213,
+     139,    89,   253,    -1,    -1,    -1,   198
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const yytype_uint16 yystos[] =
+{
+       0,     3,     4,   121,   122,     0,   123,     8,   124,   125,
+      99,   100,   262,     5,     6,     7,    10,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,   126,   127,
+     128,   129,   130,   131,   132,   133,   134,   135,   136,   137,
+     138,   141,   170,   171,   178,   179,   180,   242,   244,   245,
+     248,   261,   262,   108,   246,    99,    99,    99,    65,   100,
+     145,   151,   249,   145,   145,   145,   145,   145,   100,   146,
+     159,    99,   113,   114,   144,   166,   168,   241,   145,   145,
+     108,   108,     9,    11,    99,   247,   117,   117,   111,   117,
+     182,    29,    30,    37,    59,    60,    74,   250,   109,   101,
+     102,   103,   104,   164,   109,   109,   109,   109,   109,   109,
+     104,   161,   101,   104,   105,   163,    23,    24,    38,    62,
+      73,    96,   100,   110,   118,   150,   152,   172,   186,   189,
+     225,   229,   232,   236,   238,   239,   109,   109,    99,   243,
+     109,   100,   172,    23,   181,   185,   189,   225,   235,   237,
+     239,   240,   241,    27,    39,   251,   111,   255,   144,   115,
+     165,   142,   241,   144,   142,   144,   144,   142,    29,    37,
+      60,    74,   177,    34,    46,    28,    30,    36,    43,    44,
+      45,    47,    49,    58,    75,    76,   190,   192,   195,   197,
+     199,   203,   206,   208,   210,   212,   215,   224,    29,    37,
+      50,    53,    60,    74,    97,    98,   173,   150,   240,   163,
+     111,   150,   144,   117,   247,    99,   112,    23,    24,    61,
+      68,   252,    23,   258,   109,   100,   166,   167,   169,   109,
+     110,   143,   150,   238,   109,   109,    61,    68,   254,   255,
+     111,   111,   111,    64,    29,    56,   207,   111,    25,    27,
+      39,   196,   253,   111,   253,    48,    51,    52,    55,    63,
+      81,   219,    26,    70,   211,   111,   257,   255,    66,   254,
+     111,   255,   111,   111,   175,   163,   109,   119,    23,   153,
+     154,   155,   159,   109,   109,   249,   117,   183,   112,   144,
+     116,   116,   163,   142,   143,   104,   162,    83,   139,   144,
+      23,   233,    23,   234,    23,   209,    23,   202,    67,   202,
+      25,    31,    33,    69,    71,   191,   201,   111,   111,   220,
+     111,   255,    41,    42,    82,   216,   217,    23,   260,    29,
+     200,    35,    54,   204,   111,    23,   176,    23,   174,   176,
+     110,   240,   112,   104,   160,   147,   148,   241,   144,   118,
+     110,   111,   256,   109,   109,   112,   112,   112,   112,   112,
+      23,   223,    23,   221,    23,   222,   112,    77,    78,    79,
+      80,   205,    23,   218,   112,   112,   112,   109,   119,   113,
+     114,   156,   109,    23,   149,   262,   109,    62,    73,   184,
+     187,   188,   189,   226,   227,   230,   235,    23,   259,    84,
+      85,    86,    87,    88,    89,    90,    91,    92,    93,    94,
+      95,   140,   144,    57,    26,    40,    60,    72,   193,   201,
+     253,   112,   112,   112,   112,   240,    23,   157,    23,   158,
+     148,   144,    34,    46,   213,   215,   109,   119,   112,    32,
+     194,   198,   201,   109,   119,   109,   109,   111,   111,    66,
+     214,   187,   240,   148,   139,   228,   233,   231,   234,   111,
+     119,   109,   109,   112,   106,   112,   106,   218,   148,   140,
+     233,   234,   106,   218,   112
+};
+
+#define yyerrok                (yyerrstatus = 0)
+#define yyclearin      (yychar = YYEMPTY)
+#define YYEMPTY                (-2)
+#define YYEOF          0
+
+#define YYACCEPT       goto yyacceptlab
+#define YYABORT                goto yyabortlab
+#define YYERROR                goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+
+#define YYFAIL         goto yyerrlab
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)                                 \
+do                                                             \
+  if (yychar == YYEMPTY && yylen == 1)                         \
+    {                                                          \
+      yychar = (Token);                                                \
+      yylval = (Value);                                                \
+      yytoken = YYTRANSLATE (yychar);                          \
+      YYPOPSTACK (1);                                          \
+      goto yybackup;                                           \
+    }                                                          \
+  else                                                         \
+    {                                                          \
+      yyerror (&yylloc, state, YY_("syntax error: cannot back up")); \
+      YYERROR;                                                 \
+    }                                                          \
+while (YYID (0))
+
+
+#define YYTERROR       1
+#define YYERRCODE      256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)                               \
+    do                                                                 \
+      if (YYID (N))                                                    \
+       {                                                               \
+         (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
+         (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
+         (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
+         (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
+       }                                                               \
+      else                                                             \
+       {                                                               \
+         (Current).first_line   = (Current).last_line   =              \
+           YYRHSLOC (Rhs, 0).last_line;                                \
+         (Current).first_column = (Current).last_column =              \
+           YYRHSLOC (Rhs, 0).last_column;                              \
+       }                                                               \
+    while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)                 \
+     fprintf (File, "%d.%d-%d.%d",                     \
+             (Loc).first_line, (Loc).first_column,     \
+             (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval, &yylloc, scanner)
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)                       \
+do {                                           \
+  if (yydebug)                                 \
+    YYFPRINTF Args;                            \
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                   \
+do {                                                                     \
+  if (yydebug)                                                           \
+    {                                                                    \
+      YYFPRINTF (stderr, "%s ", Title);                                          \
+      yy_symbol_print (stderr,                                           \
+                 Type, Value, Location, state); \
+      YYFPRINTF (stderr, "\n");                                                  \
+    }                                                                    \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct asm_parser_state *state)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+    YYLTYPE const * const yylocationp;
+    struct asm_parser_state *state;
+#endif
+{
+  if (!yyvaluep)
+    return;
+  YYUSE (yylocationp);
+  YYUSE (state);
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+  YYUSE (yyoutput);
+# endif
+  switch (yytype)
+    {
+      default:
+       break;
+    }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct asm_parser_state *state)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, state)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+    YYLTYPE const * const yylocationp;
+    struct asm_parser_state *state;
+#endif
+{
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  YY_LOCATION_PRINT (yyoutput, *yylocationp);
+  YYFPRINTF (yyoutput, ": ");
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state);
+  YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+#else
+static void
+yy_stack_print (yybottom, yytop)
+    yytype_int16 *yybottom;
+    yytype_int16 *yytop;
+#endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (; yybottom <= yytop; yybottom++)
+    {
+      int yybot = *yybottom;
+      YYFPRINTF (stderr, " %d", yybot);
+    }
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)                           \
+do {                                                           \
+  if (yydebug)                                                 \
+    yy_stack_print ((Bottom), (Top));                          \
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, struct asm_parser_state *state)
+#else
+static void
+yy_reduce_print (yyvsp, yylsp, yyrule, state)
+    YYSTYPE *yyvsp;
+    YYLTYPE *yylsp;
+    int yyrule;
+    struct asm_parser_state *state;
+#endif
+{
+  int yynrhs = yyr2[yyrule];
+  int yyi;
+  unsigned long int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+            yyrule - 1, yylno);
+  /* The symbols being reduced.  */
+  for (yyi = 0; yyi < yynrhs; yyi++)
+    {
+      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
+      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+                      &(yyvsp[(yyi + 1) - (yynrhs)])
+                      , &(yylsp[(yyi + 1) - (yynrhs)])                , state);
+      YYFPRINTF (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)         \
+do {                                   \
+  if (yydebug)                         \
+    yy_reduce_print (yyvsp, yylsp, Rule, state); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef        YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+\f
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined __GLIBC__ && defined _STRING_H
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+    const char *yystr;
+#endif
+{
+  YYSIZE_T yylen;
+  for (yylen = 0; yystr[yylen]; yylen++)
+    continue;
+  return yylen;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+    char *yydest;
+    const char *yysrc;
+#endif
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      YYSIZE_T yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+       switch (*++yyp)
+         {
+         case '\'':
+         case ',':
+           goto do_not_strip_quotes;
+
+         case '\\':
+           if (*++yyp != '\\')
+             goto do_not_strip_quotes;
+           /* Fall through.  */
+         default:
+           if (yyres)
+             yyres[yyn] = *yyp;
+           yyn++;
+           break;
+
+         case '"':
+           if (yyres)
+             yyres[yyn] = '\0';
+           return yyn;
+         }
+    do_not_strip_quotes: ;
+    }
+
+  if (! yyres)
+    return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
+   including the terminating null byte.  If YYRESULT is null, do not
+   copy anything; just return the number of bytes that would be
+   copied.  As a special case, return 0 if an ordinary "syntax error"
+   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
+   size calculation.  */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+  int yyn = yypact[yystate];
+
+  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+    return 0;
+  else
+    {
+      int yytype = YYTRANSLATE (yychar);
+      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+      YYSIZE_T yysize = yysize0;
+      YYSIZE_T yysize1;
+      int yysize_overflow = 0;
+      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+      int yyx;
+
+# if 0
+      /* This is so xgettext sees the translatable formats that are
+        constructed on the fly.  */
+      YY_("syntax error, unexpected %s");
+      YY_("syntax error, unexpected %s, expecting %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+      char *yyfmt;
+      char const *yyf;
+      static char const yyunexpected[] = "syntax error, unexpected %s";
+      static char const yyexpecting[] = ", expecting %s";
+      static char const yyor[] = " or %s";
+      char yyformat[sizeof yyunexpected
+                   + sizeof yyexpecting - 1
+                   + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+                      * (sizeof yyor - 1))];
+      char const *yyprefix = yyexpecting;
+
+      /* Start YYX at -YYN if negative to avoid negative indexes in
+        YYCHECK.  */
+      int yyxbegin = yyn < 0 ? -yyn : 0;
+
+      /* Stay within bounds of both yycheck and yytname.  */
+      int yychecklim = YYLAST - yyn + 1;
+      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+      int yycount = 1;
+
+      yyarg[0] = yytname[yytype];
+      yyfmt = yystpcpy (yyformat, yyunexpected);
+
+      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+       if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+         {
+           if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+             {
+               yycount = 1;
+               yysize = yysize0;
+               yyformat[sizeof yyunexpected - 1] = '\0';
+               break;
+             }
+           yyarg[yycount++] = yytname[yyx];
+           yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+           yysize_overflow |= (yysize1 < yysize);
+           yysize = yysize1;
+           yyfmt = yystpcpy (yyfmt, yyprefix);
+           yyprefix = yyor;
+         }
+
+      yyf = YY_(yyformat);
+      yysize1 = yysize + yystrlen (yyf);
+      yysize_overflow |= (yysize1 < yysize);
+      yysize = yysize1;
+
+      if (yysize_overflow)
+       return YYSIZE_MAXIMUM;
+
+      if (yyresult)
+       {
+         /* Avoid sprintf, as that infringes on the user's name space.
+            Don't have undefined behavior even if the translation
+            produced a string with the wrong number of "%s"s.  */
+         char *yyp = yyresult;
+         int yyi = 0;
+         while ((*yyp = *yyf) != '\0')
+           {
+             if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+               {
+                 yyp += yytnamerr (yyp, yyarg[yyi++]);
+                 yyf += 2;
+               }
+             else
+               {
+                 yyp++;
+                 yyf++;
+               }
+           }
+       }
+      return yysize;
+    }
+}
+#endif /* YYERROR_VERBOSE */
+\f
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, struct asm_parser_state *state)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep, yylocationp, state)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+    YYLTYPE *yylocationp;
+    struct asm_parser_state *state;
+#endif
+{
+  YYUSE (yyvaluep);
+  YYUSE (yylocationp);
+  YYUSE (state);
+
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  switch (yytype)
+    {
+
+      default:
+       break;
+    }
+}
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (struct asm_parser_state *state);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+
+
+/*-------------------------.
+| yyparse or yypush_parse.  |
+`-------------------------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+    void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (struct asm_parser_state *state)
+#else
+int
+yyparse (state)
+    struct asm_parser_state *state;
+#endif
+#endif
+{
+/* The lookahead symbol.  */
+int yychar;
+
+/* The semantic value of the lookahead symbol.  */
+YYSTYPE yylval;
+
+/* Location data for the lookahead symbol.  */
+YYLTYPE yylloc;
+
+    /* Number of syntax errors so far.  */
+    int yynerrs;
+
+    int yystate;
+    /* Number of tokens to shift before error messages enabled.  */
+    int yyerrstatus;
+
+    /* The stacks and their tools:
+       `yyss': related to states.
+       `yyvs': related to semantic values.
+       `yyls': related to locations.
+
+       Refer to the stacks thru separate pointers, to allow yyoverflow
+       to reallocate them elsewhere.  */
+
+    /* The state stack.  */
+    yytype_int16 yyssa[YYINITDEPTH];
+    yytype_int16 *yyss;
+    yytype_int16 *yyssp;
+
+    /* The semantic value stack.  */
+    YYSTYPE yyvsa[YYINITDEPTH];
+    YYSTYPE *yyvs;
+    YYSTYPE *yyvsp;
+
+    /* The location stack.  */
+    YYLTYPE yylsa[YYINITDEPTH];
+    YYLTYPE *yyls;
+    YYLTYPE *yylsp;
+
+    /* The locations where the error started and ended.  */
+    YYLTYPE yyerror_range[2];
+
+    YYSIZE_T yystacksize;
+
+  int yyn;
+  int yyresult;
+  /* Lookahead token as an internal (translated) token number.  */
+  int yytoken;
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+  YYLTYPE yyloc;
+
+#if YYERROR_VERBOSE
+  /* Buffer for error messages, and its allocated size.  */
+  char yymsgbuf[128];
+  char *yymsg = yymsgbuf;
+  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
+
+  /* The number of symbols on the RHS of the reduced rule.
+     Keep to zero when no symbol should be popped.  */
+  int yylen = 0;
+
+  yytoken = 0;
+  yyss = yyssa;
+  yyvs = yyvsa;
+  yyls = yylsa;
+  yystacksize = YYINITDEPTH;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY; /* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+  yyssp = yyss;
+  yyvsp = yyvs;
+  yylsp = yyls;
+
+#if YYLTYPE_IS_TRIVIAL
+  /* Initialize the default location before parsing starts.  */
+  yylloc.first_line   = yylloc.last_line   = 1;
+  yylloc.first_column = yylloc.last_column = 1;
+#endif
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed.  So pushing a state here evens the stacks.  */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+       /* Give user a chance to reallocate the stack.  Use copies of
+          these so that the &'s don't force the real ones into
+          memory.  */
+       YYSTYPE *yyvs1 = yyvs;
+       yytype_int16 *yyss1 = yyss;
+       YYLTYPE *yyls1 = yyls;
+
+       /* Each stack pointer address is followed by the size of the
+          data in use in that stack, in bytes.  This used to be a
+          conditional around just the two extra args, but that might
+          be undefined if yyoverflow is a macro.  */
+       yyoverflow (YY_("memory exhausted"),
+                   &yyss1, yysize * sizeof (*yyssp),
+                   &yyvs1, yysize * sizeof (*yyvsp),
+                   &yyls1, yysize * sizeof (*yylsp),
+                   &yystacksize);
+
+       yyls = yyls1;
+       yyss = yyss1;
+       yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyexhaustedlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+       goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+       yystacksize = YYMAXDEPTH;
+
+      {
+       yytype_int16 *yyss1 = yyss;
+       union yyalloc *yyptr =
+         (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+       if (! yyptr)
+         goto yyexhaustedlab;
+       YYSTACK_RELOCATE (yyss_alloc, yyss);
+       YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+       YYSTACK_RELOCATE (yyls_alloc, yyls);
+#  undef YYSTACK_RELOCATE
+       if (yyss1 != yyssa)
+         YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+      yylsp = yyls + yysize - 1;
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+                 (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+       YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  if (yystate == YYFINAL)
+    YYACCEPT;
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+  /* Do appropriate processing given the current state.  Read a
+     lookahead token if we need one and don't already have one.  */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a lookahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+       goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  /* Shift the lookahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+  /* Discard the shifted token.  */
+  yychar = YYEMPTY;
+
+  yystate = yyn;
+  *++yyvsp = yylval;
+  *++yylsp = yylloc;
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+  /* Default location.  */
+  YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 3:
+
+/* Line 1455 of yacc.c  */
+#line 282 "program_parse.y"
+    {
+          if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid fragment program header");
+
+          }
+          state->mode = ARB_vertex;
+       ;}
+    break;
+
+  case 4:
+
+/* Line 1455 of yacc.c  */
+#line 290 "program_parse.y"
+    {
+          if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid vertex program header");
+          }
+          state->mode = ARB_fragment;
+
+          state->option.TexRect =
+             (state->ctx->Extensions.NV_texture_rectangle != GL_FALSE);
+       ;}
+    break;
+
+  case 7:
+
+/* Line 1455 of yacc.c  */
+#line 306 "program_parse.y"
+    {
+          int valid = 0;
+
+          if (state->mode == ARB_vertex) {
+             valid = _mesa_ARBvp_parse_option(state, (yyvsp[(2) - (3)].string));
+          } else if (state->mode == ARB_fragment) {
+             valid = _mesa_ARBfp_parse_option(state, (yyvsp[(2) - (3)].string));
+          }
+
+
+          free((yyvsp[(2) - (3)].string));
+
+          if (!valid) {
+             const char *const err_str = (state->mode == ARB_vertex)
+                ? "invalid ARB vertex program option"
+                : "invalid ARB fragment program option";
+
+             yyerror(& (yylsp[(2) - (3)]), state, err_str);
+             YYERROR;
+          }
+       ;}
+    break;
+
+  case 10:
+
+/* Line 1455 of yacc.c  */
+#line 334 "program_parse.y"
+    {
+          if ((yyvsp[(1) - (2)].inst) != NULL) {
+             if (state->inst_tail == NULL) {
+                state->inst_head = (yyvsp[(1) - (2)].inst);
+             } else {
+                state->inst_tail->next = (yyvsp[(1) - (2)].inst);
+             }
+
+             state->inst_tail = (yyvsp[(1) - (2)].inst);
+             (yyvsp[(1) - (2)].inst)->next = NULL;
+
+             state->prog->NumInstructions++;
+          }
+       ;}
+    break;
+
+  case 12:
+
+/* Line 1455 of yacc.c  */
+#line 352 "program_parse.y"
+    {
+          (yyval.inst) = (yyvsp[(1) - (1)].inst);
+          state->prog->NumAluInstructions++;
+       ;}
+    break;
+
+  case 13:
+
+/* Line 1455 of yacc.c  */
+#line 357 "program_parse.y"
+    {
+          (yyval.inst) = (yyvsp[(1) - (1)].inst);
+          state->prog->NumTexInstructions++;
+       ;}
+    break;
+
+  case 24:
+
+/* Line 1455 of yacc.c  */
+#line 378 "program_parse.y"
+    {
+          (yyval.inst) = asm_instruction_ctor(OPCODE_ARL, & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL);
+       ;}
+    break;
+
+  case 25:
+
+/* Line 1455 of yacc.c  */
+#line 384 "program_parse.y"
+    {
+          (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (4)].temp_inst), & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL);
+       ;}
+    break;
+
+  case 26:
+
+/* Line 1455 of yacc.c  */
+#line 390 "program_parse.y"
+    {
+          (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (4)].temp_inst), & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL);
+       ;}
+    break;
+
+  case 27:
+
+/* Line 1455 of yacc.c  */
+#line 396 "program_parse.y"
+    {
+          (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (6)].temp_inst), & (yyvsp[(2) - (6)].dst_reg), & (yyvsp[(4) - (6)].src_reg), & (yyvsp[(6) - (6)].src_reg), NULL);
+       ;}
+    break;
+
+  case 28:
+
+/* Line 1455 of yacc.c  */
+#line 403 "program_parse.y"
+    {
+          (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (6)].temp_inst), & (yyvsp[(2) - (6)].dst_reg), & (yyvsp[(4) - (6)].src_reg), & (yyvsp[(6) - (6)].src_reg), NULL);
+       ;}
+    break;
+
+  case 29:
+
+/* Line 1455 of yacc.c  */
+#line 410 "program_parse.y"
+    {
+          (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (8)].temp_inst), & (yyvsp[(2) - (8)].dst_reg), & (yyvsp[(4) - (8)].src_reg), & (yyvsp[(6) - (8)].src_reg), & (yyvsp[(8) - (8)].src_reg));
+       ;}
+    break;
+
+  case 30:
+
+/* Line 1455 of yacc.c  */
+#line 416 "program_parse.y"
+    {
+          (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (8)].temp_inst), & (yyvsp[(2) - (8)].dst_reg), & (yyvsp[(4) - (8)].src_reg), NULL, NULL);
+          if ((yyval.inst) != NULL) {
+             const GLbitfield tex_mask = (1U << (yyvsp[(6) - (8)].integer));
+             GLbitfield shadow_tex = 0;
+             GLbitfield target_mask = 0;
+
+
+             (yyval.inst)->Base.TexSrcUnit = (yyvsp[(6) - (8)].integer);
+
+             if ((yyvsp[(8) - (8)].integer) < 0) {
+                shadow_tex = tex_mask;
+
+                (yyval.inst)->Base.TexSrcTarget = -(yyvsp[(8) - (8)].integer);
+                (yyval.inst)->Base.TexShadow = 1;
+             } else {
+                (yyval.inst)->Base.TexSrcTarget = (yyvsp[(8) - (8)].integer);
+             }
+
+             target_mask = (1U << (yyval.inst)->Base.TexSrcTarget);
+
+             /* If this texture unit was previously accessed and that access
+              * had a different texture target, generate an error.
+              *
+              * If this texture unit was previously accessed and that access
+              * had a different shadow mode, generate an error.
+              */
+             if ((state->prog->TexturesUsed[(yyvsp[(6) - (8)].integer)] != 0)
+                 && ((state->prog->TexturesUsed[(yyvsp[(6) - (8)].integer)] != target_mask)
+                     || ((state->prog->ShadowSamplers & tex_mask)
+                         != shadow_tex))) {
+                yyerror(& (yylsp[(8) - (8)]), state,
+                        "multiple targets used on one texture image unit");
+                YYERROR;
+             }
+
+
+             state->prog->TexturesUsed[(yyvsp[(6) - (8)].integer)] |= target_mask;
+             state->prog->ShadowSamplers |= shadow_tex;
+          }
+       ;}
+    break;
+
+  case 31:
+
+/* Line 1455 of yacc.c  */
+#line 460 "program_parse.y"
+    {
+          (yyval.inst) = asm_instruction_ctor(OPCODE_KIL, NULL, & (yyvsp[(2) - (2)].src_reg), NULL, NULL);
+          state->fragment.UsesKill = 1;
+       ;}
+    break;
+
+  case 32:
+
+/* Line 1455 of yacc.c  */
+#line 465 "program_parse.y"
+    {
+          (yyval.inst) = asm_instruction_ctor(OPCODE_KIL_NV, NULL, NULL, NULL, NULL);
+          (yyval.inst)->Base.DstReg.CondMask = (yyvsp[(2) - (2)].dst_reg).CondMask;
+          (yyval.inst)->Base.DstReg.CondSwizzle = (yyvsp[(2) - (2)].dst_reg).CondSwizzle;
+          (yyval.inst)->Base.DstReg.CondSrc = (yyvsp[(2) - (2)].dst_reg).CondSrc;
+          state->fragment.UsesKill = 1;
+       ;}
+    break;
+
+  case 33:
+
+/* Line 1455 of yacc.c  */
+#line 475 "program_parse.y"
+    {
+          (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (12)].temp_inst), & (yyvsp[(2) - (12)].dst_reg), & (yyvsp[(4) - (12)].src_reg), & (yyvsp[(6) - (12)].src_reg), & (yyvsp[(8) - (12)].src_reg));
+          if ((yyval.inst) != NULL) {
+             const GLbitfield tex_mask = (1U << (yyvsp[(10) - (12)].integer));
+             GLbitfield shadow_tex = 0;
+             GLbitfield target_mask = 0;
+
+
+             (yyval.inst)->Base.TexSrcUnit = (yyvsp[(10) - (12)].integer);
+
+             if ((yyvsp[(12) - (12)].integer) < 0) {
+                shadow_tex = tex_mask;
+
+                (yyval.inst)->Base.TexSrcTarget = -(yyvsp[(12) - (12)].integer);
+                (yyval.inst)->Base.TexShadow = 1;
+             } else {
+                (yyval.inst)->Base.TexSrcTarget = (yyvsp[(12) - (12)].integer);
+             }
+
+             target_mask = (1U << (yyval.inst)->Base.TexSrcTarget);
+
+             /* If this texture unit was previously accessed and that access
+              * had a different texture target, generate an error.
+              *
+              * If this texture unit was previously accessed and that access
+              * had a different shadow mode, generate an error.
+              */
+             if ((state->prog->TexturesUsed[(yyvsp[(10) - (12)].integer)] != 0)
+                 && ((state->prog->TexturesUsed[(yyvsp[(10) - (12)].integer)] != target_mask)
+                     || ((state->prog->ShadowSamplers & tex_mask)
+                         != shadow_tex))) {
+                yyerror(& (yylsp[(12) - (12)]), state,
+                        "multiple targets used on one texture image unit");
+                YYERROR;
+             }
+
+
+             state->prog->TexturesUsed[(yyvsp[(10) - (12)].integer)] |= target_mask;
+             state->prog->ShadowSamplers |= shadow_tex;
+          }
+       ;}
+    break;
+
+  case 34:
+
+/* Line 1455 of yacc.c  */
+#line 519 "program_parse.y"
+    {
+          (yyval.integer) = (yyvsp[(2) - (2)].integer);
+       ;}
+    break;
+
+  case 35:
+
+/* Line 1455 of yacc.c  */
+#line 524 "program_parse.y"
+    { (yyval.integer) = TEXTURE_1D_INDEX; ;}
+    break;
+
+  case 36:
+
+/* Line 1455 of yacc.c  */
+#line 525 "program_parse.y"
+    { (yyval.integer) = TEXTURE_2D_INDEX; ;}
+    break;
+
+  case 37:
+
+/* Line 1455 of yacc.c  */
+#line 526 "program_parse.y"
+    { (yyval.integer) = TEXTURE_3D_INDEX; ;}
+    break;
+
+  case 38:
+
+/* Line 1455 of yacc.c  */
+#line 527 "program_parse.y"
+    { (yyval.integer) = TEXTURE_CUBE_INDEX; ;}
+    break;
+
+  case 39:
+
+/* Line 1455 of yacc.c  */
+#line 528 "program_parse.y"
+    { (yyval.integer) = TEXTURE_RECT_INDEX; ;}
+    break;
+
+  case 40:
+
+/* Line 1455 of yacc.c  */
+#line 529 "program_parse.y"
+    { (yyval.integer) = -TEXTURE_1D_INDEX; ;}
+    break;
+
+  case 41:
+
+/* Line 1455 of yacc.c  */
+#line 530 "program_parse.y"
+    { (yyval.integer) = -TEXTURE_2D_INDEX; ;}
+    break;
+
+  case 42:
+
+/* Line 1455 of yacc.c  */
+#line 531 "program_parse.y"
+    { (yyval.integer) = -TEXTURE_RECT_INDEX; ;}
+    break;
+
+  case 43:
+
+/* Line 1455 of yacc.c  */
+#line 532 "program_parse.y"
+    { (yyval.integer) = TEXTURE_1D_ARRAY_INDEX; ;}
+    break;
+
+  case 44:
+
+/* Line 1455 of yacc.c  */
+#line 533 "program_parse.y"
+    { (yyval.integer) = TEXTURE_2D_ARRAY_INDEX; ;}
+    break;
+
+  case 45:
+
+/* Line 1455 of yacc.c  */
+#line 534 "program_parse.y"
+    { (yyval.integer) = -TEXTURE_1D_ARRAY_INDEX; ;}
+    break;
+
+  case 46:
+
+/* Line 1455 of yacc.c  */
+#line 535 "program_parse.y"
+    { (yyval.integer) = -TEXTURE_2D_ARRAY_INDEX; ;}
+    break;
+
+  case 47:
+
+/* Line 1455 of yacc.c  */
+#line 539 "program_parse.y"
+    {
+          /* FIXME: Is this correct?  Should the extenedSwizzle be applied
+           * FIXME: to the existing swizzle?
+           */
+          (yyvsp[(4) - (6)].src_reg).Base.Swizzle = (yyvsp[(6) - (6)].swiz_mask).swizzle;
+          (yyvsp[(4) - (6)].src_reg).Base.Negate = (yyvsp[(6) - (6)].swiz_mask).mask;
+
+          (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (6)].temp_inst), & (yyvsp[(2) - (6)].dst_reg), & (yyvsp[(4) - (6)].src_reg), NULL, NULL);
+       ;}
+    break;
+
+  case 48:
+
+/* Line 1455 of yacc.c  */
+#line 551 "program_parse.y"
+    {
+          (yyval.src_reg) = (yyvsp[(2) - (2)].src_reg);
+
+          if ((yyvsp[(1) - (2)].negate)) {
+             (yyval.src_reg).Base.Negate = ~(yyval.src_reg).Base.Negate;
+          }
+       ;}
+    break;
+
+  case 49:
+
+/* Line 1455 of yacc.c  */
+#line 559 "program_parse.y"
+    {
+          (yyval.src_reg) = (yyvsp[(3) - (4)].src_reg);
+
+          if (!state->option.NV_fragment) {
+             yyerror(& (yylsp[(2) - (4)]), state, "unexpected character '|'");
+             YYERROR;
+          }
+
+          if ((yyvsp[(1) - (4)].negate)) {
+             (yyval.src_reg).Base.Negate = ~(yyval.src_reg).Base.Negate;
+          }
+
+          (yyval.src_reg).Base.Abs = 1;
+       ;}
+    break;
+
+  case 50:
+
+/* Line 1455 of yacc.c  */
+#line 576 "program_parse.y"
+    {
+          (yyval.src_reg) = (yyvsp[(1) - (2)].src_reg);
+
+          (yyval.src_reg).Base.Swizzle = _mesa_combine_swizzles((yyval.src_reg).Base.Swizzle,
+                                                   (yyvsp[(2) - (2)].swiz_mask).swizzle);
+       ;}
+    break;
+
+  case 51:
+
+/* Line 1455 of yacc.c  */
+#line 583 "program_parse.y"
+    {
+          struct asm_symbol temp_sym;
+
+          if (!state->option.NV_fragment) {
+             yyerror(& (yylsp[(1) - (1)]), state, "expected scalar suffix");
+             YYERROR;
+          }
+
+          memset(& temp_sym, 0, sizeof(temp_sym));
+          temp_sym.param_binding_begin = ~0;
+          initialize_symbol_from_const(state->prog, & temp_sym, & (yyvsp[(1) - (1)].vector), GL_TRUE);
+
+          set_src_reg_swz(& (yyval.src_reg), PROGRAM_CONSTANT,
+                           temp_sym.param_binding_begin,
+                           temp_sym.param_binding_swizzle);
+       ;}
+    break;
+
+  case 52:
+
+/* Line 1455 of yacc.c  */
+#line 602 "program_parse.y"
+    {
+          (yyval.src_reg) = (yyvsp[(2) - (3)].src_reg);
+
+          if ((yyvsp[(1) - (3)].negate)) {
+             (yyval.src_reg).Base.Negate = ~(yyval.src_reg).Base.Negate;
+          }
+
+          (yyval.src_reg).Base.Swizzle = _mesa_combine_swizzles((yyval.src_reg).Base.Swizzle,
+                                                   (yyvsp[(3) - (3)].swiz_mask).swizzle);
+       ;}
+    break;
+
+  case 53:
+
+/* Line 1455 of yacc.c  */
+#line 613 "program_parse.y"
+    {
+          (yyval.src_reg) = (yyvsp[(3) - (5)].src_reg);
+
+          if (!state->option.NV_fragment) {
+             yyerror(& (yylsp[(2) - (5)]), state, "unexpected character '|'");
+             YYERROR;
+          }
+
+          if ((yyvsp[(1) - (5)].negate)) {
+             (yyval.src_reg).Base.Negate = ~(yyval.src_reg).Base.Negate;
+          }
+
+          (yyval.src_reg).Base.Abs = 1;
+          (yyval.src_reg).Base.Swizzle = _mesa_combine_swizzles((yyval.src_reg).Base.Swizzle,
+                                                   (yyvsp[(4) - (5)].swiz_mask).swizzle);
+       ;}
+    break;
+
+  case 54:
+
+/* Line 1455 of yacc.c  */
+#line 633 "program_parse.y"
+    {
+          (yyval.dst_reg) = (yyvsp[(1) - (3)].dst_reg);
+          (yyval.dst_reg).WriteMask = (yyvsp[(2) - (3)].swiz_mask).mask;
+          (yyval.dst_reg).CondMask = (yyvsp[(3) - (3)].dst_reg).CondMask;
+          (yyval.dst_reg).CondSwizzle = (yyvsp[(3) - (3)].dst_reg).CondSwizzle;
+          (yyval.dst_reg).CondSrc = (yyvsp[(3) - (3)].dst_reg).CondSrc;
+
+          if ((yyval.dst_reg).File == PROGRAM_OUTPUT) {
+             /* Technically speaking, this should check that it is in
+              * vertex program mode.  However, PositionInvariant can never be
+              * set in fragment program mode, so it is somewhat irrelevant.
+              */
+             if (state->option.PositionInvariant
+              && ((yyval.dst_reg).Index == VERT_RESULT_HPOS)) {
+                yyerror(& (yylsp[(1) - (3)]), state, "position-invariant programs cannot "
+                        "write position");
+                YYERROR;
+             }
+
+             state->prog->OutputsWritten |= BITFIELD64_BIT((yyval.dst_reg).Index);
+          }
+       ;}
+    break;
+
+  case 55:
+
+/* Line 1455 of yacc.c  */
+#line 658 "program_parse.y"
+    {
+          set_dst_reg(& (yyval.dst_reg), PROGRAM_ADDRESS, 0);
+          (yyval.dst_reg).WriteMask = (yyvsp[(2) - (2)].swiz_mask).mask;
+       ;}
+    break;
+
+  case 56:
+
+/* Line 1455 of yacc.c  */
+#line 665 "program_parse.y"
+    {
+          const unsigned xyzw_valid =
+             ((yyvsp[(1) - (7)].ext_swizzle).xyzw_valid << 0)
+             | ((yyvsp[(3) - (7)].ext_swizzle).xyzw_valid << 1)
+             | ((yyvsp[(5) - (7)].ext_swizzle).xyzw_valid << 2)
+             | ((yyvsp[(7) - (7)].ext_swizzle).xyzw_valid << 3);
+          const unsigned rgba_valid =
+             ((yyvsp[(1) - (7)].ext_swizzle).rgba_valid << 0)
+             | ((yyvsp[(3) - (7)].ext_swizzle).rgba_valid << 1)
+             | ((yyvsp[(5) - (7)].ext_swizzle).rgba_valid << 2)
+             | ((yyvsp[(7) - (7)].ext_swizzle).rgba_valid << 3);
+
+          /* All of the swizzle components have to be valid in either RGBA
+           * or XYZW.  Note that 0 and 1 are valid in both, so both masks
+           * can have some bits set.
+           *
+           * We somewhat deviate from the spec here.  It would be really hard
+           * to figure out which component is the error, and there probably
+           * isn't a lot of benefit.
+           */
+          if ((rgba_valid != 0x0f) && (xyzw_valid != 0x0f)) {
+             yyerror(& (yylsp[(1) - (7)]), state, "cannot combine RGBA and XYZW swizzle "
+                     "components");
+             YYERROR;
+          }
+
+          (yyval.swiz_mask).swizzle = MAKE_SWIZZLE4((yyvsp[(1) - (7)].ext_swizzle).swz, (yyvsp[(3) - (7)].ext_swizzle).swz, (yyvsp[(5) - (7)].ext_swizzle).swz, (yyvsp[(7) - (7)].ext_swizzle).swz);
+          (yyval.swiz_mask).mask = ((yyvsp[(1) - (7)].ext_swizzle).negate) | ((yyvsp[(3) - (7)].ext_swizzle).negate << 1) | ((yyvsp[(5) - (7)].ext_swizzle).negate << 2)
+             | ((yyvsp[(7) - (7)].ext_swizzle).negate << 3);
+       ;}
+    break;
+
+  case 57:
+
+/* Line 1455 of yacc.c  */
+#line 698 "program_parse.y"
+    {
+          (yyval.ext_swizzle) = (yyvsp[(2) - (2)].ext_swizzle);
+          (yyval.ext_swizzle).negate = ((yyvsp[(1) - (2)].negate)) ? 1 : 0;
+       ;}
+    break;
+
+  case 58:
+
+/* Line 1455 of yacc.c  */
+#line 705 "program_parse.y"
+    {
+          if (((yyvsp[(1) - (1)].integer) != 0) && ((yyvsp[(1) - (1)].integer) != 1)) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid extended swizzle selector");
+             YYERROR;
+          }
+
+          (yyval.ext_swizzle).swz = ((yyvsp[(1) - (1)].integer) == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE;
+
+          /* 0 and 1 are valid for both RGBA swizzle names and XYZW
+           * swizzle names.
+           */
+          (yyval.ext_swizzle).xyzw_valid = 1;
+          (yyval.ext_swizzle).rgba_valid = 1;
+       ;}
+    break;
+
+  case 59:
+
+/* Line 1455 of yacc.c  */
+#line 720 "program_parse.y"
+    {
+          char s;
+
+          if (strlen((yyvsp[(1) - (1)].string)) > 1) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid extended swizzle selector");
+             YYERROR;
+          }
+
+          s = (yyvsp[(1) - (1)].string)[0];
+          free((yyvsp[(1) - (1)].string));
+
+          switch (s) {
+          case 'x':
+             (yyval.ext_swizzle).swz = SWIZZLE_X;
+             (yyval.ext_swizzle).xyzw_valid = 1;
+             break;
+          case 'y':
+             (yyval.ext_swizzle).swz = SWIZZLE_Y;
+             (yyval.ext_swizzle).xyzw_valid = 1;
+             break;
+          case 'z':
+             (yyval.ext_swizzle).swz = SWIZZLE_Z;
+             (yyval.ext_swizzle).xyzw_valid = 1;
+             break;
+          case 'w':
+             (yyval.ext_swizzle).swz = SWIZZLE_W;
+             (yyval.ext_swizzle).xyzw_valid = 1;
+             break;
+
+          case 'r':
+             (yyval.ext_swizzle).swz = SWIZZLE_X;
+             (yyval.ext_swizzle).rgba_valid = 1;
+             break;
+          case 'g':
+             (yyval.ext_swizzle).swz = SWIZZLE_Y;
+             (yyval.ext_swizzle).rgba_valid = 1;
+             break;
+          case 'b':
+             (yyval.ext_swizzle).swz = SWIZZLE_Z;
+             (yyval.ext_swizzle).rgba_valid = 1;
+             break;
+          case 'a':
+             (yyval.ext_swizzle).swz = SWIZZLE_W;
+             (yyval.ext_swizzle).rgba_valid = 1;
+             break;
+
+          default:
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid extended swizzle selector");
+             YYERROR;
+             break;
+          }
+       ;}
+    break;
+
+  case 60:
+
+/* Line 1455 of yacc.c  */
+#line 775 "program_parse.y"
+    {
+          struct asm_symbol *const s = (struct asm_symbol *)
+             _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
+
+          free((yyvsp[(1) - (1)].string));
+
+          if (s == NULL) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
+             YYERROR;
+          } else if ((s->type != at_param) && (s->type != at_temp)
+                     && (s->type != at_attrib)) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
+             YYERROR;
+          } else if ((s->type == at_param) && s->param_is_array) {
+             yyerror(& (yylsp[(1) - (1)]), state, "non-array access to array PARAM");
+             YYERROR;
+          }
+
+          init_src_reg(& (yyval.src_reg));
+          switch (s->type) {
+          case at_temp:
+             set_src_reg(& (yyval.src_reg), PROGRAM_TEMPORARY, s->temp_binding);
+             break;
+          case at_param:
+              set_src_reg_swz(& (yyval.src_reg), s->param_binding_type,
+                              s->param_binding_begin,
+                              s->param_binding_swizzle);
+             break;
+          case at_attrib:
+             set_src_reg(& (yyval.src_reg), PROGRAM_INPUT, s->attrib_binding);
+             state->prog->InputsRead |= (1U << (yyval.src_reg).Base.Index);
+
+             if (!validate_inputs(& (yylsp[(1) - (1)]), state)) {
+                YYERROR;
+             }
+             break;
+
+          default:
+             YYERROR;
+             break;
+          }
+       ;}
+    break;
+
+  case 61:
+
+/* Line 1455 of yacc.c  */
+#line 818 "program_parse.y"
+    {
+          set_src_reg(& (yyval.src_reg), PROGRAM_INPUT, (yyvsp[(1) - (1)].attrib));
+          state->prog->InputsRead |= (1U << (yyval.src_reg).Base.Index);
+
+          if (!validate_inputs(& (yylsp[(1) - (1)]), state)) {
+             YYERROR;
+          }
+       ;}
+    break;
+
+  case 62:
+
+/* Line 1455 of yacc.c  */
+#line 827 "program_parse.y"
+    {
+          if (! (yyvsp[(3) - (4)].src_reg).Base.RelAddr
+              && ((unsigned) (yyvsp[(3) - (4)].src_reg).Base.Index >= (yyvsp[(1) - (4)].sym)->param_binding_length)) {
+             yyerror(& (yylsp[(3) - (4)]), state, "out of bounds array access");
+             YYERROR;
+          }
+
+          init_src_reg(& (yyval.src_reg));
+          (yyval.src_reg).Base.File = (yyvsp[(1) - (4)].sym)->param_binding_type;
+
+          if ((yyvsp[(3) - (4)].src_reg).Base.RelAddr) {
+             (yyvsp[(1) - (4)].sym)->param_accessed_indirectly = 1;
+
+             (yyval.src_reg).Base.RelAddr = 1;
+             (yyval.src_reg).Base.Index = (yyvsp[(3) - (4)].src_reg).Base.Index;
+             (yyval.src_reg).Symbol = (yyvsp[(1) - (4)].sym);
+          } else {
+             (yyval.src_reg).Base.Index = (yyvsp[(1) - (4)].sym)->param_binding_begin + (yyvsp[(3) - (4)].src_reg).Base.Index;
+          }
+       ;}
+    break;
+
+  case 63:
+
+/* Line 1455 of yacc.c  */
+#line 848 "program_parse.y"
+    {
+           gl_register_file file = ((yyvsp[(1) - (1)].temp_sym).name != NULL) 
+             ? (yyvsp[(1) - (1)].temp_sym).param_binding_type
+             : PROGRAM_CONSTANT;
+           set_src_reg_swz(& (yyval.src_reg), file, (yyvsp[(1) - (1)].temp_sym).param_binding_begin,
+                           (yyvsp[(1) - (1)].temp_sym).param_binding_swizzle);
+       ;}
+    break;
+
+  case 64:
+
+/* Line 1455 of yacc.c  */
+#line 858 "program_parse.y"
+    {
+          set_dst_reg(& (yyval.dst_reg), PROGRAM_OUTPUT, (yyvsp[(1) - (1)].result));
+       ;}
+    break;
+
+  case 65:
+
+/* Line 1455 of yacc.c  */
+#line 862 "program_parse.y"
+    {
+          struct asm_symbol *const s = (struct asm_symbol *)
+             _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
+
+          free((yyvsp[(1) - (1)].string));
+
+          if (s == NULL) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
+             YYERROR;
+          } else if ((s->type != at_output) && (s->type != at_temp)) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
+             YYERROR;
+          }
+
+          switch (s->type) {
+          case at_temp:
+             set_dst_reg(& (yyval.dst_reg), PROGRAM_TEMPORARY, s->temp_binding);
+             break;
+          case at_output:
+             set_dst_reg(& (yyval.dst_reg), PROGRAM_OUTPUT, s->output_binding);
+             break;
+          default:
+             set_dst_reg(& (yyval.dst_reg), s->param_binding_type, s->param_binding_begin);
+             break;
+          }
+       ;}
+    break;
+
+  case 66:
+
+/* Line 1455 of yacc.c  */
+#line 891 "program_parse.y"
+    {
+          struct asm_symbol *const s = (struct asm_symbol *)
+             _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
+
+          free((yyvsp[(1) - (1)].string));
+
+          if (s == NULL) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
+             YYERROR;
+          } else if ((s->type != at_param) || !s->param_is_array) {
+             yyerror(& (yylsp[(1) - (1)]), state, "array access to non-PARAM variable");
+             YYERROR;
+          } else {
+             (yyval.sym) = s;
+          }
+       ;}
+    break;
+
+  case 69:
+
+/* Line 1455 of yacc.c  */
+#line 912 "program_parse.y"
+    {
+          init_src_reg(& (yyval.src_reg));
+          (yyval.src_reg).Base.Index = (yyvsp[(1) - (1)].integer);
+       ;}
+    break;
+
+  case 70:
+
+/* Line 1455 of yacc.c  */
+#line 919 "program_parse.y"
+    {
+          /* FINISHME: Add support for multiple address registers.
+           */
+          /* FINISHME: Add support for 4-component address registers.
+           */
+          init_src_reg(& (yyval.src_reg));
+          (yyval.src_reg).Base.RelAddr = 1;
+          (yyval.src_reg).Base.Index = (yyvsp[(3) - (3)].integer);
+       ;}
+    break;
+
+  case 71:
+
+/* Line 1455 of yacc.c  */
+#line 930 "program_parse.y"
+    { (yyval.integer) = 0; ;}
+    break;
+
+  case 72:
+
+/* Line 1455 of yacc.c  */
+#line 931 "program_parse.y"
+    { (yyval.integer) = (yyvsp[(2) - (2)].integer); ;}
+    break;
+
+  case 73:
+
+/* Line 1455 of yacc.c  */
+#line 932 "program_parse.y"
+    { (yyval.integer) = -(yyvsp[(2) - (2)].integer); ;}
+    break;
+
+  case 74:
+
+/* Line 1455 of yacc.c  */
+#line 936 "program_parse.y"
+    {
+          if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > 63)) {
+              char s[100];
+              _mesa_snprintf(s, sizeof(s),
+                             "relative address offset too large (%d)", (yyvsp[(1) - (1)].integer));
+             yyerror(& (yylsp[(1) - (1)]), state, s);
+             YYERROR;
+          } else {
+             (yyval.integer) = (yyvsp[(1) - (1)].integer);
+          }
+       ;}
+    break;
+
+  case 75:
+
+/* Line 1455 of yacc.c  */
+#line 950 "program_parse.y"
+    {
+          if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > 64)) {
+              char s[100];
+              _mesa_snprintf(s, sizeof(s),
+                             "relative address offset too large (%d)", (yyvsp[(1) - (1)].integer));
+             yyerror(& (yylsp[(1) - (1)]), state, s);
+             YYERROR;
+          } else {
+             (yyval.integer) = (yyvsp[(1) - (1)].integer);
+          }
+       ;}
+    break;
+
+  case 76:
+
+/* Line 1455 of yacc.c  */
+#line 964 "program_parse.y"
+    {
+          struct asm_symbol *const s = (struct asm_symbol *)
+             _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
+
+          free((yyvsp[(1) - (1)].string));
+
+          if (s == NULL) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid array member");
+             YYERROR;
+          } else if (s->type != at_address) {
+             yyerror(& (yylsp[(1) - (1)]), state,
+                     "invalid variable for indexed array access");
+             YYERROR;
+          } else {
+             (yyval.sym) = s;
+          }
+       ;}
+    break;
+
+  case 77:
+
+/* Line 1455 of yacc.c  */
+#line 984 "program_parse.y"
+    {
+          if ((yyvsp[(1) - (1)].swiz_mask).mask != WRITEMASK_X) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid address component selector");
+             YYERROR;
+          } else {
+             (yyval.swiz_mask) = (yyvsp[(1) - (1)].swiz_mask);
+          }
+       ;}
+    break;
+
+  case 78:
+
+/* Line 1455 of yacc.c  */
+#line 995 "program_parse.y"
+    {
+          if ((yyvsp[(1) - (1)].swiz_mask).mask != WRITEMASK_X) {
+             yyerror(& (yylsp[(1) - (1)]), state,
+                     "address register write mask must be \".x\"");
+             YYERROR;
+          } else {
+             (yyval.swiz_mask) = (yyvsp[(1) - (1)].swiz_mask);
+          }
+       ;}
+    break;
+
+  case 83:
+
+/* Line 1455 of yacc.c  */
+#line 1011 "program_parse.y"
+    { (yyval.swiz_mask).swizzle = SWIZZLE_NOOP; (yyval.swiz_mask).mask = WRITEMASK_XYZW; ;}
+    break;
+
+  case 88:
+
+/* Line 1455 of yacc.c  */
+#line 1015 "program_parse.y"
+    { (yyval.swiz_mask).swizzle = SWIZZLE_NOOP; (yyval.swiz_mask).mask = WRITEMASK_XYZW; ;}
+    break;
+
+  case 89:
+
+/* Line 1455 of yacc.c  */
+#line 1019 "program_parse.y"
+    {
+          (yyval.dst_reg) = (yyvsp[(2) - (3)].dst_reg);
+       ;}
+    break;
+
+  case 90:
+
+/* Line 1455 of yacc.c  */
+#line 1023 "program_parse.y"
+    {
+          (yyval.dst_reg) = (yyvsp[(2) - (3)].dst_reg);
+       ;}
+    break;
+
+  case 91:
+
+/* Line 1455 of yacc.c  */
+#line 1027 "program_parse.y"
+    {
+          (yyval.dst_reg).CondMask = COND_TR;
+          (yyval.dst_reg).CondSwizzle = SWIZZLE_NOOP;
+          (yyval.dst_reg).CondSrc = 0;
+       ;}
+    break;
+
+  case 92:
+
+/* Line 1455 of yacc.c  */
+#line 1035 "program_parse.y"
+    {
+          (yyval.dst_reg) = (yyvsp[(1) - (2)].dst_reg);
+          (yyval.dst_reg).CondSwizzle = (yyvsp[(2) - (2)].swiz_mask).swizzle;
+       ;}
+    break;
+
+  case 93:
+
+/* Line 1455 of yacc.c  */
+#line 1042 "program_parse.y"
+    {
+          (yyval.dst_reg) = (yyvsp[(1) - (2)].dst_reg);
+          (yyval.dst_reg).CondSwizzle = (yyvsp[(2) - (2)].swiz_mask).swizzle;
+       ;}
+    break;
+
+  case 94:
+
+/* Line 1455 of yacc.c  */
+#line 1049 "program_parse.y"
+    {
+          const int cond = _mesa_parse_cc((yyvsp[(1) - (1)].string));
+          if ((cond == 0) || ((yyvsp[(1) - (1)].string)[2] != '\0')) {
+             char *const err_str =
+                make_error_string("invalid condition code \"%s\"", (yyvsp[(1) - (1)].string));
+
+             yyerror(& (yylsp[(1) - (1)]), state, (err_str != NULL)
+                     ? err_str : "invalid condition code");
+
+             if (err_str != NULL) {
+                free(err_str);
+             }
+
+             YYERROR;
+          }
+
+          (yyval.dst_reg).CondMask = cond;
+          (yyval.dst_reg).CondSwizzle = SWIZZLE_NOOP;
+          (yyval.dst_reg).CondSrc = 0;
+       ;}
+    break;
+
+  case 95:
+
+/* Line 1455 of yacc.c  */
+#line 1072 "program_parse.y"
+    {
+          const int cond = _mesa_parse_cc((yyvsp[(1) - (1)].string));
+          if ((cond == 0) || ((yyvsp[(1) - (1)].string)[2] != '\0')) {
+             char *const err_str =
+                make_error_string("invalid condition code \"%s\"", (yyvsp[(1) - (1)].string));
+
+             yyerror(& (yylsp[(1) - (1)]), state, (err_str != NULL)
+                     ? err_str : "invalid condition code");
+
+             if (err_str != NULL) {
+                free(err_str);
+             }
+
+             YYERROR;
+          }
+
+          (yyval.dst_reg).CondMask = cond;
+          (yyval.dst_reg).CondSwizzle = SWIZZLE_NOOP;
+          (yyval.dst_reg).CondSrc = 0;
+       ;}
+    break;
+
+  case 102:
+
+/* Line 1455 of yacc.c  */
+#line 1103 "program_parse.y"
+    {
+          struct asm_symbol *const s =
+             declare_variable(state, (yyvsp[(2) - (4)].string), at_attrib, & (yylsp[(2) - (4)]));
+
+          if (s == NULL) {
+             free((yyvsp[(2) - (4)].string));
+             YYERROR;
+          } else {
+             s->attrib_binding = (yyvsp[(4) - (4)].attrib);
+             state->InputsBound |= (1U << s->attrib_binding);
+
+             if (!validate_inputs(& (yylsp[(4) - (4)]), state)) {
+                YYERROR;
+             }
+          }
+       ;}
+    break;
+
+  case 103:
+
+/* Line 1455 of yacc.c  */
+#line 1122 "program_parse.y"
+    {
+          (yyval.attrib) = (yyvsp[(2) - (2)].attrib);
+       ;}
+    break;
+
+  case 104:
+
+/* Line 1455 of yacc.c  */
+#line 1126 "program_parse.y"
+    {
+          (yyval.attrib) = (yyvsp[(2) - (2)].attrib);
+       ;}
+    break;
+
+  case 105:
+
+/* Line 1455 of yacc.c  */
+#line 1132 "program_parse.y"
+    {
+          (yyval.attrib) = VERT_ATTRIB_POS;
+       ;}
+    break;
+
+  case 106:
+
+/* Line 1455 of yacc.c  */
+#line 1136 "program_parse.y"
+    {
+          (yyval.attrib) = VERT_ATTRIB_WEIGHT;
+       ;}
+    break;
+
+  case 107:
+
+/* Line 1455 of yacc.c  */
+#line 1140 "program_parse.y"
+    {
+          (yyval.attrib) = VERT_ATTRIB_NORMAL;
+       ;}
+    break;
+
+  case 108:
+
+/* Line 1455 of yacc.c  */
+#line 1144 "program_parse.y"
+    {
+          if (!state->ctx->Extensions.EXT_secondary_color) {
+             yyerror(& (yylsp[(2) - (2)]), state, "GL_EXT_secondary_color not supported");
+             YYERROR;
+          }
+
+          (yyval.attrib) = VERT_ATTRIB_COLOR0 + (yyvsp[(2) - (2)].integer);
+       ;}
+    break;
+
+  case 109:
+
+/* Line 1455 of yacc.c  */
+#line 1153 "program_parse.y"
+    {
+          if (!state->ctx->Extensions.EXT_fog_coord) {
+             yyerror(& (yylsp[(1) - (1)]), state, "GL_EXT_fog_coord not supported");
+             YYERROR;
+          }
+
+          (yyval.attrib) = VERT_ATTRIB_FOG;
+       ;}
+    break;
+
+  case 110:
+
+/* Line 1455 of yacc.c  */
+#line 1162 "program_parse.y"
+    {
+          (yyval.attrib) = VERT_ATTRIB_TEX0 + (yyvsp[(2) - (2)].integer);
+       ;}
+    break;
+
+  case 111:
+
+/* Line 1455 of yacc.c  */
+#line 1166 "program_parse.y"
+    {
+          yyerror(& (yylsp[(1) - (4)]), state, "GL_ARB_matrix_palette not supported");
+          YYERROR;
+       ;}
+    break;
+
+  case 112:
+
+/* Line 1455 of yacc.c  */
+#line 1171 "program_parse.y"
+    {
+          (yyval.attrib) = VERT_ATTRIB_GENERIC0 + (yyvsp[(3) - (4)].integer);
+       ;}
+    break;
+
+  case 113:
+
+/* Line 1455 of yacc.c  */
+#line 1177 "program_parse.y"
+    {
+          if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxAttribs) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid vertex attribute reference");
+             YYERROR;
+          }
+
+          (yyval.integer) = (yyvsp[(1) - (1)].integer);
+       ;}
+    break;
+
+  case 117:
+
+/* Line 1455 of yacc.c  */
+#line 1191 "program_parse.y"
+    {
+          (yyval.attrib) = FRAG_ATTRIB_WPOS;
+       ;}
+    break;
+
+  case 118:
+
+/* Line 1455 of yacc.c  */
+#line 1195 "program_parse.y"
+    {
+          (yyval.attrib) = FRAG_ATTRIB_COL0 + (yyvsp[(2) - (2)].integer);
+       ;}
+    break;
+
+  case 119:
+
+/* Line 1455 of yacc.c  */
+#line 1199 "program_parse.y"
+    {
+          (yyval.attrib) = FRAG_ATTRIB_FOGC;
+       ;}
+    break;
+
+  case 120:
+
+/* Line 1455 of yacc.c  */
+#line 1203 "program_parse.y"
+    {
+          (yyval.attrib) = FRAG_ATTRIB_TEX0 + (yyvsp[(2) - (2)].integer);
+       ;}
+    break;
+
+  case 123:
+
+/* Line 1455 of yacc.c  */
+#line 1211 "program_parse.y"
+    {
+          struct asm_symbol *const s =
+             declare_variable(state, (yyvsp[(2) - (3)].string), at_param, & (yylsp[(2) - (3)]));
+
+          if (s == NULL) {
+             free((yyvsp[(2) - (3)].string));
+             YYERROR;
+          } else {
+             s->param_binding_type = (yyvsp[(3) - (3)].temp_sym).param_binding_type;
+             s->param_binding_begin = (yyvsp[(3) - (3)].temp_sym).param_binding_begin;
+             s->param_binding_length = (yyvsp[(3) - (3)].temp_sym).param_binding_length;
+              s->param_binding_swizzle = (yyvsp[(3) - (3)].temp_sym).param_binding_swizzle;
+             s->param_is_array = 0;
+          }
+       ;}
+    break;
+
+  case 124:
+
+/* Line 1455 of yacc.c  */
+#line 1229 "program_parse.y"
+    {
+          if (((yyvsp[(4) - (6)].integer) != 0) && ((unsigned) (yyvsp[(4) - (6)].integer) != (yyvsp[(6) - (6)].temp_sym).param_binding_length)) {
+             free((yyvsp[(2) - (6)].string));
+             yyerror(& (yylsp[(4) - (6)]), state, 
+                     "parameter array size and number of bindings must match");
+             YYERROR;
+          } else {
+             struct asm_symbol *const s =
+                declare_variable(state, (yyvsp[(2) - (6)].string), (yyvsp[(6) - (6)].temp_sym).type, & (yylsp[(2) - (6)]));
+
+             if (s == NULL) {
+                free((yyvsp[(2) - (6)].string));
+                YYERROR;
+             } else {
+                s->param_binding_type = (yyvsp[(6) - (6)].temp_sym).param_binding_type;
+                s->param_binding_begin = (yyvsp[(6) - (6)].temp_sym).param_binding_begin;
+                s->param_binding_length = (yyvsp[(6) - (6)].temp_sym).param_binding_length;
+                 s->param_binding_swizzle = SWIZZLE_XYZW;
+                s->param_is_array = 1;
+             }
+          }
+       ;}
+    break;
+
+  case 125:
+
+/* Line 1455 of yacc.c  */
+#line 1254 "program_parse.y"
+    {
+          (yyval.integer) = 0;
+       ;}
+    break;
+
+  case 126:
+
+/* Line 1455 of yacc.c  */
+#line 1258 "program_parse.y"
+    {
+          if (((yyvsp[(1) - (1)].integer) < 1) || ((unsigned) (yyvsp[(1) - (1)].integer) > state->limits->MaxParameters)) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid parameter array size");
+             YYERROR;
+          } else {
+             (yyval.integer) = (yyvsp[(1) - (1)].integer);
+          }
+       ;}
+    break;
+
+  case 127:
+
+/* Line 1455 of yacc.c  */
+#line 1269 "program_parse.y"
+    {
+          (yyval.temp_sym) = (yyvsp[(2) - (2)].temp_sym);
+       ;}
+    break;
+
+  case 128:
+
+/* Line 1455 of yacc.c  */
+#line 1275 "program_parse.y"
+    {
+          (yyval.temp_sym) = (yyvsp[(3) - (4)].temp_sym);
+       ;}
+    break;
+
+  case 130:
+
+/* Line 1455 of yacc.c  */
+#line 1282 "program_parse.y"
+    {
+          (yyvsp[(1) - (3)].temp_sym).param_binding_length += (yyvsp[(3) - (3)].temp_sym).param_binding_length;
+          (yyval.temp_sym) = (yyvsp[(1) - (3)].temp_sym);
+       ;}
+    break;
+
+  case 131:
+
+/* Line 1455 of yacc.c  */
+#line 1289 "program_parse.y"
+    {
+          memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+          (yyval.temp_sym).param_binding_begin = ~0;
+          initialize_symbol_from_state(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
+       ;}
+    break;
+
+  case 132:
+
+/* Line 1455 of yacc.c  */
+#line 1295 "program_parse.y"
+    {
+          memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+          (yyval.temp_sym).param_binding_begin = ~0;
+          initialize_symbol_from_param(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
+       ;}
+    break;
+
+  case 133:
+
+/* Line 1455 of yacc.c  */
+#line 1301 "program_parse.y"
+    {
+          memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+          (yyval.temp_sym).param_binding_begin = ~0;
+          initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector), GL_TRUE);
+       ;}
+    break;
+
+  case 134:
+
+/* Line 1455 of yacc.c  */
+#line 1309 "program_parse.y"
+    {
+          memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+          (yyval.temp_sym).param_binding_begin = ~0;
+          initialize_symbol_from_state(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
+       ;}
+    break;
+
+  case 135:
+
+/* Line 1455 of yacc.c  */
+#line 1315 "program_parse.y"
+    {
+          memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+          (yyval.temp_sym).param_binding_begin = ~0;
+          initialize_symbol_from_param(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
+       ;}
+    break;
+
+  case 136:
+
+/* Line 1455 of yacc.c  */
+#line 1321 "program_parse.y"
+    {
+          memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+          (yyval.temp_sym).param_binding_begin = ~0;
+          initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector), GL_TRUE);
+       ;}
+    break;
+
+  case 137:
+
+/* Line 1455 of yacc.c  */
+#line 1329 "program_parse.y"
+    {
+          memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+          (yyval.temp_sym).param_binding_begin = ~0;
+          initialize_symbol_from_state(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
+       ;}
+    break;
+
+  case 138:
+
+/* Line 1455 of yacc.c  */
+#line 1335 "program_parse.y"
+    {
+          memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+          (yyval.temp_sym).param_binding_begin = ~0;
+          initialize_symbol_from_param(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
+       ;}
+    break;
+
+  case 139:
+
+/* Line 1455 of yacc.c  */
+#line 1341 "program_parse.y"
+    {
+          memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+          (yyval.temp_sym).param_binding_begin = ~0;
+          initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector), GL_FALSE);
+       ;}
+    break;
+
+  case 140:
+
+/* Line 1455 of yacc.c  */
+#line 1348 "program_parse.y"
+    { memcpy((yyval.state), (yyvsp[(1) - (1)].state), sizeof((yyval.state))); ;}
+    break;
+
+  case 141:
+
+/* Line 1455 of yacc.c  */
+#line 1349 "program_parse.y"
+    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+    break;
+
+  case 142:
+
+/* Line 1455 of yacc.c  */
+#line 1352 "program_parse.y"
+    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+    break;
+
+  case 143:
+
+/* Line 1455 of yacc.c  */
+#line 1353 "program_parse.y"
+    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+    break;
+
+  case 144:
+
+/* Line 1455 of yacc.c  */
+#line 1354 "program_parse.y"
+    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+    break;
+
+  case 145:
+
+/* Line 1455 of yacc.c  */
+#line 1355 "program_parse.y"
+    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+    break;
+
+  case 146:
+
+/* Line 1455 of yacc.c  */
+#line 1356 "program_parse.y"
+    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+    break;
+
+  case 147:
+
+/* Line 1455 of yacc.c  */
+#line 1357 "program_parse.y"
+    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+    break;
+
+  case 148:
+
+/* Line 1455 of yacc.c  */
+#line 1358 "program_parse.y"
+    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+    break;
+
+  case 149:
+
+/* Line 1455 of yacc.c  */
+#line 1359 "program_parse.y"
+    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+    break;
+
+  case 150:
+
+/* Line 1455 of yacc.c  */
+#line 1360 "program_parse.y"
+    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+    break;
+
+  case 151:
+
+/* Line 1455 of yacc.c  */
+#line 1361 "program_parse.y"
+    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+    break;
+
+  case 152:
+
+/* Line 1455 of yacc.c  */
+#line 1362 "program_parse.y"
+    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+    break;
+
+  case 153:
+
+/* Line 1455 of yacc.c  */
+#line 1366 "program_parse.y"
+    {
+          memset((yyval.state), 0, sizeof((yyval.state)));
+          (yyval.state)[0] = STATE_MATERIAL;
+          (yyval.state)[1] = (yyvsp[(2) - (3)].integer);
+          (yyval.state)[2] = (yyvsp[(3) - (3)].integer);
+       ;}
+    break;
+
+  case 154:
+
+/* Line 1455 of yacc.c  */
+#line 1375 "program_parse.y"
+    {
+          (yyval.integer) = (yyvsp[(1) - (1)].integer);
+       ;}
+    break;
+
+  case 155:
+
+/* Line 1455 of yacc.c  */
+#line 1379 "program_parse.y"
+    {
+          (yyval.integer) = STATE_EMISSION;
+       ;}
+    break;
+
+  case 156:
+
+/* Line 1455 of yacc.c  */
+#line 1383 "program_parse.y"
+    {
+          (yyval.integer) = STATE_SHININESS;
+       ;}
+    break;
+
+  case 157:
+
+/* Line 1455 of yacc.c  */
+#line 1389 "program_parse.y"
+    {
+          memset((yyval.state), 0, sizeof((yyval.state)));
+          (yyval.state)[0] = STATE_LIGHT;
+          (yyval.state)[1] = (yyvsp[(3) - (5)].integer);
+          (yyval.state)[2] = (yyvsp[(5) - (5)].integer);
+       ;}
+    break;
+
+  case 158:
+
+/* Line 1455 of yacc.c  */
+#line 1398 "program_parse.y"
+    {
+          (yyval.integer) = (yyvsp[(1) - (1)].integer);
+       ;}
+    break;
+
+  case 159:
+
+/* Line 1455 of yacc.c  */
+#line 1402 "program_parse.y"
+    {
+          (yyval.integer) = STATE_POSITION;
+       ;}
+    break;
+
+  case 160:
+
+/* Line 1455 of yacc.c  */
+#line 1406 "program_parse.y"
+    {
+          if (!state->ctx->Extensions.EXT_point_parameters) {
+             yyerror(& (yylsp[(1) - (1)]), state, "GL_ARB_point_parameters not supported");
+             YYERROR;
+          }
+
+          (yyval.integer) = STATE_ATTENUATION;
+       ;}
+    break;
+
+  case 161:
+
+/* Line 1455 of yacc.c  */
+#line 1415 "program_parse.y"
+    {
+          (yyval.integer) = (yyvsp[(2) - (2)].integer);
+       ;}
+    break;
+
+  case 162:
+
+/* Line 1455 of yacc.c  */
+#line 1419 "program_parse.y"
+    {
+          (yyval.integer) = STATE_HALF_VECTOR;
+       ;}
+    break;
+
+  case 163:
+
+/* Line 1455 of yacc.c  */
+#line 1425 "program_parse.y"
+    {
+          (yyval.integer) = STATE_SPOT_DIRECTION;
+       ;}
+    break;
+
+  case 164:
+
+/* Line 1455 of yacc.c  */
+#line 1431 "program_parse.y"
+    {
+          (yyval.state)[0] = (yyvsp[(2) - (2)].state)[0];
+          (yyval.state)[1] = (yyvsp[(2) - (2)].state)[1];
+       ;}
+    break;
+
+  case 165:
+
+/* Line 1455 of yacc.c  */
+#line 1438 "program_parse.y"
+    {
+          memset((yyval.state), 0, sizeof((yyval.state)));
+          (yyval.state)[0] = STATE_LIGHTMODEL_AMBIENT;
+       ;}
+    break;
+
+  case 166:
+
+/* Line 1455 of yacc.c  */
+#line 1443 "program_parse.y"
+    {
+          memset((yyval.state), 0, sizeof((yyval.state)));
+          (yyval.state)[0] = STATE_LIGHTMODEL_SCENECOLOR;
+          (yyval.state)[1] = (yyvsp[(1) - (2)].integer);
+       ;}
+    break;
+
+  case 167:
+
+/* Line 1455 of yacc.c  */
+#line 1451 "program_parse.y"
+    {
+          memset((yyval.state), 0, sizeof((yyval.state)));
+          (yyval.state)[0] = STATE_LIGHTPROD;
+          (yyval.state)[1] = (yyvsp[(3) - (6)].integer);
+          (yyval.state)[2] = (yyvsp[(5) - (6)].integer);
+          (yyval.state)[3] = (yyvsp[(6) - (6)].integer);
+       ;}
+    break;
+
+  case 169:
+
+/* Line 1455 of yacc.c  */
+#line 1463 "program_parse.y"
+    {
+          memset((yyval.state), 0, sizeof((yyval.state)));
+          (yyval.state)[0] = (yyvsp[(3) - (3)].integer);
+          (yyval.state)[1] = (yyvsp[(2) - (3)].integer);
+       ;}
+    break;
+
+  case 170:
+
+/* Line 1455 of yacc.c  */
+#line 1471 "program_parse.y"
+    {
+          (yyval.integer) = STATE_TEXENV_COLOR;
+       ;}
+    break;
+
+  case 171:
+
+/* Line 1455 of yacc.c  */
+#line 1477 "program_parse.y"
+    {
+          (yyval.integer) = STATE_AMBIENT;
+       ;}
+    break;
+
+  case 172:
+
+/* Line 1455 of yacc.c  */
+#line 1481 "program_parse.y"
+    {
+          (yyval.integer) = STATE_DIFFUSE;
+       ;}
+    break;
+
+  case 173:
+
+/* Line 1455 of yacc.c  */
+#line 1485 "program_parse.y"
+    {
+          (yyval.integer) = STATE_SPECULAR;
+       ;}
+    break;
+
+  case 174:
+
+/* Line 1455 of yacc.c  */
+#line 1491 "program_parse.y"
+    {
+          if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxLights) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid light selector");
+             YYERROR;
+          }
+
+          (yyval.integer) = (yyvsp[(1) - (1)].integer);
+       ;}
+    break;
+
+  case 175:
+
+/* Line 1455 of yacc.c  */
+#line 1502 "program_parse.y"
+    {
+          memset((yyval.state), 0, sizeof((yyval.state)));
+          (yyval.state)[0] = STATE_TEXGEN;
+          (yyval.state)[1] = (yyvsp[(2) - (4)].integer);
+          (yyval.state)[2] = (yyvsp[(3) - (4)].integer) + (yyvsp[(4) - (4)].integer);
+       ;}
+    break;
+
+  case 176:
+
+/* Line 1455 of yacc.c  */
+#line 1511 "program_parse.y"
+    {
+          (yyval.integer) = STATE_TEXGEN_EYE_S;
+       ;}
+    break;
+
+  case 177:
+
+/* Line 1455 of yacc.c  */
+#line 1515 "program_parse.y"
+    {
+          (yyval.integer) = STATE_TEXGEN_OBJECT_S;
+       ;}
+    break;
+
+  case 178:
+
+/* Line 1455 of yacc.c  */
+#line 1520 "program_parse.y"
+    {
+          (yyval.integer) = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S;
+       ;}
+    break;
+
+  case 179:
+
+/* Line 1455 of yacc.c  */
+#line 1524 "program_parse.y"
+    {
+          (yyval.integer) = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S;
+       ;}
+    break;
+
+  case 180:
+
+/* Line 1455 of yacc.c  */
+#line 1528 "program_parse.y"
+    {
+          (yyval.integer) = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S;
+       ;}
+    break;
+
+  case 181:
+
+/* Line 1455 of yacc.c  */
+#line 1532 "program_parse.y"
+    {
+          (yyval.integer) = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S;
+       ;}
+    break;
+
+  case 182:
+
+/* Line 1455 of yacc.c  */
+#line 1538 "program_parse.y"
+    {
+          memset((yyval.state), 0, sizeof((yyval.state)));
+          (yyval.state)[0] = (yyvsp[(2) - (2)].integer);
+       ;}
+    break;
+
+  case 183:
+
+/* Line 1455 of yacc.c  */
+#line 1545 "program_parse.y"
+    {
+          (yyval.integer) = STATE_FOG_COLOR;
+       ;}
+    break;
+
+  case 184:
+
+/* Line 1455 of yacc.c  */
+#line 1549 "program_parse.y"
+    {
+          (yyval.integer) = STATE_FOG_PARAMS;
+       ;}
+    break;
+
+  case 185:
+
+/* Line 1455 of yacc.c  */
+#line 1555 "program_parse.y"
+    {
+          memset((yyval.state), 0, sizeof((yyval.state)));
+          (yyval.state)[0] = STATE_CLIPPLANE;
+          (yyval.state)[1] = (yyvsp[(3) - (5)].integer);
+       ;}
+    break;
+
+  case 186:
+
+/* Line 1455 of yacc.c  */
+#line 1563 "program_parse.y"
+    {
+          if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxClipPlanes) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid clip plane selector");
+             YYERROR;
+          }
+
+          (yyval.integer) = (yyvsp[(1) - (1)].integer);
+       ;}
+    break;
+
+  case 187:
+
+/* Line 1455 of yacc.c  */
+#line 1574 "program_parse.y"
+    {
+          memset((yyval.state), 0, sizeof((yyval.state)));
+          (yyval.state)[0] = (yyvsp[(2) - (2)].integer);
+       ;}
+    break;
+
+  case 188:
+
+/* Line 1455 of yacc.c  */
+#line 1581 "program_parse.y"
+    {
+          (yyval.integer) = STATE_POINT_SIZE;
+       ;}
+    break;
+
+  case 189:
+
+/* Line 1455 of yacc.c  */
+#line 1585 "program_parse.y"
+    {
+          (yyval.integer) = STATE_POINT_ATTENUATION;
+       ;}
+    break;
+
+  case 190:
+
+/* Line 1455 of yacc.c  */
+#line 1591 "program_parse.y"
+    {
+          (yyval.state)[0] = (yyvsp[(1) - (5)].state)[0];
+          (yyval.state)[1] = (yyvsp[(1) - (5)].state)[1];
+          (yyval.state)[2] = (yyvsp[(4) - (5)].integer);
+          (yyval.state)[3] = (yyvsp[(4) - (5)].integer);
+          (yyval.state)[4] = (yyvsp[(1) - (5)].state)[2];
+       ;}
+    break;
+
+  case 191:
+
+/* Line 1455 of yacc.c  */
+#line 1601 "program_parse.y"
+    {
+          (yyval.state)[0] = (yyvsp[(1) - (2)].state)[0];
+          (yyval.state)[1] = (yyvsp[(1) - (2)].state)[1];
+          (yyval.state)[2] = (yyvsp[(2) - (2)].state)[2];
+          (yyval.state)[3] = (yyvsp[(2) - (2)].state)[3];
+          (yyval.state)[4] = (yyvsp[(1) - (2)].state)[2];
+       ;}
+    break;
+
+  case 192:
+
+/* Line 1455 of yacc.c  */
+#line 1611 "program_parse.y"
+    {
+          (yyval.state)[2] = 0;
+          (yyval.state)[3] = 3;
+       ;}
+    break;
+
+  case 193:
+
+/* Line 1455 of yacc.c  */
+#line 1616 "program_parse.y"
+    {
+          /* It seems logical that the matrix row range specifier would have
+           * to specify a range or more than one row (i.e., $5 > $3).
+           * However, the ARB_vertex_program spec says "a program will fail
+           * to load if <a> is greater than <b>."  This means that $3 == $5
+           * is valid.
+           */
+          if ((yyvsp[(3) - (6)].integer) > (yyvsp[(5) - (6)].integer)) {
+             yyerror(& (yylsp[(3) - (6)]), state, "invalid matrix row range");
+             YYERROR;
+          }
+
+          (yyval.state)[2] = (yyvsp[(3) - (6)].integer);
+          (yyval.state)[3] = (yyvsp[(5) - (6)].integer);
+       ;}
+    break;
+
+  case 194:
+
+/* Line 1455 of yacc.c  */
+#line 1634 "program_parse.y"
+    {
+          (yyval.state)[0] = (yyvsp[(2) - (3)].state)[0];
+          (yyval.state)[1] = (yyvsp[(2) - (3)].state)[1];
+          (yyval.state)[2] = (yyvsp[(3) - (3)].integer);
+       ;}
+    break;
+
+  case 195:
+
+/* Line 1455 of yacc.c  */
+#line 1642 "program_parse.y"
+    {
+          (yyval.integer) = 0;
+       ;}
+    break;
+
+  case 196:
+
+/* Line 1455 of yacc.c  */
+#line 1646 "program_parse.y"
+    {
+          (yyval.integer) = (yyvsp[(1) - (1)].integer);
+       ;}
+    break;
+
+  case 197:
+
+/* Line 1455 of yacc.c  */
+#line 1652 "program_parse.y"
+    {
+          (yyval.integer) = STATE_MATRIX_INVERSE;
+       ;}
+    break;
+
+  case 198:
+
+/* Line 1455 of yacc.c  */
+#line 1656 "program_parse.y"
+    {
+          (yyval.integer) = STATE_MATRIX_TRANSPOSE;
+       ;}
+    break;
+
+  case 199:
+
+/* Line 1455 of yacc.c  */
+#line 1660 "program_parse.y"
+    {
+          (yyval.integer) = STATE_MATRIX_INVTRANS;
+       ;}
+    break;
+
+  case 200:
+
+/* Line 1455 of yacc.c  */
+#line 1666 "program_parse.y"
+    {
+          if ((yyvsp[(1) - (1)].integer) > 3) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid matrix row reference");
+             YYERROR;
+          }
+
+          (yyval.integer) = (yyvsp[(1) - (1)].integer);
+       ;}
+    break;
+
+  case 201:
+
+/* Line 1455 of yacc.c  */
+#line 1677 "program_parse.y"
+    {
+          (yyval.state)[0] = STATE_MODELVIEW_MATRIX;
+          (yyval.state)[1] = (yyvsp[(2) - (2)].integer);
+       ;}
+    break;
+
+  case 202:
+
+/* Line 1455 of yacc.c  */
+#line 1682 "program_parse.y"
+    {
+          (yyval.state)[0] = STATE_PROJECTION_MATRIX;
+          (yyval.state)[1] = 0;
+       ;}
+    break;
+
+  case 203:
+
+/* Line 1455 of yacc.c  */
+#line 1687 "program_parse.y"
+    {
+          (yyval.state)[0] = STATE_MVP_MATRIX;
+          (yyval.state)[1] = 0;
+       ;}
+    break;
+
+  case 204:
+
+/* Line 1455 of yacc.c  */
+#line 1692 "program_parse.y"
+    {
+          (yyval.state)[0] = STATE_TEXTURE_MATRIX;
+          (yyval.state)[1] = (yyvsp[(2) - (2)].integer);
+       ;}
+    break;
+
+  case 205:
+
+/* Line 1455 of yacc.c  */
+#line 1697 "program_parse.y"
+    {
+          yyerror(& (yylsp[(1) - (4)]), state, "GL_ARB_matrix_palette not supported");
+          YYERROR;
+       ;}
+    break;
+
+  case 206:
+
+/* Line 1455 of yacc.c  */
+#line 1702 "program_parse.y"
+    {
+          (yyval.state)[0] = STATE_PROGRAM_MATRIX;
+          (yyval.state)[1] = (yyvsp[(3) - (4)].integer);
+       ;}
+    break;
+
+  case 207:
+
+/* Line 1455 of yacc.c  */
+#line 1709 "program_parse.y"
+    {
+          (yyval.integer) = 0;
+       ;}
+    break;
+
+  case 208:
+
+/* Line 1455 of yacc.c  */
+#line 1713 "program_parse.y"
+    {
+          (yyval.integer) = (yyvsp[(2) - (3)].integer);
+       ;}
+    break;
+
+  case 209:
+
+/* Line 1455 of yacc.c  */
+#line 1718 "program_parse.y"
+    {
+          /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix
+           * zero is valid.
+           */
+          if ((yyvsp[(1) - (1)].integer) != 0) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid modelview matrix index");
+             YYERROR;
+          }
+
+          (yyval.integer) = (yyvsp[(1) - (1)].integer);
+       ;}
+    break;
+
+  case 210:
+
+/* Line 1455 of yacc.c  */
+#line 1731 "program_parse.y"
+    {
+          /* Since GL_ARB_matrix_palette isn't supported, just let any value
+           * through here.  The error will be generated later.
+           */
+          (yyval.integer) = (yyvsp[(1) - (1)].integer);
+       ;}
+    break;
+
+  case 211:
+
+/* Line 1455 of yacc.c  */
+#line 1739 "program_parse.y"
+    {
+          if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxProgramMatrices) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid program matrix selector");
+             YYERROR;
+          }
+
+          (yyval.integer) = (yyvsp[(1) - (1)].integer);
+       ;}
+    break;
+
+  case 212:
+
+/* Line 1455 of yacc.c  */
+#line 1750 "program_parse.y"
+    {
+          memset((yyval.state), 0, sizeof((yyval.state)));
+          (yyval.state)[0] = STATE_DEPTH_RANGE;
+       ;}
+    break;
+
+  case 217:
+
+/* Line 1455 of yacc.c  */
+#line 1762 "program_parse.y"
+    {
+          memset((yyval.state), 0, sizeof((yyval.state)));
+          (yyval.state)[0] = state->state_param_enum;
+          (yyval.state)[1] = STATE_ENV;
+          (yyval.state)[2] = (yyvsp[(4) - (5)].state)[0];
+          (yyval.state)[3] = (yyvsp[(4) - (5)].state)[1];
+       ;}
+    break;
+
+  case 218:
+
+/* Line 1455 of yacc.c  */
+#line 1772 "program_parse.y"
+    {
+          (yyval.state)[0] = (yyvsp[(1) - (1)].integer);
+          (yyval.state)[1] = (yyvsp[(1) - (1)].integer);
+       ;}
+    break;
+
+  case 219:
+
+/* Line 1455 of yacc.c  */
+#line 1777 "program_parse.y"
+    {
+          (yyval.state)[0] = (yyvsp[(1) - (3)].integer);
+          (yyval.state)[1] = (yyvsp[(3) - (3)].integer);
+       ;}
+    break;
+
+  case 220:
+
+/* Line 1455 of yacc.c  */
+#line 1784 "program_parse.y"
+    {
+          memset((yyval.state), 0, sizeof((yyval.state)));
+          (yyval.state)[0] = state->state_param_enum;
+          (yyval.state)[1] = STATE_ENV;
+          (yyval.state)[2] = (yyvsp[(4) - (5)].integer);
+          (yyval.state)[3] = (yyvsp[(4) - (5)].integer);
+       ;}
+    break;
+
+  case 221:
+
+/* Line 1455 of yacc.c  */
+#line 1794 "program_parse.y"
+    {
+          memset((yyval.state), 0, sizeof((yyval.state)));
+          (yyval.state)[0] = state->state_param_enum;
+          (yyval.state)[1] = STATE_LOCAL;
+          (yyval.state)[2] = (yyvsp[(4) - (5)].state)[0];
+          (yyval.state)[3] = (yyvsp[(4) - (5)].state)[1];
+       ;}
+    break;
+
+  case 222:
+
+/* Line 1455 of yacc.c  */
+#line 1803 "program_parse.y"
+    {
+          (yyval.state)[0] = (yyvsp[(1) - (1)].integer);
+          (yyval.state)[1] = (yyvsp[(1) - (1)].integer);
+       ;}
+    break;
+
+  case 223:
+
+/* Line 1455 of yacc.c  */
+#line 1808 "program_parse.y"
+    {
+          (yyval.state)[0] = (yyvsp[(1) - (3)].integer);
+          (yyval.state)[1] = (yyvsp[(3) - (3)].integer);
+       ;}
+    break;
+
+  case 224:
+
+/* Line 1455 of yacc.c  */
+#line 1815 "program_parse.y"
+    {
+          memset((yyval.state), 0, sizeof((yyval.state)));
+          (yyval.state)[0] = state->state_param_enum;
+          (yyval.state)[1] = STATE_LOCAL;
+          (yyval.state)[2] = (yyvsp[(4) - (5)].integer);
+          (yyval.state)[3] = (yyvsp[(4) - (5)].integer);
+       ;}
+    break;
+
+  case 225:
+
+/* Line 1455 of yacc.c  */
+#line 1825 "program_parse.y"
+    {
+          if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxEnvParams) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid environment parameter reference");
+             YYERROR;
+          }
+          (yyval.integer) = (yyvsp[(1) - (1)].integer);
+       ;}
+    break;
+
+  case 226:
+
+/* Line 1455 of yacc.c  */
+#line 1835 "program_parse.y"
+    {
+          if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxLocalParams) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid local parameter reference");
+             YYERROR;
+          }
+          (yyval.integer) = (yyvsp[(1) - (1)].integer);
+       ;}
+    break;
+
+  case 231:
+
+/* Line 1455 of yacc.c  */
+#line 1850 "program_parse.y"
+    {
+          (yyval.vector).count = 4;
+          (yyval.vector).data[0] = (yyvsp[(1) - (1)].real);
+          (yyval.vector).data[1] = (yyvsp[(1) - (1)].real);
+          (yyval.vector).data[2] = (yyvsp[(1) - (1)].real);
+          (yyval.vector).data[3] = (yyvsp[(1) - (1)].real);
+       ;}
+    break;
+
+  case 232:
+
+/* Line 1455 of yacc.c  */
+#line 1860 "program_parse.y"
+    {
+          (yyval.vector).count = 1;
+          (yyval.vector).data[0] = (yyvsp[(1) - (1)].real);
+          (yyval.vector).data[1] = (yyvsp[(1) - (1)].real);
+          (yyval.vector).data[2] = (yyvsp[(1) - (1)].real);
+          (yyval.vector).data[3] = (yyvsp[(1) - (1)].real);
+       ;}
+    break;
+
+  case 233:
+
+/* Line 1455 of yacc.c  */
+#line 1868 "program_parse.y"
+    {
+          (yyval.vector).count = 1;
+          (yyval.vector).data[0] = (float) (yyvsp[(1) - (1)].integer);
+          (yyval.vector).data[1] = (float) (yyvsp[(1) - (1)].integer);
+          (yyval.vector).data[2] = (float) (yyvsp[(1) - (1)].integer);
+          (yyval.vector).data[3] = (float) (yyvsp[(1) - (1)].integer);
+       ;}
+    break;
+
+  case 234:
+
+/* Line 1455 of yacc.c  */
+#line 1878 "program_parse.y"
+    {
+          (yyval.vector).count = 4;
+          (yyval.vector).data[0] = (yyvsp[(2) - (3)].real);
+          (yyval.vector).data[1] = 0.0f;
+          (yyval.vector).data[2] = 0.0f;
+          (yyval.vector).data[3] = 1.0f;
+       ;}
+    break;
+
+  case 235:
+
+/* Line 1455 of yacc.c  */
+#line 1886 "program_parse.y"
+    {
+          (yyval.vector).count = 4;
+          (yyval.vector).data[0] = (yyvsp[(2) - (5)].real);
+          (yyval.vector).data[1] = (yyvsp[(4) - (5)].real);
+          (yyval.vector).data[2] = 0.0f;
+          (yyval.vector).data[3] = 1.0f;
+       ;}
+    break;
+
+  case 236:
+
+/* Line 1455 of yacc.c  */
+#line 1895 "program_parse.y"
+    {
+          (yyval.vector).count = 4;
+          (yyval.vector).data[0] = (yyvsp[(2) - (7)].real);
+          (yyval.vector).data[1] = (yyvsp[(4) - (7)].real);
+          (yyval.vector).data[2] = (yyvsp[(6) - (7)].real);
+          (yyval.vector).data[3] = 1.0f;
+       ;}
+    break;
+
+  case 237:
+
+/* Line 1455 of yacc.c  */
+#line 1904 "program_parse.y"
+    {
+          (yyval.vector).count = 4;
+          (yyval.vector).data[0] = (yyvsp[(2) - (9)].real);
+          (yyval.vector).data[1] = (yyvsp[(4) - (9)].real);
+          (yyval.vector).data[2] = (yyvsp[(6) - (9)].real);
+          (yyval.vector).data[3] = (yyvsp[(8) - (9)].real);
+       ;}
+    break;
+
+  case 238:
+
+/* Line 1455 of yacc.c  */
+#line 1914 "program_parse.y"
+    {
+          (yyval.real) = ((yyvsp[(1) - (2)].negate)) ? -(yyvsp[(2) - (2)].real) : (yyvsp[(2) - (2)].real);
+       ;}
+    break;
+
+  case 239:
+
+/* Line 1455 of yacc.c  */
+#line 1918 "program_parse.y"
+    {
+          (yyval.real) = (float)(((yyvsp[(1) - (2)].negate)) ? -(yyvsp[(2) - (2)].integer) : (yyvsp[(2) - (2)].integer));
+       ;}
+    break;
+
+  case 240:
+
+/* Line 1455 of yacc.c  */
+#line 1923 "program_parse.y"
+    { (yyval.negate) = FALSE; ;}
+    break;
+
+  case 241:
+
+/* Line 1455 of yacc.c  */
+#line 1924 "program_parse.y"
+    { (yyval.negate) = TRUE;  ;}
+    break;
+
+  case 242:
+
+/* Line 1455 of yacc.c  */
+#line 1925 "program_parse.y"
+    { (yyval.negate) = FALSE; ;}
+    break;
+
+  case 243:
+
+/* Line 1455 of yacc.c  */
+#line 1928 "program_parse.y"
+    { (yyval.integer) = (yyvsp[(2) - (2)].integer); ;}
+    break;
+
+  case 245:
+
+/* Line 1455 of yacc.c  */
+#line 1932 "program_parse.y"
+    {
+          /* NV_fragment_program_option defines the size qualifiers in a
+           * fairly broken way.  "SHORT" or "LONG" can optionally be used
+           * before TEMP or OUTPUT.  However, neither is a reserved word!
+           * This means that we have to parse it as an identifier, then check
+           * to make sure it's one of the valid values.  *sigh*
+           *
+           * In addition, the grammar in the extension spec does *not* allow
+           * the size specifier to be optional, but all known implementations
+           * do.
+           */
+          if (!state->option.NV_fragment) {
+             yyerror(& (yylsp[(1) - (1)]), state, "unexpected IDENTIFIER");
+             YYERROR;
+          }
+
+          if (strcmp("SHORT", (yyvsp[(1) - (1)].string)) == 0) {
+          } else if (strcmp("LONG", (yyvsp[(1) - (1)].string)) == 0) {
+          } else {
+             char *const err_str =
+                make_error_string("invalid storage size specifier \"%s\"",
+                                  (yyvsp[(1) - (1)].string));
+
+             yyerror(& (yylsp[(1) - (1)]), state, (err_str != NULL)
+                     ? err_str : "invalid storage size specifier");
+
+             if (err_str != NULL) {
+                free(err_str);
+             }
+
+             YYERROR;
+          }
+       ;}
+    break;
+
+  case 246:
+
+/* Line 1455 of yacc.c  */
+#line 1966 "program_parse.y"
+    {
+       ;}
+    break;
+
+  case 247:
+
+/* Line 1455 of yacc.c  */
+#line 1970 "program_parse.y"
+    { (yyval.integer) = (yyvsp[(1) - (1)].integer); ;}
+    break;
+
+  case 249:
+
+/* Line 1455 of yacc.c  */
+#line 1974 "program_parse.y"
+    {
+          if (!declare_variable(state, (yyvsp[(3) - (3)].string), (yyvsp[(0) - (3)].integer), & (yylsp[(3) - (3)]))) {
+             free((yyvsp[(3) - (3)].string));
+             YYERROR;
+          }
+       ;}
+    break;
+
+  case 250:
+
+/* Line 1455 of yacc.c  */
+#line 1981 "program_parse.y"
+    {
+          if (!declare_variable(state, (yyvsp[(1) - (1)].string), (yyvsp[(0) - (1)].integer), & (yylsp[(1) - (1)]))) {
+             free((yyvsp[(1) - (1)].string));
+             YYERROR;
+          }
+       ;}
+    break;
+
+  case 251:
+
+/* Line 1455 of yacc.c  */
+#line 1990 "program_parse.y"
+    {
+          struct asm_symbol *const s =
+             declare_variable(state, (yyvsp[(3) - (5)].string), at_output, & (yylsp[(3) - (5)]));
+
+          if (s == NULL) {
+             free((yyvsp[(3) - (5)].string));
+             YYERROR;
+          } else {
+             s->output_binding = (yyvsp[(5) - (5)].result);
+          }
+       ;}
+    break;
+
+  case 252:
+
+/* Line 1455 of yacc.c  */
+#line 2004 "program_parse.y"
+    {
+          if (state->mode == ARB_vertex) {
+             (yyval.result) = VERT_RESULT_HPOS;
+          } else {
+             yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name");
+             YYERROR;
+          }
+       ;}
+    break;
+
+  case 253:
+
+/* Line 1455 of yacc.c  */
+#line 2013 "program_parse.y"
+    {
+          if (state->mode == ARB_vertex) {
+             (yyval.result) = VERT_RESULT_FOGC;
+          } else {
+             yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name");
+             YYERROR;
+          }
+       ;}
+    break;
+
+  case 254:
+
+/* Line 1455 of yacc.c  */
+#line 2022 "program_parse.y"
+    {
+          (yyval.result) = (yyvsp[(2) - (2)].result);
+       ;}
+    break;
+
+  case 255:
+
+/* Line 1455 of yacc.c  */
+#line 2026 "program_parse.y"
+    {
+          if (state->mode == ARB_vertex) {
+             (yyval.result) = VERT_RESULT_PSIZ;
+          } else {
+             yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name");
+             YYERROR;
+          }
+       ;}
+    break;
+
+  case 256:
+
+/* Line 1455 of yacc.c  */
+#line 2035 "program_parse.y"
+    {
+          if (state->mode == ARB_vertex) {
+             (yyval.result) = VERT_RESULT_TEX0 + (yyvsp[(3) - (3)].integer);
+          } else {
+             yyerror(& (yylsp[(2) - (3)]), state, "invalid program result name");
+             YYERROR;
+          }
+       ;}
+    break;
+
+  case 257:
+
+/* Line 1455 of yacc.c  */
+#line 2044 "program_parse.y"
+    {
+          if (state->mode == ARB_fragment) {
+             (yyval.result) = FRAG_RESULT_DEPTH;
+          } else {
+             yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name");
+             YYERROR;
+          }
+       ;}
+    break;
+
+  case 258:
+
+/* Line 1455 of yacc.c  */
+#line 2055 "program_parse.y"
+    {
+          (yyval.result) = (yyvsp[(2) - (3)].integer) + (yyvsp[(3) - (3)].integer);
+       ;}
+    break;
+
+  case 259:
+
+/* Line 1455 of yacc.c  */
+#line 2061 "program_parse.y"
+    {
+          (yyval.integer) = (state->mode == ARB_vertex)
+             ? VERT_RESULT_COL0
+             : FRAG_RESULT_COLOR;
+       ;}
+    break;
+
+  case 260:
+
+/* Line 1455 of yacc.c  */
+#line 2067 "program_parse.y"
+    {
+          if (state->mode == ARB_vertex) {
+             (yyval.integer) = VERT_RESULT_COL0;
+          } else {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name");
+             YYERROR;
+          }
+       ;}
+    break;
+
+  case 261:
+
+/* Line 1455 of yacc.c  */
+#line 2076 "program_parse.y"
+    {
+          if (state->mode == ARB_vertex) {
+             (yyval.integer) = VERT_RESULT_BFC0;
+          } else {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name");
+             YYERROR;
+          }
+       ;}
+    break;
+
+  case 262:
+
+/* Line 1455 of yacc.c  */
+#line 2087 "program_parse.y"
+    {
+          (yyval.integer) = 0; 
+       ;}
+    break;
+
+  case 263:
+
+/* Line 1455 of yacc.c  */
+#line 2091 "program_parse.y"
+    {
+          if (state->mode == ARB_vertex) {
+             (yyval.integer) = 0;
+          } else {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name");
+             YYERROR;
+          }
+       ;}
+    break;
+
+  case 264:
+
+/* Line 1455 of yacc.c  */
+#line 2100 "program_parse.y"
+    {
+          if (state->mode == ARB_vertex) {
+             (yyval.integer) = 1;
+          } else {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name");
+             YYERROR;
+          }
+       ;}
+    break;
+
+  case 265:
+
+/* Line 1455 of yacc.c  */
+#line 2110 "program_parse.y"
+    { (yyval.integer) = 0; ;}
+    break;
+
+  case 266:
+
+/* Line 1455 of yacc.c  */
+#line 2111 "program_parse.y"
+    { (yyval.integer) = 0; ;}
+    break;
+
+  case 267:
+
+/* Line 1455 of yacc.c  */
+#line 2112 "program_parse.y"
+    { (yyval.integer) = 1; ;}
+    break;
+
+  case 268:
+
+/* Line 1455 of yacc.c  */
+#line 2115 "program_parse.y"
+    { (yyval.integer) = 0; ;}
+    break;
+
+  case 269:
+
+/* Line 1455 of yacc.c  */
+#line 2116 "program_parse.y"
+    { (yyval.integer) = 0; ;}
+    break;
+
+  case 270:
+
+/* Line 1455 of yacc.c  */
+#line 2117 "program_parse.y"
+    { (yyval.integer) = 1; ;}
+    break;
+
+  case 271:
+
+/* Line 1455 of yacc.c  */
+#line 2120 "program_parse.y"
+    { (yyval.integer) = 0; ;}
+    break;
+
+  case 272:
+
+/* Line 1455 of yacc.c  */
+#line 2121 "program_parse.y"
+    { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;}
+    break;
+
+  case 273:
+
+/* Line 1455 of yacc.c  */
+#line 2124 "program_parse.y"
+    { (yyval.integer) = 0; ;}
+    break;
+
+  case 274:
+
+/* Line 1455 of yacc.c  */
+#line 2125 "program_parse.y"
+    { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;}
+    break;
+
+  case 275:
+
+/* Line 1455 of yacc.c  */
+#line 2128 "program_parse.y"
+    { (yyval.integer) = 0; ;}
+    break;
+
+  case 276:
+
+/* Line 1455 of yacc.c  */
+#line 2129 "program_parse.y"
+    { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;}
+    break;
+
+  case 277:
+
+/* Line 1455 of yacc.c  */
+#line 2133 "program_parse.y"
+    {
+          if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureCoordUnits) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid texture coordinate unit selector");
+             YYERROR;
+          }
+
+          (yyval.integer) = (yyvsp[(1) - (1)].integer);
+       ;}
+    break;
+
+  case 278:
+
+/* Line 1455 of yacc.c  */
+#line 2144 "program_parse.y"
+    {
+          if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureImageUnits) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid texture image unit selector");
+             YYERROR;
+          }
+
+          (yyval.integer) = (yyvsp[(1) - (1)].integer);
+       ;}
+    break;
+
+  case 279:
+
+/* Line 1455 of yacc.c  */
+#line 2155 "program_parse.y"
+    {
+          if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureUnits) {
+             yyerror(& (yylsp[(1) - (1)]), state, "invalid texture unit selector");
+             YYERROR;
+          }
+
+          (yyval.integer) = (yyvsp[(1) - (1)].integer);
+       ;}
+    break;
+
+  case 280:
+
+/* Line 1455 of yacc.c  */
+#line 2166 "program_parse.y"
+    {
+          struct asm_symbol *exist = (struct asm_symbol *)
+             _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(2) - (4)].string));
+          struct asm_symbol *target = (struct asm_symbol *)
+             _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(4) - (4)].string));
+
+          free((yyvsp[(4) - (4)].string));
+
+          if (exist != NULL) {
+             char m[1000];
+             _mesa_snprintf(m, sizeof(m), "redeclared identifier: %s", (yyvsp[(2) - (4)].string));
+             free((yyvsp[(2) - (4)].string));
+             yyerror(& (yylsp[(2) - (4)]), state, m);
+             YYERROR;
+          } else if (target == NULL) {
+             free((yyvsp[(2) - (4)].string));
+             yyerror(& (yylsp[(4) - (4)]), state,
+                     "undefined variable binding in ALIAS statement");
+             YYERROR;
+          } else {
+             _mesa_symbol_table_add_symbol(state->st, 0, (yyvsp[(2) - (4)].string), target);
+          }
+       ;}
+    break;
+
+
+
+/* Line 1455 of yacc.c  */
+#line 4937 "program_parse.tab.c"
+      default: break;
+    }
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+  *++yylsp = yyloc;
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if ! YYERROR_VERBOSE
+      yyerror (&yylloc, state, YY_("syntax error"));
+#else
+      {
+       YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+       if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+         {
+           YYSIZE_T yyalloc = 2 * yysize;
+           if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+             yyalloc = YYSTACK_ALLOC_MAXIMUM;
+           if (yymsg != yymsgbuf)
+             YYSTACK_FREE (yymsg);
+           yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+           if (yymsg)
+             yymsg_alloc = yyalloc;
+           else
+             {
+               yymsg = yymsgbuf;
+               yymsg_alloc = sizeof yymsgbuf;
+             }
+         }
+
+       if (0 < yysize && yysize <= yymsg_alloc)
+         {
+           (void) yysyntax_error (yymsg, yystate, yychar);
+           yyerror (&yylloc, state, yymsg);
+         }
+       else
+         {
+           yyerror (&yylloc, state, YY_("syntax error"));
+           if (yysize != 0)
+             goto yyexhaustedlab;
+         }
+      }
+#endif
+    }
+
+  yyerror_range[0] = yylloc;
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse lookahead token after an
+        error, discard it.  */
+
+      if (yychar <= YYEOF)
+       {
+         /* Return failure if at end of input.  */
+         if (yychar == YYEOF)
+           YYABORT;
+       }
+      else
+       {
+         yydestruct ("Error: discarding",
+                     yytoken, &yylval, &yylloc, state);
+         yychar = YYEMPTY;
+       }
+    }
+
+  /* Else will try to reuse lookahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+  /* Pacify compilers like GCC when the user code never invokes
+     YYERROR and the label yyerrorlab therefore never appears in user
+     code.  */
+  if (/*CONSTCOND*/ 0)
+     goto yyerrorlab;
+
+  yyerror_range[0] = yylsp[1-yylen];
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYERROR.  */
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;     /* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+       {
+         yyn += YYTERROR;
+         if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+           {
+             yyn = yytable[yyn];
+             if (0 < yyn)
+               break;
+           }
+       }
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+       YYABORT;
+
+      yyerror_range[0] = *yylsp;
+      yydestruct ("Error: popping",
+                 yystos[yystate], yyvsp, yylsp, state);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  *++yyvsp = yylval;
+
+  yyerror_range[1] = yylloc;
+  /* Using YYLLOC is tempting, but would change the location of
+     the lookahead.  YYLOC is available though.  */
+  YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
+  *++yylsp = yyloc;
+
+  /* Shift the error token.  */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#if !defined(yyoverflow) || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (&yylloc, state, YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+                yytoken, &yylval, &yylloc, state);
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYABORT or YYACCEPT.  */
+  YYPOPSTACK (yylen);
+  YY_STACK_PRINT (yyss, yyssp);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+                 yystos[*yyssp], yyvsp, yylsp, state);
+      YYPOPSTACK (1);
+    }
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+  if (yymsg != yymsgbuf)
+    YYSTACK_FREE (yymsg);
+#endif
+  /* Make sure YYID is used.  */
+  return YYID (yyresult);
+}
+
+
+
+/* Line 1675 of yacc.c  */
+#line 2195 "program_parse.y"
+
+
+void
+asm_instruction_set_operands(struct asm_instruction *inst,
+                            const struct prog_dst_register *dst,
+                            const struct asm_src_register *src0,
+                            const struct asm_src_register *src1,
+                            const struct asm_src_register *src2)
+{
+   /* In the core ARB extensions only the KIL instruction doesn't have a
+    * destination register.
+    */
+   if (dst == NULL) {
+      init_dst_reg(& inst->Base.DstReg);
+   } else {
+      inst->Base.DstReg = *dst;
+   }
+
+   /* The only instruction that doesn't have any source registers is the
+    * condition-code based KIL instruction added by NV_fragment_program_option.
+    */
+   if (src0 != NULL) {
+      inst->Base.SrcReg[0] = src0->Base;
+      inst->SrcReg[0] = *src0;
+   } else {
+      init_src_reg(& inst->SrcReg[0]);
+   }
+
+   if (src1 != NULL) {
+      inst->Base.SrcReg[1] = src1->Base;
+      inst->SrcReg[1] = *src1;
+   } else {
+      init_src_reg(& inst->SrcReg[1]);
+   }
+
+   if (src2 != NULL) {
+      inst->Base.SrcReg[2] = src2->Base;
+      inst->SrcReg[2] = *src2;
+   } else {
+      init_src_reg(& inst->SrcReg[2]);
+   }
+}
+
+
+struct asm_instruction *
+asm_instruction_ctor(gl_inst_opcode op,
+                    const struct prog_dst_register *dst,
+                    const struct asm_src_register *src0,
+                    const struct asm_src_register *src1,
+                    const struct asm_src_register *src2)
+{
+   struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
+
+   if (inst) {
+      _mesa_init_instructions(& inst->Base, 1);
+      inst->Base.Opcode = op;
+
+      asm_instruction_set_operands(inst, dst, src0, src1, src2);
+   }
+
+   return inst;
+}
+
+
+struct asm_instruction *
+asm_instruction_copy_ctor(const struct prog_instruction *base,
+                         const struct prog_dst_register *dst,
+                         const struct asm_src_register *src0,
+                         const struct asm_src_register *src1,
+                         const struct asm_src_register *src2)
+{
+   struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
+
+   if (inst) {
+      _mesa_init_instructions(& inst->Base, 1);
+      inst->Base.Opcode = base->Opcode;
+      inst->Base.CondUpdate = base->CondUpdate;
+      inst->Base.CondDst = base->CondDst;
+      inst->Base.SaturateMode = base->SaturateMode;
+      inst->Base.Precision = base->Precision;
+
+      asm_instruction_set_operands(inst, dst, src0, src1, src2);
+   }
+
+   return inst;
+}
+
+
+void
+init_dst_reg(struct prog_dst_register *r)
+{
+   memset(r, 0, sizeof(*r));
+   r->File = PROGRAM_UNDEFINED;
+   r->WriteMask = WRITEMASK_XYZW;
+   r->CondMask = COND_TR;
+   r->CondSwizzle = SWIZZLE_NOOP;
+}
+
+
+/** Like init_dst_reg() but set the File and Index fields. */
+void
+set_dst_reg(struct prog_dst_register *r, gl_register_file file, GLint index)
+{
+   const GLint maxIndex = 1 << INST_INDEX_BITS;
+   const GLint minIndex = 0;
+   ASSERT(index >= minIndex);
+   (void) minIndex;
+   ASSERT(index <= maxIndex);
+   (void) maxIndex;
+   ASSERT(file == PROGRAM_TEMPORARY ||
+         file == PROGRAM_ADDRESS ||
+         file == PROGRAM_OUTPUT);
+   memset(r, 0, sizeof(*r));
+   r->File = file;
+   r->Index = index;
+   r->WriteMask = WRITEMASK_XYZW;
+   r->CondMask = COND_TR;
+   r->CondSwizzle = SWIZZLE_NOOP;
+}
+
+
+void
+init_src_reg(struct asm_src_register *r)
+{
+   memset(r, 0, sizeof(*r));
+   r->Base.File = PROGRAM_UNDEFINED;
+   r->Base.Swizzle = SWIZZLE_NOOP;
+   r->Symbol = NULL;
+}
+
+
+/** Like init_src_reg() but set the File and Index fields.
+ * \return GL_TRUE if a valid src register, GL_FALSE otherwise
+ */
+void
+set_src_reg(struct asm_src_register *r, gl_register_file file, GLint index)
+{
+   set_src_reg_swz(r, file, index, SWIZZLE_XYZW);
+}
+
+
+void
+set_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index,
+                GLuint swizzle)
+{
+   const GLint maxIndex = (1 << INST_INDEX_BITS) - 1;
+   const GLint minIndex = -(1 << INST_INDEX_BITS);
+   ASSERT(file < PROGRAM_FILE_MAX);
+   ASSERT(index >= minIndex);
+   (void) minIndex;
+   ASSERT(index <= maxIndex);
+   (void) maxIndex;
+   memset(r, 0, sizeof(*r));
+   r->Base.File = file;
+   r->Base.Index = index;
+   r->Base.Swizzle = swizzle;
+   r->Symbol = NULL;
+}
+
+
+/**
+ * Validate the set of inputs used by a program
+ *
+ * Validates that legal sets of inputs are used by the program.  In this case
+ * "used" included both reading the input or binding the input to a name using
+ * the \c ATTRIB command.
+ *
+ * \return
+ * \c TRUE if the combination of inputs used is valid, \c FALSE otherwise.
+ */
+int
+validate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state)
+{
+   const int inputs = state->prog->InputsRead | state->InputsBound;
+
+   if (((inputs & 0x0ffff) & (inputs >> 16)) != 0) {
+      yyerror(locp, state, "illegal use of generic attribute and name attribute");
+      return 0;
+   }
+
+   return 1;
+}
+
+
+struct asm_symbol *
+declare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
+                struct YYLTYPE *locp)
+{
+   struct asm_symbol *s = NULL;
+   struct asm_symbol *exist = (struct asm_symbol *)
+      _mesa_symbol_table_find_symbol(state->st, 0, name);
+
+
+   if (exist != NULL) {
+      yyerror(locp, state, "redeclared identifier");
+   } else {
+      s = calloc(1, sizeof(struct asm_symbol));
+      s->name = name;
+      s->type = t;
+
+      switch (t) {
+      case at_temp:
+        if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
+           yyerror(locp, state, "too many temporaries declared");
+           free(s);
+           return NULL;
+        }
+
+        s->temp_binding = state->prog->NumTemporaries;
+        state->prog->NumTemporaries++;
+        break;
+
+      case at_address:
+        if (state->prog->NumAddressRegs >= state->limits->MaxAddressRegs) {
+           yyerror(locp, state, "too many address registers declared");
+           free(s);
+           return NULL;
+        }
+
+        /* FINISHME: Add support for multiple address registers.
+         */
+        state->prog->NumAddressRegs++;
+        break;
+
+      default:
+        break;
+      }
+
+      _mesa_symbol_table_add_symbol(state->st, 0, s->name, s);
+      s->next = state->sym;
+      state->sym = s;
+   }
+
+   return s;
+}
+
+
+int add_state_reference(struct gl_program_parameter_list *param_list,
+                       const gl_state_index tokens[STATE_LENGTH])
+{
+   const GLuint size = 4; /* XXX fix */
+   char *name;
+   GLint index;
+
+   name = _mesa_program_state_string(tokens);
+   index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name,
+                               size, GL_NONE, NULL, tokens, 0x0);
+   param_list->StateFlags |= _mesa_program_state_flags(tokens);
+
+   /* free name string here since we duplicated it in add_parameter() */
+   free(name);
+
+   return index;
+}
+
+
+int
+initialize_symbol_from_state(struct gl_program *prog,
+                            struct asm_symbol *param_var, 
+                            const gl_state_index tokens[STATE_LENGTH])
+{
+   int idx = -1;
+   gl_state_index state_tokens[STATE_LENGTH];
+
+
+   memcpy(state_tokens, tokens, sizeof(state_tokens));
+
+   param_var->type = at_param;
+   param_var->param_binding_type = PROGRAM_STATE_VAR;
+
+   /* If we are adding a STATE_MATRIX that has multiple rows, we need to
+    * unroll it and call add_state_reference() for each row
+    */
+   if ((state_tokens[0] == STATE_MODELVIEW_MATRIX ||
+       state_tokens[0] == STATE_PROJECTION_MATRIX ||
+       state_tokens[0] == STATE_MVP_MATRIX ||
+       state_tokens[0] == STATE_TEXTURE_MATRIX ||
+       state_tokens[0] == STATE_PROGRAM_MATRIX)
+       && (state_tokens[2] != state_tokens[3])) {
+      int row;
+      const int first_row = state_tokens[2];
+      const int last_row = state_tokens[3];
+
+      for (row = first_row; row <= last_row; row++) {
+        state_tokens[2] = state_tokens[3] = row;
+
+        idx = add_state_reference(prog->Parameters, state_tokens);
+        if (param_var->param_binding_begin == ~0U) {
+           param_var->param_binding_begin = idx;
+            param_var->param_binding_swizzle = SWIZZLE_XYZW;
+         }
+
+        param_var->param_binding_length++;
+      }
+   }
+   else {
+      idx = add_state_reference(prog->Parameters, state_tokens);
+      if (param_var->param_binding_begin == ~0U) {
+        param_var->param_binding_begin = idx;
+         param_var->param_binding_swizzle = SWIZZLE_XYZW;
+      }
+      param_var->param_binding_length++;
+   }
+
+   return idx;
+}
+
+
+int
+initialize_symbol_from_param(struct gl_program *prog,
+                            struct asm_symbol *param_var, 
+                            const gl_state_index tokens[STATE_LENGTH])
+{
+   int idx = -1;
+   gl_state_index state_tokens[STATE_LENGTH];
+
+
+   memcpy(state_tokens, tokens, sizeof(state_tokens));
+
+   assert((state_tokens[0] == STATE_VERTEX_PROGRAM)
+         || (state_tokens[0] == STATE_FRAGMENT_PROGRAM));
+   assert((state_tokens[1] == STATE_ENV)
+         || (state_tokens[1] == STATE_LOCAL));
+
+   /*
+    * The param type is STATE_VAR.  The program parameter entry will
+    * effectively be a pointer into the LOCAL or ENV parameter array.
+    */
+   param_var->type = at_param;
+   param_var->param_binding_type = PROGRAM_STATE_VAR;
+
+   /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements,
+    * we need to unroll it and call add_state_reference() for each row
+    */
+   if (state_tokens[2] != state_tokens[3]) {
+      int row;
+      const int first_row = state_tokens[2];
+      const int last_row = state_tokens[3];
+
+      for (row = first_row; row <= last_row; row++) {
+        state_tokens[2] = state_tokens[3] = row;
+
+        idx = add_state_reference(prog->Parameters, state_tokens);
+        if (param_var->param_binding_begin == ~0U) {
+           param_var->param_binding_begin = idx;
+            param_var->param_binding_swizzle = SWIZZLE_XYZW;
+         }
+        param_var->param_binding_length++;
+      }
+   }
+   else {
+      idx = add_state_reference(prog->Parameters, state_tokens);
+      if (param_var->param_binding_begin == ~0U) {
+        param_var->param_binding_begin = idx;
+         param_var->param_binding_swizzle = SWIZZLE_XYZW;
+      }
+      param_var->param_binding_length++;
+   }
+
+   return idx;
+}
+
+
+/**
+ * Put a float/vector constant/literal into the parameter list.
+ * \param param_var  returns info about the parameter/constant's location,
+ *                   binding, type, etc.
+ * \param vec  the vector/constant to add
+ * \param allowSwizzle  if true, try to consolidate constants which only differ
+ *                      by a swizzle.  We don't want to do this when building
+ *                      arrays of constants that may be indexed indirectly.
+ * \return index of the constant in the parameter list.
+ */
+int
+initialize_symbol_from_const(struct gl_program *prog,
+                            struct asm_symbol *param_var, 
+                            const struct asm_vector *vec,
+                             GLboolean allowSwizzle)
+{
+   unsigned swizzle;
+   const int idx = _mesa_add_unnamed_constant(prog->Parameters,
+                                              vec->data, vec->count,
+                                              allowSwizzle ? &swizzle : NULL);
+
+   param_var->type = at_param;
+   param_var->param_binding_type = PROGRAM_CONSTANT;
+
+   if (param_var->param_binding_begin == ~0U) {
+      param_var->param_binding_begin = idx;
+      param_var->param_binding_swizzle = allowSwizzle ? swizzle : SWIZZLE_XYZW;
+   }
+   param_var->param_binding_length++;
+
+   return idx;
+}
+
+
+char *
+make_error_string(const char *fmt, ...)
+{
+   int length;
+   char *str;
+   va_list args;
+
+
+   /* Call vsnprintf once to determine how large the final string is.  Call it
+    * again to do the actual formatting.  from the vsnprintf manual page:
+    *
+    *    Upon successful return, these functions return the number of
+    *    characters printed  (not including the trailing '\0' used to end
+    *    output to strings).
+    */
+   va_start(args, fmt);
+   length = 1 + vsnprintf(NULL, 0, fmt, args);
+   va_end(args);
+
+   str = malloc(length);
+   if (str) {
+      va_start(args, fmt);
+      vsnprintf(str, length, fmt, args);
+      va_end(args);
+   }
+
+   return str;
+}
+
+
+void
+yyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s)
+{
+   char *err_str;
+
+
+   err_str = make_error_string("glProgramStringARB(%s)\n", s);
+   if (err_str) {
+      _mesa_error(state->ctx, GL_INVALID_OPERATION, err_str);
+      free(err_str);
+   }
+
+   err_str = make_error_string("line %u, char %u: error: %s\n",
+                              locp->first_line, locp->first_column, s);
+   _mesa_set_program_error(state->ctx, locp->position, err_str);
+
+   if (err_str) {
+      free(err_str);
+   }
+}
+
+
+GLboolean
+_mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str,
+                       GLsizei len, struct asm_parser_state *state)
+{
+   struct asm_instruction *inst;
+   unsigned i;
+   GLubyte *strz;
+   GLboolean result = GL_FALSE;
+   void *temp;
+   struct asm_symbol *sym;
+
+   state->ctx = ctx;
+   state->prog->Target = target;
+   state->prog->Parameters = _mesa_new_parameter_list();
+
+   /* Make a copy of the program string and force it to be NUL-terminated.
+    */
+   strz = (GLubyte *) malloc(len + 1);
+   if (strz == NULL) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
+      return GL_FALSE;
+   }
+   memcpy (strz, str, len);
+   strz[len] = '\0';
+
+   state->prog->String = strz;
+
+   state->st = _mesa_symbol_table_ctor();
+
+   state->limits = (target == GL_VERTEX_PROGRAM_ARB)
+      ? & ctx->Const.VertexProgram
+      : & ctx->Const.FragmentProgram;
+
+   state->MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits;
+   state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits;
+   state->MaxTextureUnits = ctx->Const.MaxTextureUnits;
+   state->MaxClipPlanes = ctx->Const.MaxClipPlanes;
+   state->MaxLights = ctx->Const.MaxLights;
+   state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices;
+
+   state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB)
+      ? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM;
+
+   _mesa_set_program_error(ctx, -1, NULL);
+
+   _mesa_program_lexer_ctor(& state->scanner, state, (const char *) str, len);
+   yyparse(state);
+   _mesa_program_lexer_dtor(state->scanner);
+
+
+   if (ctx->Program.ErrorPos != -1) {
+      goto error;
+   }
+
+   if (! _mesa_layout_parameters(state)) {
+      struct YYLTYPE loc;
+
+      loc.first_line = 0;
+      loc.first_column = 0;
+      loc.position = len;
+
+      yyerror(& loc, state, "invalid PARAM usage");
+      goto error;
+   }
+
+
+   
+   /* Add one instruction to store the "END" instruction.
+    */
+   state->prog->Instructions =
+      _mesa_alloc_instructions(state->prog->NumInstructions + 1);
+   inst = state->inst_head;
+   for (i = 0; i < state->prog->NumInstructions; i++) {
+      struct asm_instruction *const temp = inst->next;
+
+      state->prog->Instructions[i] = inst->Base;
+      inst = temp;
+   }
+
+   /* Finally, tag on an OPCODE_END instruction */
+   {
+      const GLuint numInst = state->prog->NumInstructions;
+      _mesa_init_instructions(state->prog->Instructions + numInst, 1);
+      state->prog->Instructions[numInst].Opcode = OPCODE_END;
+   }
+   state->prog->NumInstructions++;
+
+   state->prog->NumParameters = state->prog->Parameters->NumParameters;
+   state->prog->NumAttributes = _mesa_bitcount(state->prog->InputsRead);
+
+   /*
+    * Initialize native counts to logical counts.  The device driver may
+    * change them if program is translated into a hardware program.
+    */
+   state->prog->NumNativeInstructions = state->prog->NumInstructions;
+   state->prog->NumNativeTemporaries = state->prog->NumTemporaries;
+   state->prog->NumNativeParameters = state->prog->NumParameters;
+   state->prog->NumNativeAttributes = state->prog->NumAttributes;
+   state->prog->NumNativeAddressRegs = state->prog->NumAddressRegs;
+
+   result = GL_TRUE;
+
+error:
+   for (inst = state->inst_head; inst != NULL; inst = temp) {
+      temp = inst->next;
+      free(inst);
+   }
+
+   state->inst_head = NULL;
+   state->inst_tail = NULL;
+
+   for (sym = state->sym; sym != NULL; sym = temp) {
+      temp = sym->next;
+
+      free((void *) sym->name);
+      free(sym);
+   }
+   state->sym = NULL;
+
+   _mesa_symbol_table_dtor(state->st);
+   state->st = NULL;
+
+   return result;
+}
+
diff --git a/src/mesa/program/program_parse.tab.h b/src/mesa/program/program_parse.tab.h
new file mode 100644 (file)
index 0000000..045241d
--- /dev/null
@@ -0,0 +1,209 @@
+
+/* A Bison parser, made by GNU Bison 2.4.1.  */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+   
+      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+   
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+   
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     ARBvp_10 = 258,
+     ARBfp_10 = 259,
+     ADDRESS = 260,
+     ALIAS = 261,
+     ATTRIB = 262,
+     OPTION = 263,
+     OUTPUT = 264,
+     PARAM = 265,
+     TEMP = 266,
+     END = 267,
+     BIN_OP = 268,
+     BINSC_OP = 269,
+     SAMPLE_OP = 270,
+     SCALAR_OP = 271,
+     TRI_OP = 272,
+     VECTOR_OP = 273,
+     ARL = 274,
+     KIL = 275,
+     SWZ = 276,
+     TXD_OP = 277,
+     INTEGER = 278,
+     REAL = 279,
+     AMBIENT = 280,
+     ATTENUATION = 281,
+     BACK = 282,
+     CLIP = 283,
+     COLOR = 284,
+     DEPTH = 285,
+     DIFFUSE = 286,
+     DIRECTION = 287,
+     EMISSION = 288,
+     ENV = 289,
+     EYE = 290,
+     FOG = 291,
+     FOGCOORD = 292,
+     FRAGMENT = 293,
+     FRONT = 294,
+     HALF = 295,
+     INVERSE = 296,
+     INVTRANS = 297,
+     LIGHT = 298,
+     LIGHTMODEL = 299,
+     LIGHTPROD = 300,
+     LOCAL = 301,
+     MATERIAL = 302,
+     MAT_PROGRAM = 303,
+     MATRIX = 304,
+     MATRIXINDEX = 305,
+     MODELVIEW = 306,
+     MVP = 307,
+     NORMAL = 308,
+     OBJECT = 309,
+     PALETTE = 310,
+     PARAMS = 311,
+     PLANE = 312,
+     POINT_TOK = 313,
+     POINTSIZE = 314,
+     POSITION = 315,
+     PRIMARY = 316,
+     PROGRAM = 317,
+     PROJECTION = 318,
+     RANGE = 319,
+     RESULT = 320,
+     ROW = 321,
+     SCENECOLOR = 322,
+     SECONDARY = 323,
+     SHININESS = 324,
+     SIZE_TOK = 325,
+     SPECULAR = 326,
+     SPOT = 327,
+     STATE = 328,
+     TEXCOORD = 329,
+     TEXENV = 330,
+     TEXGEN = 331,
+     TEXGEN_Q = 332,
+     TEXGEN_R = 333,
+     TEXGEN_S = 334,
+     TEXGEN_T = 335,
+     TEXTURE = 336,
+     TRANSPOSE = 337,
+     TEXTURE_UNIT = 338,
+     TEX_1D = 339,
+     TEX_2D = 340,
+     TEX_3D = 341,
+     TEX_CUBE = 342,
+     TEX_RECT = 343,
+     TEX_SHADOW1D = 344,
+     TEX_SHADOW2D = 345,
+     TEX_SHADOWRECT = 346,
+     TEX_ARRAY1D = 347,
+     TEX_ARRAY2D = 348,
+     TEX_ARRAYSHADOW1D = 349,
+     TEX_ARRAYSHADOW2D = 350,
+     VERTEX = 351,
+     VTXATTRIB = 352,
+     WEIGHT = 353,
+     IDENTIFIER = 354,
+     USED_IDENTIFIER = 355,
+     MASK4 = 356,
+     MASK3 = 357,
+     MASK2 = 358,
+     MASK1 = 359,
+     SWIZZLE = 360,
+     DOT_DOT = 361,
+     DOT = 362
+   };
+#endif
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+
+/* Line 1676 of yacc.c  */
+#line 126 "program_parse.y"
+
+   struct asm_instruction *inst;
+   struct asm_symbol *sym;
+   struct asm_symbol temp_sym;
+   struct asm_swizzle_mask swiz_mask;
+   struct asm_src_register src_reg;
+   struct prog_dst_register dst_reg;
+   struct prog_instruction temp_inst;
+   char *string;
+   unsigned result;
+   unsigned attrib;
+   int integer;
+   float real;
+   gl_state_index state[STATE_LENGTH];
+   int negate;
+   struct asm_vector vector;
+   gl_inst_opcode opcode;
+
+   struct {
+      unsigned swz;
+      unsigned rgba_valid:1;
+      unsigned xyzw_valid:1;
+      unsigned negate:1;
+   } ext_swizzle;
+
+
+
+/* Line 1676 of yacc.c  */
+#line 187 "program_parse.tab.h"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+  int first_line;
+  int first_column;
+  int last_line;
+  int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+
diff --git a/src/mesa/program/program_parse.y b/src/mesa/program/program_parse.y
new file mode 100644 (file)
index 0000000..861927c
--- /dev/null
@@ -0,0 +1,2767 @@
+%{
+/*
+ * Copyright Â© 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "main/mtypes.h"
+#include "main/imports.h"
+#include "program/program.h"
+#include "program/prog_parameter.h"
+#include "program/prog_parameter_layout.h"
+#include "program/prog_statevars.h"
+#include "program/prog_instruction.h"
+
+#include "program/symbol_table.h"
+#include "program/program_parser.h"
+
+extern void *yy_scan_string(char *);
+extern void yy_delete_buffer(void *);
+
+static struct asm_symbol *declare_variable(struct asm_parser_state *state,
+    char *name, enum asm_type t, struct YYLTYPE *locp);
+
+static int add_state_reference(struct gl_program_parameter_list *param_list,
+    const gl_state_index tokens[STATE_LENGTH]);
+
+static int initialize_symbol_from_state(struct gl_program *prog,
+    struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
+
+static int initialize_symbol_from_param(struct gl_program *prog,
+    struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
+
+static int initialize_symbol_from_const(struct gl_program *prog,
+    struct asm_symbol *param_var, const struct asm_vector *vec,
+    GLboolean allowSwizzle);
+
+static int yyparse(struct asm_parser_state *state);
+
+static char *make_error_string(const char *fmt, ...);
+
+static void yyerror(struct YYLTYPE *locp, struct asm_parser_state *state,
+    const char *s);
+
+static int validate_inputs(struct YYLTYPE *locp,
+    struct asm_parser_state *state);
+
+static void init_dst_reg(struct prog_dst_register *r);
+
+static void set_dst_reg(struct prog_dst_register *r,
+                        gl_register_file file, GLint index);
+
+static void init_src_reg(struct asm_src_register *r);
+
+static void set_src_reg(struct asm_src_register *r,
+                        gl_register_file file, GLint index);
+
+static void set_src_reg_swz(struct asm_src_register *r,
+                            gl_register_file file, GLint index, GLuint swizzle);
+
+static void asm_instruction_set_operands(struct asm_instruction *inst,
+    const struct prog_dst_register *dst, const struct asm_src_register *src0,
+    const struct asm_src_register *src1, const struct asm_src_register *src2);
+
+static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op,
+    const struct prog_dst_register *dst, const struct asm_src_register *src0,
+    const struct asm_src_register *src1, const struct asm_src_register *src2);
+
+static struct asm_instruction *asm_instruction_copy_ctor(
+    const struct prog_instruction *base, const struct prog_dst_register *dst,
+    const struct asm_src_register *src0, const struct asm_src_register *src1,
+    const struct asm_src_register *src2);
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE (!FALSE)
+#endif
+
+#define YYLLOC_DEFAULT(Current, Rhs, N)                                        \
+   do {                                                                        \
+      if (YYID(N)) {                                                   \
+        (Current).first_line = YYRHSLOC(Rhs, 1).first_line;            \
+        (Current).first_column = YYRHSLOC(Rhs, 1).first_column;        \
+        (Current).position = YYRHSLOC(Rhs, 1).position;                \
+        (Current).last_line = YYRHSLOC(Rhs, N).last_line;              \
+        (Current).last_column = YYRHSLOC(Rhs, N).last_column;          \
+      } else {                                                         \
+        (Current).first_line = YYRHSLOC(Rhs, 0).last_line;             \
+        (Current).last_line = (Current).first_line;                    \
+        (Current).first_column = YYRHSLOC(Rhs, 0).last_column;         \
+        (Current).last_column = (Current).first_column;                \
+        (Current).position = YYRHSLOC(Rhs, 0).position                 \
+           + (Current).first_column;                                   \
+      }                                                                        \
+   } while(YYID(0))
+
+#define YYLEX_PARAM state->scanner
+%}
+
+%pure-parser
+%locations
+%parse-param { struct asm_parser_state *state }
+%error-verbose
+%lex-param { void *scanner }
+
+%union {
+   struct asm_instruction *inst;
+   struct asm_symbol *sym;
+   struct asm_symbol temp_sym;
+   struct asm_swizzle_mask swiz_mask;
+   struct asm_src_register src_reg;
+   struct prog_dst_register dst_reg;
+   struct prog_instruction temp_inst;
+   char *string;
+   unsigned result;
+   unsigned attrib;
+   int integer;
+   float real;
+   gl_state_index state[STATE_LENGTH];
+   int negate;
+   struct asm_vector vector;
+   gl_inst_opcode opcode;
+
+   struct {
+      unsigned swz;
+      unsigned rgba_valid:1;
+      unsigned xyzw_valid:1;
+      unsigned negate:1;
+   } ext_swizzle;
+}
+
+%token ARBvp_10 ARBfp_10
+
+/* Tokens for assembler pseudo-ops */
+%token <integer> ADDRESS
+%token ALIAS ATTRIB
+%token OPTION OUTPUT
+%token PARAM
+%token <integer> TEMP
+%token END
+
+ /* Tokens for instructions */
+%token <temp_inst> BIN_OP BINSC_OP SAMPLE_OP SCALAR_OP TRI_OP VECTOR_OP
+%token <temp_inst> ARL KIL SWZ TXD_OP
+
+%token <integer> INTEGER
+%token <real> REAL
+
+%token AMBIENT ATTENUATION
+%token BACK
+%token CLIP COLOR
+%token DEPTH DIFFUSE DIRECTION
+%token EMISSION ENV EYE
+%token FOG FOGCOORD FRAGMENT FRONT
+%token HALF
+%token INVERSE INVTRANS
+%token LIGHT LIGHTMODEL LIGHTPROD LOCAL
+%token MATERIAL MAT_PROGRAM MATRIX MATRIXINDEX MODELVIEW MVP
+%token NORMAL
+%token OBJECT
+%token PALETTE PARAMS PLANE POINT_TOK POINTSIZE POSITION PRIMARY PROGRAM PROJECTION
+%token RANGE RESULT ROW
+%token SCENECOLOR SECONDARY SHININESS SIZE_TOK SPECULAR SPOT STATE
+%token TEXCOORD TEXENV TEXGEN TEXGEN_Q TEXGEN_R TEXGEN_S TEXGEN_T TEXTURE TRANSPOSE
+%token TEXTURE_UNIT TEX_1D TEX_2D TEX_3D TEX_CUBE TEX_RECT
+%token TEX_SHADOW1D TEX_SHADOW2D TEX_SHADOWRECT
+%token TEX_ARRAY1D TEX_ARRAY2D TEX_ARRAYSHADOW1D TEX_ARRAYSHADOW2D 
+%token VERTEX VTXATTRIB
+%token WEIGHT
+
+%token <string> IDENTIFIER USED_IDENTIFIER
+%type <string> string
+%token <swiz_mask> MASK4 MASK3 MASK2 MASK1 SWIZZLE
+%token DOT_DOT
+%token DOT
+
+%type <inst> instruction ALU_instruction TexInstruction
+%type <inst> ARL_instruction VECTORop_instruction
+%type <inst> SCALARop_instruction BINSCop_instruction BINop_instruction
+%type <inst> TRIop_instruction TXD_instruction SWZ_instruction SAMPLE_instruction
+%type <inst> KIL_instruction
+
+%type <dst_reg> dstReg maskedDstReg maskedAddrReg
+%type <src_reg> srcReg scalarUse scalarSrcReg swizzleSrcReg
+%type <swiz_mask> scalarSuffix swizzleSuffix extendedSwizzle
+%type <ext_swizzle> extSwizComp extSwizSel
+%type <swiz_mask> optionalMask
+
+%type <sym> progParamArray
+%type <integer> addrRegRelOffset addrRegPosOffset addrRegNegOffset
+%type <src_reg> progParamArrayMem progParamArrayAbs progParamArrayRel
+%type <sym> addrReg
+%type <swiz_mask> addrComponent addrWriteMask
+
+%type <dst_reg> ccMaskRule ccTest ccMaskRule2 ccTest2 optionalCcMask
+
+%type <result> resultBinding resultColBinding
+%type <integer> optFaceType optColorType
+%type <integer> optResultFaceType optResultColorType
+
+%type <integer> optTexImageUnitNum texImageUnitNum
+%type <integer> optTexCoordUnitNum texCoordUnitNum
+%type <integer> optLegacyTexUnitNum legacyTexUnitNum
+%type <integer> texImageUnit texTarget
+%type <integer> vtxAttribNum
+
+%type <attrib> attribBinding vtxAttribItem fragAttribItem
+
+%type <temp_sym> paramSingleInit paramSingleItemDecl
+%type <integer> optArraySize
+
+%type <state> stateSingleItem stateMultipleItem
+%type <state> stateMaterialItem
+%type <state> stateLightItem stateLightModelItem stateLightProdItem
+%type <state> stateTexGenItem stateFogItem stateClipPlaneItem statePointItem
+%type <state> stateMatrixItem stateMatrixRow stateMatrixRows
+%type <state> stateTexEnvItem stateDepthItem
+
+%type <state> stateLModProperty
+%type <state> stateMatrixName optMatrixRows
+
+%type <integer> stateMatProperty
+%type <integer> stateLightProperty stateSpotProperty
+%type <integer> stateLightNumber stateLProdProperty
+%type <integer> stateTexGenType stateTexGenCoord
+%type <integer> stateTexEnvProperty
+%type <integer> stateFogProperty
+%type <integer> stateClipPlaneNum
+%type <integer> statePointProperty
+
+%type <integer> stateOptMatModifier stateMatModifier stateMatrixRowNum
+%type <integer> stateOptModMatNum stateModMatNum statePaletteMatNum 
+%type <integer> stateProgramMatNum
+
+%type <integer> ambDiffSpecProperty
+
+%type <state> programSingleItem progEnvParam progLocalParam
+%type <state> programMultipleItem progEnvParams progLocalParams
+
+%type <temp_sym> paramMultipleInit paramMultInitList paramMultipleItem
+%type <temp_sym> paramSingleItemUse
+
+%type <integer> progEnvParamNum progLocalParamNum
+%type <state> progEnvParamNums progLocalParamNums
+
+%type <vector> paramConstDecl paramConstUse
+%type <vector> paramConstScalarDecl paramConstScalarUse paramConstVector
+%type <real> signedFloatConstant
+%type <negate> optionalSign
+
+%{
+extern int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
+    void *yyscanner);
+%}
+
+%%
+
+program: language optionSequence statementSequence END
+       ;
+
+language: ARBvp_10
+       {
+          if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) {
+             yyerror(& @1, state, "invalid fragment program header");
+
+          }
+          state->mode = ARB_vertex;
+       }
+       | ARBfp_10
+       {
+          if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) {
+             yyerror(& @1, state, "invalid vertex program header");
+          }
+          state->mode = ARB_fragment;
+
+          state->option.TexRect =
+             (state->ctx->Extensions.NV_texture_rectangle != GL_FALSE);
+       }
+       ;
+
+optionSequence: optionSequence option
+       |
+       ;
+
+option: OPTION string ';'
+       {
+          int valid = 0;
+
+          if (state->mode == ARB_vertex) {
+             valid = _mesa_ARBvp_parse_option(state, $2);
+          } else if (state->mode == ARB_fragment) {
+             valid = _mesa_ARBfp_parse_option(state, $2);
+          }
+
+
+          free($2);
+
+          if (!valid) {
+             const char *const err_str = (state->mode == ARB_vertex)
+                ? "invalid ARB vertex program option"
+                : "invalid ARB fragment program option";
+
+             yyerror(& @2, state, err_str);
+             YYERROR;
+          }
+       }
+       ;
+
+statementSequence: statementSequence statement
+       |
+       ;
+
+statement: instruction ';'
+       {
+          if ($1 != NULL) {
+             if (state->inst_tail == NULL) {
+                state->inst_head = $1;
+             } else {
+                state->inst_tail->next = $1;
+             }
+
+             state->inst_tail = $1;
+             $1->next = NULL;
+
+             state->prog->NumInstructions++;
+          }
+       }
+       | namingStatement ';'
+       ;
+
+instruction: ALU_instruction
+       {
+          $$ = $1;
+          state->prog->NumAluInstructions++;
+       }
+       | TexInstruction
+       {
+          $$ = $1;
+          state->prog->NumTexInstructions++;
+       }
+       ;
+
+ALU_instruction: ARL_instruction
+       | VECTORop_instruction
+       | SCALARop_instruction
+       | BINSCop_instruction
+       | BINop_instruction
+       | TRIop_instruction
+       | SWZ_instruction
+       ;
+
+TexInstruction: SAMPLE_instruction
+       | KIL_instruction
+       | TXD_instruction
+       ;
+
+ARL_instruction: ARL maskedAddrReg ',' scalarSrcReg
+       {
+          $$ = asm_instruction_ctor(OPCODE_ARL, & $2, & $4, NULL, NULL);
+       }
+       ;
+
+VECTORop_instruction: VECTOR_OP maskedDstReg ',' swizzleSrcReg
+       {
+          $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
+       }
+       ;
+
+SCALARop_instruction: SCALAR_OP maskedDstReg ',' scalarSrcReg
+       {
+          $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
+       }
+       ;
+
+BINSCop_instruction: BINSC_OP maskedDstReg ',' scalarSrcReg ',' scalarSrcReg
+       {
+          $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL);
+       }
+       ;
+
+
+BINop_instruction: BIN_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg
+       {
+          $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL);
+       }
+       ;
+
+TRIop_instruction: TRI_OP maskedDstReg ','
+                   swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg
+       {
+          $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8);
+       }
+       ;
+
+SAMPLE_instruction: SAMPLE_OP maskedDstReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
+       {
+          $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
+          if ($$ != NULL) {
+             const GLbitfield tex_mask = (1U << $6);
+             GLbitfield shadow_tex = 0;
+             GLbitfield target_mask = 0;
+
+
+             $$->Base.TexSrcUnit = $6;
+
+             if ($8 < 0) {
+                shadow_tex = tex_mask;
+
+                $$->Base.TexSrcTarget = -$8;
+                $$->Base.TexShadow = 1;
+             } else {
+                $$->Base.TexSrcTarget = $8;
+             }
+
+             target_mask = (1U << $$->Base.TexSrcTarget);
+
+             /* If this texture unit was previously accessed and that access
+              * had a different texture target, generate an error.
+              *
+              * If this texture unit was previously accessed and that access
+              * had a different shadow mode, generate an error.
+              */
+             if ((state->prog->TexturesUsed[$6] != 0)
+                 && ((state->prog->TexturesUsed[$6] != target_mask)
+                     || ((state->prog->ShadowSamplers & tex_mask)
+                         != shadow_tex))) {
+                yyerror(& @8, state,
+                        "multiple targets used on one texture image unit");
+                YYERROR;
+             }
+
+
+             state->prog->TexturesUsed[$6] |= target_mask;
+             state->prog->ShadowSamplers |= shadow_tex;
+          }
+       }
+       ;
+
+KIL_instruction: KIL swizzleSrcReg
+       {
+          $$ = asm_instruction_ctor(OPCODE_KIL, NULL, & $2, NULL, NULL);
+          state->fragment.UsesKill = 1;
+       }
+       | KIL ccTest
+       {
+          $$ = asm_instruction_ctor(OPCODE_KIL_NV, NULL, NULL, NULL, NULL);
+          $$->Base.DstReg.CondMask = $2.CondMask;
+          $$->Base.DstReg.CondSwizzle = $2.CondSwizzle;
+          $$->Base.DstReg.CondSrc = $2.CondSrc;
+          state->fragment.UsesKill = 1;
+       }
+       ;
+
+TXD_instruction: TXD_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
+       {
+          $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8);
+          if ($$ != NULL) {
+             const GLbitfield tex_mask = (1U << $10);
+             GLbitfield shadow_tex = 0;
+             GLbitfield target_mask = 0;
+
+
+             $$->Base.TexSrcUnit = $10;
+
+             if ($12 < 0) {
+                shadow_tex = tex_mask;
+
+                $$->Base.TexSrcTarget = -$12;
+                $$->Base.TexShadow = 1;
+             } else {
+                $$->Base.TexSrcTarget = $12;
+             }
+
+             target_mask = (1U << $$->Base.TexSrcTarget);
+
+             /* If this texture unit was previously accessed and that access
+              * had a different texture target, generate an error.
+              *
+              * If this texture unit was previously accessed and that access
+              * had a different shadow mode, generate an error.
+              */
+             if ((state->prog->TexturesUsed[$10] != 0)
+                 && ((state->prog->TexturesUsed[$10] != target_mask)
+                     || ((state->prog->ShadowSamplers & tex_mask)
+                         != shadow_tex))) {
+                yyerror(& @12, state,
+                        "multiple targets used on one texture image unit");
+                YYERROR;
+             }
+
+
+             state->prog->TexturesUsed[$10] |= target_mask;
+             state->prog->ShadowSamplers |= shadow_tex;
+          }
+       }
+       ;
+
+texImageUnit: TEXTURE_UNIT optTexImageUnitNum
+       {
+          $$ = $2;
+       }
+       ;
+
+texTarget: TEX_1D  { $$ = TEXTURE_1D_INDEX; }
+       | TEX_2D   { $$ = TEXTURE_2D_INDEX; }
+       | TEX_3D   { $$ = TEXTURE_3D_INDEX; }
+       | TEX_CUBE { $$ = TEXTURE_CUBE_INDEX; }
+       | TEX_RECT { $$ = TEXTURE_RECT_INDEX; }
+       | TEX_SHADOW1D   { $$ = -TEXTURE_1D_INDEX; }
+       | TEX_SHADOW2D   { $$ = -TEXTURE_2D_INDEX; }
+       | TEX_SHADOWRECT { $$ = -TEXTURE_RECT_INDEX; }
+       | TEX_ARRAY1D         { $$ = TEXTURE_1D_ARRAY_INDEX; }
+       | TEX_ARRAY2D         { $$ = TEXTURE_2D_ARRAY_INDEX; }
+       | TEX_ARRAYSHADOW1D   { $$ = -TEXTURE_1D_ARRAY_INDEX; }
+       | TEX_ARRAYSHADOW2D   { $$ = -TEXTURE_2D_ARRAY_INDEX; }
+       ;
+
+SWZ_instruction: SWZ maskedDstReg ',' srcReg ',' extendedSwizzle
+       {
+          /* FIXME: Is this correct?  Should the extenedSwizzle be applied
+           * FIXME: to the existing swizzle?
+           */
+          $4.Base.Swizzle = $6.swizzle;
+          $4.Base.Negate = $6.mask;
+
+          $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
+       }
+       ;
+
+scalarSrcReg: optionalSign scalarUse
+       {
+          $$ = $2;
+
+          if ($1) {
+             $$.Base.Negate = ~$$.Base.Negate;
+          }
+       }
+       | optionalSign '|' scalarUse '|'
+       {
+          $$ = $3;
+
+          if (!state->option.NV_fragment) {
+             yyerror(& @2, state, "unexpected character '|'");
+             YYERROR;
+          }
+
+          if ($1) {
+             $$.Base.Negate = ~$$.Base.Negate;
+          }
+
+          $$.Base.Abs = 1;
+       }
+       ;
+
+scalarUse:  srcReg scalarSuffix
+       {
+          $$ = $1;
+
+          $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
+                                                   $2.swizzle);
+       }
+       | paramConstScalarUse
+       {
+          struct asm_symbol temp_sym;
+
+          if (!state->option.NV_fragment) {
+             yyerror(& @1, state, "expected scalar suffix");
+             YYERROR;
+          }
+
+          memset(& temp_sym, 0, sizeof(temp_sym));
+          temp_sym.param_binding_begin = ~0;
+          initialize_symbol_from_const(state->prog, & temp_sym, & $1, GL_TRUE);
+
+          set_src_reg_swz(& $$, PROGRAM_CONSTANT,
+                           temp_sym.param_binding_begin,
+                           temp_sym.param_binding_swizzle);
+       }
+       ;
+
+swizzleSrcReg: optionalSign srcReg swizzleSuffix
+       {
+          $$ = $2;
+
+          if ($1) {
+             $$.Base.Negate = ~$$.Base.Negate;
+          }
+
+          $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
+                                                   $3.swizzle);
+       }
+       | optionalSign '|' srcReg swizzleSuffix '|'
+       {
+          $$ = $3;
+
+          if (!state->option.NV_fragment) {
+             yyerror(& @2, state, "unexpected character '|'");
+             YYERROR;
+          }
+
+          if ($1) {
+             $$.Base.Negate = ~$$.Base.Negate;
+          }
+
+          $$.Base.Abs = 1;
+          $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
+                                                   $4.swizzle);
+       }
+
+       ;
+
+maskedDstReg: dstReg optionalMask optionalCcMask
+       {
+          $$ = $1;
+          $$.WriteMask = $2.mask;
+          $$.CondMask = $3.CondMask;
+          $$.CondSwizzle = $3.CondSwizzle;
+          $$.CondSrc = $3.CondSrc;
+
+          if ($$.File == PROGRAM_OUTPUT) {
+             /* Technically speaking, this should check that it is in
+              * vertex program mode.  However, PositionInvariant can never be
+              * set in fragment program mode, so it is somewhat irrelevant.
+              */
+             if (state->option.PositionInvariant
+              && ($$.Index == VERT_RESULT_HPOS)) {
+                yyerror(& @1, state, "position-invariant programs cannot "
+                        "write position");
+                YYERROR;
+             }
+
+             state->prog->OutputsWritten |= BITFIELD64_BIT($$.Index);
+          }
+       }
+       ;
+
+maskedAddrReg: addrReg addrWriteMask
+       {
+          set_dst_reg(& $$, PROGRAM_ADDRESS, 0);
+          $$.WriteMask = $2.mask;
+       }
+       ;
+
+extendedSwizzle: extSwizComp ',' extSwizComp ',' extSwizComp ',' extSwizComp
+       {
+          const unsigned xyzw_valid =
+             ($1.xyzw_valid << 0)
+             | ($3.xyzw_valid << 1)
+             | ($5.xyzw_valid << 2)
+             | ($7.xyzw_valid << 3);
+          const unsigned rgba_valid =
+             ($1.rgba_valid << 0)
+             | ($3.rgba_valid << 1)
+             | ($5.rgba_valid << 2)
+             | ($7.rgba_valid << 3);
+
+          /* All of the swizzle components have to be valid in either RGBA
+           * or XYZW.  Note that 0 and 1 are valid in both, so both masks
+           * can have some bits set.
+           *
+           * We somewhat deviate from the spec here.  It would be really hard
+           * to figure out which component is the error, and there probably
+           * isn't a lot of benefit.
+           */
+          if ((rgba_valid != 0x0f) && (xyzw_valid != 0x0f)) {
+             yyerror(& @1, state, "cannot combine RGBA and XYZW swizzle "
+                     "components");
+             YYERROR;
+          }
+
+          $$.swizzle = MAKE_SWIZZLE4($1.swz, $3.swz, $5.swz, $7.swz);
+          $$.mask = ($1.negate) | ($3.negate << 1) | ($5.negate << 2)
+             | ($7.negate << 3);
+       }
+       ;
+
+extSwizComp: optionalSign extSwizSel
+       {
+          $$ = $2;
+          $$.negate = ($1) ? 1 : 0;
+       }
+       ;
+
+extSwizSel: INTEGER
+       {
+          if (($1 != 0) && ($1 != 1)) {
+             yyerror(& @1, state, "invalid extended swizzle selector");
+             YYERROR;
+          }
+
+          $$.swz = ($1 == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE;
+
+          /* 0 and 1 are valid for both RGBA swizzle names and XYZW
+           * swizzle names.
+           */
+          $$.xyzw_valid = 1;
+          $$.rgba_valid = 1;
+       }
+       | string
+       {
+          char s;
+
+          if (strlen($1) > 1) {
+             yyerror(& @1, state, "invalid extended swizzle selector");
+             YYERROR;
+          }
+
+          s = $1[0];
+          free($1);
+
+          switch (s) {
+          case 'x':
+             $$.swz = SWIZZLE_X;
+             $$.xyzw_valid = 1;
+             break;
+          case 'y':
+             $$.swz = SWIZZLE_Y;
+             $$.xyzw_valid = 1;
+             break;
+          case 'z':
+             $$.swz = SWIZZLE_Z;
+             $$.xyzw_valid = 1;
+             break;
+          case 'w':
+             $$.swz = SWIZZLE_W;
+             $$.xyzw_valid = 1;
+             break;
+
+          case 'r':
+             $$.swz = SWIZZLE_X;
+             $$.rgba_valid = 1;
+             break;
+          case 'g':
+             $$.swz = SWIZZLE_Y;
+             $$.rgba_valid = 1;
+             break;
+          case 'b':
+             $$.swz = SWIZZLE_Z;
+             $$.rgba_valid = 1;
+             break;
+          case 'a':
+             $$.swz = SWIZZLE_W;
+             $$.rgba_valid = 1;
+             break;
+
+          default:
+             yyerror(& @1, state, "invalid extended swizzle selector");
+             YYERROR;
+             break;
+          }
+       }
+       ;
+
+srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */
+       {
+          struct asm_symbol *const s = (struct asm_symbol *)
+             _mesa_symbol_table_find_symbol(state->st, 0, $1);
+
+          free($1);
+
+          if (s == NULL) {
+             yyerror(& @1, state, "invalid operand variable");
+             YYERROR;
+          } else if ((s->type != at_param) && (s->type != at_temp)
+                     && (s->type != at_attrib)) {
+             yyerror(& @1, state, "invalid operand variable");
+             YYERROR;
+          } else if ((s->type == at_param) && s->param_is_array) {
+             yyerror(& @1, state, "non-array access to array PARAM");
+             YYERROR;
+          }
+
+          init_src_reg(& $$);
+          switch (s->type) {
+          case at_temp:
+             set_src_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding);
+             break;
+          case at_param:
+              set_src_reg_swz(& $$, s->param_binding_type,
+                              s->param_binding_begin,
+                              s->param_binding_swizzle);
+             break;
+          case at_attrib:
+             set_src_reg(& $$, PROGRAM_INPUT, s->attrib_binding);
+             state->prog->InputsRead |= (1U << $$.Base.Index);
+
+             if (!validate_inputs(& @1, state)) {
+                YYERROR;
+             }
+             break;
+
+          default:
+             YYERROR;
+             break;
+          }
+       }
+       | attribBinding
+       {
+          set_src_reg(& $$, PROGRAM_INPUT, $1);
+          state->prog->InputsRead |= (1U << $$.Base.Index);
+
+          if (!validate_inputs(& @1, state)) {
+             YYERROR;
+          }
+       }
+       | progParamArray '[' progParamArrayMem ']'
+       {
+          if (! $3.Base.RelAddr
+              && ((unsigned) $3.Base.Index >= $1->param_binding_length)) {
+             yyerror(& @3, state, "out of bounds array access");
+             YYERROR;
+          }
+
+          init_src_reg(& $$);
+          $$.Base.File = $1->param_binding_type;
+
+          if ($3.Base.RelAddr) {
+             $1->param_accessed_indirectly = 1;
+
+             $$.Base.RelAddr = 1;
+             $$.Base.Index = $3.Base.Index;
+             $$.Symbol = $1;
+          } else {
+             $$.Base.Index = $1->param_binding_begin + $3.Base.Index;
+          }
+       }
+       | paramSingleItemUse
+       {
+           gl_register_file file = ($1.name != NULL) 
+             ? $1.param_binding_type
+             : PROGRAM_CONSTANT;
+           set_src_reg_swz(& $$, file, $1.param_binding_begin,
+                           $1.param_binding_swizzle);
+       }
+       ;
+
+dstReg: resultBinding
+       {
+          set_dst_reg(& $$, PROGRAM_OUTPUT, $1);
+       }
+       | USED_IDENTIFIER /* temporaryReg | vertexResultReg */
+       {
+          struct asm_symbol *const s = (struct asm_symbol *)
+             _mesa_symbol_table_find_symbol(state->st, 0, $1);
+
+          free($1);
+
+          if (s == NULL) {
+             yyerror(& @1, state, "invalid operand variable");
+             YYERROR;
+          } else if ((s->type != at_output) && (s->type != at_temp)) {
+             yyerror(& @1, state, "invalid operand variable");
+             YYERROR;
+          }
+
+          switch (s->type) {
+          case at_temp:
+             set_dst_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding);
+             break;
+          case at_output:
+             set_dst_reg(& $$, PROGRAM_OUTPUT, s->output_binding);
+             break;
+          default:
+             set_dst_reg(& $$, s->param_binding_type, s->param_binding_begin);
+             break;
+          }
+       }
+       ;
+
+progParamArray: USED_IDENTIFIER
+       {
+          struct asm_symbol *const s = (struct asm_symbol *)
+             _mesa_symbol_table_find_symbol(state->st, 0, $1);
+
+          free($1);
+
+          if (s == NULL) {
+             yyerror(& @1, state, "invalid operand variable");
+             YYERROR;
+          } else if ((s->type != at_param) || !s->param_is_array) {
+             yyerror(& @1, state, "array access to non-PARAM variable");
+             YYERROR;
+          } else {
+             $$ = s;
+          }
+       }
+       ;
+
+progParamArrayMem: progParamArrayAbs | progParamArrayRel;
+
+progParamArrayAbs: INTEGER
+       {
+          init_src_reg(& $$);
+          $$.Base.Index = $1;
+       }
+       ;
+
+progParamArrayRel: addrReg addrComponent addrRegRelOffset
+       {
+          /* FINISHME: Add support for multiple address registers.
+           */
+          /* FINISHME: Add support for 4-component address registers.
+           */
+          init_src_reg(& $$);
+          $$.Base.RelAddr = 1;
+          $$.Base.Index = $3;
+       }
+       ;
+
+addrRegRelOffset:              { $$ = 0; }
+       | '+' addrRegPosOffset { $$ = $2; }
+       | '-' addrRegNegOffset { $$ = -$2; }
+       ;
+
+addrRegPosOffset: INTEGER
+       {
+          if (($1 < 0) || ($1 > 63)) {
+              char s[100];
+              _mesa_snprintf(s, sizeof(s),
+                             "relative address offset too large (%d)", $1);
+             yyerror(& @1, state, s);
+             YYERROR;
+          } else {
+             $$ = $1;
+          }
+       }
+       ;
+
+addrRegNegOffset: INTEGER
+       {
+          if (($1 < 0) || ($1 > 64)) {
+              char s[100];
+              _mesa_snprintf(s, sizeof(s),
+                             "relative address offset too large (%d)", $1);
+             yyerror(& @1, state, s);
+             YYERROR;
+          } else {
+             $$ = $1;
+          }
+       }
+       ;
+
+addrReg: USED_IDENTIFIER
+       {
+          struct asm_symbol *const s = (struct asm_symbol *)
+             _mesa_symbol_table_find_symbol(state->st, 0, $1);
+
+          free($1);
+
+          if (s == NULL) {
+             yyerror(& @1, state, "invalid array member");
+             YYERROR;
+          } else if (s->type != at_address) {
+             yyerror(& @1, state,
+                     "invalid variable for indexed array access");
+             YYERROR;
+          } else {
+             $$ = s;
+          }
+       }
+       ;
+
+addrComponent: MASK1
+       {
+          if ($1.mask != WRITEMASK_X) {
+             yyerror(& @1, state, "invalid address component selector");
+             YYERROR;
+          } else {
+             $$ = $1;
+          }
+       }
+       ;
+
+addrWriteMask: MASK1
+       {
+          if ($1.mask != WRITEMASK_X) {
+             yyerror(& @1, state,
+                     "address register write mask must be \".x\"");
+             YYERROR;
+          } else {
+             $$ = $1;
+          }
+       }
+       ;
+
+scalarSuffix: MASK1;
+
+swizzleSuffix: MASK1
+       | MASK4
+       | SWIZZLE
+       |              { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
+       ;
+
+optionalMask: MASK4 | MASK3 | MASK2 | MASK1 
+       |              { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
+       ;
+
+optionalCcMask: '(' ccTest ')'
+       {
+          $$ = $2;
+       }
+       | '(' ccTest2 ')'
+       {
+          $$ = $2;
+       }
+       |
+       {
+          $$.CondMask = COND_TR;
+          $$.CondSwizzle = SWIZZLE_NOOP;
+          $$.CondSrc = 0;
+       }
+       ;
+
+ccTest: ccMaskRule swizzleSuffix
+       {
+          $$ = $1;
+          $$.CondSwizzle = $2.swizzle;
+       }
+       ;
+
+ccTest2: ccMaskRule2 swizzleSuffix
+       {
+          $$ = $1;
+          $$.CondSwizzle = $2.swizzle;
+       }
+       ;
+
+ccMaskRule: IDENTIFIER
+       {
+          const int cond = _mesa_parse_cc($1);
+          if ((cond == 0) || ($1[2] != '\0')) {
+             char *const err_str =
+                make_error_string("invalid condition code \"%s\"", $1);
+
+             yyerror(& @1, state, (err_str != NULL)
+                     ? err_str : "invalid condition code");
+
+             if (err_str != NULL) {
+                free(err_str);
+             }
+
+             YYERROR;
+          }
+
+          $$.CondMask = cond;
+          $$.CondSwizzle = SWIZZLE_NOOP;
+          $$.CondSrc = 0;
+       }
+       ;
+
+ccMaskRule2: USED_IDENTIFIER
+       {
+          const int cond = _mesa_parse_cc($1);
+          if ((cond == 0) || ($1[2] != '\0')) {
+             char *const err_str =
+                make_error_string("invalid condition code \"%s\"", $1);
+
+             yyerror(& @1, state, (err_str != NULL)
+                     ? err_str : "invalid condition code");
+
+             if (err_str != NULL) {
+                free(err_str);
+             }
+
+             YYERROR;
+          }
+
+          $$.CondMask = cond;
+          $$.CondSwizzle = SWIZZLE_NOOP;
+          $$.CondSrc = 0;
+       }
+       ;
+
+namingStatement: ATTRIB_statement
+       | PARAM_statement
+       | TEMP_statement
+       | ADDRESS_statement
+       | OUTPUT_statement
+       | ALIAS_statement
+       ;
+
+ATTRIB_statement: ATTRIB IDENTIFIER '=' attribBinding
+       {
+          struct asm_symbol *const s =
+             declare_variable(state, $2, at_attrib, & @2);
+
+          if (s == NULL) {
+             free($2);
+             YYERROR;
+          } else {
+             s->attrib_binding = $4;
+             state->InputsBound |= (1U << s->attrib_binding);
+
+             if (!validate_inputs(& @4, state)) {
+                YYERROR;
+             }
+          }
+       }
+       ;
+
+attribBinding: VERTEX vtxAttribItem
+       {
+          $$ = $2;
+       }
+       | FRAGMENT fragAttribItem
+       {
+          $$ = $2;
+       }
+       ;
+
+vtxAttribItem: POSITION
+       {
+          $$ = VERT_ATTRIB_POS;
+       }
+       | WEIGHT vtxOptWeightNum
+       {
+          $$ = VERT_ATTRIB_WEIGHT;
+       }
+       | NORMAL
+       {
+          $$ = VERT_ATTRIB_NORMAL;
+       }
+       | COLOR optColorType
+       {
+          if (!state->ctx->Extensions.EXT_secondary_color) {
+             yyerror(& @2, state, "GL_EXT_secondary_color not supported");
+             YYERROR;
+          }
+
+          $$ = VERT_ATTRIB_COLOR0 + $2;
+       }
+       | FOGCOORD
+       {
+          if (!state->ctx->Extensions.EXT_fog_coord) {
+             yyerror(& @1, state, "GL_EXT_fog_coord not supported");
+             YYERROR;
+          }
+
+          $$ = VERT_ATTRIB_FOG;
+       }
+       | TEXCOORD optTexCoordUnitNum
+       {
+          $$ = VERT_ATTRIB_TEX0 + $2;
+       }
+       | MATRIXINDEX '[' vtxWeightNum ']'
+       {
+          yyerror(& @1, state, "GL_ARB_matrix_palette not supported");
+          YYERROR;
+       }
+       | VTXATTRIB '[' vtxAttribNum ']'
+       {
+          $$ = VERT_ATTRIB_GENERIC0 + $3;
+       }
+       ;
+
+vtxAttribNum: INTEGER
+       {
+          if ((unsigned) $1 >= state->limits->MaxAttribs) {
+             yyerror(& @1, state, "invalid vertex attribute reference");
+             YYERROR;
+          }
+
+          $$ = $1;
+       }
+       ;
+
+vtxOptWeightNum:  | '[' vtxWeightNum ']';
+vtxWeightNum: INTEGER;
+
+fragAttribItem: POSITION
+       {
+          $$ = FRAG_ATTRIB_WPOS;
+       }
+       | COLOR optColorType
+       {
+          $$ = FRAG_ATTRIB_COL0 + $2;
+       }
+       | FOGCOORD
+       {
+          $$ = FRAG_ATTRIB_FOGC;
+       }
+       | TEXCOORD optTexCoordUnitNum
+       {
+          $$ = FRAG_ATTRIB_TEX0 + $2;
+       }
+       ;
+
+PARAM_statement: PARAM_singleStmt | PARAM_multipleStmt;
+
+PARAM_singleStmt: PARAM IDENTIFIER paramSingleInit
+       {
+          struct asm_symbol *const s =
+             declare_variable(state, $2, at_param, & @2);
+
+          if (s == NULL) {
+             free($2);
+             YYERROR;
+          } else {
+             s->param_binding_type = $3.param_binding_type;
+             s->param_binding_begin = $3.param_binding_begin;
+             s->param_binding_length = $3.param_binding_length;
+              s->param_binding_swizzle = $3.param_binding_swizzle;
+             s->param_is_array = 0;
+          }
+       }
+       ;
+
+PARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit
+       {
+          if (($4 != 0) && ((unsigned) $4 != $6.param_binding_length)) {
+             free($2);
+             yyerror(& @4, state, 
+                     "parameter array size and number of bindings must match");
+             YYERROR;
+          } else {
+             struct asm_symbol *const s =
+                declare_variable(state, $2, $6.type, & @2);
+
+             if (s == NULL) {
+                free($2);
+                YYERROR;
+             } else {
+                s->param_binding_type = $6.param_binding_type;
+                s->param_binding_begin = $6.param_binding_begin;
+                s->param_binding_length = $6.param_binding_length;
+                 s->param_binding_swizzle = SWIZZLE_XYZW;
+                s->param_is_array = 1;
+             }
+          }
+       }
+       ;
+
+optArraySize:
+       {
+          $$ = 0;
+       }
+       | INTEGER
+        {
+          if (($1 < 1) || ((unsigned) $1 > state->limits->MaxParameters)) {
+             yyerror(& @1, state, "invalid parameter array size");
+             YYERROR;
+          } else {
+             $$ = $1;
+          }
+       }
+       ;
+
+paramSingleInit: '=' paramSingleItemDecl
+       {
+          $$ = $2;
+       }
+       ;
+
+paramMultipleInit: '=' '{' paramMultInitList '}'
+       {
+          $$ = $3;
+       }
+       ;
+
+paramMultInitList: paramMultipleItem
+       | paramMultInitList ',' paramMultipleItem
+       {
+          $1.param_binding_length += $3.param_binding_length;
+          $$ = $1;
+       }
+       ;
+
+paramSingleItemDecl: stateSingleItem
+       {
+          memset(& $$, 0, sizeof($$));
+          $$.param_binding_begin = ~0;
+          initialize_symbol_from_state(state->prog, & $$, $1);
+       }
+       | programSingleItem
+       {
+          memset(& $$, 0, sizeof($$));
+          $$.param_binding_begin = ~0;
+          initialize_symbol_from_param(state->prog, & $$, $1);
+       }
+       | paramConstDecl
+       {
+          memset(& $$, 0, sizeof($$));
+          $$.param_binding_begin = ~0;
+          initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE);
+       }
+       ;
+
+paramSingleItemUse: stateSingleItem
+       {
+          memset(& $$, 0, sizeof($$));
+          $$.param_binding_begin = ~0;
+          initialize_symbol_from_state(state->prog, & $$, $1);
+       }
+       | programSingleItem
+       {
+          memset(& $$, 0, sizeof($$));
+          $$.param_binding_begin = ~0;
+          initialize_symbol_from_param(state->prog, & $$, $1);
+       }
+       | paramConstUse
+       {
+          memset(& $$, 0, sizeof($$));
+          $$.param_binding_begin = ~0;
+          initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE);
+       }
+       ;
+
+paramMultipleItem: stateMultipleItem
+       {
+          memset(& $$, 0, sizeof($$));
+          $$.param_binding_begin = ~0;
+          initialize_symbol_from_state(state->prog, & $$, $1);
+       }
+       | programMultipleItem
+       {
+          memset(& $$, 0, sizeof($$));
+          $$.param_binding_begin = ~0;
+          initialize_symbol_from_param(state->prog, & $$, $1);
+       }
+       | paramConstDecl
+       {
+          memset(& $$, 0, sizeof($$));
+          $$.param_binding_begin = ~0;
+          initialize_symbol_from_const(state->prog, & $$, & $1, GL_FALSE);
+       }
+       ;
+
+stateMultipleItem: stateSingleItem        { memcpy($$, $1, sizeof($$)); }
+       | STATE stateMatrixRows           { memcpy($$, $2, sizeof($$)); }
+       ;
+
+stateSingleItem: STATE stateMaterialItem  { memcpy($$, $2, sizeof($$)); }
+       | STATE stateLightItem            { memcpy($$, $2, sizeof($$)); }
+       | STATE stateLightModelItem       { memcpy($$, $2, sizeof($$)); }
+       | STATE stateLightProdItem        { memcpy($$, $2, sizeof($$)); }
+       | STATE stateTexGenItem           { memcpy($$, $2, sizeof($$)); }
+       | STATE stateTexEnvItem           { memcpy($$, $2, sizeof($$)); }
+       | STATE stateFogItem              { memcpy($$, $2, sizeof($$)); }
+       | STATE stateClipPlaneItem        { memcpy($$, $2, sizeof($$)); }
+       | STATE statePointItem            { memcpy($$, $2, sizeof($$)); }
+       | STATE stateMatrixRow            { memcpy($$, $2, sizeof($$)); }
+       | STATE stateDepthItem            { memcpy($$, $2, sizeof($$)); }
+       ;
+
+stateMaterialItem: MATERIAL optFaceType stateMatProperty
+       {
+          memset($$, 0, sizeof($$));
+          $$[0] = STATE_MATERIAL;
+          $$[1] = $2;
+          $$[2] = $3;
+       }
+       ;
+
+stateMatProperty: ambDiffSpecProperty
+       {
+          $$ = $1;
+       }
+       | EMISSION
+       {
+          $$ = STATE_EMISSION;
+       }
+       | SHININESS
+       {
+          $$ = STATE_SHININESS;
+       }
+       ;
+
+stateLightItem: LIGHT '[' stateLightNumber ']' stateLightProperty
+       {
+          memset($$, 0, sizeof($$));
+          $$[0] = STATE_LIGHT;
+          $$[1] = $3;
+          $$[2] = $5;
+       }
+       ;
+
+stateLightProperty: ambDiffSpecProperty
+       {
+          $$ = $1;
+       }
+       | POSITION
+       {
+          $$ = STATE_POSITION;
+       }
+       | ATTENUATION
+       {
+          if (!state->ctx->Extensions.EXT_point_parameters) {
+             yyerror(& @1, state, "GL_ARB_point_parameters not supported");
+             YYERROR;
+          }
+
+          $$ = STATE_ATTENUATION;
+       }
+       | SPOT stateSpotProperty
+       {
+          $$ = $2;
+       }
+       | HALF
+       {
+          $$ = STATE_HALF_VECTOR;
+       }
+       ;
+
+stateSpotProperty: DIRECTION
+       {
+          $$ = STATE_SPOT_DIRECTION;
+       }
+       ;
+
+stateLightModelItem: LIGHTMODEL stateLModProperty
+       {
+          $$[0] = $2[0];
+          $$[1] = $2[1];
+       }
+       ;
+
+stateLModProperty: AMBIENT
+       {
+          memset($$, 0, sizeof($$));
+          $$[0] = STATE_LIGHTMODEL_AMBIENT;
+       }
+       | optFaceType SCENECOLOR
+       {
+          memset($$, 0, sizeof($$));
+          $$[0] = STATE_LIGHTMODEL_SCENECOLOR;
+          $$[1] = $1;
+       }
+       ;
+
+stateLightProdItem: LIGHTPROD '[' stateLightNumber ']' optFaceType stateLProdProperty
+       {
+          memset($$, 0, sizeof($$));
+          $$[0] = STATE_LIGHTPROD;
+          $$[1] = $3;
+          $$[2] = $5;
+          $$[3] = $6;
+       }
+       ;
+
+stateLProdProperty: ambDiffSpecProperty;
+
+stateTexEnvItem: TEXENV optLegacyTexUnitNum stateTexEnvProperty
+       {
+          memset($$, 0, sizeof($$));
+          $$[0] = $3;
+          $$[1] = $2;
+       }
+       ;
+
+stateTexEnvProperty: COLOR
+       {
+          $$ = STATE_TEXENV_COLOR;
+       }
+       ;
+
+ambDiffSpecProperty: AMBIENT
+       {
+          $$ = STATE_AMBIENT;
+       }
+       | DIFFUSE
+       {
+          $$ = STATE_DIFFUSE;
+       }
+       | SPECULAR
+       {
+          $$ = STATE_SPECULAR;
+       }
+       ;
+
+stateLightNumber: INTEGER
+       {
+          if ((unsigned) $1 >= state->MaxLights) {
+             yyerror(& @1, state, "invalid light selector");
+             YYERROR;
+          }
+
+          $$ = $1;
+       }
+       ;
+
+stateTexGenItem: TEXGEN optTexCoordUnitNum stateTexGenType stateTexGenCoord
+       {
+          memset($$, 0, sizeof($$));
+          $$[0] = STATE_TEXGEN;
+          $$[1] = $2;
+          $$[2] = $3 + $4;
+       }
+       ;
+
+stateTexGenType: EYE
+       {
+          $$ = STATE_TEXGEN_EYE_S;
+       }
+       | OBJECT
+       {
+          $$ = STATE_TEXGEN_OBJECT_S;
+       }
+       ;
+stateTexGenCoord: TEXGEN_S
+       {
+          $$ = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S;
+       }
+       | TEXGEN_T
+       {
+          $$ = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S;
+       }
+       | TEXGEN_R
+       {
+          $$ = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S;
+       }
+       | TEXGEN_Q
+       {
+          $$ = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S;
+       }
+       ;
+
+stateFogItem: FOG stateFogProperty
+       {
+          memset($$, 0, sizeof($$));
+          $$[0] = $2;
+       }
+       ;
+
+stateFogProperty: COLOR
+       {
+          $$ = STATE_FOG_COLOR;
+       }
+       | PARAMS
+       {
+          $$ = STATE_FOG_PARAMS;
+       }
+       ;
+
+stateClipPlaneItem: CLIP '[' stateClipPlaneNum ']' PLANE
+       {
+          memset($$, 0, sizeof($$));
+          $$[0] = STATE_CLIPPLANE;
+          $$[1] = $3;
+       }
+       ;
+
+stateClipPlaneNum: INTEGER
+       {
+          if ((unsigned) $1 >= state->MaxClipPlanes) {
+             yyerror(& @1, state, "invalid clip plane selector");
+             YYERROR;
+          }
+
+          $$ = $1;
+       }
+       ;
+
+statePointItem: POINT_TOK statePointProperty
+       {
+          memset($$, 0, sizeof($$));
+          $$[0] = $2;
+       }
+       ;
+
+statePointProperty: SIZE_TOK
+       {
+          $$ = STATE_POINT_SIZE;
+       }
+       | ATTENUATION
+       {
+          $$ = STATE_POINT_ATTENUATION;
+       }
+       ;
+
+stateMatrixRow: stateMatrixItem ROW '[' stateMatrixRowNum ']'
+       {
+          $$[0] = $1[0];
+          $$[1] = $1[1];
+          $$[2] = $4;
+          $$[3] = $4;
+          $$[4] = $1[2];
+       }
+       ;
+
+stateMatrixRows: stateMatrixItem optMatrixRows
+       {
+          $$[0] = $1[0];
+          $$[1] = $1[1];
+          $$[2] = $2[2];
+          $$[3] = $2[3];
+          $$[4] = $1[2];
+       }
+       ;
+
+optMatrixRows:
+       {
+          $$[2] = 0;
+          $$[3] = 3;
+       }
+       | ROW '[' stateMatrixRowNum DOT_DOT stateMatrixRowNum ']'
+       {
+          /* It seems logical that the matrix row range specifier would have
+           * to specify a range or more than one row (i.e., $5 > $3).
+           * However, the ARB_vertex_program spec says "a program will fail
+           * to load if <a> is greater than <b>."  This means that $3 == $5
+           * is valid.
+           */
+          if ($3 > $5) {
+             yyerror(& @3, state, "invalid matrix row range");
+             YYERROR;
+          }
+
+          $$[2] = $3;
+          $$[3] = $5;
+       }
+       ;
+
+stateMatrixItem: MATRIX stateMatrixName stateOptMatModifier
+       {
+          $$[0] = $2[0];
+          $$[1] = $2[1];
+          $$[2] = $3;
+       }
+       ;
+
+stateOptMatModifier: 
+       {
+          $$ = 0;
+       }
+       | stateMatModifier
+       {
+          $$ = $1;
+       }
+       ;
+
+stateMatModifier: INVERSE 
+       {
+          $$ = STATE_MATRIX_INVERSE;
+       }
+       | TRANSPOSE 
+       {
+          $$ = STATE_MATRIX_TRANSPOSE;
+       }
+       | INVTRANS
+       {
+          $$ = STATE_MATRIX_INVTRANS;
+       }
+       ;
+
+stateMatrixRowNum: INTEGER
+       {
+          if ($1 > 3) {
+             yyerror(& @1, state, "invalid matrix row reference");
+             YYERROR;
+          }
+
+          $$ = $1;
+       }
+       ;
+
+stateMatrixName: MODELVIEW stateOptModMatNum
+       {
+          $$[0] = STATE_MODELVIEW_MATRIX;
+          $$[1] = $2;
+       }
+       | PROJECTION
+       {
+          $$[0] = STATE_PROJECTION_MATRIX;
+          $$[1] = 0;
+       }
+       | MVP
+       {
+          $$[0] = STATE_MVP_MATRIX;
+          $$[1] = 0;
+       }
+       | TEXTURE optTexCoordUnitNum
+       {
+          $$[0] = STATE_TEXTURE_MATRIX;
+          $$[1] = $2;
+       }
+       | PALETTE '[' statePaletteMatNum ']'
+       {
+          yyerror(& @1, state, "GL_ARB_matrix_palette not supported");
+          YYERROR;
+       }
+       | MAT_PROGRAM '[' stateProgramMatNum ']'
+       {
+          $$[0] = STATE_PROGRAM_MATRIX;
+          $$[1] = $3;
+       }
+       ;
+
+stateOptModMatNum:
+       {
+          $$ = 0;
+       }
+       | '[' stateModMatNum ']'
+       {
+          $$ = $2;
+       }
+       ;
+stateModMatNum: INTEGER
+       {
+          /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix
+           * zero is valid.
+           */
+          if ($1 != 0) {
+             yyerror(& @1, state, "invalid modelview matrix index");
+             YYERROR;
+          }
+
+          $$ = $1;
+       }
+       ;
+statePaletteMatNum: INTEGER
+       {
+          /* Since GL_ARB_matrix_palette isn't supported, just let any value
+           * through here.  The error will be generated later.
+           */
+          $$ = $1;
+       }
+       ;
+stateProgramMatNum: INTEGER
+       {
+          if ((unsigned) $1 >= state->MaxProgramMatrices) {
+             yyerror(& @1, state, "invalid program matrix selector");
+             YYERROR;
+          }
+
+          $$ = $1;
+       }
+       ;
+
+stateDepthItem: DEPTH RANGE
+       {
+          memset($$, 0, sizeof($$));
+          $$[0] = STATE_DEPTH_RANGE;
+       }
+       ;
+
+
+programSingleItem: progEnvParam | progLocalParam;
+
+programMultipleItem: progEnvParams | progLocalParams;
+
+progEnvParams: PROGRAM ENV '[' progEnvParamNums ']'
+       {
+          memset($$, 0, sizeof($$));
+          $$[0] = state->state_param_enum;
+          $$[1] = STATE_ENV;
+          $$[2] = $4[0];
+          $$[3] = $4[1];
+       }
+       ;
+
+progEnvParamNums: progEnvParamNum
+       {
+          $$[0] = $1;
+          $$[1] = $1;
+       }
+       | progEnvParamNum DOT_DOT progEnvParamNum
+       {
+          $$[0] = $1;
+          $$[1] = $3;
+       }
+       ;
+
+progEnvParam: PROGRAM ENV '[' progEnvParamNum ']'
+       {
+          memset($$, 0, sizeof($$));
+          $$[0] = state->state_param_enum;
+          $$[1] = STATE_ENV;
+          $$[2] = $4;
+          $$[3] = $4;
+       }
+       ;
+
+progLocalParams: PROGRAM LOCAL '[' progLocalParamNums ']'
+       {
+          memset($$, 0, sizeof($$));
+          $$[0] = state->state_param_enum;
+          $$[1] = STATE_LOCAL;
+          $$[2] = $4[0];
+          $$[3] = $4[1];
+       }
+
+progLocalParamNums: progLocalParamNum
+       {
+          $$[0] = $1;
+          $$[1] = $1;
+       }
+       | progLocalParamNum DOT_DOT progLocalParamNum
+       {
+          $$[0] = $1;
+          $$[1] = $3;
+       }
+       ;
+
+progLocalParam: PROGRAM LOCAL '[' progLocalParamNum ']'
+       {
+          memset($$, 0, sizeof($$));
+          $$[0] = state->state_param_enum;
+          $$[1] = STATE_LOCAL;
+          $$[2] = $4;
+          $$[3] = $4;
+       }
+       ;
+
+progEnvParamNum: INTEGER
+       {
+          if ((unsigned) $1 >= state->limits->MaxEnvParams) {
+             yyerror(& @1, state, "invalid environment parameter reference");
+             YYERROR;
+          }
+          $$ = $1;
+       }
+       ;
+
+progLocalParamNum: INTEGER
+       {
+          if ((unsigned) $1 >= state->limits->MaxLocalParams) {
+             yyerror(& @1, state, "invalid local parameter reference");
+             YYERROR;
+          }
+          $$ = $1;
+       }
+       ;
+
+
+
+paramConstDecl: paramConstScalarDecl | paramConstVector;
+paramConstUse: paramConstScalarUse | paramConstVector;
+
+paramConstScalarDecl: signedFloatConstant
+       {
+          $$.count = 4;
+          $$.data[0] = $1;
+          $$.data[1] = $1;
+          $$.data[2] = $1;
+          $$.data[3] = $1;
+       }
+       ;
+
+paramConstScalarUse: REAL
+       {
+          $$.count = 1;
+          $$.data[0] = $1;
+          $$.data[1] = $1;
+          $$.data[2] = $1;
+          $$.data[3] = $1;
+       }
+       | INTEGER
+       {
+          $$.count = 1;
+          $$.data[0] = (float) $1;
+          $$.data[1] = (float) $1;
+          $$.data[2] = (float) $1;
+          $$.data[3] = (float) $1;
+       }
+       ;
+
+paramConstVector: '{' signedFloatConstant '}'
+       {
+          $$.count = 4;
+          $$.data[0] = $2;
+          $$.data[1] = 0.0f;
+          $$.data[2] = 0.0f;
+          $$.data[3] = 1.0f;
+       }
+       | '{' signedFloatConstant ',' signedFloatConstant '}'
+       {
+          $$.count = 4;
+          $$.data[0] = $2;
+          $$.data[1] = $4;
+          $$.data[2] = 0.0f;
+          $$.data[3] = 1.0f;
+       }
+       | '{' signedFloatConstant ',' signedFloatConstant ','
+              signedFloatConstant '}'
+       {
+          $$.count = 4;
+          $$.data[0] = $2;
+          $$.data[1] = $4;
+          $$.data[2] = $6;
+          $$.data[3] = 1.0f;
+       }
+       | '{' signedFloatConstant ',' signedFloatConstant ','
+              signedFloatConstant ',' signedFloatConstant '}'
+       {
+          $$.count = 4;
+          $$.data[0] = $2;
+          $$.data[1] = $4;
+          $$.data[2] = $6;
+          $$.data[3] = $8;
+       }
+       ;
+
+signedFloatConstant: optionalSign REAL
+       {
+          $$ = ($1) ? -$2 : $2;
+       }
+       | optionalSign INTEGER
+       {
+          $$ = (float)(($1) ? -$2 : $2);
+       }
+       ;
+
+optionalSign: '+'        { $$ = FALSE; }
+       | '-'            { $$ = TRUE;  }
+       |                { $$ = FALSE; }
+       ;
+
+TEMP_statement: optVarSize TEMP { $<integer>$ = $2; } varNameList
+       ;
+
+optVarSize: string
+       {
+          /* NV_fragment_program_option defines the size qualifiers in a
+           * fairly broken way.  "SHORT" or "LONG" can optionally be used
+           * before TEMP or OUTPUT.  However, neither is a reserved word!
+           * This means that we have to parse it as an identifier, then check
+           * to make sure it's one of the valid values.  *sigh*
+           *
+           * In addition, the grammar in the extension spec does *not* allow
+           * the size specifier to be optional, but all known implementations
+           * do.
+           */
+          if (!state->option.NV_fragment) {
+             yyerror(& @1, state, "unexpected IDENTIFIER");
+             YYERROR;
+          }
+
+          if (strcmp("SHORT", $1) == 0) {
+          } else if (strcmp("LONG", $1) == 0) {
+          } else {
+             char *const err_str =
+                make_error_string("invalid storage size specifier \"%s\"",
+                                  $1);
+
+             yyerror(& @1, state, (err_str != NULL)
+                     ? err_str : "invalid storage size specifier");
+
+             if (err_str != NULL) {
+                free(err_str);
+             }
+
+             YYERROR;
+          }
+       }
+       |
+       {
+       }
+       ;
+
+ADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList
+       ;
+
+varNameList: varNameList ',' IDENTIFIER
+       {
+          if (!declare_variable(state, $3, $<integer>0, & @3)) {
+             free($3);
+             YYERROR;
+          }
+       }
+       | IDENTIFIER
+       {
+          if (!declare_variable(state, $1, $<integer>0, & @1)) {
+             free($1);
+             YYERROR;
+          }
+       }
+       ;
+
+OUTPUT_statement: optVarSize OUTPUT IDENTIFIER '=' resultBinding
+       {
+          struct asm_symbol *const s =
+             declare_variable(state, $3, at_output, & @3);
+
+          if (s == NULL) {
+             free($3);
+             YYERROR;
+          } else {
+             s->output_binding = $5;
+          }
+       }
+       ;
+
+resultBinding: RESULT POSITION
+       {
+          if (state->mode == ARB_vertex) {
+             $$ = VERT_RESULT_HPOS;
+          } else {
+             yyerror(& @2, state, "invalid program result name");
+             YYERROR;
+          }
+       }
+       | RESULT FOGCOORD
+       {
+          if (state->mode == ARB_vertex) {
+             $$ = VERT_RESULT_FOGC;
+          } else {
+             yyerror(& @2, state, "invalid program result name");
+             YYERROR;
+          }
+       }
+       | RESULT resultColBinding
+       {
+          $$ = $2;
+       }
+       | RESULT POINTSIZE
+       {
+          if (state->mode == ARB_vertex) {
+             $$ = VERT_RESULT_PSIZ;
+          } else {
+             yyerror(& @2, state, "invalid program result name");
+             YYERROR;
+          }
+       }
+       | RESULT TEXCOORD optTexCoordUnitNum
+       {
+          if (state->mode == ARB_vertex) {
+             $$ = VERT_RESULT_TEX0 + $3;
+          } else {
+             yyerror(& @2, state, "invalid program result name");
+             YYERROR;
+          }
+       }
+       | RESULT DEPTH
+       {
+          if (state->mode == ARB_fragment) {
+             $$ = FRAG_RESULT_DEPTH;
+          } else {
+             yyerror(& @2, state, "invalid program result name");
+             YYERROR;
+          }
+       }
+       ;
+
+resultColBinding: COLOR optResultFaceType optResultColorType
+       {
+          $$ = $2 + $3;
+       }
+       ;
+
+optResultFaceType:
+       {
+          $$ = (state->mode == ARB_vertex)
+             ? VERT_RESULT_COL0
+             : FRAG_RESULT_COLOR;
+       }
+       | FRONT
+       {
+          if (state->mode == ARB_vertex) {
+             $$ = VERT_RESULT_COL0;
+          } else {
+             yyerror(& @1, state, "invalid program result name");
+             YYERROR;
+          }
+       }
+       | BACK
+       {
+          if (state->mode == ARB_vertex) {
+             $$ = VERT_RESULT_BFC0;
+          } else {
+             yyerror(& @1, state, "invalid program result name");
+             YYERROR;
+          }
+       }
+       ;
+
+optResultColorType:
+       {
+          $$ = 0; 
+       }
+       | PRIMARY
+       {
+          if (state->mode == ARB_vertex) {
+             $$ = 0;
+          } else {
+             yyerror(& @1, state, "invalid program result name");
+             YYERROR;
+          }
+       }
+       | SECONDARY
+       {
+          if (state->mode == ARB_vertex) {
+             $$ = 1;
+          } else {
+             yyerror(& @1, state, "invalid program result name");
+             YYERROR;
+          }
+       }
+       ;
+
+optFaceType:    { $$ = 0; }
+       | FRONT { $$ = 0; }
+       | BACK  { $$ = 1; }
+       ;
+
+optColorType:       { $$ = 0; }
+       | PRIMARY   { $$ = 0; }
+       | SECONDARY { $$ = 1; }
+       ;
+
+optTexCoordUnitNum:                { $$ = 0; }
+       | '[' texCoordUnitNum ']'  { $$ = $2; }
+       ;
+
+optTexImageUnitNum:                { $$ = 0; }
+       | '[' texImageUnitNum ']'  { $$ = $2; }
+       ;
+
+optLegacyTexUnitNum:               { $$ = 0; }
+       | '[' legacyTexUnitNum ']' { $$ = $2; }
+       ;
+
+texCoordUnitNum: INTEGER
+       {
+          if ((unsigned) $1 >= state->MaxTextureCoordUnits) {
+             yyerror(& @1, state, "invalid texture coordinate unit selector");
+             YYERROR;
+          }
+
+          $$ = $1;
+       }
+       ;
+
+texImageUnitNum: INTEGER
+       {
+          if ((unsigned) $1 >= state->MaxTextureImageUnits) {
+             yyerror(& @1, state, "invalid texture image unit selector");
+             YYERROR;
+          }
+
+          $$ = $1;
+       }
+       ;
+
+legacyTexUnitNum: INTEGER
+       {
+          if ((unsigned) $1 >= state->MaxTextureUnits) {
+             yyerror(& @1, state, "invalid texture unit selector");
+             YYERROR;
+          }
+
+          $$ = $1;
+       }
+       ;
+
+ALIAS_statement: ALIAS IDENTIFIER '=' USED_IDENTIFIER
+       {
+          struct asm_symbol *exist = (struct asm_symbol *)
+             _mesa_symbol_table_find_symbol(state->st, 0, $2);
+          struct asm_symbol *target = (struct asm_symbol *)
+             _mesa_symbol_table_find_symbol(state->st, 0, $4);
+
+          free($4);
+
+          if (exist != NULL) {
+             char m[1000];
+             _mesa_snprintf(m, sizeof(m), "redeclared identifier: %s", $2);
+             free($2);
+             yyerror(& @2, state, m);
+             YYERROR;
+          } else if (target == NULL) {
+             free($2);
+             yyerror(& @4, state,
+                     "undefined variable binding in ALIAS statement");
+             YYERROR;
+          } else {
+             _mesa_symbol_table_add_symbol(state->st, 0, $2, target);
+          }
+       }
+       ;
+
+string: IDENTIFIER
+       | USED_IDENTIFIER
+       ;
+
+%%
+
+void
+asm_instruction_set_operands(struct asm_instruction *inst,
+                            const struct prog_dst_register *dst,
+                            const struct asm_src_register *src0,
+                            const struct asm_src_register *src1,
+                            const struct asm_src_register *src2)
+{
+   /* In the core ARB extensions only the KIL instruction doesn't have a
+    * destination register.
+    */
+   if (dst == NULL) {
+      init_dst_reg(& inst->Base.DstReg);
+   } else {
+      inst->Base.DstReg = *dst;
+   }
+
+   /* The only instruction that doesn't have any source registers is the
+    * condition-code based KIL instruction added by NV_fragment_program_option.
+    */
+   if (src0 != NULL) {
+      inst->Base.SrcReg[0] = src0->Base;
+      inst->SrcReg[0] = *src0;
+   } else {
+      init_src_reg(& inst->SrcReg[0]);
+   }
+
+   if (src1 != NULL) {
+      inst->Base.SrcReg[1] = src1->Base;
+      inst->SrcReg[1] = *src1;
+   } else {
+      init_src_reg(& inst->SrcReg[1]);
+   }
+
+   if (src2 != NULL) {
+      inst->Base.SrcReg[2] = src2->Base;
+      inst->SrcReg[2] = *src2;
+   } else {
+      init_src_reg(& inst->SrcReg[2]);
+   }
+}
+
+
+struct asm_instruction *
+asm_instruction_ctor(gl_inst_opcode op,
+                    const struct prog_dst_register *dst,
+                    const struct asm_src_register *src0,
+                    const struct asm_src_register *src1,
+                    const struct asm_src_register *src2)
+{
+   struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
+
+   if (inst) {
+      _mesa_init_instructions(& inst->Base, 1);
+      inst->Base.Opcode = op;
+
+      asm_instruction_set_operands(inst, dst, src0, src1, src2);
+   }
+
+   return inst;
+}
+
+
+struct asm_instruction *
+asm_instruction_copy_ctor(const struct prog_instruction *base,
+                         const struct prog_dst_register *dst,
+                         const struct asm_src_register *src0,
+                         const struct asm_src_register *src1,
+                         const struct asm_src_register *src2)
+{
+   struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
+
+   if (inst) {
+      _mesa_init_instructions(& inst->Base, 1);
+      inst->Base.Opcode = base->Opcode;
+      inst->Base.CondUpdate = base->CondUpdate;
+      inst->Base.CondDst = base->CondDst;
+      inst->Base.SaturateMode = base->SaturateMode;
+      inst->Base.Precision = base->Precision;
+
+      asm_instruction_set_operands(inst, dst, src0, src1, src2);
+   }
+
+   return inst;
+}
+
+
+void
+init_dst_reg(struct prog_dst_register *r)
+{
+   memset(r, 0, sizeof(*r));
+   r->File = PROGRAM_UNDEFINED;
+   r->WriteMask = WRITEMASK_XYZW;
+   r->CondMask = COND_TR;
+   r->CondSwizzle = SWIZZLE_NOOP;
+}
+
+
+/** Like init_dst_reg() but set the File and Index fields. */
+void
+set_dst_reg(struct prog_dst_register *r, gl_register_file file, GLint index)
+{
+   const GLint maxIndex = 1 << INST_INDEX_BITS;
+   const GLint minIndex = 0;
+   ASSERT(index >= minIndex);
+   (void) minIndex;
+   ASSERT(index <= maxIndex);
+   (void) maxIndex;
+   ASSERT(file == PROGRAM_TEMPORARY ||
+         file == PROGRAM_ADDRESS ||
+         file == PROGRAM_OUTPUT);
+   memset(r, 0, sizeof(*r));
+   r->File = file;
+   r->Index = index;
+   r->WriteMask = WRITEMASK_XYZW;
+   r->CondMask = COND_TR;
+   r->CondSwizzle = SWIZZLE_NOOP;
+}
+
+
+void
+init_src_reg(struct asm_src_register *r)
+{
+   memset(r, 0, sizeof(*r));
+   r->Base.File = PROGRAM_UNDEFINED;
+   r->Base.Swizzle = SWIZZLE_NOOP;
+   r->Symbol = NULL;
+}
+
+
+/** Like init_src_reg() but set the File and Index fields.
+ * \return GL_TRUE if a valid src register, GL_FALSE otherwise
+ */
+void
+set_src_reg(struct asm_src_register *r, gl_register_file file, GLint index)
+{
+   set_src_reg_swz(r, file, index, SWIZZLE_XYZW);
+}
+
+
+void
+set_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index,
+                GLuint swizzle)
+{
+   const GLint maxIndex = (1 << INST_INDEX_BITS) - 1;
+   const GLint minIndex = -(1 << INST_INDEX_BITS);
+   ASSERT(file < PROGRAM_FILE_MAX);
+   ASSERT(index >= minIndex);
+   (void) minIndex;
+   ASSERT(index <= maxIndex);
+   (void) maxIndex;
+   memset(r, 0, sizeof(*r));
+   r->Base.File = file;
+   r->Base.Index = index;
+   r->Base.Swizzle = swizzle;
+   r->Symbol = NULL;
+}
+
+
+/**
+ * Validate the set of inputs used by a program
+ *
+ * Validates that legal sets of inputs are used by the program.  In this case
+ * "used" included both reading the input or binding the input to a name using
+ * the \c ATTRIB command.
+ *
+ * \return
+ * \c TRUE if the combination of inputs used is valid, \c FALSE otherwise.
+ */
+int
+validate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state)
+{
+   const int inputs = state->prog->InputsRead | state->InputsBound;
+
+   if (((inputs & 0x0ffff) & (inputs >> 16)) != 0) {
+      yyerror(locp, state, "illegal use of generic attribute and name attribute");
+      return 0;
+   }
+
+   return 1;
+}
+
+
+struct asm_symbol *
+declare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
+                struct YYLTYPE *locp)
+{
+   struct asm_symbol *s = NULL;
+   struct asm_symbol *exist = (struct asm_symbol *)
+      _mesa_symbol_table_find_symbol(state->st, 0, name);
+
+
+   if (exist != NULL) {
+      yyerror(locp, state, "redeclared identifier");
+   } else {
+      s = calloc(1, sizeof(struct asm_symbol));
+      s->name = name;
+      s->type = t;
+
+      switch (t) {
+      case at_temp:
+        if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
+           yyerror(locp, state, "too many temporaries declared");
+           free(s);
+           return NULL;
+        }
+
+        s->temp_binding = state->prog->NumTemporaries;
+        state->prog->NumTemporaries++;
+        break;
+
+      case at_address:
+        if (state->prog->NumAddressRegs >= state->limits->MaxAddressRegs) {
+           yyerror(locp, state, "too many address registers declared");
+           free(s);
+           return NULL;
+        }
+
+        /* FINISHME: Add support for multiple address registers.
+         */
+        state->prog->NumAddressRegs++;
+        break;
+
+      default:
+        break;
+      }
+
+      _mesa_symbol_table_add_symbol(state->st, 0, s->name, s);
+      s->next = state->sym;
+      state->sym = s;
+   }
+
+   return s;
+}
+
+
+int add_state_reference(struct gl_program_parameter_list *param_list,
+                       const gl_state_index tokens[STATE_LENGTH])
+{
+   const GLuint size = 4; /* XXX fix */
+   char *name;
+   GLint index;
+
+   name = _mesa_program_state_string(tokens);
+   index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name,
+                               size, GL_NONE, NULL, tokens, 0x0);
+   param_list->StateFlags |= _mesa_program_state_flags(tokens);
+
+   /* free name string here since we duplicated it in add_parameter() */
+   free(name);
+
+   return index;
+}
+
+
+int
+initialize_symbol_from_state(struct gl_program *prog,
+                            struct asm_symbol *param_var, 
+                            const gl_state_index tokens[STATE_LENGTH])
+{
+   int idx = -1;
+   gl_state_index state_tokens[STATE_LENGTH];
+
+
+   memcpy(state_tokens, tokens, sizeof(state_tokens));
+
+   param_var->type = at_param;
+   param_var->param_binding_type = PROGRAM_STATE_VAR;
+
+   /* If we are adding a STATE_MATRIX that has multiple rows, we need to
+    * unroll it and call add_state_reference() for each row
+    */
+   if ((state_tokens[0] == STATE_MODELVIEW_MATRIX ||
+       state_tokens[0] == STATE_PROJECTION_MATRIX ||
+       state_tokens[0] == STATE_MVP_MATRIX ||
+       state_tokens[0] == STATE_TEXTURE_MATRIX ||
+       state_tokens[0] == STATE_PROGRAM_MATRIX)
+       && (state_tokens[2] != state_tokens[3])) {
+      int row;
+      const int first_row = state_tokens[2];
+      const int last_row = state_tokens[3];
+
+      for (row = first_row; row <= last_row; row++) {
+        state_tokens[2] = state_tokens[3] = row;
+
+        idx = add_state_reference(prog->Parameters, state_tokens);
+        if (param_var->param_binding_begin == ~0U) {
+           param_var->param_binding_begin = idx;
+            param_var->param_binding_swizzle = SWIZZLE_XYZW;
+         }
+
+        param_var->param_binding_length++;
+      }
+   }
+   else {
+      idx = add_state_reference(prog->Parameters, state_tokens);
+      if (param_var->param_binding_begin == ~0U) {
+        param_var->param_binding_begin = idx;
+         param_var->param_binding_swizzle = SWIZZLE_XYZW;
+      }
+      param_var->param_binding_length++;
+   }
+
+   return idx;
+}
+
+
+int
+initialize_symbol_from_param(struct gl_program *prog,
+                            struct asm_symbol *param_var, 
+                            const gl_state_index tokens[STATE_LENGTH])
+{
+   int idx = -1;
+   gl_state_index state_tokens[STATE_LENGTH];
+
+
+   memcpy(state_tokens, tokens, sizeof(state_tokens));
+
+   assert((state_tokens[0] == STATE_VERTEX_PROGRAM)
+         || (state_tokens[0] == STATE_FRAGMENT_PROGRAM));
+   assert((state_tokens[1] == STATE_ENV)
+         || (state_tokens[1] == STATE_LOCAL));
+
+   /*
+    * The param type is STATE_VAR.  The program parameter entry will
+    * effectively be a pointer into the LOCAL or ENV parameter array.
+    */
+   param_var->type = at_param;
+   param_var->param_binding_type = PROGRAM_STATE_VAR;
+
+   /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements,
+    * we need to unroll it and call add_state_reference() for each row
+    */
+   if (state_tokens[2] != state_tokens[3]) {
+      int row;
+      const int first_row = state_tokens[2];
+      const int last_row = state_tokens[3];
+
+      for (row = first_row; row <= last_row; row++) {
+        state_tokens[2] = state_tokens[3] = row;
+
+        idx = add_state_reference(prog->Parameters, state_tokens);
+        if (param_var->param_binding_begin == ~0U) {
+           param_var->param_binding_begin = idx;
+            param_var->param_binding_swizzle = SWIZZLE_XYZW;
+         }
+        param_var->param_binding_length++;
+      }
+   }
+   else {
+      idx = add_state_reference(prog->Parameters, state_tokens);
+      if (param_var->param_binding_begin == ~0U) {
+        param_var->param_binding_begin = idx;
+         param_var->param_binding_swizzle = SWIZZLE_XYZW;
+      }
+      param_var->param_binding_length++;
+   }
+
+   return idx;
+}
+
+
+/**
+ * Put a float/vector constant/literal into the parameter list.
+ * \param param_var  returns info about the parameter/constant's location,
+ *                   binding, type, etc.
+ * \param vec  the vector/constant to add
+ * \param allowSwizzle  if true, try to consolidate constants which only differ
+ *                      by a swizzle.  We don't want to do this when building
+ *                      arrays of constants that may be indexed indirectly.
+ * \return index of the constant in the parameter list.
+ */
+int
+initialize_symbol_from_const(struct gl_program *prog,
+                            struct asm_symbol *param_var, 
+                            const struct asm_vector *vec,
+                             GLboolean allowSwizzle)
+{
+   unsigned swizzle;
+   const int idx = _mesa_add_unnamed_constant(prog->Parameters,
+                                              vec->data, vec->count,
+                                              allowSwizzle ? &swizzle : NULL);
+
+   param_var->type = at_param;
+   param_var->param_binding_type = PROGRAM_CONSTANT;
+
+   if (param_var->param_binding_begin == ~0U) {
+      param_var->param_binding_begin = idx;
+      param_var->param_binding_swizzle = allowSwizzle ? swizzle : SWIZZLE_XYZW;
+   }
+   param_var->param_binding_length++;
+
+   return idx;
+}
+
+
+char *
+make_error_string(const char *fmt, ...)
+{
+   int length;
+   char *str;
+   va_list args;
+
+
+   /* Call vsnprintf once to determine how large the final string is.  Call it
+    * again to do the actual formatting.  from the vsnprintf manual page:
+    *
+    *    Upon successful return, these functions return the number of
+    *    characters printed  (not including the trailing '\0' used to end
+    *    output to strings).
+    */
+   va_start(args, fmt);
+   length = 1 + vsnprintf(NULL, 0, fmt, args);
+   va_end(args);
+
+   str = malloc(length);
+   if (str) {
+      va_start(args, fmt);
+      vsnprintf(str, length, fmt, args);
+      va_end(args);
+   }
+
+   return str;
+}
+
+
+void
+yyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s)
+{
+   char *err_str;
+
+
+   err_str = make_error_string("glProgramStringARB(%s)\n", s);
+   if (err_str) {
+      _mesa_error(state->ctx, GL_INVALID_OPERATION, err_str);
+      free(err_str);
+   }
+
+   err_str = make_error_string("line %u, char %u: error: %s\n",
+                              locp->first_line, locp->first_column, s);
+   _mesa_set_program_error(state->ctx, locp->position, err_str);
+
+   if (err_str) {
+      free(err_str);
+   }
+}
+
+
+GLboolean
+_mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str,
+                       GLsizei len, struct asm_parser_state *state)
+{
+   struct asm_instruction *inst;
+   unsigned i;
+   GLubyte *strz;
+   GLboolean result = GL_FALSE;
+   void *temp;
+   struct asm_symbol *sym;
+
+   state->ctx = ctx;
+   state->prog->Target = target;
+   state->prog->Parameters = _mesa_new_parameter_list();
+
+   /* Make a copy of the program string and force it to be NUL-terminated.
+    */
+   strz = (GLubyte *) malloc(len + 1);
+   if (strz == NULL) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
+      return GL_FALSE;
+   }
+   memcpy (strz, str, len);
+   strz[len] = '\0';
+
+   state->prog->String = strz;
+
+   state->st = _mesa_symbol_table_ctor();
+
+   state->limits = (target == GL_VERTEX_PROGRAM_ARB)
+      ? & ctx->Const.VertexProgram
+      : & ctx->Const.FragmentProgram;
+
+   state->MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits;
+   state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits;
+   state->MaxTextureUnits = ctx->Const.MaxTextureUnits;
+   state->MaxClipPlanes = ctx->Const.MaxClipPlanes;
+   state->MaxLights = ctx->Const.MaxLights;
+   state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices;
+
+   state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB)
+      ? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM;
+
+   _mesa_set_program_error(ctx, -1, NULL);
+
+   _mesa_program_lexer_ctor(& state->scanner, state, (const char *) str, len);
+   yyparse(state);
+   _mesa_program_lexer_dtor(state->scanner);
+
+
+   if (ctx->Program.ErrorPos != -1) {
+      goto error;
+   }
+
+   if (! _mesa_layout_parameters(state)) {
+      struct YYLTYPE loc;
+
+      loc.first_line = 0;
+      loc.first_column = 0;
+      loc.position = len;
+
+      yyerror(& loc, state, "invalid PARAM usage");
+      goto error;
+   }
+
+
+   
+   /* Add one instruction to store the "END" instruction.
+    */
+   state->prog->Instructions =
+      _mesa_alloc_instructions(state->prog->NumInstructions + 1);
+   inst = state->inst_head;
+   for (i = 0; i < state->prog->NumInstructions; i++) {
+      struct asm_instruction *const temp = inst->next;
+
+      state->prog->Instructions[i] = inst->Base;
+      inst = temp;
+   }
+
+   /* Finally, tag on an OPCODE_END instruction */
+   {
+      const GLuint numInst = state->prog->NumInstructions;
+      _mesa_init_instructions(state->prog->Instructions + numInst, 1);
+      state->prog->Instructions[numInst].Opcode = OPCODE_END;
+   }
+   state->prog->NumInstructions++;
+
+   state->prog->NumParameters = state->prog->Parameters->NumParameters;
+   state->prog->NumAttributes = _mesa_bitcount(state->prog->InputsRead);
+
+   /*
+    * Initialize native counts to logical counts.  The device driver may
+    * change them if program is translated into a hardware program.
+    */
+   state->prog->NumNativeInstructions = state->prog->NumInstructions;
+   state->prog->NumNativeTemporaries = state->prog->NumTemporaries;
+   state->prog->NumNativeParameters = state->prog->NumParameters;
+   state->prog->NumNativeAttributes = state->prog->NumAttributes;
+   state->prog->NumNativeAddressRegs = state->prog->NumAddressRegs;
+
+   result = GL_TRUE;
+
+error:
+   for (inst = state->inst_head; inst != NULL; inst = temp) {
+      temp = inst->next;
+      free(inst);
+   }
+
+   state->inst_head = NULL;
+   state->inst_tail = NULL;
+
+   for (sym = state->sym; sym != NULL; sym = temp) {
+      temp = sym->next;
+
+      free((void *) sym->name);
+      free(sym);
+   }
+   state->sym = NULL;
+
+   _mesa_symbol_table_dtor(state->st);
+   state->st = NULL;
+
+   return result;
+}
diff --git a/src/mesa/program/program_parse_extra.c b/src/mesa/program/program_parse_extra.c
new file mode 100644 (file)
index 0000000..ae98b78
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * Copyright Â© 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION 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 <string.h>
+#include "main/mtypes.h"
+#include "prog_instruction.h"
+#include "program_parser.h"
+
+
+/**
+ * Extra assembly-level parser routines
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+int
+_mesa_parse_instruction_suffix(const struct asm_parser_state *state,
+                              const char *suffix,
+                              struct prog_instruction *inst)
+{
+   inst->CondUpdate = 0;
+   inst->CondDst = 0;
+   inst->SaturateMode = SATURATE_OFF;
+   inst->Precision = FLOAT32;
+
+
+   /* The first possible suffix element is the precision specifier from
+    * NV_fragment_program_option.
+    */
+   if (state->option.NV_fragment) {
+      switch (suffix[0]) {
+      case 'H':
+        inst->Precision = FLOAT16;
+        suffix++;
+        break;
+      case 'R':
+        inst->Precision = FLOAT32;
+        suffix++;
+        break;
+      case 'X':
+        inst->Precision = FIXED12;
+        suffix++;
+        break;
+      default:
+        break;
+      }
+   }
+
+   /* The next possible suffix element is the condition code modifier selection
+    * from NV_fragment_program_option.
+    */
+   if (state->option.NV_fragment) {
+      if (suffix[0] == 'C') {
+        inst->CondUpdate = 1;
+        suffix++;
+      }
+   }
+
+
+   /* The final possible suffix element is the saturation selector from
+    * ARB_fragment_program.
+    */
+   if (state->mode == ARB_fragment) {
+      if (strcmp(suffix, "_SAT") == 0) {
+        inst->SaturateMode = SATURATE_ZERO_ONE;
+        suffix += 4;
+      }
+   }
+
+
+   /* It is an error for all of the suffix string not to be consumed.
+    */
+   return suffix[0] == '\0';
+}
+
+
+int
+_mesa_parse_cc(const char *s)
+{
+   int cond = 0;
+
+   switch (s[0]) {
+   case 'E':
+      if (s[1] == 'Q') {
+        cond = COND_EQ;
+      }
+      break;
+
+   case 'F':
+      if (s[1] == 'L') {
+        cond = COND_FL;
+      }
+      break;
+
+   case 'G':
+      if (s[1] == 'E') {
+        cond = COND_GE;
+      } else if (s[1] == 'T') {
+        cond = COND_GT;
+      }
+      break;
+
+   case 'L':
+      if (s[1] == 'E') {
+        cond = COND_LE;
+      } else if (s[1] == 'T') {
+        cond = COND_LT;
+      }
+      break;
+
+   case 'N':
+      if (s[1] == 'E') {
+        cond = COND_NE;
+      }
+      break;
+
+   case 'T':
+      if (s[1] == 'R') {
+        cond = COND_TR;
+      }
+      break;
+
+   default:
+      break;
+   }
+
+   return ((cond == 0) || (s[2] != '\0')) ? 0 : cond;
+}
+
+
+int
+_mesa_ARBvp_parse_option(struct asm_parser_state *state, const char *option)
+{
+   if (strcmp(option, "ARB_position_invariant") == 0) {
+      state->option.PositionInvariant = 1;
+      return 1;
+   }
+
+   return 0;
+}
+
+
+int
+_mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option)
+{
+   /* All of the options currently supported start with "ARB_".  The code is
+    * currently structured with nested if-statements because eventually options
+    * that start with "NV_" will be supported.  This structure will result in
+    * less churn when those options are added.
+    */
+   if (strncmp(option, "ARB_", 4) == 0) {
+      /* Advance the pointer past the "ARB_" prefix.
+       */
+      option += 4;
+
+
+      if (strncmp(option, "fog_", 4) == 0) {
+        option += 4;
+
+        if (state->option.Fog == OPTION_NONE) {
+           if (strcmp(option, "exp") == 0) {
+              state->option.Fog = OPTION_FOG_EXP;
+              return 1;
+           } else if (strcmp(option, "exp2") == 0) {
+              state->option.Fog = OPTION_FOG_EXP2;
+              return 1;
+           } else if (strcmp(option, "linear") == 0) {
+              state->option.Fog = OPTION_FOG_LINEAR;
+              return 1;
+           }
+        }
+
+        return 0;
+      } else if (strncmp(option, "precision_hint_", 15) == 0) {
+        option += 15;
+
+        if (state->option.PrecisionHint == OPTION_NONE) {
+           if (strcmp(option, "nicest") == 0) {
+              state->option.PrecisionHint = OPTION_NICEST;
+              return 1;
+           } else if (strcmp(option, "fastest") == 0) {
+              state->option.PrecisionHint = OPTION_FASTEST;
+              return 1;
+           }
+        }
+
+        return 0;
+      } else if (strcmp(option, "draw_buffers") == 0) {
+        /* Don't need to check extension availability because all Mesa-based
+         * drivers support GL_ARB_draw_buffers.
+         */
+        state->option.DrawBuffers = 1;
+        return 1;
+      } else if (strcmp(option, "fragment_program_shadow") == 0) {
+        if (state->ctx->Extensions.ARB_fragment_program_shadow) {
+           state->option.Shadow = 1;
+           return 1;
+        }
+      } else if (strncmp(option, "fragment_coord_", 15) == 0) {
+         option += 15;
+         if (state->ctx->Extensions.ARB_fragment_coord_conventions) {
+            if (strcmp(option, "origin_upper_left") == 0) {
+               state->option.OriginUpperLeft = 1;
+               return 1;
+            }
+            else if (strcmp(option, "pixel_center_integer") == 0) {
+               state->option.PixelCenterInteger = 1;
+               return 1;
+            }
+         }
+      }
+   } else if (strncmp(option, "NV_fragment_program", 19) == 0) {
+      option += 19;
+
+      /* Other NV_fragment_program strings may be supported later.
+       */
+      if (option[0] == '\0') {
+        if (state->ctx->Extensions.NV_fragment_program_option) {
+           state->option.NV_fragment = 1;
+           return 1;
+        }
+      }
+   } else if (strncmp(option, "MESA_", 5) == 0) {
+      option += 5;
+
+      if (strcmp(option, "texture_array") == 0) {
+        if (state->ctx->Extensions.MESA_texture_array) {
+           state->option.TexArray = 1;
+           return 1;
+        }
+      }
+   }
+
+   return 0;
+}
diff --git a/src/mesa/program/program_parser.h b/src/mesa/program/program_parser.h
new file mode 100644 (file)
index 0000000..be952d4
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * Copyright Â© 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#pragma once
+
+#include "main/config.h"
+
+#ifndef MTYPES_H
+struct __GLcontextRec;
+typedef struct __GLcontextRec GLcontext;
+#endif
+
+enum asm_type {
+   at_none,
+   at_address,
+   at_attrib,
+   at_param,
+   at_temp,
+   at_output
+};
+
+struct asm_symbol {
+   struct asm_symbol *next;    /**< List linkage for freeing. */
+   const char *name;
+   enum asm_type type;
+   unsigned attrib_binding;
+   unsigned output_binding;   /**< Output / result register number. */
+
+   /**
+    * One of PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM, or PROGRAM_ENV_PARAM.
+    */
+   unsigned param_binding_type;
+
+   /** 
+    * Offset into the program_parameter_list where the tokens representing our
+    * bound state (or constants) start.
+    */
+   unsigned param_binding_begin;
+
+   /**
+    * Constants put into the parameter list may be swizzled.  This
+    * field contain's the symbol's swizzle. (SWIZZLE_X/Y/Z/W)
+    */
+   unsigned param_binding_swizzle;
+
+   /* This is how many entries in the program_parameter_list we take up
+    * with our state tokens or constants. Note that this is _not_ the same as
+    * the number of param registers we eventually use.
+    */
+   unsigned param_binding_length;
+
+   /**
+    * Index of the temp register assigned to this variable.
+    */
+   unsigned temp_binding;
+
+   /**
+    * Flag whether or not a PARAM is an array
+    */
+   unsigned param_is_array:1;
+
+
+   /**
+    * Flag whether or not a PARAM array is accessed indirectly
+    */
+   unsigned param_accessed_indirectly:1;
+
+
+   /**
+    * \brief Is first pass of parameter layout done with this variable?
+    *
+    * The parameter layout routine operates in two passes.  This flag tracks
+    * whether or not the first pass has handled this variable.
+    *
+    * \sa _mesa_layout_parameters
+    */
+   unsigned pass1_done:1;
+};
+
+
+struct asm_vector {
+   unsigned count;
+   float    data[4];
+};
+
+
+struct asm_swizzle_mask {
+   unsigned swizzle:12;
+   unsigned mask:4;
+};
+
+
+struct asm_src_register {
+   struct prog_src_register Base;
+
+   /**
+    * Symbol associated with indirect access to parameter arrays.
+    *
+    * If \c Base::RelAddr is 1, this will point to the symbol for the parameter
+    * that is being dereferenced.  Further, \c Base::Index will be the offset
+    * from the address register being used.
+    */
+   struct asm_symbol *Symbol;
+};
+
+
+struct asm_instruction {
+   struct prog_instruction Base;
+   struct asm_instruction *next;
+   struct asm_src_register SrcReg[3];
+};
+
+
+struct asm_parser_state {
+   GLcontext *ctx;
+   struct gl_program *prog;
+
+   /**
+    * Per-program target limits
+    */
+   struct gl_program_constants *limits;
+
+   struct _mesa_symbol_table *st;
+
+   /**
+    * Linked list of symbols
+    *
+    * This list is \b only used when cleaning up compiler state and freeing
+    * memory.
+    */
+   struct asm_symbol *sym;
+
+   /**
+    * State for the lexer.
+    */
+   void *scanner;
+
+   /**
+    * Linked list of instructions generated during parsing.
+    */
+   /*@{*/
+   struct asm_instruction *inst_head;
+   struct asm_instruction *inst_tail;
+   /*@}*/
+
+
+   /**
+    * Selected limits copied from gl_constants
+    *
+    * These are limits from the GL context, but various bits in the program
+    * must be validated against these values.
+    */
+   /*@{*/
+   unsigned MaxTextureCoordUnits;
+   unsigned MaxTextureImageUnits;
+   unsigned MaxTextureUnits;
+   unsigned MaxClipPlanes;
+   unsigned MaxLights;
+   unsigned MaxProgramMatrices;
+   /*@}*/
+
+   /**
+    * Value to use in state vector accessors for environment and local
+    * parameters
+    */
+   unsigned state_param_enum;
+
+
+   /**
+    * Input attributes bound to specific names
+    *
+    * This is only needed so that errors can be properly produced when
+    * multiple ATTRIB statements bind illegal combinations of vertex
+    * attributes.
+    */
+   unsigned InputsBound;
+
+   enum {
+      invalid_mode = 0,
+      ARB_vertex,
+      ARB_fragment
+   } mode;
+
+   struct {
+      unsigned PositionInvariant:1;
+      unsigned Fog:2;
+      unsigned PrecisionHint:2;
+      unsigned DrawBuffers:1;
+      unsigned Shadow:1;
+      unsigned TexRect:1;
+      unsigned TexArray:1;
+      unsigned NV_fragment:1;
+      unsigned OriginUpperLeft:1;
+      unsigned PixelCenterInteger:1;
+   } option;
+
+   struct {
+      unsigned UsesKill:1;
+   } fragment;
+};
+
+#define OPTION_NONE        0
+#define OPTION_FOG_EXP     1
+#define OPTION_FOG_EXP2    2
+#define OPTION_FOG_LINEAR  3
+#define OPTION_NICEST      1
+#define OPTION_FASTEST     2
+
+typedef struct YYLTYPE {
+   int first_line;
+   int first_column;
+   int last_line;
+   int last_column;
+   int position;
+} YYLTYPE;
+
+#define YYLTYPE_IS_DECLARED 1
+#define YYLTYPE_IS_TRIVIAL 1
+
+
+extern GLboolean _mesa_parse_arb_program(GLcontext *ctx, GLenum target,
+    const GLubyte *str, GLsizei len, struct asm_parser_state *state);
+
+
+
+/* From program_lexer.l. */
+extern void _mesa_program_lexer_dtor(void *scanner);
+
+extern void _mesa_program_lexer_ctor(void **scanner,
+    struct asm_parser_state *state, const char *string, size_t len);
+
+
+/**
+ *\name From program_parse_extra.c
+ */
+/*@{*/
+
+/**
+ * Parses and processes an option string to an ARB vertex program
+ *
+ * \return
+ * Non-zero on success, zero on failure.
+ */
+extern int _mesa_ARBvp_parse_option(struct asm_parser_state *state,
+    const char *option);
+
+/**
+ * Parses and processes an option string to an ARB fragment program
+ *
+ * \return
+ * Non-zero on success, zero on failure.
+ */
+extern int _mesa_ARBfp_parse_option(struct asm_parser_state *state,
+    const char *option);
+
+/**
+ * Parses and processes instruction suffixes
+ *
+ * Instruction suffixes, such as \c _SAT, are processed.  The relevant bits
+ * are set in \c inst.  If suffixes are encountered that are either not known
+ * or not supported by the modes and options set in \c state, zero will be
+ * returned.
+ *
+ * \return
+ * Non-zero on success, zero on failure.
+ */
+extern int _mesa_parse_instruction_suffix(const struct asm_parser_state *state,
+    const char *suffix, struct prog_instruction *inst);
+
+/**
+ * Parses a condition code name
+ *
+ * The condition code names (e.g., \c LT, \c GT, \c NE) were added to assembly
+ * shaders with the \c GL_NV_fragment_program_option extension.  This function
+ * converts a string representation into one of the \c COND_ macros.
+ *
+ * \return
+ * One of the \c COND_ macros defined in prog_instruction.h on success or zero
+ * on failure.
+ */
+extern int _mesa_parse_cc(const char *s);
+
+/*@}*/
diff --git a/src/mesa/program/programopt.c b/src/mesa/program/programopt.c
new file mode 100644 (file)
index 0000000..fb2ebe6
--- /dev/null
@@ -0,0 +1,669 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.3
+ *
+ * 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  programopt.c 
+ * Vertex/Fragment program optimizations and transformations for program
+ * options, etc.
+ *
+ * \author Brian Paul
+ */
+
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "prog_parameter.h"
+#include "prog_statevars.h"
+#include "program.h"
+#include "programopt.h"
+#include "prog_instruction.h"
+
+
+/**
+ * This function inserts instructions for coordinate modelview * projection
+ * into a vertex program.
+ * May be used to implement the position_invariant option.
+ */
+static void
+_mesa_insert_mvp_dp4_code(GLcontext *ctx, struct gl_vertex_program *vprog)
+{
+   struct prog_instruction *newInst;
+   const GLuint origLen = vprog->Base.NumInstructions;
+   const GLuint newLen = origLen + 4;
+   GLuint i;
+
+   /*
+    * Setup state references for the modelview/projection matrix.
+    * XXX we should check if these state vars are already declared.
+    */
+   static const gl_state_index mvpState[4][STATE_LENGTH] = {
+      { STATE_MVP_MATRIX, 0, 0, 0, 0 },  /* state.matrix.mvp.row[0] */
+      { STATE_MVP_MATRIX, 0, 1, 1, 0 },  /* state.matrix.mvp.row[1] */
+      { STATE_MVP_MATRIX, 0, 2, 2, 0 },  /* state.matrix.mvp.row[2] */
+      { STATE_MVP_MATRIX, 0, 3, 3, 0 },  /* state.matrix.mvp.row[3] */
+   };
+   GLint mvpRef[4];
+
+   for (i = 0; i < 4; i++) {
+      mvpRef[i] = _mesa_add_state_reference(vprog->Base.Parameters,
+                                            mvpState[i]);
+   }
+
+   /* Alloc storage for new instructions */
+   newInst = _mesa_alloc_instructions(newLen);
+   if (!newInst) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY,
+                  "glProgramString(inserting position_invariant code)");
+      return;
+   }
+
+   /*
+    * Generated instructions:
+    * newInst[0] = DP4 result.position.x, mvp.row[0], vertex.position;
+    * newInst[1] = DP4 result.position.y, mvp.row[1], vertex.position;
+    * newInst[2] = DP4 result.position.z, mvp.row[2], vertex.position;
+    * newInst[3] = DP4 result.position.w, mvp.row[3], vertex.position;
+    */
+   _mesa_init_instructions(newInst, 4);
+   for (i = 0; i < 4; i++) {
+      newInst[i].Opcode = OPCODE_DP4;
+      newInst[i].DstReg.File = PROGRAM_OUTPUT;
+      newInst[i].DstReg.Index = VERT_RESULT_HPOS;
+      newInst[i].DstReg.WriteMask = (WRITEMASK_X << i);
+      newInst[i].SrcReg[0].File = PROGRAM_STATE_VAR;
+      newInst[i].SrcReg[0].Index = mvpRef[i];
+      newInst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP;
+      newInst[i].SrcReg[1].File = PROGRAM_INPUT;
+      newInst[i].SrcReg[1].Index = VERT_ATTRIB_POS;
+      newInst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP;
+   }
+
+   /* Append original instructions after new instructions */
+   _mesa_copy_instructions (newInst + 4, vprog->Base.Instructions, origLen);
+
+   /* free old instructions */
+   _mesa_free_instructions(vprog->Base.Instructions, origLen);
+
+   /* install new instructions */
+   vprog->Base.Instructions = newInst;
+   vprog->Base.NumInstructions = newLen;
+   vprog->Base.InputsRead |= VERT_BIT_POS;
+   vprog->Base.OutputsWritten |= BITFIELD64_BIT(VERT_RESULT_HPOS);
+}
+
+
+static void
+_mesa_insert_mvp_mad_code(GLcontext *ctx, struct gl_vertex_program *vprog)
+{
+   struct prog_instruction *newInst;
+   const GLuint origLen = vprog->Base.NumInstructions;
+   const GLuint newLen = origLen + 4;
+   GLuint hposTemp;
+   GLuint i;
+
+   /*
+    * Setup state references for the modelview/projection matrix.
+    * XXX we should check if these state vars are already declared.
+    */
+   static const gl_state_index mvpState[4][STATE_LENGTH] = {
+      { STATE_MVP_MATRIX, 0, 0, 0, STATE_MATRIX_TRANSPOSE },
+      { STATE_MVP_MATRIX, 0, 1, 1, STATE_MATRIX_TRANSPOSE },
+      { STATE_MVP_MATRIX, 0, 2, 2, STATE_MATRIX_TRANSPOSE },
+      { STATE_MVP_MATRIX, 0, 3, 3, STATE_MATRIX_TRANSPOSE },
+   };
+   GLint mvpRef[4];
+
+   for (i = 0; i < 4; i++) {
+      mvpRef[i] = _mesa_add_state_reference(vprog->Base.Parameters,
+                                            mvpState[i]);
+   }
+
+   /* Alloc storage for new instructions */
+   newInst = _mesa_alloc_instructions(newLen);
+   if (!newInst) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY,
+                  "glProgramString(inserting position_invariant code)");
+      return;
+   }
+
+   /* TEMP hposTemp; */
+   hposTemp = vprog->Base.NumTemporaries++;
+
+   /*
+    * Generated instructions:
+    *    emit_op2(p, OPCODE_MUL, tmp, 0, swizzle1(src,X), mat[0]);
+    *    emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Y), mat[1], tmp);
+    *    emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Z), mat[2], tmp);
+    *    emit_op3(p, OPCODE_MAD, dest, 0, swizzle1(src,W), mat[3], tmp);
+    */
+   _mesa_init_instructions(newInst, 4);
+
+   newInst[0].Opcode = OPCODE_MUL;
+   newInst[0].DstReg.File = PROGRAM_TEMPORARY;
+   newInst[0].DstReg.Index = hposTemp;
+   newInst[0].DstReg.WriteMask = WRITEMASK_XYZW;
+   newInst[0].SrcReg[0].File = PROGRAM_INPUT;
+   newInst[0].SrcReg[0].Index = VERT_ATTRIB_POS;
+   newInst[0].SrcReg[0].Swizzle = SWIZZLE_XXXX;
+   newInst[0].SrcReg[1].File = PROGRAM_STATE_VAR;
+   newInst[0].SrcReg[1].Index = mvpRef[0];
+   newInst[0].SrcReg[1].Swizzle = SWIZZLE_NOOP;
+
+   for (i = 1; i <= 2; i++) {
+      newInst[i].Opcode = OPCODE_MAD;
+      newInst[i].DstReg.File = PROGRAM_TEMPORARY;
+      newInst[i].DstReg.Index = hposTemp;
+      newInst[i].DstReg.WriteMask = WRITEMASK_XYZW;
+      newInst[i].SrcReg[0].File = PROGRAM_INPUT;
+      newInst[i].SrcReg[0].Index = VERT_ATTRIB_POS;
+      newInst[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(i,i,i,i);
+      newInst[i].SrcReg[1].File = PROGRAM_STATE_VAR;
+      newInst[i].SrcReg[1].Index = mvpRef[i];
+      newInst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP;
+      newInst[i].SrcReg[2].File = PROGRAM_TEMPORARY;
+      newInst[i].SrcReg[2].Index = hposTemp;
+      newInst[1].SrcReg[2].Swizzle = SWIZZLE_NOOP;
+   }
+
+   newInst[3].Opcode = OPCODE_MAD;
+   newInst[3].DstReg.File = PROGRAM_OUTPUT;
+   newInst[3].DstReg.Index = VERT_RESULT_HPOS;
+   newInst[3].DstReg.WriteMask = WRITEMASK_XYZW;
+   newInst[3].SrcReg[0].File = PROGRAM_INPUT;
+   newInst[3].SrcReg[0].Index = VERT_ATTRIB_POS;
+   newInst[3].SrcReg[0].Swizzle = SWIZZLE_WWWW;
+   newInst[3].SrcReg[1].File = PROGRAM_STATE_VAR;
+   newInst[3].SrcReg[1].Index = mvpRef[3];
+   newInst[3].SrcReg[1].Swizzle = SWIZZLE_NOOP;
+   newInst[3].SrcReg[2].File = PROGRAM_TEMPORARY;
+   newInst[3].SrcReg[2].Index = hposTemp;
+   newInst[3].SrcReg[2].Swizzle = SWIZZLE_NOOP;
+
+
+   /* Append original instructions after new instructions */
+   _mesa_copy_instructions (newInst + 4, vprog->Base.Instructions, origLen);
+
+   /* free old instructions */
+   _mesa_free_instructions(vprog->Base.Instructions, origLen);
+
+   /* install new instructions */
+   vprog->Base.Instructions = newInst;
+   vprog->Base.NumInstructions = newLen;
+   vprog->Base.InputsRead |= VERT_BIT_POS;
+   vprog->Base.OutputsWritten |= BITFIELD64_BIT(VERT_RESULT_HPOS);
+}
+
+
+void
+_mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog)
+{
+   if (ctx->mvp_with_dp4) 
+      _mesa_insert_mvp_dp4_code( ctx, vprog );
+   else
+      _mesa_insert_mvp_mad_code( ctx, vprog );
+}
+      
+
+
+
+
+
+/**
+ * Append extra instructions onto the given fragment program to implement
+ * the fog mode specified by fprog->FogOption.
+ * The fragment.fogcoord input is used to compute the fog blend factor.
+ *
+ * XXX with a little work, this function could be adapted to add fog code
+ * to vertex programs too.
+ */
+void
+_mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog)
+{
+   static const gl_state_index fogPStateOpt[STATE_LENGTH]
+      = { STATE_INTERNAL, STATE_FOG_PARAMS_OPTIMIZED, 0, 0, 0 };
+   static const gl_state_index fogColorState[STATE_LENGTH]
+      = { STATE_FOG_COLOR, 0, 0, 0, 0};
+   struct prog_instruction *newInst, *inst;
+   const GLuint origLen = fprog->Base.NumInstructions;
+   const GLuint newLen = origLen + 5;
+   GLuint i;
+   GLint fogPRefOpt, fogColorRef; /* state references */
+   GLuint colorTemp, fogFactorTemp; /* temporary registerss */
+
+   if (fprog->FogOption == GL_NONE) {
+      _mesa_problem(ctx, "_mesa_append_fog_code() called for fragment program"
+                    " with FogOption == GL_NONE");
+      return;
+   }
+
+   /* Alloc storage for new instructions */
+   newInst = _mesa_alloc_instructions(newLen);
+   if (!newInst) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY,
+                  "glProgramString(inserting fog_option code)");
+      return;
+   }
+
+   /* Copy orig instructions into new instruction buffer */
+   _mesa_copy_instructions(newInst, fprog->Base.Instructions, origLen);
+
+   /* PARAM fogParamsRefOpt = internal optimized fog params; */
+   fogPRefOpt
+      = _mesa_add_state_reference(fprog->Base.Parameters, fogPStateOpt);
+   /* PARAM fogColorRef = state.fog.color; */
+   fogColorRef
+      = _mesa_add_state_reference(fprog->Base.Parameters, fogColorState);
+
+   /* TEMP colorTemp; */
+   colorTemp = fprog->Base.NumTemporaries++;
+   /* TEMP fogFactorTemp; */
+   fogFactorTemp = fprog->Base.NumTemporaries++;
+
+   /* Scan program to find where result.color is written */
+   inst = newInst;
+   for (i = 0; i < fprog->Base.NumInstructions; i++) {
+      if (inst->Opcode == OPCODE_END)
+         break;
+      if (inst->DstReg.File == PROGRAM_OUTPUT &&
+          inst->DstReg.Index == FRAG_RESULT_COLOR) {
+         /* change the instruction to write to colorTemp w/ clamping */
+         inst->DstReg.File = PROGRAM_TEMPORARY;
+         inst->DstReg.Index = colorTemp;
+         inst->SaturateMode = SATURATE_ZERO_ONE;
+         /* don't break (may be several writes to result.color) */
+      }
+      inst++;
+   }
+   assert(inst->Opcode == OPCODE_END); /* we'll overwrite this inst */
+
+   _mesa_init_instructions(inst, 5);
+
+   /* emit instructions to compute fog blending factor */
+   if (fprog->FogOption == GL_LINEAR) {
+      /* MAD fogFactorTemp.x, fragment.fogcoord.x, fogPRefOpt.x, fogPRefOpt.y; */
+      inst->Opcode = OPCODE_MAD;
+      inst->DstReg.File = PROGRAM_TEMPORARY;
+      inst->DstReg.Index = fogFactorTemp;
+      inst->DstReg.WriteMask = WRITEMASK_X;
+      inst->SrcReg[0].File = PROGRAM_INPUT;
+      inst->SrcReg[0].Index = FRAG_ATTRIB_FOGC;
+      inst->SrcReg[0].Swizzle = SWIZZLE_XXXX;
+      inst->SrcReg[1].File = PROGRAM_STATE_VAR;
+      inst->SrcReg[1].Index = fogPRefOpt;
+      inst->SrcReg[1].Swizzle = SWIZZLE_XXXX;
+      inst->SrcReg[2].File = PROGRAM_STATE_VAR;
+      inst->SrcReg[2].Index = fogPRefOpt;
+      inst->SrcReg[2].Swizzle = SWIZZLE_YYYY;
+      inst->SaturateMode = SATURATE_ZERO_ONE;
+      inst++;
+   }
+   else {
+      ASSERT(fprog->FogOption == GL_EXP || fprog->FogOption == GL_EXP2);
+      /* fogPRefOpt.z = d/ln(2), fogPRefOpt.w = d/sqrt(ln(2) */
+      /* EXP: MUL fogFactorTemp.x, fogPRefOpt.z, fragment.fogcoord.x; */
+      /* EXP2: MUL fogFactorTemp.x, fogPRefOpt.w, fragment.fogcoord.x; */
+      inst->Opcode = OPCODE_MUL;
+      inst->DstReg.File = PROGRAM_TEMPORARY;
+      inst->DstReg.Index = fogFactorTemp;
+      inst->DstReg.WriteMask = WRITEMASK_X;
+      inst->SrcReg[0].File = PROGRAM_STATE_VAR;
+      inst->SrcReg[0].Index = fogPRefOpt;
+      inst->SrcReg[0].Swizzle
+         = (fprog->FogOption == GL_EXP) ? SWIZZLE_ZZZZ : SWIZZLE_WWWW;
+      inst->SrcReg[1].File = PROGRAM_INPUT;
+      inst->SrcReg[1].Index = FRAG_ATTRIB_FOGC;
+      inst->SrcReg[1].Swizzle = SWIZZLE_XXXX;
+      inst++;
+      if (fprog->FogOption == GL_EXP2) {
+         /* MUL fogFactorTemp.x, fogFactorTemp.x, fogFactorTemp.x; */
+         inst->Opcode = OPCODE_MUL;
+         inst->DstReg.File = PROGRAM_TEMPORARY;
+         inst->DstReg.Index = fogFactorTemp;
+         inst->DstReg.WriteMask = WRITEMASK_X;
+         inst->SrcReg[0].File = PROGRAM_TEMPORARY;
+         inst->SrcReg[0].Index = fogFactorTemp;
+         inst->SrcReg[0].Swizzle = SWIZZLE_XXXX;
+         inst->SrcReg[1].File = PROGRAM_TEMPORARY;
+         inst->SrcReg[1].Index = fogFactorTemp;
+         inst->SrcReg[1].Swizzle = SWIZZLE_XXXX;
+         inst++;
+      }
+      /* EX2_SAT fogFactorTemp.x, -fogFactorTemp.x; */
+      inst->Opcode = OPCODE_EX2;
+      inst->DstReg.File = PROGRAM_TEMPORARY;
+      inst->DstReg.Index = fogFactorTemp;
+      inst->DstReg.WriteMask = WRITEMASK_X;
+      inst->SrcReg[0].File = PROGRAM_TEMPORARY;
+      inst->SrcReg[0].Index = fogFactorTemp;
+      inst->SrcReg[0].Negate = NEGATE_XYZW;
+      inst->SrcReg[0].Swizzle = SWIZZLE_XXXX;
+      inst->SaturateMode = SATURATE_ZERO_ONE;
+      inst++;
+   }
+   /* LRP result.color.xyz, fogFactorTemp.xxxx, colorTemp, fogColorRef; */
+   inst->Opcode = OPCODE_LRP;
+   inst->DstReg.File = PROGRAM_OUTPUT;
+   inst->DstReg.Index = FRAG_RESULT_COLOR;
+   inst->DstReg.WriteMask = WRITEMASK_XYZ;
+   inst->SrcReg[0].File = PROGRAM_TEMPORARY;
+   inst->SrcReg[0].Index = fogFactorTemp;
+   inst->SrcReg[0].Swizzle = SWIZZLE_XXXX;
+   inst->SrcReg[1].File = PROGRAM_TEMPORARY;
+   inst->SrcReg[1].Index = colorTemp;
+   inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
+   inst->SrcReg[2].File = PROGRAM_STATE_VAR;
+   inst->SrcReg[2].Index = fogColorRef;
+   inst->SrcReg[2].Swizzle = SWIZZLE_NOOP;
+   inst++;
+   /* MOV result.color.w, colorTemp.x;  # copy alpha */
+   inst->Opcode = OPCODE_MOV;
+   inst->DstReg.File = PROGRAM_OUTPUT;
+   inst->DstReg.Index = FRAG_RESULT_COLOR;
+   inst->DstReg.WriteMask = WRITEMASK_W;
+   inst->SrcReg[0].File = PROGRAM_TEMPORARY;
+   inst->SrcReg[0].Index = colorTemp;
+   inst->SrcReg[0].Swizzle = SWIZZLE_NOOP;
+   inst++;
+   /* END; */
+   inst->Opcode = OPCODE_END;
+   inst++;
+
+   /* free old instructions */
+   _mesa_free_instructions(fprog->Base.Instructions, origLen);
+
+   /* install new instructions */
+   fprog->Base.Instructions = newInst;
+   fprog->Base.NumInstructions = inst - newInst;
+   fprog->Base.InputsRead |= FRAG_BIT_FOGC;
+   /* XXX do this?  fprog->FogOption = GL_NONE; */
+}
+
+
+
+static GLboolean
+is_texture_instruction(const struct prog_instruction *inst)
+{
+   switch (inst->Opcode) {
+   case OPCODE_TEX:
+   case OPCODE_TXB:
+   case OPCODE_TXD:
+   case OPCODE_TXL:
+   case OPCODE_TXP:
+   case OPCODE_TXP_NV:
+      return GL_TRUE;
+   default:
+      return GL_FALSE;
+   }
+}
+      
+
+/**
+ * Count the number of texure indirections in the given program.
+ * The program's NumTexIndirections field will be updated.
+ * See the GL_ARB_fragment_program spec (issue 24) for details.
+ * XXX we count texture indirections in texenvprogram.c (maybe use this code
+ * instead and elsewhere).
+ */
+void
+_mesa_count_texture_indirections(struct gl_program *prog)
+{
+   GLuint indirections = 1;
+   GLbitfield tempsOutput = 0x0;
+   GLbitfield aluTemps = 0x0;
+   GLuint i;
+
+   for (i = 0; i < prog->NumInstructions; i++) {
+      const struct prog_instruction *inst = prog->Instructions + i;
+
+      if (is_texture_instruction(inst)) {
+         if (((inst->SrcReg[0].File == PROGRAM_TEMPORARY) && 
+              (tempsOutput & (1 << inst->SrcReg[0].Index))) ||
+             ((inst->Opcode != OPCODE_KIL) &&
+              (inst->DstReg.File == PROGRAM_TEMPORARY) && 
+              (aluTemps & (1 << inst->DstReg.Index)))) 
+            {
+               indirections++;
+               tempsOutput = 0x0;
+               aluTemps = 0x0;
+            }
+      }
+      else {
+         GLuint j;
+         for (j = 0; j < 3; j++) {
+            if (inst->SrcReg[j].File == PROGRAM_TEMPORARY)
+               aluTemps |= (1 << inst->SrcReg[j].Index);
+         }
+         if (inst->DstReg.File == PROGRAM_TEMPORARY)
+            aluTemps |= (1 << inst->DstReg.Index);
+      }
+
+      if ((inst->Opcode != OPCODE_KIL) && (inst->DstReg.File == PROGRAM_TEMPORARY))
+         tempsOutput |= (1 << inst->DstReg.Index);
+   }
+
+   prog->NumTexIndirections = indirections;
+}
+
+
+/**
+ * Count number of texture instructions in given program and update the
+ * program's NumTexInstructions field.
+ */
+void
+_mesa_count_texture_instructions(struct gl_program *prog)
+{
+   GLuint i;
+   prog->NumTexInstructions = 0;
+   for (i = 0; i < prog->NumInstructions; i++) {
+      prog->NumTexInstructions += is_texture_instruction(prog->Instructions + i);
+   }
+}
+
+
+/**
+ * Scan/rewrite program to remove reads of custom (output) registers.
+ * The passed type has to be either PROGRAM_OUTPUT or PROGRAM_VARYING
+ * (for vertex shaders).
+ * In GLSL shaders, varying vars can be read and written.
+ * On some hardware, trying to read an output register causes trouble.
+ * So, rewrite the program to use a temporary register in this case.
+ */
+void
+_mesa_remove_output_reads(struct gl_program *prog, gl_register_file type)
+{
+   GLuint i;
+   GLint outputMap[VERT_RESULT_MAX];
+   GLuint numVaryingReads = 0;
+   GLboolean usedTemps[MAX_PROGRAM_TEMPS];
+   GLuint firstTemp = 0;
+
+   _mesa_find_used_registers(prog, PROGRAM_TEMPORARY,
+                             usedTemps, MAX_PROGRAM_TEMPS);
+
+   assert(type == PROGRAM_VARYING || type == PROGRAM_OUTPUT);
+   assert(prog->Target == GL_VERTEX_PROGRAM_ARB || type != PROGRAM_VARYING);
+
+   for (i = 0; i < VERT_RESULT_MAX; i++)
+      outputMap[i] = -1;
+
+   /* look for instructions which read from varying vars */
+   for (i = 0; i < prog->NumInstructions; i++) {
+      struct prog_instruction *inst = prog->Instructions + i;
+      const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
+      GLuint j;
+      for (j = 0; j < numSrc; j++) {
+         if (inst->SrcReg[j].File == type) {
+            /* replace the read with a temp reg */
+            const GLuint var = inst->SrcReg[j].Index;
+            if (outputMap[var] == -1) {
+               numVaryingReads++;
+               outputMap[var] = _mesa_find_free_register(usedTemps,
+                                                         MAX_PROGRAM_TEMPS,
+                                                         firstTemp);
+               firstTemp = outputMap[var] + 1;
+            }
+            inst->SrcReg[j].File = PROGRAM_TEMPORARY;
+            inst->SrcReg[j].Index = outputMap[var];
+         }
+      }
+   }
+
+   if (numVaryingReads == 0)
+      return; /* nothing to be done */
+
+   /* look for instructions which write to the varying vars identified above */
+   for (i = 0; i < prog->NumInstructions; i++) {
+      struct prog_instruction *inst = prog->Instructions + i;
+      if (inst->DstReg.File == type &&
+          outputMap[inst->DstReg.Index] >= 0) {
+         /* change inst to write to the temp reg, instead of the varying */
+         inst->DstReg.File = PROGRAM_TEMPORARY;
+         inst->DstReg.Index = outputMap[inst->DstReg.Index];
+      }
+   }
+
+   /* insert new instructions to copy the temp vars to the varying vars */
+   {
+      struct prog_instruction *inst;
+      GLint endPos, var;
+
+      /* Look for END instruction and insert the new varying writes */
+      endPos = -1;
+      for (i = 0; i < prog->NumInstructions; i++) {
+         struct prog_instruction *inst = prog->Instructions + i;
+         if (inst->Opcode == OPCODE_END) {
+            endPos = i;
+            _mesa_insert_instructions(prog, i, numVaryingReads);
+            break;
+         }
+      }
+
+      assert(endPos >= 0);
+
+      /* insert new MOV instructions here */
+      inst = prog->Instructions + endPos;
+      for (var = 0; var < VERT_RESULT_MAX; var++) {
+         if (outputMap[var] >= 0) {
+            /* MOV VAR[var], TEMP[tmp]; */
+            inst->Opcode = OPCODE_MOV;
+            inst->DstReg.File = type;
+            inst->DstReg.Index = var;
+            inst->SrcReg[0].File = PROGRAM_TEMPORARY;
+            inst->SrcReg[0].Index = outputMap[var];
+            inst++;
+         }
+      }
+   }
+}
+
+
+/**
+ * Make the given fragment program into a "no-op" shader.
+ * Actually, just copy the incoming fragment color (or texcoord)
+ * to the output color.
+ * This is for debug/test purposes.
+ */
+void
+_mesa_nop_fragment_program(GLcontext *ctx, struct gl_fragment_program *prog)
+{
+   struct prog_instruction *inst;
+   GLuint inputAttr;
+
+   inst = _mesa_alloc_instructions(2);
+   if (!inst) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "_mesa_nop_fragment_program");
+      return;
+   }
+
+   _mesa_init_instructions(inst, 2);
+
+   inst[0].Opcode = OPCODE_MOV;
+   inst[0].DstReg.File = PROGRAM_OUTPUT;
+   inst[0].DstReg.Index = FRAG_RESULT_COLOR;
+   inst[0].SrcReg[0].File = PROGRAM_INPUT;
+   if (prog->Base.InputsRead & FRAG_BIT_COL0)
+      inputAttr = FRAG_ATTRIB_COL0;
+   else
+      inputAttr = FRAG_ATTRIB_TEX0;
+   inst[0].SrcReg[0].Index = inputAttr;
+
+   inst[1].Opcode = OPCODE_END;
+
+   _mesa_free_instructions(prog->Base.Instructions,
+                           prog->Base.NumInstructions);
+
+   prog->Base.Instructions = inst;
+   prog->Base.NumInstructions = 2;
+   prog->Base.InputsRead = 1 << inputAttr;
+   prog->Base.OutputsWritten = BITFIELD64_BIT(FRAG_RESULT_COLOR);
+}
+
+
+/**
+ * \sa _mesa_nop_fragment_program
+ * Replace the given vertex program with a "no-op" program that just
+ * transforms vertex position and emits color.
+ */
+void
+_mesa_nop_vertex_program(GLcontext *ctx, struct gl_vertex_program *prog)
+{
+   struct prog_instruction *inst;
+   GLuint inputAttr;
+
+   /*
+    * Start with a simple vertex program that emits color.
+    */
+   inst = _mesa_alloc_instructions(2);
+   if (!inst) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "_mesa_nop_vertex_program");
+      return;
+   }
+
+   _mesa_init_instructions(inst, 2);
+
+   inst[0].Opcode = OPCODE_MOV;
+   inst[0].DstReg.File = PROGRAM_OUTPUT;
+   inst[0].DstReg.Index = VERT_RESULT_COL0;
+   inst[0].SrcReg[0].File = PROGRAM_INPUT;
+   if (prog->Base.InputsRead & VERT_BIT_COLOR0)
+      inputAttr = VERT_ATTRIB_COLOR0;
+   else
+      inputAttr = VERT_ATTRIB_TEX0;
+   inst[0].SrcReg[0].Index = inputAttr;
+
+   inst[1].Opcode = OPCODE_END;
+
+   _mesa_free_instructions(prog->Base.Instructions,
+                           prog->Base.NumInstructions);
+
+   prog->Base.Instructions = inst;
+   prog->Base.NumInstructions = 2;
+   prog->Base.InputsRead = 1 << inputAttr;
+   prog->Base.OutputsWritten = BITFIELD64_BIT(VERT_RESULT_COL0);
+
+   /*
+    * Now insert code to do standard modelview/projection transformation.
+    */
+   _mesa_insert_mvp_code(ctx, prog);
+}
diff --git a/src/mesa/program/programopt.h b/src/mesa/program/programopt.h
new file mode 100644 (file)
index 0000000..21fac07
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.3
+ *
+ * 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.
+ */
+
+
+#ifndef PROGRAMOPT_H
+#define PROGRAMOPT_H 1
+
+
+extern void
+_mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog);
+
+extern void
+_mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog);
+
+extern void
+_mesa_count_texture_indirections(struct gl_program *prog);
+
+extern void
+_mesa_count_texture_instructions(struct gl_program *prog);
+
+extern void
+_mesa_remove_output_reads(struct gl_program *prog, gl_register_file type);
+
+extern void
+_mesa_nop_fragment_program(GLcontext *ctx, struct gl_fragment_program *prog);
+
+extern void
+_mesa_nop_vertex_program(GLcontext *ctx, struct gl_vertex_program *prog);
+
+
+#endif /* PROGRAMOPT_H */
diff --git a/src/mesa/program/symbol_table.c b/src/mesa/program/symbol_table.c
new file mode 100644 (file)
index 0000000..3fea5ee
--- /dev/null
@@ -0,0 +1,412 @@
+/*
+ * Copyright Â© 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION 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/imports.h"
+#include "symbol_table.h"
+#include "hash_table.h"
+
+struct symbol {
+    /**
+     * Link to the next symbol in the table with the same name
+     *
+     * The linked list of symbols with the same name is ordered by scope
+     * from inner-most to outer-most.
+     */
+    struct symbol *next_with_same_name;
+
+
+    /**
+     * Link to the next symbol in the table with the same scope
+     *
+     * The linked list of symbols with the same scope is unordered.  Symbols
+     * in this list my have unique names.
+     */
+    struct symbol *next_with_same_scope;
+
+
+    /**
+     * Header information for the list of symbols with the same name.
+     */
+    struct symbol_header *hdr;
+
+
+    /**
+     * Name space of the symbol
+     *
+     * Name space are arbitrary user assigned integers.  No two symbols can
+     * exist in the same name space at the same scope level.
+     */
+    int name_space;
+
+    /** Scope depth where this symbol was defined. */
+    unsigned depth;
+
+    /**
+     * Arbitrary user supplied data.
+     */
+    void *data;
+};
+
+
+/**
+ */
+struct symbol_header {
+    /** Linkage in list of all headers in a given symbol table. */
+    struct symbol_header *next;
+
+    /** Symbol name. */
+    const char *name;
+
+    /** Linked list of symbols with the same name. */
+    struct symbol *symbols;
+};
+
+
+/**
+ * Element of the scope stack.
+ */
+struct scope_level {
+    /** Link to next (inner) scope level. */
+    struct scope_level *next;
+    
+    /** Linked list of symbols with the same scope. */
+    struct symbol *symbols;
+};
+
+
+/**
+ *
+ */
+struct _mesa_symbol_table {
+    /** Hash table containing all symbols in the symbol table. */
+    struct hash_table *ht;
+
+    /** Top of scope stack. */
+    struct scope_level *current_scope;
+
+    /** List of all symbol headers in the table. */
+    struct symbol_header *hdr;
+
+    /** Current scope depth. */
+    unsigned depth;
+};
+
+
+struct _mesa_symbol_table_iterator {
+    /**
+     * Name space of symbols returned by this iterator.
+     */
+    int name_space;
+
+
+    /**
+     * Currently iterated symbol
+     *
+     * The next call to \c _mesa_symbol_table_iterator_get will return this
+     * value.  It will also update this value to the value that should be
+     * returned by the next call.
+     */
+    struct symbol *curr;
+};
+
+
+static void
+check_symbol_table(struct _mesa_symbol_table *table)
+{
+#if 1
+    struct scope_level *scope;
+
+    for (scope = table->current_scope; scope != NULL; scope = scope->next) {
+        struct symbol *sym;
+
+        for (sym = scope->symbols
+             ; sym != NULL
+             ; sym = sym->next_with_same_name) {
+            const struct symbol_header *const hdr = sym->hdr;
+            struct symbol *sym2;
+
+            for (sym2 = hdr->symbols
+                 ; sym2 != NULL
+                 ; sym2 = sym2->next_with_same_name) {
+                assert(sym2->hdr == hdr);
+            }
+        }
+    }
+#endif
+}
+
+void
+_mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table)
+{
+    struct scope_level *const scope = table->current_scope;
+    struct symbol *sym = scope->symbols;
+
+    table->current_scope = scope->next;
+    table->depth--;
+
+    free(scope);
+
+    while (sym != NULL) {
+        struct symbol *const next = sym->next_with_same_scope;
+        struct symbol_header *const hdr = sym->hdr;
+
+        assert(hdr->symbols == sym);
+
+        hdr->symbols = sym->next_with_same_name;
+
+        free(sym);
+
+        sym = next;
+    }
+
+    check_symbol_table(table);
+}
+
+
+void
+_mesa_symbol_table_push_scope(struct _mesa_symbol_table *table)
+{
+    struct scope_level *const scope = calloc(1, sizeof(*scope));
+    
+    scope->next = table->current_scope;
+    table->current_scope = scope;
+    table->depth++;
+}
+
+
+static struct symbol_header *
+find_symbol(struct _mesa_symbol_table *table, const char *name)
+{
+    return (struct symbol_header *) hash_table_find(table->ht, name);
+}
+
+
+struct _mesa_symbol_table_iterator *
+_mesa_symbol_table_iterator_ctor(struct _mesa_symbol_table *table,
+                                 int name_space, const char *name)
+{
+    struct _mesa_symbol_table_iterator *iter = calloc(1, sizeof(*iter));
+    struct symbol_header *const hdr = find_symbol(table, name);
+    
+    iter->name_space = name_space;
+
+    if (hdr != NULL) {
+        struct symbol *sym;
+
+        for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
+            assert(sym->hdr == hdr);
+
+            if ((name_space == -1) || (sym->name_space == name_space)) {
+                iter->curr = sym;
+                break;
+            }
+        }
+    }
+
+    return iter;
+}
+
+
+void
+_mesa_symbol_table_iterator_dtor(struct _mesa_symbol_table_iterator *iter)
+{
+    free(iter);
+}
+
+
+void *
+_mesa_symbol_table_iterator_get(struct _mesa_symbol_table_iterator *iter)
+{
+    return (iter->curr == NULL) ? NULL : iter->curr->data;
+}
+
+
+int
+_mesa_symbol_table_iterator_next(struct _mesa_symbol_table_iterator *iter)
+{
+    struct symbol_header *hdr;
+
+    if (iter->curr == NULL) {
+        return 0;
+    }
+
+    hdr = iter->curr->hdr;
+    iter->curr = iter->curr->next_with_same_name;
+
+    while (iter->curr != NULL) {
+        assert(iter->curr->hdr == hdr);
+
+        if ((iter->name_space == -1)
+            || (iter->curr->name_space == iter->name_space)) {
+            return 1;
+        }
+
+        iter->curr = iter->curr->next_with_same_name;
+    }
+
+    return 0;
+}
+
+
+/**
+ * Determine the scope "distance" of a symbol from the current scope
+ *
+ * \return
+ * A non-negative number for the number of scopes between the current scope
+ * and the scope where a symbol was defined.  A value of zero means the current
+ * scope.  A negative number if the symbol does not exist.
+ */
+int
+_mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table,
+                               int name_space, const char *name)
+{
+    struct symbol_header *const hdr = find_symbol(table, name);
+    struct symbol *sym;
+
+    if (hdr != NULL) {
+       for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
+         assert(sym->hdr == hdr);
+
+         if ((name_space == -1) || (sym->name_space == name_space)) {
+            assert(sym->depth <= table->depth);
+            return sym->depth - table->depth;
+         }
+       }
+    }
+
+    return -1;
+}
+
+
+void *
+_mesa_symbol_table_find_symbol(struct _mesa_symbol_table *table,
+                               int name_space, const char *name)
+{
+    struct symbol_header *const hdr = find_symbol(table, name);
+
+    if (hdr != NULL) {
+        struct symbol *sym;
+
+
+        for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
+            assert(sym->hdr == hdr);
+
+            if ((name_space == -1) || (sym->name_space == name_space)) {
+                return sym->data;
+            }
+        }
+    }
+
+    return NULL;
+}
+
+
+int
+_mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table,
+                              int name_space, const char *name,
+                              void *declaration)
+{
+    struct symbol_header *hdr;
+    struct symbol *sym;
+
+    check_symbol_table(table);
+
+    hdr = find_symbol(table, name);
+
+    check_symbol_table(table);
+
+    if (hdr == NULL) {
+        hdr = calloc(1, sizeof(*hdr));
+        hdr->name = name;
+
+        hash_table_insert(table->ht, hdr, name);
+       hdr->next = table->hdr;
+       table->hdr = hdr;
+    }
+
+    check_symbol_table(table);
+
+    /* If the symbol already exists in this namespace at this scope, it cannot
+     * be added to the table.
+     */
+    for (sym = hdr->symbols
+        ; (sym != NULL) && (sym->name_space != name_space)
+        ; sym = sym->next_with_same_name) {
+       /* empty */
+    }
+
+    if (sym && (sym->depth == table->depth))
+       return -1;
+
+    sym = calloc(1, sizeof(*sym));
+    sym->next_with_same_name = hdr->symbols;
+    sym->next_with_same_scope = table->current_scope->symbols;
+    sym->hdr = hdr;
+    sym->name_space = name_space;
+    sym->data = declaration;
+    sym->depth = table->depth;
+
+    assert(sym->hdr == hdr);
+
+    hdr->symbols = sym;
+    table->current_scope->symbols = sym;
+
+    check_symbol_table(table);
+    return 0;
+}
+
+
+struct _mesa_symbol_table *
+_mesa_symbol_table_ctor(void)
+{
+    struct _mesa_symbol_table *table = calloc(1, sizeof(*table));
+
+    if (table != NULL) {
+       table->ht = hash_table_ctor(32, hash_table_string_hash,
+                                  hash_table_string_compare);
+
+       _mesa_symbol_table_push_scope(table);
+    }
+
+    return table;
+}
+
+
+void
+_mesa_symbol_table_dtor(struct _mesa_symbol_table *table)
+{
+   struct symbol_header *hdr;
+   struct symbol_header *next;
+
+   while (table->current_scope != NULL) {
+      _mesa_symbol_table_pop_scope(table);
+   }
+
+   for (hdr = table->hdr; hdr != NULL; hdr = next) {
+       next = hdr->next;
+       free(hdr);
+   }
+
+   hash_table_dtor(table->ht);
+   free(table);
+}
diff --git a/src/mesa/program/symbol_table.h b/src/mesa/program/symbol_table.h
new file mode 100644 (file)
index 0000000..1d570fc
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright Â© 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION 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 MESA_SYMBOL_TABLE_H
+#define MESA_SYMBOL_TABLE_H
+
+struct _mesa_symbol_table;
+struct _mesa_symbol_table_iterator;
+
+extern void _mesa_symbol_table_push_scope(struct _mesa_symbol_table *table);
+
+extern void _mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table);
+
+extern int _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *symtab,
+    int name_space, const char *name, void *declaration);
+
+extern int _mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table,
+    int name_space, const char *name);
+
+extern void *_mesa_symbol_table_find_symbol(
+    struct _mesa_symbol_table *symtab, int name_space, const char *name);
+
+extern struct _mesa_symbol_table *_mesa_symbol_table_ctor(void);
+
+extern void _mesa_symbol_table_dtor(struct _mesa_symbol_table *);
+
+extern struct _mesa_symbol_table_iterator *_mesa_symbol_table_iterator_ctor(
+    struct _mesa_symbol_table *table, int name_space, const char *name);
+
+extern void _mesa_symbol_table_iterator_dtor(
+    struct _mesa_symbol_table_iterator *);
+
+extern void *_mesa_symbol_table_iterator_get(
+    struct _mesa_symbol_table_iterator *iter);
+
+extern int _mesa_symbol_table_iterator_next(
+    struct _mesa_symbol_table_iterator *iter);
+
+#endif /* MESA_SYMBOL_TABLE_H */
diff --git a/src/mesa/shader/.gitignore b/src/mesa/shader/.gitignore
deleted file mode 100644 (file)
index 086fd9a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-program_parse.output
diff --git a/src/mesa/shader/Makefile b/src/mesa/shader/Makefile
deleted file mode 100644 (file)
index 400a543..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-all: program_parse.tab.c lex.yy.c
-
-program_parse.tab.c program_parse.tab.h: program_parse.y
-       bison -v -d $<
-
-lex.yy.c: program_lexer.l
-       flex --never-interactive $<
diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c
deleted file mode 100644 (file)
index 6373529..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.1
- *
- * Copyright (C) 1999-2008  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.
- */
-
-#define DEBUG_PARSING 0
-
-/**
- * \file arbprogparse.c
- * ARB_*_program parser core
- * \author Karl Rasche
- */
-
-/**
-Notes on program parameters, etc.
-
-The instructions we emit will use six kinds of source registers:
-
-  PROGRAM_INPUT      - input registers
-  PROGRAM_TEMPORARY  - temp registers
-  PROGRAM_ADDRESS    - address/indirect register
-  PROGRAM_SAMPLER    - texture sampler
-  PROGRAM_CONSTANT   - indexes into program->Parameters, a known constant/literal
-  PROGRAM_STATE_VAR  - indexes into program->Parameters, and may actually be:
-                       + a state variable, like "state.fog.color", or
-                       + a pointer to a "program.local[k]" parameter, or
-                       + a pointer to a "program.env[k]" parameter
-
-Basically, all the program.local[] and program.env[] values will get mapped
-into the unified gl_program->Parameters array.  This solves the problem of
-having three separate program parameter arrays.
-*/
-
-
-#include "main/glheader.h"
-#include "main/imports.h"
-#include "main/context.h"
-#include "main/mtypes.h"
-#include "arbprogparse.h"
-#include "programopt.h"
-#include "prog_parameter.h"
-#include "prog_statevars.h"
-#include "prog_instruction.h"
-#include "program_parser.h"
-
-
-void
-_mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target,
-                                 const GLvoid *str, GLsizei len,
-                                 struct gl_fragment_program *program)
-{
-   struct gl_program prog;
-   struct asm_parser_state state;
-   GLuint i;
-
-   ASSERT(target == GL_FRAGMENT_PROGRAM_ARB);
-
-   memset(&prog, 0, sizeof(prog));
-   memset(&state, 0, sizeof(state));
-   state.prog = &prog;
-
-   if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len,
-                               &state)) {
-      /* Error in the program. Just return. */
-      return;
-   }
-
-   if (program->Base.String != NULL)
-      free(program->Base.String);
-
-   /* Copy the relevant contents of the arb_program struct into the
-    * fragment_program struct.
-    */
-   program->Base.String          = prog.String;
-   program->Base.NumInstructions = prog.NumInstructions;
-   program->Base.NumTemporaries  = prog.NumTemporaries;
-   program->Base.NumParameters   = prog.NumParameters;
-   program->Base.NumAttributes   = prog.NumAttributes;
-   program->Base.NumAddressRegs  = prog.NumAddressRegs;
-   program->Base.NumNativeInstructions = prog.NumNativeInstructions;
-   program->Base.NumNativeTemporaries = prog.NumNativeTemporaries;
-   program->Base.NumNativeParameters = prog.NumNativeParameters;
-   program->Base.NumNativeAttributes = prog.NumNativeAttributes;
-   program->Base.NumNativeAddressRegs = prog.NumNativeAddressRegs;
-   program->Base.NumAluInstructions   = prog.NumAluInstructions;
-   program->Base.NumTexInstructions   = prog.NumTexInstructions;
-   program->Base.NumTexIndirections   = prog.NumTexIndirections;
-   program->Base.NumNativeAluInstructions = prog.NumAluInstructions;
-   program->Base.NumNativeTexInstructions = prog.NumTexInstructions;
-   program->Base.NumNativeTexIndirections = prog.NumTexIndirections;
-   program->Base.InputsRead      = prog.InputsRead;
-   program->Base.OutputsWritten  = prog.OutputsWritten;
-   for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) {
-      program->Base.TexturesUsed[i] = prog.TexturesUsed[i];
-      if (prog.TexturesUsed[i])
-         program->Base.SamplersUsed |= (1 << i);
-   }
-   program->Base.ShadowSamplers = prog.ShadowSamplers;
-   switch (state.option.Fog) {
-   case OPTION_FOG_EXP:    program->FogOption = GL_EXP;    break;
-   case OPTION_FOG_EXP2:   program->FogOption = GL_EXP2;   break;
-   case OPTION_FOG_LINEAR: program->FogOption = GL_LINEAR; break;
-   default:                program->FogOption = GL_NONE;   break;
-   }
-   program->OriginUpperLeft = state.option.OriginUpperLeft;
-   program->PixelCenterInteger = state.option.PixelCenterInteger;
-
-   program->UsesKill            = state.fragment.UsesKill;
-
-   if (program->FogOption)
-      program->Base.InputsRead |= FRAG_BIT_FOGC;
-
-   if (program->Base.Instructions)
-      free(program->Base.Instructions);
-   program->Base.Instructions = prog.Instructions;
-
-   if (program->Base.Parameters)
-      _mesa_free_parameter_list(program->Base.Parameters);
-   program->Base.Parameters    = prog.Parameters;
-
-   /* Append fog instructions now if the program has "OPTION ARB_fog_exp"
-    * or similar.  We used to leave this up to drivers, but it appears
-    * there's no hardware that wants to do fog in a discrete stage separate
-    * from the fragment shader.
-    */
-   if (program->FogOption != GL_NONE) {
-      _mesa_append_fog_code(ctx, program);
-      program->FogOption = GL_NONE;
-   }
-
-#if DEBUG_FP
-   printf("____________Fragment program %u ________\n", program->Base.Id);
-   _mesa_print_program(&program->Base);
-#endif
-}
-
-
-
-/**
- * Parse the vertex program string.  If success, update the given
- * vertex_program object with the new program.  Else, leave the vertex_program
- * object unchanged.
- */
-void
-_mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target,
-                              const GLvoid *str, GLsizei len,
-                              struct gl_vertex_program *program)
-{
-   struct gl_program prog;
-   struct asm_parser_state state;
-
-   ASSERT(target == GL_VERTEX_PROGRAM_ARB);
-
-   memset(&prog, 0, sizeof(prog));
-   memset(&state, 0, sizeof(state));
-   state.prog = &prog;
-
-   if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len,
-                               &state)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramString(bad program)");
-      return;
-   }
-
-   if (program->Base.String != NULL)
-      free(program->Base.String);
-
-   /* Copy the relevant contents of the arb_program struct into the 
-    * vertex_program struct.
-    */
-   program->Base.String          = prog.String;
-   program->Base.NumInstructions = prog.NumInstructions;
-   program->Base.NumTemporaries  = prog.NumTemporaries;
-   program->Base.NumParameters   = prog.NumParameters;
-   program->Base.NumAttributes   = prog.NumAttributes;
-   program->Base.NumAddressRegs  = prog.NumAddressRegs;
-   program->Base.NumNativeInstructions = prog.NumNativeInstructions;
-   program->Base.NumNativeTemporaries = prog.NumNativeTemporaries;
-   program->Base.NumNativeParameters = prog.NumNativeParameters;
-   program->Base.NumNativeAttributes = prog.NumNativeAttributes;
-   program->Base.NumNativeAddressRegs = prog.NumNativeAddressRegs;
-   program->Base.InputsRead     = prog.InputsRead;
-   program->Base.OutputsWritten = prog.OutputsWritten;
-   program->IsPositionInvariant = (state.option.PositionInvariant)
-      ? GL_TRUE : GL_FALSE;
-
-   if (program->Base.Instructions)
-      free(program->Base.Instructions);
-   program->Base.Instructions = prog.Instructions;
-
-   if (program->Base.Parameters)
-      _mesa_free_parameter_list(program->Base.Parameters);
-   program->Base.Parameters = prog.Parameters; 
-
-#if DEBUG_VP
-   printf("____________Vertex program %u __________\n", program->Base.Id);
-   _mesa_print_program(&program->Base);
-#endif
-}
diff --git a/src/mesa/shader/arbprogparse.h b/src/mesa/shader/arbprogparse.h
deleted file mode 100644 (file)
index 980d39f..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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 ARBPROGPARSE_H
-#define ARBPROGPARSE_H
-
-#include "main/mtypes.h"
-
-extern void
-_mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target,
-                              const GLvoid *str, GLsizei len,
-                              struct gl_vertex_program *program);
-
-extern void
-_mesa_parse_arb_fragment_program(GLcontext *ctx, GLenum target,
-                                 const GLvoid *str, GLsizei len,
-                                 struct gl_fragment_program *program);
-
-#endif
diff --git a/src/mesa/shader/arbprogram.c b/src/mesa/shader/arbprogram.c
deleted file mode 100644 (file)
index 8c0b944..0000000
+++ /dev/null
@@ -1,940 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.0
- *
- * 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 arbprogram.c
- * ARB_vertex/fragment_program state management functions.
- * \author Brian Paul
- */
-
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/hash.h"
-#include "main/imports.h"
-#include "main/macros.h"
-#include "main/mtypes.h"
-#include "arbprogram.h"
-#include "arbprogparse.h"
-#include "nvfragparse.h"
-#include "nvvertparse.h"
-#include "program.h"
-
-
-
-/**
- * Mixing ARB and NV vertex/fragment programs can be tricky.
- * Note: GL_VERTEX_PROGRAM_ARB == GL_VERTEX_PROGRAM_NV
- *  but, GL_FRAGMENT_PROGRAM_ARB != GL_FRAGMENT_PROGRAM_NV
- * The two different fragment program targets are supposed to be compatible
- * to some extent (see GL_ARB_fragment_program spec).
- * This function does the compatibility check.
- */
-static GLboolean
-compatible_program_targets(GLenum t1, GLenum t2)
-{
-   if (t1 == t2)
-      return GL_TRUE;
-   if (t1 == GL_FRAGMENT_PROGRAM_ARB && t2 == GL_FRAGMENT_PROGRAM_NV)
-      return GL_TRUE;
-   if (t1 == GL_FRAGMENT_PROGRAM_NV && t2 == GL_FRAGMENT_PROGRAM_ARB)
-      return GL_TRUE;
-   return GL_FALSE;
-}
-
-
-/**
- * Bind a program (make it current)
- * \note Called from the GL API dispatcher by both glBindProgramNV
- * and glBindProgramARB.
- */
-void GLAPIENTRY
-_mesa_BindProgram(GLenum target, GLuint id)
-{
-   struct gl_program *curProg, *newProg;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   /* Error-check target and get curProg */
-   if ((target == GL_VERTEX_PROGRAM_ARB) && /* == GL_VERTEX_PROGRAM_NV */
-        (ctx->Extensions.NV_vertex_program ||
-         ctx->Extensions.ARB_vertex_program)) {
-      curProg = &ctx->VertexProgram.Current->Base;
-   }
-   else if ((target == GL_FRAGMENT_PROGRAM_NV
-             && ctx->Extensions.NV_fragment_program) ||
-            (target == GL_FRAGMENT_PROGRAM_ARB
-             && ctx->Extensions.ARB_fragment_program)) {
-      curProg = &ctx->FragmentProgram.Current->Base;
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glBindProgramNV/ARB(target)");
-      return;
-   }
-
-   /*
-    * Get pointer to new program to bind.
-    * NOTE: binding to a non-existant program is not an error.
-    * That's supposed to be caught in glBegin.
-    */
-   if (id == 0) {
-      /* Bind a default program */
-      newProg = NULL;
-      if (target == GL_VERTEX_PROGRAM_ARB) /* == GL_VERTEX_PROGRAM_NV */
-         newProg = &ctx->Shared->DefaultVertexProgram->Base;
-      else
-         newProg = &ctx->Shared->DefaultFragmentProgram->Base;
-   }
-   else {
-      /* Bind a user program */
-      newProg = _mesa_lookup_program(ctx, id);
-      if (!newProg || newProg == &_mesa_DummyProgram) {
-         /* allocate a new program now */
-         newProg = ctx->Driver.NewProgram(ctx, target, id);
-         if (!newProg) {
-            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindProgramNV/ARB");
-            return;
-         }
-         _mesa_HashInsert(ctx->Shared->Programs, id, newProg);
-      }
-      else if (!compatible_program_targets(newProg->Target, target)) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glBindProgramNV/ARB(target mismatch)");
-         return;
-      }
-   }
-
-   /** All error checking is complete now **/
-
-   if (curProg->Id == id) {
-      /* binding same program - no change */
-      return;
-   }
-
-   /* signal new program (and its new constants) */
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
-
-   /* bind newProg */
-   if (target == GL_VERTEX_PROGRAM_ARB) { /* == GL_VERTEX_PROGRAM_NV */
-      _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
-                               (struct gl_vertex_program *) newProg);
-   }
-   else if (target == GL_FRAGMENT_PROGRAM_NV ||
-            target == GL_FRAGMENT_PROGRAM_ARB) {
-      _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
-                               (struct gl_fragment_program *) newProg);
-   }
-
-   /* Never null pointers */
-   ASSERT(ctx->VertexProgram.Current);
-   ASSERT(ctx->FragmentProgram.Current);
-
-   if (ctx->Driver.BindProgram)
-      ctx->Driver.BindProgram(ctx, target, newProg);
-}
-
-
-/**
- * Delete a list of programs.
- * \note Not compiled into display lists.
- * \note Called by both glDeleteProgramsNV and glDeleteProgramsARB.
- */
-void GLAPIENTRY 
-_mesa_DeletePrograms(GLsizei n, const GLuint *ids)
-{
-   GLint i;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
-   if (n < 0) {
-      _mesa_error( ctx, GL_INVALID_VALUE, "glDeleteProgramsNV" );
-      return;
-   }
-
-   for (i = 0; i < n; i++) {
-      if (ids[i] != 0) {
-         struct gl_program *prog = _mesa_lookup_program(ctx, ids[i]);
-         if (prog == &_mesa_DummyProgram) {
-            _mesa_HashRemove(ctx->Shared->Programs, ids[i]);
-         }
-         else if (prog) {
-            /* Unbind program if necessary */
-            switch (prog->Target) {
-            case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */
-            case GL_VERTEX_STATE_PROGRAM_NV:
-               if (ctx->VertexProgram.Current &&
-                   ctx->VertexProgram.Current->Base.Id == ids[i]) {
-                  /* unbind this currently bound program */
-                  _mesa_BindProgram(prog->Target, 0);
-               }
-               break;
-            case GL_FRAGMENT_PROGRAM_NV:
-            case GL_FRAGMENT_PROGRAM_ARB:
-               if (ctx->FragmentProgram.Current &&
-                   ctx->FragmentProgram.Current->Base.Id == ids[i]) {
-                  /* unbind this currently bound program */
-                  _mesa_BindProgram(prog->Target, 0);
-               }
-               break;
-            default:
-               _mesa_problem(ctx, "bad target in glDeleteProgramsNV");
-               return;
-            }
-            /* The ID is immediately available for re-use now */
-            _mesa_HashRemove(ctx->Shared->Programs, ids[i]);
-            _mesa_reference_program(ctx, &prog, NULL);
-         }
-      }
-   }
-}
-
-
-/**
- * Generate a list of new program identifiers.
- * \note Not compiled into display lists.
- * \note Called by both glGenProgramsNV and glGenProgramsARB.
- */
-void GLAPIENTRY
-_mesa_GenPrograms(GLsizei n, GLuint *ids)
-{
-   GLuint first;
-   GLuint i;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (n < 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGenPrograms");
-      return;
-   }
-
-   if (!ids)
-      return;
-
-   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->Programs, n);
-
-   /* Insert pointer to dummy program as placeholder */
-   for (i = 0; i < (GLuint) n; i++) {
-      _mesa_HashInsert(ctx->Shared->Programs, first + i, &_mesa_DummyProgram);
-   }
-
-   /* Return the program names */
-   for (i = 0; i < (GLuint) n; i++) {
-      ids[i] = first + i;
-   }
-}
-
-
-/**
- * Determine if id names a vertex or fragment program.
- * \note Not compiled into display lists.
- * \note Called from both glIsProgramNV and glIsProgramARB.
- * \param id is the program identifier
- * \return GL_TRUE if id is a program, else GL_FALSE.
- */
-GLboolean GLAPIENTRY
-_mesa_IsProgramARB(GLuint id)
-{
-   struct gl_program *prog = NULL; 
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
-
-   if (id == 0)
-      return GL_FALSE;
-
-   prog = _mesa_lookup_program(ctx, id);
-   if (prog && (prog != &_mesa_DummyProgram))
-      return GL_TRUE;
-   else
-      return GL_FALSE;
-}
-
-
-void GLAPIENTRY
-_mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
-                       const GLvoid *string)
-{
-   struct gl_program *base;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
-
-   if (!ctx->Extensions.ARB_vertex_program
-       && !ctx->Extensions.ARB_fragment_program) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramStringARB()");
-      return;
-   }
-
-   if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
-      return;
-   }
-
-   /* The first couple cases are complicated.  The same enum value is used for
-    * ARB and NV vertex programs.  If the target is a vertex program, parse it
-    * using the ARB grammar if the string starts with "!!ARB" or if
-    * NV_vertex_program is not supported.
-    */
-   if (target == GL_VERTEX_PROGRAM_ARB
-       && ctx->Extensions.ARB_vertex_program
-       && ((strncmp(string, "!!ARB", 5) == 0)
-          || !ctx->Extensions.NV_vertex_program)) {
-      struct gl_vertex_program *prog = ctx->VertexProgram.Current;
-      _mesa_parse_arb_vertex_program(ctx, target, string, len, prog);
-
-      base = & prog->Base;
-   }
-   else if ((target == GL_VERTEX_PROGRAM_ARB
-            || target == GL_VERTEX_STATE_PROGRAM_NV)
-           && ctx->Extensions.NV_vertex_program) {
-      struct gl_vertex_program *prog = ctx->VertexProgram.Current;
-      _mesa_parse_nv_vertex_program(ctx, target, string, len, prog);
-
-      base = & prog->Base;
-   }
-   else if (target == GL_FRAGMENT_PROGRAM_ARB
-            && ctx->Extensions.ARB_fragment_program) {
-      struct gl_fragment_program *prog = ctx->FragmentProgram.Current;
-      _mesa_parse_arb_fragment_program(ctx, target, string, len, prog);
-
-      base = & prog->Base;
-   }
-   else if (target == GL_FRAGMENT_PROGRAM_NV
-            && ctx->Extensions.NV_fragment_program) {
-      struct gl_fragment_program *prog = ctx->FragmentProgram.Current;
-      _mesa_parse_nv_fragment_program(ctx, target, string, len, prog);
-
-      base = & prog->Base;
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)");
-      return;
-   }
-
-   if (ctx->Program.ErrorPos == -1) {
-      /* finally, give the program to the driver for translation/checking */
-      if (!ctx->Driver.ProgramStringNotify(ctx, target, base)) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glProgramStringARB(rejected by driver");
-      }
-   }
-}
-
-
-/**
- * Set a program env parameter register.
- * \note Called from the GL API dispatcher.
- * Note, this function is also used by the GL_NV_vertex_program extension
- * (alias to ProgramParameterdNV)
- */
-void GLAPIENTRY
-_mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index,
-                               GLdouble x, GLdouble y, GLdouble z, GLdouble w)
-{
-   _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) x, (GLfloat) y, 
-                                 (GLfloat) z, (GLfloat) w);
-}
-
-
-/**
- * Set a program env parameter register.
- * \note Called from the GL API dispatcher.
- * Note, this function is also used by the GL_NV_vertex_program extension
- * (alias to ProgramParameterdvNV)
- */
-void GLAPIENTRY
-_mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
-                                const GLdouble *params)
-{
-   _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) params[0], 
-                                 (GLfloat) params[1], (GLfloat) params[2], 
-                                 (GLfloat) params[3]);
-}
-
-
-/**
- * Set a program env parameter register.
- * \note Called from the GL API dispatcher.
- * Note, this function is also used by the GL_NV_vertex_program extension
- * (alias to ProgramParameterfNV)
- */
-void GLAPIENTRY
-_mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
-                               GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
-
-   if (target == GL_FRAGMENT_PROGRAM_ARB
-       && ctx->Extensions.ARB_fragment_program) {
-      if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
-         return;
-      }
-      ASSIGN_4V(ctx->FragmentProgram.Parameters[index], x, y, z, w);
-   }
-   else if (target == GL_VERTEX_PROGRAM_ARB /* == GL_VERTEX_PROGRAM_NV */
-       && (ctx->Extensions.ARB_vertex_program || ctx->Extensions.NV_vertex_program)) {
-      if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
-         return;
-      }
-      ASSIGN_4V(ctx->VertexProgram.Parameters[index], x, y, z, w);
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)");
-      return;
-   }
-}
-
-
-
-/**
- * Set a program env parameter register.
- * \note Called from the GL API dispatcher.
- * Note, this function is also used by the GL_NV_vertex_program extension
- * (alias to ProgramParameterfvNV)
- */
-void GLAPIENTRY
-_mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
-                                const GLfloat *params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
-
-   if (target == GL_FRAGMENT_PROGRAM_ARB
-       && ctx->Extensions.ARB_fragment_program) {
-      if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter4fv(index)");
-         return;
-      }
-      memcpy(ctx->FragmentProgram.Parameters[index], params,
-             4 * sizeof(GLfloat));
-   }
-   else if (target == GL_VERTEX_PROGRAM_ARB /* == GL_VERTEX_PROGRAM_NV */
-       && (ctx->Extensions.ARB_vertex_program || ctx->Extensions.NV_vertex_program)) {
-      if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter4fv(index)");
-         return;
-      }
-      memcpy(ctx->VertexProgram.Parameters[index], params,
-             4 * sizeof(GLfloat));
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter4fv(target)");
-      return;
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
-                                const GLfloat *params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLfloat * dest;
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
-
-   if (count <= 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(count)");
-   }
-
-   if (target == GL_FRAGMENT_PROGRAM_ARB
-       && ctx->Extensions.ARB_fragment_program) {
-      if ((index + count) > ctx->Const.FragmentProgram.MaxEnvParams) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(index + count)");
-         return;
-      }
-      dest = ctx->FragmentProgram.Parameters[index];
-   }
-   else if (target == GL_VERTEX_PROGRAM_ARB
-       && ctx->Extensions.ARB_vertex_program) {
-      if ((index + count) > ctx->Const.VertexProgram.MaxEnvParams) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(index + count)");
-         return;
-      }
-      dest = ctx->VertexProgram.Parameters[index];
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameters4fv(target)");
-      return;
-   }
-
-   memcpy(dest, params, count * 4 * sizeof(GLfloat));
-}
-
-
-void GLAPIENTRY
-_mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index,
-                                  GLdouble *params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLfloat fparams[4];
-
-   _mesa_GetProgramEnvParameterfvARB(target, index, fparams);
-   if (ctx->ErrorValue == GL_NO_ERROR) {
-      params[0] = fparams[0];
-      params[1] = fparams[1];
-      params[2] = fparams[2];
-      params[3] = fparams[3];
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index, 
-                                  GLfloat *params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (target == GL_FRAGMENT_PROGRAM_ARB
-       && ctx->Extensions.ARB_fragment_program) {
-      if (index >= ctx->Const.FragmentProgram.MaxEnvParams) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
-         return;
-      }
-      COPY_4V(params, ctx->FragmentProgram.Parameters[index]);
-   }
-   else if (target == GL_VERTEX_PROGRAM_ARB
-       && ctx->Extensions.ARB_vertex_program) {
-      if (index >= ctx->Const.VertexProgram.MaxEnvParams) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
-         return;
-      }
-      COPY_4V(params, ctx->VertexProgram.Parameters[index]);
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)");
-      return;
-   }
-}
-
-
-/**
- * Note, this function is also used by the GL_NV_fragment_program extension.
- */
-void GLAPIENTRY
-_mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index,
-                                 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   struct gl_program *prog;
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
-
-   if ((target == GL_FRAGMENT_PROGRAM_NV
-        && ctx->Extensions.NV_fragment_program) ||
-       (target == GL_FRAGMENT_PROGRAM_ARB
-        && ctx->Extensions.ARB_fragment_program)) {
-      if (index >= ctx->Const.FragmentProgram.MaxLocalParams) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
-         return;
-      }
-      prog = &(ctx->FragmentProgram.Current->Base);
-   }
-   else if (target == GL_VERTEX_PROGRAM_ARB
-            && ctx->Extensions.ARB_vertex_program) {
-      if (index >= ctx->Const.VertexProgram.MaxLocalParams) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
-         return;
-      }
-      prog = &(ctx->VertexProgram.Current->Base);
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
-      return;
-   }
-
-   ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
-   prog->LocalParams[index][0] = x;
-   prog->LocalParams[index][1] = y;
-   prog->LocalParams[index][2] = z;
-   prog->LocalParams[index][3] = w;
-}
-
-
-/**
- * Note, this function is also used by the GL_NV_fragment_program extension.
- */
-void GLAPIENTRY
-_mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
-                                  const GLfloat *params)
-{
-   _mesa_ProgramLocalParameter4fARB(target, index, params[0], params[1],
-                                    params[2], params[3]);
-}
-
-
-void GLAPIENTRY
-_mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
-                                  const GLfloat *params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLfloat *dest;
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
-
-   if (count <= 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fv(count)");
-   }
-
-   if (target == GL_FRAGMENT_PROGRAM_ARB
-       && ctx->Extensions.ARB_fragment_program) {
-      if ((index + count) > ctx->Const.FragmentProgram.MaxLocalParams) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fvEXT(index + count)");
-         return;
-      }
-      dest = ctx->FragmentProgram.Current->Base.LocalParams[index];
-   }
-   else if (target == GL_VERTEX_PROGRAM_ARB
-            && ctx->Extensions.ARB_vertex_program) {
-      if ((index + count) > ctx->Const.VertexProgram.MaxLocalParams) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fvEXT(index + count)");
-         return;
-      }
-      dest = ctx->VertexProgram.Current->Base.LocalParams[index];
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameters4fvEXT(target)");
-      return;
-   }
-
-   memcpy(dest, params, count * 4 * sizeof(GLfloat));
-}
-
-
-/**
- * Note, this function is also used by the GL_NV_fragment_program extension.
- */
-void GLAPIENTRY
-_mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index,
-                                 GLdouble x, GLdouble y,
-                                 GLdouble z, GLdouble w)
-{
-   _mesa_ProgramLocalParameter4fARB(target, index, (GLfloat) x, (GLfloat) y, 
-                                    (GLfloat) z, (GLfloat) w);
-}
-
-
-/**
- * Note, this function is also used by the GL_NV_fragment_program extension.
- */
-void GLAPIENTRY
-_mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index,
-                                  const GLdouble *params)
-{
-   _mesa_ProgramLocalParameter4fARB(target, index,
-                                    (GLfloat) params[0], (GLfloat) params[1],
-                                    (GLfloat) params[2], (GLfloat) params[3]);
-}
-
-
-/**
- * Note, this function is also used by the GL_NV_fragment_program extension.
- */
-void GLAPIENTRY
-_mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index,
-                                    GLfloat *params)
-{
-   const struct gl_program *prog;
-   GLuint maxParams;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (target == GL_VERTEX_PROGRAM_ARB
-       && ctx->Extensions.ARB_vertex_program) {
-      prog = &(ctx->VertexProgram.Current->Base);
-      maxParams = ctx->Const.VertexProgram.MaxLocalParams;
-   }
-   else if (target == GL_FRAGMENT_PROGRAM_ARB
-            && ctx->Extensions.ARB_fragment_program) {
-      prog = &(ctx->FragmentProgram.Current->Base);
-      maxParams = ctx->Const.FragmentProgram.MaxLocalParams;
-   }
-   else if (target == GL_FRAGMENT_PROGRAM_NV
-            && ctx->Extensions.NV_fragment_program) {
-      prog = &(ctx->FragmentProgram.Current->Base);
-      maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM,
-                  "glGetProgramLocalParameterARB(target)");
-      return;
-   }
-
-   if (index >= maxParams) {
-      _mesa_error(ctx, GL_INVALID_VALUE,
-                  "glGetProgramLocalParameterARB(index)");
-      return;
-   }
-
-   ASSERT(prog);
-   ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
-   COPY_4V(params, prog->LocalParams[index]);
-}
-
-
-/**
- * Note, this function is also used by the GL_NV_fragment_program extension.
- */
-void GLAPIENTRY
-_mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index,
-                                    GLdouble *params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLfloat floatParams[4];
-   ASSIGN_4V(floatParams, 0.0F, 0.0F, 0.0F, 0.0F);
-   _mesa_GetProgramLocalParameterfvARB(target, index, floatParams);
-   if (ctx->ErrorValue == GL_NO_ERROR) {
-      COPY_4V(params, floatParams);
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
-{
-   const struct gl_program_constants *limits;
-   struct gl_program *prog;
-   GET_CURRENT_CONTEXT(ctx);
-
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (target == GL_VERTEX_PROGRAM_ARB
-       && ctx->Extensions.ARB_vertex_program) {
-      prog = &(ctx->VertexProgram.Current->Base);
-      limits = &ctx->Const.VertexProgram;
-   }
-   else if (target == GL_FRAGMENT_PROGRAM_ARB
-            && ctx->Extensions.ARB_fragment_program) {
-      prog = &(ctx->FragmentProgram.Current->Base);
-      limits = &ctx->Const.FragmentProgram;
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
-      return;
-   }
-
-   ASSERT(prog);
-   ASSERT(limits);
-
-   /* Queries supported for both vertex and fragment programs */
-   switch (pname) {
-      case GL_PROGRAM_LENGTH_ARB:
-         *params
-            = prog->String ? (GLint) strlen((char *) prog->String) : 0;
-         return;
-      case GL_PROGRAM_FORMAT_ARB:
-         *params = prog->Format;
-         return;
-      case GL_PROGRAM_BINDING_ARB:
-         *params = prog->Id;
-         return;
-      case GL_PROGRAM_INSTRUCTIONS_ARB:
-         *params = prog->NumInstructions;
-         return;
-      case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
-         *params = limits->MaxInstructions;
-         return;
-      case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
-         *params = prog->NumNativeInstructions;
-         return;
-      case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
-         *params = limits->MaxNativeInstructions;
-         return;
-      case GL_PROGRAM_TEMPORARIES_ARB:
-         *params = prog->NumTemporaries;
-         return;
-      case GL_MAX_PROGRAM_TEMPORARIES_ARB:
-         *params = limits->MaxTemps;
-         return;
-      case GL_PROGRAM_NATIVE_TEMPORARIES_ARB:
-         *params = prog->NumNativeTemporaries;
-         return;
-      case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
-         *params = limits->MaxNativeTemps;
-         return;
-      case GL_PROGRAM_PARAMETERS_ARB:
-         *params = prog->NumParameters;
-         return;
-      case GL_MAX_PROGRAM_PARAMETERS_ARB:
-         *params = limits->MaxParameters;
-         return;
-      case GL_PROGRAM_NATIVE_PARAMETERS_ARB:
-         *params = prog->NumNativeParameters;
-         return;
-      case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
-         *params = limits->MaxNativeParameters;
-         return;
-      case GL_PROGRAM_ATTRIBS_ARB:
-         *params = prog->NumAttributes;
-         return;
-      case GL_MAX_PROGRAM_ATTRIBS_ARB:
-         *params = limits->MaxAttribs;
-         return;
-      case GL_PROGRAM_NATIVE_ATTRIBS_ARB:
-         *params = prog->NumNativeAttributes;
-         return;
-      case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
-         *params = limits->MaxNativeAttribs;
-         return;
-      case GL_PROGRAM_ADDRESS_REGISTERS_ARB:
-         *params = prog->NumAddressRegs;
-         return;
-      case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
-         *params = limits->MaxAddressRegs;
-         return;
-      case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
-         *params = prog->NumNativeAddressRegs;
-         return;
-      case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
-         *params = limits->MaxNativeAddressRegs;
-         return;
-      case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
-         *params = limits->MaxLocalParams;
-         return;
-      case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
-         *params = limits->MaxEnvParams;
-         return;
-      case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB:
-         /*
-          * XXX we may not really need a driver callback here.
-          * If the number of native instructions, registers, etc. used
-          * are all below the maximums, we could return true.
-          * The spec says that even if this query returns true, there's
-          * no guarantee that the program will run in hardware.
-          */
-         if (prog->Id == 0) {
-            /* default/null program */
-            *params = GL_FALSE;
-         }
-        else if (ctx->Driver.IsProgramNative) {
-            /* ask the driver */
-           *params = ctx->Driver.IsProgramNative( ctx, target, prog );
-         }
-        else {
-            /* probably running in software */
-           *params = GL_TRUE;
-         }
-         return;
-      default:
-         /* continue with fragment-program only queries below */
-         break;
-   }
-
-   /*
-    * The following apply to fragment programs only (at this time)
-    */
-   if (target == GL_FRAGMENT_PROGRAM_ARB) {
-      const struct gl_fragment_program *fp = ctx->FragmentProgram.Current;
-      switch (pname) {
-         case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
-            *params = fp->Base.NumNativeAluInstructions;
-            return;
-         case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
-            *params = fp->Base.NumAluInstructions;
-            return;
-         case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
-            *params = fp->Base.NumTexInstructions;
-            return;
-         case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
-            *params = fp->Base.NumNativeTexInstructions;
-            return;
-         case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
-            *params = fp->Base.NumTexIndirections;
-            return;
-         case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
-            *params = fp->Base.NumNativeTexIndirections;
-            return;
-         case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
-            *params = limits->MaxAluInstructions;
-            return;
-         case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
-            *params = limits->MaxNativeAluInstructions;
-            return;
-         case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
-            *params = limits->MaxTexInstructions;
-            return;
-         case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
-            *params = limits->MaxNativeTexInstructions;
-            return;
-         case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB:
-            *params = limits->MaxTexIndirections;
-            return;
-         case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
-            *params = limits->MaxNativeTexIndirections;
-            return;
-         default:
-            _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
-            return;
-      }
-   } else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
-      return;
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string)
-{
-   const struct gl_program *prog;
-   char *dst = (char *) string;
-   GET_CURRENT_CONTEXT(ctx);
-
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (target == GL_VERTEX_PROGRAM_ARB) {
-      prog = &(ctx->VertexProgram.Current->Base);
-   }
-   else if (target == GL_FRAGMENT_PROGRAM_ARB) {
-      prog = &(ctx->FragmentProgram.Current->Base);
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)");
-      return;
-   }
-
-   ASSERT(prog);
-
-   if (pname != GL_PROGRAM_STRING_ARB) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)");
-      return;
-   }
-
-   if (prog->String)
-      memcpy(dst, prog->String, strlen((char *) prog->String));
-   else
-      *dst = '\0';
-}
diff --git a/src/mesa/shader/arbprogram.h b/src/mesa/shader/arbprogram.h
deleted file mode 100644 (file)
index df16513..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.2
- *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#ifndef ARBPROGRAM_H
-#define ARBPROGRAM_H
-
-
-extern void GLAPIENTRY
-_mesa_BindProgram(GLenum target, GLuint id);
-
-extern void GLAPIENTRY
-_mesa_DeletePrograms(GLsizei n, const GLuint *ids);
-
-extern void GLAPIENTRY
-_mesa_GenPrograms(GLsizei n, GLuint *ids);
-
-
-extern GLboolean GLAPIENTRY
-_mesa_IsProgramARB(GLuint id);
-
-
-extern void GLAPIENTRY
-_mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
-                       const GLvoid *string);
-
-
-extern void GLAPIENTRY
-_mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index,
-                               GLdouble x, GLdouble y, GLdouble z, GLdouble w);
-
-
-extern void GLAPIENTRY
-_mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
-                                const GLdouble *params);
-
-
-extern void GLAPIENTRY
-_mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
-                               GLfloat x, GLfloat y, GLfloat z, GLfloat w);
-
-
-extern void GLAPIENTRY
-_mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
-                                const GLfloat *params);
-
-
-extern void GLAPIENTRY
-_mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
-                                const GLfloat *params);
-
-
-extern void GLAPIENTRY
-_mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index,
-                                 GLdouble x, GLdouble y,
-                                 GLdouble z, GLdouble w);
-
-
-extern void GLAPIENTRY
-_mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index,
-                                  const GLdouble *params);
-
-
-extern void GLAPIENTRY
-_mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index,
-                                 GLfloat x, GLfloat y, GLfloat z, GLfloat w);
-
-
-extern void GLAPIENTRY
-_mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
-                                  const GLfloat *params);
-
-
-extern void GLAPIENTRY
-_mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count,
-                                  const GLfloat *params);
-
-
-extern void GLAPIENTRY
-_mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index,
-                                  GLdouble *params);
-
-
-extern void GLAPIENTRY
-_mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index, 
-                                  GLfloat *params);
-
-
-extern void GLAPIENTRY
-_mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index,
-                                    GLdouble *params);
-
-
-extern void GLAPIENTRY
-_mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index, 
-                                    GLfloat *params);
-
-
-extern void GLAPIENTRY
-_mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params);
-
-
-extern void GLAPIENTRY
-_mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string);
-
-
-#endif
diff --git a/src/mesa/shader/atifragshader.c b/src/mesa/shader/atifragshader.c
deleted file mode 100644 (file)
index 21bb958..0000000
+++ /dev/null
@@ -1,794 +0,0 @@
-/**
- * \file atifragshader.c
- * \author David Airlie
- * Copyright (C) 2004  David Airlie   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and 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
- * DAVID AIRLIE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION 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/context.h"
-#include "main/hash.h"
-#include "main/imports.h"
-#include "main/macros.h"
-#include "main/enums.h"
-#include "main/mtypes.h"
-#include "main/dispatch.h"
-#include "atifragshader.h"
-
-#if FEATURE_ATI_fragment_shader
-
-#define MESA_DEBUG_ATI_FS 0
-
-static struct ati_fragment_shader DummyShader;
-
-
-void
-_mesa_init_ati_fragment_shader_dispatch(struct _glapi_table *disp)
-{
-   SET_GenFragmentShadersATI(disp, _mesa_GenFragmentShadersATI);
-   SET_BindFragmentShaderATI(disp, _mesa_BindFragmentShaderATI);
-   SET_DeleteFragmentShaderATI(disp, _mesa_DeleteFragmentShaderATI);
-   SET_BeginFragmentShaderATI(disp, _mesa_BeginFragmentShaderATI);
-   SET_EndFragmentShaderATI(disp, _mesa_EndFragmentShaderATI);
-   SET_PassTexCoordATI(disp, _mesa_PassTexCoordATI);
-   SET_SampleMapATI(disp, _mesa_SampleMapATI);
-   SET_ColorFragmentOp1ATI(disp, _mesa_ColorFragmentOp1ATI);
-   SET_ColorFragmentOp2ATI(disp, _mesa_ColorFragmentOp2ATI);
-   SET_ColorFragmentOp3ATI(disp, _mesa_ColorFragmentOp3ATI);
-   SET_AlphaFragmentOp1ATI(disp, _mesa_AlphaFragmentOp1ATI);
-   SET_AlphaFragmentOp2ATI(disp, _mesa_AlphaFragmentOp2ATI);
-   SET_AlphaFragmentOp3ATI(disp, _mesa_AlphaFragmentOp3ATI);
-   SET_SetFragmentShaderConstantATI(disp, _mesa_SetFragmentShaderConstantATI);
-}
-
-
-/**
- * Allocate and initialize a new ATI fragment shader object.
- */
-struct ati_fragment_shader *
-_mesa_new_ati_fragment_shader(GLcontext *ctx, GLuint id)
-{
-   struct ati_fragment_shader *s = CALLOC_STRUCT(ati_fragment_shader);
-   (void) ctx;
-   if (s) {
-      s->Id = id;
-      s->RefCount = 1;
-   }
-   return s;
-}
-
-
-/**
- * Delete the given ati fragment shader
- */
-void
-_mesa_delete_ati_fragment_shader(GLcontext *ctx, struct ati_fragment_shader *s)
-{
-   GLuint i;
-   for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {
-      if (s->Instructions[i])
-         free(s->Instructions[i]);
-      if (s->SetupInst[i])
-         free(s->SetupInst[i]);
-   }
-   free(s);
-}
-
-
-
-static void
-new_arith_inst(struct ati_fragment_shader *prog)
-{
-/* set "default" instruction as not all may get defined.
-   there is no specified way to express a nop with ati fragment shaders we use
-   GL_NONE as the op enum and just set some params to 0 - so nothing to do here */
-   prog->numArithInstr[prog->cur_pass >> 1]++;
-}
-
-static void
-new_tex_inst(struct ati_fragment_shader *prog)
-{
-}
-
-static void match_pair_inst(struct ati_fragment_shader *curProg, GLuint optype)
-{
-   if (optype == curProg->last_optype) {
-      curProg->last_optype = 1;
-   }
-}
-
-#if MESA_DEBUG_ATI_FS
-static char *
-create_dst_mod_str(GLuint mod)
-{
-   static char ret_str[1024];
-
-   memset(ret_str, 0, 1024);
-   if (mod & GL_2X_BIT_ATI)
-      strncat(ret_str, "|2X", 1024);
-
-   if (mod & GL_4X_BIT_ATI)
-      strncat(ret_str, "|4X", 1024);
-
-   if (mod & GL_8X_BIT_ATI)
-      strncat(ret_str, "|8X", 1024);
-   if (mod & GL_HALF_BIT_ATI)
-      strncat(ret_str, "|HA", 1024);
-   if (mod & GL_QUARTER_BIT_ATI)
-      strncat(ret_str, "|QU", 1024);
-   if (mod & GL_EIGHTH_BIT_ATI)
-      strncat(ret_str, "|EI", 1024);
-
-   if (mod & GL_SATURATE_BIT_ATI)
-      strncat(ret_str, "|SAT", 1024);
-
-   if (strlen(ret_str) == 0)
-      strncat(ret_str, "NONE", 1024);
-   return ret_str;
-}
-
-static char *atifs_ops[] = {"ColorFragmentOp1ATI", "ColorFragmentOp2ATI", "ColorFragmentOp3ATI", 
-                           "AlphaFragmentOp1ATI", "AlphaFragmentOp2ATI", "AlphaFragmentOp3ATI" };
-
-static void debug_op(GLint optype, GLuint arg_count, GLenum op, GLuint dst,
-                    GLuint dstMask, GLuint dstMod, GLuint arg1,
-                    GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
-                    GLuint arg2Rep, GLuint arg2Mod, GLuint arg3,
-                    GLuint arg3Rep, GLuint arg3Mod)
-{
-  char *op_name;
-
-  op_name = atifs_ops[(arg_count-1)+(optype?3:0)];
-  
-  fprintf(stderr, "%s(%s, %s", op_name, _mesa_lookup_enum_by_nr(op),
-             _mesa_lookup_enum_by_nr(dst));
-  if (!optype)
-    fprintf(stderr, ", %d", dstMask);
-  
-  fprintf(stderr, ", %s", create_dst_mod_str(dstMod));
-  
-  fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg1),
-             _mesa_lookup_enum_by_nr(arg1Rep), arg1Mod);
-  if (arg_count>1)
-    fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg2),
-             _mesa_lookup_enum_by_nr(arg2Rep), arg2Mod);
-  if (arg_count>2)
-    fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg3),
-             _mesa_lookup_enum_by_nr(arg3Rep), arg3Mod);
-
-  fprintf(stderr,")\n");
-
-}
-#endif
-
-static int check_arith_arg(struct ati_fragment_shader *curProg,
-                       GLuint optype, GLuint arg, GLuint argRep)
-{
-   GET_CURRENT_CONTEXT(ctx);
-
-   if (((arg < GL_CON_0_ATI) || (arg > GL_CON_7_ATI)) &&
-      ((arg < GL_REG_0_ATI) || (arg > GL_REG_5_ATI)) &&
-      (arg != GL_ZERO) && (arg != GL_ONE) &&
-      (arg != GL_PRIMARY_COLOR_ARB) && (arg != GL_SECONDARY_INTERPOLATOR_ATI)) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(arg)");
-      return 0;
-   }
-   if ((arg == GL_SECONDARY_INTERPOLATOR_ATI) && (((optype == 0) && (argRep == GL_ALPHA)) ||
-      ((optype == 1) && ((arg == GL_ALPHA) || (argRep == GL_NONE))))) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)");
-      return 0;
-   }
-   if ((arg == GL_SECONDARY_INTERPOLATOR_ATI) && (((optype == 0) && (argRep == GL_ALPHA)) ||
-      ((optype == 1) && ((arg == GL_ALPHA) || (argRep == GL_NONE))))) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)");
-      return 0;
-   }
-   if ((curProg->cur_pass == 1) &&
-      ((arg == GL_PRIMARY_COLOR_ARB) || (arg == GL_SECONDARY_INTERPOLATOR_ATI))) {
-      curProg->interpinp1 = GL_TRUE;
-   }
-   return 1;
-}
-
-GLuint GLAPIENTRY
-_mesa_GenFragmentShadersATI(GLuint range)
-{
-   GLuint first;
-   GLuint i;
-   GET_CURRENT_CONTEXT(ctx);
-
-   if (range == 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGenFragmentShadersATI(range)");
-      return 0;
-   }
-
-   if (ctx->ATIFragmentShader.Compiling) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGenFragmentShadersATI(insideShader)");
-      return 0;
-   }
-
-   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->ATIShaders, range);
-   for (i = 0; i < range; i++) {
-      _mesa_HashInsert(ctx->Shared->ATIShaders, first + i, &DummyShader);
-   }
-
-   return first;
-}
-
-void GLAPIENTRY
-_mesa_BindFragmentShaderATI(GLuint id)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
-   struct ati_fragment_shader *newProg;
-
-   if (ctx->ATIFragmentShader.Compiling) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glBindFragmentShaderATI(insideShader)");
-      return;
-   }
-
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
-
-   if (curProg->Id == id) {
-      return;
-   }
-
-   /* unbind current */
-   if (curProg->Id != 0) {
-      curProg->RefCount--;
-      if (curProg->RefCount <= 0) {
-        _mesa_HashRemove(ctx->Shared->ATIShaders, id);
-      }
-   }
-
-   /* find new shader */
-   if (id == 0) {
-      newProg = ctx->Shared->DefaultFragmentShader;
-   }
-   else {
-      newProg = (struct ati_fragment_shader *)
-         _mesa_HashLookup(ctx->Shared->ATIShaders, id);
-      if (!newProg || newProg == &DummyShader) {
-        /* allocate a new program now */
-        newProg = _mesa_new_ati_fragment_shader(ctx, id);
-        if (!newProg) {
-           _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFragmentShaderATI");
-           return;
-        }
-        _mesa_HashInsert(ctx->Shared->ATIShaders, id, newProg);
-      }
-
-   }
-
-   /* do actual bind */
-   ctx->ATIFragmentShader.Current = newProg;
-
-   ASSERT(ctx->ATIFragmentShader.Current);
-   if (newProg)
-      newProg->RefCount++;
-
-   /*if (ctx->Driver.BindProgram)
-      ctx->Driver.BindProgram(ctx, target, prog); */
-}
-
-void GLAPIENTRY
-_mesa_DeleteFragmentShaderATI(GLuint id)
-{
-   GET_CURRENT_CONTEXT(ctx);
-
-   if (ctx->ATIFragmentShader.Compiling) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteFragmentShaderATI(insideShader)");
-      return;
-   }
-
-   if (id != 0) {
-      struct ati_fragment_shader *prog = (struct ati_fragment_shader *)
-        _mesa_HashLookup(ctx->Shared->ATIShaders, id);
-      if (prog == &DummyShader) {
-        _mesa_HashRemove(ctx->Shared->ATIShaders, id);
-      }
-      else if (prog) {
-        if (ctx->ATIFragmentShader.Current &&
-            ctx->ATIFragmentShader.Current->Id == id) {
-            FLUSH_VERTICES(ctx, _NEW_PROGRAM);
-           _mesa_BindFragmentShaderATI(0);
-        }
-      }
-
-      /* The ID is immediately available for re-use now */
-      _mesa_HashRemove(ctx->Shared->ATIShaders, id);
-      if (prog) {
-        prog->RefCount--;
-        if (prog->RefCount <= 0) {
-           free(prog);
-        }
-      }
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_BeginFragmentShaderATI(void)
-{
-   GLint i;
-   GET_CURRENT_CONTEXT(ctx);
-
-   if (ctx->ATIFragmentShader.Compiling) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginFragmentShaderATI(insideShader)");
-      return;
-   }
-
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
-
-   /* if the shader was already defined free instructions and get new ones
-      (or, could use the same mem but would need to reinitialize) */
-   /* no idea if it's allowed to redefine a shader */
-   for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {
-         if (ctx->ATIFragmentShader.Current->Instructions[i])
-            free(ctx->ATIFragmentShader.Current->Instructions[i]);
-         if (ctx->ATIFragmentShader.Current->SetupInst[i])
-            free(ctx->ATIFragmentShader.Current->SetupInst[i]);
-   }
-
-   /* malloc the instructions here - not sure if the best place but its
-      a start */
-   for (i = 0; i < MAX_NUM_PASSES_ATI; i++) {
-      ctx->ATIFragmentShader.Current->Instructions[i] =
-        (struct atifs_instruction *)
-        calloc(1, sizeof(struct atifs_instruction) *
-                  (MAX_NUM_INSTRUCTIONS_PER_PASS_ATI));
-      ctx->ATIFragmentShader.Current->SetupInst[i] =
-        (struct atifs_setupinst *)
-        calloc(1, sizeof(struct atifs_setupinst) *
-                  (MAX_NUM_FRAGMENT_REGISTERS_ATI));
-   }
-
-/* can't rely on calloc for initialization as it's possible to redefine a shader (?) */
-   ctx->ATIFragmentShader.Current->LocalConstDef = 0;
-   ctx->ATIFragmentShader.Current->numArithInstr[0] = 0;
-   ctx->ATIFragmentShader.Current->numArithInstr[1] = 0;
-   ctx->ATIFragmentShader.Current->regsAssigned[0] = 0;
-   ctx->ATIFragmentShader.Current->regsAssigned[1] = 0;
-   ctx->ATIFragmentShader.Current->NumPasses = 0;
-   ctx->ATIFragmentShader.Current->cur_pass = 0;
-   ctx->ATIFragmentShader.Current->last_optype = 0;
-   ctx->ATIFragmentShader.Current->interpinp1 = GL_FALSE;
-   ctx->ATIFragmentShader.Current->isValid = GL_FALSE;
-   ctx->ATIFragmentShader.Current->swizzlerq = 0;
-   ctx->ATIFragmentShader.Compiling = 1;
-}
-
-void GLAPIENTRY
-_mesa_EndFragmentShaderATI(void)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
-#if MESA_DEBUG_ATI_FS
-   GLint i, j;
-#endif
-
-   if (!ctx->ATIFragmentShader.Compiling) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(outsideShader)");
-      return;
-   }
-   if (curProg->interpinp1 && (ctx->ATIFragmentShader.Current->cur_pass > 1)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(interpinfirstpass)");
-   /* according to spec, DON'T return here */
-   }
-
-   match_pair_inst(curProg, 0);
-   ctx->ATIFragmentShader.Compiling = 0;
-   ctx->ATIFragmentShader.Current->isValid = GL_TRUE;
-   if ((ctx->ATIFragmentShader.Current->cur_pass == 0) ||
-      (ctx->ATIFragmentShader.Current->cur_pass == 2)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(noarithinst)");
-   }
-   if (ctx->ATIFragmentShader.Current->cur_pass > 1)
-      ctx->ATIFragmentShader.Current->NumPasses = 2;
-   else
-      ctx->ATIFragmentShader.Current->NumPasses = 1;
-
-   ctx->ATIFragmentShader.Current->cur_pass = 0;
-
-#if MESA_DEBUG_ATI_FS
-   for (j = 0; j < MAX_NUM_PASSES_ATI; j++) {
-      for (i = 0; i < MAX_NUM_FRAGMENT_REGISTERS_ATI; i++) {
-        GLuint op = curProg->SetupInst[j][i].Opcode;
-        const char *op_enum = op > 5 ? _mesa_lookup_enum_by_nr(op) : "0";
-        GLuint src = curProg->SetupInst[j][i].src;
-        GLuint swizzle = curProg->SetupInst[j][i].swizzle;
-        fprintf(stderr, "%2d %04X %s %d %04X\n", i, op, op_enum, src,
-             swizzle);
-      }
-      for (i = 0; i < curProg->numArithInstr[j]; i++) {
-        GLuint op0 = curProg->Instructions[j][i].Opcode[0];
-        GLuint op1 = curProg->Instructions[j][i].Opcode[1];
-        const char *op0_enum = op0 > 5 ? _mesa_lookup_enum_by_nr(op0) : "0";
-        const char *op1_enum = op1 > 5 ? _mesa_lookup_enum_by_nr(op1) : "0";
-        GLuint count0 = curProg->Instructions[j][i].ArgCount[0];
-        GLuint count1 = curProg->Instructions[j][i].ArgCount[1];
-        fprintf(stderr, "%2d %04X %s %d %04X %s %d\n", i, op0, op0_enum, count0,
-             op1, op1_enum, count1);
-      }
-   }
-#endif
-
-   if (!ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_SHADER_ATI, NULL)) {
-      ctx->ATIFragmentShader.Current->isValid = GL_FALSE;
-      /* XXX is this the right error? */
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glEndFragmentShaderATI(driver rejected shader)");
-   }
-}
-
-void GLAPIENTRY
-_mesa_PassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
-   struct atifs_setupinst *curI;
-
-   if (!ctx->ATIFragmentShader.Compiling) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(outsideShader)");
-      return;
-   }
-
-   if (curProg->cur_pass == 1) {
-      match_pair_inst(curProg, 0);
-      curProg->cur_pass = 2;
-   }
-   if ((curProg->cur_pass > 2) ||
-      ((1 << (dst - GL_REG_0_ATI)) & curProg->regsAssigned[curProg->cur_pass >> 1])) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoord(pass)");
-      return;
-   }
-   if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI) ||
-      ((dst - GL_REG_0_ATI) >= ctx->Const.MaxTextureUnits)) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(dst)");
-      return;
-   }
-   if (((coord < GL_REG_0_ATI) || (coord > GL_REG_5_ATI)) &&
-       ((coord < GL_TEXTURE0_ARB) || (coord > GL_TEXTURE7_ARB) ||
-       ((coord - GL_TEXTURE0_ARB) >= ctx->Const.MaxTextureUnits))) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(coord)");
-      return;
-   }
-   if ((curProg->cur_pass == 0) && (coord >= GL_REG_0_ATI)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(coord)");
-      return;
-   }
-   if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= GL_SWIZZLE_STQ_DQ_ATI)) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(swizzle)");
-      return;
-   }
-   if ((swizzle & 1) && (coord >= GL_REG_0_ATI)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(swizzle)");
-      return;
-   }
-   if (coord <= GL_TEXTURE7_ARB) {
-      GLuint tmp = coord - GL_TEXTURE0_ARB;
-      if ((((curProg->swizzlerq >> (tmp * 2)) & 3) != 0) &&
-          (((swizzle & 1) + 1) != ((curProg->swizzlerq >> (tmp * 2)) & 3))) {
-        _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(swizzle)");
-        return;
-      } else {
-        curProg->swizzlerq |= (((swizzle & 1) + 1) << (tmp * 2));
-      }
-   }
-
-   curProg->regsAssigned[curProg->cur_pass >> 1] |=  1 << (dst - GL_REG_0_ATI);
-   new_tex_inst(curProg);
-
-   /* add the instructions */
-   curI = &curProg->SetupInst[curProg->cur_pass >> 1][dst - GL_REG_0_ATI];
-
-   curI->Opcode = ATI_FRAGMENT_SHADER_PASS_OP;
-   curI->src = coord;
-   curI->swizzle = swizzle;
-
-#if MESA_DEBUG_ATI_FS
-   _mesa_debug(ctx, "%s(%s, %s, %s)\n", __FUNCTION__,
-              _mesa_lookup_enum_by_nr(dst), _mesa_lookup_enum_by_nr(coord),
-              _mesa_lookup_enum_by_nr(swizzle));
-#endif
-}
-
-void GLAPIENTRY
-_mesa_SampleMapATI(GLuint dst, GLuint interp, GLenum swizzle)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
-   struct atifs_setupinst *curI;
-
-   if (!ctx->ATIFragmentShader.Compiling) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(outsideShader)");
-      return;
-   }
-
-   if (curProg->cur_pass == 1) {
-      match_pair_inst(curProg, 0);
-      curProg->cur_pass = 2;
-   }
-   if ((curProg->cur_pass > 2) ||
-      ((1 << (dst - GL_REG_0_ATI)) & curProg->regsAssigned[curProg->cur_pass >> 1])) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(pass)");
-      return;
-   }
-   if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI) ||
-      ((dst - GL_REG_0_ATI) >= ctx->Const.MaxTextureUnits)) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(dst)");
-      return;
-   }
-   if (((interp < GL_REG_0_ATI) || (interp > GL_REG_5_ATI)) &&
-       ((interp < GL_TEXTURE0_ARB) || (interp > GL_TEXTURE7_ARB) ||
-       ((interp - GL_TEXTURE0_ARB) >= ctx->Const.MaxTextureUnits))) {
-   /* is this texture5 or texture7? spec is a bit unclear there */
-      _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(interp)");
-      return;
-   }
-   if ((curProg->cur_pass == 0) && (interp >= GL_REG_0_ATI)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(interp)");
-      return;
-   }
-   if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= GL_SWIZZLE_STQ_DQ_ATI)) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(swizzle)");
-      return;
-   }
-   if ((swizzle & 1) && (interp >= GL_REG_0_ATI)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(swizzle)");
-      return;
-   }
-   if (interp <= GL_TEXTURE7_ARB) {
-      GLuint tmp = interp - GL_TEXTURE0_ARB;
-      if ((((curProg->swizzlerq >> (tmp * 2)) & 3) != 0) &&
-          (((swizzle & 1) + 1) != ((curProg->swizzlerq >> (tmp * 2)) & 3))) {
-        _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(swizzle)");
-        return;
-      } else {
-        curProg->swizzlerq |= (((swizzle & 1) + 1) << (tmp * 2));
-      }
-   }
-
-   curProg->regsAssigned[curProg->cur_pass >> 1] |=  1 << (dst - GL_REG_0_ATI);
-   new_tex_inst(curProg);
-
-   /* add the instructions */
-   curI = &curProg->SetupInst[curProg->cur_pass >> 1][dst - GL_REG_0_ATI];
-
-   curI->Opcode = ATI_FRAGMENT_SHADER_SAMPLE_OP;
-   curI->src = interp;
-   curI->swizzle = swizzle;
-
-#if MESA_DEBUG_ATI_FS
-   _mesa_debug(ctx, "%s(%s, %s, %s)\n", __FUNCTION__,
-              _mesa_lookup_enum_by_nr(dst), _mesa_lookup_enum_by_nr(interp),
-              _mesa_lookup_enum_by_nr(swizzle));
-#endif
-}
-
-static void
-_mesa_FragmentOpXATI(GLint optype, GLuint arg_count, GLenum op, GLuint dst,
-                    GLuint dstMask, GLuint dstMod, GLuint arg1,
-                    GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
-                    GLuint arg2Rep, GLuint arg2Mod, GLuint arg3,
-                    GLuint arg3Rep, GLuint arg3Mod)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
-   GLint ci;
-   struct atifs_instruction *curI;
-   GLuint modtemp = dstMod & ~GL_SATURATE_BIT_ATI;
-
-   if (!ctx->ATIFragmentShader.Compiling) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(outsideShader)");
-      return;
-   }
-
-   if (curProg->cur_pass==0)
-      curProg->cur_pass=1;
-
-   else if (curProg->cur_pass==2)
-      curProg->cur_pass=3;
-
-   /* decide whether this is a new instruction or not ... all color instructions are new,
-      and alpha instructions might also be new if there was no preceding color inst */
-   if ((optype == 0) || (curProg->last_optype == optype)) {
-      if (curProg->numArithInstr[curProg->cur_pass >> 1] > 7) {
-        _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(instrCount)");
-        return;
-      }
-      /* easier to do that here slight side effect invalid instr will still be inserted as nops */
-      match_pair_inst(curProg, optype);
-      new_arith_inst(curProg);
-   }
-   curProg->last_optype = optype;
-   ci = curProg->numArithInstr[curProg->cur_pass >> 1] - 1;
-
-   /* add the instructions */
-   curI = &curProg->Instructions[curProg->cur_pass >> 1][ci];
-
-   /* error checking */
-   if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI)) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(dst)");
-      return;
-   }
-   if ((modtemp != GL_NONE) && (modtemp != GL_2X_BIT_ATI) &&
-      (modtemp != GL_4X_BIT_ATI) && (modtemp != GL_8X_BIT_ATI) &&
-      (modtemp != GL_HALF_BIT_ATI) && !(modtemp != GL_QUARTER_BIT_ATI) &&
-      (modtemp != GL_EIGHTH_BIT_ATI)) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(dstMod)%x", modtemp);
-      return;
-   }
-   /* op checking? Actually looks like that's missing in the spec but we'll do it anyway */
-   if (((op < GL_ADD_ATI) || (op > GL_DOT2_ADD_ATI)) && !(op == GL_MOV_ATI)) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(op)");
-      return;
-   }
-   if (optype == 1) {
-      if (((op == GL_DOT2_ADD_ATI) && (curI->Opcode[0] != GL_DOT2_ADD_ATI)) ||
-        ((op == GL_DOT3_ATI) && (curI->Opcode[0] != GL_DOT3_ATI)) ||
-        ((op == GL_DOT4_ATI) && (curI->Opcode[0] != GL_DOT4_ATI)) ||
-        ((op != GL_DOT4_ATI) && (curI->Opcode[0] == GL_DOT4_ATI))) {
-        _mesa_error(ctx, GL_INVALID_OPERATION, "AFragmentOpATI(op)");
-        return;
-      }
-   }
-   if ((op == GL_DOT4_ATI) &&
-      (((arg1 == GL_SECONDARY_INTERPOLATOR_ATI) && ((arg1Rep == GL_ALPHA) || (arg1Rep == GL_NONE))) ||
-      (((arg2 == GL_SECONDARY_INTERPOLATOR_ATI) && ((arg2Rep == GL_ALPHA) || (arg2Rep == GL_NONE)))))) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)");
-   }
-
-   if (!check_arith_arg(curProg, optype, arg1, arg1Rep)) {
-      return;
-   }
-   if (arg2) {
-      if (!check_arith_arg(curProg, optype, arg2, arg2Rep)) {
-        return;
-      }
-   }
-   if (arg3) {
-      if (!check_arith_arg(curProg, optype, arg3, arg3Rep)) {
-        return;
-      }
-      if ((arg1 >= GL_CON_0_ATI) && (arg1 <= GL_CON_7_ATI) &&
-         (arg2 >= GL_CON_0_ATI) && (arg2 <= GL_CON_7_ATI) &&
-         (arg3 >= GL_CON_0_ATI) && (arg3 <= GL_CON_7_ATI) &&
-         (arg1 != arg2) && (arg1 != arg3) && (arg2 != arg3)) {
-        _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(3Consts)");
-        return;
-      }
-   }
-
-   /* all ok - not all fully validated though (e.g. argNMod - spec doesn't say anything) */
-
-   curI->Opcode[optype] = op;
-   curI->SrcReg[optype][0].Index = arg1;
-   curI->SrcReg[optype][0].argRep = arg1Rep;
-   curI->SrcReg[optype][0].argMod = arg1Mod;
-   curI->ArgCount[optype] = arg_count;
-
-   if (arg2) {
-      curI->SrcReg[optype][1].Index = arg2;
-      curI->SrcReg[optype][1].argRep = arg2Rep;
-      curI->SrcReg[optype][1].argMod = arg2Mod;
-   }
-
-   if (arg3) {
-      curI->SrcReg[optype][2].Index = arg3;
-      curI->SrcReg[optype][2].argRep = arg3Rep;
-      curI->SrcReg[optype][2].argMod = arg3Mod;
-   }
-
-   curI->DstReg[optype].Index = dst;
-   curI->DstReg[optype].dstMod = dstMod;
-   curI->DstReg[optype].dstMask = dstMask;
-
-#if MESA_DEBUG_ATI_FS
-   debug_op(optype, arg_count, op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3, arg3Rep, arg3Mod);
-#endif
-
-}
-
-void GLAPIENTRY
-_mesa_ColorFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMask,
-                         GLuint dstMod, GLuint arg1, GLuint arg1Rep,
-                         GLuint arg1Mod)
-{
-   _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_COLOR_OP, 1, op, dst, dstMask,
-                       dstMod, arg1, arg1Rep, arg1Mod, 0, 0, 0, 0, 0, 0);
-}
-
-void GLAPIENTRY
-_mesa_ColorFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMask,
-                         GLuint dstMod, GLuint arg1, GLuint arg1Rep,
-                         GLuint arg1Mod, GLuint arg2, GLuint arg2Rep,
-                         GLuint arg2Mod)
-{
-   _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_COLOR_OP, 2, op, dst, dstMask,
-                       dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep,
-                       arg2Mod, 0, 0, 0);
-}
-
-void GLAPIENTRY
-_mesa_ColorFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMask,
-                         GLuint dstMod, GLuint arg1, GLuint arg1Rep,
-                         GLuint arg1Mod, GLuint arg2, GLuint arg2Rep,
-                         GLuint arg2Mod, GLuint arg3, GLuint arg3Rep,
-                         GLuint arg3Mod)
-{
-   _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_COLOR_OP, 3, op, dst, dstMask,
-                       dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep,
-                       arg2Mod, arg3, arg3Rep, arg3Mod);
-}
-
-void GLAPIENTRY
-_mesa_AlphaFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1,
-                         GLuint arg1Rep, GLuint arg1Mod)
-{
-   _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_ALPHA_OP, 1, op, dst, 0, dstMod,
-                       arg1, arg1Rep, arg1Mod, 0, 0, 0, 0, 0, 0);
-}
-
-void GLAPIENTRY
-_mesa_AlphaFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1,
-                         GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
-                         GLuint arg2Rep, GLuint arg2Mod)
-{
-   _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_ALPHA_OP, 2, op, dst, 0, dstMod,
-                       arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, 0, 0,
-                       0);
-}
-
-void GLAPIENTRY
-_mesa_AlphaFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1,
-                         GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
-                         GLuint arg2Rep, GLuint arg2Mod, GLuint arg3,
-                         GLuint arg3Rep, GLuint arg3Mod)
-{
-   _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_ALPHA_OP, 3, op, dst, 0, dstMod,
-                       arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3,
-                       arg3Rep, arg3Mod);
-}
-
-void GLAPIENTRY
-_mesa_SetFragmentShaderConstantATI(GLuint dst, const GLfloat * value)
-{
-   GLuint dstindex;
-   GET_CURRENT_CONTEXT(ctx);
-
-   if ((dst < GL_CON_0_ATI) || (dst > GL_CON_7_ATI)) {
-      /* spec says nothing about what should happen here but we can't just segfault...*/
-      _mesa_error(ctx, GL_INVALID_ENUM, "glSetFragmentShaderConstantATI(dst)");
-      return;
-   }
-
-   dstindex = dst - GL_CON_0_ATI;
-   if (ctx->ATIFragmentShader.Compiling) {
-      struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current;
-      COPY_4V(curProg->Constants[dstindex], value);
-      curProg->LocalConstDef |= 1 << dstindex;
-   }
-   else {
-      FLUSH_VERTICES(ctx, _NEW_PROGRAM);
-      COPY_4V(ctx->ATIFragmentShader.GlobalConstants[dstindex], value);
-   }
-}
-
-#endif /* FEATURE_ATI_fragment_shader */
diff --git a/src/mesa/shader/atifragshader.h b/src/mesa/shader/atifragshader.h
deleted file mode 100644 (file)
index 31c335e..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Mesa 3-D graphics library ATI Fragment Shader
- *
- * Copyright (C) 2004  David Airlie   All Rights Reserved.
- *
- */
-
-#ifndef ATIFRAGSHADER_H
-#define ATIFRAGSHADER_H
-
-#include "main/mtypes.h"
-
-#define MAX_NUM_INSTRUCTIONS_PER_PASS_ATI 8
-#define MAX_NUM_PASSES_ATI                2
-#define MAX_NUM_FRAGMENT_REGISTERS_ATI    6
-
-struct ati_fs_opcode_st
-{
-   GLenum opcode;
-   GLint num_src_args;
-};
-
-extern struct ati_fs_opcode_st ati_fs_opcodes[];
-
-struct atifragshader_src_register
-{
-   GLuint Index;
-   GLuint argRep;
-   GLuint argMod;
-};
-
-struct atifragshader_dst_register
-{
-   GLuint Index;
-   GLuint dstMod;
-   GLuint dstMask;
-};
-
-#define ATI_FRAGMENT_SHADER_COLOR_OP 0
-#define ATI_FRAGMENT_SHADER_ALPHA_OP 1
-#define ATI_FRAGMENT_SHADER_PASS_OP  2
-#define ATI_FRAGMENT_SHADER_SAMPLE_OP 3
-
-/* two opcodes - one for color/one for alpha */
-/* up to three source registers for most ops */
-struct atifs_instruction
-{
-   GLenum Opcode[2];
-   GLuint ArgCount[2];
-   struct atifragshader_src_register SrcReg[2][3];
-   struct atifragshader_dst_register DstReg[2];
-};
-
-/* different from arithmetic shader instruction */
-struct atifs_setupinst
-{
-   GLenum Opcode;
-   GLuint src;
-   GLenum swizzle;
-};
-
-
-#if FEATURE_ATI_fragment_shader
-
-extern void
-_mesa_init_ati_fragment_shader_dispatch(struct _glapi_table *disp);
-
-extern struct ati_fragment_shader *
-_mesa_new_ati_fragment_shader(GLcontext *ctx, GLuint id);
-
-extern void
-_mesa_delete_ati_fragment_shader(GLcontext *ctx,
-                                 struct ati_fragment_shader *s);
-
-
-extern GLuint GLAPIENTRY _mesa_GenFragmentShadersATI(GLuint range);
-
-extern void GLAPIENTRY _mesa_BindFragmentShaderATI(GLuint id);
-
-extern void GLAPIENTRY _mesa_DeleteFragmentShaderATI(GLuint id);
-
-extern void GLAPIENTRY _mesa_BeginFragmentShaderATI(void);
-
-extern void GLAPIENTRY _mesa_EndFragmentShaderATI(void);
-
-extern void GLAPIENTRY
-_mesa_PassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle);
-
-extern void GLAPIENTRY
-_mesa_SampleMapATI(GLuint dst, GLuint interp, GLenum swizzle);
-
-extern void GLAPIENTRY
-_mesa_ColorFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMask,
-                         GLuint dstMod, GLuint arg1, GLuint arg1Rep,
-                         GLuint arg1Mod);
-
-extern void GLAPIENTRY
-_mesa_ColorFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMask,
-                         GLuint dstMod, GLuint arg1, GLuint arg1Rep,
-                         GLuint arg1Mod, GLuint arg2, GLuint arg2Rep,
-                         GLuint arg2Mod);
-
-extern void GLAPIENTRY
-_mesa_ColorFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMask,
-                         GLuint dstMod, GLuint arg1, GLuint arg1Rep,
-                         GLuint arg1Mod, GLuint arg2, GLuint arg2Rep,
-                         GLuint arg2Mod, GLuint arg3, GLuint arg3Rep,
-                         GLuint arg3Mod);
-
-extern void GLAPIENTRY
-_mesa_AlphaFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1,
-                         GLuint arg1Rep, GLuint arg1Mod);
-
-extern void GLAPIENTRY
-_mesa_AlphaFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1,
-                         GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
-                         GLuint arg2Rep, GLuint arg2Mod);
-
-extern void GLAPIENTRY
-_mesa_AlphaFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1,
-                         GLuint arg1Rep, GLuint arg1Mod, GLuint arg2,
-                         GLuint arg2Rep, GLuint arg2Mod, GLuint arg3,
-                         GLuint arg3Rep, GLuint arg3Mod);
-
-extern void GLAPIENTRY
-_mesa_SetFragmentShaderConstantATI(GLuint dst, const GLfloat * value);
-
-#else /* FEATURE_ATI_fragment_shader */
-
-static INLINE void
-_mesa_init_ati_fragment_shader_dispatch(struct _glapi_table *disp)
-{
-}
-
-static INLINE struct ati_fragment_shader *
-_mesa_new_ati_fragment_shader(GLcontext *ctx, GLuint id)
-{
-   return NULL;
-}
-
-static INLINE void
-_mesa_delete_ati_fragment_shader(GLcontext *ctx,
-                                 struct ati_fragment_shader *s)
-{
-}
-
-#endif /* FEATURE_ATI_fragment_shader */
-
-#endif /* ATIFRAGSHADER_H */
diff --git a/src/mesa/shader/descrip.mms b/src/mesa/shader/descrip.mms
deleted file mode 100644 (file)
index 5973002..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-# Makefile for core library for VMS
-# contributed by Jouk Jansen  joukj@hrem.nano.tudelft.nl
-# Last revision : 29 September 2008
-.first
-       define gl [---.include.gl]
-       define math [-.math]
-       define swrast [-.swrast]
-       define array_cache [-.array_cache]
-       define glapi [-.glapi]
-       define main [-.main]
-       define shader [-.shader]
-
-.include [---]mms-config.
-
-##### MACROS #####
-
-VPATH = RCS
-
-INCDIR = [---.include],[-.main],[-.glapi],[.slang]
-LIBDIR = [---.lib]
-CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1,"__extension__=")/name=(as_is,short)/float=ieee/ieee=denorm
-
-SOURCES = \
-       atifragshader.c \
-       arbprogparse.c \
-       arbprogram.c \
-       nvfragparse.c \
-       nvprogram.c \
-       nvvertparse.c \
-       program.c \
-       programopt.c \
-       prog_debug.c \
-       prog_execute.c \
-       prog_instruction.c \
-       prog_parameter.c \
-       prog_print.c \
-       prog_cache.c \
-       prog_statevars.c \
-       shader_api.c prog_uniform.c
-
-OBJECTS = \
-       atifragshader.obj,\
-       arbprogparse.obj,\
-       arbprogram.obj,\
-       nvfragparse.obj,\
-       nvprogram.obj,\
-       nvvertparse.obj,\
-       program.obj,\
-       programopt.obj,\
-       prog_debug.obj,\
-       prog_execute.obj,\
-       prog_instruction.obj,\
-       prog_parameter.obj,\
-       prog_print.obj,\
-       prog_statevars.obj,\
-       shader_api.obj,prog_uniform.obj,prog_cache.obj
-
-##### RULES #####
-
-VERSION=Mesa V3.4
-
-##### TARGETS #####
-all : 
-       $(MMS)$(MMSQUALIFIERS) $(LIBDIR)$(GL_LIB)
-       set def [.slang]
-       $(MMS)$(MMSQUALIFIERS)
-       set def [-]
-
-# Make the library
-$(LIBDIR)$(GL_LIB) : $(OBJECTS)
-  @ library $(LIBDIR)$(GL_LIB) $(OBJECTS)
-
-clean :
-       purge
-       delete *.obj;*
-
-atifragshader.obj : atifragshader.c
-arbprogparse.obj : arbprogparse.c
-arbprogram.obj : arbprogram.c
-nvfragparse.obj : nvfragparse.c
-nvprogram.obj : nvprogram.c
-nvvertparse.obj : nvvertparse.c
-program.obj : program.c
-programopt. obj : programopt.c
-prog_debug.obj : prog_debug.c
-prog_execute.obj : prog_execute.c
-prog_instruction.obj : prog_instruction.c
-prog_parameter.obj : prog_parameter.c
-prog_print.obj : prog_print.c
-prog_statevars.obj : prog_statevars.c
-shader_api.obj : shader_api.c
-prog_uniform.obj : prog_uniform.c
-prog_cache.obj : prog_cache.c
diff --git a/src/mesa/shader/hash_table.c b/src/mesa/shader/hash_table.c
deleted file mode 100644 (file)
index f7ef366..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright Â© 2008 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION 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 hash_table.c
- * \brief Implementation of a generic, opaque hash table data type.
- *
- * \author Ian Romanick <ian.d.romanick@intel.com>
- */
-
-#include "main/imports.h"
-#include "main/simple_list.h"
-#include "hash_table.h"
-
-struct node {
-   struct node *next;
-   struct node *prev;
-};
-
-struct hash_table {
-    hash_func_t    hash;
-    hash_compare_func_t  compare;
-
-    unsigned num_buckets;
-    struct node buckets[1];
-};
-
-
-struct hash_node {
-    struct node link;
-    const void *key;
-    void *data;
-};
-
-
-struct hash_table *
-hash_table_ctor(unsigned num_buckets, hash_func_t hash,
-                hash_compare_func_t compare)
-{
-    struct hash_table *ht;
-    unsigned i;
-
-
-    if (num_buckets < 16) {
-        num_buckets = 16;
-    }
-
-    ht = malloc(sizeof(*ht) + ((num_buckets - 1) 
-                                    * sizeof(ht->buckets[0])));
-    if (ht != NULL) {
-        ht->hash = hash;
-        ht->compare = compare;
-        ht->num_buckets = num_buckets;
-
-        for (i = 0; i < num_buckets; i++) {
-            make_empty_list(& ht->buckets[i]);
-        }
-    }
-
-    return ht;
-}
-
-
-void
-hash_table_dtor(struct hash_table *ht)
-{
-   hash_table_clear(ht);
-   free(ht);
-}
-
-
-void
-hash_table_clear(struct hash_table *ht)
-{
-   struct node *node;
-   struct node *temp;
-   unsigned i;
-
-
-   for (i = 0; i < ht->num_buckets; i++) {
-      foreach_s(node, temp, & ht->buckets[i]) {
-        remove_from_list(node);
-        free(node);
-      }
-
-      assert(is_empty_list(& ht->buckets[i]));
-   }
-}
-
-
-void *
-hash_table_find(struct hash_table *ht, const void *key)
-{
-    const unsigned hash_value = (*ht->hash)(key);
-    const unsigned bucket = hash_value % ht->num_buckets;
-    struct node *node;
-
-    foreach(node, & ht->buckets[bucket]) {
-       struct hash_node *hn = (struct hash_node *) node;
-
-       if ((*ht->compare)(hn->key, key) == 0) {
-         return hn->data;
-       }
-    }
-
-    return NULL;
-}
-
-
-void
-hash_table_insert(struct hash_table *ht, void *data, const void *key)
-{
-    const unsigned hash_value = (*ht->hash)(key);
-    const unsigned bucket = hash_value % ht->num_buckets;
-    struct hash_node *node;
-
-    node = calloc(1, sizeof(*node));
-
-    node->data = data;
-    node->key = key;
-
-    insert_at_head(& ht->buckets[bucket], & node->link);
-}
-
-void
-hash_table_remove(struct hash_table *ht, const void *key)
-{
-    const unsigned hash_value = (*ht->hash)(key);
-    const unsigned bucket = hash_value % ht->num_buckets;
-    struct node *node;
-
-    foreach(node, & ht->buckets[bucket]) {
-       struct hash_node *hn = (struct hash_node *) node;
-
-       if ((*ht->compare)(hn->key, key) == 0) {
-         remove_from_list(node);
-         free(node);
-         return;
-       }
-    }
-}
-
-unsigned
-hash_table_string_hash(const void *key)
-{
-    const char *str = (const char *) key;
-    unsigned hash = 5381;
-
-
-    while (*str != '\0') {
-        hash = (hash * 33) + *str;
-        str++;
-    }
-
-    return hash;
-}
-
-
-unsigned
-hash_table_pointer_hash(const void *key)
-{
-   return (unsigned)((uintptr_t) key / sizeof(void *));
-}
-
-
-int
-hash_table_pointer_compare(const void *key1, const void *key2)
-{
-   return key1 == key2 ? 0 : 1;
-}
diff --git a/src/mesa/shader/hash_table.h b/src/mesa/shader/hash_table.h
deleted file mode 100644 (file)
index 228ab94..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright Â© 2008 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION 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 hash_table.h
- * \brief Implementation of a generic, opaque hash table data type.
- *
- * \author Ian Romanick <ian.d.romanick@intel.com>
- */
-
-#ifndef HASH_TABLE_H
-#define HASH_TABLE_H
-
-#include <string.h>
-
-struct hash_table;
-
-typedef unsigned (*hash_func_t)(const void *key);
-typedef int (*hash_compare_func_t)(const void *key1, const void *key2);
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Hash table constructor
- *
- * Creates a hash table with the specified number of buckets.  The supplied
- * \c hash and \c compare routines are used when adding elements to the table
- * and when searching for elements in the table.
- *
- * \param num_buckets  Number of buckets (bins) in the hash table.
- * \param hash         Function used to compute hash value of input keys.
- * \param compare      Function used to compare keys.
- */
-extern struct hash_table *hash_table_ctor(unsigned num_buckets,
-    hash_func_t hash, hash_compare_func_t compare);
-
-
-/**
- * Release all memory associated with a hash table
- *
- * \warning
- * This function cannot release memory occupied either by keys or data.
- */
-extern void hash_table_dtor(struct hash_table *ht);
-
-
-/**
- * Flush all entries from a hash table
- *
- * \param ht  Table to be cleared of its entries.
- */
-extern void hash_table_clear(struct hash_table *ht);
-
-
-/**
- * Search a hash table for a specific element
- *
- * \param ht   Table to be searched
- * \param key  Key of the desired element
- *
- * \return
- * The \c data value supplied to \c hash_table_insert when the element with
- * the matching key was added.  If no matching key exists in the table,
- * \c NULL is returned.
- */
-extern void *hash_table_find(struct hash_table *ht, const void *key);
-
-
-/**
- * Add an element to a hash table
- */
-extern void hash_table_insert(struct hash_table *ht, void *data,
-    const void *key);
-
-/**
- * Remove a specific element from a hash table.
- */
-extern void hash_table_remove(struct hash_table *ht, const void *key);
-
-/**
- * Compute hash value of a string
- *
- * Computes the hash value of a string using the DJB2 algorithm developed by
- * Professor Daniel J. Bernstein.  It was published on comp.lang.c once upon
- * a time.  I was unable to find the original posting in the archives.
- *
- * \param key  Pointer to a NUL terminated string to be hashed.
- *
- * \sa hash_table_string_compare
- */
-extern unsigned hash_table_string_hash(const void *key);
-
-
-/**
- * Compare two strings used as keys
- *
- * This is just a macro wrapper around \c strcmp.
- *
- * \sa hash_table_string_hash
- */
-#define hash_table_string_compare ((hash_compare_func_t) strcmp)
-
-
-/**
- * Compute hash value of a pointer
- *
- * \param key  Pointer to be used as a hash key
- *
- * \note
- * The memory pointed to by \c key is \b never accessed.  The value of \c key
- * itself is used as the hash key
- *
- * \sa hash_table_pointer_compare
- */
-unsigned
-hash_table_pointer_hash(const void *key);
-
-
-/**
- * Compare two pointers used as keys
- *
- * \sa hash_table_pointer_hash
- */
-int
-hash_table_pointer_compare(const void *key1, const void *key2);
-
-#ifdef __cplusplus
-};
-#endif
-#endif /* HASH_TABLE_H */
diff --git a/src/mesa/shader/ir_to_mesa.cpp b/src/mesa/shader/ir_to_mesa.cpp
deleted file mode 100644 (file)
index 89cad8a..0000000
+++ /dev/null
@@ -1,2308 +0,0 @@
-/*
- * Copyright (C) 2005-2007  Brian Paul   All Rights Reserved.
- * Copyright (C) 2008  VMware, Inc.   All Rights Reserved.
- * Copyright Â© 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION 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 ir_to_mesa.cpp
- *
- * Translates the IR to ARB_fragment_program text if possible,
- * printing the result
- */
-
-#include <stdio.h>
-#include "ir.h"
-#include "ir_visitor.h"
-#include "ir_print_visitor.h"
-#include "ir_expression_flattening.h"
-#include "glsl_types.h"
-#include "glsl_parser_extras.h"
-#include "../glsl/program.h"
-#include "ir_optimization.h"
-#include "ast.h"
-
-extern "C" {
-#include "main/mtypes.h"
-#include "shader/prog_instruction.h"
-#include "shader/prog_optimize.h"
-#include "shader/prog_print.h"
-#include "shader/program.h"
-#include "shader/prog_uniform.h"
-#include "shader/prog_parameter.h"
-#include "shader/shader_api.h"
-}
-
-/**
- * This struct is a corresponding struct to Mesa prog_src_register, with
- * wider fields.
- */
-typedef struct ir_to_mesa_src_reg {
-   int file; /**< PROGRAM_* from Mesa */
-   int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
-   GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
-   int negate; /**< NEGATE_XYZW mask from mesa */
-   /** Register index should be offset by the integer in this reg. */
-   ir_to_mesa_src_reg *reladdr;
-} ir_to_mesa_src_reg;
-
-typedef struct ir_to_mesa_dst_reg {
-   int file; /**< PROGRAM_* from Mesa */
-   int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
-   int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
-   GLuint cond_mask:4;
-   /** Register index should be offset by the integer in this reg. */
-   ir_to_mesa_src_reg *reladdr;
-} ir_to_mesa_dst_reg;
-
-extern ir_to_mesa_src_reg ir_to_mesa_undef;
-
-class ir_to_mesa_instruction : public exec_node {
-public:
-   enum prog_opcode op;
-   ir_to_mesa_dst_reg dst_reg;
-   ir_to_mesa_src_reg src_reg[3];
-   /** Pointer to the ir source this tree came from for debugging */
-   ir_instruction *ir;
-   GLboolean cond_update;
-   int sampler; /**< sampler index */
-   int tex_target; /**< One of TEXTURE_*_INDEX */
-   GLboolean tex_shadow;
-
-   class function_entry *function; /* Set on OPCODE_CAL or OPCODE_BGNSUB */
-};
-
-class variable_storage : public exec_node {
-public:
-   variable_storage(ir_variable *var, int file, int index)
-      : file(file), index(index), var(var)
-   {
-      /* empty */
-   }
-
-   int file;
-   int index;
-   ir_variable *var; /* variable that maps to this, if any */
-};
-
-class function_entry : public exec_node {
-public:
-   ir_function_signature *sig;
-
-   /**
-    * identifier of this function signature used by the program.
-    *
-    * At the point that Mesa instructions for function calls are
-    * generated, we don't know the address of the first instruction of
-    * the function body.  So we make the BranchTarget that is called a
-    * small integer and rewrite them during set_branchtargets().
-    */
-   int sig_id;
-
-   /**
-    * Pointer to first instruction of the function body.
-    *
-    * Set during function body emits after main() is processed.
-    */
-   ir_to_mesa_instruction *bgn_inst;
-
-   /**
-    * Index of the first instruction of the function body in actual
-    * Mesa IR.
-    *
-    * Set after convertion from ir_to_mesa_instruction to prog_instruction.
-    */
-   int inst;
-
-   /** Storage for the return value. */
-   ir_to_mesa_src_reg return_reg;
-};
-
-class ir_to_mesa_visitor : public ir_visitor {
-public:
-   ir_to_mesa_visitor();
-
-   function_entry *current_function;
-
-   GLcontext *ctx;
-   struct gl_program *prog;
-
-   int next_temp;
-
-   variable_storage *find_variable_storage(ir_variable *var);
-
-   function_entry *get_function_signature(ir_function_signature *sig);
-
-   ir_to_mesa_src_reg get_temp(const glsl_type *type);
-   void reladdr_to_temp(ir_instruction *ir,
-                       ir_to_mesa_src_reg *reg, int *num_reladdr);
-
-   struct ir_to_mesa_src_reg src_reg_for_float(float val);
-
-   /**
-    * \name Visit methods
-    *
-    * As typical for the visitor pattern, there must be one \c visit method for
-    * each concrete subclass of \c ir_instruction.  Virtual base classes within
-    * the hierarchy should not have \c visit methods.
-    */
-   /*@{*/
-   virtual void visit(ir_variable *);
-   virtual void visit(ir_loop *);
-   virtual void visit(ir_loop_jump *);
-   virtual void visit(ir_function_signature *);
-   virtual void visit(ir_function *);
-   virtual void visit(ir_expression *);
-   virtual void visit(ir_swizzle *);
-   virtual void visit(ir_dereference_variable  *);
-   virtual void visit(ir_dereference_array *);
-   virtual void visit(ir_dereference_record *);
-   virtual void visit(ir_assignment *);
-   virtual void visit(ir_constant *);
-   virtual void visit(ir_call *);
-   virtual void visit(ir_return *);
-   virtual void visit(ir_discard *);
-   virtual void visit(ir_texture *);
-   virtual void visit(ir_if *);
-   /*@}*/
-
-   struct ir_to_mesa_src_reg result;
-
-   /** List of variable_storage */
-   exec_list variables;
-
-   /** List of function_entry */
-   exec_list function_signatures;
-   int next_signature_id;
-
-   /** List of ir_to_mesa_instruction */
-   exec_list instructions;
-
-   ir_to_mesa_instruction *ir_to_mesa_emit_op0(ir_instruction *ir,
-                                              enum prog_opcode op);
-
-   ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir,
-                                              enum prog_opcode op,
-                                              ir_to_mesa_dst_reg dst,
-                                              ir_to_mesa_src_reg src0);
-
-   ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir,
-                                              enum prog_opcode op,
-                                              ir_to_mesa_dst_reg dst,
-                                              ir_to_mesa_src_reg src0,
-                                              ir_to_mesa_src_reg src1);
-
-   ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir,
-                                              enum prog_opcode op,
-                                              ir_to_mesa_dst_reg dst,
-                                              ir_to_mesa_src_reg src0,
-                                              ir_to_mesa_src_reg src1,
-                                              ir_to_mesa_src_reg src2);
-
-   void ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
-                                  enum prog_opcode op,
-                                  ir_to_mesa_dst_reg dst,
-                                  ir_to_mesa_src_reg src0);
-
-   void ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
-                                  enum prog_opcode op,
-                                  ir_to_mesa_dst_reg dst,
-                                  ir_to_mesa_src_reg src0,
-                                  ir_to_mesa_src_reg src1);
-
-   GLboolean try_emit_mad(ir_expression *ir,
-                         int mul_operand);
-
-   int *sampler_map;
-   int sampler_map_size;
-
-   void map_sampler(int location, int sampler);
-   int get_sampler_number(int location);
-
-   void *mem_ctx;
-};
-
-ir_to_mesa_src_reg ir_to_mesa_undef = {
-   PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, NEGATE_NONE, NULL,
-};
-
-ir_to_mesa_dst_reg ir_to_mesa_undef_dst = {
-   PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, COND_TR, NULL,
-};
-
-ir_to_mesa_dst_reg ir_to_mesa_address_reg = {
-   PROGRAM_ADDRESS, 0, WRITEMASK_X, COND_TR, NULL
-};
-
-static int swizzle_for_size(int size)
-{
-   int size_swizzles[4] = {
-      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
-      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
-      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
-      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
-   };
-
-   return size_swizzles[size - 1];
-}
-
-ir_to_mesa_instruction *
-ir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir,
-                                       enum prog_opcode op,
-                                       ir_to_mesa_dst_reg dst,
-                                       ir_to_mesa_src_reg src0,
-                                       ir_to_mesa_src_reg src1,
-                                       ir_to_mesa_src_reg src2)
-{
-   ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction();
-   int num_reladdr = 0;
-
-   /* If we have to do relative addressing, we want to load the ARL
-    * reg directly for one of the regs, and preload the other reladdr
-    * sources into temps.
-    */
-   num_reladdr += dst.reladdr != NULL;
-   num_reladdr += src0.reladdr != NULL;
-   num_reladdr += src1.reladdr != NULL;
-   num_reladdr += src2.reladdr != NULL;
-
-   reladdr_to_temp(ir, &src2, &num_reladdr);
-   reladdr_to_temp(ir, &src1, &num_reladdr);
-   reladdr_to_temp(ir, &src0, &num_reladdr);
-
-   if (dst.reladdr) {
-      ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg,
-                          *dst.reladdr);
-
-      num_reladdr--;
-   }
-   assert(num_reladdr == 0);
-
-   inst->op = op;
-   inst->dst_reg = dst;
-   inst->src_reg[0] = src0;
-   inst->src_reg[1] = src1;
-   inst->src_reg[2] = src2;
-   inst->ir = ir;
-
-   inst->function = NULL;
-
-   this->instructions.push_tail(inst);
-
-   return inst;
-}
-
-
-ir_to_mesa_instruction *
-ir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir,
-                                       enum prog_opcode op,
-                                       ir_to_mesa_dst_reg dst,
-                                       ir_to_mesa_src_reg src0,
-                                       ir_to_mesa_src_reg src1)
-{
-   return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef);
-}
-
-ir_to_mesa_instruction *
-ir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir,
-                                       enum prog_opcode op,
-                                       ir_to_mesa_dst_reg dst,
-                                       ir_to_mesa_src_reg src0)
-{
-   return ir_to_mesa_emit_op3(ir, op, dst,
-                             src0, ir_to_mesa_undef, ir_to_mesa_undef);
-}
-
-ir_to_mesa_instruction *
-ir_to_mesa_visitor::ir_to_mesa_emit_op0(ir_instruction *ir,
-                                       enum prog_opcode op)
-{
-   return ir_to_mesa_emit_op3(ir, op, ir_to_mesa_undef_dst,
-                             ir_to_mesa_undef,
-                             ir_to_mesa_undef,
-                             ir_to_mesa_undef);
-}
-
-void
-ir_to_mesa_visitor::map_sampler(int location, int sampler)
-{
-   if (this->sampler_map_size <= location) {
-      this->sampler_map = talloc_realloc(this->mem_ctx, this->sampler_map,
-                                        int, location + 1);
-      this->sampler_map_size = location + 1;
-   }
-
-   this->sampler_map[location] = sampler;
-}
-
-int
-ir_to_mesa_visitor::get_sampler_number(int location)
-{
-   assert(location < this->sampler_map_size);
-   return this->sampler_map[location];
-}
-
-inline ir_to_mesa_dst_reg
-ir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg)
-{
-   ir_to_mesa_dst_reg dst_reg;
-
-   dst_reg.file = reg.file;
-   dst_reg.index = reg.index;
-   dst_reg.writemask = WRITEMASK_XYZW;
-   dst_reg.cond_mask = COND_TR;
-   dst_reg.reladdr = reg.reladdr;
-
-   return dst_reg;
-}
-
-inline ir_to_mesa_src_reg
-ir_to_mesa_src_reg_from_dst(ir_to_mesa_dst_reg reg)
-{
-   ir_to_mesa_src_reg src_reg;
-
-   src_reg.file = reg.file;
-   src_reg.index = reg.index;
-   src_reg.swizzle = SWIZZLE_XYZW;
-   src_reg.negate = 0;
-   src_reg.reladdr = reg.reladdr;
-
-   return src_reg;
-}
-
-/**
- * Emits Mesa scalar opcodes to produce unique answers across channels.
- *
- * Some Mesa opcodes are scalar-only, like ARB_fp/vp.  The src X
- * channel determines the result across all channels.  So to do a vec4
- * of this operation, we want to emit a scalar per source channel used
- * to produce dest channels.
- */
-void
-ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
-                                              enum prog_opcode op,
-                                              ir_to_mesa_dst_reg dst,
-                                              ir_to_mesa_src_reg orig_src0,
-                                              ir_to_mesa_src_reg orig_src1)
-{
-   int i, j;
-   int done_mask = ~dst.writemask;
-
-   /* Mesa RCP is a scalar operation splatting results to all channels,
-    * like ARB_fp/vp.  So emit as many RCPs as necessary to cover our
-    * dst channels.
-    */
-   for (i = 0; i < 4; i++) {
-      GLuint this_mask = (1 << i);
-      ir_to_mesa_instruction *inst;
-      ir_to_mesa_src_reg src0 = orig_src0;
-      ir_to_mesa_src_reg src1 = orig_src1;
-
-      if (done_mask & this_mask)
-        continue;
-
-      GLuint src0_swiz = GET_SWZ(src0.swizzle, i);
-      GLuint src1_swiz = GET_SWZ(src1.swizzle, i);
-      for (j = i + 1; j < 4; j++) {
-        if (!(done_mask & (1 << j)) &&
-            GET_SWZ(src0.swizzle, j) == src0_swiz &&
-            GET_SWZ(src1.swizzle, j) == src1_swiz) {
-           this_mask |= (1 << j);
-        }
-      }
-      src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
-                                  src0_swiz, src0_swiz);
-      src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz,
-                                 src1_swiz, src1_swiz);
-
-      inst = ir_to_mesa_emit_op2(ir, op,
-                                dst,
-                                src0,
-                                src1);
-      inst->dst_reg.writemask = this_mask;
-      done_mask |= this_mask;
-   }
-}
-
-void
-ir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
-                                              enum prog_opcode op,
-                                              ir_to_mesa_dst_reg dst,
-                                              ir_to_mesa_src_reg src0)
-{
-   ir_to_mesa_src_reg undef = ir_to_mesa_undef;
-
-   undef.swizzle = SWIZZLE_XXXX;
-
-   ir_to_mesa_emit_scalar_op2(ir, op, dst, src0, undef);
-}
-
-struct ir_to_mesa_src_reg
-ir_to_mesa_visitor::src_reg_for_float(float val)
-{
-   ir_to_mesa_src_reg src_reg;
-
-   src_reg.file = PROGRAM_CONSTANT;
-   src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
-                                             &val, 1, &src_reg.swizzle);
-   src_reg.reladdr = NULL;
-   src_reg.negate = 0;
-
-   return src_reg;
-}
-
-static int
-type_size(const struct glsl_type *type)
-{
-   unsigned int i;
-   int size;
-
-   switch (type->base_type) {
-   case GLSL_TYPE_UINT:
-   case GLSL_TYPE_INT:
-   case GLSL_TYPE_FLOAT:
-   case GLSL_TYPE_BOOL:
-      if (type->is_matrix()) {
-        return type->matrix_columns;
-      } else {
-        /* Regardless of size of vector, it gets a vec4. This is bad
-         * packing for things like floats, but otherwise arrays become a
-         * mess.  Hopefully a later pass over the code can pack scalars
-         * down if appropriate.
-         */
-        return 1;
-      }
-   case GLSL_TYPE_ARRAY:
-      return type_size(type->fields.array) * type->length;
-   case GLSL_TYPE_STRUCT:
-      size = 0;
-      for (i = 0; i < type->length; i++) {
-        size += type_size(type->fields.structure[i].type);
-      }
-      return size;
-   default:
-      assert(0);
-   }
-}
-
-/**
- * In the initial pass of codegen, we assign temporary numbers to
- * intermediate results.  (not SSA -- variable assignments will reuse
- * storage).  Actual register allocation for the Mesa VM occurs in a
- * pass over the Mesa IR later.
- */
-ir_to_mesa_src_reg
-ir_to_mesa_visitor::get_temp(const glsl_type *type)
-{
-   ir_to_mesa_src_reg src_reg;
-   int swizzle[4];
-   int i;
-
-   assert(!type->is_array());
-
-   src_reg.file = PROGRAM_TEMPORARY;
-   src_reg.index = next_temp;
-   src_reg.reladdr = NULL;
-   next_temp += type_size(type);
-
-   for (i = 0; i < type->vector_elements; i++)
-      swizzle[i] = i;
-   for (; i < 4; i++)
-      swizzle[i] = type->vector_elements - 1;
-   src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
-                                  swizzle[2], swizzle[3]);
-   src_reg.negate = 0;
-
-   return src_reg;
-}
-
-variable_storage *
-ir_to_mesa_visitor::find_variable_storage(ir_variable *var)
-{
-   
-   variable_storage *entry;
-
-   foreach_iter(exec_list_iterator, iter, this->variables) {
-      entry = (variable_storage *)iter.get();
-
-      if (entry->var == var)
-        return entry;
-   }
-
-   return NULL;
-}
-
-void
-ir_to_mesa_visitor::visit(ir_variable *ir)
-{
-   (void)ir;
-}
-
-void
-ir_to_mesa_visitor::visit(ir_loop *ir)
-{
-   assert(!ir->from);
-   assert(!ir->to);
-   assert(!ir->increment);
-   assert(!ir->counter);
-
-   ir_to_mesa_emit_op0(NULL, OPCODE_BGNLOOP);
-   visit_exec_list(&ir->body_instructions, this);
-   ir_to_mesa_emit_op0(NULL, OPCODE_ENDLOOP);
-}
-
-void
-ir_to_mesa_visitor::visit(ir_loop_jump *ir)
-{
-   switch (ir->mode) {
-   case ir_loop_jump::jump_break:
-      ir_to_mesa_emit_op0(NULL, OPCODE_BRK);
-      break;
-   case ir_loop_jump::jump_continue:
-      ir_to_mesa_emit_op0(NULL, OPCODE_CONT);
-      break;
-   }
-}
-
-
-void
-ir_to_mesa_visitor::visit(ir_function_signature *ir)
-{
-   assert(0);
-   (void)ir;
-}
-
-void
-ir_to_mesa_visitor::visit(ir_function *ir)
-{
-   /* Ignore function bodies other than main() -- we shouldn't see calls to
-    * them since they should all be inlined before we get to ir_to_mesa.
-    */
-   if (strcmp(ir->name, "main") == 0) {
-      const ir_function_signature *sig;
-      exec_list empty;
-
-      sig = ir->matching_signature(&empty);
-
-      assert(sig);
-
-      foreach_iter(exec_list_iterator, iter, sig->body) {
-        ir_instruction *ir = (ir_instruction *)iter.get();
-
-        ir->accept(this);
-      }
-   }
-}
-
-GLboolean
-ir_to_mesa_visitor::try_emit_mad(ir_expression *ir, int mul_operand)
-{
-   int nonmul_operand = 1 - mul_operand;
-   ir_to_mesa_src_reg a, b, c;
-
-   ir_expression *expr = ir->operands[mul_operand]->as_expression();
-   if (!expr || expr->operation != ir_binop_mul)
-      return false;
-
-   expr->operands[0]->accept(this);
-   a = this->result;
-   expr->operands[1]->accept(this);
-   b = this->result;
-   ir->operands[nonmul_operand]->accept(this);
-   c = this->result;
-
-   this->result = get_temp(ir->type);
-   ir_to_mesa_emit_op3(ir, OPCODE_MAD,
-                      ir_to_mesa_dst_reg_from_src(this->result), a, b, c);
-
-   return true;
-}
-
-void
-ir_to_mesa_visitor::reladdr_to_temp(ir_instruction *ir,
-                                   ir_to_mesa_src_reg *reg, int *num_reladdr)
-{
-   if (!reg->reladdr)
-      return;
-
-   ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, *reg->reladdr);
-
-   if (*num_reladdr != 1) {
-      ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type);
-
-      ir_to_mesa_emit_op1(ir, OPCODE_MOV,
-                         ir_to_mesa_dst_reg_from_src(temp), *reg);
-      *reg = temp;
-   }
-
-   (*num_reladdr)--;
-}
-
-void
-ir_to_mesa_visitor::visit(ir_expression *ir)
-{
-   unsigned int operand;
-   struct ir_to_mesa_src_reg op[2];
-   struct ir_to_mesa_src_reg result_src;
-   struct ir_to_mesa_dst_reg result_dst;
-   const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1);
-   const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1);
-   const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1);
-
-   /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c)
-    */
-   if (ir->operation == ir_binop_add) {
-      if (try_emit_mad(ir, 1))
-        return;
-      if (try_emit_mad(ir, 0))
-        return;
-   }
-
-   for (operand = 0; operand < ir->get_num_operands(); operand++) {
-      this->result.file = PROGRAM_UNDEFINED;
-      ir->operands[operand]->accept(this);
-      if (this->result.file == PROGRAM_UNDEFINED) {
-        ir_print_visitor v;
-        printf("Failed to get tree for expression operand:\n");
-        ir->operands[operand]->accept(&v);
-        exit(1);
-      }
-      op[operand] = this->result;
-
-      /* Matrix expression operands should have been broken down to vector
-       * operations already.
-       */
-      assert(!ir->operands[operand]->type->is_matrix());
-   }
-
-   this->result.file = PROGRAM_UNDEFINED;
-
-   /* Storage for our result.  Ideally for an assignment we'd be using
-    * the actual storage for the result here, instead.
-    */
-   result_src = get_temp(ir->type);
-   /* convenience for the emit functions below. */
-   result_dst = ir_to_mesa_dst_reg_from_src(result_src);
-   /* Limit writes to the channels that will be used by result_src later.
-    * This does limit this temp's use as a temporary for multi-instruction
-    * sequences.
-    */
-   result_dst.writemask = (1 << ir->type->vector_elements) - 1;
-
-   switch (ir->operation) {
-   case ir_unop_logic_not:
-      ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst,
-                         op[0], src_reg_for_float(0.0));
-      break;
-   case ir_unop_neg:
-      op[0].negate = ~op[0].negate;
-      result_src = op[0];
-      break;
-   case ir_unop_abs:
-      ir_to_mesa_emit_op1(ir, OPCODE_ABS, result_dst, op[0]);
-      break;
-   case ir_unop_sign:
-      ir_to_mesa_emit_op1(ir, OPCODE_SSG, result_dst, op[0]);
-      break;
-   case ir_unop_rcp:
-      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[0]);
-      break;
-
-   case ir_unop_exp:
-      ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst,
-                                src_reg_for_float(M_E), op[0]);
-      break;
-   case ir_unop_exp2:
-      ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]);
-      break;
-   case ir_unop_log:
-      ir_to_mesa_emit_scalar_op1(ir, OPCODE_LOG, result_dst, op[0]);
-      break;
-   case ir_unop_log2:
-      ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]);
-      break;
-   case ir_unop_sin:
-      ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]);
-      break;
-   case ir_unop_cos:
-      ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]);
-      break;
-
-   case ir_unop_dFdx:
-      ir_to_mesa_emit_op1(ir, OPCODE_DDX, result_dst, op[0]);
-      break;
-   case ir_unop_dFdy:
-      ir_to_mesa_emit_op1(ir, OPCODE_DDY, result_dst, op[0]);
-      break;
-
-   case ir_binop_add:
-      ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]);
-      break;
-   case ir_binop_sub:
-      ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]);
-      break;
-
-   case ir_binop_mul:
-      ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]);
-      break;
-   case ir_binop_div:
-      assert(!"not reached: should be handled by ir_div_to_mul_rcp");
-   case ir_binop_mod:
-      assert(!"ir_binop_mod should have been converted to b * fract(a/b)");
-      break;
-
-   case ir_binop_less:
-      ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]);
-      break;
-   case ir_binop_greater:
-      ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]);
-      break;
-   case ir_binop_lequal:
-      ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]);
-      break;
-   case ir_binop_gequal:
-      ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]);
-      break;
-   case ir_binop_equal:
-      ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
-      break;
-   case ir_binop_logic_xor:
-   case ir_binop_nequal:
-      ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
-      break;
-
-   case ir_binop_logic_or:
-      /* This could be a saturated add and skip the SNE. */
-      ir_to_mesa_emit_op2(ir, OPCODE_ADD,
-                         result_dst,
-                         op[0], op[1]);
-
-      ir_to_mesa_emit_op2(ir, OPCODE_SNE,
-                         result_dst,
-                         result_src, src_reg_for_float(0.0));
-      break;
-
-   case ir_binop_logic_and:
-      /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */
-      ir_to_mesa_emit_op2(ir, OPCODE_MUL,
-                         result_dst,
-                         op[0], op[1]);
-      break;
-
-   case ir_binop_dot:
-      if (ir->operands[0]->type == vec4_type) {
-        assert(ir->operands[1]->type == vec4_type);
-        ir_to_mesa_emit_op2(ir, OPCODE_DP4,
-                            result_dst,
-                            op[0], op[1]);
-      } else if (ir->operands[0]->type == vec3_type) {
-        assert(ir->operands[1]->type == vec3_type);
-        ir_to_mesa_emit_op2(ir, OPCODE_DP3,
-                            result_dst,
-                            op[0], op[1]);
-      } else if (ir->operands[0]->type == vec2_type) {
-        assert(ir->operands[1]->type == vec2_type);
-        ir_to_mesa_emit_op2(ir, OPCODE_DP2,
-                            result_dst,
-                            op[0], op[1]);
-      }
-      break;
-
-   case ir_binop_cross:
-      ir_to_mesa_emit_op2(ir, OPCODE_XPD, result_dst, op[0], op[1]);
-      break;
-
-   case ir_unop_sqrt:
-      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
-      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, result_src);
-      /* For incoming channels < 0, set the result to 0. */
-      ir_to_mesa_emit_op3(ir, OPCODE_CMP, result_dst,
-                         op[0], src_reg_for_float(0.0), result_src);
-      break;
-   case ir_unop_rsq:
-      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
-      break;
-   case ir_unop_i2f:
-   case ir_unop_b2f:
-   case ir_unop_b2i:
-      /* Mesa IR lacks types, ints are stored as truncated floats. */
-      result_src = op[0];
-      break;
-   case ir_unop_f2i:
-      ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
-      break;
-   case ir_unop_f2b:
-   case ir_unop_i2b:
-      ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst,
-                         result_src, src_reg_for_float(0.0));
-      break;
-   case ir_unop_trunc:
-      ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
-      break;
-   case ir_unop_ceil:
-      op[0].negate = ~op[0].negate;
-      ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
-      result_src.negate = ~result_src.negate;
-      break;
-   case ir_unop_floor:
-      ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
-      break;
-   case ir_unop_fract:
-      ir_to_mesa_emit_op1(ir, OPCODE_FRC, result_dst, op[0]);
-      break;
-
-   case ir_binop_min:
-      ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]);
-      break;
-   case ir_binop_max:
-      ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]);
-      break;
-   case ir_binop_pow:
-      ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, op[0], op[1]);
-      break;
-
-   case ir_unop_bit_not:
-   case ir_unop_u2f:
-   case ir_binop_lshift:
-   case ir_binop_rshift:
-   case ir_binop_bit_and:
-   case ir_binop_bit_xor:
-   case ir_binop_bit_or:
-      assert(!"GLSL 1.30 features unsupported");
-      break;
-   }
-
-   this->result = result_src;
-}
-
-
-void
-ir_to_mesa_visitor::visit(ir_swizzle *ir)
-{
-   ir_to_mesa_src_reg src_reg;
-   int i;
-   int swizzle[4];
-
-   /* Note that this is only swizzles in expressions, not those on the left
-    * hand side of an assignment, which do write masking.  See ir_assignment
-    * for that.
-    */
-
-   ir->val->accept(this);
-   src_reg = this->result;
-   assert(src_reg.file != PROGRAM_UNDEFINED);
-
-   for (i = 0; i < 4; i++) {
-      if (i < ir->type->vector_elements) {
-        switch (i) {
-        case 0:
-           swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.x);
-           break;
-        case 1:
-           swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.y);
-           break;
-        case 2:
-           swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.z);
-           break;
-        case 3:
-           swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.w);
-           break;
-        }
-      } else {
-        /* If the type is smaller than a vec4, replicate the last
-         * channel out.
-         */
-        swizzle[i] = swizzle[ir->type->vector_elements - 1];
-      }
-   }
-
-   src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0],
-                                  swizzle[1],
-                                  swizzle[2],
-                                  swizzle[3]);
-
-   this->result = src_reg;
-}
-
-static int
-add_matrix_ref(struct gl_program *prog, int *tokens)
-{
-   int base_pos = -1;
-   int i;
-
-   /* Add a ref for each column.  It looks like the reason we do
-    * it this way is that _mesa_add_state_reference doesn't work
-    * for things that aren't vec4s, so the tokens[2]/tokens[3]
-    * range has to be equal.
-    */
-   for (i = 0; i < 4; i++) {
-      tokens[2] = i;
-      tokens[3] = i;
-      int pos = _mesa_add_state_reference(prog->Parameters,
-                                         (gl_state_index *)tokens);
-      if (base_pos == -1)
-        base_pos = pos;
-      else
-        assert(base_pos + i == pos);
-   }
-
-   return base_pos;
-}
-
-static variable_storage *
-get_builtin_matrix_ref(void *mem_ctx, struct gl_program *prog, ir_variable *var,
-                      ir_rvalue *array_index)
-{
-   /*
-    * NOTE: The ARB_vertex_program extension specified that matrices get
-    * loaded in registers in row-major order.  With GLSL, we want column-
-    * major order.  So, we need to transpose all matrices here...
-    */
-   static const struct {
-      const char *name;
-      int matrix;
-      int modifier;
-   } matrices[] = {
-      { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE },
-      { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS },
-      { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 },
-      { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
-
-      { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE },
-      { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS },
-      { "gl_ProjectionMatrixTranspose", STATE_PROJECTION_MATRIX, 0 },
-      { "gl_ProjectionMatrixInverseTranspose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE },
-
-      { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE },
-      { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS },
-      { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 },
-      { "gl_ModelViewProjectionMatrixInverseTranspose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE },
-
-      { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE },
-      { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS },
-      { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 },
-      { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE },
-
-      { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
-
-   };
-   unsigned int i;
-   variable_storage *entry;
-
-   /* C++ gets angry when we try to use an int as a gl_state_index, so we use
-    * ints for gl_state_index.  Make sure they're compatible.
-    */
-   assert(sizeof(gl_state_index) == sizeof(int));
-
-   for (i = 0; i < Elements(matrices); i++) {
-      if (strcmp(var->name, matrices[i].name) == 0) {
-        int tokens[STATE_LENGTH];
-        int base_pos = -1;
-
-        tokens[0] = matrices[i].matrix;
-        tokens[4] = matrices[i].modifier;
-        if (matrices[i].matrix == STATE_TEXTURE_MATRIX) {
-           ir_constant *index = array_index->constant_expression_value();
-           if (index) {
-              tokens[1] = index->value.i[0];
-              base_pos = add_matrix_ref(prog, tokens);
-           } else {
-              for (i = 0; i < var->type->length; i++) {
-                 tokens[1] = i;
-                 int pos = add_matrix_ref(prog, tokens);
-                 if (base_pos == -1)
-                    base_pos = pos;
-                 else
-                    assert(base_pos + (int)i * 4 == pos);
-              }
-           }
-        } else {
-           tokens[1] = 0; /* unused array index */
-           base_pos = add_matrix_ref(prog, tokens);
-        }
-        tokens[4] = matrices[i].modifier;
-
-        entry = new(mem_ctx) variable_storage(var,
-                                              PROGRAM_STATE_VAR,
-                                              base_pos);
-
-        return entry;
-      }
-   }
-
-   return NULL;
-}
-
-void
-ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
-{
-   ir_to_mesa_src_reg src_reg;
-   variable_storage *entry = find_variable_storage(ir->var);
-   unsigned int loc;
-
-   if (!entry) {
-      switch (ir->var->mode) {
-      case ir_var_uniform:
-        entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, ir->var,
-                                       NULL);
-        if (entry)
-           break;
-
-        /* FINISHME: Fix up uniform name for arrays and things */
-        if (ir->var->type->base_type == GLSL_TYPE_SAMPLER) {
-           /* FINISHME: we whack the location of the var here, which
-            * is probably not expected.  But we need to communicate
-            * mesa's sampler number to the tex instruction.
-            */
-           int sampler = _mesa_add_sampler(this->prog->Parameters,
-                                           ir->var->name,
-                                           ir->var->type->gl_type);
-           map_sampler(ir->var->location, sampler);
-
-           entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_SAMPLER,
-                                                 sampler);
-           this->variables.push_tail(entry);
-           break;
-        }
-
-        assert(ir->var->type->gl_type != 0 &&
-               ir->var->type->gl_type != GL_INVALID_ENUM);
-        loc = _mesa_add_uniform(this->prog->Parameters,
-                                ir->var->name,
-                                type_size(ir->var->type) * 4,
-                                ir->var->type->gl_type,
-                                NULL);
-
-        /* Always mark the uniform used at this point.  If it isn't
-         * used, dead code elimination should have nuked the decl already.
-         */
-        this->prog->Parameters->Parameters[loc].Used = GL_TRUE;
-
-        entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_UNIFORM, loc);
-        this->variables.push_tail(entry);
-        break;
-      case ir_var_in:
-      case ir_var_out:
-      case ir_var_inout:
-        /* The linker assigns locations for varyings and attributes,
-         * including deprecated builtins (like gl_Color), user-assign
-         * generic attributes (glBindVertexLocation), and
-         * user-defined varyings.
-         *
-         * FINISHME: We would hit this path for function arguments.  Fix!
-         */
-        assert(ir->var->location != -1);
-        if (ir->var->mode == ir_var_in ||
-            ir->var->mode == ir_var_inout) {
-           entry = new(mem_ctx) variable_storage(ir->var,
-                                                 PROGRAM_INPUT,
-                                                 ir->var->location);
-
-           if (this->prog->Target == GL_VERTEX_PROGRAM_ARB &&
-               ir->var->location >= VERT_ATTRIB_GENERIC0) {
-              _mesa_add_attribute(prog->Attributes,
-                                  ir->var->name,
-                                  type_size(ir->var->type) * 4,
-                                  ir->var->type->gl_type,
-                                  ir->var->location - VERT_ATTRIB_GENERIC0);
-           }
-        } else {
-           entry = new(mem_ctx) variable_storage(ir->var,
-                                                 PROGRAM_OUTPUT,
-                                                 ir->var->location);
-        }
-
-        break;
-      case ir_var_auto:
-      case ir_var_temporary:
-        entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_TEMPORARY,
-                                              this->next_temp);
-        this->variables.push_tail(entry);
-
-        next_temp += type_size(ir->var->type);
-        break;
-      }
-
-      if (!entry) {
-        printf("Failed to make storage for %s\n", ir->var->name);
-        exit(1);
-      }
-   }
-
-   src_reg.file = entry->file;
-   src_reg.index = entry->index;
-   /* If the type is smaller than a vec4, replicate the last channel out. */
-   if (ir->type->is_scalar() || ir->type->is_vector())
-      src_reg.swizzle = swizzle_for_size(ir->var->type->vector_elements);
-   else
-      src_reg.swizzle = SWIZZLE_NOOP;
-   src_reg.reladdr = NULL;
-   src_reg.negate = 0;
-
-   this->result = src_reg;
-}
-
-void
-ir_to_mesa_visitor::visit(ir_dereference_array *ir)
-{
-   ir_constant *index;
-   ir_to_mesa_src_reg src_reg;
-   ir_dereference_variable *deref_var = ir->array->as_dereference_variable();
-   int element_size = type_size(ir->type);
-
-   index = ir->array_index->constant_expression_value();
-
-   if (deref_var && strncmp(deref_var->var->name,
-                           "gl_TextureMatrix",
-                           strlen("gl_TextureMatrix")) == 0) {
-      ir_to_mesa_src_reg src_reg;
-      struct variable_storage *entry;
-
-      entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, deref_var->var,
-                                    ir->array_index);
-      assert(entry);
-
-      src_reg.file = entry->file;
-      src_reg.index = entry->index;
-      src_reg.swizzle = swizzle_for_size(ir->type->vector_elements);
-      src_reg.negate = 0;
-
-      if (index) {
-        src_reg.reladdr = NULL;
-      } else {
-        ir_to_mesa_src_reg index_reg = get_temp(glsl_type::float_type);
-
-        ir->array_index->accept(this);
-        ir_to_mesa_emit_op2(ir, OPCODE_MUL,
-                            ir_to_mesa_dst_reg_from_src(index_reg),
-                            this->result, src_reg_for_float(element_size));
-
-        src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg);
-        memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg));
-      }
-
-      this->result = src_reg;
-      return;
-   }
-
-   ir->array->accept(this);
-   src_reg = this->result;
-
-   if (index) {
-      src_reg.index += index->value.i[0] * element_size;
-   } else {
-      ir_to_mesa_src_reg array_base = this->result;
-      /* Variable index array dereference.  It eats the "vec4" of the
-       * base of the array and an index that offsets the Mesa register
-       * index.
-       */
-      ir->array_index->accept(this);
-
-      ir_to_mesa_src_reg index_reg;
-
-      if (element_size == 1) {
-        index_reg = this->result;
-      } else {
-        index_reg = get_temp(glsl_type::float_type);
-
-        ir_to_mesa_emit_op2(ir, OPCODE_MUL,
-                            ir_to_mesa_dst_reg_from_src(index_reg),
-                            this->result, src_reg_for_float(element_size));
-      }
-
-      src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg);
-      memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg));
-   }
-
-   /* If the type is smaller than a vec4, replicate the last channel out. */
-   if (ir->type->is_scalar() || ir->type->is_vector())
-      src_reg.swizzle = swizzle_for_size(ir->type->vector_elements);
-   else
-      src_reg.swizzle = SWIZZLE_NOOP;
-
-   this->result = src_reg;
-}
-
-void
-ir_to_mesa_visitor::visit(ir_dereference_record *ir)
-{
-   unsigned int i;
-   const glsl_type *struct_type = ir->record->type;
-   int offset = 0;
-
-   ir->record->accept(this);
-
-   for (i = 0; i < struct_type->length; i++) {
-      if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
-        break;
-      offset += type_size(struct_type->fields.structure[i].type);
-   }
-   this->result.swizzle = swizzle_for_size(ir->type->vector_elements);
-   this->result.index += offset;
-}
-
-/**
- * We want to be careful in assignment setup to hit the actual storage
- * instead of potentially using a temporary like we might with the
- * ir_dereference handler.
- *
- * Thanks to ir_swizzle_swizzle, and ir_vec_index_to_swizzle, we
- * should only see potentially one variable array index of a vector,
- * and one swizzle, before getting to actual vec4 storage.  So handle
- * those, then go use ir_dereference to handle the rest.
- */
-static struct ir_to_mesa_dst_reg
-get_assignment_lhs(ir_instruction *ir, ir_to_mesa_visitor *v,
-                  ir_to_mesa_src_reg *r)
-{
-   struct ir_to_mesa_dst_reg dst_reg;
-   ir_swizzle *swiz;
-
-   ir_dereference_array *deref_array = ir->as_dereference_array();
-   /* This should have been handled by ir_vec_index_to_cond_assign */
-   if (deref_array) {
-      assert(!deref_array->array->type->is_vector());
-   }
-
-   /* Use the rvalue deref handler for the most part.  We'll ignore
-    * swizzles in it and write swizzles using writemask, though.
-    */
-   ir->accept(v);
-   dst_reg = ir_to_mesa_dst_reg_from_src(v->result);
-
-   if ((swiz = ir->as_swizzle())) {
-      int swizzles[4] = {
-        swiz->mask.x,
-        swiz->mask.y,
-        swiz->mask.z,
-        swiz->mask.w
-      };
-      int new_r_swizzle[4];
-      int orig_r_swizzle = r->swizzle;
-      int i;
-
-      for (i = 0; i < 4; i++) {
-        new_r_swizzle[i] = GET_SWZ(orig_r_swizzle, 0);
-      }
-
-      dst_reg.writemask = 0;
-      for (i = 0; i < 4; i++) {
-        if (i < swiz->mask.num_components) {
-           dst_reg.writemask |= 1 << swizzles[i];
-           new_r_swizzle[swizzles[i]] = GET_SWZ(orig_r_swizzle, i);
-        }
-      }
-
-      r->swizzle = MAKE_SWIZZLE4(new_r_swizzle[0],
-                                new_r_swizzle[1],
-                                new_r_swizzle[2],
-                                new_r_swizzle[3]);
-   }
-
-   return dst_reg;
-}
-
-void
-ir_to_mesa_visitor::visit(ir_assignment *ir)
-{
-   struct ir_to_mesa_dst_reg l;
-   struct ir_to_mesa_src_reg r;
-   int i;
-
-   assert(!ir->lhs->type->is_array());
-
-   ir->rhs->accept(this);
-   r = this->result;
-
-   l = get_assignment_lhs(ir->lhs, this, &r);
-
-   assert(l.file != PROGRAM_UNDEFINED);
-   assert(r.file != PROGRAM_UNDEFINED);
-
-   if (ir->condition) {
-      ir_to_mesa_src_reg condition;
-
-      ir->condition->accept(this);
-      condition = this->result;
-
-      /* We use the OPCODE_CMP (a < 0 ? b : c) for conditional moves,
-       * and the condition we produced is 0.0 or 1.0.  By flipping the
-       * sign, we can choose which value OPCODE_CMP produces without
-       * an extra computing the condition.
-       */
-      condition.negate = ~condition.negate;
-      for (i = 0; i < type_size(ir->lhs->type); i++) {
-        ir_to_mesa_emit_op3(ir, OPCODE_CMP, l,
-                            condition, r, ir_to_mesa_src_reg_from_dst(l));
-        l.index++;
-        r.index++;
-      }
-   } else {
-      for (i = 0; i < type_size(ir->lhs->type); i++) {
-        ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
-        l.index++;
-        r.index++;
-      }
-   }
-}
-
-
-void
-ir_to_mesa_visitor::visit(ir_constant *ir)
-{
-   ir_to_mesa_src_reg src_reg;
-   GLfloat stack_vals[4];
-   GLfloat *values = stack_vals;
-   unsigned int i;
-
-   if (ir->type->is_array()) {
-      ir->print();
-      printf("\n");
-      assert(!"FINISHME: array constants");
-   }
-
-   if (ir->type->is_matrix()) {
-      /* Unfortunately, 4 floats is all we can get into
-       * _mesa_add_unnamed_constant.  So, make a temp to store the
-       * matrix and move each constant value into it.  If we get
-       * lucky, copy propagation will eliminate the extra moves.
-       */
-      ir_to_mesa_src_reg mat = get_temp(glsl_type::vec4_type);
-      ir_to_mesa_dst_reg mat_column = ir_to_mesa_dst_reg_from_src(mat);
-
-      for (i = 0; i < ir->type->matrix_columns; i++) {
-        src_reg.file = PROGRAM_CONSTANT;
-
-        assert(ir->type->base_type == GLSL_TYPE_FLOAT);
-        values = &ir->value.f[i * ir->type->vector_elements];
-
-        src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
-                                                   values,
-                                                   ir->type->vector_elements,
-                                                   &src_reg.swizzle);
-        src_reg.reladdr = NULL;
-        src_reg.negate = 0;
-        ir_to_mesa_emit_op1(ir, OPCODE_MOV, mat_column, src_reg);
-
-        mat_column.index++;
-      }
-
-      this->result = mat;
-   }
-
-   src_reg.file = PROGRAM_CONSTANT;
-   switch (ir->type->base_type) {
-   case GLSL_TYPE_FLOAT:
-      values = &ir->value.f[0];
-      break;
-   case GLSL_TYPE_UINT:
-      for (i = 0; i < ir->type->vector_elements; i++) {
-        values[i] = ir->value.u[i];
-      }
-      break;
-   case GLSL_TYPE_INT:
-      for (i = 0; i < ir->type->vector_elements; i++) {
-        values[i] = ir->value.i[i];
-      }
-      break;
-   case GLSL_TYPE_BOOL:
-      for (i = 0; i < ir->type->vector_elements; i++) {
-        values[i] = ir->value.b[i];
-      }
-      break;
-   default:
-      assert(!"Non-float/uint/int/bool constant");
-   }
-
-   src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
-                                             values, ir->type->vector_elements,
-                                             &src_reg.swizzle);
-   src_reg.reladdr = NULL;
-   src_reg.negate = 0;
-
-   this->result = src_reg;
-}
-
-function_entry *
-ir_to_mesa_visitor::get_function_signature(ir_function_signature *sig)
-{
-   function_entry *entry;
-
-   foreach_iter(exec_list_iterator, iter, this->function_signatures) {
-      entry = (function_entry *)iter.get();
-
-      if (entry->sig == sig)
-        return entry;
-   }
-
-   entry = talloc(mem_ctx, function_entry);
-   entry->sig = sig;
-   entry->sig_id = this->next_signature_id++;
-   entry->bgn_inst = NULL;
-
-   /* Allocate storage for all the parameters. */
-   foreach_iter(exec_list_iterator, iter, sig->parameters) {
-      ir_variable *param = (ir_variable *)iter.get();
-      variable_storage *storage;
-
-      storage = find_variable_storage(param);
-      assert(!storage);
-
-      storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY,
-                                             this->next_temp);
-      this->variables.push_tail(storage);
-
-      this->next_temp += type_size(param->type);
-      break;
-   }
-
-   if (sig->return_type) {
-      entry->return_reg = get_temp(sig->return_type);
-   } else {
-      entry->return_reg = ir_to_mesa_undef;
-   }
-
-   this->function_signatures.push_tail(entry);
-   return entry;
-}
-
-void
-ir_to_mesa_visitor::visit(ir_call *ir)
-{
-   ir_to_mesa_instruction *call_inst;
-   ir_function_signature *sig = ir->get_callee();
-   function_entry *entry = get_function_signature(sig);
-   int i;
-
-   /* Process in parameters. */
-   exec_list_iterator sig_iter = sig->parameters.iterator();
-   foreach_iter(exec_list_iterator, iter, *ir) {
-      ir_rvalue *param_rval = (ir_rvalue *)iter.get();
-      ir_variable *param = (ir_variable *)sig_iter.get();
-
-      if (param->mode == ir_var_in ||
-         param->mode == ir_var_inout) {
-        variable_storage *storage = find_variable_storage(param);
-        assert(storage);
-
-        param_rval->accept(this);
-        ir_to_mesa_src_reg r = this->result;
-
-        ir_to_mesa_dst_reg l;
-        l.file = storage->file;
-        l.index = storage->index;
-        l.reladdr = NULL;
-        l.writemask = WRITEMASK_XYZW;
-        l.cond_mask = COND_TR;
-
-        for (i = 0; i < type_size(param->type); i++) {
-           ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
-           l.index++;
-           r.index++;
-        }
-      }
-
-      sig_iter.next();
-   }
-   assert(!sig_iter.has_next());
-
-   /* Emit call instruction */
-   call_inst = ir_to_mesa_emit_op1(ir, OPCODE_CAL,
-                                  ir_to_mesa_undef_dst, ir_to_mesa_undef);
-   call_inst->function = entry;
-
-   /* Process out parameters. */
-   sig_iter = sig->parameters.iterator();
-   foreach_iter(exec_list_iterator, iter, *ir) {
-      ir_rvalue *param_rval = (ir_rvalue *)iter.get();
-      ir_variable *param = (ir_variable *)sig_iter.get();
-
-      if (param->mode == ir_var_out ||
-         param->mode == ir_var_inout) {
-        variable_storage *storage = find_variable_storage(param);
-        assert(storage);
-
-        ir_to_mesa_src_reg r;
-        r.file = storage->file;
-        r.index = storage->index;
-        r.reladdr = NULL;
-        r.swizzle = SWIZZLE_NOOP;
-        r.negate = 0;
-
-        param_rval->accept(this);
-        ir_to_mesa_dst_reg l = ir_to_mesa_dst_reg_from_src(this->result);
-
-        for (i = 0; i < type_size(param->type); i++) {
-           ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
-           l.index++;
-           r.index++;
-        }
-      }
-
-      sig_iter.next();
-   }
-   assert(!sig_iter.has_next());
-
-   /* Process return value. */
-   this->result = entry->return_reg;
-}
-
-
-void
-ir_to_mesa_visitor::visit(ir_texture *ir)
-{
-   ir_to_mesa_src_reg result_src, coord, lod_info = { 0 }, projector;
-   ir_to_mesa_dst_reg result_dst, coord_dst;
-   ir_to_mesa_instruction *inst = NULL;
-   prog_opcode opcode = OPCODE_NOP;
-
-   ir->coordinate->accept(this);
-
-   /* Put our coords in a temp.  We'll need to modify them for shadow,
-    * projection, or LOD, so the only case we'd use it as is is if
-    * we're doing plain old texturing.  Mesa IR optimization should
-    * handle cleaning up our mess in that case.
-    */
-   coord = get_temp(glsl_type::vec4_type);
-   coord_dst = ir_to_mesa_dst_reg_from_src(coord);
-   ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst,
-                      this->result);
-
-   if (ir->projector) {
-      ir->projector->accept(this);
-      projector = this->result;
-   }
-
-   /* Storage for our result.  Ideally for an assignment we'd be using
-    * the actual storage for the result here, instead.
-    */
-   result_src = get_temp(glsl_type::vec4_type);
-   result_dst = ir_to_mesa_dst_reg_from_src(result_src);
-
-   switch (ir->op) {
-   case ir_tex:
-      opcode = OPCODE_TEX;
-      break;
-   case ir_txb:
-      opcode = OPCODE_TXB;
-      ir->lod_info.bias->accept(this);
-      lod_info = this->result;
-      break;
-   case ir_txl:
-      opcode = OPCODE_TXL;
-      ir->lod_info.lod->accept(this);
-      lod_info = this->result;
-      break;
-   case ir_txd:
-   case ir_txf:
-      assert(!"GLSL 1.30 features unsupported");
-      break;
-   }
-
-   if (ir->projector) {
-      if (opcode == OPCODE_TEX) {
-        /* Slot the projector in as the last component of the coord. */
-        coord_dst.writemask = WRITEMASK_W;
-        ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, projector);
-        coord_dst.writemask = WRITEMASK_XYZW;
-        opcode = OPCODE_TXP;
-      } else {
-        ir_to_mesa_src_reg coord_w = coord;
-        coord_w.swizzle = SWIZZLE_WWWW;
-
-        /* For the other TEX opcodes there's no projective version
-         * since the last slot is taken up by lod info.  Do the
-         * projective divide now.
-         */
-        coord_dst.writemask = WRITEMASK_W;
-        ir_to_mesa_emit_op1(ir, OPCODE_RCP, coord_dst, projector);
-
-        coord_dst.writemask = WRITEMASK_XYZ;
-        ir_to_mesa_emit_op2(ir, OPCODE_MUL, coord_dst, coord, coord_w);
-
-        coord_dst.writemask = WRITEMASK_XYZW;
-        coord.swizzle = SWIZZLE_XYZW;
-      }
-   }
-
-   if (ir->shadow_comparitor) {
-      /* Slot the shadow value in as the second to last component of the
-       * coord.
-       */
-      ir->shadow_comparitor->accept(this);
-      coord_dst.writemask = WRITEMASK_Z;
-      ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, this->result);
-      coord_dst.writemask = WRITEMASK_XYZW;
-   }
-
-   if (opcode == OPCODE_TXL || opcode == OPCODE_TXB) {
-      /* Mesa IR stores lod or lod bias in the last channel of the coords. */
-      coord_dst.writemask = WRITEMASK_W;
-      ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, lod_info);
-      coord_dst.writemask = WRITEMASK_XYZW;
-   }
-
-   inst = ir_to_mesa_emit_op1(ir, opcode, result_dst, coord);
-
-   if (ir->shadow_comparitor)
-      inst->tex_shadow = GL_TRUE;
-
-   ir_dereference_variable *sampler = ir->sampler->as_dereference_variable();
-   assert(sampler); /* FINISHME: sampler arrays */
-   /* generate the mapping, remove when we generate storage at
-    * declaration time
-    */
-   sampler->accept(this);
-
-   inst->sampler = get_sampler_number(sampler->var->location);
-
-   switch (sampler->type->sampler_dimensionality) {
-   case GLSL_SAMPLER_DIM_1D:
-      inst->tex_target = TEXTURE_1D_INDEX;
-      break;
-   case GLSL_SAMPLER_DIM_2D:
-      inst->tex_target = TEXTURE_2D_INDEX;
-      break;
-   case GLSL_SAMPLER_DIM_3D:
-      inst->tex_target = TEXTURE_3D_INDEX;
-      break;
-   case GLSL_SAMPLER_DIM_CUBE:
-      inst->tex_target = TEXTURE_CUBE_INDEX;
-      break;
-   default:
-      assert(!"FINISHME: other texture targets");
-   }
-
-   this->result = result_src;
-}
-
-void
-ir_to_mesa_visitor::visit(ir_return *ir)
-{
-   assert(current_function);
-
-   if (ir->get_value()) {
-      ir_to_mesa_dst_reg l;
-      int i;
-
-      ir->get_value()->accept(this);
-      ir_to_mesa_src_reg r = this->result;
-
-      l = ir_to_mesa_dst_reg_from_src(current_function->return_reg);
-
-      for (i = 0; i < type_size(current_function->sig->return_type); i++) {
-        ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
-        l.index++;
-        r.index++;
-      }
-   }
-
-   ir_to_mesa_emit_op0(ir, OPCODE_RET);
-}
-
-void
-ir_to_mesa_visitor::visit(ir_discard *ir)
-{
-   assert(ir->condition == NULL); /* FINISHME */
-
-   ir_to_mesa_emit_op0(ir, OPCODE_KIL_NV);
-}
-
-void
-ir_to_mesa_visitor::visit(ir_if *ir)
-{
-   ir_to_mesa_instruction *cond_inst, *if_inst, *else_inst = NULL;
-   ir_to_mesa_instruction *prev_inst;
-
-   prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
-
-   ir->condition->accept(this);
-   assert(this->result.file != PROGRAM_UNDEFINED);
-
-   if (ctx->Shader.EmitCondCodes) {
-      cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
-
-      /* See if we actually generated any instruction for generating
-       * the condition.  If not, then cook up a move to a temp so we
-       * have something to set cond_update on.
-       */
-      if (cond_inst == prev_inst) {
-        ir_to_mesa_src_reg temp = get_temp(glsl_type::bool_type);
-        cond_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_MOV,
-                                        ir_to_mesa_dst_reg_from_src(temp),
-                                        result);
-      }
-      cond_inst->cond_update = GL_TRUE;
-
-      if_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_IF);
-      if_inst->dst_reg.cond_mask = COND_NE;
-   } else {
-      if_inst = ir_to_mesa_emit_op1(ir->condition,
-                                   OPCODE_IF, ir_to_mesa_undef_dst,
-                                   this->result);
-   }
-
-   this->instructions.push_tail(if_inst);
-
-   visit_exec_list(&ir->then_instructions, this);
-
-   if (!ir->else_instructions.is_empty()) {
-      else_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_ELSE);
-      visit_exec_list(&ir->else_instructions, this);
-   }
-
-   if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF,
-                                ir_to_mesa_undef_dst, ir_to_mesa_undef);
-}
-
-ir_to_mesa_visitor::ir_to_mesa_visitor()
-{
-   result.file = PROGRAM_UNDEFINED;
-   next_temp = 1;
-   next_signature_id = 1;
-   sampler_map = NULL;
-   sampler_map_size = 0;
-   current_function = NULL;
-}
-
-static struct prog_src_register
-mesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)
-{
-   struct prog_src_register mesa_reg;
-
-   mesa_reg.File = reg.file;
-   assert(reg.index < (1 << INST_INDEX_BITS) - 1);
-   mesa_reg.Index = reg.index;
-   mesa_reg.Swizzle = reg.swizzle;
-   mesa_reg.RelAddr = reg.reladdr != NULL;
-   mesa_reg.Negate = reg.negate;
-   mesa_reg.Abs = 0;
-
-   return mesa_reg;
-}
-
-static void
-set_branchtargets(ir_to_mesa_visitor *v,
-                 struct prog_instruction *mesa_instructions,
-                 int num_instructions)
-{
-   int if_count = 0, loop_count = 0;
-   int *if_stack, *loop_stack;
-   int if_stack_pos = 0, loop_stack_pos = 0;
-   int i, j;
-
-   for (i = 0; i < num_instructions; i++) {
-      switch (mesa_instructions[i].Opcode) {
-      case OPCODE_IF:
-        if_count++;
-        break;
-      case OPCODE_BGNLOOP:
-        loop_count++;
-        break;
-      case OPCODE_BRK:
-      case OPCODE_CONT:
-        mesa_instructions[i].BranchTarget = -1;
-        break;
-      default:
-        break;
-      }
-   }
-
-   if_stack = (int *)calloc(if_count, sizeof(*if_stack));
-   loop_stack = (int *)calloc(loop_count, sizeof(*loop_stack));
-
-   for (i = 0; i < num_instructions; i++) {
-      switch (mesa_instructions[i].Opcode) {
-      case OPCODE_IF:
-        if_stack[if_stack_pos] = i;
-        if_stack_pos++;
-        break;
-      case OPCODE_ELSE:
-        mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
-        if_stack[if_stack_pos - 1] = i;
-        break;
-      case OPCODE_ENDIF:
-        mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
-        if_stack_pos--;
-        break;
-      case OPCODE_BGNLOOP:
-        loop_stack[loop_stack_pos] = i;
-        loop_stack_pos++;
-        break;
-      case OPCODE_ENDLOOP:
-        loop_stack_pos--;
-        /* Rewrite any breaks/conts at this nesting level (haven't
-         * already had a BranchTarget assigned) to point to the end
-         * of the loop.
-         */
-        for (j = loop_stack[loop_stack_pos]; j < i; j++) {
-           if (mesa_instructions[j].Opcode == OPCODE_BRK ||
-               mesa_instructions[j].Opcode == OPCODE_CONT) {
-              if (mesa_instructions[j].BranchTarget == -1) {
-                 mesa_instructions[j].BranchTarget = i;
-              }
-           }
-        }
-        /* The loop ends point at each other. */
-        mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos];
-        mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i;
-        break;
-      case OPCODE_CAL:
-        foreach_iter(exec_list_iterator, iter, v->function_signatures) {
-           function_entry *entry = (function_entry *)iter.get();
-
-           if (entry->sig_id == mesa_instructions[i].BranchTarget) {
-              mesa_instructions[i].BranchTarget = entry->inst;
-              break;
-           }
-        }
-        break;
-      default:
-        break;
-      }
-   }
-
-   free(if_stack);
-}
-
-static void
-print_program(struct prog_instruction *mesa_instructions,
-             ir_instruction **mesa_instruction_annotation,
-             int num_instructions)
-{
-   ir_instruction *last_ir = NULL;
-   int i;
-   int indent = 0;
-
-   for (i = 0; i < num_instructions; i++) {
-      struct prog_instruction *mesa_inst = mesa_instructions + i;
-      ir_instruction *ir = mesa_instruction_annotation[i];
-
-      fprintf(stdout, "%3d: ", i);
-
-      if (last_ir != ir && ir) {
-        int j;
-
-        for (j = 0; j < indent; j++) {
-           fprintf(stdout, " ");
-        }
-        ir->print();
-        printf("\n");
-        last_ir = ir;
-
-        fprintf(stdout, "     "); /* line number spacing. */
-      }
-
-      indent = _mesa_fprint_instruction_opt(stdout, mesa_inst, indent,
-                                           PROG_PRINT_DEBUG, NULL);
-   }
-}
-
-static void
-mark_input(struct gl_program *prog,
-          int index,
-          GLboolean reladdr)
-{
-   prog->InputsRead |= BITFIELD64_BIT(index);
-   int i;
-
-   if (reladdr) {
-      if (index >= FRAG_ATTRIB_TEX0 && index <= FRAG_ATTRIB_TEX7) {
-        for (i = 0; i < 8; i++) {
-           prog->InputsRead |= BITFIELD64_BIT(FRAG_ATTRIB_TEX0 + i);
-        }
-      } else {
-        assert(!"FINISHME: Mark InputsRead for varying arrays");
-      }
-   }
-}
-
-static void
-mark_output(struct gl_program *prog,
-          int index,
-          GLboolean reladdr)
-{
-   prog->OutputsWritten |= BITFIELD64_BIT(index);
-   int i;
-
-   if (reladdr) {
-      if (index >= VERT_RESULT_TEX0 && index <= VERT_RESULT_TEX7) {
-        for (i = 0; i < 8; i++) {
-           prog->OutputsWritten |= BITFIELD64_BIT(FRAG_ATTRIB_TEX0 + i);
-        }
-      } else {
-        assert(!"FINISHME: Mark OutputsWritten for varying arrays");
-      }
-   }
-}
-
-static void
-count_resources(struct gl_program *prog)
-{
-   unsigned int i;
-
-   prog->InputsRead = 0;
-   prog->OutputsWritten = 0;
-   prog->SamplersUsed = 0;
-
-   for (i = 0; i < prog->NumInstructions; i++) {
-      struct prog_instruction *inst = &prog->Instructions[i];
-      unsigned int reg;
-
-      switch (inst->DstReg.File) {
-      case PROGRAM_OUTPUT:
-        mark_output(prog, inst->DstReg.Index, inst->DstReg.RelAddr);
-        break;
-      case PROGRAM_INPUT:
-        mark_input(prog, inst->DstReg.Index, inst->DstReg.RelAddr);
-        break;
-      default:
-        break;
-      }
-
-      for (reg = 0; reg < _mesa_num_inst_src_regs(inst->Opcode); reg++) {
-        switch (inst->SrcReg[reg].File) {
-        case PROGRAM_OUTPUT:
-           mark_output(prog, inst->SrcReg[reg].Index,
-                       inst->SrcReg[reg].RelAddr);
-           break;
-        case PROGRAM_INPUT:
-           mark_input(prog, inst->SrcReg[reg].Index, inst->SrcReg[reg].RelAddr);
-           break;
-        default:
-           break;
-        }
-      }
-
-      /* Instead of just using the uniform's value to map to a
-       * sampler, Mesa first allocates a separate number for the
-       * sampler (_mesa_add_sampler), then we reindex it down to a
-       * small integer (sampler_map[], SamplersUsed), then that gets
-       * mapped to the uniform's value, and we get an actual sampler.
-       */
-      if (_mesa_is_tex_instruction(inst->Opcode)) {
-        prog->SamplerTargets[inst->TexSrcUnit] =
-           (gl_texture_index)inst->TexSrcTarget;
-        prog->SamplersUsed |= 1 << inst->TexSrcUnit;
-        if (inst->TexShadow) {
-           prog->ShadowSamplers |= 1 << inst->TexSrcUnit;
-        }
-      }
-   }
-
-   _mesa_update_shader_textures_used(prog);
-}
-
-/* Each stage has some uniforms in its Parameters list.  The Uniforms
- * list for the linked shader program has a pointer to these uniforms
- * in each of the stage's Parameters list, so that their values can be
- * updated when a uniform is set.
- */
-static void
-link_uniforms_to_shared_uniform_list(struct gl_uniform_list *uniforms,
-                                    struct gl_program *prog)
-{
-   unsigned int i;
-
-   for (i = 0; i < prog->Parameters->NumParameters; i++) {
-      const struct gl_program_parameter *p = prog->Parameters->Parameters + i;
-
-      if (p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) {
-        struct gl_uniform *uniform =
-           _mesa_append_uniform(uniforms, p->Name, prog->Target, i);
-        if (uniform)
-           uniform->Initialized = p->Initialized;
-      }
-   }
-}
-
-struct gl_program *
-get_mesa_program(GLcontext *ctx, struct gl_shader_program *shader_program,
-                struct gl_shader *shader)
-{
-   void *mem_ctx = shader_program;
-   ir_to_mesa_visitor v;
-   struct prog_instruction *mesa_instructions, *mesa_inst;
-   ir_instruction **mesa_instruction_annotation;
-   int i;
-   struct gl_program *prog;
-   GLenum target;
-   const char *target_string;
-   GLboolean progress;
-
-   switch (shader->Type) {
-   case GL_VERTEX_SHADER:
-      target = GL_VERTEX_PROGRAM_ARB;
-      target_string = "vertex";
-      break;
-   case GL_FRAGMENT_SHADER:
-      target = GL_FRAGMENT_PROGRAM_ARB;
-      target_string = "fragment";
-      break;
-   default:
-      assert(!"should not be reached");
-      break;
-   }
-
-   validate_ir_tree(shader->ir);
-
-   prog = ctx->Driver.NewProgram(ctx, target, 1);
-   if (!prog)
-      return NULL;
-   prog->Parameters = _mesa_new_parameter_list();
-   prog->Varying = _mesa_new_parameter_list();
-   prog->Attributes = _mesa_new_parameter_list();
-   v.ctx = ctx;
-   v.prog = prog;
-
-   v.mem_ctx = talloc_new(NULL);
-
-   /* Emit Mesa IR for main(). */
-   visit_exec_list(shader->ir, &v);
-   v.ir_to_mesa_emit_op0(NULL, OPCODE_END);
-
-   /* Now emit bodies for any functions that were used. */
-   do {
-      progress = GL_FALSE;
-
-      foreach_iter(exec_list_iterator, iter, v.function_signatures) {
-        function_entry *entry = (function_entry *)iter.get();
-
-        if (!entry->bgn_inst) {
-           v.current_function = entry;
-
-           entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_BGNSUB);
-           entry->bgn_inst->function = entry;
-
-           visit_exec_list(&entry->sig->body, &v);
-
-           entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_RET);
-           entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_ENDSUB);
-           progress = GL_TRUE;
-        }
-      }
-   } while (progress);
-
-   prog->NumTemporaries = v.next_temp;
-
-   int num_instructions = 0;
-   foreach_iter(exec_list_iterator, iter, v.instructions) {
-      num_instructions++;
-   }
-
-   mesa_instructions =
-      (struct prog_instruction *)calloc(num_instructions,
-                                       sizeof(*mesa_instructions));
-   mesa_instruction_annotation = talloc_array(mem_ctx, ir_instruction *,
-                                             num_instructions);
-
-   mesa_inst = mesa_instructions;
-   i = 0;
-   foreach_iter(exec_list_iterator, iter, v.instructions) {
-      ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get();
-
-      mesa_inst->Opcode = inst->op;
-      mesa_inst->CondUpdate = inst->cond_update;
-      mesa_inst->DstReg.File = inst->dst_reg.file;
-      mesa_inst->DstReg.Index = inst->dst_reg.index;
-      mesa_inst->DstReg.CondMask = inst->dst_reg.cond_mask;
-      mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask;
-      mesa_inst->DstReg.RelAddr = inst->dst_reg.reladdr != NULL;
-      mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]);
-      mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]);
-      mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]);
-      mesa_inst->TexSrcUnit = inst->sampler;
-      mesa_inst->TexSrcTarget = inst->tex_target;
-      mesa_inst->TexShadow = inst->tex_shadow;
-      mesa_instruction_annotation[i] = inst->ir;
-
-      if (ctx->Shader.EmitNoIfs && mesa_inst->Opcode == OPCODE_IF) {
-        shader_program->InfoLog =
-           talloc_asprintf_append(shader_program->InfoLog,
-                                  "Couldn't flatten if statement\n");
-        shader_program->LinkStatus = false;
-      }
-
-      if (mesa_inst->Opcode == OPCODE_BGNSUB)
-        inst->function->inst = i;
-      else if (mesa_inst->Opcode == OPCODE_CAL)
-        mesa_inst->BranchTarget = inst->function->sig_id; /* rewritten later */
-      else if (mesa_inst->Opcode == OPCODE_ARL)
-        prog->NumAddressRegs = 1;
-
-      mesa_inst++;
-      i++;
-   }
-
-   set_branchtargets(&v, mesa_instructions, num_instructions);
-   if (ctx->Shader.Flags & GLSL_DUMP) {
-      printf("Mesa %s program:\n", target_string);
-      print_program(mesa_instructions, mesa_instruction_annotation,
-                   num_instructions);
-   }
-
-   prog->Instructions = mesa_instructions;
-   prog->NumInstructions = num_instructions;
-
-   _mesa_reference_program(ctx, &shader->Program, prog);
-
-   if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) {
-      _mesa_optimize_program(ctx, prog);
-   }
-
-   return prog;
-}
-
-extern "C" {
-
-void
-_mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader)
-{
-   struct _mesa_glsl_parse_state *state =
-      new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader);
-
-   const char *source = shader->Source;
-   state->error = preprocess(state, &source, &state->info_log,
-                            &ctx->Extensions);
-
-   if (!state->error) {
-     _mesa_glsl_lexer_ctor(state, source);
-     _mesa_glsl_parse(state);
-     _mesa_glsl_lexer_dtor(state);
-   }
-
-   shader->ir = new(shader) exec_list;
-   if (!state->error && !state->translation_unit.is_empty())
-      _mesa_ast_to_hir(shader->ir, state);
-
-   if (!state->error && !shader->ir->is_empty()) {
-      validate_ir_tree(shader->ir);
-
-      /* Lowering */
-      do_mat_op_to_vec(shader->ir);
-      do_mod_to_fract(shader->ir);
-      do_div_to_mul_rcp(shader->ir);
-
-      /* Optimization passes */
-      bool progress;
-      do {
-        progress = false;
-
-        progress = do_function_inlining(shader->ir) || progress;
-        progress = do_if_simplification(shader->ir) || progress;
-        progress = do_copy_propagation(shader->ir) || progress;
-        progress = do_dead_code_local(shader->ir) || progress;
-        progress = do_dead_code_unlinked(state, shader->ir) || progress;
-        progress = do_constant_variable_unlinked(shader->ir) || progress;
-        progress = do_constant_folding(shader->ir) || progress;
-        progress = do_if_return(shader->ir) || progress;
-        if (ctx->Shader.EmitNoIfs)
-           progress = do_if_to_cond_assign(shader->ir) || progress;
-
-        progress = do_vec_index_to_swizzle(shader->ir) || progress;
-        /* Do this one after the previous to let the easier pass handle
-         * constant vector indexing.
-         */
-        progress = do_vec_index_to_cond_assign(shader->ir) || progress;
-
-        progress = do_swizzle_swizzle(shader->ir) || progress;
-      } while (progress);
-
-      validate_ir_tree(shader->ir);
-   }
-
-   shader->symbols = state->symbols;
-
-   shader->CompileStatus = !state->error;
-   shader->InfoLog = state->info_log;
-   shader->Version = state->language_version;
-   memcpy(shader->builtins_to_link, state->builtins_to_link,
-         sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link);
-   shader->num_builtins_to_link = state->num_builtins_to_link;
-
-   /* Retain any live IR, but trash the rest. */
-   reparent_ir(shader->ir, shader);
-
-   talloc_free(state);
- }
-
-void
-_mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
-{
-   unsigned int i;
-
-   _mesa_clear_shader_program_data(ctx, prog);
-
-   prog->LinkStatus = GL_TRUE;
-
-   for (i = 0; i < prog->NumShaders; i++) {
-      if (!prog->Shaders[i]->CompileStatus) {
-        prog->InfoLog =
-           talloc_asprintf_append(prog->InfoLog,
-                                  "linking with uncompiled shader");
-        prog->LinkStatus = GL_FALSE;
-      }
-   }
-
-   prog->Varying = _mesa_new_parameter_list();
-   _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL);
-   _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL);
-
-   if (prog->LinkStatus) {
-      link_shaders(prog);
-
-      /* We don't use the linker's uniforms list, and cook up our own at
-       * generate time.
-       */
-      free(prog->Uniforms);
-      prog->Uniforms = _mesa_new_uniform_list();
-   }
-
-   if (prog->LinkStatus) {
-      for (i = 0; i < prog->_NumLinkedShaders; i++) {
-        struct gl_program *linked_prog;
-
-        linked_prog = get_mesa_program(ctx, prog,
-                                       prog->_LinkedShaders[i]);
-        count_resources(linked_prog);
-
-        link_uniforms_to_shared_uniform_list(prog->Uniforms, linked_prog);
-
-        switch (prog->_LinkedShaders[i]->Type) {
-        case GL_VERTEX_SHADER:
-           _mesa_reference_vertprog(ctx, &prog->VertexProgram,
-                                    (struct gl_vertex_program *)linked_prog);
-           ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
-                                           linked_prog);
-           break;
-        case GL_FRAGMENT_SHADER:
-           _mesa_reference_fragprog(ctx, &prog->FragmentProgram,
-                                    (struct gl_fragment_program *)linked_prog);
-           ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
-                                           linked_prog);
-           break;
-        }
-      }
-   }
-}
-
-} /* extern "C" */
diff --git a/src/mesa/shader/ir_to_mesa.h b/src/mesa/shader/ir_to_mesa.h
deleted file mode 100644 (file)
index e832f84..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright Â© 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "main/config.h"
-#include "main/mtypes.h"
-
-void _mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *sh);
-void _mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/src/mesa/shader/lex.yy.c b/src/mesa/shader/lex.yy.c
deleted file mode 100644 (file)
index 4c5c644..0000000
+++ /dev/null
@@ -1,3655 +0,0 @@
-
-#line 3 "lex.yy.c"
-
-#define  YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 35
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with  platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types. 
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t; 
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-#endif /* ! C99 */
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN               (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN              (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN              (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX               (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX              (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX              (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX              (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX             (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX             (4294967295U)
-#endif
-
-#endif /* ! FLEXINT_H */
-
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else  /* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif /* defined (__STDC__) */
-#endif /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index.  If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
- */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
-
-/* An opaque pointer. */
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
-typedef void* yyscan_t;
-#endif
-
-/* For convenience, these vars (plus the bison vars far below)
-   are macros in the reentrant scanner. */
-#define yyin yyg->yyin_r
-#define yyout yyg->yyout_r
-#define yyextra yyg->yyextra_r
-#define yyleng yyg->yyleng_r
-#define yytext yyg->yytext_r
-#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
-#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
-#define yy_flex_debug yyg->yy_flex_debug_r
-
-/* Enter a start condition.  This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN yyg->yy_start = 1 + 2 *
-
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state.  The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START ((yyg->yy_start - 1) / 2)
-#define YYSTATE YY_START
-
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart(yyin ,yyscanner )
-
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#define YY_BUF_SIZE 16384
-#endif
-
-/* The state buf must be large enough to hold one state per character in the main buffer.
- */
-#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-
-    #define YY_LESS_LINENO(n)
-    
-/* Return all but the first "n" matched characters back to the input stream. */
-#define yyless(n) \
-       do \
-               { \
-               /* Undo effects of setting up yytext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-               *yy_cp = yyg->yy_hold_char; \
-               YY_RESTORE_YY_MORE_OFFSET \
-               yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
-               YY_DO_BEFORE_ACTION; /* set up yytext again */ \
-               } \
-       while ( 0 )
-
-#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
-       {
-       FILE *yy_input_file;
-
-       char *yy_ch_buf;                /* input buffer */
-       char *yy_buf_pos;               /* current position in input buffer */
-
-       /* Size of input buffer in bytes, not including room for EOB
-        * characters.
-        */
-       yy_size_t yy_buf_size;
-
-       /* Number of characters read into yy_ch_buf, not including EOB
-        * characters.
-        */
-       int yy_n_chars;
-
-       /* Whether we "own" the buffer - i.e., we know we created it,
-        * and can realloc() it to grow it, and should free() it to
-        * delete it.
-        */
-       int yy_is_our_buffer;
-
-       /* Whether this is an "interactive" input source; if so, and
-        * if we're using stdio for input, then we want to use getc()
-        * instead of fread(), to make sure we stop fetching input after
-        * each newline.
-        */
-       int yy_is_interactive;
-
-       /* Whether we're considered to be at the beginning of a line.
-        * If so, '^' rules will be active on the next match, otherwise
-        * not.
-        */
-       int yy_at_bol;
-
-    int yy_bs_lineno; /**< The line count. */
-    int yy_bs_column; /**< The column count. */
-    
-       /* Whether to try to fill the input buffer when we reach the
-        * end of it.
-        */
-       int yy_fill_buffer;
-
-       int yy_buffer_status;
-
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
-       /* When an EOF's been seen but there's still some text to process
-        * then we mark the buffer as YY_EOF_PENDING, to indicate that we
-        * shouldn't try reading from the input source any more.  We might
-        * still have a bunch of tokens to match, though, because of
-        * possible backing-up.
-        *
-        * When we actually see the EOF, we change the status to "new"
-        * (via yyrestart()), so that the user can continue scanning by
-        * just pointing yyin at a new input file.
-        */
-#define YY_BUFFER_EOF_PENDING 2
-
-       };
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
- *
- * Returns the top of the stack, or NULL.
- */
-#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
-                          ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
-                          : NULL)
-
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
-
-void yyrestart (FILE *input_file ,yyscan_t yyscanner );
-void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
-void yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-void yypop_buffer_state (yyscan_t yyscanner );
-
-static void yyensure_buffer_stack (yyscan_t yyscanner );
-static void yy_load_buffer_state (yyscan_t yyscanner );
-static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
-
-#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
-
-YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
-YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
-
-void *yyalloc (yy_size_t ,yyscan_t yyscanner );
-void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
-void yyfree (void * ,yyscan_t yyscanner );
-
-#define yy_new_buffer yy_create_buffer
-
-#define yy_set_interactive(is_interactive) \
-       { \
-       if ( ! YY_CURRENT_BUFFER ){ \
-        yyensure_buffer_stack (yyscanner); \
-               YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
-       } \
-       YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
-       }
-
-#define yy_set_bol(at_bol) \
-       { \
-       if ( ! YY_CURRENT_BUFFER ){\
-        yyensure_buffer_stack (yyscanner); \
-               YY_CURRENT_BUFFER_LVALUE =    \
-            yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
-       } \
-       YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
-       }
-
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
-
-#define yywrap(n) 1
-#define YY_SKIP_YYWRAP
-
-typedef unsigned char YY_CHAR;
-
-typedef int yy_state_type;
-
-#define yytext_ptr yytext_r
-
-static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state  ,yyscan_t yyscanner);
-static int yy_get_next_buffer (yyscan_t yyscanner );
-static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up yytext.
- */
-#define YY_DO_BEFORE_ACTION \
-       yyg->yytext_ptr = yy_bp; \
-       yyleng = (size_t) (yy_cp - yy_bp); \
-       yyg->yy_hold_char = *yy_cp; \
-       *yy_cp = '\0'; \
-       yyg->yy_c_buf_p = yy_cp;
-
-#define YY_NUM_RULES 170
-#define YY_END_OF_BUFFER 171
-/* This struct is not used in this scanner,
-   but its presence is necessary. */
-struct yy_trans_info
-       {
-       flex_int32_t yy_verify;
-       flex_int32_t yy_nxt;
-       };
-static yyconst flex_int16_t yy_accept[850] =
-    {   0,
-        0,    0,  171,  169,  167,  166,  169,  169,  139,  165,
-      141,  141,  141,  141,  139,  139,  139,  139,  139,  139,
-      139,  139,  139,  139,  139,  139,  139,  139,  139,  139,
-      139,  139,  139,  139,  139,  167,    0,    0,  168,  139,
-        0,  140,  142,  162,  162,    0,    0,    0,    0,  162,
-        0,    0,    0,    0,    0,    0,    0,  119,  163,  120,
-      121,  153,  153,  153,  153,    0,  141,    0,  127,  128,
-      129,  139,  139,  139,  139,  139,  139,  139,  139,  139,
-      139,  139,  139,  139,  139,  139,  139,  139,  139,  139,
-      139,  139,  139,  139,  139,  139,  139,  139,  139,  139,
-
-      139,  139,  139,  139,  139,  139,  139,  139,  139,  139,
-      139,  139,  139,  139,  139,  139,  139,  139,  139,  139,
-      139,  139,  139,  139,  139,  139,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,  161,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,  160,  160,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-      159,  159,  159,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,  150,  150,  150,  151,  151,  152,  143,
-      142,  143,    0,  144,   11,   12,  139,   13,  139,  139,
-       14,   15,  139,   16,   17,   18,   19,   20,   21,    6,
-
-       22,   23,   24,   25,   26,   28,   27,   29,   30,   31,
-       32,   33,   34,   35,  139,  139,  139,  139,  139,   40,
-       41,  139,   42,   43,   44,   45,   46,   47,   48,  139,
-       49,   50,   51,   52,   53,   54,   55,  139,   56,   57,
-       58,   59,  139,  139,   64,   65,  139,  139,  139,  139,
-      139,  139,    0,    0,    0,    0,  142,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,   80,   81,   83,
-        0,  158,    0,    0,    0,    0,    0,    0,   97,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,  157,
-      156,  156,  109,    0,    0,    0,    0,    0,    0,    0,
-
-        0,    0,    0,  147,  147,  148,  149,    0,  145,   11,
-       11,  139,   12,   12,   12,  139,  139,  139,  139,  139,
-       15,   15,  139,  130,   16,   16,  139,   17,   17,  139,
-       18,   18,  139,   19,   19,  139,   20,   20,  139,   21,
-       21,  139,   22,   22,  139,   24,   24,  139,   25,   25,
-      139,   28,   28,  139,   27,   27,  139,   30,   30,  139,
-       31,   31,  139,   32,   32,  139,   33,   33,  139,   34,
-       34,  139,   35,   35,  139,  139,  139,  139,   36,  139,
-       38,  139,   40,   40,  139,   41,   41,  139,  131,   42,
-       42,  139,   43,   43,  139,  139,   45,   45,  139,   46,
-
-       46,  139,   47,   47,  139,   48,   48,  139,  139,   49,
-       49,  139,   50,   50,  139,   51,   51,  139,   52,   52,
-      139,   53,   53,  139,   54,   54,  139,  139,   10,   56,
-      139,   57,  139,   58,  139,   59,  139,   60,  139,   62,
-      139,   64,   64,  139,  139,  139,  139,  139,  139,  139,
-      139,    0,  164,    0,    0,    0,   73,   74,    0,    0,
-        0,    0,    0,    0,    0,   85,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,  155,    0,    0,    0,  113,    0,
-      115,    0,    0,    0,    0,    0,    0,  154,  146,  139,
-
-      139,  139,    4,  139,  139,  139,  139,  139,  139,  139,
-      139,  139,  139,  139,  139,  139,  139,  139,  139,  139,
-      139,  139,  139,  139,  139,  139,    9,   37,   39,  139,
-      139,  139,  139,  139,  139,  139,  139,  139,  139,  139,
-      139,  139,  139,  139,  139,  139,  139,  139,  139,  139,
-       60,  139,   61,   62,  139,   63,  139,  139,  139,  139,
-      139,   69,  139,  139,    0,    0,    0,    0,    0,   75,
-       76,    0,    0,    0,    0,   84,    0,    0,   88,   91,
-        0,    0,    0,    0,    0,    0,    0,  102,  103,    0,
-        0,    0,    0,  108,    0,    0,    0,    0,    0,    0,
-
-        0,    0,    0,    0,  139,  139,  139,  139,  139,  139,
-        5,  139,  139,  139,  139,  139,  139,  139,  139,  139,
-      139,  139,  139,  139,  139,  139,  139,  139,  139,  139,
-        7,    8,  139,  139,  139,  139,  139,  139,  139,  139,
-      139,  139,  139,  139,  139,  139,  139,  139,  139,  139,
-      139,  139,  139,  139,   61,  139,  139,   63,  139,  139,
-      139,  139,  139,   70,  139,   66,    0,    0,    0,    0,
-      124,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-       94,    0,   98,   99,    0,  101,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,  117,  118,    0,    0,
-
-      125,   11,    3,   12,  135,  136,  139,   14,   15,   16,
-       17,   18,   19,   20,   21,   22,   24,   25,   28,   27,
-       30,   31,   32,   33,   34,   35,   40,   41,   42,   43,
-       44,   45,   46,   47,   48,  139,  139,  139,   49,   50,
-       51,   52,   53,   54,   55,   56,   57,   58,   59,  139,
-      139,  139,  139,   64,   65,  139,   68,  126,    0,    0,
-       71,    0,   77,    0,    0,    0,   86,    0,    0,    0,
-        0,    0,    0,  100,    0,    0,  106,   93,    0,    0,
-        0,    0,    0,    0,  122,    0,  139,  132,  133,  139,
-       60,  139,   62,  139,   67,    0,    0,    0,    0,   79,
-
-       82,   87,    0,    0,   92,    0,    0,    0,  105,    0,
-        0,    0,    0,  114,  116,    0,  139,  139,   61,   63,
-        2,    1,    0,   78,    0,   90,    0,   96,  104,    0,
-        0,  111,  112,  123,  139,  134,    0,   89,    0,  107,
-      110,  139,   72,   95,  139,  139,  137,  138,    0
-    } ;
-
-static yyconst flex_int32_t yy_ec[256] =
-    {   0,
-        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
-        1,    1,    4,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    2,    5,    1,    6,    7,    1,    1,    1,    1,
-        1,    1,    8,    1,    8,    9,    1,   10,   11,   12,
-       13,   14,   15,   15,   15,   15,   15,    1,    1,    1,
-        1,    1,    1,    1,   16,   17,   18,   19,   20,   21,
-       22,   23,   24,    7,   25,   26,   27,   28,   29,   30,
-       31,   32,   33,   34,   35,   36,   37,   38,   39,   40,
-        1,    1,    1,    1,   41,    1,   42,   43,   44,   45,
-
-       46,   47,   48,   49,   50,   51,   52,   53,   54,   55,
-       56,   57,   58,   59,   60,   61,   62,   63,   64,   65,
-       66,   67,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1
-    } ;
-
-static yyconst flex_int32_t yy_meta[68] =
-    {   0,
-        1,    1,    1,    1,    1,    1,    2,    1,    3,    2,
-        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-        2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-        2,    2,    2,    2,    2,    2,    2
-    } ;
-
-static yyconst flex_int16_t yy_base[853] =
-    {   0,
-        0,    0, 1299, 1300,   66, 1300, 1293, 1294,    0,   69,
-       85,  128,  140,  152,  151,   58,   56,   63,   76, 1272,
-      158,  160,   39,  163,  173,  189,   52, 1265,   76, 1235,
-     1234, 1246, 1230, 1244, 1243,  105, 1272, 1284, 1300,    0,
-      225, 1300,  218,  160,  157,   20,  123,   66,  119,  192,
-     1244, 1230,   54,  162, 1228, 1240,  194, 1300,  200,  195,
-       98,  227,  196,  231,  235,  293,  305,  316, 1300, 1300,
-     1300, 1249, 1262, 1256,  223, 1245, 1248, 1244, 1259,  107,
-      298, 1241, 1255,  246, 1241, 1254, 1245, 1258, 1235, 1246,
-     1237,  182, 1238, 1229, 1238, 1229, 1228, 1229,  144, 1223,
-
-     1229, 1240, 1231, 1225, 1222, 1223, 1227,  289, 1236, 1223,
-      302, 1230, 1217, 1231, 1207,   65,  315,  276, 1227, 1226,
-     1202, 1187, 1182, 1199, 1175, 1180, 1206,  279, 1195,  293,
-     1190,  342,  299, 1192, 1173,  317, 1183, 1179, 1174,  207,
-     1180, 1166, 1182, 1179, 1170,  320,  324, 1172, 1161, 1175,
-     1178, 1160, 1175, 1162, 1159, 1166,  284, 1174,  227,  288,
-      327,  342,  345, 1151, 1168, 1169, 1162, 1144,  318, 1145,
-     1167, 1158,  330,  341,  345,  349,  353,  357,  361, 1300,
-      419,  430,  436,  442,  440,  441, 1191,    0, 1190, 1173,
-     1163,  443, 1183,  444,  451,  468,  470,  472,  471,    0,
-
-      496,    0,  497,  498,    0,  499,  500,    0,  524,  525,
-      526,  536,  537,  553, 1178, 1171, 1184,  354,  356,  561,
-      563, 1165,  564,  565, 1157,  580,  590,  591,  592, 1178,
-      593,  617,  618,  619,  629,  630, 1155, 1165,  330,  362,
-      419,  483,  445,  364,  646, 1153, 1145, 1144, 1129, 1129,
-     1128, 1127, 1170, 1142, 1130,  662,  669,  643, 1134,  487,
-     1131, 1125, 1125, 1119, 1132, 1132, 1117, 1300, 1300, 1132,
-     1120,  646, 1127,  135, 1124, 1130,  561, 1125, 1300, 1116,
-     1123, 1122, 1125, 1111, 1110, 1114, 1109,  448, 1114,  650,
-      653,  665, 1300, 1106, 1104, 1104, 1112, 1113, 1095,  670,
-
-     1100, 1106,  486,  579,  655,  661,  668,  726,  732, 1112,
-      682, 1119, 1110,  688,  730, 1117, 1116, 1109, 1123, 1113,
-     1104,  712, 1111,    0, 1102,  731, 1109, 1100,  733, 1107,
-     1098,  734, 1105, 1096,  736, 1103, 1094,  737, 1101, 1092,
-      738, 1099, 1090,  739, 1097, 1088,  740, 1095, 1086,  741,
-     1093, 1084,  742, 1091, 1082,  743, 1089, 1080,  744, 1087,
-     1078,  745, 1085, 1076,  746, 1083, 1074,  747, 1081, 1072,
-      748, 1079, 1070,  749, 1077, 1080, 1073, 1080,    0, 1073,
-        0, 1088, 1063,  750, 1070, 1061,  751, 1068,    0, 1059,
-      752, 1066, 1057,  755, 1064, 1063, 1054,  758, 1061, 1052,
-
-      776, 1059, 1050,  777, 1057, 1048,  779, 1055, 1058, 1045,
-      780, 1052, 1043,  782, 1050, 1041,  783, 1048, 1039,  784,
-     1046, 1037,  785, 1044, 1035,  786, 1042, 1041,    0, 1032,
-     1039, 1030, 1037, 1028, 1035, 1026, 1033,  787, 1032,  788,
-     1047, 1022,  789, 1029, 1028, 1006, 1000, 1005, 1011,  994,
-     1009,  424, 1300, 1008,  998, 1002, 1300, 1300,  992, 1001,
-      987, 1004,  987,  990,  984, 1300,  985,  984,  981,  988,
-      981,  989,  985,  995,  992,  974,  980,  987,  971,  970,
-      988,  970,  982,  981, 1300,  980,  970,  974, 1300,  961,
-     1300,  966,  966,  974,  957,  958,  968, 1300, 1300, 1000,
-
-      982,  998,    0,  798,  996,  996,  995,  994,  993,  992,
-      991,  990,  989,  988,  987,  986,  985,  984,  983,  982,
-      981,  980,  979,  978,  965,  958,    0,    0,    0,  975,
-      974,  973,  972,  971,  970,  969,  968,  967,  945,  965,
-      964,  963,  962,  961,  960,  959,  958,  957,  956,  955,
-      929,  936,  793,  927,  934,  794,  950,  949,  918,  921,
-      901,    0,  902,  895,  902,  901,  902,  894,  912, 1300,
-     1300,  894,  892,  902,  895, 1300,  890,  907,  516, 1300,
-      898,  882,  883,  892,  883,  882,  882, 1300,  881,  890,
-      880,  896,  893, 1300,  892,  890,  879,  880,  876,  868,
-
-      875,  870,  871,  866,  892,  892,  890,  904,  903,  898,
-        0,  886,  885,  884,  883,  882,  881,  880,  879,  878,
-      877,  876,  875,  874,  873,  872,  871,  870,  869,  868,
-        0,    0,  867,  866,  865,  864,  863,  862,  861,  860,
-      859,  804,  858,  857,  856,  855,  854,  853,  852,  851,
-      850,  849,  848,  865,  839,  846,  862,  836,  843,  841,
-      840,  818,  818,    0,  825,    0,  859,  858,  807,  825,
-     1300,  820,  815,  808,  804,  816,  806,  804,  800,  816,
-      807,  806, 1300, 1300,  809, 1300,  804,  797,  786,  797,
-      789,  793,  806,  801,  804,  786, 1300, 1300,  798,  787,
-
-     1300,    0,    0,    0,    0,    0,  826,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,  814,  813,  802,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,  785,
-      798,  779,  792,    0,    0,  656,    0,    0,  706,  702,
-     1300,  649, 1300,  648,  648,  654, 1300,  637,  645,  610,
-      612,  608,  608, 1300,  572,  583, 1300, 1300,  577,  573,
-      560,  557,  542,  555, 1300,  539,  573,    0,    0,  572,
-        0,  555,    0,  546,    0,  562,  551,  495,  479, 1300,
-
-     1300, 1300,  481,  481, 1300,  480,  443,   31, 1300,  141,
-      166,  171,  186, 1300, 1300,  211,  236,  276,    0,    0,
-     1300, 1300,  290, 1300,  325, 1300,  346, 1300, 1300,  343,
-      341, 1300, 1300, 1300,  365,    0,  380, 1300,  371, 1300,
-     1300,  486, 1300, 1300,  451,  458,    0,    0, 1300,  836,
-      503,  839
-    } ;
-
-static yyconst flex_int16_t yy_def[853] =
-    {   0,
-      849,    1,  849,  849,  849,  849,  849,  850,  851,  849,
-      849,  849,  849,  849,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  849,  849,  850,  849,  851,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  852,  849,  849,  849,  849,
-      849,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  851,
-
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-
-      849,  849,  849,  849,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-
-      849,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  851,  851,  851,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  851,  851,  851,  851,
-      851,  851,  851,  851,  851,  849,  849,  849,  849,  849,
-
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  851,  851,  851,  851,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  851,  851,  849,  849,  849,  849,
-      849,  851,  849,  849,  851,  851,  851,  851,    0,  849,
-      849,  849
-    } ;
-
-static yyconst flex_int16_t yy_nxt[1368] =
-    {   0,
-        4,    5,    6,    5,    7,    8,    9,    4,   10,   11,
-       12,   13,   14,   11,   11,   15,    9,   16,   17,   18,
-       19,    9,    9,    9,   20,   21,   22,    9,   23,   24,
-        9,   25,   26,   27,   28,    9,    9,   29,    9,    9,
-        9,    9,    9,    9,    9,    9,   30,    9,    9,    9,
-        9,    9,    9,    9,    9,    9,   31,    9,   32,   33,
-       34,    9,   35,    9,    9,    9,    9,   36,   96,   36,
-       41,  116,  137,   97,   80,  138,  829,   42,   43,   43,
-       43,   43,   43,   43,   77,   81,   78,  119,   82,  117,
-       83,  238,   79,   66,   67,   67,   67,   67,   67,   67,
-
-       84,   85,  239,  150,   68,  120,   36,   86,   36,  151,
-       44,   45,   46,   47,   48,   49,   50,   51,   52,  141,
-      142,   53,   54,   55,   56,   57,   58,   59,   60,   61,
-       68,  143,   62,   63,   64,   65,   66,   67,   67,   67,
-       67,   67,   67,  170,  194,  195,   69,   68,   66,   67,
-       67,   67,   67,   67,   67,  218,  171,  219,   70,   68,
-       66,   67,   67,   67,   67,   67,   67,   72,  139,   73,
-       71,   68,  140,   68,  144,   92,   74,  145,   98,   88,
-      467,   89,   75,   93,   76,   68,   90,   99,   94,   91,
-      101,  100,  102,  103,   95,  468,  830,   68,  136,  133,
-
-      210,  133,  133,  152,  133,  104,  105,  133,  106,  107,
-      108,  109,  110,  134,  111,  133,  112,  153,  133,  211,
-      135,  831,  113,  114,  154,  115,   41,   43,   43,   43,
-       43,   43,   43,  146,  147,  157,  832,  132,  165,  133,
-      166,  161,  162,  167,  168,  833,  158,  163,  188,  159,
-      133,  169,  160,  265,  189,  164,  834,  201,  133,  174,
-      173,  175,  176,  132,  835,  266,  128,  129,   46,   47,
-       48,   49,  172,   51,   52,  202,  285,   53,   54,   55,
-       56,   57,   58,  130,   60,   61,  286,  243,  131,  244,
-      173,  173,  173,  173,  177,  173,  173,  178,  179,  173,
-
-      173,  173,  181,  181,  181,  181,  181,  181,  228,  836,
-      196,  197,  182,   66,   67,   67,   67,   67,   67,   67,
-      198,  232,  229,  183,   68,  184,  184,  184,  184,  184,
-      184,  240,  134,  241,  255,  233,  282,  287,  182,  135,
-      258,  258,  283,  288,  242,  837,  258,  430,  164,  256,
-       68,  257,  257,  257,  257,  257,  257,  258,  258,  258,
-      261,  258,  258,  298,  258,  272,  258,  258,  258,  258,
-      431,  258,  381,  299,  258,  258,  379,  838,  258,  432,
-      440,  289,  258,  290,  258,  258,  291,  292,  380,  258,
-      382,  839,  258,  303,  303,  303,  303,  840,  441,  841,
-
-      258,  842,  433,  258,  303,  303,  303,  303,  304,  303,
-      303,  305,  306,  303,  303,  303,  303,  303,  303,  303,
-      307,  303,  303,  303,  303,  303,  303,  303,   43,   43,
-       43,   43,   43,   43,  843,  844,  434,  308,  132,  309,
-      309,  309,  309,  309,  309,  184,  184,  184,  184,  184,
-      184,  184,  184,  184,  184,  184,  184,  310,  313,  435,
-      321,  325,  311,  314,  132,  322,  326,  438,  328,  847,
-      565,  311,  315,  329,  322,  326,  848,  311,  314,  439,
-      312,  316,  329,  323,  327,  331,  566,  334,  340,  337,
-      332,  330,  335,  341,  338,  482,  845,  846,  483,  332,
-
-      436,  335,  341,  338,   40,  332,  828,  335,  333,  338,
-      336,  342,  339,  343,  346,  349,  352,  355,  344,  347,
-      350,  353,  356,  437,  827,  826,  825,  344,  347,  350,
-      353,  356,  455,  824,  347,  350,  345,  348,  351,  354,
-      357,  358,  361,  364,  823,  456,  359,  362,  365,  498,
-      498,  498,  498,  367,  370,  359,  362,  365,  368,  371,
-      822,  359,  362,  365,  360,  363,  366,  368,  371,  678,
-      373,  821,  679,  368,  371,  374,  369,  372,  383,  820,
-      386,  390,  393,  384,  374,  387,  391,  394,  819,  818,
-      374,  817,  384,  375,  387,  391,  394,  397,  816,  815,
-
-      814,  385,  398,  388,  392,  395,  471,  400,  403,  406,
-      410,  398,  401,  404,  407,  411,  813,  398,  812,  472,
-      399,  401,  404,  407,  411,  811,  810,  401,  404,  407,
-      402,  405,  408,  412,  413,  416,  419,  809,  808,  414,
-      417,  420,  498,  498,  498,  498,  422,  425,  414,  417,
-      420,  423,  426,  807,  414,  417,  420,  415,  418,  421,
-      423,  426,  806,  442,  805,  804,  423,  426,  443,  424,
-      427,  257,  257,  257,  257,  257,  257,  443,  257,  257,
-      257,  257,  257,  257,  453,  453,  444,  453,  453,  803,
-      453,  453,  453,  453,  453,  453,  802,  453,  801,  310,
-
-      453,  453,  800,  799,  453,  313,  485,  453,  453,  798,
-      797,  453,  453,  492,  796,  493,  795,  494,  499,  498,
-      498,  498,  312,  453,  498,  498,  498,  498,  316,  321,
-      495,  498,  498,  498,  498,  309,  309,  309,  309,  309,
-      309,  309,  309,  309,  309,  309,  309,  313,  325,  501,
-      328,  331,  323,  334,  337,  340,  343,  346,  349,  352,
-      355,  358,  361,  364,  367,  370,  373,  383,  386,  390,
-      316,  327,  393,  330,  333,  397,  336,  339,  342,  345,
-      348,  351,  354,  357,  360,  363,  366,  369,  372,  375,
-      385,  388,  392,  400,  403,  395,  406,  410,  399,  413,
-
-      416,  419,  422,  425,  551,  554,  442,  794,  608,  609,
-      655,  658,  793,  792,  736,  737,  402,  405,  791,  408,
-      412,  790,  415,  418,  421,  424,  427,  552,  555,  444,
-      610,  789,  788,  656,  659,  738,   38,   38,   38,  180,
-      180,  787,  786,  785,  784,  783,  782,  781,  780,  779,
-      778,  777,  776,  775,  774,  773,  772,  771,  770,  769,
-      768,  767,  766,  765,  764,  763,  762,  761,  760,  759,
-      758,  757,  756,  755,  754,  753,  659,  752,  751,  656,
-      750,  749,  748,  747,  746,  745,  744,  743,  742,  741,
-      740,  739,  735,  734,  733,  732,  731,  730,  729,  728,
-
-      727,  726,  725,  724,  723,  722,  721,  720,  719,  718,
-      717,  716,  715,  714,  713,  712,  711,  710,  709,  708,
-      707,  706,  705,  704,  703,  702,  701,  700,  699,  698,
-      697,  696,  695,  694,  693,  692,  691,  690,  689,  688,
-      687,  686,  685,  684,  683,  682,  681,  680,  677,  676,
-      675,  674,  673,  672,  671,  670,  669,  668,  667,  666,
-      665,  664,  663,  662,  661,  660,  657,  555,  654,  552,
-      653,  652,  651,  650,  649,  648,  647,  646,  645,  644,
-      643,  642,  641,  640,  639,  638,  637,  636,  635,  634,
-      633,  632,  631,  630,  629,  628,  627,  626,  625,  624,
-
-      623,  622,  621,  620,  619,  618,  617,  616,  615,  614,
-      613,  612,  611,  607,  606,  605,  604,  603,  602,  601,
-      600,  599,  598,  597,  596,  595,  594,  593,  592,  591,
-      590,  589,  588,  587,  586,  585,  584,  583,  582,  581,
-      580,  579,  578,  577,  576,  575,  574,  573,  572,  571,
-      570,  569,  568,  567,  564,  563,  562,  561,  560,  559,
-      558,  557,  444,  556,  553,  550,  437,  549,  435,  548,
-      433,  547,  431,  546,  545,  427,  544,  424,  543,  421,
-      542,  418,  541,  415,  540,  412,  539,  538,  408,  537,
-      405,  536,  402,  535,  399,  534,  533,  395,  532,  392,
-
-      531,  388,  530,  385,  529,  528,  527,  526,  525,  524,
-      375,  523,  372,  522,  369,  521,  366,  520,  363,  519,
-      360,  518,  357,  517,  354,  516,  351,  515,  348,  514,
-      345,  513,  342,  512,  339,  511,  336,  510,  333,  509,
-      330,  508,  327,  507,  323,  506,  505,  504,  503,  502,
-      316,  500,  312,  497,  496,  491,  490,  489,  488,  487,
-      486,  484,  481,  480,  479,  478,  477,  476,  475,  474,
-      473,  470,  469,  466,  465,  464,  463,  462,  461,  460,
-      459,  458,  457,  454,  289,  261,  452,  451,  450,  449,
-      448,  447,  446,  445,  429,  428,  409,  396,  389,  378,
-
-      377,  376,  324,  320,  319,  318,  317,  302,  301,  300,
-      297,  296,  295,  294,  293,  284,  281,  280,  279,  278,
-      277,  276,  275,  274,  273,  271,  270,  269,  268,  267,
-      264,  263,  262,  260,  259,  172,  254,  253,  252,  251,
-      250,  249,  248,  247,  246,  245,  237,  236,  235,  234,
-      231,  230,  227,  226,  225,  224,  223,  222,  221,  220,
-      217,  216,  215,  214,  213,  212,  209,  208,  207,  206,
-      205,  204,  203,  200,  199,  193,  192,  191,  190,  187,
-      186,  185,  156,  155,  149,  148,   39,  127,  126,  125,
-      124,  123,  122,  121,  118,   87,   39,   37,  849,    3,
-
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849
-    } ;
-
-static yyconst flex_int16_t yy_chk[1368] =
-    {   0,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    1,    5,   23,    5,
-       10,   27,   46,   23,   17,   46,  808,   10,   10,   10,
-       10,   10,   10,   10,   16,   17,   16,   29,   17,   27,
-       18,  116,   16,   11,   11,   11,   11,   11,   11,   11,
-
-       18,   19,  116,   53,   11,   29,   36,   19,   36,   53,
-       10,   10,   10,   10,   10,   10,   10,   10,   10,   48,
-       48,   10,   10,   10,   10,   10,   10,   10,   10,   10,
-       11,   48,   10,   10,   10,   10,   12,   12,   12,   12,
-       12,   12,   12,   61,   80,   80,   12,   12,   13,   13,
-       13,   13,   13,   13,   13,   99,   61,   99,   13,   13,
-       14,   14,   14,   14,   14,   14,   14,   15,   47,   15,
-       14,   14,   47,   12,   49,   22,   15,   49,   24,   21,
-      274,   21,   15,   22,   15,   13,   21,   24,   22,   21,
-       25,   24,   25,   25,   22,  274,  810,   14,   45,   45,
-
-       92,   44,   44,   54,   45,   25,   26,   44,   26,   26,
-       26,   26,   26,   44,   26,   45,   26,   54,   44,   92,
-       44,  811,   26,   26,   54,   26,   41,   43,   43,   43,
-       43,   43,   43,   50,   50,   57,  812,   43,   60,   50,
-       60,   59,   59,   60,   60,  813,   57,   59,   75,   57,
-       50,   60,   57,  140,   75,   59,  816,   84,   59,   63,
-       63,   63,   63,   43,  817,  140,   41,   41,   41,   41,
-       41,   41,   62,   41,   41,   84,  159,   41,   41,   41,
-       41,   41,   41,   41,   41,   41,  159,  118,   41,  118,
-       62,   62,   62,   62,   64,   64,   64,   64,   65,   65,
-
-       65,   65,   66,   66,   66,   66,   66,   66,  108,  818,
-       81,   81,   66,   67,   67,   67,   67,   67,   67,   67,
-       81,  111,  108,   68,   67,   68,   68,   68,   68,   68,
-       68,  117,  128,  117,  130,  111,  157,  160,   66,  128,
-      133,  133,  157,  160,  117,  823,  133,  239,  130,  132,
-       67,  132,  132,  132,  132,  132,  132,  133,  136,  136,
-      136,  146,  146,  169,  136,  147,  147,  146,  161,  161,
-      239,  147,  219,  169,  161,  136,  218,  825,  146,  240,
-      244,  161,  147,  162,  162,  161,  163,  163,  218,  162,
-      219,  827,  163,  173,  173,  173,  173,  830,  244,  831,
-
-      162,  835,  240,  163,  174,  174,  174,  174,  175,  175,
-      175,  175,  176,  176,  176,  176,  177,  177,  177,  177,
-      178,  178,  178,  178,  179,  179,  179,  179,  181,  181,
-      181,  181,  181,  181,  837,  839,  241,  182,  181,  182,
-      182,  182,  182,  182,  182,  183,  183,  183,  183,  183,
-      183,  184,  184,  184,  184,  184,  184,  185,  186,  241,
-      192,  194,  185,  186,  181,  192,  194,  243,  195,  845,
-      452,  185,  186,  195,  192,  194,  846,  185,  186,  243,
-      185,  186,  195,  192,  194,  196,  452,  197,  199,  198,
-      196,  195,  197,  199,  198,  288,  842,  842,  288,  196,
-
-      242,  197,  199,  198,  851,  196,  807,  197,  196,  198,
-      197,  199,  198,  201,  203,  204,  206,  207,  201,  203,
-      204,  206,  207,  242,  806,  804,  803,  201,  203,  204,
-      206,  207,  260,  799,  203,  204,  201,  203,  204,  206,
-      207,  209,  210,  211,  798,  260,  209,  210,  211,  303,
-      303,  303,  303,  212,  213,  209,  210,  211,  212,  213,
-      797,  209,  210,  211,  209,  210,  211,  212,  213,  579,
-      214,  796,  579,  212,  213,  214,  212,  213,  220,  794,
-      221,  223,  224,  220,  214,  221,  223,  224,  792,  790,
-      214,  787,  220,  214,  221,  223,  224,  226,  786,  784,
-
-      783,  220,  226,  221,  223,  224,  277,  227,  228,  229,
-      231,  226,  227,  228,  229,  231,  782,  226,  781,  277,
-      226,  227,  228,  229,  231,  780,  779,  227,  228,  229,
-      227,  228,  229,  231,  232,  233,  234,  776,  775,  232,
-      233,  234,  304,  304,  304,  304,  235,  236,  232,  233,
-      234,  235,  236,  773,  232,  233,  234,  232,  233,  234,
-      235,  236,  772,  245,  771,  770,  235,  236,  245,  235,
-      236,  256,  256,  256,  256,  256,  256,  245,  257,  257,
-      257,  257,  257,  257,  258,  258,  245,  272,  272,  769,
-      258,  290,  290,  272,  291,  291,  768,  290,  766,  311,
-
-      291,  258,  765,  764,  272,  314,  292,  292,  290,  762,
-      760,  291,  292,  300,  759,  300,  756,  300,  305,  305,
-      305,  305,  311,  292,  306,  306,  306,  306,  314,  322,
-      300,  307,  307,  307,  307,  308,  308,  308,  308,  308,
-      308,  309,  309,  309,  309,  309,  309,  315,  326,  315,
-      329,  332,  322,  335,  338,  341,  344,  347,  350,  353,
-      356,  359,  362,  365,  368,  371,  374,  384,  387,  391,
-      315,  326,  394,  329,  332,  398,  335,  338,  341,  344,
-      347,  350,  353,  356,  359,  362,  365,  368,  371,  374,
-      384,  387,  391,  401,  404,  394,  407,  411,  398,  414,
-
-      417,  420,  423,  426,  438,  440,  443,  753,  504,  504,
-      553,  556,  752,  751,  642,  642,  401,  404,  750,  407,
-      411,  738,  414,  417,  420,  423,  426,  438,  440,  443,
-      504,  737,  736,  553,  556,  642,  850,  850,  850,  852,
-      852,  707,  700,  699,  696,  695,  694,  693,  692,  691,
-      690,  689,  688,  687,  685,  682,  681,  680,  679,  678,
-      677,  676,  675,  674,  673,  672,  670,  669,  668,  667,
-      665,  663,  662,  661,  660,  659,  658,  657,  656,  655,
-      654,  653,  652,  651,  650,  649,  648,  647,  646,  645,
-      644,  643,  641,  640,  639,  638,  637,  636,  635,  634,
-
-      633,  630,  629,  628,  627,  626,  625,  624,  623,  622,
-      621,  620,  619,  618,  617,  616,  615,  614,  613,  612,
-      610,  609,  608,  607,  606,  605,  604,  603,  602,  601,
-      600,  599,  598,  597,  596,  595,  593,  592,  591,  590,
-      589,  587,  586,  585,  584,  583,  582,  581,  578,  577,
-      575,  574,  573,  572,  569,  568,  567,  566,  565,  564,
-      563,  561,  560,  559,  558,  557,  555,  554,  552,  551,
-      550,  549,  548,  547,  546,  545,  544,  543,  542,  541,
-      540,  539,  538,  537,  536,  535,  534,  533,  532,  531,
-      530,  526,  525,  524,  523,  522,  521,  520,  519,  518,
-
-      517,  516,  515,  514,  513,  512,  511,  510,  509,  508,
-      507,  506,  505,  502,  501,  500,  497,  496,  495,  494,
-      493,  492,  490,  488,  487,  486,  484,  483,  482,  481,
-      480,  479,  478,  477,  476,  475,  474,  473,  472,  471,
-      470,  469,  468,  467,  465,  464,  463,  462,  461,  460,
-      459,  456,  455,  454,  451,  450,  449,  448,  447,  446,
-      445,  444,  442,  441,  439,  437,  436,  435,  434,  433,
-      432,  431,  430,  428,  427,  425,  424,  422,  421,  419,
-      418,  416,  415,  413,  412,  410,  409,  408,  406,  405,
-      403,  402,  400,  399,  397,  396,  395,  393,  392,  390,
-
-      388,  386,  385,  383,  382,  380,  378,  377,  376,  375,
-      373,  372,  370,  369,  367,  366,  364,  363,  361,  360,
-      358,  357,  355,  354,  352,  351,  349,  348,  346,  345,
-      343,  342,  340,  339,  337,  336,  334,  333,  331,  330,
-      328,  327,  325,  323,  321,  320,  319,  318,  317,  316,
-      313,  312,  310,  302,  301,  299,  298,  297,  296,  295,
-      294,  289,  287,  286,  285,  284,  283,  282,  281,  280,
-      278,  276,  275,  273,  271,  270,  267,  266,  265,  264,
-      263,  262,  261,  259,  255,  254,  253,  252,  251,  250,
-      249,  248,  247,  246,  238,  237,  230,  225,  222,  217,
-
-      216,  215,  193,  191,  190,  189,  187,  172,  171,  170,
-      168,  167,  166,  165,  164,  158,  156,  155,  154,  153,
-      152,  151,  150,  149,  148,  145,  144,  143,  142,  141,
-      139,  138,  137,  135,  134,  131,  129,  127,  126,  125,
-      124,  123,  122,  121,  120,  119,  115,  114,  113,  112,
-      110,  109,  107,  106,  105,  104,  103,  102,  101,  100,
-       98,   97,   96,   95,   94,   93,   91,   90,   89,   88,
-       87,   86,   85,   83,   82,   79,   78,   77,   76,   74,
-       73,   72,   56,   55,   52,   51,   38,   37,   35,   34,
-       33,   32,   31,   30,   28,   20,    8,    7,    3,  849,
-
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849,  849,  849,  849,
-      849,  849,  849,  849,  849,  849,  849
-    } ;
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
- */
-#define REJECT reject_used_but_not_detected
-#define yymore() yymore_used_but_not_detected
-#define YY_MORE_ADJ 0
-#define YY_RESTORE_YY_MORE_OFFSET
-#line 1 "program_lexer.l"
-#line 2 "program_lexer.l"
-/*
- * Copyright Â© 2009 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION 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/imports.h"
-#include "shader/prog_instruction.h"
-#include "shader/prog_statevars.h"
-
-#include "shader/symbol_table.h"
-#include "shader/program_parser.h"
-#include "shader/program_parse.tab.h"
-
-#define require_ARB_vp (yyextra->mode == ARB_vertex)
-#define require_ARB_fp (yyextra->mode == ARB_fragment)
-#define require_NV_fp  (yyextra->option.NV_fragment)
-#define require_shadow (yyextra->option.Shadow)
-#define require_rect   (yyextra->option.TexRect)
-#define require_texarray        (yyextra->option.TexArray)
-
-#ifndef HAVE_UNISTD_H
-#define YY_NO_UNISTD_H
-#endif
-
-#define return_token_or_IDENTIFIER(condition, token)   \
-   do {                                                        \
-      if (condition) {                                 \
-        return token;                                  \
-      } else {                                         \
-        return handle_ident(yyextra, yytext, yylval);  \
-      }                                                        \
-   } while (0)
-
-#define return_token_or_DOT(condition, token)          \
-   do {                                                        \
-      if (condition) {                                 \
-        return token;                                  \
-      } else {                                         \
-        yyless(1);                                     \
-        return DOT;                                    \
-      }                                                        \
-   } while (0)
-
-
-#define return_opcode(condition, token, opcode, len)   \
-   do {                                                        \
-      if (condition &&                                 \
-         _mesa_parse_instruction_suffix(yyextra,       \
-                                        yytext + len,  \
-                                        & yylval->temp_inst)) {        \
-        yylval->temp_inst.Opcode = OPCODE_ ## opcode;  \
-        return token;                                  \
-      } else {                                         \
-        return handle_ident(yyextra, yytext, yylval);  \
-      }                                                        \
-   } while (0)
-
-#define SWIZZLE_INVAL  MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
-                                    SWIZZLE_NIL, SWIZZLE_NIL)
-
-static unsigned
-mask_from_char(char c)
-{
-   switch (c) {
-   case 'x':
-   case 'r':
-      return WRITEMASK_X;
-   case 'y':
-   case 'g':
-      return WRITEMASK_Y;
-   case 'z':
-   case 'b':
-      return WRITEMASK_Z;
-   case 'w':
-   case 'a':
-      return WRITEMASK_W;
-   }
-
-   return 0;
-}
-
-static unsigned
-swiz_from_char(char c)
-{
-   switch (c) {
-   case 'x':
-   case 'r':
-      return SWIZZLE_X;
-   case 'y':
-   case 'g':
-      return SWIZZLE_Y;
-   case 'z':
-   case 'b':
-      return SWIZZLE_Z;
-   case 'w':
-   case 'a':
-      return SWIZZLE_W;
-   }
-
-   return 0;
-}
-
-static int
-handle_ident(struct asm_parser_state *state, const char *text, YYSTYPE *lval)
-{
-   lval->string = strdup(text);
-
-   return (_mesa_symbol_table_find_symbol(state->st, 0, text) == NULL)
-      ? IDENTIFIER : USED_IDENTIFIER;
-}
-
-#define YY_USER_ACTION                                                 \
-   do {                                                                        \
-      yylloc->first_column = yylloc->last_column;                      \
-      yylloc->last_column += yyleng;                                   \
-      if ((yylloc->first_line == 1)                                    \
-         && (yylloc->first_column == 1)) {                             \
-        yylloc->position = 1;                                          \
-      } else {                                                         \
-        yylloc->position += yylloc->last_column - yylloc->first_column; \
-      }                                                                        \
-   } while(0);
-
-#define YY_EXTRA_TYPE struct asm_parser_state *
-#line 1156 "lex.yy.c"
-
-#define INITIAL 0
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#ifndef YY_EXTRA_TYPE
-#define YY_EXTRA_TYPE void *
-#endif
-
-/* Holds the entire state of the reentrant scanner. */
-struct yyguts_t
-    {
-
-    /* User-defined. Not touched by flex. */
-    YY_EXTRA_TYPE yyextra_r;
-
-    /* The rest are the same as the globals declared in the non-reentrant scanner. */
-    FILE *yyin_r, *yyout_r;
-    size_t yy_buffer_stack_top; /**< index of top of stack. */
-    size_t yy_buffer_stack_max; /**< capacity of stack. */
-    YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
-    char yy_hold_char;
-    int yy_n_chars;
-    int yyleng_r;
-    char *yy_c_buf_p;
-    int yy_init;
-    int yy_start;
-    int yy_did_buffer_switch_on_eof;
-    int yy_start_stack_ptr;
-    int yy_start_stack_depth;
-    int *yy_start_stack;
-    yy_state_type yy_last_accepting_state;
-    char* yy_last_accepting_cpos;
-
-    int yylineno_r;
-    int yy_flex_debug_r;
-
-    char *yytext_r;
-    int yy_more_flag;
-    int yy_more_len;
-
-    YYSTYPE * yylval_r;
-
-    YYLTYPE * yylloc_r;
-
-    }; /* end struct yyguts_t */
-
-static int yy_init_globals (yyscan_t yyscanner );
-
-    /* This must go here because YYSTYPE and YYLTYPE are included
-     * from bison output in section 1.*/
-    #    define yylval yyg->yylval_r
-    
-    #    define yylloc yyg->yylloc_r
-    
-int yylex_init (yyscan_t* scanner);
-
-int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
-
-/* Accessor methods to globals.
-   These are made visible to non-reentrant scanners for convenience. */
-
-int yylex_destroy (yyscan_t yyscanner );
-
-int yyget_debug (yyscan_t yyscanner );
-
-void yyset_debug (int debug_flag ,yyscan_t yyscanner );
-
-YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner );
-
-void yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
-
-FILE *yyget_in (yyscan_t yyscanner );
-
-void yyset_in  (FILE * in_str ,yyscan_t yyscanner );
-
-FILE *yyget_out (yyscan_t yyscanner );
-
-void yyset_out  (FILE * out_str ,yyscan_t yyscanner );
-
-int yyget_leng (yyscan_t yyscanner );
-
-char *yyget_text (yyscan_t yyscanner );
-
-int yyget_lineno (yyscan_t yyscanner );
-
-void yyset_lineno (int line_number ,yyscan_t yyscanner );
-
-YYSTYPE * yyget_lval (yyscan_t yyscanner );
-
-void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
-
-       YYLTYPE *yyget_lloc (yyscan_t yyscanner );
-    
-        void yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );
-    
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int yywrap (yyscan_t yyscanner );
-#else
-extern int yywrap (yyscan_t yyscanner );
-#endif
-#endif
-
-    static void yyunput (int c,char *buf_ptr  ,yyscan_t yyscanner);
-    
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
-#endif
-
-#ifndef YY_NO_INPUT
-
-#ifdef __cplusplus
-static int yyinput (yyscan_t yyscanner );
-#else
-static int input (yyscan_t yyscanner );
-#endif
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#define YY_READ_BUF_SIZE 8192
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO fwrite( yytext, yyleng, 1, yyout )
-#endif
-
-/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
-       if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
-               { \
-               int c = '*'; \
-               unsigned n; \
-               for ( n = 0; n < max_size && \
-                            (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
-                       buf[n] = (char) c; \
-               if ( c == '\n' ) \
-                       buf[n++] = (char) c; \
-               if ( c == EOF && ferror( yyin ) ) \
-                       YY_FATAL_ERROR( "input in flex scanner failed" ); \
-               result = n; \
-               } \
-       else \
-               { \
-               errno=0; \
-               while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
-                       { \
-                       if( errno != EINTR) \
-                               { \
-                               YY_FATAL_ERROR( "input in flex scanner failed" ); \
-                               break; \
-                               } \
-                       errno=0; \
-                       clearerr(yyin); \
-                       } \
-               }\
-\
-
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
-#endif
-
-/* end tables serialization structures and prototypes */
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int yylex \
-               (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
-
-#define YY_DECL int yylex \
-               (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
-#endif /* !YY_DECL */
-
-/* Code executed at the beginning of each rule, after yytext and yyleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK break;
-#endif
-
-#define YY_RULE_SETUP \
-       YY_USER_ACTION
-
-/** The main scanner function which does all the work.
- */
-YY_DECL
-{
-       register yy_state_type yy_current_state;
-       register char *yy_cp, *yy_bp;
-       register int yy_act;
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-#line 157 "program_lexer.l"
-
-
-#line 1400 "lex.yy.c"
-
-    yylval = yylval_param;
-
-    yylloc = yylloc_param;
-
-       if ( !yyg->yy_init )
-               {
-               yyg->yy_init = 1;
-
-#ifdef YY_USER_INIT
-               YY_USER_INIT;
-#endif
-
-               if ( ! yyg->yy_start )
-                       yyg->yy_start = 1;      /* first start state */
-
-               if ( ! yyin )
-                       yyin = stdin;
-
-               if ( ! yyout )
-                       yyout = stdout;
-
-               if ( ! YY_CURRENT_BUFFER ) {
-                       yyensure_buffer_stack (yyscanner);
-                       YY_CURRENT_BUFFER_LVALUE =
-                               yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
-               }
-
-               yy_load_buffer_state(yyscanner );
-               }
-
-       while ( 1 )             /* loops until end-of-file is reached */
-               {
-               yy_cp = yyg->yy_c_buf_p;
-
-               /* Support of yytext. */
-               *yy_cp = yyg->yy_hold_char;
-
-               /* yy_bp points to the position in yy_ch_buf of the start of
-                * the current run.
-                */
-               yy_bp = yy_cp;
-
-               yy_current_state = yyg->yy_start;
-yy_match:
-               do
-                       {
-                       register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
-                       if ( yy_accept[yy_current_state] )
-                               {
-                               yyg->yy_last_accepting_state = yy_current_state;
-                               yyg->yy_last_accepting_cpos = yy_cp;
-                               }
-                       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-                               {
-                               yy_current_state = (int) yy_def[yy_current_state];
-                               if ( yy_current_state >= 850 )
-                                       yy_c = yy_meta[(unsigned int) yy_c];
-                               }
-                       yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-                       ++yy_cp;
-                       }
-               while ( yy_base[yy_current_state] != 1300 );
-
-yy_find_action:
-               yy_act = yy_accept[yy_current_state];
-               if ( yy_act == 0 )
-                       { /* have to back up */
-                       yy_cp = yyg->yy_last_accepting_cpos;
-                       yy_current_state = yyg->yy_last_accepting_state;
-                       yy_act = yy_accept[yy_current_state];
-                       }
-
-               YY_DO_BEFORE_ACTION;
-
-do_action:     /* This label is used only to access EOF actions. */
-
-               switch ( yy_act )
-       { /* beginning of action switch */
-                       case 0: /* must back up */
-                       /* undo the effects of YY_DO_BEFORE_ACTION */
-                       *yy_cp = yyg->yy_hold_char;
-                       yy_cp = yyg->yy_last_accepting_cpos;
-                       yy_current_state = yyg->yy_last_accepting_state;
-                       goto yy_find_action;
-
-case 1:
-YY_RULE_SETUP
-#line 159 "program_lexer.l"
-{ return ARBvp_10; }
-       YY_BREAK
-case 2:
-YY_RULE_SETUP
-#line 160 "program_lexer.l"
-{ return ARBfp_10; }
-       YY_BREAK
-case 3:
-YY_RULE_SETUP
-#line 161 "program_lexer.l"
-{
-   yylval->integer = at_address;
-   return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS);
-}
-       YY_BREAK
-case 4:
-YY_RULE_SETUP
-#line 165 "program_lexer.l"
-{ return ALIAS; }
-       YY_BREAK
-case 5:
-YY_RULE_SETUP
-#line 166 "program_lexer.l"
-{ return ATTRIB; }
-       YY_BREAK
-case 6:
-YY_RULE_SETUP
-#line 167 "program_lexer.l"
-{ return END; }
-       YY_BREAK
-case 7:
-YY_RULE_SETUP
-#line 168 "program_lexer.l"
-{ return OPTION; }
-       YY_BREAK
-case 8:
-YY_RULE_SETUP
-#line 169 "program_lexer.l"
-{ return OUTPUT; }
-       YY_BREAK
-case 9:
-YY_RULE_SETUP
-#line 170 "program_lexer.l"
-{ return PARAM; }
-       YY_BREAK
-case 10:
-YY_RULE_SETUP
-#line 171 "program_lexer.l"
-{ yylval->integer = at_temp; return TEMP; }
-       YY_BREAK
-case 11:
-YY_RULE_SETUP
-#line 173 "program_lexer.l"
-{ return_opcode(             1, VECTOR_OP, ABS, 3); }
-       YY_BREAK
-case 12:
-YY_RULE_SETUP
-#line 174 "program_lexer.l"
-{ return_opcode(             1, BIN_OP, ADD, 3); }
-       YY_BREAK
-case 13:
-YY_RULE_SETUP
-#line 175 "program_lexer.l"
-{ return_opcode(require_ARB_vp, ARL, ARL, 3); }
-       YY_BREAK
-case 14:
-YY_RULE_SETUP
-#line 177 "program_lexer.l"
-{ return_opcode(require_ARB_fp, TRI_OP, CMP, 3); }
-       YY_BREAK
-case 15:
-YY_RULE_SETUP
-#line 178 "program_lexer.l"
-{ return_opcode(require_ARB_fp, SCALAR_OP, COS, 3); }
-       YY_BREAK
-case 16:
-YY_RULE_SETUP
-#line 180 "program_lexer.l"
-{ return_opcode(require_NV_fp,  VECTOR_OP, DDX, 3); }
-       YY_BREAK
-case 17:
-YY_RULE_SETUP
-#line 181 "program_lexer.l"
-{ return_opcode(require_NV_fp,  VECTOR_OP, DDY, 3); }
-       YY_BREAK
-case 18:
-YY_RULE_SETUP
-#line 182 "program_lexer.l"
-{ return_opcode(             1, BIN_OP, DP3, 3); }
-       YY_BREAK
-case 19:
-YY_RULE_SETUP
-#line 183 "program_lexer.l"
-{ return_opcode(             1, BIN_OP, DP4, 3); }
-       YY_BREAK
-case 20:
-YY_RULE_SETUP
-#line 184 "program_lexer.l"
-{ return_opcode(             1, BIN_OP, DPH, 3); }
-       YY_BREAK
-case 21:
-YY_RULE_SETUP
-#line 185 "program_lexer.l"
-{ return_opcode(             1, BIN_OP, DST, 3); }
-       YY_BREAK
-case 22:
-YY_RULE_SETUP
-#line 187 "program_lexer.l"
-{ return_opcode(             1, SCALAR_OP, EX2, 3); }
-       YY_BREAK
-case 23:
-YY_RULE_SETUP
-#line 188 "program_lexer.l"
-{ return_opcode(require_ARB_vp, SCALAR_OP, EXP, 3); }
-       YY_BREAK
-case 24:
-YY_RULE_SETUP
-#line 190 "program_lexer.l"
-{ return_opcode(             1, VECTOR_OP, FLR, 3); }
-       YY_BREAK
-case 25:
-YY_RULE_SETUP
-#line 191 "program_lexer.l"
-{ return_opcode(             1, VECTOR_OP, FRC, 3); }
-       YY_BREAK
-case 26:
-YY_RULE_SETUP
-#line 193 "program_lexer.l"
-{ return_opcode(require_ARB_fp, KIL, KIL, 3); }
-       YY_BREAK
-case 27:
-YY_RULE_SETUP
-#line 195 "program_lexer.l"
-{ return_opcode(             1, VECTOR_OP, LIT, 3); }
-       YY_BREAK
-case 28:
-YY_RULE_SETUP
-#line 196 "program_lexer.l"
-{ return_opcode(             1, SCALAR_OP, LG2, 3); }
-       YY_BREAK
-case 29:
-YY_RULE_SETUP
-#line 197 "program_lexer.l"
-{ return_opcode(require_ARB_vp, SCALAR_OP, LOG, 3); }
-       YY_BREAK
-case 30:
-YY_RULE_SETUP
-#line 198 "program_lexer.l"
-{ return_opcode(require_ARB_fp, TRI_OP, LRP, 3); }
-       YY_BREAK
-case 31:
-YY_RULE_SETUP
-#line 200 "program_lexer.l"
-{ return_opcode(             1, TRI_OP, MAD, 3); }
-       YY_BREAK
-case 32:
-YY_RULE_SETUP
-#line 201 "program_lexer.l"
-{ return_opcode(             1, BIN_OP, MAX, 3); }
-       YY_BREAK
-case 33:
-YY_RULE_SETUP
-#line 202 "program_lexer.l"
-{ return_opcode(             1, BIN_OP, MIN, 3); }
-       YY_BREAK
-case 34:
-YY_RULE_SETUP
-#line 203 "program_lexer.l"
-{ return_opcode(             1, VECTOR_OP, MOV, 3); }
-       YY_BREAK
-case 35:
-YY_RULE_SETUP
-#line 204 "program_lexer.l"
-{ return_opcode(             1, BIN_OP, MUL, 3); }
-       YY_BREAK
-case 36:
-YY_RULE_SETUP
-#line 206 "program_lexer.l"
-{ return_opcode(require_NV_fp,  VECTOR_OP, PK2H, 4); }
-       YY_BREAK
-case 37:
-YY_RULE_SETUP
-#line 207 "program_lexer.l"
-{ return_opcode(require_NV_fp,  VECTOR_OP, PK2US, 5); }
-       YY_BREAK
-case 38:
-YY_RULE_SETUP
-#line 208 "program_lexer.l"
-{ return_opcode(require_NV_fp,  VECTOR_OP, PK4B, 4); }
-       YY_BREAK
-case 39:
-YY_RULE_SETUP
-#line 209 "program_lexer.l"
-{ return_opcode(require_NV_fp,  VECTOR_OP, PK4UB, 5); }
-       YY_BREAK
-case 40:
-YY_RULE_SETUP
-#line 210 "program_lexer.l"
-{ return_opcode(             1, BINSC_OP, POW, 3); }
-       YY_BREAK
-case 41:
-YY_RULE_SETUP
-#line 212 "program_lexer.l"
-{ return_opcode(             1, SCALAR_OP, RCP, 3); }
-       YY_BREAK
-case 42:
-YY_RULE_SETUP
-#line 213 "program_lexer.l"
-{ return_opcode(require_NV_fp,  BIN_OP,    RFL, 3); }
-       YY_BREAK
-case 43:
-YY_RULE_SETUP
-#line 214 "program_lexer.l"
-{ return_opcode(             1, SCALAR_OP, RSQ, 3); }
-       YY_BREAK
-case 44:
-YY_RULE_SETUP
-#line 216 "program_lexer.l"
-{ return_opcode(require_ARB_fp, SCALAR_OP, SCS, 3); }
-       YY_BREAK
-case 45:
-YY_RULE_SETUP
-#line 217 "program_lexer.l"
-{ return_opcode(require_NV_fp,  BIN_OP, SEQ, 3); }
-       YY_BREAK
-case 46:
-YY_RULE_SETUP
-#line 218 "program_lexer.l"
-{ return_opcode(require_NV_fp,  BIN_OP, SFL, 3); }
-       YY_BREAK
-case 47:
-YY_RULE_SETUP
-#line 219 "program_lexer.l"
-{ return_opcode(             1, BIN_OP, SGE, 3); }
-       YY_BREAK
-case 48:
-YY_RULE_SETUP
-#line 220 "program_lexer.l"
-{ return_opcode(require_NV_fp,  BIN_OP, SGT, 3); }
-       YY_BREAK
-case 49:
-YY_RULE_SETUP
-#line 221 "program_lexer.l"
-{ return_opcode(require_ARB_fp, SCALAR_OP, SIN, 3); }
-       YY_BREAK
-case 50:
-YY_RULE_SETUP
-#line 222 "program_lexer.l"
-{ return_opcode(require_NV_fp,  BIN_OP, SLE, 3); }
-       YY_BREAK
-case 51:
-YY_RULE_SETUP
-#line 223 "program_lexer.l"
-{ return_opcode(             1, BIN_OP, SLT, 3); }
-       YY_BREAK
-case 52:
-YY_RULE_SETUP
-#line 224 "program_lexer.l"
-{ return_opcode(require_NV_fp,  BIN_OP, SNE, 3); }
-       YY_BREAK
-case 53:
-YY_RULE_SETUP
-#line 225 "program_lexer.l"
-{ return_opcode(require_NV_fp,  BIN_OP, STR, 3); }
-       YY_BREAK
-case 54:
-YY_RULE_SETUP
-#line 226 "program_lexer.l"
-{ return_opcode(             1, BIN_OP, SUB, 3); }
-       YY_BREAK
-case 55:
-YY_RULE_SETUP
-#line 227 "program_lexer.l"
-{ return_opcode(             1, SWZ, SWZ, 3); }
-       YY_BREAK
-case 56:
-YY_RULE_SETUP
-#line 229 "program_lexer.l"
-{ return_opcode(require_ARB_fp, SAMPLE_OP, TEX, 3); }
-       YY_BREAK
-case 57:
-YY_RULE_SETUP
-#line 230 "program_lexer.l"
-{ return_opcode(require_ARB_fp, SAMPLE_OP, TXB, 3); }
-       YY_BREAK
-case 58:
-YY_RULE_SETUP
-#line 231 "program_lexer.l"
-{ return_opcode(require_NV_fp,  TXD_OP, TXD, 3); }
-       YY_BREAK
-case 59:
-YY_RULE_SETUP
-#line 232 "program_lexer.l"
-{ return_opcode(require_ARB_fp, SAMPLE_OP, TXP, 3); }
-       YY_BREAK
-case 60:
-YY_RULE_SETUP
-#line 234 "program_lexer.l"
-{ return_opcode(require_NV_fp,  SCALAR_OP, UP2H, 4); }
-       YY_BREAK
-case 61:
-YY_RULE_SETUP
-#line 235 "program_lexer.l"
-{ return_opcode(require_NV_fp,  SCALAR_OP, UP2US, 5); }
-       YY_BREAK
-case 62:
-YY_RULE_SETUP
-#line 236 "program_lexer.l"
-{ return_opcode(require_NV_fp,  SCALAR_OP, UP4B, 4); }
-       YY_BREAK
-case 63:
-YY_RULE_SETUP
-#line 237 "program_lexer.l"
-{ return_opcode(require_NV_fp,  SCALAR_OP, UP4UB, 5); }
-       YY_BREAK
-case 64:
-YY_RULE_SETUP
-#line 239 "program_lexer.l"
-{ return_opcode(require_NV_fp,  TRI_OP, X2D, 3); }
-       YY_BREAK
-case 65:
-YY_RULE_SETUP
-#line 240 "program_lexer.l"
-{ return_opcode(             1, BIN_OP, XPD, 3); }
-       YY_BREAK
-case 66:
-YY_RULE_SETUP
-#line 242 "program_lexer.l"
-{ return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); }
-       YY_BREAK
-case 67:
-YY_RULE_SETUP
-#line 243 "program_lexer.l"
-{ return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); }
-       YY_BREAK
-case 68:
-YY_RULE_SETUP
-#line 244 "program_lexer.l"
-{ return PROGRAM; }
-       YY_BREAK
-case 69:
-YY_RULE_SETUP
-#line 245 "program_lexer.l"
-{ return STATE; }
-       YY_BREAK
-case 70:
-YY_RULE_SETUP
-#line 246 "program_lexer.l"
-{ return RESULT; }
-       YY_BREAK
-case 71:
-YY_RULE_SETUP
-#line 248 "program_lexer.l"
-{ return AMBIENT; }
-       YY_BREAK
-case 72:
-YY_RULE_SETUP
-#line 249 "program_lexer.l"
-{ return ATTENUATION; }
-       YY_BREAK
-case 73:
-YY_RULE_SETUP
-#line 250 "program_lexer.l"
-{ return BACK; }
-       YY_BREAK
-case 74:
-YY_RULE_SETUP
-#line 251 "program_lexer.l"
-{ return_token_or_DOT(require_ARB_vp, CLIP); }
-       YY_BREAK
-case 75:
-YY_RULE_SETUP
-#line 252 "program_lexer.l"
-{ return COLOR; }
-       YY_BREAK
-case 76:
-YY_RULE_SETUP
-#line 253 "program_lexer.l"
-{ return_token_or_DOT(require_ARB_fp, DEPTH); }
-       YY_BREAK
-case 77:
-YY_RULE_SETUP
-#line 254 "program_lexer.l"
-{ return DIFFUSE; }
-       YY_BREAK
-case 78:
-YY_RULE_SETUP
-#line 255 "program_lexer.l"
-{ return DIRECTION; }
-       YY_BREAK
-case 79:
-YY_RULE_SETUP
-#line 256 "program_lexer.l"
-{ return EMISSION; }
-       YY_BREAK
-case 80:
-YY_RULE_SETUP
-#line 257 "program_lexer.l"
-{ return ENV; }
-       YY_BREAK
-case 81:
-YY_RULE_SETUP
-#line 258 "program_lexer.l"
-{ return EYE; }
-       YY_BREAK
-case 82:
-YY_RULE_SETUP
-#line 259 "program_lexer.l"
-{ return FOGCOORD; }
-       YY_BREAK
-case 83:
-YY_RULE_SETUP
-#line 260 "program_lexer.l"
-{ return FOG; }
-       YY_BREAK
-case 84:
-YY_RULE_SETUP
-#line 261 "program_lexer.l"
-{ return FRONT; }
-       YY_BREAK
-case 85:
-YY_RULE_SETUP
-#line 262 "program_lexer.l"
-{ return HALF; }
-       YY_BREAK
-case 86:
-YY_RULE_SETUP
-#line 263 "program_lexer.l"
-{ return INVERSE; }
-       YY_BREAK
-case 87:
-YY_RULE_SETUP
-#line 264 "program_lexer.l"
-{ return INVTRANS; }
-       YY_BREAK
-case 88:
-YY_RULE_SETUP
-#line 265 "program_lexer.l"
-{ return LIGHT; }
-       YY_BREAK
-case 89:
-YY_RULE_SETUP
-#line 266 "program_lexer.l"
-{ return LIGHTMODEL; }
-       YY_BREAK
-case 90:
-YY_RULE_SETUP
-#line 267 "program_lexer.l"
-{ return LIGHTPROD; }
-       YY_BREAK
-case 91:
-YY_RULE_SETUP
-#line 268 "program_lexer.l"
-{ return LOCAL; }
-       YY_BREAK
-case 92:
-YY_RULE_SETUP
-#line 269 "program_lexer.l"
-{ return MATERIAL; }
-       YY_BREAK
-case 93:
-YY_RULE_SETUP
-#line 270 "program_lexer.l"
-{ return MAT_PROGRAM; }
-       YY_BREAK
-case 94:
-YY_RULE_SETUP
-#line 271 "program_lexer.l"
-{ return MATRIX; }
-       YY_BREAK
-case 95:
-YY_RULE_SETUP
-#line 272 "program_lexer.l"
-{ return_token_or_DOT(require_ARB_vp, MATRIXINDEX); }
-       YY_BREAK
-case 96:
-YY_RULE_SETUP
-#line 273 "program_lexer.l"
-{ return MODELVIEW; }
-       YY_BREAK
-case 97:
-YY_RULE_SETUP
-#line 274 "program_lexer.l"
-{ return MVP; }
-       YY_BREAK
-case 98:
-YY_RULE_SETUP
-#line 275 "program_lexer.l"
-{ return_token_or_DOT(require_ARB_vp, NORMAL); }
-       YY_BREAK
-case 99:
-YY_RULE_SETUP
-#line 276 "program_lexer.l"
-{ return OBJECT; }
-       YY_BREAK
-case 100:
-YY_RULE_SETUP
-#line 277 "program_lexer.l"
-{ return PALETTE; }
-       YY_BREAK
-case 101:
-YY_RULE_SETUP
-#line 278 "program_lexer.l"
-{ return PARAMS; }
-       YY_BREAK
-case 102:
-YY_RULE_SETUP
-#line 279 "program_lexer.l"
-{ return PLANE; }
-       YY_BREAK
-case 103:
-YY_RULE_SETUP
-#line 280 "program_lexer.l"
-{ return_token_or_DOT(require_ARB_vp, POINT_TOK); }
-       YY_BREAK
-case 104:
-YY_RULE_SETUP
-#line 281 "program_lexer.l"
-{ return_token_or_DOT(require_ARB_vp, POINTSIZE); }
-       YY_BREAK
-case 105:
-YY_RULE_SETUP
-#line 282 "program_lexer.l"
-{ return POSITION; }
-       YY_BREAK
-case 106:
-YY_RULE_SETUP
-#line 283 "program_lexer.l"
-{ return PRIMARY; }
-       YY_BREAK
-case 107:
-YY_RULE_SETUP
-#line 284 "program_lexer.l"
-{ return PROJECTION; }
-       YY_BREAK
-case 108:
-YY_RULE_SETUP
-#line 285 "program_lexer.l"
-{ return_token_or_DOT(require_ARB_fp, RANGE); }
-       YY_BREAK
-case 109:
-YY_RULE_SETUP
-#line 286 "program_lexer.l"
-{ return ROW; }
-       YY_BREAK
-case 110:
-YY_RULE_SETUP
-#line 287 "program_lexer.l"
-{ return SCENECOLOR; }
-       YY_BREAK
-case 111:
-YY_RULE_SETUP
-#line 288 "program_lexer.l"
-{ return SECONDARY; }
-       YY_BREAK
-case 112:
-YY_RULE_SETUP
-#line 289 "program_lexer.l"
-{ return SHININESS; }
-       YY_BREAK
-case 113:
-YY_RULE_SETUP
-#line 290 "program_lexer.l"
-{ return_token_or_DOT(require_ARB_vp, SIZE_TOK); }
-       YY_BREAK
-case 114:
-YY_RULE_SETUP
-#line 291 "program_lexer.l"
-{ return SPECULAR; }
-       YY_BREAK
-case 115:
-YY_RULE_SETUP
-#line 292 "program_lexer.l"
-{ return SPOT; }
-       YY_BREAK
-case 116:
-YY_RULE_SETUP
-#line 293 "program_lexer.l"
-{ return TEXCOORD; }
-       YY_BREAK
-case 117:
-YY_RULE_SETUP
-#line 294 "program_lexer.l"
-{ return_token_or_DOT(require_ARB_fp, TEXENV); }
-       YY_BREAK
-case 118:
-YY_RULE_SETUP
-#line 295 "program_lexer.l"
-{ return_token_or_DOT(require_ARB_vp, TEXGEN); }
-       YY_BREAK
-case 119:
-YY_RULE_SETUP
-#line 296 "program_lexer.l"
-{ return_token_or_DOT(require_ARB_vp, TEXGEN_Q); }
-       YY_BREAK
-case 120:
-YY_RULE_SETUP
-#line 297 "program_lexer.l"
-{ return_token_or_DOT(require_ARB_vp, TEXGEN_S); }
-       YY_BREAK
-case 121:
-YY_RULE_SETUP
-#line 298 "program_lexer.l"
-{ return_token_or_DOT(require_ARB_vp, TEXGEN_T); }
-       YY_BREAK
-case 122:
-YY_RULE_SETUP
-#line 299 "program_lexer.l"
-{ return TEXTURE; }
-       YY_BREAK
-case 123:
-YY_RULE_SETUP
-#line 300 "program_lexer.l"
-{ return TRANSPOSE; }
-       YY_BREAK
-case 124:
-YY_RULE_SETUP
-#line 301 "program_lexer.l"
-{ return_token_or_DOT(require_ARB_vp, VTXATTRIB); }
-       YY_BREAK
-case 125:
-YY_RULE_SETUP
-#line 302 "program_lexer.l"
-{ return_token_or_DOT(require_ARB_vp, WEIGHT); }
-       YY_BREAK
-case 126:
-YY_RULE_SETUP
-#line 304 "program_lexer.l"
-{ return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); }
-       YY_BREAK
-case 127:
-YY_RULE_SETUP
-#line 305 "program_lexer.l"
-{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); }
-       YY_BREAK
-case 128:
-YY_RULE_SETUP
-#line 306 "program_lexer.l"
-{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); }
-       YY_BREAK
-case 129:
-YY_RULE_SETUP
-#line 307 "program_lexer.l"
-{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); }
-       YY_BREAK
-case 130:
-YY_RULE_SETUP
-#line 308 "program_lexer.l"
-{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); }
-       YY_BREAK
-case 131:
-YY_RULE_SETUP
-#line 309 "program_lexer.l"
-{ return_token_or_IDENTIFIER(require_ARB_fp && require_rect, TEX_RECT); }
-       YY_BREAK
-case 132:
-YY_RULE_SETUP
-#line 310 "program_lexer.l"
-{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW1D); }
-       YY_BREAK
-case 133:
-YY_RULE_SETUP
-#line 311 "program_lexer.l"
-{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW2D); }
-       YY_BREAK
-case 134:
-YY_RULE_SETUP
-#line 312 "program_lexer.l"
-{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_rect, TEX_SHADOWRECT); }
-       YY_BREAK
-case 135:
-YY_RULE_SETUP
-#line 313 "program_lexer.l"
-{ return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY1D); }
-       YY_BREAK
-case 136:
-YY_RULE_SETUP
-#line 314 "program_lexer.l"
-{ return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY2D); }
-       YY_BREAK
-case 137:
-YY_RULE_SETUP
-#line 315 "program_lexer.l"
-{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW1D); }
-       YY_BREAK
-case 138:
-YY_RULE_SETUP
-#line 316 "program_lexer.l"
-{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); }
-       YY_BREAK
-case 139:
-YY_RULE_SETUP
-#line 318 "program_lexer.l"
-{ return handle_ident(yyextra, yytext, yylval); }
-       YY_BREAK
-case 140:
-YY_RULE_SETUP
-#line 320 "program_lexer.l"
-{ return DOT_DOT; }
-       YY_BREAK
-case 141:
-YY_RULE_SETUP
-#line 322 "program_lexer.l"
-{
-   yylval->integer = strtol(yytext, NULL, 10);
-   return INTEGER;
-}
-       YY_BREAK
-case 142:
-YY_RULE_SETUP
-#line 326 "program_lexer.l"
-{
-   yylval->real = _mesa_strtof(yytext, NULL);
-   return REAL;
-}
-       YY_BREAK
-case 143:
-/* rule 143 can match eol */
-*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */
-yyg->yy_c_buf_p = yy_cp -= 1;
-YY_DO_BEFORE_ACTION; /* set up yytext again */
-YY_RULE_SETUP
-#line 330 "program_lexer.l"
-{
-   yylval->real = _mesa_strtof(yytext, NULL);
-   return REAL;
-}
-       YY_BREAK
-case 144:
-YY_RULE_SETUP
-#line 334 "program_lexer.l"
-{
-   yylval->real = _mesa_strtof(yytext, NULL);
-   return REAL;
-}
-       YY_BREAK
-case 145:
-YY_RULE_SETUP
-#line 338 "program_lexer.l"
-{
-   yylval->real = _mesa_strtof(yytext, NULL);
-   return REAL;
-}
-       YY_BREAK
-case 146:
-YY_RULE_SETUP
-#line 343 "program_lexer.l"
-{
-   yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
-   yylval->swiz_mask.mask = WRITEMASK_XYZW;
-   return MASK4;
-}
-       YY_BREAK
-case 147:
-YY_RULE_SETUP
-#line 349 "program_lexer.l"
-{
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_XY
-      | mask_from_char(yytext[3]);
-   return MASK3;
-}
-       YY_BREAK
-case 148:
-YY_RULE_SETUP
-#line 355 "program_lexer.l"
-{
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_XZW;
-   return MASK3;
-}
-       YY_BREAK
-case 149:
-YY_RULE_SETUP
-#line 360 "program_lexer.l"
-{
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_YZW;
-   return MASK3;
-}
-       YY_BREAK
-case 150:
-YY_RULE_SETUP
-#line 366 "program_lexer.l"
-{
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_X
-      | mask_from_char(yytext[2]);
-   return MASK2;
-}
-       YY_BREAK
-case 151:
-YY_RULE_SETUP
-#line 372 "program_lexer.l"
-{
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_Y
-      | mask_from_char(yytext[2]);
-   return MASK2;
-}
-       YY_BREAK
-case 152:
-YY_RULE_SETUP
-#line 378 "program_lexer.l"
-{
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_ZW;
-   return MASK2;
-}
-       YY_BREAK
-case 153:
-YY_RULE_SETUP
-#line 384 "program_lexer.l"
-{
-   const unsigned s = swiz_from_char(yytext[1]);
-   yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
-   yylval->swiz_mask.mask = mask_from_char(yytext[1]);
-   return MASK1; 
-}
-       YY_BREAK
-case 154:
-YY_RULE_SETUP
-#line 391 "program_lexer.l"
-{
-   yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
-                                           swiz_from_char(yytext[2]),
-                                           swiz_from_char(yytext[3]),
-                                           swiz_from_char(yytext[4]));
-   yylval->swiz_mask.mask = 0;
-   return SWIZZLE;
-}
-       YY_BREAK
-case 155:
-YY_RULE_SETUP
-#line 400 "program_lexer.l"
-{
-   yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
-   yylval->swiz_mask.mask = WRITEMASK_XYZW;
-   return_token_or_DOT(require_ARB_fp, MASK4);
-}
-       YY_BREAK
-case 156:
-YY_RULE_SETUP
-#line 406 "program_lexer.l"
-{
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_XY
-      | mask_from_char(yytext[3]);
-   return_token_or_DOT(require_ARB_fp, MASK3);
-}
-       YY_BREAK
-case 157:
-YY_RULE_SETUP
-#line 412 "program_lexer.l"
-{
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_XZW;
-   return_token_or_DOT(require_ARB_fp, MASK3);
-}
-       YY_BREAK
-case 158:
-YY_RULE_SETUP
-#line 417 "program_lexer.l"
-{
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_YZW;
-   return_token_or_DOT(require_ARB_fp, MASK3);
-}
-       YY_BREAK
-case 159:
-YY_RULE_SETUP
-#line 423 "program_lexer.l"
-{
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_X
-      | mask_from_char(yytext[2]);
-   return_token_or_DOT(require_ARB_fp, MASK2);
-}
-       YY_BREAK
-case 160:
-YY_RULE_SETUP
-#line 429 "program_lexer.l"
-{
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_Y
-      | mask_from_char(yytext[2]);
-   return_token_or_DOT(require_ARB_fp, MASK2);
-}
-       YY_BREAK
-case 161:
-YY_RULE_SETUP
-#line 435 "program_lexer.l"
-{
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_ZW;
-   return_token_or_DOT(require_ARB_fp, MASK2);
-}
-       YY_BREAK
-case 162:
-YY_RULE_SETUP
-#line 441 "program_lexer.l"
-{
-   const unsigned s = swiz_from_char(yytext[1]);
-   yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
-   yylval->swiz_mask.mask = mask_from_char(yytext[1]);
-   return_token_or_DOT(require_ARB_fp, MASK1);
-}
-       YY_BREAK
-case 163:
-YY_RULE_SETUP
-#line 449 "program_lexer.l"
-{
-   if (require_ARB_vp) {
-      return TEXGEN_R;
-   } else {
-      yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X,
-                                               SWIZZLE_X, SWIZZLE_X);
-      yylval->swiz_mask.mask = WRITEMASK_X;
-      return MASK1;
-   }
-}
-       YY_BREAK
-case 164:
-YY_RULE_SETUP
-#line 460 "program_lexer.l"
-{
-   yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
-                                           swiz_from_char(yytext[2]),
-                                           swiz_from_char(yytext[3]),
-                                           swiz_from_char(yytext[4]));
-   yylval->swiz_mask.mask = 0;
-   return_token_or_DOT(require_ARB_fp, SWIZZLE);
-}
-       YY_BREAK
-case 165:
-YY_RULE_SETUP
-#line 469 "program_lexer.l"
-{ return DOT; }
-       YY_BREAK
-case 166:
-/* rule 166 can match eol */
-YY_RULE_SETUP
-#line 471 "program_lexer.l"
-{
-   yylloc->first_line++;
-   yylloc->first_column = 1;
-   yylloc->last_line++;
-   yylloc->last_column = 1;
-   yylloc->position++;
-}
-       YY_BREAK
-case 167:
-YY_RULE_SETUP
-#line 478 "program_lexer.l"
-/* eat whitespace */ ;
-       YY_BREAK
-case 168:
-*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */
-yyg->yy_c_buf_p = yy_cp -= 1;
-YY_DO_BEFORE_ACTION; /* set up yytext again */
-YY_RULE_SETUP
-#line 479 "program_lexer.l"
-/* eat comments */ ;
-       YY_BREAK
-case 169:
-YY_RULE_SETUP
-#line 480 "program_lexer.l"
-{ return yytext[0]; }
-       YY_BREAK
-case 170:
-YY_RULE_SETUP
-#line 481 "program_lexer.l"
-ECHO;
-       YY_BREAK
-#line 2464 "lex.yy.c"
-case YY_STATE_EOF(INITIAL):
-       yyterminate();
-
-       case YY_END_OF_BUFFER:
-               {
-               /* Amount of text matched not including the EOB char. */
-               int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
-
-               /* Undo the effects of YY_DO_BEFORE_ACTION. */
-               *yy_cp = yyg->yy_hold_char;
-               YY_RESTORE_YY_MORE_OFFSET
-
-               if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
-                       {
-                       /* We're scanning a new file or input source.  It's
-                        * possible that this happened because the user
-                        * just pointed yyin at a new source and called
-                        * yylex().  If so, then we have to assure
-                        * consistency between YY_CURRENT_BUFFER and our
-                        * globals.  Here is the right place to do so, because
-                        * this is the first action (other than possibly a
-                        * back-up) that will match for the new input source.
-                        */
-                       yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-                       YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
-                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
-                       }
-
-               /* Note that here we test for yy_c_buf_p "<=" to the position
-                * of the first EOB in the buffer, since yy_c_buf_p will
-                * already have been incremented past the NUL character
-                * (since all states make transitions on EOB to the
-                * end-of-buffer state).  Contrast this with the test
-                * in input().
-                */
-               if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
-                       { /* This was really a NUL. */
-                       yy_state_type yy_next_state;
-
-                       yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
-
-                       yy_current_state = yy_get_previous_state( yyscanner );
-
-                       /* Okay, we're now positioned to make the NUL
-                        * transition.  We couldn't have
-                        * yy_get_previous_state() go ahead and do it
-                        * for us because it doesn't know how to deal
-                        * with the possibility of jamming (and we don't
-                        * want to build jamming into it because then it
-                        * will run more slowly).
-                        */
-
-                       yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
-
-                       yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
-
-                       if ( yy_next_state )
-                               {
-                               /* Consume the NUL. */
-                               yy_cp = ++yyg->yy_c_buf_p;
-                               yy_current_state = yy_next_state;
-                               goto yy_match;
-                               }
-
-                       else
-                               {
-                               yy_cp = yyg->yy_c_buf_p;
-                               goto yy_find_action;
-                               }
-                       }
-
-               else switch ( yy_get_next_buffer( yyscanner ) )
-                       {
-                       case EOB_ACT_END_OF_FILE:
-                               {
-                               yyg->yy_did_buffer_switch_on_eof = 0;
-
-                               if ( yywrap(yyscanner ) )
-                                       {
-                                       /* Note: because we've taken care in
-                                        * yy_get_next_buffer() to have set up
-                                        * yytext, we can now set up
-                                        * yy_c_buf_p so that if some total
-                                        * hoser (like flex itself) wants to
-                                        * call the scanner after we return the
-                                        * YY_NULL, it'll still work - another
-                                        * YY_NULL will get returned.
-                                        */
-                                       yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
-
-                                       yy_act = YY_STATE_EOF(YY_START);
-                                       goto do_action;
-                                       }
-
-                               else
-                                       {
-                                       if ( ! yyg->yy_did_buffer_switch_on_eof )
-                                               YY_NEW_FILE;
-                                       }
-                               break;
-                               }
-
-                       case EOB_ACT_CONTINUE_SCAN:
-                               yyg->yy_c_buf_p =
-                                       yyg->yytext_ptr + yy_amount_of_matched_text;
-
-                               yy_current_state = yy_get_previous_state( yyscanner );
-
-                               yy_cp = yyg->yy_c_buf_p;
-                               yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
-                               goto yy_match;
-
-                       case EOB_ACT_LAST_MATCH:
-                               yyg->yy_c_buf_p =
-                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
-
-                               yy_current_state = yy_get_previous_state( yyscanner );
-
-                               yy_cp = yyg->yy_c_buf_p;
-                               yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
-                               goto yy_find_action;
-                       }
-               break;
-               }
-
-       default:
-               YY_FATAL_ERROR(
-                       "fatal flex scanner internal error--no action found" );
-       } /* end of action switch */
-               } /* end of scanning one token */
-} /* end of yylex */
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- *     EOB_ACT_LAST_MATCH -
- *     EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- *     EOB_ACT_END_OF_FILE - end of file
- */
-static int yy_get_next_buffer (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-       register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
-       register char *source = yyg->yytext_ptr;
-       register int number_to_move, i;
-       int ret_val;
-
-       if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
-               YY_FATAL_ERROR(
-               "fatal flex scanner internal error--end of buffer missed" );
-
-       if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
-               { /* Don't try to fill the buffer, so this is an EOF. */
-               if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
-                       {
-                       /* We matched a single character, the EOB, so
-                        * treat this as a final EOF.
-                        */
-                       return EOB_ACT_END_OF_FILE;
-                       }
-
-               else
-                       {
-                       /* We matched some text prior to the EOB, first
-                        * process it.
-                        */
-                       return EOB_ACT_LAST_MATCH;
-                       }
-               }
-
-       /* Try to read more data. */
-
-       /* First move last chars to start of buffer. */
-       number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
-
-       for ( i = 0; i < number_to_move; ++i )
-               *(dest++) = *(source++);
-
-       if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
-               /* don't do the read, it's not guaranteed to return an EOF,
-                * just force an EOF
-                */
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
-
-       else
-               {
-                       int num_to_read =
-                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
-
-               while ( num_to_read <= 0 )
-                       { /* Not enough room in the buffer - grow it. */
-
-                       /* just a shorter name for the current buffer */
-                       YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
-
-                       int yy_c_buf_p_offset =
-                               (int) (yyg->yy_c_buf_p - b->yy_ch_buf);
-
-                       if ( b->yy_is_our_buffer )
-                               {
-                               int new_size = b->yy_buf_size * 2;
-
-                               if ( new_size <= 0 )
-                                       b->yy_buf_size += b->yy_buf_size / 8;
-                               else
-                                       b->yy_buf_size *= 2;
-
-                               b->yy_ch_buf = (char *)
-                                       /* Include room in for 2 EOB chars. */
-                                       yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
-                               }
-                       else
-                               /* Can't grow it, we don't own it. */
-                               b->yy_ch_buf = 0;
-
-                       if ( ! b->yy_ch_buf )
-                               YY_FATAL_ERROR(
-                               "fatal error - scanner input buffer overflow" );
-
-                       yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
-
-                       num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
-                                               number_to_move - 1;
-
-                       }
-
-               if ( num_to_read > YY_READ_BUF_SIZE )
-                       num_to_read = YY_READ_BUF_SIZE;
-
-               /* Read in more data. */
-               YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-                       yyg->yy_n_chars, (size_t) num_to_read );
-
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
-               }
-
-       if ( yyg->yy_n_chars == 0 )
-               {
-               if ( number_to_move == YY_MORE_ADJ )
-                       {
-                       ret_val = EOB_ACT_END_OF_FILE;
-                       yyrestart(yyin  ,yyscanner);
-                       }
-
-               else
-                       {
-                       ret_val = EOB_ACT_LAST_MATCH;
-                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
-                               YY_BUFFER_EOF_PENDING;
-                       }
-               }
-
-       else
-               ret_val = EOB_ACT_CONTINUE_SCAN;
-
-       if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
-               /* Extend the array by 50%, plus the number we really need. */
-               yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
-               YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
-               if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
-                       YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
-       }
-
-       yyg->yy_n_chars += number_to_move;
-       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
-       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
-
-       yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
-
-       return ret_val;
-}
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
-    static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
-{
-       register yy_state_type yy_current_state;
-       register char *yy_cp;
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-       yy_current_state = yyg->yy_start;
-
-       for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
-               {
-               register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
-               if ( yy_accept[yy_current_state] )
-                       {
-                       yyg->yy_last_accepting_state = yy_current_state;
-                       yyg->yy_last_accepting_cpos = yy_cp;
-                       }
-               while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-                       {
-                       yy_current_state = (int) yy_def[yy_current_state];
-                       if ( yy_current_state >= 850 )
-                               yy_c = yy_meta[(unsigned int) yy_c];
-                       }
-               yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-               }
-
-       return yy_current_state;
-}
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- *     next_state = yy_try_NUL_trans( current_state );
- */
-    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state , yyscan_t yyscanner)
-{
-       register int yy_is_jam;
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
-       register char *yy_cp = yyg->yy_c_buf_p;
-
-       register YY_CHAR yy_c = 1;
-       if ( yy_accept[yy_current_state] )
-               {
-               yyg->yy_last_accepting_state = yy_current_state;
-               yyg->yy_last_accepting_cpos = yy_cp;
-               }
-       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
-               {
-               yy_current_state = (int) yy_def[yy_current_state];
-               if ( yy_current_state >= 850 )
-                       yy_c = yy_meta[(unsigned int) yy_c];
-               }
-       yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-       yy_is_jam = (yy_current_state == 849);
-
-       return yy_is_jam ? 0 : yy_current_state;
-}
-
-    static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner)
-{
-       register char *yy_cp;
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-    yy_cp = yyg->yy_c_buf_p;
-
-       /* undo effects of setting up yytext */
-       *yy_cp = yyg->yy_hold_char;
-
-       if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
-               { /* need to shift things up to make room */
-               /* +2 for EOB chars. */
-               register int number_to_move = yyg->yy_n_chars + 2;
-               register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
-                                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
-               register char *source =
-                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
-
-               while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
-                       *--dest = *--source;
-
-               yy_cp += (int) (dest - source);
-               yy_bp += (int) (dest - source);
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
-                       yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
-
-               if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
-                       YY_FATAL_ERROR( "flex scanner push-back overflow" );
-               }
-
-       *--yy_cp = (char) c;
-
-       yyg->yytext_ptr = yy_bp;
-       yyg->yy_hold_char = *yy_cp;
-       yyg->yy_c_buf_p = yy_cp;
-}
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
-    static int yyinput (yyscan_t yyscanner)
-#else
-    static int input  (yyscan_t yyscanner)
-#endif
-
-{
-       int c;
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-       *yyg->yy_c_buf_p = yyg->yy_hold_char;
-
-       if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
-               {
-               /* yy_c_buf_p now points to the character we want to return.
-                * If this occurs *before* the EOB characters, then it's a
-                * valid NUL; if not, then we've hit the end of the buffer.
-                */
-               if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
-                       /* This was really a NUL. */
-                       *yyg->yy_c_buf_p = '\0';
-
-               else
-                       { /* need more input */
-                       int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
-                       ++yyg->yy_c_buf_p;
-
-                       switch ( yy_get_next_buffer( yyscanner ) )
-                               {
-                               case EOB_ACT_LAST_MATCH:
-                                       /* This happens because yy_g_n_b()
-                                        * sees that we've accumulated a
-                                        * token and flags that we need to
-                                        * try matching the token before
-                                        * proceeding.  But for input(),
-                                        * there's no matching to consider.
-                                        * So convert the EOB_ACT_LAST_MATCH
-                                        * to EOB_ACT_END_OF_FILE.
-                                        */
-
-                                       /* Reset buffer status. */
-                                       yyrestart(yyin ,yyscanner);
-
-                                       /*FALLTHROUGH*/
-
-                               case EOB_ACT_END_OF_FILE:
-                                       {
-                                       if ( yywrap(yyscanner ) )
-                                               return EOF;
-
-                                       if ( ! yyg->yy_did_buffer_switch_on_eof )
-                                               YY_NEW_FILE;
-#ifdef __cplusplus
-                                       return yyinput(yyscanner);
-#else
-                                       return input(yyscanner);
-#endif
-                                       }
-
-                               case EOB_ACT_CONTINUE_SCAN:
-                                       yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
-                                       break;
-                               }
-                       }
-               }
-
-       c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */
-       *yyg->yy_c_buf_p = '\0';        /* preserve yytext */
-       yyg->yy_hold_char = *++yyg->yy_c_buf_p;
-
-       return c;
-}
-#endif /* ifndef YY_NO_INPUT */
-
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- * @param yyscanner The scanner object.
- * @note This function does not reset the start condition to @c INITIAL .
- */
-    void yyrestart  (FILE * input_file , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-       if ( ! YY_CURRENT_BUFFER ){
-        yyensure_buffer_stack (yyscanner);
-               YY_CURRENT_BUFFER_LVALUE =
-            yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
-       }
-
-       yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
-       yy_load_buffer_state(yyscanner );
-}
-
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- * @param yyscanner The scanner object.
- */
-    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-       /* TODO. We should be able to replace this entire function body
-        * with
-        *              yypop_buffer_state();
-        *              yypush_buffer_state(new_buffer);
-     */
-       yyensure_buffer_stack (yyscanner);
-       if ( YY_CURRENT_BUFFER == new_buffer )
-               return;
-
-       if ( YY_CURRENT_BUFFER )
-               {
-               /* Flush out information for old buffer. */
-               *yyg->yy_c_buf_p = yyg->yy_hold_char;
-               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
-               }
-
-       YY_CURRENT_BUFFER_LVALUE = new_buffer;
-       yy_load_buffer_state(yyscanner );
-
-       /* We don't actually know whether we did this switch during
-        * EOF (yywrap()) processing, but the only time this flag
-        * is looked at is after yywrap() is called, so it's safe
-        * to go ahead and always set it.
-        */
-       yyg->yy_did_buffer_switch_on_eof = 1;
-}
-
-static void yy_load_buffer_state  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-       yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
-       yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
-       yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
-       yyg->yy_hold_char = *yyg->yy_c_buf_p;
-}
-
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- * @param yyscanner The scanner object.
- * @return the allocated buffer state.
- */
-    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size , yyscan_t yyscanner)
-{
-       YY_BUFFER_STATE b;
-    
-       b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
-       if ( ! b )
-               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
-       b->yy_buf_size = size;
-
-       /* yy_ch_buf has to be 2 characters longer than the size given because
-        * we need to put in 2 end-of-buffer characters.
-        */
-       b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ,yyscanner );
-       if ( ! b->yy_ch_buf )
-               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
-       b->yy_is_our_buffer = 1;
-
-       yy_init_buffer(b,file ,yyscanner);
-
-       return b;
-}
-
-/** Destroy the buffer.
- * @param b a buffer created with yy_create_buffer()
- * @param yyscanner The scanner object.
- */
-    void yy_delete_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-       if ( ! b )
-               return;
-
-       if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
-               YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
-
-       if ( b->yy_is_our_buffer )
-               yyfree((void *) b->yy_ch_buf ,yyscanner );
-
-       yyfree((void *) b ,yyscanner );
-}
-
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a yyrestart() or at EOF.
- */
-    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file , yyscan_t yyscanner)
-
-{
-       int oerrno = errno;
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-       yy_flush_buffer(b ,yyscanner);
-
-       b->yy_input_file = file;
-       b->yy_fill_buffer = 1;
-
-    /* If b is the current buffer, then yy_init_buffer was _probably_
-     * called from yyrestart() or through yy_get_next_buffer.
-     * In that case, we don't want to reset the lineno or column.
-     */
-    if (b != YY_CURRENT_BUFFER){
-        b->yy_bs_lineno = 1;
-        b->yy_bs_column = 0;
-    }
-
-        b->yy_is_interactive = 0;
-    
-       errno = oerrno;
-}
-
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- * @param yyscanner The scanner object.
- */
-    void yy_flush_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-       if ( ! b )
-               return;
-
-       b->yy_n_chars = 0;
-
-       /* We always need two end-of-buffer characters.  The first causes
-        * a transition to the end-of-buffer state.  The second causes
-        * a jam in that state.
-        */
-       b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
-       b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
-       b->yy_buf_pos = &b->yy_ch_buf[0];
-
-       b->yy_at_bol = 1;
-       b->yy_buffer_status = YY_BUFFER_NEW;
-
-       if ( b == YY_CURRENT_BUFFER )
-               yy_load_buffer_state(yyscanner );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- *  the current state. This function will allocate the stack
- *  if necessary.
- *  @param new_buffer The new state.
- *  @param yyscanner The scanner object.
- */
-void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-       if (new_buffer == NULL)
-               return;
-
-       yyensure_buffer_stack(yyscanner);
-
-       /* This block is copied from yy_switch_to_buffer. */
-       if ( YY_CURRENT_BUFFER )
-               {
-               /* Flush out information for old buffer. */
-               *yyg->yy_c_buf_p = yyg->yy_hold_char;
-               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
-               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
-               }
-
-       /* Only push if top exists. Otherwise, replace top. */
-       if (YY_CURRENT_BUFFER)
-               yyg->yy_buffer_stack_top++;
-       YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
-       /* copied from yy_switch_to_buffer. */
-       yy_load_buffer_state(yyscanner );
-       yyg->yy_did_buffer_switch_on_eof = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- *  The next element becomes the new top.
- *  @param yyscanner The scanner object.
- */
-void yypop_buffer_state (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-       if (!YY_CURRENT_BUFFER)
-               return;
-
-       yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
-       YY_CURRENT_BUFFER_LVALUE = NULL;
-       if (yyg->yy_buffer_stack_top > 0)
-               --yyg->yy_buffer_stack_top;
-
-       if (YY_CURRENT_BUFFER) {
-               yy_load_buffer_state(yyscanner );
-               yyg->yy_did_buffer_switch_on_eof = 1;
-       }
-}
-
-/* Allocates the stack if it does not exist.
- *  Guarantees space for at least one push.
- */
-static void yyensure_buffer_stack (yyscan_t yyscanner)
-{
-       int num_to_alloc;
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-       if (!yyg->yy_buffer_stack) {
-
-               /* First allocation is just for 2 elements, since we don't know if this
-                * scanner will even need a stack. We use 2 instead of 1 to avoid an
-                * immediate realloc on the next call.
-         */
-               num_to_alloc = 1;
-               yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc
-                                                               (num_to_alloc * sizeof(struct yy_buffer_state*)
-                                                               , yyscanner);
-               if ( ! yyg->yy_buffer_stack )
-                       YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
-                                                                 
-               memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-                               
-               yyg->yy_buffer_stack_max = num_to_alloc;
-               yyg->yy_buffer_stack_top = 0;
-               return;
-       }
-
-       if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
-
-               /* Increase the buffer to prepare for a possible push. */
-               int grow_size = 8 /* arbitrary grow size */;
-
-               num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
-               yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc
-                                                               (yyg->yy_buffer_stack,
-                                                               num_to_alloc * sizeof(struct yy_buffer_state*)
-                                                               , yyscanner);
-               if ( ! yyg->yy_buffer_stack )
-                       YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
-
-               /* zero only the new slots.*/
-               memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
-               yyg->yy_buffer_stack_max = num_to_alloc;
-       }
-}
-
-/** Setup the input buffer state to scan directly from a user-specified character buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object. 
- */
-YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size , yyscan_t yyscanner)
-{
-       YY_BUFFER_STATE b;
-    
-       if ( size < 2 ||
-            base[size-2] != YY_END_OF_BUFFER_CHAR ||
-            base[size-1] != YY_END_OF_BUFFER_CHAR )
-               /* They forgot to leave room for the EOB's. */
-               return 0;
-
-       b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
-       if ( ! b )
-               YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
-
-       b->yy_buf_size = size - 2;      /* "- 2" to take care of EOB's */
-       b->yy_buf_pos = b->yy_ch_buf = base;
-       b->yy_is_our_buffer = 0;
-       b->yy_input_file = 0;
-       b->yy_n_chars = b->yy_buf_size;
-       b->yy_is_interactive = 0;
-       b->yy_at_bol = 1;
-       b->yy_fill_buffer = 0;
-       b->yy_buffer_status = YY_BUFFER_NEW;
-
-       yy_switch_to_buffer(b ,yyscanner );
-
-       return b;
-}
-
-/** Setup the input buffer state to scan a string. The next call to yylex() will
- * scan from a @e copy of @a str.
- * @param yystr a NUL-terminated string to scan
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- *       yy_scan_bytes() instead.
- */
-YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
-{
-    
-       return yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
-}
-
-/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
- * scan from a @e copy of @a bytes.
- * @param bytes the byte buffer to scan
- * @param len the number of bytes in the buffer pointed to by @a bytes.
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, int  _yybytes_len , yyscan_t yyscanner)
-{
-       YY_BUFFER_STATE b;
-       char *buf;
-       yy_size_t n;
-       int i;
-    
-       /* Get memory for full buffer, including space for trailing EOB's. */
-       n = _yybytes_len + 2;
-       buf = (char *) yyalloc(n ,yyscanner );
-       if ( ! buf )
-               YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
-
-       for ( i = 0; i < _yybytes_len; ++i )
-               buf[i] = yybytes[i];
-
-       buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
-
-       b = yy_scan_buffer(buf,n ,yyscanner);
-       if ( ! b )
-               YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
-
-       /* It's okay to grow etc. this buffer, and we should throw it
-        * away when we're done.
-        */
-       b->yy_is_our_buffer = 1;
-
-       return b;
-}
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
-{
-       (void) fprintf( stderr, "%s\n", msg );
-       exit( YY_EXIT_FAILURE );
-}
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
-       do \
-               { \
-               /* Undo effects of setting up yytext. */ \
-        int yyless_macro_arg = (n); \
-        YY_LESS_LINENO(yyless_macro_arg);\
-               yytext[yyleng] = yyg->yy_hold_char; \
-               yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
-               yyg->yy_hold_char = *yyg->yy_c_buf_p; \
-               *yyg->yy_c_buf_p = '\0'; \
-               yyleng = yyless_macro_arg; \
-               } \
-       while ( 0 )
-
-/* Accessor  methods (get/set functions) to struct members. */
-
-/** Get the user-defined data for this scanner.
- * @param yyscanner The scanner object.
- */
-YY_EXTRA_TYPE yyget_extra  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    return yyextra;
-}
-
-/** Get the current line number.
- * @param yyscanner The scanner object.
- */
-int yyget_lineno  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    
-        if (! YY_CURRENT_BUFFER)
-            return 0;
-    
-    return yylineno;
-}
-
-/** Get the current column number.
- * @param yyscanner The scanner object.
- */
-int yyget_column  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    
-        if (! YY_CURRENT_BUFFER)
-            return 0;
-    
-    return yycolumn;
-}
-
-/** Get the input stream.
- * @param yyscanner The scanner object.
- */
-FILE *yyget_in  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    return yyin;
-}
-
-/** Get the output stream.
- * @param yyscanner The scanner object.
- */
-FILE *yyget_out  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    return yyout;
-}
-
-/** Get the length of the current token.
- * @param yyscanner The scanner object.
- */
-int yyget_leng  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    return yyleng;
-}
-
-/** Get the current token.
- * @param yyscanner The scanner object.
- */
-
-char *yyget_text  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    return yytext;
-}
-
-/** Set the user-defined data. This data is never touched by the scanner.
- * @param user_defined The data to be associated with this scanner.
- * @param yyscanner The scanner object.
- */
-void yyset_extra (YY_EXTRA_TYPE  user_defined , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    yyextra = user_defined ;
-}
-
-/** Set the current line number.
- * @param line_number
- * @param yyscanner The scanner object.
- */
-void yyset_lineno (int  line_number , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-        /* lineno is only valid if an input buffer exists. */
-        if (! YY_CURRENT_BUFFER )
-           yy_fatal_error( "yyset_lineno called with no buffer" , yyscanner); 
-    
-    yylineno = line_number;
-}
-
-/** Set the current column.
- * @param line_number
- * @param yyscanner The scanner object.
- */
-void yyset_column (int  column_no , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-        /* column is only valid if an input buffer exists. */
-        if (! YY_CURRENT_BUFFER )
-           yy_fatal_error( "yyset_column called with no buffer" , yyscanner); 
-    
-    yycolumn = column_no;
-}
-
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param in_str A readable stream.
- * @param yyscanner The scanner object.
- * @see yy_switch_to_buffer
- */
-void yyset_in (FILE *  in_str , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    yyin = in_str ;
-}
-
-void yyset_out (FILE *  out_str , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    yyout = out_str ;
-}
-
-int yyget_debug  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    return yy_flex_debug;
-}
-
-void yyset_debug (int  bdebug , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    yy_flex_debug = bdebug ;
-}
-
-/* Accessor methods for yylval and yylloc */
-
-YYSTYPE * yyget_lval  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    return yylval;
-}
-
-void yyset_lval (YYSTYPE *  yylval_param , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    yylval = yylval_param;
-}
-
-YYLTYPE *yyget_lloc  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    return yylloc;
-}
-    
-void yyset_lloc (YYLTYPE *  yylloc_param , yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    yylloc = yylloc_param;
-}
-    
-/* User-visible API */
-
-/* yylex_init is special because it creates the scanner itself, so it is
- * the ONLY reentrant function that doesn't take the scanner as the last argument.
- * That's why we explicitly handle the declaration, instead of using our macros.
- */
-
-int yylex_init(yyscan_t* ptr_yy_globals)
-
-{
-    if (ptr_yy_globals == NULL){
-        errno = EINVAL;
-        return 1;
-    }
-
-    *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL );
-
-    if (*ptr_yy_globals == NULL){
-        errno = ENOMEM;
-        return 1;
-    }
-
-    /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
-    memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
-    return yy_init_globals ( *ptr_yy_globals );
-}
-
-/* yylex_init_extra has the same functionality as yylex_init, but follows the
- * convention of taking the scanner as the last argument. Note however, that
- * this is a *pointer* to a scanner, as it will be allocated by this call (and
- * is the reason, too, why this function also must handle its own declaration).
- * The user defined value in the first argument will be available to yyalloc in
- * the yyextra field.
- */
-
-int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
-
-{
-    struct yyguts_t dummy_yyguts;
-
-    yyset_extra (yy_user_defined, &dummy_yyguts);
-
-    if (ptr_yy_globals == NULL){
-        errno = EINVAL;
-        return 1;
-    }
-       
-    *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
-       
-    if (*ptr_yy_globals == NULL){
-        errno = ENOMEM;
-        return 1;
-    }
-    
-    /* By setting to 0xAA, we expose bugs in
-    yy_init_globals. Leave at 0x00 for releases. */
-    memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-    
-    yyset_extra (yy_user_defined, *ptr_yy_globals);
-    
-    return yy_init_globals ( *ptr_yy_globals );
-}
-
-static int yy_init_globals (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-    /* Initialization is the same as for the non-reentrant scanner.
-     * This function is called from yylex_destroy(), so don't allocate here.
-     */
-
-    yyg->yy_buffer_stack = 0;
-    yyg->yy_buffer_stack_top = 0;
-    yyg->yy_buffer_stack_max = 0;
-    yyg->yy_c_buf_p = (char *) 0;
-    yyg->yy_init = 0;
-    yyg->yy_start = 0;
-
-    yyg->yy_start_stack_ptr = 0;
-    yyg->yy_start_stack_depth = 0;
-    yyg->yy_start_stack =  NULL;
-
-/* Defined in main.c */
-#ifdef YY_STDINIT
-    yyin = stdin;
-    yyout = stdout;
-#else
-    yyin = (FILE *) 0;
-    yyout = (FILE *) 0;
-#endif
-
-    /* For future reference: Set errno on error, since we are called by
-     * yylex_init()
-     */
-    return 0;
-}
-
-/* yylex_destroy is for both reentrant and non-reentrant scanners. */
-int yylex_destroy  (yyscan_t yyscanner)
-{
-    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-    /* Pop the buffer stack, destroying each element. */
-       while(YY_CURRENT_BUFFER){
-               yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
-               YY_CURRENT_BUFFER_LVALUE = NULL;
-               yypop_buffer_state(yyscanner);
-       }
-
-       /* Destroy the stack itself. */
-       yyfree(yyg->yy_buffer_stack ,yyscanner);
-       yyg->yy_buffer_stack = NULL;
-
-    /* Destroy the start condition stack. */
-        yyfree(yyg->yy_start_stack ,yyscanner );
-        yyg->yy_start_stack = NULL;
-
-    /* Reset the globals. This is important in a non-reentrant scanner so the next time
-     * yylex() is called, initialization will occur. */
-    yy_init_globals( yyscanner);
-
-    /* Destroy the main struct (reentrant only). */
-    yyfree ( yyscanner , yyscanner );
-    yyscanner = NULL;
-    return 0;
-}
-
-/*
- * Internal utility routines.
- */
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
-{
-       register int i;
-       for ( i = 0; i < n; ++i )
-               s1[i] = s2[i];
-}
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
-{
-       register int n;
-       for ( n = 0; s[n]; ++n )
-               ;
-
-       return n;
-}
-#endif
-
-void *yyalloc (yy_size_t  size , yyscan_t yyscanner)
-{
-       return (void *) malloc( size );
-}
-
-void *yyrealloc  (void * ptr, yy_size_t  size , yyscan_t yyscanner)
-{
-       /* The cast to (char *) in the following accommodates both
-        * implementations that use char* generic pointers, and those
-        * that use void* generic pointers.  It works with the latter
-        * because both ANSI C and C++ allow castless assignment from
-        * any pointer type to void*, and deal with argument conversions
-        * as though doing an assignment.
-        */
-       return (void *) realloc( (char *) ptr, size );
-}
-
-void yyfree (void * ptr , yyscan_t yyscanner)
-{
-       free( (char *) ptr );   /* see yyrealloc() for (char *) cast */
-}
-
-#define YYTABLES_NAME "yytables"
-
-#line 481 "program_lexer.l"
-
-
-
-void
-_mesa_program_lexer_ctor(void **scanner, struct asm_parser_state *state,
-                        const char *string, size_t len)
-{
-   yylex_init_extra(state,scanner);
-   yy_scan_bytes(string,len,*scanner);
-}
-
-void
-_mesa_program_lexer_dtor(void *scanner)
-{
-   yylex_destroy(scanner);
-}
-
diff --git a/src/mesa/shader/nvfragparse.c b/src/mesa/shader/nvfragparse.c
deleted file mode 100644 (file)
index 0de3c58..0000000
+++ /dev/null
@@ -1,1588 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * \file nvfragparse.c
- * NVIDIA fragment program parser.
- * \author Brian Paul
- */
-
-/*
- * Regarding GL_NV_fragment_program:
- *
- * Portions of this software may use or implement intellectual
- * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims
- * any and all warranties with respect to such intellectual property,
- * including any use thereof or modifications thereto.
- */
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/imports.h"
-#include "main/macros.h"
-#include "program.h"
-#include "prog_parameter.h"
-#include "prog_print.h"
-#include "prog_instruction.h"
-#include "nvfragparse.h"
-
-
-#define INPUT_1V     1
-#define INPUT_2V     2
-#define INPUT_3V     3
-#define INPUT_1S     4
-#define INPUT_2S     5
-#define INPUT_CC     6
-#define INPUT_1V_T   7  /* one source vector, plus textureId */
-#define INPUT_3V_T   8  /* one source vector, plus textureId */
-#define INPUT_NONE   9
-#define INPUT_1V_S  10  /* a string and a vector register */
-#define OUTPUT_V    20
-#define OUTPUT_S    21
-#define OUTPUT_NONE 22
-
-/* IRIX defines some of these */
-#undef _R
-#undef _H
-#undef _X
-#undef _C
-#undef _S
-
-/* Optional suffixes */
-#define _R  FLOAT32  /* float */
-#define _H  FLOAT16  /* half-float */
-#define _X  FIXED12  /* fixed */
-#define _C  0x08     /* set cond codes */
-#define _S  0x10     /* saturate, clamp result to [0,1] */
-
-struct instruction_pattern {
-   const char *name;
-   enum prog_opcode opcode;
-   GLuint inputs;
-   GLuint outputs;
-   GLuint suffixes;
-};
-
-static const struct instruction_pattern Instructions[] = {
-   { "ADD", OPCODE_ADD, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "COS", OPCODE_COS, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
-   { "DDX", OPCODE_DDX, INPUT_1V, OUTPUT_V, _R | _H |      _C | _S },
-   { "DDY", OPCODE_DDY, INPUT_1V, OUTPUT_V, _R | _H |      _C | _S },
-   { "DP3", OPCODE_DP3, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S },
-   { "DP4", OPCODE_DP4, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S },
-   { "DST", OPCODE_DP4, INPUT_2V, OUTPUT_V, _R | _H |      _C | _S },
-   { "EX2", OPCODE_DP4, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
-   { "FLR", OPCODE_FLR, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "FRC", OPCODE_FRC, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "KIL", OPCODE_KIL_NV, INPUT_CC, OUTPUT_NONE, 0                },
-   { "LG2", OPCODE_LG2, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
-   { "LIT", OPCODE_LIT, INPUT_1V, OUTPUT_V, _R | _H |      _C | _S },
-   { "LRP", OPCODE_LRP, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "MAD", OPCODE_MAD, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "MAX", OPCODE_MAX, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "MIN", OPCODE_MIN, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "MOV", OPCODE_MOV, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "MUL", OPCODE_MUL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "PK2H",  OPCODE_PK2H,  INPUT_1V, OUTPUT_S, 0                  },
-   { "PK2US", OPCODE_PK2US, INPUT_1V, OUTPUT_S, 0                  },
-   { "PK4B",  OPCODE_PK4B,  INPUT_1V, OUTPUT_S, 0                  },
-   { "PK4UB", OPCODE_PK4UB, INPUT_1V, OUTPUT_S, 0                  },
-   { "POW", OPCODE_POW, INPUT_2S, OUTPUT_S, _R | _H |      _C | _S },
-   { "RCP", OPCODE_RCP, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
-   { "RFL", OPCODE_RFL, INPUT_2V, OUTPUT_V, _R | _H |      _C | _S },
-   { "RSQ", OPCODE_RSQ, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
-   { "SEQ", OPCODE_SEQ, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "SFL", OPCODE_SFL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "SGE", OPCODE_SGE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "SGT", OPCODE_SGT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "SIN", OPCODE_SIN, INPUT_1S, OUTPUT_S, _R | _H |      _C | _S },
-   { "SLE", OPCODE_SLE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "SLT", OPCODE_SLT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "SNE", OPCODE_SNE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "STR", OPCODE_STR, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "SUB", OPCODE_SUB, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
-   { "TEX", OPCODE_TEX, INPUT_1V_T, OUTPUT_V,              _C | _S },
-   { "TXD", OPCODE_TXD, INPUT_3V_T, OUTPUT_V,              _C | _S },
-   { "TXP", OPCODE_TXP_NV, INPUT_1V_T, OUTPUT_V,           _C | _S },
-   { "UP2H",  OPCODE_UP2H,  INPUT_1S, OUTPUT_V,            _C | _S },
-   { "UP2US", OPCODE_UP2US, INPUT_1S, OUTPUT_V,            _C | _S },
-   { "UP4B",  OPCODE_UP4B,  INPUT_1S, OUTPUT_V,            _C | _S },
-   { "UP4UB", OPCODE_UP4UB, INPUT_1S, OUTPUT_V,            _C | _S },
-   { "X2D", OPCODE_X2D, INPUT_3V, OUTPUT_V, _R | _H |      _C | _S },
-   { "PRINT", OPCODE_PRINT, INPUT_1V_S, OUTPUT_NONE, 0               },
-   { NULL, (enum prog_opcode) -1, 0, 0, 0 }
-};
-
-
-/*
- * Information needed or computed during parsing.
- * Remember, we can't modify the target program object until we've
- * _successfully_ parsed the program text.
- */
-struct parse_state {
-   GLcontext *ctx;
-   const GLubyte *start;              /* start of program string */
-   const GLubyte *pos;                /* current position */
-   const GLubyte *curLine;
-   struct gl_fragment_program *program;  /* current program */
-
-   struct gl_program_parameter_list *parameters;
-
-   GLuint numInst;                    /* number of instructions parsed */
-   GLuint inputsRead;                 /* bitmask of input registers used */
-   GLuint outputsWritten;             /* bitmask of 1 << FRAG_OUTPUT_* bits */
-   GLuint texturesUsed[MAX_TEXTURE_IMAGE_UNITS];
-};
-
-
-
-/*
- * Called whenever we find an error during parsing.
- */
-static void
-record_error(struct parse_state *parseState, const char *msg, int lineNo)
-{
-#ifdef DEBUG
-   GLint line, column;
-   const GLubyte *lineStr;
-   lineStr = _mesa_find_line_column(parseState->start,
-                                    parseState->pos, &line, &column);
-   _mesa_debug(parseState->ctx,
-               "nvfragparse.c(%d): line %d, column %d:%s (%s)\n",
-               lineNo, line, column, (char *) lineStr, msg);
-   free((void *) lineStr);
-#else
-   (void) lineNo;
-#endif
-
-   /* Check that no error was already recorded.  Only record the first one. */
-   if (parseState->ctx->Program.ErrorString[0] == 0) {
-      _mesa_set_program_error(parseState->ctx,
-                              parseState->pos - parseState->start,
-                              msg);
-   }
-}
-
-
-#define RETURN_ERROR                                                   \
-do {                                                                   \
-   record_error(parseState, "Unexpected end of input.", __LINE__);     \
-   return GL_FALSE;                                                    \
-} while(0)
-
-#define RETURN_ERROR1(msg)                                             \
-do {                                                                   \
-   record_error(parseState, msg, __LINE__);                            \
-   return GL_FALSE;                                                    \
-} while(0)
-
-#define RETURN_ERROR2(msg1, msg2)                                      \
-do {                                                                   \
-   char err[1000];                                                     \
-   sprintf(err, "%s %s", msg1, msg2);                          \
-   record_error(parseState, err, __LINE__);                            \
-   return GL_FALSE;                                                    \
-} while(0)
-
-
-
-
-/*
- * Search a list of instruction structures for a match.
- */
-static struct instruction_pattern
-MatchInstruction(const GLubyte *token)
-{
-   const struct instruction_pattern *inst;
-   struct instruction_pattern result;
-
-   result.name = NULL;
-   result.opcode = MAX_OPCODE; /* i.e. invalid instruction */
-   result.inputs = 0;
-   result.outputs = 0;
-   result.suffixes = 0;
-
-   for (inst = Instructions; inst->name; inst++) {
-      if (strncmp((const char *) token, inst->name, 3) == 0) {
-         /* matched! */
-         int i = 3;
-         result = *inst;
-         result.suffixes = 0;
-         /* look at suffix */
-         if (token[i] == 'R') {
-            result.suffixes |= _R;
-            i++;
-         }
-         else if (token[i] == 'H') {
-            result.suffixes |= _H;
-            i++;
-         }
-         else if (token[i] == 'X') {
-            result.suffixes |= _X;
-            i++;
-         }
-         if (token[i] == 'C') {
-            result.suffixes |= _C;
-            i++;
-         }
-         if (token[i] == '_' && token[i+1] == 'S' &&
-             token[i+2] == 'A' && token[i+3] == 'T') {
-            result.suffixes |= _S;
-         }
-         return result;
-      }
-   }
-
-   return result;
-}
-
-
-
-
-/**********************************************************************/
-
-
-static GLboolean IsLetter(GLubyte b)
-{
-   return (b >= 'a' && b <= 'z') ||
-          (b >= 'A' && b <= 'Z') ||
-          (b == '_') ||
-          (b == '$');
-}
-
-
-static GLboolean IsDigit(GLubyte b)
-{
-   return b >= '0' && b <= '9';
-}
-
-
-static GLboolean IsWhitespace(GLubyte b)
-{
-   return b == ' ' || b == '\t' || b == '\n' || b == '\r';
-}
-
-
-/**
- * Starting at 'str' find the next token.  A token can be an integer,
- * an identifier or punctuation symbol.
- * \return <= 0 we found an error, else, return number of characters parsed.
- */
-static GLint
-GetToken(struct parse_state *parseState, GLubyte *token)
-{
-   const GLubyte *str = parseState->pos;
-   GLint i = 0, j = 0;
-
-   token[0] = 0;
-
-   /* skip whitespace and comments */
-   while (str[i] && (IsWhitespace(str[i]) || str[i] == '#')) {
-      if (str[i] == '#') {
-         /* skip comment */
-         while (str[i] && (str[i] != '\n' && str[i] != '\r')) {
-            i++;
-         }
-         if (str[i] == '\n' || str[i] == '\r')
-            parseState->curLine = str + i + 1;
-      }
-      else {
-         /* skip whitespace */
-         if (str[i] == '\n' || str[i] == '\r')
-            parseState->curLine = str + i + 1;
-         i++;
-      }
-   }
-
-   if (str[i] == 0)
-      return -i;
-
-   /* try matching an integer */
-   while (str[i] && IsDigit(str[i])) {
-      token[j++] = str[i++];
-   }
-   if (j > 0 || !str[i]) {
-      token[j] = 0;
-      return i;
-   }
-
-   /* try matching an identifier */
-   if (IsLetter(str[i])) {
-      while (str[i] && (IsLetter(str[i]) || IsDigit(str[i]))) {
-         token[j++] = str[i++];
-      }
-      token[j] = 0;
-      return i;
-   }
-
-   /* punctuation character */
-   if (str[i]) {
-      token[0] = str[i++];
-      token[1] = 0;
-      return i;
-   }
-
-   /* end of input */
-   token[0] = 0;
-   return i;
-}
-
-
-/**
- * Get next token from input stream and increment stream pointer past token.
- */
-static GLboolean
-Parse_Token(struct parse_state *parseState, GLubyte *token)
-{
-   GLint i;
-   i = GetToken(parseState, token);
-   if (i <= 0) {
-      parseState->pos += (-i);
-      return GL_FALSE;
-   }
-   parseState->pos += i;
-   return GL_TRUE;
-}
-
-
-/**
- * Get next token from input stream but don't increment stream pointer.
- */
-static GLboolean
-Peek_Token(struct parse_state *parseState, GLubyte *token)
-{
-   GLint i, len;
-   i = GetToken(parseState, token);
-   if (i <= 0) {
-      parseState->pos += (-i);
-      return GL_FALSE;
-   }
-   len = (GLint) strlen((const char *) token);
-   parseState->pos += (i - len);
-   return GL_TRUE;
-}
-
-
-/**********************************************************************/
-
-static const char *InputRegisters[MAX_NV_FRAGMENT_PROGRAM_INPUTS + 1] = {
-   "WPOS", "COL0", "COL1", "FOGC",
-   "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL
-};
-
-
-
-/**********************************************************************/
-
-/**
- * Try to match 'pattern' as the next token after any whitespace/comments.
- */
-static GLboolean
-Parse_String(struct parse_state *parseState, const char *pattern)
-{
-   const GLubyte *m;
-   GLint i;
-
-   /* skip whitespace and comments */
-   while (IsWhitespace(*parseState->pos) || *parseState->pos == '#') {
-      if (*parseState->pos == '#') {
-         while (*parseState->pos && (*parseState->pos != '\n' && *parseState->pos != '\r')) {
-            parseState->pos += 1;
-         }
-         if (*parseState->pos == '\n' || *parseState->pos == '\r')
-            parseState->curLine = parseState->pos + 1;
-      }
-      else {
-         /* skip whitespace */
-         if (*parseState->pos == '\n' || *parseState->pos == '\r')
-            parseState->curLine = parseState->pos + 1;
-         parseState->pos += 1;
-      }
-   }
-
-   /* Try to match the pattern */
-   m = parseState->pos;
-   for (i = 0; pattern[i]; i++) {
-      if (*m != (GLubyte) pattern[i])
-         return GL_FALSE;
-      m += 1;
-   }
-   parseState->pos = m;
-
-   return GL_TRUE; /* success */
-}
-
-
-static GLboolean
-Parse_Identifier(struct parse_state *parseState, GLubyte *ident)
-{
-   if (!Parse_Token(parseState, ident))
-      RETURN_ERROR;
-   if (IsLetter(ident[0]))
-      return GL_TRUE;
-   else
-      RETURN_ERROR1("Expected an identfier");
-}
-
-
-/**
- * Parse a floating point constant, or a defined symbol name.
- * [+/-]N[.N[eN]]
- * Output:  number[0 .. 3] will get the value.
- */
-static GLboolean
-Parse_ScalarConstant(struct parse_state *parseState, GLfloat *number)
-{
-   char *end = NULL;
-
-   *number = (GLfloat) _mesa_strtof((const char *) parseState->pos, &end);
-
-   if (end && end > (char *) parseState->pos) {
-      /* got a number */
-      parseState->pos = (GLubyte *) end;
-      number[1] = *number;
-      number[2] = *number;
-      number[3] = *number;
-      return GL_TRUE;
-   }
-   else {
-      /* should be an identifier */
-      GLubyte ident[100];
-      const GLfloat *constant;
-      if (!Parse_Identifier(parseState, ident))
-         RETURN_ERROR1("Expected an identifier");
-      constant = _mesa_lookup_parameter_value(parseState->parameters,
-                                              -1, (const char *) ident);
-      /* XXX Check that it's a constant and not a parameter */
-      if (!constant) {
-         RETURN_ERROR1("Undefined symbol");
-      }
-      else {
-         COPY_4V(number, constant);
-         return GL_TRUE;
-      }
-   }
-}
-
-
-
-/**
- * Parse a vector constant, one of:
- *   { float }
- *   { float, float }
- *   { float, float, float }
- *   { float, float, float, float }
- */
-static GLboolean
-Parse_VectorConstant(struct parse_state *parseState, GLfloat *vec)
-{
-   /* "{" was already consumed */
-
-   ASSIGN_4V(vec, 0.0, 0.0, 0.0, 1.0);
-
-   if (!Parse_ScalarConstant(parseState, vec+0))  /* X */
-      return GL_FALSE;
-
-   if (Parse_String(parseState, "}")) {
-      return GL_TRUE;
-   }
-
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR1("Expected comma in vector constant");
-
-   if (!Parse_ScalarConstant(parseState, vec+1))  /* Y */
-      return GL_FALSE;
-
-   if (Parse_String(parseState, "}")) {
-      return GL_TRUE;
-   }
-
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR1("Expected comma in vector constant");
-
-   if (!Parse_ScalarConstant(parseState, vec+2))  /* Z */
-      return GL_FALSE;
-
-   if (Parse_String(parseState, "}")) {
-      return GL_TRUE;
-   }
-
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR1("Expected comma in vector constant");
-
-   if (!Parse_ScalarConstant(parseState, vec+3))  /* W */
-      return GL_FALSE;
-
-   if (!Parse_String(parseState, "}"))
-      RETURN_ERROR1("Expected closing brace in vector constant");
-
-   return GL_TRUE;
-}
-
-
-/**
- * Parse <number>, <varname> or {a, b, c, d}.
- * Return number of values in the vector or scalar, or zero if parse error.
- */
-static GLuint
-Parse_VectorOrScalarConstant(struct parse_state *parseState, GLfloat *vec)
-{
-   if (Parse_String(parseState, "{")) {
-      return Parse_VectorConstant(parseState, vec);
-   }
-   else {
-      GLboolean b = Parse_ScalarConstant(parseState, vec);
-      if (b) {
-         vec[1] = vec[2] = vec[3] = vec[0];
-      }
-      return b;
-   }
-}
-
-
-/**
- * Parse a texture image source:
- *    [TEX0 | TEX1 | .. | TEX15] , [1D | 2D | 3D | CUBE | RECT]
- */
-static GLboolean
-Parse_TextureImageId(struct parse_state *parseState,
-                     GLubyte *texUnit, GLubyte *texTargetBit)
-{
-   GLubyte imageSrc[100];
-   GLint unit;
-
-   if (!Parse_Token(parseState, imageSrc))
-      RETURN_ERROR;
-   
-   if (imageSrc[0] != 'T' ||
-       imageSrc[1] != 'E' ||
-       imageSrc[2] != 'X') {
-      RETURN_ERROR1("Expected TEX# source");
-   }
-   unit = atoi((const char *) imageSrc + 3);
-   if ((unit < 0 || unit > MAX_TEXTURE_IMAGE_UNITS) ||
-       (unit == 0 && (imageSrc[3] != '0' || imageSrc[4] != 0))) {
-      RETURN_ERROR1("Invalied TEX# source index");
-   }
-   *texUnit = unit;
-
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR1("Expected ,");
-
-   if (Parse_String(parseState, "1D")) {
-      *texTargetBit = TEXTURE_1D_BIT;
-   }
-   else if (Parse_String(parseState, "2D")) {
-      *texTargetBit = TEXTURE_2D_BIT;
-   }
-   else if (Parse_String(parseState, "3D")) {
-      *texTargetBit = TEXTURE_3D_BIT;
-   }
-   else if (Parse_String(parseState, "CUBE")) {
-      *texTargetBit = TEXTURE_CUBE_BIT;
-   }
-   else if (Parse_String(parseState, "RECT")) {
-      *texTargetBit = TEXTURE_RECT_BIT;
-   }
-   else {
-      RETURN_ERROR1("Invalid texture target token");
-   }
-
-   /* update record of referenced texture units */
-   parseState->texturesUsed[*texUnit] |= *texTargetBit;
-   if (_mesa_bitcount(parseState->texturesUsed[*texUnit]) > 1) {
-      RETURN_ERROR1("Only one texture target can be used per texture unit.");
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Parse a scalar suffix like .x, .y, .z or .w or parse a swizzle suffix
- * like .wxyz, .xxyy, etc and return the swizzle indexes.
- */
-static GLboolean
-Parse_SwizzleSuffix(const GLubyte *token, GLuint swizzle[4])
-{
-   if (token[1] == 0) {
-      /* single letter swizzle (scalar) */
-      if (token[0] == 'x')
-         ASSIGN_4V(swizzle, 0, 0, 0, 0);
-      else if (token[0] == 'y')
-         ASSIGN_4V(swizzle, 1, 1, 1, 1);
-      else if (token[0] == 'z')
-         ASSIGN_4V(swizzle, 2, 2, 2, 2);
-      else if (token[0] == 'w')
-         ASSIGN_4V(swizzle, 3, 3, 3, 3);
-      else
-         return GL_FALSE;
-   }
-   else {
-      /* 4-component swizzle (vector) */
-      GLint k;
-      for (k = 0; k < 4 && token[k]; k++) {
-         if (token[k] == 'x')
-            swizzle[k] = 0;
-         else if (token[k] == 'y')
-            swizzle[k] = 1;
-         else if (token[k] == 'z')
-            swizzle[k] = 2;
-         else if (token[k] == 'w')
-            swizzle[k] = 3;
-         else
-            return GL_FALSE;
-      }
-      if (k != 4)
-         return GL_FALSE;
-   }
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_CondCodeMask(struct parse_state *parseState,
-                   struct prog_dst_register *dstReg)
-{
-   if (Parse_String(parseState, "EQ"))
-      dstReg->CondMask = COND_EQ;
-   else if (Parse_String(parseState, "GE"))
-      dstReg->CondMask = COND_GE;
-   else if (Parse_String(parseState, "GT"))
-      dstReg->CondMask = COND_GT;
-   else if (Parse_String(parseState, "LE"))
-      dstReg->CondMask = COND_LE;
-   else if (Parse_String(parseState, "LT"))
-      dstReg->CondMask = COND_LT;
-   else if (Parse_String(parseState, "NE"))
-      dstReg->CondMask = COND_NE;
-   else if (Parse_String(parseState, "TR"))
-      dstReg->CondMask = COND_TR;
-   else if (Parse_String(parseState, "FL"))
-      dstReg->CondMask = COND_FL;
-   else
-      RETURN_ERROR1("Invalid condition code mask");
-
-   /* look for optional .xyzw swizzle */
-   if (Parse_String(parseState, ".")) {
-      GLubyte token[100];
-      GLuint swz[4];
-
-      if (!Parse_Token(parseState, token))  /* get xyzw suffix */
-         RETURN_ERROR;
-
-      if (!Parse_SwizzleSuffix(token, swz))
-         RETURN_ERROR1("Invalid swizzle suffix");
-
-      dstReg->CondSwizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Parse a temporary register: Rnn or Hnn
- */
-static GLboolean
-Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum)
-{
-   GLubyte token[100];
-
-   /* Should be 'R##' or 'H##' */
-   if (!Parse_Token(parseState, token))
-      RETURN_ERROR;
-   if (token[0] != 'R' && token[0] != 'H')
-      RETURN_ERROR1("Expected R## or H##");
-
-   if (IsDigit(token[1])) {
-      GLint reg = atoi((const char *) (token + 1));
-      if (token[0] == 'H')
-         reg += 32;
-      if (reg >= MAX_NV_FRAGMENT_PROGRAM_TEMPS)
-         RETURN_ERROR1("Invalid temporary register name");
-      *tempRegNum = reg;
-   }
-   else {
-      RETURN_ERROR1("Invalid temporary register name");
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Parse a write-only dummy register: RC or HC.
- */
-static GLboolean
-Parse_DummyReg(struct parse_state *parseState, GLint *regNum)
-{
-   if (Parse_String(parseState, "RC")) {
-       *regNum = 0;
-   }
-   else if (Parse_String(parseState, "HC")) {
-       *regNum = 1;
-   }
-   else {
-      RETURN_ERROR1("Invalid write-only register name");
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Parse a program local parameter register "p[##]"
- */
-static GLboolean
-Parse_ProgramParamReg(struct parse_state *parseState, GLint *regNum)
-{
-   GLubyte token[100];
-
-   if (!Parse_String(parseState, "p["))
-      RETURN_ERROR1("Expected p[");
-
-   if (!Parse_Token(parseState, token))
-      RETURN_ERROR;
-
-   if (IsDigit(token[0])) {
-      /* a numbered program parameter register */
-      GLint reg = atoi((const char *) token);
-      if (reg >= MAX_NV_FRAGMENT_PROGRAM_PARAMS)
-         RETURN_ERROR1("Invalid constant program number");
-      *regNum = reg;
-   }
-   else {
-      RETURN_ERROR;
-   }
-
-   if (!Parse_String(parseState, "]"))
-      RETURN_ERROR1("Expected ]");
-
-   return GL_TRUE;
-}
-
-
-/**
- * Parse f[name]  - fragment input register
- */
-static GLboolean
-Parse_FragReg(struct parse_state *parseState, GLint *tempRegNum)
-{
-   GLubyte token[100];
-   GLint j;
-
-   /* Match 'f[' */
-   if (!Parse_String(parseState, "f["))
-      RETURN_ERROR1("Expected f[");
-
-   /* get <name> and look for match */
-   if (!Parse_Token(parseState, token)) {
-      RETURN_ERROR;
-   }
-   for (j = 0; InputRegisters[j]; j++) {
-      if (strcmp((const char *) token, InputRegisters[j]) == 0) {
-         *tempRegNum = j;
-         parseState->inputsRead |= (1 << j);
-         break;
-      }
-   }
-   if (!InputRegisters[j]) {
-      /* unknown input register label */
-      RETURN_ERROR2("Invalid register name", token);
-   }
-
-   /* Match '[' */
-   if (!Parse_String(parseState, "]"))
-      RETURN_ERROR1("Expected ]");
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum)
-{
-   GLubyte token[100];
-
-   /* Match "o[" */
-   if (!Parse_String(parseState, "o["))
-      RETURN_ERROR1("Expected o[");
-
-   /* Get output reg name */
-   if (!Parse_Token(parseState, token))
-      RETURN_ERROR;
-
-   /* try to match an output register name */
-   if (strcmp((char *) token, "COLR") == 0 ||
-       strcmp((char *) token, "COLH") == 0) {
-      /* note that we don't distinguish between COLR and COLH */
-      *outputRegNum = FRAG_RESULT_COLOR;
-      parseState->outputsWritten |= (1 << FRAG_RESULT_COLOR);
-   }
-   else if (strcmp((char *) token, "DEPR") == 0) {
-      *outputRegNum = FRAG_RESULT_DEPTH;
-      parseState->outputsWritten |= (1 << FRAG_RESULT_DEPTH);
-   }
-   else {
-      RETURN_ERROR1("Invalid output register name");
-   }
-
-   /* Match ']' */
-   if (!Parse_String(parseState, "]"))
-      RETURN_ERROR1("Expected ]");
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_MaskedDstReg(struct parse_state *parseState,
-                   struct prog_dst_register *dstReg)
-{
-   GLubyte token[100];
-   GLint idx;
-
-   /* Dst reg can be R<n>, H<n>, o[n], RC or HC */
-   if (!Peek_Token(parseState, token))
-      RETURN_ERROR;
-
-   if (strcmp((const char *) token, "RC") == 0 ||
-       strcmp((const char *) token, "HC") == 0) {
-      /* a write-only register */
-      dstReg->File = PROGRAM_WRITE_ONLY;
-      if (!Parse_DummyReg(parseState, &idx))
-         RETURN_ERROR;
-      dstReg->Index = idx;
-   }
-   else if (token[0] == 'R' || token[0] == 'H') {
-      /* a temporary register */
-      dstReg->File = PROGRAM_TEMPORARY;
-      if (!Parse_TempReg(parseState, &idx))
-         RETURN_ERROR;
-      dstReg->Index = idx;
-   }
-   else if (token[0] == 'o') {
-      /* an output register */
-      dstReg->File = PROGRAM_OUTPUT;
-      if (!Parse_OutputReg(parseState, &idx))
-         RETURN_ERROR;
-      dstReg->Index = idx;
-   }
-   else {
-      RETURN_ERROR1("Invalid destination register name");
-   }
-
-   /* Parse optional write mask */
-   if (Parse_String(parseState, ".")) {
-      /* got a mask */
-      GLint k = 0;
-
-      if (!Parse_Token(parseState, token))  /* get xyzw writemask */
-         RETURN_ERROR;
-
-      dstReg->WriteMask = 0;
-
-      if (token[k] == 'x') {
-         dstReg->WriteMask |= WRITEMASK_X;
-         k++;
-      }
-      if (token[k] == 'y') {
-         dstReg->WriteMask |= WRITEMASK_Y;
-         k++;
-      }
-      if (token[k] == 'z') {
-         dstReg->WriteMask |= WRITEMASK_Z;
-         k++;
-      }
-      if (token[k] == 'w') {
-         dstReg->WriteMask |= WRITEMASK_W;
-         k++;
-      }
-      if (k == 0) {
-         RETURN_ERROR1("Invalid writemask character");
-      }
-
-   }
-   else {
-      dstReg->WriteMask = WRITEMASK_XYZW;
-   }
-
-   /* optional condition code mask */
-   if (Parse_String(parseState, "(")) {
-      /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".x|y|z|w) */
-      /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".[xyzw]) */
-      if (!Parse_CondCodeMask(parseState, dstReg))
-         RETURN_ERROR;
-
-      if (!Parse_String(parseState, ")"))  /* consume ")" */
-         RETURN_ERROR1("Expected )");
-
-      return GL_TRUE;
-   }
-   else {
-      /* no cond code mask */
-      dstReg->CondMask = COND_TR;
-      dstReg->CondSwizzle = SWIZZLE_NOOP;
-      return GL_TRUE;
-   }
-}
-
-
-/**
- * Parse a vector source (register, constant, etc):
- *   <vectorSrc>    ::= <absVectorSrc>
- *                    | <baseVectorSrc>
- *   <absVectorSrc> ::= <negate> "|" <baseVectorSrc> "|"
- */
-static GLboolean
-Parse_VectorSrc(struct parse_state *parseState,
-                struct prog_src_register *srcReg)
-{
-   GLfloat sign = 1.0F;
-   GLubyte token[100];
-   GLint idx;
-   GLuint negateBase, negateAbs;
-
-   /*
-    * First, take care of +/- and absolute value stuff.
-    */
-   if (Parse_String(parseState, "-"))
-      sign = -1.0F;
-   else if (Parse_String(parseState, "+"))
-      sign = +1.0F;
-
-   if (Parse_String(parseState, "|")) {
-      srcReg->Abs = GL_TRUE;
-      negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
-
-      if (Parse_String(parseState, "-"))
-         negateBase = NEGATE_XYZW;
-      else if (Parse_String(parseState, "+"))
-         negateBase = NEGATE_NONE;
-      else
-         negateBase = NEGATE_NONE;
-   }
-   else {
-      srcReg->Abs = GL_FALSE;
-      negateAbs = NEGATE_NONE;
-      negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
-   }
-
-   srcReg->Negate = srcReg->Abs ? negateAbs : negateBase;
-
-   /* This should be the real src vector/register name */
-   if (!Peek_Token(parseState, token))
-      RETURN_ERROR;
-
-   /* Src reg can be Rn, Hn, f[n], p[n], a named parameter, a scalar
-    * literal or vector literal.
-    */
-   if (token[0] == 'R' || token[0] == 'H') {
-      srcReg->File = PROGRAM_TEMPORARY;
-      if (!Parse_TempReg(parseState, &idx))
-         RETURN_ERROR;
-      srcReg->Index = idx;
-   }
-   else if (token[0] == 'f') {
-      /* XXX this might be an identifier! */
-      srcReg->File = PROGRAM_INPUT;
-      if (!Parse_FragReg(parseState, &idx))
-         RETURN_ERROR;
-      srcReg->Index = idx;
-   }
-   else if (token[0] == 'p') {
-      /* XXX this might be an identifier! */
-      srcReg->File = PROGRAM_LOCAL_PARAM;
-      if (!Parse_ProgramParamReg(parseState, &idx))
-         RETURN_ERROR;
-      srcReg->Index = idx;
-   }
-   else if (IsLetter(token[0])){
-      GLubyte ident[100];
-      GLint paramIndex;
-      if (!Parse_Identifier(parseState, ident))
-         RETURN_ERROR;
-      paramIndex = _mesa_lookup_parameter_index(parseState->parameters,
-                                                -1, (const char *) ident);
-      if (paramIndex < 0) {
-         RETURN_ERROR2("Undefined constant or parameter: ", ident);
-      }
-      srcReg->File = PROGRAM_NAMED_PARAM;
-      srcReg->Index = paramIndex;      
-   }
-   else if (IsDigit(token[0]) || token[0] == '-' || token[0] == '+' || token[0] == '.'){
-      /* literal scalar constant */
-      GLfloat values[4];
-      GLuint paramIndex;
-      if (!Parse_ScalarConstant(parseState, values))
-         RETURN_ERROR;
-      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
-                                              values, 4, NULL);
-      srcReg->File = PROGRAM_NAMED_PARAM;
-      srcReg->Index = paramIndex;
-   }
-   else if (token[0] == '{'){
-      /* literal vector constant */
-      GLfloat values[4];
-      GLuint paramIndex;
-      (void) Parse_String(parseState, "{");
-      if (!Parse_VectorConstant(parseState, values))
-         RETURN_ERROR;
-      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
-                                              values, 4, NULL);
-      srcReg->File = PROGRAM_NAMED_PARAM;
-      srcReg->Index = paramIndex;      
-   }
-   else {
-      RETURN_ERROR2("Invalid source register name", token);
-   }
-
-   /* init swizzle fields */
-   srcReg->Swizzle = SWIZZLE_NOOP;
-
-   /* Look for optional swizzle suffix */
-   if (Parse_String(parseState, ".")) {
-      GLuint swz[4];
-
-      if (!Parse_Token(parseState, token))
-         RETURN_ERROR;
-
-      if (!Parse_SwizzleSuffix(token, swz))
-         RETURN_ERROR1("Invalid swizzle suffix");
-
-      srcReg->Swizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
-   }
-
-   /* Finish absolute value */
-   if (srcReg->Abs && !Parse_String(parseState, "|")) {
-      RETURN_ERROR1("Expected |");
-   }
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_ScalarSrcReg(struct parse_state *parseState,
-                   struct prog_src_register *srcReg)
-{
-   GLubyte token[100];
-   GLfloat sign = 1.0F;
-   GLboolean needSuffix = GL_TRUE;
-   GLint idx;
-   GLuint negateBase, negateAbs;
-
-   /*
-    * First, take care of +/- and absolute value stuff.
-    */
-   if (Parse_String(parseState, "-"))
-      sign = -1.0F;
-   else if (Parse_String(parseState, "+"))
-      sign = +1.0F;
-
-   if (Parse_String(parseState, "|")) {
-      srcReg->Abs = GL_TRUE;
-      negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
-
-      if (Parse_String(parseState, "-"))
-         negateBase = NEGATE_XYZW;
-      else if (Parse_String(parseState, "+"))
-         negateBase = NEGATE_NONE;
-      else
-         negateBase = NEGATE_NONE;
-   }
-   else {
-      srcReg->Abs = GL_FALSE;
-      negateAbs = NEGATE_NONE;
-      negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
-   }
-
-   srcReg->Negate = srcReg->Abs ? negateAbs : negateBase;
-
-   if (!Peek_Token(parseState, token))
-      RETURN_ERROR;
-
-   /* Src reg can be R<n>, H<n> or a named fragment attrib */
-   if (token[0] == 'R' || token[0] == 'H') {
-      srcReg->File = PROGRAM_TEMPORARY;
-      if (!Parse_TempReg(parseState, &idx))
-         RETURN_ERROR;
-      srcReg->Index = idx;
-   }
-   else if (token[0] == 'f') {
-      srcReg->File = PROGRAM_INPUT;
-      if (!Parse_FragReg(parseState, &idx))
-         RETURN_ERROR;
-      srcReg->Index = idx;
-   }
-   else if (token[0] == '{') {
-      /* vector literal */
-      GLfloat values[4];
-      GLuint paramIndex;
-      (void) Parse_String(parseState, "{");
-      if (!Parse_VectorConstant(parseState, values))
-         RETURN_ERROR;
-      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
-                                              values, 4, NULL);
-      srcReg->File = PROGRAM_NAMED_PARAM;
-      srcReg->Index = paramIndex;      
-   }
-   else if (IsLetter(token[0])){
-      /* named param/constant */
-      GLubyte ident[100];
-      GLint paramIndex;
-      if (!Parse_Identifier(parseState, ident))
-         RETURN_ERROR;
-      paramIndex = _mesa_lookup_parameter_index(parseState->parameters,
-                                                -1, (const char *) ident);
-      if (paramIndex < 0) {
-         RETURN_ERROR2("Undefined constant or parameter: ", ident);
-      }
-      srcReg->File = PROGRAM_NAMED_PARAM;
-      srcReg->Index = paramIndex;      
-   }
-   else if (IsDigit(token[0])) {
-      /* scalar literal */
-      GLfloat values[4];
-      GLuint paramIndex;
-      if (!Parse_ScalarConstant(parseState, values))
-         RETURN_ERROR;
-      paramIndex = _mesa_add_unnamed_constant(parseState->parameters,
-                                              values, 4, NULL);
-      srcReg->Index = paramIndex;      
-      srcReg->File = PROGRAM_NAMED_PARAM;
-      needSuffix = GL_FALSE;
-   }
-   else {
-      RETURN_ERROR2("Invalid scalar source argument", token);
-   }
-
-   srcReg->Swizzle = 0;
-   if (needSuffix) {
-      /* parse .[xyzw] suffix */
-      if (!Parse_String(parseState, "."))
-         RETURN_ERROR1("Expected .");
-
-      if (!Parse_Token(parseState, token))
-         RETURN_ERROR;
-
-      if (token[0] == 'x' && token[1] == 0) {
-         srcReg->Swizzle = 0;
-      }
-      else if (token[0] == 'y' && token[1] == 0) {
-         srcReg->Swizzle = 1;
-      }
-      else if (token[0] == 'z' && token[1] == 0) {
-         srcReg->Swizzle = 2;
-      }
-      else if (token[0] == 'w' && token[1] == 0) {
-         srcReg->Swizzle = 3;
-      }
-      else {
-         RETURN_ERROR1("Invalid scalar source suffix");
-      }
-   }
-
-   /* Finish absolute value */
-   if (srcReg->Abs && !Parse_String(parseState, "|")) {
-      RETURN_ERROR1("Expected |");
-   }
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_PrintInstruction(struct parse_state *parseState,
-                       struct prog_instruction *inst)
-{
-   const GLubyte *str;
-   GLubyte *msg;
-   GLuint len;
-   GLint idx;
-
-   /* The first argument is a literal string 'just like this' */
-   if (!Parse_String(parseState, "'"))
-      RETURN_ERROR1("Expected '");
-
-   str = parseState->pos;
-   for (len = 0; str[len] != '\''; len++) /* find closing quote */
-      ;
-   parseState->pos += len + 1;
-   msg = (GLubyte*) malloc(len + 1);
-
-   memcpy(msg, str, len);
-   msg[len] = 0;
-   inst->Data = msg;
-
-   if (Parse_String(parseState, ",")) {
-      /* got an optional register to print */
-      GLubyte token[100];
-      GetToken(parseState, token);
-      if (token[0] == 'o') {
-         /* dst reg */
-         if (!Parse_OutputReg(parseState, &idx))
-            RETURN_ERROR;
-        inst->SrcReg[0].Index = idx;
-         inst->SrcReg[0].File = PROGRAM_OUTPUT;
-      }
-      else {
-         /* src reg */
-         if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
-            RETURN_ERROR;
-      }
-   }
-   else {
-      inst->SrcReg[0].File = PROGRAM_UNDEFINED;
-   }
-
-   inst->SrcReg[0].Swizzle = SWIZZLE_NOOP;
-   inst->SrcReg[0].Abs = GL_FALSE;
-   inst->SrcReg[0].Negate = NEGATE_NONE;
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_InstructionSequence(struct parse_state *parseState,
-                          struct prog_instruction program[])
-{
-   while (1) {
-      struct prog_instruction *inst = program + parseState->numInst;
-      struct instruction_pattern instMatch;
-      GLubyte token[100];
-
-      /* Initialize the instruction */
-      _mesa_init_instructions(inst, 1);
-
-      /* special instructions */
-      if (Parse_String(parseState, "DEFINE")) {
-         GLubyte id[100];
-         GLfloat value[7];  /* yes, 7 to be safe */
-         if (!Parse_Identifier(parseState, id))
-            RETURN_ERROR;
-         /* XXX make sure id is not a reserved identifer, like R9 */
-         if (!Parse_String(parseState, "="))
-            RETURN_ERROR1("Expected =");
-         if (!Parse_VectorOrScalarConstant(parseState, value))
-            RETURN_ERROR;
-         if (!Parse_String(parseState, ";"))
-            RETURN_ERROR1("Expected ;");
-         if (_mesa_lookup_parameter_index(parseState->parameters,
-                                          -1, (const char *) id) >= 0) {
-            RETURN_ERROR2(id, "already defined");
-         }
-         _mesa_add_named_parameter(parseState->parameters,
-                                   (const char *) id, value);
-      }
-      else if (Parse_String(parseState, "DECLARE")) {
-         GLubyte id[100];
-         GLfloat value[7] = {0, 0, 0, 0, 0, 0, 0};  /* yes, to be safe */
-         if (!Parse_Identifier(parseState, id))
-            RETURN_ERROR;
-         /* XXX make sure id is not a reserved identifer, like R9 */
-         if (Parse_String(parseState, "=")) {
-            if (!Parse_VectorOrScalarConstant(parseState, value))
-               RETURN_ERROR;
-         }
-         if (!Parse_String(parseState, ";"))
-            RETURN_ERROR1("Expected ;");
-         if (_mesa_lookup_parameter_index(parseState->parameters,
-                                          -1, (const char *) id) >= 0) {
-            RETURN_ERROR2(id, "already declared");
-         }
-         _mesa_add_named_parameter(parseState->parameters,
-                                   (const char *) id, value);
-      }
-      else if (Parse_String(parseState, "END")) {
-         inst->Opcode = OPCODE_END;
-         parseState->numInst++;
-         if (Parse_Token(parseState, token)) {
-            RETURN_ERROR1("Code after END opcode.");
-         }
-         break;
-      }
-      else {
-         /* general/arithmetic instruction */
-
-         /* get token */
-         if (!Parse_Token(parseState, token)) {
-            RETURN_ERROR1("Missing END instruction.");
-         }
-
-         /* try to find matching instuction */
-         instMatch = MatchInstruction(token);
-         if (instMatch.opcode >= MAX_OPCODE) {
-            /* bad instruction name */
-            RETURN_ERROR2("Unexpected token: ", token);
-         }
-
-         inst->Opcode = instMatch.opcode;
-         inst->Precision = instMatch.suffixes & (_R | _H | _X);
-         inst->SaturateMode = (instMatch.suffixes & (_S))
-            ? SATURATE_ZERO_ONE : SATURATE_OFF;
-         inst->CondUpdate = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE;
-
-         /*
-          * parse the input and output operands
-          */
-         if (instMatch.outputs == OUTPUT_S || instMatch.outputs == OUTPUT_V) {
-            if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
-               RETURN_ERROR;
-            if (!Parse_String(parseState, ","))
-               RETURN_ERROR1("Expected ,");
-         }
-         else if (instMatch.outputs == OUTPUT_NONE) {
-            if (instMatch.opcode == OPCODE_KIL_NV) {
-               /* This is a little weird, the cond code info is in
-                * the dest register.
-                */
-               if (!Parse_CondCodeMask(parseState, &inst->DstReg))
-                  RETURN_ERROR;
-            }
-            else {
-               ASSERT(instMatch.opcode == OPCODE_PRINT);
-            }
-         }
-
-         if (instMatch.inputs == INPUT_1V) {
-            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
-               RETURN_ERROR;
-         }
-         else if (instMatch.inputs == INPUT_2V) {
-            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
-               RETURN_ERROR;
-            if (!Parse_String(parseState, ","))
-               RETURN_ERROR1("Expected ,");
-            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
-               RETURN_ERROR;
-         }
-         else if (instMatch.inputs == INPUT_3V) {
-            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
-               RETURN_ERROR;
-            if (!Parse_String(parseState, ","))
-               RETURN_ERROR1("Expected ,");
-            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
-               RETURN_ERROR;
-            if (!Parse_String(parseState, ","))
-               RETURN_ERROR1("Expected ,");
-            if (!Parse_VectorSrc(parseState, &inst->SrcReg[2]))
-               RETURN_ERROR;
-         }
-         else if (instMatch.inputs == INPUT_1S) {
-            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
-               RETURN_ERROR;
-         }
-         else if (instMatch.inputs == INPUT_2S) {
-            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
-               RETURN_ERROR;
-            if (!Parse_String(parseState, ","))
-               RETURN_ERROR1("Expected ,");
-            if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[1]))
-               RETURN_ERROR;
-         }
-         else if (instMatch.inputs == INPUT_CC) {
-            /* XXX to-do */
-         }
-         else if (instMatch.inputs == INPUT_1V_T) {
-           GLubyte unit, idx;
-            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
-               RETURN_ERROR;
-            if (!Parse_String(parseState, ","))
-               RETURN_ERROR1("Expected ,");
-            if (!Parse_TextureImageId(parseState, &unit, &idx))
-               RETURN_ERROR;
-           inst->TexSrcUnit = unit;
-           inst->TexSrcTarget = idx;
-         }
-         else if (instMatch.inputs == INPUT_3V_T) {
-           GLubyte unit, idx;
-            if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
-               RETURN_ERROR;
-            if (!Parse_String(parseState, ","))
-               RETURN_ERROR1("Expected ,");
-            if (!Parse_VectorSrc(parseState, &inst->SrcReg[1]))
-               RETURN_ERROR;
-            if (!Parse_String(parseState, ","))
-               RETURN_ERROR1("Expected ,");
-            if (!Parse_VectorSrc(parseState, &inst->SrcReg[2]))
-               RETURN_ERROR;
-            if (!Parse_String(parseState, ","))
-               RETURN_ERROR1("Expected ,");
-            if (!Parse_TextureImageId(parseState, &unit, &idx))
-               RETURN_ERROR;
-           inst->TexSrcUnit = unit;
-           inst->TexSrcTarget = idx;
-         }
-         else if (instMatch.inputs == INPUT_1V_S) {
-            if (!Parse_PrintInstruction(parseState, inst))
-               RETURN_ERROR;
-         }
-
-         /* end of statement semicolon */
-         if (!Parse_String(parseState, ";"))
-            RETURN_ERROR1("Expected ;");
-
-         parseState->numInst++;
-
-         if (parseState->numInst >= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS)
-            RETURN_ERROR1("Program too long");
-      }
-   }
-   return GL_TRUE;
-}
-
-
-
-/**
- * Parse/compile the 'str' returning the compiled 'program'.
- * ctx->Program.ErrorPos will be -1 if successful.  Otherwise, ErrorPos
- * indicates the position of the error in 'str'.
- */
-void
-_mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,
-                                const GLubyte *str, GLsizei len,
-                                struct gl_fragment_program *program)
-{
-   struct parse_state parseState;
-   struct prog_instruction instBuffer[MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS];
-   struct prog_instruction *newInst;
-   GLenum target;
-   GLubyte *programString;
-
-   /* Make a null-terminated copy of the program string */
-   programString = (GLubyte *) MALLOC(len + 1);
-   if (!programString) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
-      return;
-   }
-   memcpy(programString, str, len);
-   programString[len] = 0;
-
-   /* Get ready to parse */
-   memset(&parseState, 0, sizeof(struct parse_state));
-   parseState.ctx = ctx;
-   parseState.start = programString;
-   parseState.program = program;
-   parseState.numInst = 0;
-   parseState.curLine = programString;
-   parseState.parameters = _mesa_new_parameter_list();
-
-   /* Reset error state */
-   _mesa_set_program_error(ctx, -1, NULL);
-
-   /* check the program header */
-   if (strncmp((const char *) programString, "!!FP1.0", 7) == 0) {
-      target = GL_FRAGMENT_PROGRAM_NV;
-      parseState.pos = programString + 7;
-   }
-   else if (strncmp((const char *) programString, "!!FCP1.0", 8) == 0) {
-      /* fragment / register combiner program - not supported */
-      _mesa_set_program_error(ctx, 0, "Invalid fragment program header");
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
-      return;
-   }
-   else {
-      /* invalid header */
-      _mesa_set_program_error(ctx, 0, "Invalid fragment program header");
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
-      return;
-   }
-
-   /* make sure target and header match */
-   if (target != dstTarget) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glLoadProgramNV(target mismatch 0x%x != 0x%x)",
-                  target, dstTarget);
-      return;
-   }
-
-   if (Parse_InstructionSequence(&parseState, instBuffer)) {
-      GLuint u;
-      /* successful parse! */
-
-      if (parseState.outputsWritten == 0) {
-         /* must write at least one output! */
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "Invalid fragment program - no outputs written.");
-         return;
-      }
-
-      /* copy the compiled instructions */
-      assert(parseState.numInst <= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS);
-      newInst = _mesa_alloc_instructions(parseState.numInst);
-      if (!newInst) {
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
-         return;  /* out of memory */
-      }
-      _mesa_copy_instructions(newInst, instBuffer, parseState.numInst);
-
-      /* install the program */
-      program->Base.Target = target;
-      if (program->Base.String) {
-         FREE(program->Base.String);
-      }
-      program->Base.String = programString;
-      program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;
-      if (program->Base.Instructions) {
-         free(program->Base.Instructions);
-      }
-      program->Base.Instructions = newInst;
-      program->Base.NumInstructions = parseState.numInst;
-      program->Base.InputsRead = parseState.inputsRead;
-      program->Base.OutputsWritten = parseState.outputsWritten;
-      for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++)
-         program->Base.TexturesUsed[u] = parseState.texturesUsed[u];
-
-      /* save program parameters */
-      program->Base.Parameters = parseState.parameters;
-
-      /* allocate registers for declared program parameters */
-#if 00
-      _mesa_assign_program_registers(&(program->SymbolTable));
-#endif
-
-#ifdef DEBUG_foo
-      printf("--- glLoadProgramNV(%d) result ---\n", program->Base.Id);
-      _mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0);
-      printf("----------------------------------\n");
-#endif
-   }
-   else {
-      /* Error! */
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV");
-      /* NOTE: _mesa_set_program_error would have been called already */
-   }
-}
-
-
-const char *
-_mesa_nv_fragment_input_register_name(GLuint i)
-{
-   ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_INPUTS);
-   return InputRegisters[i];
-}
-
diff --git a/src/mesa/shader/nvfragparse.h b/src/mesa/shader/nvfragparse.h
deleted file mode 100644 (file)
index 544ab80..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-
-/*
- * Mesa 3-D graphics library
- * Version:  5.1
- *
- * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Brian Paul
- */
-
-
-#ifndef NVFRAGPARSE_H
-#define NVFRAGPARSE_H
-
-
-extern void
-_mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum target,
-                                const GLubyte *str, GLsizei len,
-                                struct gl_fragment_program *program);
-
-
-extern const char *
-_mesa_nv_fragment_input_register_name(GLuint i);
-
-#endif
diff --git a/src/mesa/shader/nvprogram.c b/src/mesa/shader/nvprogram.c
deleted file mode 100644 (file)
index 19020be..0000000
+++ /dev/null
@@ -1,917 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.2
- *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file nvprogram.c
- * NVIDIA vertex/fragment program state management functions.
- * \author Brian Paul
- */
-
-/*
- * Regarding GL_NV_fragment/vertex_program, GL_NV_vertex_program1_1, etc:
- *
- * Portions of this software may use or implement intellectual
- * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims
- * any and all warranties with respect to such intellectual property,
- * including any use thereof or modifications thereto.
- */
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/hash.h"
-#include "main/imports.h"
-#include "main/macros.h"
-#include "program.h"
-#include "prog_parameter.h"
-#include "prog_instruction.h"
-#include "nvfragparse.h"
-#include "nvvertparse.h"
-#include "arbprogparse.h"
-#include "nvprogram.h"
-
-
-
-/**
- * Execute a vertex state program.
- * \note Called from the GL API dispatcher.
- */
-void GLAPIENTRY
-_mesa_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params)
-{
-   struct gl_vertex_program *vprog;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (target != GL_VERTEX_STATE_PROGRAM_NV) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glExecuteProgramNV");
-      return;
-   }
-
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
-
-   vprog = (struct gl_vertex_program *) _mesa_lookup_program(ctx, id);
-
-   if (!vprog || vprog->Base.Target != GL_VERTEX_STATE_PROGRAM_NV) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glExecuteProgramNV");
-      return;
-   }
-   
-   _mesa_problem(ctx, "glExecuteProgramNV() not supported");
-}
-
-
-/**
- * Determine if a set of programs is resident in hardware.
- * \note Not compiled into display lists.
- * \note Called from the GL API dispatcher.
- */
-GLboolean GLAPIENTRY
-_mesa_AreProgramsResidentNV(GLsizei n, const GLuint *ids,
-                            GLboolean *residences)
-{
-   GLint i, j;
-   GLboolean allResident = GL_TRUE;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
-
-   if (n < 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glAreProgramsResidentNV(n)");
-      return GL_FALSE;
-   }
-
-   for (i = 0; i < n; i++) {
-      const struct gl_program *prog;
-      if (ids[i] == 0) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glAreProgramsResidentNV");
-         return GL_FALSE;
-      }
-      prog = _mesa_lookup_program(ctx, ids[i]);
-      if (!prog) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glAreProgramsResidentNV");
-         return GL_FALSE;
-      }
-      if (prog->Resident) {
-        if (!allResident)
-           residences[i] = GL_TRUE;
-      }
-      else {
-         if (allResident) {
-           allResident = GL_FALSE;
-           for (j = 0; j < i; j++)
-              residences[j] = GL_TRUE;
-        }
-        residences[i] = GL_FALSE;
-      }
-   }
-
-   return allResident;
-}
-
-
-/**
- * Request that a set of programs be resident in hardware.
- * \note Called from the GL API dispatcher.
- */
-void GLAPIENTRY
-_mesa_RequestResidentProgramsNV(GLsizei n, const GLuint *ids)
-{
-   GLint i;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (n < 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glRequestResidentProgramsNV(n)");
-      return;
-   }
-
-   /* just error checking for now */
-   for (i = 0; i < n; i++) {
-      struct gl_program *prog;
-
-      if (ids[i] == 0) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glRequestResidentProgramsNV(id)");
-         return;
-      }
-
-      prog = _mesa_lookup_program(ctx, ids[i]);
-      if (!prog) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glRequestResidentProgramsNV(id)");
-         return;
-      }
-
-      /* XXX this is really a hardware thing we should hook out */
-      prog->Resident = GL_TRUE;
-   }
-}
-
-
-/**
- * Get a program parameter register.
- * \note Not compiled into display lists.
- * \note Called from the GL API dispatcher.
- */
-void GLAPIENTRY
-_mesa_GetProgramParameterfvNV(GLenum target, GLuint index,
-                              GLenum pname, GLfloat *params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (target == GL_VERTEX_PROGRAM_NV) {
-      if (pname == GL_PROGRAM_PARAMETER_NV) {
-         if (index < MAX_NV_VERTEX_PROGRAM_PARAMS) {
-            COPY_4V(params, ctx->VertexProgram.Parameters[index]);
-         }
-         else {
-            _mesa_error(ctx, GL_INVALID_VALUE,
-                        "glGetProgramParameterfvNV(index)");
-            return;
-         }
-      }
-      else {
-         _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramParameterfvNV(pname)");
-         return;
-      }
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramParameterfvNV(target)");
-      return;
-   }
-}
-
-
-/**
- * Get a program parameter register.
- * \note Not compiled into display lists.
- * \note Called from the GL API dispatcher.
- */
-void GLAPIENTRY
-_mesa_GetProgramParameterdvNV(GLenum target, GLuint index,
-                              GLenum pname, GLdouble *params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (target == GL_VERTEX_PROGRAM_NV) {
-      if (pname == GL_PROGRAM_PARAMETER_NV) {
-         if (index < MAX_NV_VERTEX_PROGRAM_PARAMS) {
-            COPY_4V(params, ctx->VertexProgram.Parameters[index]);
-         }
-         else {
-            _mesa_error(ctx, GL_INVALID_VALUE,
-                        "glGetProgramParameterdvNV(index)");
-            return;
-         }
-      }
-      else {
-         _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramParameterdvNV(pname)");
-         return;
-      }
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramParameterdvNV(target)");
-      return;
-   }
-}
-
-
-/**
- * Get a program attribute.
- * \note Not compiled into display lists.
- * \note Called from the GL API dispatcher.
- */
-void GLAPIENTRY
-_mesa_GetProgramivNV(GLuint id, GLenum pname, GLint *params)
-{
-   struct gl_program *prog;
-   GET_CURRENT_CONTEXT(ctx);
-
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   prog = _mesa_lookup_program(ctx, id);
-   if (!prog) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramivNV");
-      return;
-   }
-
-   switch (pname) {
-      case GL_PROGRAM_TARGET_NV:
-         *params = prog->Target;
-         return;
-      case GL_PROGRAM_LENGTH_NV:
-         *params = prog->String ?(GLint) strlen((char *) prog->String) : 0;
-         return;
-      case GL_PROGRAM_RESIDENT_NV:
-         *params = prog->Resident;
-         return;
-      default:
-         _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivNV(pname)");
-         return;
-   }
-}
-
-
-/**
- * Get the program source code.
- * \note Not compiled into display lists.
- * \note Called from the GL API dispatcher.
- */
-void GLAPIENTRY
-_mesa_GetProgramStringNV(GLuint id, GLenum pname, GLubyte *program)
-{
-   struct gl_program *prog;
-   GET_CURRENT_CONTEXT(ctx);
-
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (pname != GL_PROGRAM_STRING_NV) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringNV(pname)");
-      return;
-   }
-
-   prog = _mesa_lookup_program(ctx, id);
-   if (!prog) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramStringNV");
-      return;
-   }
-
-   if (prog->String) {
-      memcpy(program, prog->String, strlen((char *) prog->String));
-   }
-   else {
-      program[0] = 0;
-   }
-}
-
-
-/**
- * Get matrix tracking information.
- * \note Not compiled into display lists.
- * \note Called from the GL API dispatcher.
- */
-void GLAPIENTRY
-_mesa_GetTrackMatrixivNV(GLenum target, GLuint address,
-                         GLenum pname, GLint *params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (target == GL_VERTEX_PROGRAM_NV
-       && ctx->Extensions.NV_vertex_program) {
-      GLuint i;
-
-      if ((address & 0x3) || address >= MAX_NV_VERTEX_PROGRAM_PARAMS) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glGetTrackMatrixivNV(address)");
-         return;
-      }
-
-      i = address / 4;
-
-      switch (pname) {
-         case GL_TRACK_MATRIX_NV:
-            params[0] = (GLint) ctx->VertexProgram.TrackMatrix[i];
-            return;
-         case GL_TRACK_MATRIX_TRANSFORM_NV:
-            params[0] = (GLint) ctx->VertexProgram.TrackMatrixTransform[i];
-            return;
-         default:
-            _mesa_error(ctx, GL_INVALID_ENUM, "glGetTrackMatrixivNV");
-            return;
-      }
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTrackMatrixivNV");
-      return;
-   }
-}
-
-
-/**
- * Get a vertex (or vertex array) attribute.
- * \note Not compiled into display lists.
- * \note Called from the GL API dispatcher.
- */
-void GLAPIENTRY
-_mesa_GetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params)
-{
-   const struct gl_client_array *array;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)");
-      return;
-   }
-
-   array = &ctx->Array.ArrayObj->VertexAttrib[index];
-
-   switch (pname) {
-      case GL_ATTRIB_ARRAY_SIZE_NV:
-         params[0] = array->Size;
-         break;
-      case GL_ATTRIB_ARRAY_STRIDE_NV:
-         params[0] = array->Stride;
-         break;
-      case GL_ATTRIB_ARRAY_TYPE_NV:
-         params[0] = array->Type;
-         break;
-      case GL_CURRENT_ATTRIB_NV:
-         if (index == 0) {
-            _mesa_error(ctx, GL_INVALID_OPERATION,
-                        "glGetVertexAttribdvNV(index == 0)");
-            return;
-         }
-        FLUSH_CURRENT(ctx, 0);
-         COPY_4V(params, ctx->Current.Attrib[index]);
-         break;
-      default:
-         _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribdvNV");
-         return;
-   }
-}
-
-/**
- * Get a vertex (or vertex array) attribute.
- * \note Not compiled into display lists.
- * \note Called from the GL API dispatcher.
- */
-void GLAPIENTRY
-_mesa_GetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params)
-{
-   const struct gl_client_array *array;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)");
-      return;
-   }
-
-   array = &ctx->Array.ArrayObj->VertexAttrib[index];
-
-   switch (pname) {
-      case GL_ATTRIB_ARRAY_SIZE_NV:
-         params[0] = (GLfloat) array->Size;
-         break;
-      case GL_ATTRIB_ARRAY_STRIDE_NV:
-         params[0] = (GLfloat) array->Stride;
-         break;
-      case GL_ATTRIB_ARRAY_TYPE_NV:
-         params[0] = (GLfloat) array->Type;
-         break;
-      case GL_CURRENT_ATTRIB_NV:
-         if (index == 0) {
-            _mesa_error(ctx, GL_INVALID_OPERATION,
-                        "glGetVertexAttribfvNV(index == 0)");
-            return;
-         }
-        FLUSH_CURRENT(ctx, 0);
-         COPY_4V(params, ctx->Current.Attrib[index]);
-         break;
-      default:
-         _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribdvNV");
-         return;
-   }
-}
-
-/**
- * Get a vertex (or vertex array) attribute.
- * \note Not compiled into display lists.
- * \note Called from the GL API dispatcher.
- */
-void GLAPIENTRY
-_mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params)
-{
-   const struct gl_client_array *array;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)");
-      return;
-   }
-
-   array = &ctx->Array.ArrayObj->VertexAttrib[index];
-
-   switch (pname) {
-      case GL_ATTRIB_ARRAY_SIZE_NV:
-         params[0] = array->Size;
-         break;
-      case GL_ATTRIB_ARRAY_STRIDE_NV:
-         params[0] = array->Stride;
-         break;
-      case GL_ATTRIB_ARRAY_TYPE_NV:
-         params[0] = array->Type;
-         break;
-      case GL_CURRENT_ATTRIB_NV:
-         if (index == 0) {
-            _mesa_error(ctx, GL_INVALID_OPERATION,
-                        "glGetVertexAttribivNV(index == 0)");
-            return;
-         }
-        FLUSH_CURRENT(ctx, 0);
-         params[0] = (GLint) ctx->Current.Attrib[index][0];
-         params[1] = (GLint) ctx->Current.Attrib[index][1];
-         params[2] = (GLint) ctx->Current.Attrib[index][2];
-         params[3] = (GLint) ctx->Current.Attrib[index][3];
-         break;
-      case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
-         params[0] = array->BufferObj->Name;
-         break;
-      default:
-         _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribdvNV");
-         return;
-   }
-}
-
-
-/**
- * Get a vertex array attribute pointer.
- * \note Not compiled into display lists.
- * \note Called from the GL API dispatcher.
- */
-void GLAPIENTRY
-_mesa_GetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid **pointer)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerNV(index)");
-      return;
-   }
-
-   if (pname != GL_ATTRIB_ARRAY_POINTER_NV) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerNV(pname)");
-      return;
-   }
-
-   *pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[index].Ptr;
-}
-
-void
-_mesa_emit_nv_temp_initialization(GLcontext *ctx,
-                                 struct gl_program *program)
-{
-   struct prog_instruction *inst;
-   GLuint i;
-
-   if (!ctx->Shader.EmitNVTempInitialization)
-      return;
-
-   /* We'll swizzle up a zero temporary so we can use it for the
-    * ARL.
-    */
-   if (program->NumTemporaries == 0)
-      program->NumTemporaries = 1;
-
-   _mesa_insert_instructions(program, 0, program->NumTemporaries + 1);
-
-   for (i = 0; i < program->NumTemporaries; i++) {
-      struct prog_instruction *inst = &program->Instructions[i];
-
-      inst->Opcode = OPCODE_SWZ;
-      inst->DstReg.File = PROGRAM_TEMPORARY;
-      inst->DstReg.Index = i;
-      inst->DstReg.WriteMask = WRITEMASK_XYZW;
-      inst->SrcReg[0].File = PROGRAM_TEMPORARY;
-      inst->SrcReg[0].Index = 0;
-      inst->SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_ZERO,
-                                             SWIZZLE_ZERO,
-                                             SWIZZLE_ZERO,
-                                             SWIZZLE_ZERO);
-   }
-
-   inst = &program->Instructions[i];
-   inst->Opcode = OPCODE_ARL;
-   inst->DstReg.File = PROGRAM_ADDRESS;
-   inst->DstReg.Index = 0;
-   inst->DstReg.WriteMask = WRITEMASK_XYZW;
-   inst->SrcReg[0].File = PROGRAM_TEMPORARY;
-   inst->SrcReg[0].Index = 0;
-   inst->SrcReg[0].Swizzle = SWIZZLE_XXXX;
-
-   if (program->NumAddressRegs == 0)
-      program->NumAddressRegs = 1;
-}
-
-void
-_mesa_setup_nv_temporary_count(GLcontext *ctx, struct gl_program *program)
-{
-   GLuint i;
-
-   program->NumTemporaries = 0;
-   for (i = 0; i < program->NumInstructions; i++) {
-      struct prog_instruction *inst = &program->Instructions[i];
-
-      if (inst->DstReg.File == PROGRAM_TEMPORARY) {
-        program->NumTemporaries = MAX2(program->NumTemporaries,
-                                       inst->DstReg.Index + 1);
-      }
-      if (inst->SrcReg[0].File == PROGRAM_TEMPORARY) {
-        program->NumTemporaries = MAX2((GLint)program->NumTemporaries,
-                                       inst->SrcReg[0].Index + 1);
-      }
-      if (inst->SrcReg[1].File == PROGRAM_TEMPORARY) {
-        program->NumTemporaries = MAX2((GLint)program->NumTemporaries,
-                                       inst->SrcReg[1].Index + 1);
-      }
-      if (inst->SrcReg[2].File == PROGRAM_TEMPORARY) {
-        program->NumTemporaries = MAX2((GLint)program->NumTemporaries,
-                                       inst->SrcReg[2].Index + 1);
-      }
-   }
-}
-
-/**
- * Load/parse/compile a program.
- * \note Called from the GL API dispatcher.
- */
-void GLAPIENTRY
-_mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len,
-                    const GLubyte *program)
-{
-   struct gl_program *prog;
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (!ctx->Extensions.NV_vertex_program
-       && !ctx->Extensions.NV_fragment_program) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV()");
-      return;
-   }
-
-   if (id == 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glLoadProgramNV(id)");
-      return;
-   }
-
-   if (len < 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glLoadProgramNV(len)");
-      return;
-   }
-
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
-
-   prog = _mesa_lookup_program(ctx, id);
-
-   if (prog && prog->Target != 0 && prog->Target != target) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(target)");
-      return;
-   }
-
-   if ((target == GL_VERTEX_PROGRAM_NV ||
-        target == GL_VERTEX_STATE_PROGRAM_NV)
-       && ctx->Extensions.NV_vertex_program) {
-      struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog;
-      if (!vprog || prog == &_mesa_DummyProgram) {
-         vprog = (struct gl_vertex_program *)
-            ctx->Driver.NewProgram(ctx, target, id);
-         if (!vprog) {
-            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
-            return;
-         }
-         _mesa_HashInsert(ctx->Shared->Programs, id, vprog);
-      }
-
-      if (ctx->Extensions.ARB_vertex_program
-         && (strncmp((char *) program, "!!ARB", 5) == 0)) {
-        _mesa_parse_arb_vertex_program(ctx, target, program, len, vprog);
-      } else {
-        _mesa_parse_nv_vertex_program(ctx, target, program, len, vprog);
-      }
-   }
-   else if (target == GL_FRAGMENT_PROGRAM_NV
-            && ctx->Extensions.NV_fragment_program) {
-      struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog;
-      if (!fprog || prog == &_mesa_DummyProgram) {
-         fprog = (struct gl_fragment_program *)
-            ctx->Driver.NewProgram(ctx, target, id);
-         if (!fprog) {
-            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
-            return;
-         }
-         _mesa_HashInsert(ctx->Shared->Programs, id, fprog);
-      }
-      _mesa_parse_nv_fragment_program(ctx, target, program, len, fprog);
-   }
-   else if (target == GL_FRAGMENT_PROGRAM_ARB
-            && ctx->Extensions.ARB_fragment_program) {
-      struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog;
-      if (!fprog || prog == &_mesa_DummyProgram) {
-         fprog = (struct gl_fragment_program *)
-            ctx->Driver.NewProgram(ctx, target, id);
-         if (!fprog) {
-            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
-            return;
-         }
-         _mesa_HashInsert(ctx->Shared->Programs, id, fprog);
-      }
-      _mesa_parse_arb_fragment_program(ctx, target, program, len, fprog);
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glLoadProgramNV(target)");
-   }
-}
-
-
-
-/**
- * Set a sequence of program parameter registers.
- * \note Called from the GL API dispatcher.
- */
-void GLAPIENTRY
-_mesa_ProgramParameters4dvNV(GLenum target, GLuint index,
-                             GLuint num, const GLdouble *params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) {
-      GLuint i;
-      if (index + num > MAX_NV_VERTEX_PROGRAM_PARAMS) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramParameters4dvNV");
-         return;
-      }
-      for (i = 0; i < num; i++) {
-         ctx->VertexProgram.Parameters[index + i][0] = (GLfloat) params[0];
-         ctx->VertexProgram.Parameters[index + i][1] = (GLfloat) params[1];
-         ctx->VertexProgram.Parameters[index + i][2] = (GLfloat) params[2];
-         ctx->VertexProgram.Parameters[index + i][3] = (GLfloat) params[3];
-         params += 4;
-      };
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameters4dvNV");
-      return;
-   }
-}
-
-
-/**
- * Set a sequence of program parameter registers.
- * \note Called from the GL API dispatcher.
- */
-void GLAPIENTRY
-_mesa_ProgramParameters4fvNV(GLenum target, GLuint index,
-                             GLuint num, const GLfloat *params)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) {
-      GLuint i;
-      if (index + num > MAX_NV_VERTEX_PROGRAM_PARAMS) {
-         _mesa_error(ctx, GL_INVALID_VALUE, "glProgramParameters4fvNV");
-         return;
-      }
-      for (i = 0; i < num; i++) {
-         COPY_4V(ctx->VertexProgram.Parameters[index + i], params);
-         params += 4;
-      }
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameters4fvNV");
-      return;
-   }
-}
-
-
-
-/**
- * Setup tracking of matrices into program parameter registers.
- * \note Called from the GL API dispatcher.
- */
-void GLAPIENTRY
-_mesa_TrackMatrixNV(GLenum target, GLuint address,
-                    GLenum matrix, GLenum transform)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
-
-   if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) {
-      if (address & 0x3) {
-         /* addr must be multiple of four */
-         _mesa_error(ctx, GL_INVALID_VALUE, "glTrackMatrixNV(address)");
-         return;
-      }
-
-      switch (matrix) {
-         case GL_NONE:
-         case GL_MODELVIEW:
-         case GL_PROJECTION:
-         case GL_TEXTURE:
-         case GL_COLOR:
-         case GL_MODELVIEW_PROJECTION_NV:
-         case GL_MATRIX0_NV:
-         case GL_MATRIX1_NV:
-         case GL_MATRIX2_NV:
-         case GL_MATRIX3_NV:
-         case GL_MATRIX4_NV:
-         case GL_MATRIX5_NV:
-         case GL_MATRIX6_NV:
-         case GL_MATRIX7_NV:
-            /* OK, fallthrough */
-            break;
-         default:
-            _mesa_error(ctx, GL_INVALID_ENUM, "glTrackMatrixNV(matrix)");
-            return;
-      }
-
-      switch (transform) {
-         case GL_IDENTITY_NV:
-         case GL_INVERSE_NV:
-         case GL_TRANSPOSE_NV:
-         case GL_INVERSE_TRANSPOSE_NV:
-            /* OK, fallthrough */
-            break;
-         default:
-            _mesa_error(ctx, GL_INVALID_ENUM, "glTrackMatrixNV(transform)");
-            return;
-      }
-
-      ctx->VertexProgram.TrackMatrix[address / 4] = matrix;
-      ctx->VertexProgram.TrackMatrixTransform[address / 4] = transform;
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glTrackMatrixNV(target)");
-      return;
-   }
-}
-
-
-void GLAPIENTRY
-_mesa_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name,
-                                GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
-   struct gl_program *prog;
-   struct gl_fragment_program *fragProg;
-   GLfloat *v;
-
-   GET_CURRENT_CONTEXT(ctx);
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
-
-   prog = _mesa_lookup_program(ctx, id);
-   if (!prog || prog->Target != GL_FRAGMENT_PROGRAM_NV) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramNamedParameterNV");
-      return;
-   }
-
-   if (len <= 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glProgramNamedParameterNV(len)");
-      return;
-   }
-
-   fragProg = (struct gl_fragment_program *) prog;
-   v = _mesa_lookup_parameter_value(fragProg->Base.Parameters, len,
-                                    (char *) name);
-   if (v) {
-      v[0] = x;
-      v[1] = y;
-      v[2] = z;
-      v[3] = w;
-      return;
-   }
-
-   _mesa_error(ctx, GL_INVALID_VALUE, "glProgramNamedParameterNV(name)");
-}
-
-
-void GLAPIENTRY
-_mesa_ProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte *name,
-                                 const float v[])
-{
-   _mesa_ProgramNamedParameter4fNV(id, len, name, v[0], v[1], v[2], v[3]);
-}
-
-
-void GLAPIENTRY
-_mesa_ProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte *name,
-                                GLdouble x, GLdouble y, GLdouble z, GLdouble w)
-{
-   _mesa_ProgramNamedParameter4fNV(id, len, name, (GLfloat)x, (GLfloat)y, 
-                                   (GLfloat)z, (GLfloat)w);
-}
-
-
-void GLAPIENTRY
-_mesa_ProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte *name,
-                                 const double v[])
-{
-   _mesa_ProgramNamedParameter4fNV(id, len, name,
-                                   (GLfloat)v[0], (GLfloat)v[1],
-                                   (GLfloat)v[2], (GLfloat)v[3]);
-}
-
-
-void GLAPIENTRY
-_mesa_GetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name,
-                                   GLfloat *params)
-{
-   struct gl_program *prog;
-   struct gl_fragment_program *fragProg;
-   const GLfloat *v;
-
-   GET_CURRENT_CONTEXT(ctx);
-
-   ASSERT_OUTSIDE_BEGIN_END(ctx);
-
-   prog = _mesa_lookup_program(ctx, id);
-   if (!prog || prog->Target != GL_FRAGMENT_PROGRAM_NV) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramNamedParameterNV");
-      return;
-   }
-
-   if (len <= 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramNamedParameterNV");
-      return;
-   }
-
-   fragProg = (struct gl_fragment_program *) prog;
-   v = _mesa_lookup_parameter_value(fragProg->Base.Parameters,
-                                    len, (char *) name);
-   if (v) {
-      params[0] = v[0];
-      params[1] = v[1];
-      params[2] = v[2];
-      params[3] = v[3];
-      return;
-   }
-
-   _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramNamedParameterNV");
-}
-
-
-void GLAPIENTRY
-_mesa_GetProgramNamedParameterdvNV(GLuint id, GLsizei len, const GLubyte *name,
-                                   GLdouble *params)
-{
-   GLfloat floatParams[4];
-   _mesa_GetProgramNamedParameterfvNV(id, len, name, floatParams);
-   COPY_4V(params, floatParams);
-}
diff --git a/src/mesa/shader/nvprogram.h b/src/mesa/shader/nvprogram.h
deleted file mode 100644 (file)
index 8ee5966..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  5.1
- *
- * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Brian Paul
- */
-
-
-#ifndef NVPROGRAM_H
-#define NVPROGRAM_H
-
-
-extern void GLAPIENTRY
-_mesa_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params);
-
-extern GLboolean GLAPIENTRY 
-_mesa_AreProgramsResidentNV(GLsizei n, const GLuint *ids, GLboolean *residences);
-
-extern void GLAPIENTRY
-_mesa_RequestResidentProgramsNV(GLsizei n, const GLuint *ids);
-
-extern void GLAPIENTRY
-_mesa_GetProgramParameterfvNV(GLenum target, GLuint index, GLenum pname, GLfloat *params);
-
-extern void GLAPIENTRY
-_mesa_GetProgramParameterdvNV(GLenum target, GLuint index, GLenum pname, GLdouble *params);
-
-extern void GLAPIENTRY
-_mesa_GetProgramivNV(GLuint id, GLenum pname, GLint *params);
-
-extern void GLAPIENTRY
-_mesa_GetProgramStringNV(GLuint id, GLenum pname, GLubyte *program);
-
-extern void GLAPIENTRY
-_mesa_GetTrackMatrixivNV(GLenum target, GLuint address, GLenum pname, GLint *params);
-
-extern void GLAPIENTRY
-_mesa_GetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params);
-
-extern void GLAPIENTRY
-_mesa_GetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params);
-
-extern void GLAPIENTRY
-_mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params);
-
-extern void GLAPIENTRY
-_mesa_GetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid **pointer);
-
-extern void GLAPIENTRY
-_mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len, const GLubyte *program);
-
-extern void GLAPIENTRY
-_mesa_ProgramParameters4dvNV(GLenum target, GLuint index, GLuint num, const GLdouble *params);
-
-extern void GLAPIENTRY
-_mesa_ProgramParameters4fvNV(GLenum target, GLuint index, GLuint num, const GLfloat *params);
-
-extern void GLAPIENTRY
-_mesa_TrackMatrixNV(GLenum target, GLuint address, GLenum matrix, GLenum transform);
-
-
-extern void GLAPIENTRY
-_mesa_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name,
-                                GLfloat x, GLfloat y, GLfloat z, GLfloat w);
-
-extern void GLAPIENTRY
-_mesa_ProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte *name,
-                                 const float v[]);
-
-extern void GLAPIENTRY
-_mesa_ProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte *name,
-                                GLdouble x, GLdouble y, GLdouble z, GLdouble w);
-
-extern void GLAPIENTRY
-_mesa_ProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte *name,
-                                 const double v[]);
-
-extern void GLAPIENTRY
-_mesa_GetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name,
-                                   GLfloat *params);
-
-extern void GLAPIENTRY
-_mesa_GetProgramNamedParameterdvNV(GLuint id, GLsizei len, const GLubyte *name,
-                                   GLdouble *params);
-
-extern void
-_mesa_setup_nv_temporary_count(GLcontext *ctx, struct gl_program *program);
-
-extern void
-_mesa_emit_nv_temp_initialization(GLcontext *ctx,
-                                 struct gl_program *program);
-
-#endif
diff --git a/src/mesa/shader/nvvertparse.c b/src/mesa/shader/nvvertparse.c
deleted file mode 100644 (file)
index 7332fc4..0000000
+++ /dev/null
@@ -1,1454 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.2
- *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file nvvertparse.c
- * NVIDIA vertex program parser.
- * \author Brian Paul
- */
-
-/*
- * Regarding GL_NV_vertex_program, GL_NV_vertex_program1_1:
- *
- * Portions of this software may use or implement intellectual
- * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims
- * any and all warranties with respect to such intellectual property,
- * including any use thereof or modifications thereto.
- */
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/imports.h"
-#include "nvprogram.h"
-#include "nvvertparse.h"
-#include "prog_instruction.h"
-#include "prog_parameter.h"
-#include "prog_print.h"
-#include "program.h"
-
-
-/**
- * Current parsing state.  This structure is passed among the parsing
- * functions and keeps track of the current parser position and various
- * program attributes.
- */
-struct parse_state {
-   GLcontext *ctx;
-   const GLubyte *start;
-   const GLubyte *pos;
-   const GLubyte *curLine;
-   GLboolean isStateProgram;
-   GLboolean isPositionInvariant;
-   GLboolean isVersion1_1;
-   GLbitfield inputsRead;
-   GLbitfield outputsWritten;
-   GLboolean anyProgRegsWritten;
-   GLuint numInst;                 /* number of instructions parsed */
-};
-
-
-/*
- * Called whenever we find an error during parsing.
- */
-static void
-record_error(struct parse_state *parseState, const char *msg, int lineNo)
-{
-#ifdef DEBUG
-   GLint line, column;
-   const GLubyte *lineStr;
-   lineStr = _mesa_find_line_column(parseState->start,
-                                    parseState->pos, &line, &column);
-   _mesa_debug(parseState->ctx,
-               "nvfragparse.c(%d): line %d, column %d:%s (%s)\n",
-               lineNo, line, column, (char *) lineStr, msg);
-   free((void *) lineStr);
-#else
-   (void) lineNo;
-#endif
-
-   /* Check that no error was already recorded.  Only record the first one. */
-   if (parseState->ctx->Program.ErrorString[0] == 0) {
-      _mesa_set_program_error(parseState->ctx,
-                              parseState->pos - parseState->start,
-                              msg);
-   }
-}
-
-
-#define RETURN_ERROR                                                   \
-do {                                                                   \
-   record_error(parseState, "Unexpected end of input.", __LINE__);     \
-   return GL_FALSE;                                                    \
-} while(0)
-
-#define RETURN_ERROR1(msg)                                             \
-do {                                                                   \
-   record_error(parseState, msg, __LINE__);                            \
-   return GL_FALSE;                                                    \
-} while(0)
-
-#define RETURN_ERROR2(msg1, msg2)                                      \
-do {                                                                   \
-   char err[1000];                                                     \
-   sprintf(err, "%s %s", msg1, msg2);                          \
-   record_error(parseState, err, __LINE__);                            \
-   return GL_FALSE;                                                    \
-} while(0)
-
-
-
-
-
-static GLboolean IsLetter(GLubyte b)
-{
-   return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z');
-}
-
-
-static GLboolean IsDigit(GLubyte b)
-{
-   return b >= '0' && b <= '9';
-}
-
-
-static GLboolean IsWhitespace(GLubyte b)
-{
-   return b == ' ' || b == '\t' || b == '\n' || b == '\r';
-}
-
-
-/**
- * Starting at 'str' find the next token.  A token can be an integer,
- * an identifier or punctuation symbol.
- * \return <= 0 we found an error, else, return number of characters parsed.
- */
-static GLint
-GetToken(struct parse_state *parseState, GLubyte *token)
-{
-   const GLubyte *str = parseState->pos;
-   GLint i = 0, j = 0;
-
-   token[0] = 0;
-
-   /* skip whitespace and comments */
-   while (str[i] && (IsWhitespace(str[i]) || str[i] == '#')) {
-      if (str[i] == '#') {
-         /* skip comment */
-         while (str[i] && (str[i] != '\n' && str[i] != '\r')) {
-            i++;
-         }
-         if (str[i] == '\n' || str[i] == '\r')
-            parseState->curLine = str + i + 1;
-      }
-      else {
-         /* skip whitespace */
-         if (str[i] == '\n' || str[i] == '\r')
-            parseState->curLine = str + i + 1;
-         i++;
-      }
-   }
-
-   if (str[i] == 0)
-      return -i;
-
-   /* try matching an integer */
-   while (str[i] && IsDigit(str[i])) {
-      token[j++] = str[i++];
-   }
-   if (j > 0 || !str[i]) {
-      token[j] = 0;
-      return i;
-   }
-
-   /* try matching an identifier */
-   if (IsLetter(str[i])) {
-      while (str[i] && (IsLetter(str[i]) || IsDigit(str[i]))) {
-         token[j++] = str[i++];
-      }
-      token[j] = 0;
-      return i;
-   }
-
-   /* punctuation character */
-   if (str[i]) {
-      token[0] = str[i++];
-      token[1] = 0;
-      return i;
-   }
-
-   /* end of input */
-   token[0] = 0;
-   return i;
-}
-
-
-/**
- * Get next token from input stream and increment stream pointer past token.
- */
-static GLboolean
-Parse_Token(struct parse_state *parseState, GLubyte *token)
-{
-   GLint i;
-   i = GetToken(parseState, token);
-   if (i <= 0) {
-      parseState->pos += (-i);
-      return GL_FALSE;
-   }
-   parseState->pos += i;
-   return GL_TRUE;
-}
-
-
-/**
- * Get next token from input stream but don't increment stream pointer.
- */
-static GLboolean
-Peek_Token(struct parse_state *parseState, GLubyte *token)
-{
-   GLint i, len;
-   i = GetToken(parseState, token);
-   if (i <= 0) {
-      parseState->pos += (-i);
-      return GL_FALSE;
-   }
-   len = (GLint) strlen((const char *) token);
-   parseState->pos += (i - len);
-   return GL_TRUE;
-}
-
-
-/**
- * Try to match 'pattern' as the next token after any whitespace/comments.
- * Advance the current parsing position only if we match the pattern.
- * \return GL_TRUE if pattern is matched, GL_FALSE otherwise.
- */
-static GLboolean
-Parse_String(struct parse_state *parseState, const char *pattern)
-{
-   const GLubyte *m;
-   GLint i;
-
-   /* skip whitespace and comments */
-   while (IsWhitespace(*parseState->pos) || *parseState->pos == '#') {
-      if (*parseState->pos == '#') {
-         while (*parseState->pos && (*parseState->pos != '\n' && *parseState->pos != '\r')) {
-            parseState->pos += 1;
-         }
-         if (*parseState->pos == '\n' || *parseState->pos == '\r')
-            parseState->curLine = parseState->pos + 1;
-      }
-      else {
-         /* skip whitespace */
-         if (*parseState->pos == '\n' || *parseState->pos == '\r')
-            parseState->curLine = parseState->pos + 1;
-         parseState->pos += 1;
-      }
-   }
-
-   /* Try to match the pattern */
-   m = parseState->pos;
-   for (i = 0; pattern[i]; i++) {
-      if (*m != (GLubyte) pattern[i])
-         return GL_FALSE;
-      m += 1;
-   }
-   parseState->pos = m;
-
-   return GL_TRUE; /* success */
-}
-
-
-/**********************************************************************/
-
-static const char *InputRegisters[MAX_NV_VERTEX_PROGRAM_INPUTS + 1] = {
-   "OPOS", "WGHT", "NRML", "COL0", "COL1", "FOGC", "6", "7",
-   "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL
-};
-
-static const char *OutputRegisters[MAX_NV_VERTEX_PROGRAM_OUTPUTS + 1] = {
-   "HPOS", "COL0", "COL1", "FOGC", 
-   "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", 
-   "PSIZ", "BFC0", "BFC1", NULL
-};
-
-
-
-/**
- * Parse a temporary register: Rnn
- */
-static GLboolean
-Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum)
-{
-   GLubyte token[100];
-
-   /* Should be 'R##' */
-   if (!Parse_Token(parseState, token))
-      RETURN_ERROR;
-   if (token[0] != 'R')
-      RETURN_ERROR1("Expected R##");
-
-   if (IsDigit(token[1])) {
-      GLint reg = atoi((char *) (token + 1));
-      if (reg >= MAX_NV_VERTEX_PROGRAM_TEMPS)
-         RETURN_ERROR1("Bad temporary register name");
-      *tempRegNum = reg;
-   }
-   else {
-      RETURN_ERROR1("Bad temporary register name");
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Parse address register "A0.x"
- */
-static GLboolean
-Parse_AddrReg(struct parse_state *parseState)
-{
-   /* match 'A0' */
-   if (!Parse_String(parseState, "A0"))
-      RETURN_ERROR;
-
-   /* match '.' */
-   if (!Parse_String(parseState, "."))
-      RETURN_ERROR;
-
-   /* match 'x' */
-   if (!Parse_String(parseState, "x"))
-      RETURN_ERROR;
-
-   return GL_TRUE;
-}
-
-
-/**
- * Parse absolute program parameter register "c[##]"
- */
-static GLboolean
-Parse_AbsParamReg(struct parse_state *parseState, GLint *regNum)
-{
-   GLubyte token[100];
-
-   if (!Parse_String(parseState, "c"))
-      RETURN_ERROR;
-
-   if (!Parse_String(parseState, "["))
-      RETURN_ERROR;
-
-   if (!Parse_Token(parseState, token))
-      RETURN_ERROR;
-
-   if (IsDigit(token[0])) {
-      /* a numbered program parameter register */
-      GLint reg = atoi((char *) token);
-      if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS)
-         RETURN_ERROR1("Bad program parameter number");
-      *regNum = reg;
-   }
-   else {
-      RETURN_ERROR;
-   }
-
-   if (!Parse_String(parseState, "]"))
-      RETURN_ERROR;
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_ParamReg(struct parse_state *parseState, struct prog_src_register *srcReg)
-{
-   GLubyte token[100];
-
-   if (!Parse_String(parseState, "c"))
-      RETURN_ERROR;
-
-   if (!Parse_String(parseState, "["))
-      RETURN_ERROR;
-
-   if (!Peek_Token(parseState, token))
-      RETURN_ERROR;
-
-   if (IsDigit(token[0])) {
-      /* a numbered program parameter register */
-      GLint reg;
-      (void) Parse_Token(parseState, token);
-      reg = atoi((char *) token);
-      if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS)
-         RETURN_ERROR1("Bad program parameter number");
-      srcReg->File = PROGRAM_ENV_PARAM;
-      srcReg->Index = reg;
-   }
-   else if (strcmp((const char *) token, "A0") == 0) {
-      /* address register "A0.x" */
-      if (!Parse_AddrReg(parseState))
-         RETURN_ERROR;
-
-      srcReg->RelAddr = GL_TRUE;
-      srcReg->File = PROGRAM_ENV_PARAM;
-      /* Look for +/-N offset */
-      if (!Peek_Token(parseState, token))
-         RETURN_ERROR;
-
-      if (token[0] == '-' || token[0] == '+') {
-         const GLubyte sign = token[0];
-         (void) Parse_Token(parseState, token); /* consume +/- */
-
-         /* an integer should be next */
-         if (!Parse_Token(parseState, token))
-            RETURN_ERROR;
-
-         if (IsDigit(token[0])) {
-            const GLint k = atoi((char *) token);
-            if (sign == '-') {
-               if (k > 64)
-                  RETURN_ERROR1("Bad address offset");
-               srcReg->Index = -k;
-            }
-            else {
-               if (k > 63)
-                  RETURN_ERROR1("Bad address offset");
-               srcReg->Index = k;
-            }
-         }
-         else {
-            RETURN_ERROR;
-         }
-      }
-      else {
-         /* probably got a ']', catch it below */
-      }
-   }
-   else {
-      RETURN_ERROR;
-   }
-
-   /* Match closing ']' */
-   if (!Parse_String(parseState, "]"))
-      RETURN_ERROR;
-
-   return GL_TRUE;
-}
-
-
-/**
- * Parse v[#] or v[<name>]
- */
-static GLboolean
-Parse_AttribReg(struct parse_state *parseState, GLint *tempRegNum)
-{
-   GLubyte token[100];
-   GLint j;
-
-   /* Match 'v' */
-   if (!Parse_String(parseState, "v"))
-      RETURN_ERROR;
-
-   /* Match '[' */
-   if (!Parse_String(parseState, "["))
-      RETURN_ERROR;
-
-   /* match number or named register */
-   if (!Parse_Token(parseState, token))
-      RETURN_ERROR;
-
-   if (parseState->isStateProgram && token[0] != '0')
-      RETURN_ERROR1("Only v[0] accessible in vertex state programs");
-
-   if (IsDigit(token[0])) {
-      GLint reg = atoi((char *) token);
-      if (reg >= MAX_NV_VERTEX_PROGRAM_INPUTS)
-         RETURN_ERROR1("Bad vertex attribute register name");
-      *tempRegNum = reg;
-   }
-   else {
-      for (j = 0; InputRegisters[j]; j++) {
-         if (strcmp((const char *) token, InputRegisters[j]) == 0) {
-            *tempRegNum = j;
-            break;
-         }
-      }
-      if (!InputRegisters[j]) {
-         /* unknown input register label */
-         RETURN_ERROR2("Bad register name", token);
-      }
-   }
-
-   /* Match '[' */
-   if (!Parse_String(parseState, "]"))
-      RETURN_ERROR;
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum)
-{
-   GLubyte token[100];
-   GLint start, j;
-
-   /* Match 'o' */
-   if (!Parse_String(parseState, "o"))
-      RETURN_ERROR;
-
-   /* Match '[' */
-   if (!Parse_String(parseState, "["))
-      RETURN_ERROR;
-
-   /* Get output reg name */
-   if (!Parse_Token(parseState, token))
-      RETURN_ERROR;
-
-   if (parseState->isPositionInvariant)
-      start = 1; /* skip HPOS register name */
-   else
-      start = 0;
-
-   /* try to match an output register name */
-   for (j = start; OutputRegisters[j]; j++) {
-      if (strcmp((const char *) token, OutputRegisters[j]) == 0) {
-         *outputRegNum = j;
-         break;
-      }
-   }
-   if (!OutputRegisters[j])
-      RETURN_ERROR1("Unrecognized output register name");
-
-   /* Match ']' */
-   if (!Parse_String(parseState, "]"))
-      RETURN_ERROR1("Expected ]");
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_MaskedDstReg(struct parse_state *parseState, struct prog_dst_register *dstReg)
-{
-   GLubyte token[100];
-   GLint idx;
-
-   /* Dst reg can be R<n> or o[n] */
-   if (!Peek_Token(parseState, token))
-      RETURN_ERROR;
-
-   if (token[0] == 'R') {
-      /* a temporary register */
-      dstReg->File = PROGRAM_TEMPORARY;
-      if (!Parse_TempReg(parseState, &idx))
-         RETURN_ERROR;
-      dstReg->Index = idx;
-   }
-   else if (!parseState->isStateProgram && token[0] == 'o') {
-      /* an output register */
-      dstReg->File = PROGRAM_OUTPUT;
-      if (!Parse_OutputReg(parseState, &idx))
-         RETURN_ERROR;
-      dstReg->Index = idx;
-   }
-   else if (parseState->isStateProgram && token[0] == 'c' &&
-            parseState->isStateProgram) {
-      /* absolute program parameter register */
-      /* Only valid for vertex state programs */
-      dstReg->File = PROGRAM_ENV_PARAM;
-      if (!Parse_AbsParamReg(parseState, &idx))
-         RETURN_ERROR;
-      dstReg->Index = idx;
-   }
-   else {
-      RETURN_ERROR1("Bad destination register name");
-   }
-
-   /* Parse optional write mask */
-   if (!Peek_Token(parseState, token))
-      RETURN_ERROR;
-
-   if (token[0] == '.') {
-      /* got a mask */
-      GLint k = 0;
-
-      if (!Parse_String(parseState, "."))
-         RETURN_ERROR;
-
-      if (!Parse_Token(parseState, token))
-         RETURN_ERROR;
-
-      dstReg->WriteMask = 0;
-
-      if (token[k] == 'x') {
-         dstReg->WriteMask |= WRITEMASK_X;
-         k++;
-      }
-      if (token[k] == 'y') {
-         dstReg->WriteMask |= WRITEMASK_Y;
-         k++;
-      }
-      if (token[k] == 'z') {
-         dstReg->WriteMask |= WRITEMASK_Z;
-         k++;
-      }
-      if (token[k] == 'w') {
-         dstReg->WriteMask |= WRITEMASK_W;
-         k++;
-      }
-      if (k == 0) {
-         RETURN_ERROR1("Bad writemask character");
-      }
-      return GL_TRUE;
-   }
-   else {
-      dstReg->WriteMask = WRITEMASK_XYZW;
-      return GL_TRUE;
-   }
-}
-
-
-static GLboolean
-Parse_SwizzleSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg)
-{
-   GLubyte token[100];
-   GLint idx;
-
-   srcReg->RelAddr = GL_FALSE;
-
-   /* check for '-' */
-   if (!Peek_Token(parseState, token))
-      RETURN_ERROR;
-   if (token[0] == '-') {
-      (void) Parse_String(parseState, "-");
-      srcReg->Negate = NEGATE_XYZW;
-      if (!Peek_Token(parseState, token))
-         RETURN_ERROR;
-   }
-   else {
-      srcReg->Negate = NEGATE_NONE;
-   }
-
-   /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
-   if (token[0] == 'R') {
-      srcReg->File = PROGRAM_TEMPORARY;
-      if (!Parse_TempReg(parseState, &idx))
-         RETURN_ERROR;
-      srcReg->Index = idx;
-   }
-   else if (token[0] == 'c') {
-      if (!Parse_ParamReg(parseState, srcReg))
-         RETURN_ERROR;
-   }
-   else if (token[0] == 'v') {
-      srcReg->File = PROGRAM_INPUT;
-      if (!Parse_AttribReg(parseState, &idx))
-         RETURN_ERROR;
-      srcReg->Index = idx;
-   }
-   else {
-      RETURN_ERROR2("Bad source register name", token);
-   }
-
-   /* init swizzle fields */
-   srcReg->Swizzle = SWIZZLE_NOOP;
-
-   /* Look for optional swizzle suffix */
-   if (!Peek_Token(parseState, token))
-      RETURN_ERROR;
-   if (token[0] == '.') {
-      (void) Parse_String(parseState, ".");  /* consume . */
-
-      if (!Parse_Token(parseState, token))
-         RETURN_ERROR;
-
-      if (token[1] == 0) {
-         /* single letter swizzle */
-         if (token[0] == 'x')
-            srcReg->Swizzle = SWIZZLE_XXXX;
-         else if (token[0] == 'y')
-            srcReg->Swizzle = SWIZZLE_YYYY;
-         else if (token[0] == 'z')
-            srcReg->Swizzle = SWIZZLE_ZZZZ;
-         else if (token[0] == 'w')
-            srcReg->Swizzle = SWIZZLE_WWWW;
-         else
-            RETURN_ERROR1("Expected x, y, z, or w");
-      }
-      else {
-         /* 2, 3 or 4-component swizzle */
-         GLint k;
-
-         srcReg->Swizzle = 0;
-
-         for (k = 0; token[k] && k < 5; k++) {
-            if (token[k] == 'x')
-               srcReg->Swizzle |= 0 << (k*3);
-            else if (token[k] == 'y')
-               srcReg->Swizzle |= 1 << (k*3);
-            else if (token[k] == 'z')
-               srcReg->Swizzle |= 2 << (k*3);
-            else if (token[k] == 'w')
-               srcReg->Swizzle |= 3 << (k*3);
-            else
-               RETURN_ERROR;
-         }
-         if (k >= 5)
-            RETURN_ERROR;
-      }
-   }
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_ScalarSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg)
-{
-   GLubyte token[100];
-   GLint idx;
-
-   srcReg->RelAddr = GL_FALSE;
-
-   /* check for '-' */
-   if (!Peek_Token(parseState, token))
-      RETURN_ERROR;
-   if (token[0] == '-') {
-      srcReg->Negate = NEGATE_XYZW;
-      (void) Parse_String(parseState, "-"); /* consume '-' */
-      if (!Peek_Token(parseState, token))
-         RETURN_ERROR;
-   }
-   else {
-      srcReg->Negate = NEGATE_NONE;
-   }
-
-   /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
-   if (token[0] == 'R') {
-      srcReg->File = PROGRAM_TEMPORARY;
-      if (!Parse_TempReg(parseState, &idx))
-         RETURN_ERROR;
-      srcReg->Index = idx;
-   }
-   else if (token[0] == 'c') {
-      if (!Parse_ParamReg(parseState, srcReg))
-         RETURN_ERROR;
-   }
-   else if (token[0] == 'v') {
-      srcReg->File = PROGRAM_INPUT;
-      if (!Parse_AttribReg(parseState, &idx))
-         RETURN_ERROR;
-      srcReg->Index = idx;
-   }
-   else {
-      RETURN_ERROR2("Bad source register name", token);
-   }
-
-   /* Look for .[xyzw] suffix */
-   if (!Parse_String(parseState, "."))
-      RETURN_ERROR;
-
-   if (!Parse_Token(parseState, token))
-      RETURN_ERROR;
-
-   if (token[0] == 'x' && token[1] == 0) {
-      srcReg->Swizzle = 0;
-   }
-   else if (token[0] == 'y' && token[1] == 0) {
-      srcReg->Swizzle = 1;
-   }
-   else if (token[0] == 'z' && token[1] == 0) {
-      srcReg->Swizzle = 2;
-   }
-   else if (token[0] == 'w' && token[1] == 0) {
-      srcReg->Swizzle = 3;
-   }
-   else {
-      RETURN_ERROR1("Bad scalar source suffix");
-   }
-
-   return GL_TRUE;
-}
-
-
-static GLint
-Parse_UnaryOpInstruction(struct parse_state *parseState,
-                         struct prog_instruction *inst,
-                         enum prog_opcode opcode)
-{
-   if (opcode == OPCODE_ABS && !parseState->isVersion1_1)
-      RETURN_ERROR1("ABS illegal for vertex program 1.0");
-
-   inst->Opcode = opcode;
-
-   /* dest reg */
-   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
-      RETURN_ERROR;
-
-   /* comma */
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR;
-
-   /* src arg */
-   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
-      RETURN_ERROR;
-
-   /* semicolon */
-   if (!Parse_String(parseState, ";"))
-      RETURN_ERROR;
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_BiOpInstruction(struct parse_state *parseState,
-                      struct prog_instruction *inst,
-                      enum prog_opcode opcode)
-{
-   if (opcode == OPCODE_DPH && !parseState->isVersion1_1)
-      RETURN_ERROR1("DPH illegal for vertex program 1.0");
-   if (opcode == OPCODE_SUB && !parseState->isVersion1_1)
-      RETURN_ERROR1("SUB illegal for vertex program 1.0");
-
-   inst->Opcode = opcode;
-
-   /* dest reg */
-   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
-      RETURN_ERROR;
-
-   /* comma */
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR;
-
-   /* first src arg */
-   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
-      RETURN_ERROR;
-
-   /* comma */
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR;
-
-   /* second src arg */
-   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1]))
-      RETURN_ERROR;
-
-   /* semicolon */
-   if (!Parse_String(parseState, ";"))
-      RETURN_ERROR;
-
-   /* make sure we don't reference more than one program parameter register */
-   if (inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
-       inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
-       inst->SrcReg[0].Index != inst->SrcReg[1].Index)
-      RETURN_ERROR1("Can't reference two program parameter registers");
-
-   /* make sure we don't reference more than one vertex attribute register */
-   if (inst->SrcReg[0].File == PROGRAM_INPUT &&
-       inst->SrcReg[1].File == PROGRAM_INPUT &&
-       inst->SrcReg[0].Index != inst->SrcReg[1].Index)
-      RETURN_ERROR1("Can't reference two vertex attribute registers");
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_TriOpInstruction(struct parse_state *parseState,
-                       struct prog_instruction *inst,
-                       enum prog_opcode opcode)
-{
-   inst->Opcode = opcode;
-
-   /* dest reg */
-   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
-      RETURN_ERROR;
-
-   /* comma */
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR;
-
-   /* first src arg */
-   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
-      RETURN_ERROR;
-
-   /* comma */
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR;
-
-   /* second src arg */
-   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1]))
-      RETURN_ERROR;
-
-   /* comma */
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR;
-
-   /* third src arg */
-   if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[2]))
-      RETURN_ERROR;
-
-   /* semicolon */
-   if (!Parse_String(parseState, ";"))
-      RETURN_ERROR;
-
-   /* make sure we don't reference more than one program parameter register */
-   if ((inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
-        inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
-        inst->SrcReg[0].Index != inst->SrcReg[1].Index) ||
-       (inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
-        inst->SrcReg[2].File == PROGRAM_ENV_PARAM &&
-        inst->SrcReg[0].Index != inst->SrcReg[2].Index) ||
-       (inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
-        inst->SrcReg[2].File == PROGRAM_ENV_PARAM &&
-        inst->SrcReg[1].Index != inst->SrcReg[2].Index))
-      RETURN_ERROR1("Can only reference one program register");
-
-   /* make sure we don't reference more than one vertex attribute register */
-   if ((inst->SrcReg[0].File == PROGRAM_INPUT &&
-        inst->SrcReg[1].File == PROGRAM_INPUT &&
-        inst->SrcReg[0].Index != inst->SrcReg[1].Index) ||
-       (inst->SrcReg[0].File == PROGRAM_INPUT &&
-        inst->SrcReg[2].File == PROGRAM_INPUT &&
-        inst->SrcReg[0].Index != inst->SrcReg[2].Index) ||
-       (inst->SrcReg[1].File == PROGRAM_INPUT &&
-        inst->SrcReg[2].File == PROGRAM_INPUT &&
-        inst->SrcReg[1].Index != inst->SrcReg[2].Index))
-      RETURN_ERROR1("Can only reference one input register");
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_ScalarInstruction(struct parse_state *parseState,
-                        struct prog_instruction *inst,
-                        enum prog_opcode opcode)
-{
-   if (opcode == OPCODE_RCC && !parseState->isVersion1_1)
-      RETURN_ERROR1("RCC illegal for vertex program 1.0");
-
-   inst->Opcode = opcode;
-
-   /* dest reg */
-   if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
-      RETURN_ERROR;
-
-   /* comma */
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR;
-
-   /* first src arg */
-   if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
-      RETURN_ERROR;
-
-   /* semicolon */
-   if (!Parse_String(parseState, ";"))
-      RETURN_ERROR;
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_AddressInstruction(struct parse_state *parseState, struct prog_instruction *inst)
-{
-   inst->Opcode = OPCODE_ARL;
-
-   /* Make ARB_vp backends happy */
-   inst->DstReg.File = PROGRAM_ADDRESS;
-   inst->DstReg.WriteMask = WRITEMASK_X;
-   inst->DstReg.Index = 0;
-
-   /* dest A0 reg */
-   if (!Parse_AddrReg(parseState))
-      RETURN_ERROR;
-
-   /* comma */
-   if (!Parse_String(parseState, ","))
-      RETURN_ERROR;
-
-   /* parse src reg */
-   if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
-      RETURN_ERROR;
-
-   /* semicolon */
-   if (!Parse_String(parseState, ";"))
-      RETURN_ERROR;
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_EndInstruction(struct parse_state *parseState, struct prog_instruction *inst)
-{
-   GLubyte token[100];
-
-   inst->Opcode = OPCODE_END;
-
-   /* this should fail! */
-   if (Parse_Token(parseState, token))
-      RETURN_ERROR2("Unexpected token after END:", token);
-   else
-      return GL_TRUE;
-}
-
-
-/**
- * The PRINT instruction is Mesa-specific and is meant as a debugging aid for
- * the vertex program developer.
- * The NV_vertex_program extension grammar is modified as follows:
- *
- *  <instruction>        ::= <ARL-instruction>
- *                         | ...
- *                         | <PRINT-instruction>
- *
- *  <PRINT-instruction>  ::= "PRINT" <string literal>
- *                         | "PRINT" <string literal> "," <srcReg>
- *                         | "PRINT" <string literal> "," <dstReg>
- */
-static GLboolean
-Parse_PrintInstruction(struct parse_state *parseState, struct prog_instruction *inst)
-{
-   const GLubyte *str;
-   GLubyte *msg;
-   GLuint len;
-   GLubyte token[100];
-   struct prog_src_register *srcReg = &inst->SrcReg[0];
-   GLint idx;
-
-   inst->Opcode = OPCODE_PRINT;
-
-   /* The first argument is a literal string 'just like this' */
-   if (!Parse_String(parseState, "'"))
-      RETURN_ERROR;
-
-   str = parseState->pos;
-   for (len = 0; str[len] != '\''; len++) /* find closing quote */
-      ;
-   parseState->pos += len + 1;
-   msg = (GLubyte*) malloc(len + 1);
-
-   memcpy(msg, str, len);
-   msg[len] = 0;
-   inst->Data = msg;
-
-   /* comma */
-   if (Parse_String(parseState, ",")) {
-
-      /* The second argument is a register name */
-      if (!Peek_Token(parseState, token))
-         RETURN_ERROR;
-
-      srcReg->RelAddr = GL_FALSE;
-      srcReg->Negate = NEGATE_NONE;
-      srcReg->Swizzle = SWIZZLE_NOOP;
-
-      /* Register can be R<n>, c[n], c[n +/- offset], a named vertex attrib,
-       * or an o[n] output register.
-       */
-      if (token[0] == 'R') {
-         srcReg->File = PROGRAM_TEMPORARY;
-         if (!Parse_TempReg(parseState, &idx))
-            RETURN_ERROR;
-        srcReg->Index = idx;
-      }
-      else if (token[0] == 'c') {
-         srcReg->File = PROGRAM_ENV_PARAM;
-         if (!Parse_ParamReg(parseState, srcReg))
-            RETURN_ERROR;
-      }
-      else if (token[0] == 'v') {
-         srcReg->File = PROGRAM_INPUT;
-         if (!Parse_AttribReg(parseState, &idx))
-            RETURN_ERROR;
-        srcReg->Index = idx;
-      }
-      else if (token[0] == 'o') {
-         srcReg->File = PROGRAM_OUTPUT;
-         if (!Parse_OutputReg(parseState, &idx))
-            RETURN_ERROR;
-        srcReg->Index = idx;
-      }
-      else {
-         RETURN_ERROR2("Bad source register name", token);
-      }
-   }
-   else {
-      srcReg->File = PROGRAM_UNDEFINED;
-   }
-
-   /* semicolon */
-   if (!Parse_String(parseState, ";"))
-      RETURN_ERROR;
-
-   return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_OptionSequence(struct parse_state *parseState,
-                     struct prog_instruction program[])
-{
-   (void) program;
-   while (1) {
-      if (!Parse_String(parseState, "OPTION"))
-         return GL_TRUE;  /* ok, not an OPTION statement */
-      if (Parse_String(parseState, "NV_position_invariant")) {
-         parseState->isPositionInvariant = GL_TRUE;
-      }
-      else {
-         RETURN_ERROR1("unexpected OPTION statement");
-      }
-      if (!Parse_String(parseState, ";"))
-         return GL_FALSE;
-   }
-}
-
-
-static GLboolean
-Parse_InstructionSequence(struct parse_state *parseState,
-                          struct prog_instruction program[])
-{
-   while (1) {
-      struct prog_instruction *inst = program + parseState->numInst;
-
-      /* Initialize the instruction */
-      _mesa_init_instructions(inst, 1);
-
-      if (Parse_String(parseState, "MOV")) {
-         if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_MOV))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "LIT")) {
-         if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_LIT))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "ABS")) {
-         if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_ABS))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "MUL")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MUL))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "ADD")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_ADD))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "DP3")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP3))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "DP4")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP4))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "DST")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DST))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "MIN")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MIN))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "MAX")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MAX))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "SLT")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SLT))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "SGE")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SGE))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "DPH")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DPH))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "SUB")) {
-         if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SUB))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "MAD")) {
-         if (!Parse_TriOpInstruction(parseState, inst, OPCODE_MAD))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "RCP")) {
-         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCP))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "RSQ")) {
-         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RSQ))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "EXP")) {
-         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_EXP))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "LOG")) {
-         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_LOG))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "RCC")) {
-         if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCC))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "ARL")) {
-         if (!Parse_AddressInstruction(parseState, inst))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "PRINT")) {
-         if (!Parse_PrintInstruction(parseState, inst))
-            RETURN_ERROR;
-      }
-      else if (Parse_String(parseState, "END")) {
-         if (!Parse_EndInstruction(parseState, inst))
-            RETURN_ERROR;
-         else {
-            parseState->numInst++;
-            return GL_TRUE;  /* all done */
-         }
-      }
-      else {
-         /* bad instruction name */
-         RETURN_ERROR1("Unexpected token");
-      }
-
-      /* examine input/output registers */
-      if (inst->DstReg.File == PROGRAM_OUTPUT)
-         parseState->outputsWritten |= (1 << inst->DstReg.Index);
-      else if (inst->DstReg.File == PROGRAM_ENV_PARAM)
-         parseState->anyProgRegsWritten = GL_TRUE;
-
-      if (inst->SrcReg[0].File == PROGRAM_INPUT)
-         parseState->inputsRead |= (1 << inst->SrcReg[0].Index);
-      if (inst->SrcReg[1].File == PROGRAM_INPUT)
-         parseState->inputsRead |= (1 << inst->SrcReg[1].Index);
-      if (inst->SrcReg[2].File == PROGRAM_INPUT)
-         parseState->inputsRead |= (1 << inst->SrcReg[2].Index);
-
-      parseState->numInst++;
-
-      if (parseState->numInst >= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS)
-         RETURN_ERROR1("Program too long");
-   }
-
-   RETURN_ERROR;
-}
-
-
-static GLboolean
-Parse_Program(struct parse_state *parseState,
-              struct prog_instruction instBuffer[])
-{
-   if (parseState->isVersion1_1) {
-      if (!Parse_OptionSequence(parseState, instBuffer)) {
-         return GL_FALSE;
-      }
-   }
-   return Parse_InstructionSequence(parseState, instBuffer);
-}
-
-
-/**
- * Parse/compile the 'str' returning the compiled 'program'.
- * ctx->Program.ErrorPos will be -1 if successful.  Otherwise, ErrorPos
- * indicates the position of the error in 'str'.
- */
-void
-_mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget,
-                              const GLubyte *str, GLsizei len,
-                              struct gl_vertex_program *program)
-{
-   struct parse_state parseState;
-   struct prog_instruction instBuffer[MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS];
-   struct prog_instruction *newInst;
-   GLenum target;
-   GLubyte *programString;
-
-   /* Make a null-terminated copy of the program string */
-   programString = (GLubyte *) MALLOC(len + 1);
-   if (!programString) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
-      return;
-   }
-   memcpy(programString, str, len);
-   programString[len] = 0;
-
-   /* Get ready to parse */
-   parseState.ctx = ctx;
-   parseState.start = programString;
-   parseState.isPositionInvariant = GL_FALSE;
-   parseState.isVersion1_1 = GL_FALSE;
-   parseState.numInst = 0;
-   parseState.inputsRead = 0;
-   parseState.outputsWritten = 0;
-   parseState.anyProgRegsWritten = GL_FALSE;
-
-   /* Reset error state */
-   _mesa_set_program_error(ctx, -1, NULL);
-
-   /* check the program header */
-   if (strncmp((const char *) programString, "!!VP1.0", 7) == 0) {
-      target = GL_VERTEX_PROGRAM_NV;
-      parseState.pos = programString + 7;
-      parseState.isStateProgram = GL_FALSE;
-   }
-   else if (strncmp((const char *) programString, "!!VP1.1", 7) == 0) {
-      target = GL_VERTEX_PROGRAM_NV;
-      parseState.pos = programString + 7;
-      parseState.isStateProgram = GL_FALSE;
-      parseState.isVersion1_1 = GL_TRUE;
-   }
-   else if (strncmp((const char *) programString, "!!VSP1.0", 8) == 0) {
-      target = GL_VERTEX_STATE_PROGRAM_NV;
-      parseState.pos = programString + 8;
-      parseState.isStateProgram = GL_TRUE;
-   }
-   else {
-      /* invalid header */
-      ctx->Program.ErrorPos = 0;
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
-      return;
-   }
-
-   /* make sure target and header match */
-   if (target != dstTarget) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glLoadProgramNV(target mismatch)");
-      return;
-   }
-
-
-   if (Parse_Program(&parseState, instBuffer)) {
-      gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0};
-      int i;
-
-      /* successful parse! */
-
-      if (parseState.isStateProgram) {
-         if (!parseState.anyProgRegsWritten) {
-            _mesa_error(ctx, GL_INVALID_OPERATION,
-                        "glLoadProgramNV(c[#] not written)");
-            return;
-         }
-      }
-      else {
-         if (!parseState.isPositionInvariant &&
-             !(parseState.outputsWritten & (1 << VERT_RESULT_HPOS))) {
-            /* bit 1 = HPOS register */
-            _mesa_error(ctx, GL_INVALID_OPERATION,
-                        "glLoadProgramNV(HPOS not written)");
-            return;
-         }
-      }
-
-      /* copy the compiled instructions */
-      assert(parseState.numInst <= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS);
-      newInst = _mesa_alloc_instructions(parseState.numInst);
-      if (!newInst) {
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
-         free(programString);
-         return;  /* out of memory */
-      }
-      _mesa_copy_instructions(newInst, instBuffer, parseState.numInst);
-
-      /* install the program */
-      program->Base.Target = target;
-      if (program->Base.String) {
-         free(program->Base.String);
-      }
-      program->Base.String = programString;
-      program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;
-      if (program->Base.Instructions) {
-         free(program->Base.Instructions);
-      }
-      program->Base.Instructions = newInst;
-      program->Base.InputsRead = parseState.inputsRead;
-      if (parseState.isPositionInvariant)
-         program->Base.InputsRead |= VERT_BIT_POS;
-      program->Base.NumInstructions = parseState.numInst;
-      program->Base.OutputsWritten = parseState.outputsWritten;
-      program->IsPositionInvariant = parseState.isPositionInvariant;
-      program->IsNVProgram = GL_TRUE;
-
-#ifdef DEBUG_foo
-      printf("--- glLoadProgramNV result ---\n");
-      _mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0);
-      printf("------------------------------\n");
-#endif
-
-      if (program->Base.Parameters)
-        _mesa_free_parameter_list(program->Base.Parameters);
-
-      program->Base.Parameters = _mesa_new_parameter_list ();
-      program->Base.NumParameters = 0;
-
-      state_tokens[0] = STATE_VERTEX_PROGRAM;
-      state_tokens[1] = STATE_ENV;
-      /* Add refs to all of the potential params, in order.  If we want to not
-       * upload everything, _mesa_layout_parameters is the answer.
-       */
-      for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS; i++) {
-        GLint index;
-        state_tokens[2] = i;
-        index = _mesa_add_state_reference(program->Base.Parameters,
-                                          state_tokens);
-        assert(index == i);
-      }
-      program->Base.NumParameters = program->Base.Parameters->NumParameters;
-
-      _mesa_setup_nv_temporary_count(ctx, &program->Base);
-      _mesa_emit_nv_temp_initialization(ctx, &program->Base);
-   }
-   else {
-      /* Error! */
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV");
-      /* NOTE: _mesa_set_program_error would have been called already */
-      /* GL_NV_vertex_program isn't supposed to set the error string
-       * so we reset it here.
-       */
-      _mesa_set_program_error(ctx, ctx->Program.ErrorPos, NULL);
-   }
-}
-
-
-const char *
-_mesa_nv_vertex_input_register_name(GLuint i)
-{
-   ASSERT(i < MAX_NV_VERTEX_PROGRAM_INPUTS);
-   return InputRegisters[i];
-}
-
-
-const char *
-_mesa_nv_vertex_output_register_name(GLuint i)
-{
-   ASSERT(i < MAX_NV_VERTEX_PROGRAM_OUTPUTS);
-   return OutputRegisters[i];
-}
-
diff --git a/src/mesa/shader/nvvertparse.h b/src/mesa/shader/nvvertparse.h
deleted file mode 100644 (file)
index 9919e22..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  5.1
- *
- * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- *    Brian Paul
- */
-
-
-#ifndef NVVERTPARSE_H
-#define NVVERTPARSE_H
-
-
-extern void
-_mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum target,
-                              const GLubyte *str, GLsizei len,
-                              struct gl_vertex_program *program);
-
-
-extern const char *
-_mesa_nv_vertex_input_register_name(GLuint i);
-
-extern const char *
-_mesa_nv_vertex_output_register_name(GLuint i);
-
-#endif
diff --git a/src/mesa/shader/prog_cache.c b/src/mesa/shader/prog_cache.c
deleted file mode 100644 (file)
index e5b602f..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-
-#include "main/glheader.h"
-#include "main/mtypes.h"
-#include "main/imports.h"
-#include "shader/prog_cache.h"
-#include "shader/program.h"
-
-
-struct cache_item
-{
-   GLuint hash;
-   void *key;
-   struct gl_program *program;
-   struct cache_item *next;
-};
-
-struct gl_program_cache
-{
-   struct cache_item **items;
-   struct cache_item *last;
-   GLuint size, n_items;
-};
-
-
-
-/**
- * Compute hash index from state key.
- */
-static GLuint
-hash_key(const void *key, GLuint key_size)
-{
-   const GLuint *ikey = (const GLuint *) key;
-   GLuint hash = 0, i;
-
-   assert(key_size >= 4);
-
-   /* Make a slightly better attempt at a hash function:
-    */
-   for (i = 0; i < key_size / sizeof(*ikey); i++)
-   {
-      hash += ikey[i];
-      hash += (hash << 10);
-      hash ^= (hash >> 6);
-   }
-
-   return hash;
-}
-
-
-/**
- * Rebuild/expand the hash table to accomodate more entries
- */
-static void
-rehash(struct gl_program_cache *cache)
-{
-   struct cache_item **items;
-   struct cache_item *c, *next;
-   GLuint size, i;
-
-   cache->last = NULL;
-
-   size = cache->size * 3;
-   items = (struct cache_item**) malloc(size * sizeof(*items));
-   memset(items, 0, size * sizeof(*items));
-
-   for (i = 0; i < cache->size; i++)
-      for (c = cache->items[i]; c; c = next) {
-        next = c->next;
-        c->next = items[c->hash % size];
-        items[c->hash % size] = c;
-      }
-
-   free(cache->items);
-   cache->items = items;
-   cache->size = size;
-}
-
-
-static void
-clear_cache(GLcontext *ctx, struct gl_program_cache *cache)
-{
-   struct cache_item *c, *next;
-   GLuint i;
-   
-   cache->last = NULL;
-
-   for (i = 0; i < cache->size; i++) {
-      for (c = cache->items[i]; c; c = next) {
-        next = c->next;
-        free(c->key);
-         _mesa_reference_program(ctx, &c->program, NULL);
-        free(c);
-      }
-      cache->items[i] = NULL;
-   }
-
-
-   cache->n_items = 0;
-}
-
-
-
-struct gl_program_cache *
-_mesa_new_program_cache(void)
-{
-   struct gl_program_cache *cache = CALLOC_STRUCT(gl_program_cache);
-   if (cache) {
-      cache->size = 17;
-      cache->items = (struct cache_item **)
-         calloc(1, cache->size * sizeof(struct cache_item));
-      if (!cache->items) {
-         free(cache);
-         return NULL;
-      }
-   }
-   return cache;
-}
-
-
-void
-_mesa_delete_program_cache(GLcontext *ctx, struct gl_program_cache *cache)
-{
-   clear_cache(ctx, cache);
-   free(cache->items);
-   free(cache);
-}
-
-
-struct gl_program *
-_mesa_search_program_cache(struct gl_program_cache *cache,
-                           const void *key, GLuint keysize)
-{
-   if (cache->last && 
-       memcmp(cache->last->key, key, keysize) == 0) {
-      return cache->last->program;
-   }
-   else {
-      const GLuint hash = hash_key(key, keysize);
-      struct cache_item *c;
-
-      for (c = cache->items[hash % cache->size]; c; c = c->next) {
-         if (c->hash == hash && memcmp(c->key, key, keysize) == 0) {
-            cache->last = c;
-            return c->program;
-         }
-      }
-
-      return NULL;
-   }
-}
-
-
-void
-_mesa_program_cache_insert(GLcontext *ctx,
-                           struct gl_program_cache *cache,
-                           const void *key, GLuint keysize,
-                           struct gl_program *program)
-{
-   const GLuint hash = hash_key(key, keysize);
-   struct cache_item *c = CALLOC_STRUCT(cache_item);
-
-   c->hash = hash;
-
-   c->key = malloc(keysize);
-   memcpy(c->key, key, keysize);
-
-   c->program = program;  /* no refcount change */
-
-   if (cache->n_items > cache->size * 1.5) {
-      if (cache->size < 1000)
-        rehash(cache);
-      else 
-        clear_cache(ctx, cache);
-   }
-
-   cache->n_items++;
-   c->next = cache->items[hash % cache->size];
-   cache->items[hash % cache->size] = c;
-}
diff --git a/src/mesa/shader/prog_cache.h b/src/mesa/shader/prog_cache.h
deleted file mode 100644 (file)
index 4e1ccac..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-
-#ifndef PROG_CACHE_H
-#define PROG_CACHE_H
-
-
-/** Opaque type */
-struct gl_program_cache;
-
-
-extern struct gl_program_cache *
-_mesa_new_program_cache(void);
-
-extern void
-_mesa_delete_program_cache(GLcontext *ctx, struct gl_program_cache *pc);
-
-
-extern struct gl_program *
-_mesa_search_program_cache(struct gl_program_cache *cache,
-                           const void *key, GLuint keysize);
-
-extern void
-_mesa_program_cache_insert(GLcontext *ctx,
-                           struct gl_program_cache *cache,
-                           const void *key, GLuint keysize,
-                           struct gl_program *program);
-
-
-#endif /* PROG_CACHE_H */
diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c
deleted file mode 100644 (file)
index b6da344..0000000
+++ /dev/null
@@ -1,1802 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.3
- *
- * Copyright (C) 1999-2008  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 prog_execute.c
- * Software interpreter for vertex/fragment programs.
- * \author Brian Paul
- */
-
-/*
- * NOTE: we do everything in single-precision floating point; we don't
- * currently observe the single/half/fixed-precision qualifiers.
- *
- */
-
-
-#include "main/glheader.h"
-#include "main/colormac.h"
-#include "main/context.h"
-#include "prog_execute.h"
-#include "prog_instruction.h"
-#include "prog_parameter.h"
-#include "prog_print.h"
-#include "prog_noise.h"
-
-
-/* debug predicate */
-#define DEBUG_PROG 0
-
-
-/**
- * Set x to positive or negative infinity.
- */
-#if defined(USE_IEEE) || defined(_WIN32)
-#define SET_POS_INFINITY(x)                  \
-   do {                                      \
-         fi_type fi;                         \
-         fi.i = 0x7F800000;                  \
-         x = fi.f;                           \
-   } while (0)
-#define SET_NEG_INFINITY(x)                  \
-   do {                                      \
-         fi_type fi;                         \
-         fi.i = 0xFF800000;                  \
-         x = fi.f;                           \
-   } while (0)
-#elif defined(VMS)
-#define SET_POS_INFINITY(x)  x = __MAXFLOAT
-#define SET_NEG_INFINITY(x)  x = -__MAXFLOAT
-#else
-#define SET_POS_INFINITY(x)  x = (GLfloat) HUGE_VAL
-#define SET_NEG_INFINITY(x)  x = (GLfloat) -HUGE_VAL
-#endif
-
-#define SET_FLOAT_BITS(x, bits) ((fi_type *) (void *) &(x))->i = bits
-
-
-static const GLfloat ZeroVec[4] = { 0.0F, 0.0F, 0.0F, 0.0F };
-
-
-
-/**
- * Return a pointer to the 4-element float vector specified by the given
- * source register.
- */
-static INLINE const GLfloat *
-get_src_register_pointer(const struct prog_src_register *source,
-                         const struct gl_program_machine *machine)
-{
-   const struct gl_program *prog = machine->CurProgram;
-   GLint reg = source->Index;
-
-   if (source->RelAddr) {
-      /* add address register value to src index/offset */
-      reg += machine->AddressReg[0][0];
-      if (reg < 0) {
-         return ZeroVec;
-      }
-   }
-
-   switch (source->File) {
-   case PROGRAM_TEMPORARY:
-      if (reg >= MAX_PROGRAM_TEMPS)
-         return ZeroVec;
-      return machine->Temporaries[reg];
-
-   case PROGRAM_INPUT:
-      if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
-         if (reg >= VERT_ATTRIB_MAX)
-            return ZeroVec;
-         return machine->VertAttribs[reg];
-      }
-      else {
-         if (reg >= FRAG_ATTRIB_MAX)
-            return ZeroVec;
-         return machine->Attribs[reg][machine->CurElement];
-      }
-
-   case PROGRAM_OUTPUT:
-      if (reg >= MAX_PROGRAM_OUTPUTS)
-         return ZeroVec;
-      return machine->Outputs[reg];
-
-   case PROGRAM_LOCAL_PARAM:
-      if (reg >= MAX_PROGRAM_LOCAL_PARAMS)
-         return ZeroVec;
-      return machine->CurProgram->LocalParams[reg];
-
-   case PROGRAM_ENV_PARAM:
-      if (reg >= MAX_PROGRAM_ENV_PARAMS)
-         return ZeroVec;
-      return machine->EnvParams[reg];
-
-   case PROGRAM_STATE_VAR:
-      /* Fallthrough */
-   case PROGRAM_CONSTANT:
-      /* Fallthrough */
-   case PROGRAM_UNIFORM:
-      /* Fallthrough */
-   case PROGRAM_NAMED_PARAM:
-      if (reg >= (GLint) prog->Parameters->NumParameters)
-         return ZeroVec;
-      return prog->Parameters->ParameterValues[reg];
-
-   default:
-      _mesa_problem(NULL,
-         "Invalid src register file %d in get_src_register_pointer()",
-         source->File);
-      return NULL;
-   }
-}
-
-
-/**
- * Return a pointer to the 4-element float vector specified by the given
- * destination register.
- */
-static INLINE GLfloat *
-get_dst_register_pointer(const struct prog_dst_register *dest,
-                         struct gl_program_machine *machine)
-{
-   static GLfloat dummyReg[4];
-   GLint reg = dest->Index;
-
-   if (dest->RelAddr) {
-      /* add address register value to src index/offset */
-      reg += machine->AddressReg[0][0];
-      if (reg < 0) {
-         return dummyReg;
-      }
-   }
-
-   switch (dest->File) {
-   case PROGRAM_TEMPORARY:
-      if (reg >= MAX_PROGRAM_TEMPS)
-         return dummyReg;
-      return machine->Temporaries[reg];
-
-   case PROGRAM_OUTPUT:
-      if (reg >= MAX_PROGRAM_OUTPUTS)
-         return dummyReg;
-      return machine->Outputs[reg];
-
-   case PROGRAM_WRITE_ONLY:
-      return dummyReg;
-
-   default:
-      _mesa_problem(NULL,
-         "Invalid dest register file %d in get_dst_register_pointer()",
-         dest->File);
-      return NULL;
-   }
-}
-
-
-
-/**
- * Fetch a 4-element float vector from the given source register.
- * Apply swizzling and negating as needed.
- */
-static void
-fetch_vector4(const struct prog_src_register *source,
-              const struct gl_program_machine *machine, GLfloat result[4])
-{
-   const GLfloat *src = get_src_register_pointer(source, machine);
-   ASSERT(src);
-
-   if (source->Swizzle == SWIZZLE_NOOP) {
-      /* no swizzling */
-      COPY_4V(result, src);
-   }
-   else {
-      ASSERT(GET_SWZ(source->Swizzle, 0) <= 3);
-      ASSERT(GET_SWZ(source->Swizzle, 1) <= 3);
-      ASSERT(GET_SWZ(source->Swizzle, 2) <= 3);
-      ASSERT(GET_SWZ(source->Swizzle, 3) <= 3);
-      result[0] = src[GET_SWZ(source->Swizzle, 0)];
-      result[1] = src[GET_SWZ(source->Swizzle, 1)];
-      result[2] = src[GET_SWZ(source->Swizzle, 2)];
-      result[3] = src[GET_SWZ(source->Swizzle, 3)];
-   }
-
-   if (source->Abs) {
-      result[0] = FABSF(result[0]);
-      result[1] = FABSF(result[1]);
-      result[2] = FABSF(result[2]);
-      result[3] = FABSF(result[3]);
-   }
-   if (source->Negate) {
-      ASSERT(source->Negate == NEGATE_XYZW);
-      result[0] = -result[0];
-      result[1] = -result[1];
-      result[2] = -result[2];
-      result[3] = -result[3];
-   }
-
-#ifdef NAN_CHECK
-   assert(!IS_INF_OR_NAN(result[0]));
-   assert(!IS_INF_OR_NAN(result[0]));
-   assert(!IS_INF_OR_NAN(result[0]));
-   assert(!IS_INF_OR_NAN(result[0]));
-#endif
-}
-
-
-/**
- * Fetch a 4-element uint vector from the given source register.
- * Apply swizzling but not negation/abs.
- */
-static void
-fetch_vector4ui(const struct prog_src_register *source,
-                const struct gl_program_machine *machine, GLuint result[4])
-{
-   const GLuint *src = (GLuint *) get_src_register_pointer(source, machine);
-   ASSERT(src);
-
-   if (source->Swizzle == SWIZZLE_NOOP) {
-      /* no swizzling */
-      COPY_4V(result, src);
-   }
-   else {
-      ASSERT(GET_SWZ(source->Swizzle, 0) <= 3);
-      ASSERT(GET_SWZ(source->Swizzle, 1) <= 3);
-      ASSERT(GET_SWZ(source->Swizzle, 2) <= 3);
-      ASSERT(GET_SWZ(source->Swizzle, 3) <= 3);
-      result[0] = src[GET_SWZ(source->Swizzle, 0)];
-      result[1] = src[GET_SWZ(source->Swizzle, 1)];
-      result[2] = src[GET_SWZ(source->Swizzle, 2)];
-      result[3] = src[GET_SWZ(source->Swizzle, 3)];
-   }
-
-   /* Note: no Negate or Abs here */
-}
-
-
-
-/**
- * Fetch the derivative with respect to X or Y for the given register.
- * XXX this currently only works for fragment program input attribs.
- */
-static void
-fetch_vector4_deriv(GLcontext * ctx,
-                    const struct prog_src_register *source,
-                    const struct gl_program_machine *machine,
-                    char xOrY, GLfloat result[4])
-{
-   if (source->File == PROGRAM_INPUT &&
-       source->Index < (GLint) machine->NumDeriv) {
-      const GLint col = machine->CurElement;
-      const GLfloat w = machine->Attribs[FRAG_ATTRIB_WPOS][col][3];
-      const GLfloat invQ = 1.0f / w;
-      GLfloat deriv[4];
-
-      if (xOrY == 'X') {
-         deriv[0] = machine->DerivX[source->Index][0] * invQ;
-         deriv[1] = machine->DerivX[source->Index][1] * invQ;
-         deriv[2] = machine->DerivX[source->Index][2] * invQ;
-         deriv[3] = machine->DerivX[source->Index][3] * invQ;
-      }
-      else {
-         deriv[0] = machine->DerivY[source->Index][0] * invQ;
-         deriv[1] = machine->DerivY[source->Index][1] * invQ;
-         deriv[2] = machine->DerivY[source->Index][2] * invQ;
-         deriv[3] = machine->DerivY[source->Index][3] * invQ;
-      }
-
-      result[0] = deriv[GET_SWZ(source->Swizzle, 0)];
-      result[1] = deriv[GET_SWZ(source->Swizzle, 1)];
-      result[2] = deriv[GET_SWZ(source->Swizzle, 2)];
-      result[3] = deriv[GET_SWZ(source->Swizzle, 3)];
-      
-      if (source->Abs) {
-         result[0] = FABSF(result[0]);
-         result[1] = FABSF(result[1]);
-         result[2] = FABSF(result[2]);
-         result[3] = FABSF(result[3]);
-      }
-      if (source->Negate) {
-         ASSERT(source->Negate == NEGATE_XYZW);
-         result[0] = -result[0];
-         result[1] = -result[1];
-         result[2] = -result[2];
-         result[3] = -result[3];
-      }
-   }
-   else {
-      ASSIGN_4V(result, 0.0, 0.0, 0.0, 0.0);
-   }
-}
-
-
-/**
- * As above, but only return result[0] element.
- */
-static void
-fetch_vector1(const struct prog_src_register *source,
-              const struct gl_program_machine *machine, GLfloat result[4])
-{
-   const GLfloat *src = get_src_register_pointer(source, machine);
-   ASSERT(src);
-
-   result[0] = src[GET_SWZ(source->Swizzle, 0)];
-
-   if (source->Abs) {
-      result[0] = FABSF(result[0]);
-   }
-   if (source->Negate) {
-      result[0] = -result[0];
-   }
-}
-
-
-static GLuint
-fetch_vector1ui(const struct prog_src_register *source,
-                const struct gl_program_machine *machine)
-{
-   const GLuint *src = (GLuint *) get_src_register_pointer(source, machine);
-   return src[GET_SWZ(source->Swizzle, 0)];
-}
-
-
-/**
- * Fetch texel from texture.  Use partial derivatives when possible.
- */
-static INLINE void
-fetch_texel(GLcontext *ctx,
-            const struct gl_program_machine *machine,
-            const struct prog_instruction *inst,
-            const GLfloat texcoord[4], GLfloat lodBias,
-            GLfloat color[4])
-{
-   const GLuint unit = machine->Samplers[inst->TexSrcUnit];
-
-   /* Note: we only have the right derivatives for fragment input attribs.
-    */
-   if (machine->NumDeriv > 0 &&
-       inst->SrcReg[0].File == PROGRAM_INPUT &&
-       inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit) {
-      /* simple texture fetch for which we should have derivatives */
-      GLuint attr = inst->SrcReg[0].Index;
-      machine->FetchTexelDeriv(ctx, texcoord,
-                               machine->DerivX[attr],
-                               machine->DerivY[attr],
-                               lodBias, unit, color);
-   }
-   else {
-      machine->FetchTexelLod(ctx, texcoord, lodBias, unit, color);
-   }
-}
-
-
-/**
- * Test value against zero and return GT, LT, EQ or UN if NaN.
- */
-static INLINE GLuint
-generate_cc(float value)
-{
-   if (value != value)
-      return COND_UN;           /* NaN */
-   if (value > 0.0F)
-      return COND_GT;
-   if (value < 0.0F)
-      return COND_LT;
-   return COND_EQ;
-}
-
-
-/**
- * Test if the ccMaskRule is satisfied by the given condition code.
- * Used to mask destination writes according to the current condition code.
- */
-static INLINE GLboolean
-test_cc(GLuint condCode, GLuint ccMaskRule)
-{
-   switch (ccMaskRule) {
-   case COND_EQ: return (condCode == COND_EQ);
-   case COND_NE: return (condCode != COND_EQ);
-   case COND_LT: return (condCode == COND_LT);
-   case COND_GE: return (condCode == COND_GT || condCode == COND_EQ);
-   case COND_LE: return (condCode == COND_LT || condCode == COND_EQ);
-   case COND_GT: return (condCode == COND_GT);
-   case COND_TR: return GL_TRUE;
-   case COND_FL: return GL_FALSE;
-   default:      return GL_TRUE;
-   }
-}
-
-
-/**
- * Evaluate the 4 condition codes against a predicate and return GL_TRUE
- * or GL_FALSE to indicate result.
- */
-static INLINE GLboolean
-eval_condition(const struct gl_program_machine *machine,
-               const struct prog_instruction *inst)
-{
-   const GLuint swizzle = inst->DstReg.CondSwizzle;
-   const GLuint condMask = inst->DstReg.CondMask;
-   if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) ||
-       test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) ||
-       test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) ||
-       test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) {
-      return GL_TRUE;
-   }
-   else {
-      return GL_FALSE;
-   }
-}
-
-
-
-/**
- * Store 4 floats into a register.  Observe the instructions saturate and
- * set-condition-code flags.
- */
-static void
-store_vector4(const struct prog_instruction *inst,
-              struct gl_program_machine *machine, const GLfloat value[4])
-{
-   const struct prog_dst_register *dstReg = &(inst->DstReg);
-   const GLboolean clamp = inst->SaturateMode == SATURATE_ZERO_ONE;
-   GLuint writeMask = dstReg->WriteMask;
-   GLfloat clampedValue[4];
-   GLfloat *dst = get_dst_register_pointer(dstReg, machine);
-
-#if 0
-   if (value[0] > 1.0e10 ||
-       IS_INF_OR_NAN(value[0]) ||
-       IS_INF_OR_NAN(value[1]) ||
-       IS_INF_OR_NAN(value[2]) || IS_INF_OR_NAN(value[3]))
-      printf("store %g %g %g %g\n", value[0], value[1], value[2], value[3]);
-#endif
-
-   if (clamp) {
-      clampedValue[0] = CLAMP(value[0], 0.0F, 1.0F);
-      clampedValue[1] = CLAMP(value[1], 0.0F, 1.0F);
-      clampedValue[2] = CLAMP(value[2], 0.0F, 1.0F);
-      clampedValue[3] = CLAMP(value[3], 0.0F, 1.0F);
-      value = clampedValue;
-   }
-
-   if (dstReg->CondMask != COND_TR) {
-      /* condition codes may turn off some writes */
-      if (writeMask & WRITEMASK_X) {
-         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 0)],
-                      dstReg->CondMask))
-            writeMask &= ~WRITEMASK_X;
-      }
-      if (writeMask & WRITEMASK_Y) {
-         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 1)],
-                      dstReg->CondMask))
-            writeMask &= ~WRITEMASK_Y;
-      }
-      if (writeMask & WRITEMASK_Z) {
-         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 2)],
-                      dstReg->CondMask))
-            writeMask &= ~WRITEMASK_Z;
-      }
-      if (writeMask & WRITEMASK_W) {
-         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 3)],
-                      dstReg->CondMask))
-            writeMask &= ~WRITEMASK_W;
-      }
-   }
-
-#ifdef NAN_CHECK
-   assert(!IS_INF_OR_NAN(value[0]));
-   assert(!IS_INF_OR_NAN(value[0]));
-   assert(!IS_INF_OR_NAN(value[0]));
-   assert(!IS_INF_OR_NAN(value[0]));
-#endif
-
-   if (writeMask & WRITEMASK_X)
-      dst[0] = value[0];
-   if (writeMask & WRITEMASK_Y)
-      dst[1] = value[1];
-   if (writeMask & WRITEMASK_Z)
-      dst[2] = value[2];
-   if (writeMask & WRITEMASK_W)
-      dst[3] = value[3];
-
-   if (inst->CondUpdate) {
-      if (writeMask & WRITEMASK_X)
-         machine->CondCodes[0] = generate_cc(value[0]);
-      if (writeMask & WRITEMASK_Y)
-         machine->CondCodes[1] = generate_cc(value[1]);
-      if (writeMask & WRITEMASK_Z)
-         machine->CondCodes[2] = generate_cc(value[2]);
-      if (writeMask & WRITEMASK_W)
-         machine->CondCodes[3] = generate_cc(value[3]);
-#if DEBUG_PROG
-      printf("CondCodes=(%s,%s,%s,%s) for:\n",
-             _mesa_condcode_string(machine->CondCodes[0]),
-             _mesa_condcode_string(machine->CondCodes[1]),
-             _mesa_condcode_string(machine->CondCodes[2]),
-             _mesa_condcode_string(machine->CondCodes[3]));
-#endif
-   }
-}
-
-
-/**
- * Store 4 uints into a register.  Observe the set-condition-code flags.
- */
-static void
-store_vector4ui(const struct prog_instruction *inst,
-                struct gl_program_machine *machine, const GLuint value[4])
-{
-   const struct prog_dst_register *dstReg = &(inst->DstReg);
-   GLuint writeMask = dstReg->WriteMask;
-   GLuint *dst = (GLuint *) get_dst_register_pointer(dstReg, machine);
-
-   if (dstReg->CondMask != COND_TR) {
-      /* condition codes may turn off some writes */
-      if (writeMask & WRITEMASK_X) {
-         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 0)],
-                      dstReg->CondMask))
-            writeMask &= ~WRITEMASK_X;
-      }
-      if (writeMask & WRITEMASK_Y) {
-         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 1)],
-                      dstReg->CondMask))
-            writeMask &= ~WRITEMASK_Y;
-      }
-      if (writeMask & WRITEMASK_Z) {
-         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 2)],
-                      dstReg->CondMask))
-            writeMask &= ~WRITEMASK_Z;
-      }
-      if (writeMask & WRITEMASK_W) {
-         if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 3)],
-                      dstReg->CondMask))
-            writeMask &= ~WRITEMASK_W;
-      }
-   }
-
-   if (writeMask & WRITEMASK_X)
-      dst[0] = value[0];
-   if (writeMask & WRITEMASK_Y)
-      dst[1] = value[1];
-   if (writeMask & WRITEMASK_Z)
-      dst[2] = value[2];
-   if (writeMask & WRITEMASK_W)
-      dst[3] = value[3];
-
-   if (inst->CondUpdate) {
-      if (writeMask & WRITEMASK_X)
-         machine->CondCodes[0] = generate_cc((float)value[0]);
-      if (writeMask & WRITEMASK_Y)
-         machine->CondCodes[1] = generate_cc((float)value[1]);
-      if (writeMask & WRITEMASK_Z)
-         machine->CondCodes[2] = generate_cc((float)value[2]);
-      if (writeMask & WRITEMASK_W)
-         machine->CondCodes[3] = generate_cc((float)value[3]);
-#if DEBUG_PROG
-      printf("CondCodes=(%s,%s,%s,%s) for:\n",
-             _mesa_condcode_string(machine->CondCodes[0]),
-             _mesa_condcode_string(machine->CondCodes[1]),
-             _mesa_condcode_string(machine->CondCodes[2]),
-             _mesa_condcode_string(machine->CondCodes[3]));
-#endif
-   }
-}
-
-
-
-/**
- * Execute the given vertex/fragment program.
- *
- * \param ctx  rendering context
- * \param program  the program to execute
- * \param machine  machine state (must be initialized)
- * \return GL_TRUE if program completed or GL_FALSE if program executed KIL.
- */
-GLboolean
-_mesa_execute_program(GLcontext * ctx,
-                      const struct gl_program *program,
-                      struct gl_program_machine *machine)
-{
-   const GLuint numInst = program->NumInstructions;
-   const GLuint maxExec = 10000;
-   GLuint pc, numExec = 0;
-
-   machine->CurProgram = program;
-
-   if (DEBUG_PROG) {
-      printf("execute program %u --------------------\n", program->Id);
-   }
-
-   if (program->Target == GL_VERTEX_PROGRAM_ARB) {
-      machine->EnvParams = ctx->VertexProgram.Parameters;
-   }
-   else {
-      machine->EnvParams = ctx->FragmentProgram.Parameters;
-   }
-
-   for (pc = 0; pc < numInst; pc++) {
-      const struct prog_instruction *inst = program->Instructions + pc;
-
-      if (DEBUG_PROG) {
-         _mesa_print_instruction(inst);
-      }
-
-      switch (inst->Opcode) {
-      case OPCODE_ABS:
-         {
-            GLfloat a[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            result[0] = FABSF(a[0]);
-            result[1] = FABSF(a[1]);
-            result[2] = FABSF(a[2]);
-            result[3] = FABSF(a[3]);
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_ADD:
-         {
-            GLfloat a[4], b[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            result[0] = a[0] + b[0];
-            result[1] = a[1] + b[1];
-            result[2] = a[2] + b[2];
-            result[3] = a[3] + b[3];
-            store_vector4(inst, machine, result);
-            if (DEBUG_PROG) {
-               printf("ADD (%g %g %g %g) = (%g %g %g %g) + (%g %g %g %g)\n",
-                      result[0], result[1], result[2], result[3],
-                      a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
-            }
-         }
-         break;
-      case OPCODE_AND:     /* bitwise AND */
-         {
-            GLuint a[4], b[4], result[4];
-            fetch_vector4ui(&inst->SrcReg[0], machine, a);
-            fetch_vector4ui(&inst->SrcReg[1], machine, b);
-            result[0] = a[0] & b[0];
-            result[1] = a[1] & b[1];
-            result[2] = a[2] & b[2];
-            result[3] = a[3] & b[3];
-            store_vector4ui(inst, machine, result);
-         }
-         break;
-      case OPCODE_ARL:
-         {
-            GLfloat t[4];
-            fetch_vector4(&inst->SrcReg[0], machine, t);
-            machine->AddressReg[0][0] = IFLOOR(t[0]);
-            if (DEBUG_PROG) {
-               printf("ARL %d\n", machine->AddressReg[0][0]);
-            }
-         }
-         break;
-      case OPCODE_BGNLOOP:
-         /* no-op */
-         ASSERT(program->Instructions[inst->BranchTarget].Opcode
-                == OPCODE_ENDLOOP);
-         break;
-      case OPCODE_ENDLOOP:
-         /* subtract 1 here since pc is incremented by for(pc) loop */
-         ASSERT(program->Instructions[inst->BranchTarget].Opcode
-                == OPCODE_BGNLOOP);
-         pc = inst->BranchTarget - 1;   /* go to matching BNGLOOP */
-         break;
-      case OPCODE_BGNSUB:      /* begin subroutine */
-         break;
-      case OPCODE_ENDSUB:      /* end subroutine */
-         break;
-      case OPCODE_BRA:         /* branch (conditional) */
-         if (eval_condition(machine, inst)) {
-            /* take branch */
-            /* Subtract 1 here since we'll do pc++ below */
-            pc = inst->BranchTarget - 1;
-         }
-         break;
-      case OPCODE_BRK:         /* break out of loop (conditional) */
-         ASSERT(program->Instructions[inst->BranchTarget].Opcode
-                == OPCODE_ENDLOOP);
-         if (eval_condition(machine, inst)) {
-            /* break out of loop */
-            /* pc++ at end of for-loop will put us after the ENDLOOP inst */
-            pc = inst->BranchTarget;
-         }
-         break;
-      case OPCODE_CONT:        /* continue loop (conditional) */
-         ASSERT(program->Instructions[inst->BranchTarget].Opcode
-                == OPCODE_ENDLOOP);
-         if (eval_condition(machine, inst)) {
-            /* continue at ENDLOOP */
-            /* Subtract 1 here since we'll do pc++ at end of for-loop */
-            pc = inst->BranchTarget - 1;
-         }
-         break;
-      case OPCODE_CAL:         /* Call subroutine (conditional) */
-         if (eval_condition(machine, inst)) {
-            /* call the subroutine */
-            if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) {
-               return GL_TRUE;  /* Per GL_NV_vertex_program2 spec */
-            }
-            machine->CallStack[machine->StackDepth++] = pc + 1; /* next inst */
-            /* Subtract 1 here since we'll do pc++ at end of for-loop */
-            pc = inst->BranchTarget - 1;
-         }
-         break;
-      case OPCODE_CMP:
-         {
-            GLfloat a[4], b[4], c[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            fetch_vector4(&inst->SrcReg[2], machine, c);
-            result[0] = a[0] < 0.0F ? b[0] : c[0];
-            result[1] = a[1] < 0.0F ? b[1] : c[1];
-            result[2] = a[2] < 0.0F ? b[2] : c[2];
-            result[3] = a[3] < 0.0F ? b[3] : c[3];
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_COS:
-         {
-            GLfloat a[4], result[4];
-            fetch_vector1(&inst->SrcReg[0], machine, a);
-            result[0] = result[1] = result[2] = result[3]
-               = (GLfloat) cos(a[0]);
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_DDX:         /* Partial derivative with respect to X */
-         {
-            GLfloat result[4];
-            fetch_vector4_deriv(ctx, &inst->SrcReg[0], machine,
-                                'X', result);
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_DDY:         /* Partial derivative with respect to Y */
-         {
-            GLfloat result[4];
-            fetch_vector4_deriv(ctx, &inst->SrcReg[0], machine,
-                                'Y', result);
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_DP2:
-         {
-            GLfloat a[4], b[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            result[0] = result[1] = result[2] = result[3] = DOT2(a, b);
-            store_vector4(inst, machine, result);
-            if (DEBUG_PROG) {
-               printf("DP2 %g = (%g %g) . (%g %g)\n",
-                      result[0], a[0], a[1], b[0], b[1]);
-            }
-         }
-         break;
-      case OPCODE_DP2A:
-         {
-            GLfloat a[4], b[4], c, result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            fetch_vector1(&inst->SrcReg[1], machine, &c);
-            result[0] = result[1] = result[2] = result[3] = DOT2(a, b) + c;
-            store_vector4(inst, machine, result);
-            if (DEBUG_PROG) {
-               printf("DP2A %g = (%g %g) . (%g %g) + %g\n",
-                      result[0], a[0], a[1], b[0], b[1], c);
-            }
-         }
-         break;
-      case OPCODE_DP3:
-         {
-            GLfloat a[4], b[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            result[0] = result[1] = result[2] = result[3] = DOT3(a, b);
-            store_vector4(inst, machine, result);
-            if (DEBUG_PROG) {
-               printf("DP3 %g = (%g %g %g) . (%g %g %g)\n",
-                      result[0], a[0], a[1], a[2], b[0], b[1], b[2]);
-            }
-         }
-         break;
-      case OPCODE_DP4:
-         {
-            GLfloat a[4], b[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            result[0] = result[1] = result[2] = result[3] = DOT4(a, b);
-            store_vector4(inst, machine, result);
-            if (DEBUG_PROG) {
-               printf("DP4 %g = (%g, %g %g %g) . (%g, %g %g %g)\n",
-                      result[0], a[0], a[1], a[2], a[3],
-                      b[0], b[1], b[2], b[3]);
-            }
-         }
-         break;
-      case OPCODE_DPH:
-         {
-            GLfloat a[4], b[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            result[0] = result[1] = result[2] = result[3] = DOT3(a, b) + b[3];
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_DST:         /* Distance vector */
-         {
-            GLfloat a[4], b[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            result[0] = 1.0F;
-            result[1] = a[1] * b[1];
-            result[2] = a[2];
-            result[3] = b[3];
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_EXP:
-         {
-            GLfloat t[4], q[4], floor_t0;
-            fetch_vector1(&inst->SrcReg[0], machine, t);
-            floor_t0 = FLOORF(t[0]);
-            if (floor_t0 > FLT_MAX_EXP) {
-               SET_POS_INFINITY(q[0]);
-               SET_POS_INFINITY(q[2]);
-            }
-            else if (floor_t0 < FLT_MIN_EXP) {
-               q[0] = 0.0F;
-               q[2] = 0.0F;
-            }
-            else {
-               q[0] = LDEXPF(1.0, (int) floor_t0);
-               /* Note: GL_NV_vertex_program expects 
-                * result.z = result.x * APPX(result.y)
-                * We do what the ARB extension says.
-                */
-               q[2] = (GLfloat) pow(2.0, t[0]);
-            }
-            q[1] = t[0] - floor_t0;
-            q[3] = 1.0F;
-            store_vector4( inst, machine, q );
-         }
-         break;
-      case OPCODE_EX2:         /* Exponential base 2 */
-         {
-            GLfloat a[4], result[4], val;
-            fetch_vector1(&inst->SrcReg[0], machine, a);
-            val = (GLfloat) pow(2.0, a[0]);
-            /*
-            if (IS_INF_OR_NAN(val))
-               val = 1.0e10;
-            */
-            result[0] = result[1] = result[2] = result[3] = val;
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_FLR:
-         {
-            GLfloat a[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            result[0] = FLOORF(a[0]);
-            result[1] = FLOORF(a[1]);
-            result[2] = FLOORF(a[2]);
-            result[3] = FLOORF(a[3]);
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_FRC:
-         {
-            GLfloat a[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            result[0] = a[0] - FLOORF(a[0]);
-            result[1] = a[1] - FLOORF(a[1]);
-            result[2] = a[2] - FLOORF(a[2]);
-            result[3] = a[3] - FLOORF(a[3]);
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_IF:
-         {
-            GLboolean cond;
-            ASSERT(program->Instructions[inst->BranchTarget].Opcode
-                   == OPCODE_ELSE ||
-                   program->Instructions[inst->BranchTarget].Opcode
-                   == OPCODE_ENDIF);
-            /* eval condition */
-            if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
-               GLfloat a[4];
-               fetch_vector1(&inst->SrcReg[0], machine, a);
-               cond = (a[0] != 0.0);
-            }
-            else {
-               cond = eval_condition(machine, inst);
-            }
-            if (DEBUG_PROG) {
-               printf("IF: %d\n", cond);
-            }
-            /* do if/else */
-            if (cond) {
-               /* do if-clause (just continue execution) */
-            }
-            else {
-               /* go to the instruction after ELSE or ENDIF */
-               assert(inst->BranchTarget >= 0);
-               pc = inst->BranchTarget;
-            }
-         }
-         break;
-      case OPCODE_ELSE:
-         /* goto ENDIF */
-         ASSERT(program->Instructions[inst->BranchTarget].Opcode
-                == OPCODE_ENDIF);
-         assert(inst->BranchTarget >= 0);
-         pc = inst->BranchTarget;
-         break;
-      case OPCODE_ENDIF:
-         /* nothing */
-         break;
-      case OPCODE_KIL_NV:      /* NV_f_p only (conditional) */
-         if (eval_condition(machine, inst)) {
-            return GL_FALSE;
-         }
-         break;
-      case OPCODE_KIL:         /* ARB_f_p only */
-         {
-            GLfloat a[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            if (DEBUG_PROG) {
-               printf("KIL if (%g %g %g %g) <= 0.0\n",
-                      a[0], a[1], a[2], a[3]);
-            }
-
-            if (a[0] < 0.0F || a[1] < 0.0F || a[2] < 0.0F || a[3] < 0.0F) {
-               return GL_FALSE;
-            }
-         }
-         break;
-      case OPCODE_LG2:         /* log base 2 */
-         {
-            GLfloat a[4], result[4], val;
-            fetch_vector1(&inst->SrcReg[0], machine, a);
-           /* The fast LOG2 macro doesn't meet the precision requirements.
-            */
-            if (a[0] == 0.0F) {
-               val = -FLT_MAX;
-            }
-            else {
-               val = (float)(log(a[0]) * 1.442695F);
-            }
-            result[0] = result[1] = result[2] = result[3] = val;
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_LIT:
-         {
-            const GLfloat epsilon = 1.0F / 256.0F;      /* from NV VP spec */
-            GLfloat a[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            a[0] = MAX2(a[0], 0.0F);
-            a[1] = MAX2(a[1], 0.0F);
-            /* XXX ARB version clamps a[3], NV version doesn't */
-            a[3] = CLAMP(a[3], -(128.0F - epsilon), (128.0F - epsilon));
-            result[0] = 1.0F;
-            result[1] = a[0];
-            /* XXX we could probably just use pow() here */
-            if (a[0] > 0.0F) {
-               if (a[1] == 0.0 && a[3] == 0.0)
-                  result[2] = 1.0F;
-               else
-                  result[2] = (GLfloat) pow(a[1], a[3]);
-            }
-            else {
-               result[2] = 0.0F;
-            }
-            result[3] = 1.0F;
-            store_vector4(inst, machine, result);
-            if (DEBUG_PROG) {
-               printf("LIT (%g %g %g %g) : (%g %g %g %g)\n",
-                      result[0], result[1], result[2], result[3],
-                      a[0], a[1], a[2], a[3]);
-            }
-         }
-         break;
-      case OPCODE_LOG:
-         {
-            GLfloat t[4], q[4], abs_t0;
-            fetch_vector1(&inst->SrcReg[0], machine, t);
-            abs_t0 = FABSF(t[0]);
-            if (abs_t0 != 0.0F) {
-               /* Since we really can't handle infinite values on VMS
-                * like other OSes we'll use __MAXFLOAT to represent
-                * infinity.  This may need some tweaking.
-                */
-#ifdef VMS
-               if (abs_t0 == __MAXFLOAT)
-#else
-               if (IS_INF_OR_NAN(abs_t0))
-#endif
-               {
-                  SET_POS_INFINITY(q[0]);
-                  q[1] = 1.0F;
-                  SET_POS_INFINITY(q[2]);
-               }
-               else {
-                  int exponent;
-                  GLfloat mantissa = FREXPF(t[0], &exponent);
-                  q[0] = (GLfloat) (exponent - 1);
-                  q[1] = (GLfloat) (2.0 * mantissa); /* map [.5, 1) -> [1, 2) */
-
-                 /* The fast LOG2 macro doesn't meet the precision
-                  * requirements.
-                  */
-                  q[2] = (float)(log(t[0]) * 1.442695F);
-               }
-            }
-            else {
-               SET_NEG_INFINITY(q[0]);
-               q[1] = 1.0F;
-               SET_NEG_INFINITY(q[2]);
-            }
-            q[3] = 1.0;
-            store_vector4(inst, machine, q);
-         }
-         break;
-      case OPCODE_LRP:
-         {
-            GLfloat a[4], b[4], c[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            fetch_vector4(&inst->SrcReg[2], machine, c);
-            result[0] = a[0] * b[0] + (1.0F - a[0]) * c[0];
-            result[1] = a[1] * b[1] + (1.0F - a[1]) * c[1];
-            result[2] = a[2] * b[2] + (1.0F - a[2]) * c[2];
-            result[3] = a[3] * b[3] + (1.0F - a[3]) * c[3];
-            store_vector4(inst, machine, result);
-            if (DEBUG_PROG) {
-               printf("LRP (%g %g %g %g) = (%g %g %g %g), "
-                      "(%g %g %g %g), (%g %g %g %g)\n",
-                      result[0], result[1], result[2], result[3],
-                      a[0], a[1], a[2], a[3],
-                      b[0], b[1], b[2], b[3], c[0], c[1], c[2], c[3]);
-            }
-         }
-         break;
-      case OPCODE_MAD:
-         {
-            GLfloat a[4], b[4], c[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            fetch_vector4(&inst->SrcReg[2], machine, c);
-            result[0] = a[0] * b[0] + c[0];
-            result[1] = a[1] * b[1] + c[1];
-            result[2] = a[2] * b[2] + c[2];
-            result[3] = a[3] * b[3] + c[3];
-            store_vector4(inst, machine, result);
-            if (DEBUG_PROG) {
-               printf("MAD (%g %g %g %g) = (%g %g %g %g) * "
-                      "(%g %g %g %g) + (%g %g %g %g)\n",
-                      result[0], result[1], result[2], result[3],
-                      a[0], a[1], a[2], a[3],
-                      b[0], b[1], b[2], b[3], c[0], c[1], c[2], c[3]);
-            }
-         }
-         break;
-      case OPCODE_MAX:
-         {
-            GLfloat a[4], b[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            result[0] = MAX2(a[0], b[0]);
-            result[1] = MAX2(a[1], b[1]);
-            result[2] = MAX2(a[2], b[2]);
-            result[3] = MAX2(a[3], b[3]);
-            store_vector4(inst, machine, result);
-            if (DEBUG_PROG) {
-               printf("MAX (%g %g %g %g) = (%g %g %g %g), (%g %g %g %g)\n",
-                      result[0], result[1], result[2], result[3],
-                      a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
-            }
-         }
-         break;
-      case OPCODE_MIN:
-         {
-            GLfloat a[4], b[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            result[0] = MIN2(a[0], b[0]);
-            result[1] = MIN2(a[1], b[1]);
-            result[2] = MIN2(a[2], b[2]);
-            result[3] = MIN2(a[3], b[3]);
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_MOV:
-         {
-            GLfloat result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, result);
-            store_vector4(inst, machine, result);
-            if (DEBUG_PROG) {
-               printf("MOV (%g %g %g %g)\n",
-                      result[0], result[1], result[2], result[3]);
-            }
-         }
-         break;
-      case OPCODE_MUL:
-         {
-            GLfloat a[4], b[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            result[0] = a[0] * b[0];
-            result[1] = a[1] * b[1];
-            result[2] = a[2] * b[2];
-            result[3] = a[3] * b[3];
-            store_vector4(inst, machine, result);
-            if (DEBUG_PROG) {
-               printf("MUL (%g %g %g %g) = (%g %g %g %g) * (%g %g %g %g)\n",
-                      result[0], result[1], result[2], result[3],
-                      a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
-            }
-         }
-         break;
-      case OPCODE_NOISE1:
-         {
-            GLfloat a[4], result[4];
-            fetch_vector1(&inst->SrcReg[0], machine, a);
-            result[0] =
-               result[1] =
-               result[2] =
-               result[3] = _mesa_noise1(a[0]);
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_NOISE2:
-         {
-            GLfloat a[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            result[0] =
-               result[1] =
-               result[2] = result[3] = _mesa_noise2(a[0], a[1]);
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_NOISE3:
-         {
-            GLfloat a[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            result[0] =
-               result[1] =
-               result[2] =
-               result[3] = _mesa_noise3(a[0], a[1], a[2]);
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_NOISE4:
-         {
-            GLfloat a[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            result[0] =
-               result[1] =
-               result[2] =
-               result[3] = _mesa_noise4(a[0], a[1], a[2], a[3]);
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_NOP:
-         break;
-      case OPCODE_NOT:         /* bitwise NOT */
-         {
-            GLuint a[4], result[4];
-            fetch_vector4ui(&inst->SrcReg[0], machine, a);
-            result[0] = ~a[0];
-            result[1] = ~a[1];
-            result[2] = ~a[2];
-            result[3] = ~a[3];
-            store_vector4ui(inst, machine, result);
-         }
-         break;
-      case OPCODE_NRM3:        /* 3-component normalization */
-         {
-            GLfloat a[4], result[4];
-            GLfloat tmp;
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            tmp = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
-            if (tmp != 0.0F)
-               tmp = INV_SQRTF(tmp);
-            result[0] = tmp * a[0];
-            result[1] = tmp * a[1];
-            result[2] = tmp * a[2];
-            result[3] = 0.0;  /* undefined, but prevent valgrind warnings */
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_NRM4:        /* 4-component normalization */
-         {
-            GLfloat a[4], result[4];
-            GLfloat tmp;
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            tmp = a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3];
-            if (tmp != 0.0F)
-               tmp = INV_SQRTF(tmp);
-            result[0] = tmp * a[0];
-            result[1] = tmp * a[1];
-            result[2] = tmp * a[2];
-            result[3] = tmp * a[3];
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_OR:          /* bitwise OR */
-         {
-            GLuint a[4], b[4], result[4];
-            fetch_vector4ui(&inst->SrcReg[0], machine, a);
-            fetch_vector4ui(&inst->SrcReg[1], machine, b);
-            result[0] = a[0] | b[0];
-            result[1] = a[1] | b[1];
-            result[2] = a[2] | b[2];
-            result[3] = a[3] | b[3];
-            store_vector4ui(inst, machine, result);
-         }
-         break;
-      case OPCODE_PK2H:        /* pack two 16-bit floats in one 32-bit float */
-         {
-            GLfloat a[4];
-            GLuint result[4];
-            GLhalfNV hx, hy;
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            hx = _mesa_float_to_half(a[0]);
-            hy = _mesa_float_to_half(a[1]);
-            result[0] =
-            result[1] =
-            result[2] =
-            result[3] = hx | (hy << 16);
-            store_vector4ui(inst, machine, result);
-         }
-         break;
-      case OPCODE_PK2US:       /* pack two GLushorts into one 32-bit float */
-         {
-            GLfloat a[4];
-            GLuint result[4], usx, usy;
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            a[0] = CLAMP(a[0], 0.0F, 1.0F);
-            a[1] = CLAMP(a[1], 0.0F, 1.0F);
-            usx = IROUND(a[0] * 65535.0F);
-            usy = IROUND(a[1] * 65535.0F);
-            result[0] =
-            result[1] =
-            result[2] =
-            result[3] = usx | (usy << 16);
-            store_vector4ui(inst, machine, result);
-         }
-         break;
-      case OPCODE_PK4B:        /* pack four GLbytes into one 32-bit float */
-         {
-            GLfloat a[4];
-            GLuint result[4], ubx, uby, ubz, ubw;
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            a[0] = CLAMP(a[0], -128.0F / 127.0F, 1.0F);
-            a[1] = CLAMP(a[1], -128.0F / 127.0F, 1.0F);
-            a[2] = CLAMP(a[2], -128.0F / 127.0F, 1.0F);
-            a[3] = CLAMP(a[3], -128.0F / 127.0F, 1.0F);
-            ubx = IROUND(127.0F * a[0] + 128.0F);
-            uby = IROUND(127.0F * a[1] + 128.0F);
-            ubz = IROUND(127.0F * a[2] + 128.0F);
-            ubw = IROUND(127.0F * a[3] + 128.0F);
-            result[0] =
-            result[1] =
-            result[2] =
-            result[3] = ubx | (uby << 8) | (ubz << 16) | (ubw << 24);
-            store_vector4ui(inst, machine, result);
-         }
-         break;
-      case OPCODE_PK4UB:       /* pack four GLubytes into one 32-bit float */
-         {
-            GLfloat a[4];
-            GLuint result[4], ubx, uby, ubz, ubw;
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            a[0] = CLAMP(a[0], 0.0F, 1.0F);
-            a[1] = CLAMP(a[1], 0.0F, 1.0F);
-            a[2] = CLAMP(a[2], 0.0F, 1.0F);
-            a[3] = CLAMP(a[3], 0.0F, 1.0F);
-            ubx = IROUND(255.0F * a[0]);
-            uby = IROUND(255.0F * a[1]);
-            ubz = IROUND(255.0F * a[2]);
-            ubw = IROUND(255.0F * a[3]);
-            result[0] =
-            result[1] =
-            result[2] =
-            result[3] = ubx | (uby << 8) | (ubz << 16) | (ubw << 24);
-            store_vector4ui(inst, machine, result);
-         }
-         break;
-      case OPCODE_POW:
-         {
-            GLfloat a[4], b[4], result[4];
-            fetch_vector1(&inst->SrcReg[0], machine, a);
-            fetch_vector1(&inst->SrcReg[1], machine, b);
-            result[0] = result[1] = result[2] = result[3]
-               = (GLfloat) pow(a[0], b[0]);
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_RCP:
-         {
-            GLfloat a[4], result[4];
-            fetch_vector1(&inst->SrcReg[0], machine, a);
-            if (DEBUG_PROG) {
-               if (a[0] == 0)
-                  printf("RCP(0)\n");
-               else if (IS_INF_OR_NAN(a[0]))
-                  printf("RCP(inf)\n");
-            }
-            result[0] = result[1] = result[2] = result[3] = 1.0F / a[0];
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_RET:         /* return from subroutine (conditional) */
-         if (eval_condition(machine, inst)) {
-            if (machine->StackDepth == 0) {
-               return GL_TRUE;  /* Per GL_NV_vertex_program2 spec */
-            }
-            /* subtract one because of pc++ in the for loop */
-            pc = machine->CallStack[--machine->StackDepth] - 1;
-         }
-         break;
-      case OPCODE_RFL:         /* reflection vector */
-         {
-            GLfloat axis[4], dir[4], result[4], tmpX, tmpW;
-            fetch_vector4(&inst->SrcReg[0], machine, axis);
-            fetch_vector4(&inst->SrcReg[1], machine, dir);
-            tmpW = DOT3(axis, axis);
-            tmpX = (2.0F * DOT3(axis, dir)) / tmpW;
-            result[0] = tmpX * axis[0] - dir[0];
-            result[1] = tmpX * axis[1] - dir[1];
-            result[2] = tmpX * axis[2] - dir[2];
-            /* result[3] is never written! XXX enforce in parser! */
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_RSQ:         /* 1 / sqrt() */
-         {
-            GLfloat a[4], result[4];
-            fetch_vector1(&inst->SrcReg[0], machine, a);
-            a[0] = FABSF(a[0]);
-            result[0] = result[1] = result[2] = result[3] = INV_SQRTF(a[0]);
-            store_vector4(inst, machine, result);
-            if (DEBUG_PROG) {
-               printf("RSQ %g = 1/sqrt(|%g|)\n", result[0], a[0]);
-            }
-         }
-         break;
-      case OPCODE_SCS:         /* sine and cos */
-         {
-            GLfloat a[4], result[4];
-            fetch_vector1(&inst->SrcReg[0], machine, a);
-            result[0] = (GLfloat) cos(a[0]);
-            result[1] = (GLfloat) sin(a[0]);
-            result[2] = 0.0;    /* undefined! */
-            result[3] = 0.0;    /* undefined! */
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_SEQ:         /* set on equal */
-         {
-            GLfloat a[4], b[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            result[0] = (a[0] == b[0]) ? 1.0F : 0.0F;
-            result[1] = (a[1] == b[1]) ? 1.0F : 0.0F;
-            result[2] = (a[2] == b[2]) ? 1.0F : 0.0F;
-            result[3] = (a[3] == b[3]) ? 1.0F : 0.0F;
-            store_vector4(inst, machine, result);
-            if (DEBUG_PROG) {
-               printf("SEQ (%g %g %g %g) = (%g %g %g %g) == (%g %g %g %g)\n",
-                      result[0], result[1], result[2], result[3],
-                      a[0], a[1], a[2], a[3],
-                      b[0], b[1], b[2], b[3]);
-            }
-         }
-         break;
-      case OPCODE_SFL:         /* set false, operands ignored */
-         {
-            static const GLfloat result[4] = { 0.0F, 0.0F, 0.0F, 0.0F };
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_SGE:         /* set on greater or equal */
-         {
-            GLfloat a[4], b[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            result[0] = (a[0] >= b[0]) ? 1.0F : 0.0F;
-            result[1] = (a[1] >= b[1]) ? 1.0F : 0.0F;
-            result[2] = (a[2] >= b[2]) ? 1.0F : 0.0F;
-            result[3] = (a[3] >= b[3]) ? 1.0F : 0.0F;
-            store_vector4(inst, machine, result);
-            if (DEBUG_PROG) {
-               printf("SGE (%g %g %g %g) = (%g %g %g %g) >= (%g %g %g %g)\n",
-                      result[0], result[1], result[2], result[3],
-                      a[0], a[1], a[2], a[3],
-                      b[0], b[1], b[2], b[3]);
-            }
-         }
-         break;
-      case OPCODE_SGT:         /* set on greater */
-         {
-            GLfloat a[4], b[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            result[0] = (a[0] > b[0]) ? 1.0F : 0.0F;
-            result[1] = (a[1] > b[1]) ? 1.0F : 0.0F;
-            result[2] = (a[2] > b[2]) ? 1.0F : 0.0F;
-            result[3] = (a[3] > b[3]) ? 1.0F : 0.0F;
-            store_vector4(inst, machine, result);
-            if (DEBUG_PROG) {
-               printf("SGT (%g %g %g %g) = (%g %g %g %g) > (%g %g %g %g)\n",
-                      result[0], result[1], result[2], result[3],
-                      a[0], a[1], a[2], a[3],
-                      b[0], b[1], b[2], b[3]);
-            }
-         }
-         break;
-      case OPCODE_SIN:
-         {
-            GLfloat a[4], result[4];
-            fetch_vector1(&inst->SrcReg[0], machine, a);
-            result[0] = result[1] = result[2] = result[3]
-               = (GLfloat) sin(a[0]);
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_SLE:         /* set on less or equal */
-         {
-            GLfloat a[4], b[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            result[0] = (a[0] <= b[0]) ? 1.0F : 0.0F;
-            result[1] = (a[1] <= b[1]) ? 1.0F : 0.0F;
-            result[2] = (a[2] <= b[2]) ? 1.0F : 0.0F;
-            result[3] = (a[3] <= b[3]) ? 1.0F : 0.0F;
-            store_vector4(inst, machine, result);
-            if (DEBUG_PROG) {
-               printf("SLE (%g %g %g %g) = (%g %g %g %g) <= (%g %g %g %g)\n",
-                      result[0], result[1], result[2], result[3],
-                      a[0], a[1], a[2], a[3],
-                      b[0], b[1], b[2], b[3]);
-            }
-         }
-         break;
-      case OPCODE_SLT:         /* set on less */
-         {
-            GLfloat a[4], b[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            result[0] = (a[0] < b[0]) ? 1.0F : 0.0F;
-            result[1] = (a[1] < b[1]) ? 1.0F : 0.0F;
-            result[2] = (a[2] < b[2]) ? 1.0F : 0.0F;
-            result[3] = (a[3] < b[3]) ? 1.0F : 0.0F;
-            store_vector4(inst, machine, result);
-            if (DEBUG_PROG) {
-               printf("SLT (%g %g %g %g) = (%g %g %g %g) < (%g %g %g %g)\n",
-                      result[0], result[1], result[2], result[3],
-                      a[0], a[1], a[2], a[3],
-                      b[0], b[1], b[2], b[3]);
-            }
-         }
-         break;
-      case OPCODE_SNE:         /* set on not equal */
-         {
-            GLfloat a[4], b[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            result[0] = (a[0] != b[0]) ? 1.0F : 0.0F;
-            result[1] = (a[1] != b[1]) ? 1.0F : 0.0F;
-            result[2] = (a[2] != b[2]) ? 1.0F : 0.0F;
-            result[3] = (a[3] != b[3]) ? 1.0F : 0.0F;
-            store_vector4(inst, machine, result);
-            if (DEBUG_PROG) {
-               printf("SNE (%g %g %g %g) = (%g %g %g %g) != (%g %g %g %g)\n",
-                      result[0], result[1], result[2], result[3],
-                      a[0], a[1], a[2], a[3],
-                      b[0], b[1], b[2], b[3]);
-            }
-         }
-         break;
-      case OPCODE_SSG:         /* set sign (-1, 0 or +1) */
-         {
-            GLfloat a[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            result[0] = (GLfloat) ((a[0] > 0.0F) - (a[0] < 0.0F));
-            result[1] = (GLfloat) ((a[1] > 0.0F) - (a[1] < 0.0F));
-            result[2] = (GLfloat) ((a[2] > 0.0F) - (a[2] < 0.0F));
-            result[3] = (GLfloat) ((a[3] > 0.0F) - (a[3] < 0.0F));
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_STR:         /* set true, operands ignored */
-         {
-            static const GLfloat result[4] = { 1.0F, 1.0F, 1.0F, 1.0F };
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_SUB:
-         {
-            GLfloat a[4], b[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            result[0] = a[0] - b[0];
-            result[1] = a[1] - b[1];
-            result[2] = a[2] - b[2];
-            result[3] = a[3] - b[3];
-            store_vector4(inst, machine, result);
-            if (DEBUG_PROG) {
-               printf("SUB (%g %g %g %g) = (%g %g %g %g) - (%g %g %g %g)\n",
-                      result[0], result[1], result[2], result[3],
-                      a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]);
-            }
-         }
-         break;
-      case OPCODE_SWZ:         /* extended swizzle */
-         {
-            const struct prog_src_register *source = &inst->SrcReg[0];
-            const GLfloat *src = get_src_register_pointer(source, machine);
-            GLfloat result[4];
-            GLuint i;
-            for (i = 0; i < 4; i++) {
-               const GLuint swz = GET_SWZ(source->Swizzle, i);
-               if (swz == SWIZZLE_ZERO)
-                  result[i] = 0.0;
-               else if (swz == SWIZZLE_ONE)
-                  result[i] = 1.0;
-               else {
-                  ASSERT(swz >= 0);
-                  ASSERT(swz <= 3);
-                  result[i] = src[swz];
-               }
-               if (source->Negate & (1 << i))
-                  result[i] = -result[i];
-            }
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_TEX:         /* Both ARB and NV frag prog */
-         /* Simple texel lookup */
-         {
-            GLfloat texcoord[4], color[4];
-            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
-
-            fetch_texel(ctx, machine, inst, texcoord, 0.0, color);
-
-            if (DEBUG_PROG) {
-               printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g]\n",
-                      color[0], color[1], color[2], color[3],
-                      inst->TexSrcUnit,
-                      texcoord[0], texcoord[1], texcoord[2], texcoord[3]);
-            }
-            store_vector4(inst, machine, color);
-         }
-         break;
-      case OPCODE_TXB:         /* GL_ARB_fragment_program only */
-         /* Texel lookup with LOD bias */
-         {
-            GLfloat texcoord[4], color[4], lodBias;
-
-            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
-
-            /* texcoord[3] is the bias to add to lambda */
-            lodBias = texcoord[3];
-
-            fetch_texel(ctx, machine, inst, texcoord, lodBias, color);
-
-            store_vector4(inst, machine, color);
-         }
-         break;
-      case OPCODE_TXD:         /* GL_NV_fragment_program only */
-         /* Texture lookup w/ partial derivatives for LOD */
-         {
-            GLfloat texcoord[4], dtdx[4], dtdy[4], color[4];
-            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
-            fetch_vector4(&inst->SrcReg[1], machine, dtdx);
-            fetch_vector4(&inst->SrcReg[2], machine, dtdy);
-            machine->FetchTexelDeriv(ctx, texcoord, dtdx, dtdy,
-                                     0.0, /* lodBias */
-                                     inst->TexSrcUnit, color);
-            store_vector4(inst, machine, color);
-         }
-         break;
-      case OPCODE_TXP:         /* GL_ARB_fragment_program only */
-         /* Texture lookup w/ projective divide */
-         {
-            GLfloat texcoord[4], color[4];
-
-            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
-            /* Not so sure about this test - if texcoord[3] is
-             * zero, we'd probably be fine except for an ASSERT in
-             * IROUND_POS() which gets triggered by the inf values created.
-             */
-            if (texcoord[3] != 0.0) {
-               texcoord[0] /= texcoord[3];
-               texcoord[1] /= texcoord[3];
-               texcoord[2] /= texcoord[3];
-            }
-
-            fetch_texel(ctx, machine, inst, texcoord, 0.0, color);
-
-            store_vector4(inst, machine, color);
-         }
-         break;
-      case OPCODE_TXP_NV:      /* GL_NV_fragment_program only */
-         /* Texture lookup w/ projective divide, as above, but do not
-          * do the divide by w if sampling from a cube map.
-          */
-         {
-            GLfloat texcoord[4], color[4];
-
-            fetch_vector4(&inst->SrcReg[0], machine, texcoord);
-            if (inst->TexSrcTarget != TEXTURE_CUBE_INDEX &&
-                texcoord[3] != 0.0) {
-               texcoord[0] /= texcoord[3];
-               texcoord[1] /= texcoord[3];
-               texcoord[2] /= texcoord[3];
-            }
-
-            fetch_texel(ctx, machine, inst, texcoord, 0.0, color);
-
-            store_vector4(inst, machine, color);
-         }
-         break;
-      case OPCODE_TRUNC:       /* truncate toward zero */
-         {
-            GLfloat a[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            result[0] = (GLfloat) (GLint) a[0];
-            result[1] = (GLfloat) (GLint) a[1];
-            result[2] = (GLfloat) (GLint) a[2];
-            result[3] = (GLfloat) (GLint) a[3];
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_UP2H:        /* unpack two 16-bit floats */
-         {
-            const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine);
-            GLfloat result[4];
-            GLushort hx, hy;
-            hx = raw & 0xffff;
-            hy = raw >> 16;
-            result[0] = result[2] = _mesa_half_to_float(hx);
-            result[1] = result[3] = _mesa_half_to_float(hy);
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_UP2US:       /* unpack two GLushorts */
-         {
-            const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine);
-            GLfloat result[4];
-            GLushort usx, usy;
-            usx = raw & 0xffff;
-            usy = raw >> 16;
-            result[0] = result[2] = usx * (1.0f / 65535.0f);
-            result[1] = result[3] = usy * (1.0f / 65535.0f);
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_UP4B:        /* unpack four GLbytes */
-         {
-            const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine);
-            GLfloat result[4];
-            result[0] = (((raw >> 0) & 0xff) - 128) / 127.0F;
-            result[1] = (((raw >> 8) & 0xff) - 128) / 127.0F;
-            result[2] = (((raw >> 16) & 0xff) - 128) / 127.0F;
-            result[3] = (((raw >> 24) & 0xff) - 128) / 127.0F;
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_UP4UB:       /* unpack four GLubytes */
-         {
-            const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine);
-            GLfloat result[4];
-            result[0] = ((raw >> 0) & 0xff) / 255.0F;
-            result[1] = ((raw >> 8) & 0xff) / 255.0F;
-            result[2] = ((raw >> 16) & 0xff) / 255.0F;
-            result[3] = ((raw >> 24) & 0xff) / 255.0F;
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_XOR:         /* bitwise XOR */
-         {
-            GLuint a[4], b[4], result[4];
-            fetch_vector4ui(&inst->SrcReg[0], machine, a);
-            fetch_vector4ui(&inst->SrcReg[1], machine, b);
-            result[0] = a[0] ^ b[0];
-            result[1] = a[1] ^ b[1];
-            result[2] = a[2] ^ b[2];
-            result[3] = a[3] ^ b[3];
-            store_vector4ui(inst, machine, result);
-         }
-         break;
-      case OPCODE_XPD:         /* cross product */
-         {
-            GLfloat a[4], b[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            result[0] = a[1] * b[2] - a[2] * b[1];
-            result[1] = a[2] * b[0] - a[0] * b[2];
-            result[2] = a[0] * b[1] - a[1] * b[0];
-            result[3] = 1.0;
-            store_vector4(inst, machine, result);
-            if (DEBUG_PROG) {
-               printf("XPD (%g %g %g %g) = (%g %g %g) X (%g %g %g)\n",
-                      result[0], result[1], result[2], result[3],
-                      a[0], a[1], a[2], b[0], b[1], b[2]);
-            }
-         }
-         break;
-      case OPCODE_X2D:         /* 2-D matrix transform */
-         {
-            GLfloat a[4], b[4], c[4], result[4];
-            fetch_vector4(&inst->SrcReg[0], machine, a);
-            fetch_vector4(&inst->SrcReg[1], machine, b);
-            fetch_vector4(&inst->SrcReg[2], machine, c);
-            result[0] = a[0] + b[0] * c[0] + b[1] * c[1];
-            result[1] = a[1] + b[0] * c[2] + b[1] * c[3];
-            result[2] = a[2] + b[0] * c[0] + b[1] * c[1];
-            result[3] = a[3] + b[0] * c[2] + b[1] * c[3];
-            store_vector4(inst, machine, result);
-         }
-         break;
-      case OPCODE_PRINT:
-         {
-            if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
-               GLfloat a[4];
-               fetch_vector4(&inst->SrcReg[0], machine, a);
-               printf("%s%g, %g, %g, %g\n", (const char *) inst->Data,
-                            a[0], a[1], a[2], a[3]);
-            }
-            else {
-               printf("%s\n", (const char *) inst->Data);
-            }
-         }
-         break;
-      case OPCODE_END:
-         return GL_TRUE;
-      default:
-         _mesa_problem(ctx, "Bad opcode %d in _mesa_execute_program",
-                       inst->Opcode);
-         return GL_TRUE;        /* return value doesn't matter */
-      }
-
-      numExec++;
-      if (numExec > maxExec) {
-        static GLboolean reported = GL_FALSE;
-        if (!reported) {
-           _mesa_problem(ctx, "Infinite loop detected in fragment program");
-           reported = GL_TRUE;
-        }
-         return GL_TRUE;
-      }
-
-   } /* for pc */
-
-   return GL_TRUE;
-}
diff --git a/src/mesa/shader/prog_execute.h b/src/mesa/shader/prog_execute.h
deleted file mode 100644 (file)
index adefc54..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.0.3
- *
- * 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.
- */
-
-#ifndef PROG_EXECUTE_H
-#define PROG_EXECUTE_H
-
-#include "main/config.h"
-
-
-typedef void (*FetchTexelLodFunc)(GLcontext *ctx, const GLfloat texcoord[4],
-                                  GLfloat lambda, GLuint unit, GLfloat color[4]);
-
-typedef void (*FetchTexelDerivFunc)(GLcontext *ctx, const GLfloat texcoord[4],
-                                    const GLfloat texdx[4],
-                                    const GLfloat texdy[4],
-                                    GLfloat lodBias,
-                                    GLuint unit, GLfloat color[4]);
-
-
-/**
- * Virtual machine state used during execution of vertex/fragment programs.
- */
-struct gl_program_machine
-{
-   const struct gl_program *CurProgram;
-
-   /** Fragment Input attributes */
-   GLfloat (*Attribs)[MAX_WIDTH][4];
-   GLfloat (*DerivX)[4];
-   GLfloat (*DerivY)[4];
-   GLuint NumDeriv; /**< Max index into DerivX/Y arrays */
-   GLuint CurElement; /**< Index into Attribs arrays */
-
-   /** Vertex Input attribs */
-   GLfloat VertAttribs[VERT_ATTRIB_MAX][4];
-
-   GLfloat Temporaries[MAX_PROGRAM_TEMPS][4];
-   GLfloat Outputs[MAX_PROGRAM_OUTPUTS][4];
-   GLfloat (*EnvParams)[4]; /**< Vertex or Fragment env parameters */
-   GLuint CondCodes[4];  /**< COND_* value for x/y/z/w */
-   GLint AddressReg[MAX_PROGRAM_ADDRESS_REGS][4];
-
-   const GLubyte *Samplers;  /** Array mapping sampler var to tex unit */
-
-   GLuint CallStack[MAX_PROGRAM_CALL_DEPTH]; /**< For CAL/RET instructions */
-   GLuint StackDepth; /**< Index/ptr to top of CallStack[] */
-
-   /** Texture fetch functions */
-   FetchTexelLodFunc FetchTexelLod;
-   FetchTexelDerivFunc FetchTexelDeriv;
-};
-
-
-extern void
-_mesa_get_program_register(GLcontext *ctx, gl_register_file file,
-                           GLuint index, GLfloat val[4]);
-
-extern GLboolean
-_mesa_execute_program(GLcontext *ctx,
-                      const struct gl_program *program,
-                      struct gl_program_machine *machine);
-
-
-#endif /* PROG_EXECUTE_H */
diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c
deleted file mode 100644 (file)
index 81099cb..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.3
- *
- * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
- * Copyright (C) 1999-2009  VMware, 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
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#include "main/glheader.h"
-#include "main/imports.h"
-#include "main/mtypes.h"
-#include "prog_instruction.h"
-
-
-/**
- * Initialize program instruction fields to defaults.
- * \param inst  first instruction to initialize
- * \param count  number of instructions to initialize
- */
-void
-_mesa_init_instructions(struct prog_instruction *inst, GLuint count)
-{
-   GLuint i;
-
-   memset(inst, 0, count * sizeof(struct prog_instruction));
-
-   for (i = 0; i < count; i++) {
-      inst[i].SrcReg[0].File = PROGRAM_UNDEFINED;
-      inst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP;
-      inst[i].SrcReg[1].File = PROGRAM_UNDEFINED;
-      inst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP;
-      inst[i].SrcReg[2].File = PROGRAM_UNDEFINED;
-      inst[i].SrcReg[2].Swizzle = SWIZZLE_NOOP;
-
-      inst[i].DstReg.File = PROGRAM_UNDEFINED;
-      inst[i].DstReg.WriteMask = WRITEMASK_XYZW;
-      inst[i].DstReg.CondMask = COND_TR;
-      inst[i].DstReg.CondSwizzle = SWIZZLE_NOOP;
-
-      inst[i].SaturateMode = SATURATE_OFF;
-      inst[i].Precision = FLOAT32;
-   }
-}
-
-
-/**
- * Allocate an array of program instructions.
- * \param numInst  number of instructions
- * \return pointer to instruction memory
- */
-struct prog_instruction *
-_mesa_alloc_instructions(GLuint numInst)
-{
-   return (struct prog_instruction *)
-      calloc(1, numInst * sizeof(struct prog_instruction));
-}
-
-
-/**
- * Reallocate memory storing an array of program instructions.
- * This is used when we need to append additional instructions onto an
- * program.
- * \param oldInst  pointer to first of old/src instructions
- * \param numOldInst  number of instructions at <oldInst>
- * \param numNewInst  desired size of new instruction array.
- * \return  pointer to start of new instruction array.
- */
-struct prog_instruction *
-_mesa_realloc_instructions(struct prog_instruction *oldInst,
-                           GLuint numOldInst, GLuint numNewInst)
-{
-   struct prog_instruction *newInst;
-
-   newInst = (struct prog_instruction *)
-      _mesa_realloc(oldInst,
-                    numOldInst * sizeof(struct prog_instruction),
-                    numNewInst * sizeof(struct prog_instruction));
-
-   return newInst;
-}
-
-
-/**
- * Copy an array of program instructions.
- * \param dest  pointer to destination.
- * \param src  pointer to source.
- * \param n  number of instructions to copy.
- * \return pointer to destination.
- */
-struct prog_instruction *
-_mesa_copy_instructions(struct prog_instruction *dest,
-                        const struct prog_instruction *src, GLuint n)
-{
-   GLuint i;
-   memcpy(dest, src, n * sizeof(struct prog_instruction));
-   for (i = 0; i < n; i++) {
-      if (src[i].Comment)
-         dest[i].Comment = _mesa_strdup(src[i].Comment);
-   }
-   return dest;
-}
-
-
-/**
- * Free an array of instructions
- */
-void
-_mesa_free_instructions(struct prog_instruction *inst, GLuint count)
-{
-   GLuint i;
-   for (i = 0; i < count; i++) {
-      if (inst[i].Data)
-         free(inst[i].Data);
-      if (inst[i].Comment)
-         free((char *) inst[i].Comment);
-   }
-   free(inst);
-}
-
-
-/**
- * Basic info about each instruction
- */
-struct instruction_info
-{
-   gl_inst_opcode Opcode;
-   const char *Name;
-   GLuint NumSrcRegs;
-   GLuint NumDstRegs;
-};
-
-/**
- * Instruction info
- * \note Opcode should equal array index!
- */
-static const struct instruction_info InstInfo[MAX_OPCODE] = {
-   { OPCODE_NOP,    "NOP",     0, 0 },
-   { OPCODE_ABS,    "ABS",     1, 1 },
-   { OPCODE_ADD,    "ADD",     2, 1 },
-   { OPCODE_AND,    "AND",     2, 1 },
-   { OPCODE_ARA,    "ARA",     1, 1 },
-   { OPCODE_ARL,    "ARL",     1, 1 },
-   { OPCODE_ARL_NV, "ARL_NV",  1, 1 },
-   { OPCODE_ARR,    "ARL",     1, 1 },
-   { OPCODE_BGNLOOP,"BGNLOOP", 0, 0 },
-   { OPCODE_BGNSUB, "BGNSUB",  0, 0 },
-   { OPCODE_BRA,    "BRA",     0, 0 },
-   { OPCODE_BRK,    "BRK",     0, 0 },
-   { OPCODE_CAL,    "CAL",     0, 0 },
-   { OPCODE_CMP,    "CMP",     3, 1 },
-   { OPCODE_CONT,   "CONT",    0, 0 },
-   { OPCODE_COS,    "COS",     1, 1 },
-   { OPCODE_DDX,    "DDX",     1, 1 },
-   { OPCODE_DDY,    "DDY",     1, 1 },
-   { OPCODE_DP2,    "DP2",     2, 1 },
-   { OPCODE_DP2A,   "DP2A",    3, 1 },
-   { OPCODE_DP3,    "DP3",     2, 1 },
-   { OPCODE_DP4,    "DP4",     2, 1 },
-   { OPCODE_DPH,    "DPH",     2, 1 },
-   { OPCODE_DST,    "DST",     2, 1 },
-   { OPCODE_ELSE,   "ELSE",    0, 0 },
-   { OPCODE_END,    "END",     0, 0 },
-   { OPCODE_ENDIF,  "ENDIF",   0, 0 },
-   { OPCODE_ENDLOOP,"ENDLOOP", 0, 0 },
-   { OPCODE_ENDSUB, "ENDSUB",  0, 0 },
-   { OPCODE_EX2,    "EX2",     1, 1 },
-   { OPCODE_EXP,    "EXP",     1, 1 },
-   { OPCODE_FLR,    "FLR",     1, 1 },
-   { OPCODE_FRC,    "FRC",     1, 1 },
-   { OPCODE_IF,     "IF",      1, 0 },
-   { OPCODE_KIL,    "KIL",     1, 0 },
-   { OPCODE_KIL_NV, "KIL_NV",  0, 0 },
-   { OPCODE_LG2,    "LG2",     1, 1 },
-   { OPCODE_LIT,    "LIT",     1, 1 },
-   { OPCODE_LOG,    "LOG",     1, 1 },
-   { OPCODE_LRP,    "LRP",     3, 1 },
-   { OPCODE_MAD,    "MAD",     3, 1 },
-   { OPCODE_MAX,    "MAX",     2, 1 },
-   { OPCODE_MIN,    "MIN",     2, 1 },
-   { OPCODE_MOV,    "MOV",     1, 1 },
-   { OPCODE_MUL,    "MUL",     2, 1 },
-   { OPCODE_NOISE1, "NOISE1",  1, 1 },
-   { OPCODE_NOISE2, "NOISE2",  1, 1 },
-   { OPCODE_NOISE3, "NOISE3",  1, 1 },
-   { OPCODE_NOISE4, "NOISE4",  1, 1 },
-   { OPCODE_NOT,    "NOT",     1, 1 },
-   { OPCODE_NRM3,   "NRM3",    1, 1 },
-   { OPCODE_NRM4,   "NRM4",    1, 1 },
-   { OPCODE_OR,     "OR",      2, 1 },
-   { OPCODE_PK2H,   "PK2H",    1, 1 },
-   { OPCODE_PK2US,  "PK2US",   1, 1 },
-   { OPCODE_PK4B,   "PK4B",    1, 1 },
-   { OPCODE_PK4UB,  "PK4UB",   1, 1 },
-   { OPCODE_POW,    "POW",     2, 1 },
-   { OPCODE_POPA,   "POPA",    0, 0 },
-   { OPCODE_PRINT,  "PRINT",   1, 0 },
-   { OPCODE_PUSHA,  "PUSHA",   0, 0 },
-   { OPCODE_RCC,    "RCC",     1, 1 },
-   { OPCODE_RCP,    "RCP",     1, 1 },
-   { OPCODE_RET,    "RET",     0, 0 },
-   { OPCODE_RFL,    "RFL",     1, 1 },
-   { OPCODE_RSQ,    "RSQ",     1, 1 },
-   { OPCODE_SCS,    "SCS",     1, 1 },
-   { OPCODE_SEQ,    "SEQ",     2, 1 },
-   { OPCODE_SFL,    "SFL",     0, 1 },
-   { OPCODE_SGE,    "SGE",     2, 1 },
-   { OPCODE_SGT,    "SGT",     2, 1 },
-   { OPCODE_SIN,    "SIN",     1, 1 },
-   { OPCODE_SLE,    "SLE",     2, 1 },
-   { OPCODE_SLT,    "SLT",     2, 1 },
-   { OPCODE_SNE,    "SNE",     2, 1 },
-   { OPCODE_SSG,    "SSG",     1, 1 },
-   { OPCODE_STR,    "STR",     0, 1 },
-   { OPCODE_SUB,    "SUB",     2, 1 },
-   { OPCODE_SWZ,    "SWZ",     1, 1 },
-   { OPCODE_TEX,    "TEX",     1, 1 },
-   { OPCODE_TXB,    "TXB",     1, 1 },
-   { OPCODE_TXD,    "TXD",     3, 1 },
-   { OPCODE_TXL,    "TXL",     1, 1 },
-   { OPCODE_TXP,    "TXP",     1, 1 },
-   { OPCODE_TXP_NV, "TXP_NV",  1, 1 },
-   { OPCODE_TRUNC,  "TRUNC",   1, 1 },
-   { OPCODE_UP2H,   "UP2H",    1, 1 },
-   { OPCODE_UP2US,  "UP2US",   1, 1 },
-   { OPCODE_UP4B,   "UP4B",    1, 1 },
-   { OPCODE_UP4UB,  "UP4UB",   1, 1 },
-   { OPCODE_X2D,    "X2D",     3, 1 },
-   { OPCODE_XOR,    "XOR",     2, 1 },
-   { OPCODE_XPD,    "XPD",     2, 1 }
-};
-
-
-/**
- * Return the number of src registers for the given instruction/opcode.
- */
-GLuint
-_mesa_num_inst_src_regs(gl_inst_opcode opcode)
-{
-   ASSERT(opcode < MAX_OPCODE);
-   ASSERT(opcode == InstInfo[opcode].Opcode);
-   ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode);
-   return InstInfo[opcode].NumSrcRegs;
-}
-
-
-/**
- * Return the number of dst registers for the given instruction/opcode.
- */
-GLuint
-_mesa_num_inst_dst_regs(gl_inst_opcode opcode)
-{
-   ASSERT(opcode < MAX_OPCODE);
-   ASSERT(opcode == InstInfo[opcode].Opcode);
-   ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode);
-   return InstInfo[opcode].NumDstRegs;
-}
-
-
-GLboolean
-_mesa_is_tex_instruction(gl_inst_opcode opcode)
-{
-   return (opcode == OPCODE_TEX ||
-           opcode == OPCODE_TXB ||
-           opcode == OPCODE_TXD ||
-           opcode == OPCODE_TXL ||
-           opcode == OPCODE_TXP);
-}
-
-
-/**
- * Check if there's a potential src/dst register data dependency when
- * using SOA execution.
- * Example:
- *   MOV T, T.yxwz;
- * This would expand into:
- *   MOV t0, t1;
- *   MOV t1, t0;
- *   MOV t2, t3;
- *   MOV t3, t2;
- * The second instruction will have the wrong value for t0 if executed as-is.
- */
-GLboolean
-_mesa_check_soa_dependencies(const struct prog_instruction *inst)
-{
-   GLuint i, chan;
-
-   if (inst->DstReg.WriteMask == WRITEMASK_X ||
-       inst->DstReg.WriteMask == WRITEMASK_Y ||
-       inst->DstReg.WriteMask == WRITEMASK_Z ||
-       inst->DstReg.WriteMask == WRITEMASK_W ||
-       inst->DstReg.WriteMask == 0x0) {
-      /* no chance of data dependency */
-      return GL_FALSE;
-   }
-
-   /* loop over src regs */
-   for (i = 0; i < 3; i++) {
-      if (inst->SrcReg[i].File == inst->DstReg.File &&
-          inst->SrcReg[i].Index == inst->DstReg.Index) {
-         /* loop over dest channels */
-         GLuint channelsWritten = 0x0;
-         for (chan = 0; chan < 4; chan++) {
-            if (inst->DstReg.WriteMask & (1 << chan)) {
-               /* check if we're reading a channel that's been written */
-               GLuint swizzle = GET_SWZ(inst->SrcReg[i].Swizzle, chan);
-               if (swizzle <= SWIZZLE_W &&
-                   (channelsWritten & (1 << swizzle))) {
-                  return GL_TRUE;
-               }
-
-               channelsWritten |= (1 << chan);
-            }
-         }
-      }
-   }
-   return GL_FALSE;
-}
-
-
-/**
- * Return string name for given program opcode.
- */
-const char *
-_mesa_opcode_string(gl_inst_opcode opcode)
-{
-   if (opcode < MAX_OPCODE)
-      return InstInfo[opcode].Name;
-   else {
-      static char s[20];
-      _mesa_snprintf(s, sizeof(s), "OP%u", opcode);
-      return s;
-   }
-}
-
diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h
deleted file mode 100644 (file)
index c1e3a1e..0000000
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.3
- *
- * Copyright (C) 1999-2008  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 prog_instruction.h
- *
- * Vertex/fragment program instruction datatypes and constants.
- *
- * \author Brian Paul
- * \author Keith Whitwell
- * \author Ian Romanick <idr@us.ibm.com>
- */
-
-
-#ifndef PROG_INSTRUCTION_H
-#define PROG_INSTRUCTION_H
-
-
-#include "main/mfeatures.h"
-
-
-/**
- * Swizzle indexes.
- * Do not change!
- */
-/*@{*/
-#define SWIZZLE_X    0
-#define SWIZZLE_Y    1
-#define SWIZZLE_Z    2
-#define SWIZZLE_W    3
-#define SWIZZLE_ZERO 4   /**< For SWZ instruction only */
-#define SWIZZLE_ONE  5   /**< For SWZ instruction only */
-#define SWIZZLE_NIL  7   /**< used during shader code gen (undefined value) */
-/*@}*/
-
-#define MAKE_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<3) | ((c)<<6) | ((d)<<9))
-#define SWIZZLE_NOOP           MAKE_SWIZZLE4(0,1,2,3)
-#define GET_SWZ(swz, idx)      (((swz) >> ((idx)*3)) & 0x7)
-#define GET_BIT(msk, idx)      (((msk) >> (idx)) & 0x1)
-
-#define SWIZZLE_XYZW MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W)
-#define SWIZZLE_XXXX MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X)
-#define SWIZZLE_YYYY MAKE_SWIZZLE4(SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y)
-#define SWIZZLE_ZZZZ MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z)
-#define SWIZZLE_WWWW MAKE_SWIZZLE4(SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W)
-
-
-/**
- * Writemask values, 1 bit per component.
- */
-/*@{*/
-#define WRITEMASK_X     0x1
-#define WRITEMASK_Y     0x2
-#define WRITEMASK_XY    0x3
-#define WRITEMASK_Z     0x4
-#define WRITEMASK_XZ    0x5
-#define WRITEMASK_YZ    0x6
-#define WRITEMASK_XYZ   0x7
-#define WRITEMASK_W     0x8
-#define WRITEMASK_XW    0x9
-#define WRITEMASK_YW    0xa
-#define WRITEMASK_XYW   0xb
-#define WRITEMASK_ZW    0xc
-#define WRITEMASK_XZW   0xd
-#define WRITEMASK_YZW   0xe
-#define WRITEMASK_XYZW  0xf
-/*@}*/
-
-
-/**
- * Condition codes
- */
-/*@{*/
-#define COND_GT  1  /**< greater than zero */
-#define COND_EQ  2  /**< equal to zero */
-#define COND_LT  3  /**< less than zero */
-#define COND_UN  4  /**< unordered (NaN) */
-#define COND_GE  5  /**< greater than or equal to zero */
-#define COND_LE  6  /**< less than or equal to zero */
-#define COND_NE  7  /**< not equal to zero */
-#define COND_TR  8  /**< always true */
-#define COND_FL  9  /**< always false */
-/*@}*/
-
-
-/**
- * Instruction precision for GL_NV_fragment_program
- */
-/*@{*/
-#define FLOAT32  0x1
-#define FLOAT16  0x2
-#define FIXED12  0x4
-/*@}*/
-
-
-/**
- * Saturation modes when storing values.
- */
-/*@{*/
-#define SATURATE_OFF            0
-#define SATURATE_ZERO_ONE       1
-/*@}*/
-
-
-/**
- * Per-component negation masks
- */
-/*@{*/
-#define NEGATE_X    0x1
-#define NEGATE_Y    0x2
-#define NEGATE_Z    0x4
-#define NEGATE_W    0x8
-#define NEGATE_XYZ  0x7
-#define NEGATE_XYZW 0xf
-#define NEGATE_NONE 0x0
-/*@}*/
-
-
-/**
- * Program instruction opcodes, for both vertex and fragment programs.
- * \note changes to this opcode list must be reflected in t_vb_arbprogram.c
- */
-typedef enum prog_opcode {
-                     /* ARB_vp   ARB_fp   NV_vp   NV_fp     GLSL */
-                     /*------------------------------------------*/
-   OPCODE_NOP = 0,   /*                                      X   */
-   OPCODE_ABS,       /*   X        X       1.1               X   */
-   OPCODE_ADD,       /*   X        X       X       X         X   */
-   OPCODE_AND,       /*                                          */
-   OPCODE_ARA,       /*                    2                     */
-   OPCODE_ARL,       /*   X                X                     */
-   OPCODE_ARL_NV,    /*                    2                     */
-   OPCODE_ARR,       /*                    2                     */
-   OPCODE_BGNLOOP,   /*                                     opt  */
-   OPCODE_BGNSUB,    /*                                     opt  */
-   OPCODE_BRA,       /*                    2                 X   */
-   OPCODE_BRK,       /*                    2                opt  */
-   OPCODE_CAL,       /*                    2       2             */
-   OPCODE_CMP,       /*            X                             */
-   OPCODE_CONT,      /*                                     opt  */
-   OPCODE_COS,       /*            X       2       X         X   */
-   OPCODE_DDX,       /*                            X         X   */
-   OPCODE_DDY,       /*                            X         X   */
-   OPCODE_DP2,       /*                            2             */
-   OPCODE_DP2A,      /*                            2             */
-   OPCODE_DP3,       /*   X        X       X       X         X   */
-   OPCODE_DP4,       /*   X        X       X       X         X   */
-   OPCODE_DPH,       /*   X        X       1.1                   */
-   OPCODE_DST,       /*   X        X       X       X             */
-   OPCODE_ELSE,      /*                                      X   */
-   OPCODE_END,       /*   X        X       X       X        opt  */
-   OPCODE_ENDIF,     /*                                     opt  */
-   OPCODE_ENDLOOP,   /*                                     opt  */
-   OPCODE_ENDSUB,    /*                                     opt  */
-   OPCODE_EX2,       /*   X        X       2       X         X   */
-   OPCODE_EXP,       /*   X                X                 X   */
-   OPCODE_FLR,       /*   X        X       2       X         X   */
-   OPCODE_FRC,       /*   X        X       2       X         X   */
-   OPCODE_IF,        /*                                     opt  */
-   OPCODE_KIL,       /*            X                             */
-   OPCODE_KIL_NV,    /*                            X         X   */
-   OPCODE_LG2,       /*   X        X       2       X         X   */
-   OPCODE_LIT,       /*   X        X       X       X             */
-   OPCODE_LOG,       /*   X                X                 X   */
-   OPCODE_LRP,       /*            X               X             */
-   OPCODE_MAD,       /*   X        X       X       X         X   */
-   OPCODE_MAX,       /*   X        X       X       X         X   */
-   OPCODE_MIN,       /*   X        X       X       X         X   */
-   OPCODE_MOV,       /*   X        X       X       X         X   */
-   OPCODE_MUL,       /*   X        X       X       X         X   */
-   OPCODE_NOISE1,    /*                                      X   */
-   OPCODE_NOISE2,    /*                                      X   */
-   OPCODE_NOISE3,    /*                                      X   */
-   OPCODE_NOISE4,    /*                                      X   */
-   OPCODE_NOT,       /*                                          */
-   OPCODE_NRM3,      /*                                          */
-   OPCODE_NRM4,      /*                                          */
-   OPCODE_OR,        /*                                          */
-   OPCODE_PK2H,      /*                            X             */
-   OPCODE_PK2US,     /*                            X             */
-   OPCODE_PK4B,      /*                            X             */
-   OPCODE_PK4UB,     /*                            X             */
-   OPCODE_POW,       /*   X        X               X         X   */
-   OPCODE_POPA,      /*                    3                     */
-   OPCODE_PRINT,     /*                    X       X             */
-   OPCODE_PUSHA,     /*                    3                     */
-   OPCODE_RCC,       /*                    1.1                   */
-   OPCODE_RCP,       /*   X        X       X       X         X   */
-   OPCODE_RET,       /*                    2       2             */
-   OPCODE_RFL,       /*            X               X             */
-   OPCODE_RSQ,       /*   X        X       X       X         X   */
-   OPCODE_SCS,       /*            X                             */
-   OPCODE_SEQ,       /*                    2       X         X   */
-   OPCODE_SFL,       /*                    2       X             */
-   OPCODE_SGE,       /*   X        X       X       X         X   */
-   OPCODE_SGT,       /*                    2       X         X   */
-   OPCODE_SIN,       /*            X       2       X         X   */
-   OPCODE_SLE,       /*                    2       X         X   */
-   OPCODE_SLT,       /*   X        X       X       X         X   */
-   OPCODE_SNE,       /*                    2       X         X   */
-   OPCODE_SSG,       /*                    2                     */
-   OPCODE_STR,       /*                    2       X             */
-   OPCODE_SUB,       /*   X        X       1.1     X         X   */
-   OPCODE_SWZ,       /*   X        X                             */
-   OPCODE_TEX,       /*            X       3       X         X   */
-   OPCODE_TXB,       /*            X       3                 X   */
-   OPCODE_TXD,       /*                            X         X   */
-   OPCODE_TXL,       /*                    3       2         X   */
-   OPCODE_TXP,       /*            X                         X   */
-   OPCODE_TXP_NV,    /*                    3       X             */
-   OPCODE_TRUNC,     /*                                      X   */
-   OPCODE_UP2H,      /*                            X             */
-   OPCODE_UP2US,     /*                            X             */
-   OPCODE_UP4B,      /*                            X             */
-   OPCODE_UP4UB,     /*                            X             */
-   OPCODE_X2D,       /*                            X             */
-   OPCODE_XOR,       /*                                          */
-   OPCODE_XPD,       /*   X        X                         X   */
-   MAX_OPCODE
-} gl_inst_opcode;
-
-
-/**
- * Number of bits for the src/dst register Index field.
- * This limits the size of temp/uniform register files.
- */
-#define INST_INDEX_BITS 10
-
-
-/**
- * Instruction source register.
- */
-struct prog_src_register
-{
-   GLuint File:4;      /**< One of the PROGRAM_* register file values. */
-   GLint Index:(INST_INDEX_BITS+1); /**< Extra bit here for sign bit.
-                                     * May be negative for relative addressing.
-                                     */
-   GLuint Swizzle:12;
-   GLuint RelAddr:1;
-
-   /** Take the component-wise absolute value */
-   GLuint Abs:1;
-
-   /**
-    * Post-Abs negation.
-    * This will either be NEGATE_NONE or NEGATE_XYZW, except for the SWZ
-    * instruction which allows per-component negation.
-    */
-   GLuint Negate:4;
-};
-
-
-/**
- * Instruction destination register.
- */
-struct prog_dst_register
-{
-   GLuint File:4;      /**< One of the PROGRAM_* register file values */
-   GLuint Index:INST_INDEX_BITS;  /**< Unsigned, never negative */
-   GLuint WriteMask:4;
-   GLuint RelAddr:1;
-
-   /**
-    * \name Conditional destination update control.
-    *
-    * \since
-    * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
-    * NV_vertex_program2_option.
-    */
-   /*@{*/
-   /**
-    * Takes one of the 9 possible condition values (EQ, FL, GT, GE, LE, LT,
-    * NE, TR, or UN).  Dest reg is only written to if the matching
-    * (swizzled) condition code value passes.  When a conditional update mask
-    * is not specified, this will be \c COND_TR.
-    */
-   GLuint CondMask:4;
-
-   /**
-    * Condition code swizzle value.
-    */
-   GLuint CondSwizzle:12;
-
-   /**
-    * Selects the condition code register to use for conditional destination
-    * update masking.  In NV_fragmnet_program or NV_vertex_program2 mode, only
-    * condition code register 0 is available.  In NV_vertex_program3 mode,
-    * condition code registers 0 and 1 are available.
-    */
-   GLuint CondSrc:1;
-   /*@}*/
-};
-
-
-/**
- * Vertex/fragment program instruction.
- */
-struct prog_instruction
-{
-   gl_inst_opcode Opcode;
-   struct prog_src_register SrcReg[3];
-   struct prog_dst_register DstReg;
-
-   /**
-    * Indicates that the instruction should update the condition code
-    * register.
-    *
-    * \since
-    * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
-    * NV_vertex_program2_option.
-    */
-   GLuint CondUpdate:1;
-
-   /**
-    * If prog_instruction::CondUpdate is \c GL_TRUE, this value selects the
-    * condition code register that is to be updated.
-    *
-    * In GL_NV_fragment_program or GL_NV_vertex_program2 mode, only condition
-    * code register 0 is available.  In GL_NV_vertex_program3 mode, condition
-    * code registers 0 and 1 are available.
-    *
-    * \since
-    * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
-    * NV_vertex_program2_option.
-    */
-   GLuint CondDst:1;
-
-   /**
-    * Saturate each value of the vectored result to the range [0,1] or the
-    * range [-1,1].  \c SSAT mode (i.e., saturation to the range [-1,1]) is
-    * only available in NV_fragment_program2 mode.
-    * Value is one of the SATURATE_* tokens.
-    *
-    * \since
-    * NV_fragment_program, NV_fragment_program_option, NV_vertex_program3.
-    */
-   GLuint SaturateMode:2;
-
-   /**
-    * Per-instruction selectable precision: FLOAT32, FLOAT16, FIXED12.
-    *
-    * \since
-    * NV_fragment_program, NV_fragment_program_option.
-    */
-   GLuint Precision:3;
-
-   /**
-    * \name Extra fields for TEX, TXB, TXD, TXL, TXP instructions.
-    */
-   /*@{*/
-   /** Source texture unit. */
-   GLuint TexSrcUnit:5;
-
-   /** Source texture target, one of TEXTURE_{1D,2D,3D,CUBE,RECT}_INDEX */
-   GLuint TexSrcTarget:3;
-
-   /** True if tex instruction should do shadow comparison */
-   GLuint TexShadow:1;
-   /*@}*/
-
-   /**
-    * For BRA and CAL instructions, the location to jump to.
-    * For BGNLOOP, points to ENDLOOP (and vice-versa).
-    * For BRK, points to ENDLOOP
-    * For IF, points to ELSE or ENDIF.
-    * For ELSE, points to ENDIF.
-    */
-   GLint BranchTarget;
-
-   /** for debugging purposes */
-   const char *Comment;
-
-   /** Arbitrary data.  Used for OPCODE_PRINT and some drivers */
-   void *Data;
-
-   /** for driver use (try to remove someday) */
-   GLint Aux;
-};
-
-
-extern void
-_mesa_init_instructions(struct prog_instruction *inst, GLuint count);
-
-extern struct prog_instruction *
-_mesa_alloc_instructions(GLuint numInst);
-
-extern struct prog_instruction *
-_mesa_realloc_instructions(struct prog_instruction *oldInst,
-                           GLuint numOldInst, GLuint numNewInst);
-
-extern struct prog_instruction *
-_mesa_copy_instructions(struct prog_instruction *dest,
-                        const struct prog_instruction *src, GLuint n);
-
-extern void
-_mesa_free_instructions(struct prog_instruction *inst, GLuint count);
-
-extern GLuint
-_mesa_num_inst_src_regs(gl_inst_opcode opcode);
-
-extern GLuint
-_mesa_num_inst_dst_regs(gl_inst_opcode opcode);
-
-extern GLboolean
-_mesa_is_tex_instruction(gl_inst_opcode opcode);
-
-extern GLboolean
-_mesa_check_soa_dependencies(const struct prog_instruction *inst);
-
-extern const char *
-_mesa_opcode_string(gl_inst_opcode opcode);
-
-
-#endif /* PROG_INSTRUCTION_H */
diff --git a/src/mesa/shader/prog_noise.c b/src/mesa/shader/prog_noise.c
deleted file mode 100644 (file)
index 1713ddb..0000000
+++ /dev/null
@@ -1,638 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5
- *
- * Copyright (C) 2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/*
- * SimplexNoise1234
- * Copyright (c) 2003-2005, Stefan Gustavson
- *
- * Contact: stegu@itn.liu.se
- */
-
-/**
- * \file
- * \brief C implementation of Perlin Simplex Noise over 1, 2, 3 and 4 dims.
- * \author Stefan Gustavson (stegu@itn.liu.se)
- *
- *
- * This implementation is "Simplex Noise" as presented by
- * Ken Perlin at a relatively obscure and not often cited course
- * session "Real-Time Shading" at Siggraph 2001 (before real
- * time shading actually took on), under the title "hardware noise".
- * The 3D function is numerically equivalent to his Java reference
- * code available in the PDF course notes, although I re-implemented
- * it from scratch to get more readable code. The 1D, 2D and 4D cases
- * were implemented from scratch by me from Ken Perlin's text.
- *
- * This file has no dependencies on any other file, not even its own
- * header file. The header file is made for use by external code only.
- */
-
-
-#include "main/imports.h"
-#include "prog_noise.h"
-
-#define FASTFLOOR(x) ( ((x)>0) ? ((int)x) : (((int)x)-1) )
-
-/*
- * ---------------------------------------------------------------------
- * Static data
- */
-
-/**
- * Permutation table. This is just a random jumble of all numbers 0-255,
- * repeated twice to avoid wrapping the index at 255 for each lookup.
- * This needs to be exactly the same for all instances on all platforms,
- * so it's easiest to just keep it as static explicit data.
- * This also removes the need for any initialisation of this class.
- *
- * Note that making this an int[] instead of a char[] might make the
- * code run faster on platforms with a high penalty for unaligned single
- * byte addressing. Intel x86 is generally single-byte-friendly, but
- * some other CPUs are faster with 4-aligned reads.
- * However, a char[] is smaller, which avoids cache trashing, and that
- * is probably the most important aspect on most architectures.
- * This array is accessed a *lot* by the noise functions.
- * A vector-valued noise over 3D accesses it 96 times, and a
- * float-valued 4D noise 64 times. We want this to fit in the cache!
- */
-unsigned char perm[512] = { 151, 160, 137, 91, 90, 15,
-   131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8,
-      99, 37, 240, 21, 10, 23,
-   190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35,
-      11, 32, 57, 177, 33,
-   88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71,
-      134, 139, 48, 27, 166,
-   77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41,
-      55, 46, 245, 40, 244,
-   102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89,
-      18, 169, 200, 196,
-   135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217,
-      226, 250, 124, 123,
-   5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58,
-      17, 182, 189, 28, 42,
-   223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155,
-      167, 43, 172, 9,
-   129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104,
-      218, 246, 97, 228,
-   251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235,
-      249, 14, 239, 107,
-   49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45,
-      127, 4, 150, 254,
-   138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66,
-      215, 61, 156, 180,
-   151, 160, 137, 91, 90, 15,
-   131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8,
-      99, 37, 240, 21, 10, 23,
-   190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35,
-      11, 32, 57, 177, 33,
-   88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71,
-      134, 139, 48, 27, 166,
-   77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41,
-      55, 46, 245, 40, 244,
-   102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89,
-      18, 169, 200, 196,
-   135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217,
-      226, 250, 124, 123,
-   5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58,
-      17, 182, 189, 28, 42,
-   223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155,
-      167, 43, 172, 9,
-   129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104,
-      218, 246, 97, 228,
-   251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235,
-      249, 14, 239, 107,
-   49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45,
-      127, 4, 150, 254,
-   138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66,
-      215, 61, 156, 180
-};
-
-/*
- * ---------------------------------------------------------------------
- */
-
-/*
- * Helper functions to compute gradients-dot-residualvectors (1D to 4D)
- * Note that these generate gradients of more than unit length. To make
- * a close match with the value range of classic Perlin noise, the final
- * noise values need to be rescaled to fit nicely within [-1,1].
- * (The simplex noise functions as such also have different scaling.)
- * Note also that these noise functions are the most practical and useful
- * signed version of Perlin noise. To return values according to the
- * RenderMan specification from the SL noise() and pnoise() functions,
- * the noise values need to be scaled and offset to [0,1], like this:
- * float SLnoise = (SimplexNoise1234::noise(x,y,z) + 1.0) * 0.5;
- */
-
-static float
-grad1(int hash, float x)
-{
-   int h = hash & 15;
-   float grad = 1.0f + (h & 7); /* Gradient value 1.0, 2.0, ..., 8.0 */
-   if (h & 8)
-      grad = -grad;             /* Set a random sign for the gradient */
-   return (grad * x);           /* Multiply the gradient with the distance */
-}
-
-static float
-grad2(int hash, float x, float y)
-{
-   int h = hash & 7;            /* Convert low 3 bits of hash code */
-   float u = h < 4 ? x : y;     /* into 8 simple gradient directions, */
-   float v = h < 4 ? y : x;     /* and compute the dot product with (x,y). */
-   return ((h & 1) ? -u : u) + ((h & 2) ? -2.0f * v : 2.0f * v);
-}
-
-static float
-grad3(int hash, float x, float y, float z)
-{
-   int h = hash & 15;           /* Convert low 4 bits of hash code into 12 simple */
-   float u = h < 8 ? x : y;     /* gradient directions, and compute dot product. */
-   float v = h < 4 ? y : h == 12 || h == 14 ? x : z;    /* Fix repeats at h = 12 to 15 */
-   return ((h & 1) ? -u : u) + ((h & 2) ? -v : v);
-}
-
-static float
-grad4(int hash, float x, float y, float z, float t)
-{
-   int h = hash & 31;           /* Convert low 5 bits of hash code into 32 simple */
-   float u = h < 24 ? x : y;    /* gradient directions, and compute dot product. */
-   float v = h < 16 ? y : z;
-   float w = h < 8 ? z : t;
-   return ((h & 1) ? -u : u) + ((h & 2) ? -v : v) + ((h & 4) ? -w : w);
-}
-
-/**
- * A lookup table to traverse the simplex around a given point in 4D.
- * Details can be found where this table is used, in the 4D noise method.
- * TODO: This should not be required, backport it from Bill's GLSL code!
- */
-static unsigned char simplex[64][4] = {
-   {0, 1, 2, 3}, {0, 1, 3, 2}, {0, 0, 0, 0}, {0, 2, 3, 1},
-   {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {1, 2, 3, 0},
-   {0, 2, 1, 3}, {0, 0, 0, 0}, {0, 3, 1, 2}, {0, 3, 2, 1},
-   {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {1, 3, 2, 0},
-   {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
-   {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
-   {1, 2, 0, 3}, {0, 0, 0, 0}, {1, 3, 0, 2}, {0, 0, 0, 0},
-   {0, 0, 0, 0}, {0, 0, 0, 0}, {2, 3, 0, 1}, {2, 3, 1, 0},
-   {1, 0, 2, 3}, {1, 0, 3, 2}, {0, 0, 0, 0}, {0, 0, 0, 0},
-   {0, 0, 0, 0}, {2, 0, 3, 1}, {0, 0, 0, 0}, {2, 1, 3, 0},
-   {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
-   {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
-   {2, 0, 1, 3}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
-   {3, 0, 1, 2}, {3, 0, 2, 1}, {0, 0, 0, 0}, {3, 1, 2, 0},
-   {2, 1, 0, 3}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0},
-   {3, 1, 0, 2}, {0, 0, 0, 0}, {3, 2, 0, 1}, {3, 2, 1, 0}
-};
-
-
-/** 1D simplex noise */
-GLfloat
-_mesa_noise1(GLfloat x)
-{
-   int i0 = FASTFLOOR(x);
-   int i1 = i0 + 1;
-   float x0 = x - i0;
-   float x1 = x0 - 1.0f;
-   float t1 = 1.0f - x1 * x1;
-   float n0, n1;
-
-   float t0 = 1.0f - x0 * x0;
-/*  if(t0 < 0.0f) t0 = 0.0f; // this never happens for the 1D case */
-   t0 *= t0;
-   n0 = t0 * t0 * grad1(perm[i0 & 0xff], x0);
-
-/*  if(t1 < 0.0f) t1 = 0.0f; // this never happens for the 1D case */
-   t1 *= t1;
-   n1 = t1 * t1 * grad1(perm[i1 & 0xff], x1);
-   /* The maximum value of this noise is 8*(3/4)^4 = 2.53125 */
-   /* A factor of 0.395 would scale to fit exactly within [-1,1], but */
-   /* we want to match PRMan's 1D noise, so we scale it down some more. */
-   return 0.25f * (n0 + n1);
-}
-
-
-/** 2D simplex noise */
-GLfloat
-_mesa_noise2(GLfloat x, GLfloat y)
-{
-#define F2 0.366025403f         /* F2 = 0.5*(sqrt(3.0)-1.0) */
-#define G2 0.211324865f         /* G2 = (3.0-Math.sqrt(3.0))/6.0 */
-
-   float n0, n1, n2;            /* Noise contributions from the three corners */
-
-   /* Skew the input space to determine which simplex cell we're in */
-   float s = (x + y) * F2;      /* Hairy factor for 2D */
-   float xs = x + s;
-   float ys = y + s;
-   int i = FASTFLOOR(xs);
-   int j = FASTFLOOR(ys);
-
-   float t = (float) (i + j) * G2;
-   float X0 = i - t;            /* Unskew the cell origin back to (x,y) space */
-   float Y0 = j - t;
-   float x0 = x - X0;           /* The x,y distances from the cell origin */
-   float y0 = y - Y0;
-
-   float x1, y1, x2, y2;
-   int ii, jj;
-   float t0, t1, t2;
-
-   /* For the 2D case, the simplex shape is an equilateral triangle. */
-   /* Determine which simplex we are in. */
-   int i1, j1;                  /* Offsets for second (middle) corner of simplex in (i,j) coords */
-   if (x0 > y0) {
-      i1 = 1;
-      j1 = 0;
-   }                            /* lower triangle, XY order: (0,0)->(1,0)->(1,1) */
-   else {
-      i1 = 0;
-      j1 = 1;
-   }                            /* upper triangle, YX order: (0,0)->(0,1)->(1,1) */
-
-   /* A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and */
-   /* a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where */
-   /* c = (3-sqrt(3))/6 */
-
-   x1 = x0 - i1 + G2;           /* Offsets for middle corner in (x,y) unskewed coords */
-   y1 = y0 - j1 + G2;
-   x2 = x0 - 1.0f + 2.0f * G2;  /* Offsets for last corner in (x,y) unskewed coords */
-   y2 = y0 - 1.0f + 2.0f * G2;
-
-   /* Wrap the integer indices at 256, to avoid indexing perm[] out of bounds */
-   ii = i % 256;
-   jj = j % 256;
-
-   /* Calculate the contribution from the three corners */
-   t0 = 0.5f - x0 * x0 - y0 * y0;
-   if (t0 < 0.0f)
-      n0 = 0.0f;
-   else {
-      t0 *= t0;
-      n0 = t0 * t0 * grad2(perm[ii + perm[jj]], x0, y0);
-   }
-
-   t1 = 0.5f - x1 * x1 - y1 * y1;
-   if (t1 < 0.0f)
-      n1 = 0.0f;
-   else {
-      t1 *= t1;
-      n1 = t1 * t1 * grad2(perm[ii + i1 + perm[jj + j1]], x1, y1);
-   }
-
-   t2 = 0.5f - x2 * x2 - y2 * y2;
-   if (t2 < 0.0f)
-      n2 = 0.0f;
-   else {
-      t2 *= t2;
-      n2 = t2 * t2 * grad2(perm[ii + 1 + perm[jj + 1]], x2, y2);
-   }
-
-   /* Add contributions from each corner to get the final noise value. */
-   /* The result is scaled to return values in the interval [-1,1]. */
-   return 40.0f * (n0 + n1 + n2);       /* TODO: The scale factor is preliminary! */
-}
-
-
-/** 3D simplex noise */
-GLfloat
-_mesa_noise3(GLfloat x, GLfloat y, GLfloat z)
-{
-/* Simple skewing factors for the 3D case */
-#define F3 0.333333333f
-#define G3 0.166666667f
-
-   float n0, n1, n2, n3;        /* Noise contributions from the four corners */
-
-   /* Skew the input space to determine which simplex cell we're in */
-   float s = (x + y + z) * F3;  /* Very nice and simple skew factor for 3D */
-   float xs = x + s;
-   float ys = y + s;
-   float zs = z + s;
-   int i = FASTFLOOR(xs);
-   int j = FASTFLOOR(ys);
-   int k = FASTFLOOR(zs);
-
-   float t = (float) (i + j + k) * G3;
-   float X0 = i - t;            /* Unskew the cell origin back to (x,y,z) space */
-   float Y0 = j - t;
-   float Z0 = k - t;
-   float x0 = x - X0;           /* The x,y,z distances from the cell origin */
-   float y0 = y - Y0;
-   float z0 = z - Z0;
-
-   float x1, y1, z1, x2, y2, z2, x3, y3, z3;
-   int ii, jj, kk;
-   float t0, t1, t2, t3;
-
-   /* For the 3D case, the simplex shape is a slightly irregular tetrahedron. */
-   /* Determine which simplex we are in. */
-   int i1, j1, k1;              /* Offsets for second corner of simplex in (i,j,k) coords */
-   int i2, j2, k2;              /* Offsets for third corner of simplex in (i,j,k) coords */
-
-/* This code would benefit from a backport from the GLSL version! */
-   if (x0 >= y0) {
-      if (y0 >= z0) {
-         i1 = 1;
-         j1 = 0;
-         k1 = 0;
-         i2 = 1;
-         j2 = 1;
-         k2 = 0;
-      }                         /* X Y Z order */
-      else if (x0 >= z0) {
-         i1 = 1;
-         j1 = 0;
-         k1 = 0;
-         i2 = 1;
-         j2 = 0;
-         k2 = 1;
-      }                         /* X Z Y order */
-      else {
-         i1 = 0;
-         j1 = 0;
-         k1 = 1;
-         i2 = 1;
-         j2 = 0;
-         k2 = 1;
-      }                         /* Z X Y order */
-   }
-   else {                       /* x0<y0 */
-      if (y0 < z0) {
-         i1 = 0;
-         j1 = 0;
-         k1 = 1;
-         i2 = 0;
-         j2 = 1;
-         k2 = 1;
-      }                         /* Z Y X order */
-      else if (x0 < z0) {
-         i1 = 0;
-         j1 = 1;
-         k1 = 0;
-         i2 = 0;
-         j2 = 1;
-         k2 = 1;
-      }                         /* Y Z X order */
-      else {
-         i1 = 0;
-         j1 = 1;
-         k1 = 0;
-         i2 = 1;
-         j2 = 1;
-         k2 = 0;
-      }                         /* Y X Z order */
-   }
-
-   /* A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in
-    * (x,y,z), a step of (0,1,0) in (i,j,k) means a step of
-    * (-c,1-c,-c) in (x,y,z), and a step of (0,0,1) in (i,j,k) means a
-    * step of (-c,-c,1-c) in (x,y,z), where c = 1/6.
-    */
-
-   x1 = x0 - i1 + G3;         /* Offsets for second corner in (x,y,z) coords */
-   y1 = y0 - j1 + G3;
-   z1 = z0 - k1 + G3;
-   x2 = x0 - i2 + 2.0f * G3;  /* Offsets for third corner in (x,y,z) coords */
-   y2 = y0 - j2 + 2.0f * G3;
-   z2 = z0 - k2 + 2.0f * G3;
-   x3 = x0 - 1.0f + 3.0f * G3;/* Offsets for last corner in (x,y,z) coords */
-   y3 = y0 - 1.0f + 3.0f * G3;
-   z3 = z0 - 1.0f + 3.0f * G3;
-
-   /* Wrap the integer indices at 256 to avoid indexing perm[] out of bounds */
-   ii = i % 256;
-   jj = j % 256;
-   kk = k % 256;
-
-   /* Calculate the contribution from the four corners */
-   t0 = 0.6f - x0 * x0 - y0 * y0 - z0 * z0;
-   if (t0 < 0.0f)
-      n0 = 0.0f;
-   else {
-      t0 *= t0;
-      n0 = t0 * t0 * grad3(perm[ii + perm[jj + perm[kk]]], x0, y0, z0);
-   }
-
-   t1 = 0.6f - x1 * x1 - y1 * y1 - z1 * z1;
-   if (t1 < 0.0f)
-      n1 = 0.0f;
-   else {
-      t1 *= t1;
-      n1 =
-         t1 * t1 * grad3(perm[ii + i1 + perm[jj + j1 + perm[kk + k1]]], x1,
-                         y1, z1);
-   }
-
-   t2 = 0.6f - x2 * x2 - y2 * y2 - z2 * z2;
-   if (t2 < 0.0f)
-      n2 = 0.0f;
-   else {
-      t2 *= t2;
-      n2 =
-         t2 * t2 * grad3(perm[ii + i2 + perm[jj + j2 + perm[kk + k2]]], x2,
-                         y2, z2);
-   }
-
-   t3 = 0.6f - x3 * x3 - y3 * y3 - z3 * z3;
-   if (t3 < 0.0f)
-      n3 = 0.0f;
-   else {
-      t3 *= t3;
-      n3 =
-         t3 * t3 * grad3(perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]], x3, y3,
-                         z3);
-   }
-
-   /* Add contributions from each corner to get the final noise value.
-    * The result is scaled to stay just inside [-1,1]
-    */
-   return 32.0f * (n0 + n1 + n2 + n3);  /* TODO: The scale factor is preliminary! */
-}
-
-
-/** 4D simplex noise */
-GLfloat
-_mesa_noise4(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
-   /* The skewing and unskewing factors are hairy again for the 4D case */
-#define F4 0.309016994f         /* F4 = (Math.sqrt(5.0)-1.0)/4.0 */
-#define G4 0.138196601f         /* G4 = (5.0-Math.sqrt(5.0))/20.0 */
-
-   float n0, n1, n2, n3, n4;    /* Noise contributions from the five corners */
-
-   /* Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in */
-   float s = (x + y + z + w) * F4;      /* Factor for 4D skewing */
-   float xs = x + s;
-   float ys = y + s;
-   float zs = z + s;
-   float ws = w + s;
-   int i = FASTFLOOR(xs);
-   int j = FASTFLOOR(ys);
-   int k = FASTFLOOR(zs);
-   int l = FASTFLOOR(ws);
-
-   float t = (i + j + k + l) * G4;      /* Factor for 4D unskewing */
-   float X0 = i - t;            /* Unskew the cell origin back to (x,y,z,w) space */
-   float Y0 = j - t;
-   float Z0 = k - t;
-   float W0 = l - t;
-
-   float x0 = x - X0;           /* The x,y,z,w distances from the cell origin */
-   float y0 = y - Y0;
-   float z0 = z - Z0;
-   float w0 = w - W0;
-
-   /* For the 4D case, the simplex is a 4D shape I won't even try to describe.
-    * To find out which of the 24 possible simplices we're in, we need to
-    * determine the magnitude ordering of x0, y0, z0 and w0.
-    * The method below is a good way of finding the ordering of x,y,z,w and
-    * then find the correct traversal order for the simplex we're in.
-    * First, six pair-wise comparisons are performed between each possible pair
-    * of the four coordinates, and the results are used to add up binary bits
-    * for an integer index.
-    */
-   int c1 = (x0 > y0) ? 32 : 0;
-   int c2 = (x0 > z0) ? 16 : 0;
-   int c3 = (y0 > z0) ? 8 : 0;
-   int c4 = (x0 > w0) ? 4 : 0;
-   int c5 = (y0 > w0) ? 2 : 0;
-   int c6 = (z0 > w0) ? 1 : 0;
-   int c = c1 + c2 + c3 + c4 + c5 + c6;
-
-   int i1, j1, k1, l1;  /* The integer offsets for the second simplex corner */
-   int i2, j2, k2, l2;  /* The integer offsets for the third simplex corner */
-   int i3, j3, k3, l3;  /* The integer offsets for the fourth simplex corner */
-
-   float x1, y1, z1, w1, x2, y2, z2, w2, x3, y3, z3, w3, x4, y4, z4, w4;
-   int ii, jj, kk, ll;
-   float t0, t1, t2, t3, t4;
-
-   /*
-    * simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some
-    * order.  Many values of c will never occur, since e.g. x>y>z>w
-    * makes x<z, y<w and x<w impossible. Only the 24 indices which
-    * have non-zero entries make any sense.  We use a thresholding to
-    * set the coordinates in turn from the largest magnitude.  The
-    * number 3 in the "simplex" array is at the position of the
-    * largest coordinate.
-    */
-   i1 = simplex[c][0] >= 3 ? 1 : 0;
-   j1 = simplex[c][1] >= 3 ? 1 : 0;
-   k1 = simplex[c][2] >= 3 ? 1 : 0;
-   l1 = simplex[c][3] >= 3 ? 1 : 0;
-   /* The number 2 in the "simplex" array is at the second largest coordinate. */
-   i2 = simplex[c][0] >= 2 ? 1 : 0;
-   j2 = simplex[c][1] >= 2 ? 1 : 0;
-   k2 = simplex[c][2] >= 2 ? 1 : 0;
-   l2 = simplex[c][3] >= 2 ? 1 : 0;
-   /* The number 1 in the "simplex" array is at the second smallest coordinate. */
-   i3 = simplex[c][0] >= 1 ? 1 : 0;
-   j3 = simplex[c][1] >= 1 ? 1 : 0;
-   k3 = simplex[c][2] >= 1 ? 1 : 0;
-   l3 = simplex[c][3] >= 1 ? 1 : 0;
-   /* The fifth corner has all coordinate offsets = 1, so no need to look that up. */
-
-   x1 = x0 - i1 + G4;           /* Offsets for second corner in (x,y,z,w) coords */
-   y1 = y0 - j1 + G4;
-   z1 = z0 - k1 + G4;
-   w1 = w0 - l1 + G4;
-   x2 = x0 - i2 + 2.0f * G4;    /* Offsets for third corner in (x,y,z,w) coords */
-   y2 = y0 - j2 + 2.0f * G4;
-   z2 = z0 - k2 + 2.0f * G4;
-   w2 = w0 - l2 + 2.0f * G4;
-   x3 = x0 - i3 + 3.0f * G4;    /* Offsets for fourth corner in (x,y,z,w) coords */
-   y3 = y0 - j3 + 3.0f * G4;
-   z3 = z0 - k3 + 3.0f * G4;
-   w3 = w0 - l3 + 3.0f * G4;
-   x4 = x0 - 1.0f + 4.0f * G4;  /* Offsets for last corner in (x,y,z,w) coords */
-   y4 = y0 - 1.0f + 4.0f * G4;
-   z4 = z0 - 1.0f + 4.0f * G4;
-   w4 = w0 - 1.0f + 4.0f * G4;
-
-   /* Wrap the integer indices at 256, to avoid indexing perm[] out of bounds */
-   ii = i % 256;
-   jj = j % 256;
-   kk = k % 256;
-   ll = l % 256;
-
-   /* Calculate the contribution from the five corners */
-   t0 = 0.6f - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0;
-   if (t0 < 0.0f)
-      n0 = 0.0f;
-   else {
-      t0 *= t0;
-      n0 =
-         t0 * t0 * grad4(perm[ii + perm[jj + perm[kk + perm[ll]]]], x0, y0,
-                         z0, w0);
-   }
-
-   t1 = 0.6f - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1;
-   if (t1 < 0.0f)
-      n1 = 0.0f;
-   else {
-      t1 *= t1;
-      n1 =
-         t1 * t1 *
-         grad4(perm[ii + i1 + perm[jj + j1 + perm[kk + k1 + perm[ll + l1]]]],
-               x1, y1, z1, w1);
-   }
-
-   t2 = 0.6f - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2;
-   if (t2 < 0.0f)
-      n2 = 0.0f;
-   else {
-      t2 *= t2;
-      n2 =
-         t2 * t2 *
-         grad4(perm[ii + i2 + perm[jj + j2 + perm[kk + k2 + perm[ll + l2]]]],
-               x2, y2, z2, w2);
-   }
-
-   t3 = 0.6f - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3;
-   if (t3 < 0.0f)
-      n3 = 0.0f;
-   else {
-      t3 *= t3;
-      n3 =
-         t3 * t3 *
-         grad4(perm[ii + i3 + perm[jj + j3 + perm[kk + k3 + perm[ll + l3]]]],
-               x3, y3, z3, w3);
-   }
-
-   t4 = 0.6f - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4;
-   if (t4 < 0.0f)
-      n4 = 0.0f;
-   else {
-      t4 *= t4;
-      n4 =
-         t4 * t4 *
-         grad4(perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]], x4,
-               y4, z4, w4);
-   }
-
-   /* Sum up and scale the result to cover the range [-1,1] */
-   return 27.0f * (n0 + n1 + n2 + n3 + n4);     /* TODO: The scale factor is preliminary! */
-}
diff --git a/src/mesa/shader/prog_noise.h b/src/mesa/shader/prog_noise.h
deleted file mode 100644 (file)
index c477947..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5
- *
- * Copyright (C) 2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef PROG_NOISE
-#define PROG_NOISE
-
-extern GLfloat _mesa_noise1(GLfloat);
-extern GLfloat _mesa_noise2(GLfloat, GLfloat);
-extern GLfloat _mesa_noise3(GLfloat, GLfloat, GLfloat);
-extern GLfloat _mesa_noise4(GLfloat, GLfloat, GLfloat, GLfloat);
-
-#endif
-
diff --git a/src/mesa/shader/prog_optimize.c b/src/mesa/shader/prog_optimize.c
deleted file mode 100644 (file)
index bd120b8..0000000
+++ /dev/null
@@ -1,1041 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.5
- *
- * Copyright (C) 2009  VMware, 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
- * 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
- * VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION 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/context.h"
-#include "main/macros.h"
-#include "program.h"
-#include "prog_instruction.h"
-#include "prog_optimize.h"
-#include "prog_print.h"
-
-
-#define MAX_LOOP_NESTING 50
-
-
-static GLboolean dbg = GL_FALSE;
-
-/* Returns the mask of channels read from the given srcreg in this instruction.
- */
-static GLuint
-get_src_arg_mask(const struct prog_instruction *inst, int arg)
-{
-   int writemask = inst->DstReg.WriteMask;
-
-   if (inst->CondUpdate)
-      writemask = WRITEMASK_XYZW;
-
-   switch (inst->Opcode) {
-   case OPCODE_MOV:
-   case OPCODE_ABS:
-   case OPCODE_ADD:
-   case OPCODE_MUL:
-   case OPCODE_SUB:
-      return writemask;
-   case OPCODE_RCP:
-   case OPCODE_SIN:
-   case OPCODE_COS:
-   case OPCODE_RSQ:
-   case OPCODE_POW:
-   case OPCODE_EX2:
-      return WRITEMASK_X;
-   case OPCODE_DP2:
-      return WRITEMASK_XY;
-   case OPCODE_DP3:
-   case OPCODE_XPD:
-      return WRITEMASK_XYZ;
-   default:
-      return WRITEMASK_XYZW;
-   }
-}
-
-/**
- * In 'prog' remove instruction[i] if removeFlags[i] == TRUE.
- * \return number of instructions removed
- */
-static GLuint
-remove_instructions(struct gl_program *prog, const GLboolean *removeFlags)
-{
-   GLint i, removeEnd = 0, removeCount = 0;
-   GLuint totalRemoved = 0;
-
-   /* go backward */
-   for (i = prog->NumInstructions - 1; i >= 0; i--) {
-      if (removeFlags[i]) {
-         totalRemoved++;
-         if (removeCount == 0) {
-            /* begin a run of instructions to remove */
-            removeEnd = i;
-            removeCount = 1;
-         }
-         else {
-            /* extend the run of instructions to remove */
-            removeCount++;
-         }
-      }
-      else {
-         /* don't remove this instruction, but check if the preceeding
-          * instructions are to be removed.
-          */
-         if (removeCount > 0) {
-            GLint removeStart = removeEnd - removeCount + 1;
-            _mesa_delete_instructions(prog, removeStart, removeCount);
-            removeStart = removeCount = 0; /* reset removal info */
-         }
-      }
-   }
-   /* Finish removing if the first instruction was to be removed. */
-   if (removeCount > 0) {
-      GLint removeStart = removeEnd - removeCount + 1;
-      _mesa_delete_instructions(prog, removeStart, removeCount);
-   }
-   return totalRemoved;
-}
-
-
-/**
- * Remap register indexes according to map.
- * \param prog  the program to search/replace
- * \param file  the type of register file to search/replace
- * \param map  maps old register indexes to new indexes
- */
-static void
-replace_regs(struct gl_program *prog, gl_register_file file, const GLint map[])
-{
-   GLuint i;
-
-   for (i = 0; i < prog->NumInstructions; i++) {
-      struct prog_instruction *inst = prog->Instructions + i;
-      const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
-      GLuint j;
-      for (j = 0; j < numSrc; j++) {
-         if (inst->SrcReg[j].File == file) {
-            GLuint index = inst->SrcReg[j].Index;
-            ASSERT(map[index] >= 0);
-            inst->SrcReg[j].Index = map[index];
-         }
-      }
-      if (inst->DstReg.File == file) {
-         const GLuint index = inst->DstReg.Index;
-         ASSERT(map[index] >= 0);
-         inst->DstReg.Index = map[index];
-      }
-   }
-}
-
-
-/**
- * Consolidate temporary registers to use low numbers.  For example, if the
- * shader only uses temps 4, 5, 8, replace them with 0, 1, 2.
- */
-static void
-_mesa_consolidate_registers(struct gl_program *prog)
-{
-   GLboolean tempUsed[MAX_PROGRAM_TEMPS];
-   GLint tempMap[MAX_PROGRAM_TEMPS];
-   GLuint tempMax = 0, i;
-
-   if (dbg) {
-      printf("Optimize: Begin register consolidation\n");
-   }
-
-   memset(tempUsed, 0, sizeof(tempUsed));
-
-   for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
-      tempMap[i] = -1;
-   }
-
-   /* set tempUsed[i] if temporary [i] is referenced */
-   for (i = 0; i < prog->NumInstructions; i++) {
-      const struct prog_instruction *inst = prog->Instructions + i;
-      const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
-      GLuint j;
-      for (j = 0; j < numSrc; j++) {
-         if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) {
-            const GLuint index = inst->SrcReg[j].Index;
-            ASSERT(index < MAX_PROGRAM_TEMPS);
-            tempUsed[index] = GL_TRUE;
-            tempMax = MAX2(tempMax, index);
-            break;
-         }
-      }
-      if (inst->DstReg.File == PROGRAM_TEMPORARY) {
-         const GLuint index = inst->DstReg.Index;
-         ASSERT(index < MAX_PROGRAM_TEMPS);
-         tempUsed[index] = GL_TRUE;
-         tempMax = MAX2(tempMax, index);
-      }
-   }
-
-   /* allocate a new index for each temp that's used */
-   {
-      GLuint freeTemp = 0;
-      for (i = 0; i <= tempMax; i++) {
-         if (tempUsed[i]) {
-            tempMap[i] = freeTemp++;
-            /*printf("replace %u with %u\n", i, tempMap[i]);*/
-         }
-      }
-      if (freeTemp == tempMax + 1) {
-         /* no consolidation possible */
-         return;
-      }         
-      if (dbg) {
-         printf("Replace regs 0..%u with 0..%u\n", tempMax, freeTemp-1);
-      }
-   }
-
-   replace_regs(prog, PROGRAM_TEMPORARY, tempMap);
-
-   if (dbg) {
-      printf("Optimize: End register consolidation\n");
-   }
-}
-
-
-/**
- * Remove dead instructions from the given program.
- * This is very primitive for now.  Basically look for temp registers
- * that are written to but never read.  Remove any instructions that
- * write to such registers.  Be careful with condition code setters.
- */
-static void
-_mesa_remove_dead_code(struct gl_program *prog)
-{
-   GLboolean tempRead[MAX_PROGRAM_TEMPS][4];
-   GLboolean *removeInst; /* per-instruction removal flag */
-   GLuint i, rem = 0, comp;
-
-   memset(tempRead, 0, sizeof(tempRead));
-
-   if (dbg) {
-      printf("Optimize: Begin dead code removal\n");
-      /*_mesa_print_program(prog);*/
-   }
-
-   removeInst = (GLboolean *)
-      calloc(1, prog->NumInstructions * sizeof(GLboolean));
-
-   /* Determine which temps are read and written */
-   for (i = 0; i < prog->NumInstructions; i++) {
-      const struct prog_instruction *inst = prog->Instructions + i;
-      const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
-      GLuint j;
-
-      /* check src regs */
-      for (j = 0; j < numSrc; j++) {
-         if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) {
-            const GLuint index = inst->SrcReg[j].Index;
-            GLuint read_mask;
-            ASSERT(index < MAX_PROGRAM_TEMPS);
-           read_mask = get_src_arg_mask(inst, j);
-
-            if (inst->SrcReg[j].RelAddr) {
-               if (dbg)
-                  printf("abort remove dead code (indirect temp)\n");
-               goto done;
-            }
-
-           for (comp = 0; comp < 4; comp++) {
-              GLuint swz = (inst->SrcReg[j].Swizzle >> (3 * comp)) & 0x7;
-
-              if ((read_mask & (1 << comp)) == 0)
-                 continue;
-
-              switch (swz) {
-              case SWIZZLE_X:
-                 tempRead[index][0] = GL_TRUE;
-                 break;
-              case SWIZZLE_Y:
-                 tempRead[index][1] = GL_TRUE;
-                 break;
-              case SWIZZLE_Z:
-                 tempRead[index][2] = GL_TRUE;
-                 break;
-              case SWIZZLE_W:
-                 tempRead[index][3] = GL_TRUE;
-                 break;
-              }
-           }
-         }
-      }
-
-      /* check dst reg */
-      if (inst->DstReg.File == PROGRAM_TEMPORARY) {
-         const GLuint index = inst->DstReg.Index;
-         ASSERT(index < MAX_PROGRAM_TEMPS);
-
-         if (inst->DstReg.RelAddr) {
-            if (dbg)
-               printf("abort remove dead code (indirect temp)\n");
-            goto done;
-         }
-
-         if (inst->CondUpdate) {
-            /* If we're writing to this register and setting condition
-             * codes we cannot remove the instruction.  Prevent removal
-             * by setting the 'read' flag.
-             */
-            tempRead[index][0] = GL_TRUE;
-            tempRead[index][1] = GL_TRUE;
-            tempRead[index][2] = GL_TRUE;
-            tempRead[index][3] = GL_TRUE;
-         }
-      }
-   }
-
-   /* find instructions that write to dead registers, flag for removal */
-   for (i = 0; i < prog->NumInstructions; i++) {
-      struct prog_instruction *inst = prog->Instructions + i;
-      const GLuint numDst = _mesa_num_inst_dst_regs(inst->Opcode);
-
-      if (numDst != 0 && inst->DstReg.File == PROGRAM_TEMPORARY) {
-         GLint chan, index = inst->DstReg.Index;
-
-        for (chan = 0; chan < 4; chan++) {
-           if (!tempRead[index][chan] &&
-               inst->DstReg.WriteMask & (1 << chan)) {
-              if (dbg) {
-                 printf("Remove writemask on %u.%c\n", i,
-                              chan == 3 ? 'w' : 'x' + chan);
-              }
-              inst->DstReg.WriteMask &= ~(1 << chan);
-              rem++;
-           }
-        }
-
-        if (inst->DstReg.WriteMask == 0) {
-           /* If we cleared all writes, the instruction can be removed. */
-           if (dbg)
-              printf("Remove instruction %u: \n", i);
-           removeInst[i] = GL_TRUE;
-        }
-      }
-   }
-
-   /* now remove the instructions which aren't needed */
-   rem = remove_instructions(prog, removeInst);
-
-   if (dbg) {
-      printf("Optimize: End dead code removal.\n");
-      printf("  %u channel writes removed\n", rem);
-      printf("  %u instructions removed\n", rem);
-      /*_mesa_print_program(prog);*/
-   }
-
-done:
-   free(removeInst);
-}
-
-
-enum temp_use
-{
-   READ,
-   WRITE,
-   FLOW,
-   END
-};
-
-/**
- * Scan forward in program from 'start' for the next occurance of TEMP[index].
- * Return READ, WRITE, FLOW or END to indicate the next usage or an indicator
- * that we can't look further.
- */
-static enum temp_use
-find_next_temp_use(const struct gl_program *prog, GLuint start, GLuint index)
-{
-   GLuint i;
-
-   for (i = start; i < prog->NumInstructions; i++) {
-      const struct prog_instruction *inst = prog->Instructions + i;
-      switch (inst->Opcode) {
-      case OPCODE_BGNLOOP:
-      case OPCODE_ENDLOOP:
-      case OPCODE_BGNSUB:
-      case OPCODE_ENDSUB:
-         return FLOW;
-      default:
-         {
-            const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
-            GLuint j;
-            for (j = 0; j < numSrc; j++) {
-               if (inst->SrcReg[j].File == PROGRAM_TEMPORARY &&
-                   inst->SrcReg[j].Index == index)
-                  return READ;
-            }
-            if (inst->DstReg.File == PROGRAM_TEMPORARY &&
-                inst->DstReg.Index == index)
-               return WRITE;
-         }
-      }
-   }
-
-   return END;
-}
-
-static GLboolean _mesa_is_flow_control_opcode(enum prog_opcode opcode)
-{
-   switch (opcode) {
-   case OPCODE_BGNLOOP:
-   case OPCODE_BGNSUB:
-   case OPCODE_BRA:
-   case OPCODE_CAL:
-   case OPCODE_CONT:
-   case OPCODE_IF:
-   case OPCODE_ELSE:
-   case OPCODE_END:
-   case OPCODE_ENDIF:
-   case OPCODE_ENDLOOP:
-   case OPCODE_ENDSUB:
-   case OPCODE_RET:
-      return GL_TRUE;
-   default:
-      return GL_FALSE;
-   }
-}
-
-/**
- * Try to remove use of extraneous MOV instructions, to free them up for dead
- * code removal.
- */
-static void
-_mesa_remove_extra_move_use(struct gl_program *prog)
-{
-   GLuint i, j;
-
-   if (dbg) {
-      printf("Optimize: Begin remove extra move use\n");
-      _mesa_print_program(prog);
-   }
-
-   /*
-    * Look for sequences such as this:
-    *    MOV tmpX, arg0;
-    *    ...
-    *    FOO tmpY, tmpX, arg1;
-    * and convert into:
-    *    MOV tmpX, arg0;
-    *    ...
-    *    FOO tmpY, arg0, arg1;
-    */
-
-   for (i = 0; i + 1 < prog->NumInstructions; i++) {
-      const struct prog_instruction *mov = prog->Instructions + i;
-
-      if (mov->Opcode != OPCODE_MOV ||
-         mov->DstReg.File != PROGRAM_TEMPORARY ||
-         mov->DstReg.RelAddr ||
-         mov->DstReg.CondMask != COND_TR ||
-         mov->SaturateMode != SATURATE_OFF ||
-         mov->SrcReg[0].RelAddr)
-        continue;
-
-      /* Walk through remaining instructions until the or src reg gets
-       * rewritten or we get into some flow-control, eliminating the use of
-       * this MOV.
-       */
-      for (j = i + 1; j < prog->NumInstructions; j++) {
-        struct prog_instruction *inst2 = prog->Instructions + j;
-        GLuint arg;
-
-        if (_mesa_is_flow_control_opcode(inst2->Opcode))
-            break;
-
-        /* First rewrite this instruction's args if appropriate. */
-        for (arg = 0; arg < _mesa_num_inst_src_regs(inst2->Opcode); arg++) {
-           int comp;
-           int read_mask = get_src_arg_mask(inst2, arg);
-
-           if (inst2->SrcReg[arg].File != mov->DstReg.File ||
-               inst2->SrcReg[arg].Index != mov->DstReg.Index ||
-               inst2->SrcReg[arg].RelAddr ||
-               inst2->SrcReg[arg].Abs)
-              continue;
-
-           /* Check that all the sources for this arg of inst2 come from inst1
-            * or constants.
-            */
-           for (comp = 0; comp < 4; comp++) {
-              int src_swz = GET_SWZ(inst2->SrcReg[arg].Swizzle, comp);
-
-              /* If the MOV didn't write that channel, can't use it. */
-              if ((read_mask & (1 << comp)) &&
-                  src_swz <= SWIZZLE_W &&
-                  (mov->DstReg.WriteMask & (1 << src_swz)) == 0)
-                 break;
-           }
-           if (comp != 4)
-              continue;
-
-           /* Adjust the swizzles of inst2 to point at MOV's source */
-           for (comp = 0; comp < 4; comp++) {
-              int inst2_swz = GET_SWZ(inst2->SrcReg[arg].Swizzle, comp);
-
-              if (inst2_swz <= SWIZZLE_W) {
-                 GLuint s = GET_SWZ(mov->SrcReg[0].Swizzle, inst2_swz);
-                 inst2->SrcReg[arg].Swizzle &= ~(7 << (3 * comp));
-                 inst2->SrcReg[arg].Swizzle |= s << (3 * comp);
-                 inst2->SrcReg[arg].Negate ^= (((mov->SrcReg[0].Negate >>
-                                                 inst2_swz) & 0x1) << comp);
-              }
-           }
-           inst2->SrcReg[arg].File = mov->SrcReg[0].File;
-           inst2->SrcReg[arg].Index = mov->SrcReg[0].Index;
-        }
-
-        /* If this instruction overwrote part of the move, our time is up. */
-        if ((inst2->DstReg.File == mov->DstReg.File &&
-             (inst2->DstReg.RelAddr ||
-              inst2->DstReg.Index == mov->DstReg.Index)) ||
-            (inst2->DstReg.File == mov->SrcReg[0].File &&
-             (inst2->DstReg.RelAddr ||
-              inst2->DstReg.Index == mov->SrcReg[0].Index)))
-           break;
-      }
-   }
-
-   if (dbg) {
-      printf("Optimize: End remove extra move use.\n");
-      /*_mesa_print_program(prog);*/
-   }
-}
-
-/**
- * Try to remove extraneous MOV instructions from the given program.
- */
-static void
-_mesa_remove_extra_moves(struct gl_program *prog)
-{
-   GLboolean *removeInst; /* per-instruction removal flag */
-   GLuint i, rem, loopNesting = 0, subroutineNesting = 0;
-
-   if (dbg) {
-      printf("Optimize: Begin remove extra moves\n");
-      _mesa_print_program(prog);
-   }
-
-   removeInst = (GLboolean *)
-      calloc(1, prog->NumInstructions * sizeof(GLboolean));
-
-   /*
-    * Look for sequences such as this:
-    *    FOO tmpX, arg0, arg1;
-    *    MOV tmpY, tmpX;
-    * and convert into:
-    *    FOO tmpY, arg0, arg1;
-    */
-
-   for (i = 0; i < prog->NumInstructions; i++) {
-      const struct prog_instruction *inst = prog->Instructions + i;
-
-      switch (inst->Opcode) {
-      case OPCODE_BGNLOOP:
-         loopNesting++;
-         break;
-      case OPCODE_ENDLOOP:
-         loopNesting--;
-         break;
-      case OPCODE_BGNSUB:
-         subroutineNesting++;
-         break;
-      case OPCODE_ENDSUB:
-         subroutineNesting--;
-         break;
-      case OPCODE_MOV:
-         if (i > 0 &&
-             loopNesting == 0 &&
-             subroutineNesting == 0 &&
-             inst->SrcReg[0].File == PROGRAM_TEMPORARY &&
-             inst->SrcReg[0].Swizzle == SWIZZLE_XYZW) {
-            /* see if this MOV can be removed */
-            const GLuint tempIndex = inst->SrcReg[0].Index;
-            struct prog_instruction *prevInst;
-            GLuint prevI;
-
-            /* get pointer to previous instruction */
-            prevI = i - 1;
-            while (prevI > 0 && removeInst[prevI])
-               prevI--;
-            prevInst = prog->Instructions + prevI;
-
-            if (prevInst->DstReg.File == PROGRAM_TEMPORARY &&
-                prevInst->DstReg.Index == tempIndex &&
-                prevInst->DstReg.WriteMask == WRITEMASK_XYZW) {
-
-               enum temp_use next_use =
-                  find_next_temp_use(prog, i + 1, tempIndex);
-
-               if (next_use == WRITE || next_use == END) {
-                  /* OK, we can safely remove this MOV instruction.
-                   * Transform:
-                   *   prevI: FOO tempIndex, x, y;
-                   *       i: MOV z, tempIndex;
-                   * Into:
-                   *   prevI: FOO z, x, y;
-                   */
-
-                  /* patch up prev inst */
-                  prevInst->DstReg.File = inst->DstReg.File;
-                  prevInst->DstReg.Index = inst->DstReg.Index;
-
-                  /* flag this instruction for removal */
-                  removeInst[i] = GL_TRUE;
-
-                  if (dbg) {
-                     printf("Remove MOV at %u\n", i);
-                     printf("new prev inst %u: ", prevI);
-                     _mesa_print_instruction(prevInst);
-                  }
-               }
-            }
-         }
-         break;
-      default:
-         ; /* nothing */
-      }
-   }
-
-   /* now remove the instructions which aren't needed */
-   rem = remove_instructions(prog, removeInst);
-
-   free(removeInst);
-
-   if (dbg) {
-      printf("Optimize: End remove extra moves.  %u instructions removed\n", rem);
-      /*_mesa_print_program(prog);*/
-   }
-}
-
-
-/** A live register interval */
-struct interval
-{
-   GLuint Reg;         /** The temporary register index */
-   GLuint Start, End;  /** Start/end instruction numbers */
-};
-
-
-/** A list of register intervals */
-struct interval_list
-{
-   GLuint Num;
-   struct interval Intervals[MAX_PROGRAM_TEMPS];
-};
-
-
-static void
-append_interval(struct interval_list *list, const struct interval *inv)
-{
-   list->Intervals[list->Num++] = *inv;
-}
-
-
-/** Insert interval inv into list, sorted by interval end */
-static void
-insert_interval_by_end(struct interval_list *list, const struct interval *inv)
-{
-   /* XXX we could do a binary search insertion here since list is sorted */
-   GLint i = list->Num - 1;
-   while (i >= 0 && list->Intervals[i].End > inv->End) {
-      list->Intervals[i + 1] = list->Intervals[i];
-      i--;
-   }
-   list->Intervals[i + 1] = *inv;
-   list->Num++;
-
-#ifdef DEBUG
-   {
-      GLuint i;
-      for (i = 0; i + 1 < list->Num; i++) {
-         ASSERT(list->Intervals[i].End <= list->Intervals[i + 1].End);
-      }
-   }
-#endif
-}
-
-
-/** Remove the given interval from the interval list */
-static void
-remove_interval(struct interval_list *list, const struct interval *inv)
-{
-   /* XXX we could binary search since list is sorted */
-   GLuint k;
-   for (k = 0; k < list->Num; k++) {
-      if (list->Intervals[k].Reg == inv->Reg) {
-         /* found, remove it */
-         ASSERT(list->Intervals[k].Start == inv->Start);
-         ASSERT(list->Intervals[k].End == inv->End);
-         while (k < list->Num - 1) {
-            list->Intervals[k] = list->Intervals[k + 1];
-            k++;
-         }
-         list->Num--;
-         return;
-      }
-   }
-}
-
-
-/** called by qsort() */
-static int
-compare_start(const void *a, const void *b)
-{
-   const struct interval *ia = (const struct interval *) a;
-   const struct interval *ib = (const struct interval *) b;
-   if (ia->Start < ib->Start)
-      return -1;
-   else if (ia->Start > ib->Start)
-      return +1;
-   else
-      return 0;
-}
-
-/** sort the interval list according to interval starts */
-static void
-sort_interval_list_by_start(struct interval_list *list)
-{
-   qsort(list->Intervals, list->Num, sizeof(struct interval), compare_start);
-#ifdef DEBUG
-   {
-      GLuint i;
-      for (i = 0; i + 1 < list->Num; i++) {
-         ASSERT(list->Intervals[i].Start <= list->Intervals[i + 1].Start);
-      }
-   }
-#endif
-}
-
-struct loop_info
-{
-   GLuint Start, End;  /**< Start, end instructions of loop */
-};
-
-/**
- * Update the intermediate interval info for register 'index' and
- * instruction 'ic'.
- */
-static void
-update_interval(GLint intBegin[], GLint intEnd[],
-               struct loop_info *loopStack, GLuint loopStackDepth,
-               GLuint index, GLuint ic)
-{
-   int i;
-
-   /* If the register is used in a loop, extend its lifetime through the end
-    * of the outermost loop that doesn't contain its definition.
-    */
-   for (i = 0; i < loopStackDepth; i++) {
-      if (intBegin[index] < loopStack[i].Start) {
-        ic = loopStack[i].End;
-        break;
-      }
-   }
-
-   ASSERT(index < MAX_PROGRAM_TEMPS);
-   if (intBegin[index] == -1) {
-      ASSERT(intEnd[index] == -1);
-      intBegin[index] = intEnd[index] = ic;
-   }
-   else {
-      intEnd[index] = ic;
-   }
-}
-
-
-/**
- * Find first/last instruction that references each temporary register.
- */
-GLboolean
-_mesa_find_temp_intervals(const struct prog_instruction *instructions,
-                          GLuint numInstructions,
-                          GLint intBegin[MAX_PROGRAM_TEMPS],
-                          GLint intEnd[MAX_PROGRAM_TEMPS])
-{
-   struct loop_info loopStack[MAX_LOOP_NESTING];
-   GLuint loopStackDepth = 0;
-   GLuint i;
-
-   for (i = 0; i < MAX_PROGRAM_TEMPS; i++){
-      intBegin[i] = intEnd[i] = -1;
-   }
-
-   /* Scan instructions looking for temporary registers */
-   for (i = 0; i < numInstructions; i++) {
-      const struct prog_instruction *inst = instructions + i;
-      if (inst->Opcode == OPCODE_BGNLOOP) {
-         loopStack[loopStackDepth].Start = i;
-         loopStack[loopStackDepth].End = inst->BranchTarget;
-         loopStackDepth++;
-      }
-      else if (inst->Opcode == OPCODE_ENDLOOP) {
-         loopStackDepth--;
-      }
-      else if (inst->Opcode == OPCODE_CAL) {
-         return GL_FALSE;
-      }
-      else {
-         const GLuint numSrc = 3;/*_mesa_num_inst_src_regs(inst->Opcode);*/
-         GLuint j;
-         for (j = 0; j < numSrc; j++) {
-            if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) {
-               const GLuint index = inst->SrcReg[j].Index;
-               if (inst->SrcReg[j].RelAddr)
-                  return GL_FALSE;
-               update_interval(intBegin, intEnd, loopStack, loopStackDepth,
-                              index, i);
-            }
-         }
-         if (inst->DstReg.File == PROGRAM_TEMPORARY) {
-            const GLuint index = inst->DstReg.Index;
-            if (inst->DstReg.RelAddr)
-               return GL_FALSE;
-            update_interval(intBegin, intEnd, loopStack, loopStackDepth,
-                           index, i);
-         }
-      }
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Find the live intervals for each temporary register in the program.
- * For register R, the interval [A,B] indicates that R is referenced
- * from instruction A through instruction B.
- * Special consideration is needed for loops and subroutines.
- * \return GL_TRUE if success, GL_FALSE if we cannot proceed for some reason
- */
-static GLboolean
-find_live_intervals(struct gl_program *prog,
-                    struct interval_list *liveIntervals)
-{
-   GLint intBegin[MAX_PROGRAM_TEMPS], intEnd[MAX_PROGRAM_TEMPS];
-   GLuint i;
-
-   /*
-    * Note: we'll return GL_FALSE below if we find relative indexing
-    * into the TEMP register file.  We can't handle that yet.
-    * We also give up on subroutines for now.
-    */
-
-   if (dbg) {
-      printf("Optimize: Begin find intervals\n");
-   }
-
-   /* build intermediate arrays */
-   if (!_mesa_find_temp_intervals(prog->Instructions, prog->NumInstructions,
-                                  intBegin, intEnd))
-      return GL_FALSE;
-
-   /* Build live intervals list from intermediate arrays */
-   liveIntervals->Num = 0;
-   for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
-      if (intBegin[i] >= 0) {
-         struct interval inv;
-         inv.Reg = i;
-         inv.Start = intBegin[i];
-         inv.End = intEnd[i];
-         append_interval(liveIntervals, &inv);
-      }
-   }
-
-   /* Sort the list according to interval starts */
-   sort_interval_list_by_start(liveIntervals);
-
-   if (dbg) {
-      /* print interval info */
-      for (i = 0; i < liveIntervals->Num; i++) {
-         const struct interval *inv = liveIntervals->Intervals + i;
-         printf("Reg[%d] live [%d, %d]:",
-                      inv->Reg, inv->Start, inv->End);
-         if (1) {
-            GLuint j;
-            for (j = 0; j < inv->Start; j++)
-               printf(" ");
-            for (j = inv->Start; j <= inv->End; j++)
-               printf("x");
-         }
-         printf("\n");
-      }
-   }
-
-   return GL_TRUE;
-}
-
-
-/** Scan the array of used register flags to find free entry */
-static GLint
-alloc_register(GLboolean usedRegs[MAX_PROGRAM_TEMPS])
-{
-   GLuint k;
-   for (k = 0; k < MAX_PROGRAM_TEMPS; k++) {
-      if (!usedRegs[k]) {
-         usedRegs[k] = GL_TRUE;
-         return k;
-      }
-   }
-   return -1;
-}
-
-
-/**
- * This function implements "Linear Scan Register Allocation" to reduce
- * the number of temporary registers used by the program.
- *
- * We compute the "live interval" for all temporary registers then
- * examine the overlap of the intervals to allocate new registers.
- * Basically, if two intervals do not overlap, they can use the same register.
- */
-static void
-_mesa_reallocate_registers(struct gl_program *prog)
-{
-   struct interval_list liveIntervals;
-   GLint registerMap[MAX_PROGRAM_TEMPS];
-   GLboolean usedRegs[MAX_PROGRAM_TEMPS];
-   GLuint i;
-   GLint maxTemp = -1;
-
-   if (dbg) {
-      printf("Optimize: Begin live-interval register reallocation\n");
-      _mesa_print_program(prog);
-   }
-
-   for (i = 0; i < MAX_PROGRAM_TEMPS; i++){
-      registerMap[i] = -1;
-      usedRegs[i] = GL_FALSE;
-   }
-
-   if (!find_live_intervals(prog, &liveIntervals)) {
-      if (dbg)
-         printf("Aborting register reallocation\n");
-      return;
-   }
-
-   {
-      struct interval_list activeIntervals;
-      activeIntervals.Num = 0;
-
-      /* loop over live intervals, allocating a new register for each */
-      for (i = 0; i < liveIntervals.Num; i++) {
-         const struct interval *live = liveIntervals.Intervals + i;
-
-         if (dbg)
-            printf("Consider register %u\n", live->Reg);
-
-         /* Expire old intervals.  Intervals which have ended with respect
-          * to the live interval can have their remapped registers freed.
-          */
-         {
-            GLint j;
-            for (j = 0; j < (GLint) activeIntervals.Num; j++) {
-               const struct interval *inv = activeIntervals.Intervals + j;
-               if (inv->End >= live->Start) {
-                  /* Stop now.  Since the activeInterval list is sorted
-                   * we know we don't have to go further.
-                   */
-                  break;
-               }
-               else {
-                  /* Interval 'inv' has expired */
-                  const GLint regNew = registerMap[inv->Reg];
-                  ASSERT(regNew >= 0);
-
-                  if (dbg)
-                     printf("  expire interval for reg %u\n", inv->Reg);
-
-                  /* remove interval j from active list */
-                  remove_interval(&activeIntervals, inv);
-                  j--;  /* counter-act j++ in for-loop above */
-
-                  /* return register regNew to the free pool */
-                  if (dbg)
-                     printf("  free reg %d\n", regNew);
-                  ASSERT(usedRegs[regNew] == GL_TRUE);
-                  usedRegs[regNew] = GL_FALSE;
-               }
-            }
-         }
-
-         /* find a free register for this live interval */
-         {
-            const GLint k = alloc_register(usedRegs);
-            if (k < 0) {
-               /* out of registers, give up */
-               return;
-            }
-            registerMap[live->Reg] = k;
-            maxTemp = MAX2(maxTemp, k);
-            if (dbg)
-               printf("  remap register %u -> %d\n", live->Reg, k);
-         }
-
-         /* Insert this live interval into the active list which is sorted
-          * by increasing end points.
-          */
-         insert_interval_by_end(&activeIntervals, live);
-      }
-   }
-
-   if (maxTemp + 1 < (GLint) liveIntervals.Num) {
-      /* OK, we've reduced the number of registers needed.
-       * Scan the program and replace all the old temporary register
-       * indexes with the new indexes.
-       */
-      replace_regs(prog, PROGRAM_TEMPORARY, registerMap);
-
-      prog->NumTemporaries = maxTemp + 1;
-   }
-
-   if (dbg) {
-      printf("Optimize: End live-interval register reallocation\n");
-      printf("Num temp regs before: %u  after: %u\n",
-                   liveIntervals.Num, maxTemp + 1);
-      _mesa_print_program(prog);
-   }
-}
-
-
-/**
- * Apply optimizations to the given program to eliminate unnecessary
- * instructions, temp regs, etc.
- */
-void
-_mesa_optimize_program(GLcontext *ctx, struct gl_program *program)
-{
-   _mesa_remove_extra_move_use(program);
-
-   if (1)
-      _mesa_remove_dead_code(program);
-
-   if (0) /* not tested much yet */
-      _mesa_remove_extra_moves(program);
-
-   if (0)
-      _mesa_consolidate_registers(program);
-   else
-      _mesa_reallocate_registers(program);
-}
diff --git a/src/mesa/shader/prog_optimize.h b/src/mesa/shader/prog_optimize.h
deleted file mode 100644 (file)
index 43894a2..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.5
- *
- * Copyright (C) 2009  VMware, 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
- * 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
- * VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION 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 PROG_OPT_H
-#define PROG_OPT_H
-
-
-#include "main/config.h"
-
-
-struct gl_program;
-struct prog_instruction;
-
-
-extern GLboolean
-_mesa_find_temp_intervals(const struct prog_instruction *instructions,
-                          GLuint numInstructions,
-                          GLint intBegin[MAX_PROGRAM_TEMPS],
-                          GLint intEnd[MAX_PROGRAM_TEMPS]);
-
-extern void
-_mesa_optimize_program(GLcontext *ctx, struct gl_program *program);
-
-#endif
diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c
deleted file mode 100644 (file)
index ddbfe95..0000000
+++ /dev/null
@@ -1,751 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.3
- *
- * Copyright (C) 1999-2008  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 prog_parameter.c
- * Program parameter lists and functions.
- * \author Brian Paul
- */
-
-
-#include "main/glheader.h"
-#include "main/imports.h"
-#include "main/macros.h"
-#include "prog_instruction.h"
-#include "prog_parameter.h"
-#include "prog_statevars.h"
-
-
-struct gl_program_parameter_list *
-_mesa_new_parameter_list(void)
-{
-   return CALLOC_STRUCT(gl_program_parameter_list);
-}
-
-
-struct gl_program_parameter_list *
-_mesa_new_parameter_list_sized(unsigned size)
-{
-   struct gl_program_parameter_list *p = _mesa_new_parameter_list();
-
-   if ((p != NULL) && (size != 0)) {
-      p->Size = size;
-
-      /* alloc arrays */
-      p->Parameters = (struct gl_program_parameter *)
-        calloc(1, size * sizeof(struct gl_program_parameter));
-
-      p->ParameterValues = (GLfloat (*)[4])
-         _mesa_align_malloc(size * 4 *sizeof(GLfloat), 16);
-
-
-      if ((p->Parameters == NULL) || (p->ParameterValues == NULL)) {
-        free(p->Parameters);
-        _mesa_align_free(p->ParameterValues);
-        free(p);
-        p = NULL;
-      }
-   }
-
-   return p;
-}
-
-
-/**
- * Free a parameter list and all its parameters
- */
-void
-_mesa_free_parameter_list(struct gl_program_parameter_list *paramList)
-{
-   GLuint i;
-   for (i = 0; i < paramList->NumParameters; i++) {
-      if (paramList->Parameters[i].Name)
-        free((void *) paramList->Parameters[i].Name);
-   }
-   free(paramList->Parameters);
-   if (paramList->ParameterValues)
-      _mesa_align_free(paramList->ParameterValues);
-   free(paramList);
-}
-
-
-/**
- * Add a new parameter to a parameter list.
- * Note that parameter values are usually 4-element GLfloat vectors.
- * When size > 4 we'll allocate a sequential block of parameters to
- * store all the values (in blocks of 4).
- *
- * \param paramList  the list to add the parameter to
- * \param type  type of parameter, such as 
- * \param name  the parameter name, will be duplicated/copied!
- * \param size  number of elements in 'values' vector (1..4, or more)
- * \param datatype  GL_FLOAT, GL_FLOAT_VECx, GL_INT, GL_INT_VECx or GL_NONE.
- * \param values  initial parameter value, up to 4 GLfloats, or NULL
- * \param state  state indexes, or NULL
- * \return  index of new parameter in the list, or -1 if error (out of mem)
- */
-GLint
-_mesa_add_parameter(struct gl_program_parameter_list *paramList,
-                    gl_register_file type, const char *name,
-                    GLuint size, GLenum datatype, const GLfloat *values,
-                    const gl_state_index state[STATE_LENGTH],
-                    GLbitfield flags)
-{
-   const GLuint oldNum = paramList->NumParameters;
-   const GLuint sz4 = (size + 3) / 4; /* no. of new param slots needed */
-
-   assert(size > 0);
-
-   if (oldNum + sz4 > paramList->Size) {
-      /* Need to grow the parameter list array (alloc some extra) */
-      paramList->Size = paramList->Size + 4 * sz4;
-
-      /* realloc arrays */
-      paramList->Parameters = (struct gl_program_parameter *)
-        _mesa_realloc(paramList->Parameters,
-                      oldNum * sizeof(struct gl_program_parameter),
-                      paramList->Size * sizeof(struct gl_program_parameter));
-
-      paramList->ParameterValues = (GLfloat (*)[4])
-         _mesa_align_realloc(paramList->ParameterValues,         /* old buf */
-                             oldNum * 4 * sizeof(GLfloat),      /* old size */
-                             paramList->Size * 4 *sizeof(GLfloat), /* new sz */
-                             16);
-   }
-
-   if (!paramList->Parameters ||
-       !paramList->ParameterValues) {
-      /* out of memory */
-      paramList->NumParameters = 0;
-      paramList->Size = 0;
-      return -1;
-   }
-   else {
-      GLuint i;
-
-      paramList->NumParameters = oldNum + sz4;
-
-      memset(&paramList->Parameters[oldNum], 0,
-             sz4 * sizeof(struct gl_program_parameter));
-
-      for (i = 0; i < sz4; i++) {
-         struct gl_program_parameter *p = paramList->Parameters + oldNum + i;
-         p->Name = name ? _mesa_strdup(name) : NULL;
-         p->Type = type;
-         p->Size = size;
-         p->DataType = datatype;
-         p->Flags = flags;
-         if (values) {
-            COPY_4V(paramList->ParameterValues[oldNum + i], values);
-            values += 4;
-            p->Initialized = GL_TRUE;
-         }
-         else {
-            /* silence valgrind */
-            ASSIGN_4V(paramList->ParameterValues[oldNum + i], 0, 0, 0, 0);
-         }
-         size -= 4;
-      }
-
-      if (state) {
-         for (i = 0; i < STATE_LENGTH; i++)
-            paramList->Parameters[oldNum].StateIndexes[i] = state[i];
-      }
-
-      return (GLint) oldNum;
-   }
-}
-
-
-/**
- * Add a new named program parameter (Ex: NV_fragment_program DEFINE statement)
- * \return index of the new entry in the parameter list
- */
-GLint
-_mesa_add_named_parameter(struct gl_program_parameter_list *paramList,
-                          const char *name, const GLfloat values[4])
-{
-   return _mesa_add_parameter(paramList, PROGRAM_NAMED_PARAM, name,
-                              4, GL_NONE, values, NULL, 0x0);
-                              
-}
-
-
-/**
- * Add a new named constant to the parameter list.
- * This will be used when the program contains something like this:
- *    PARAM myVals = { 0, 1, 2, 3 };
- *
- * \param paramList  the parameter list
- * \param name  the name for the constant
- * \param values  four float values
- * \return index/position of the new parameter in the parameter list
- */
-GLint
-_mesa_add_named_constant(struct gl_program_parameter_list *paramList,
-                         const char *name, const GLfloat values[4],
-                         GLuint size)
-{
-   /* first check if this is a duplicate constant */
-   GLint pos;
-   for (pos = 0; pos < (GLint)paramList->NumParameters; pos++) {
-      const GLfloat *pvals = paramList->ParameterValues[pos];
-      if (pvals[0] == values[0] &&
-          pvals[1] == values[1] &&
-          pvals[2] == values[2] &&
-          pvals[3] == values[3] &&
-          strcmp(paramList->Parameters[pos].Name, name) == 0) {
-         /* Same name and value is already in the param list - reuse it */
-         return pos;
-      }
-   }
-   /* not found, add new parameter */
-   return _mesa_add_parameter(paramList, PROGRAM_CONSTANT, name,
-                              size, GL_NONE, values, NULL, 0x0);
-}
-
-
-/**
- * Add a new unnamed constant to the parameter list.  This will be used
- * when a fragment/vertex program contains something like this:
- *    MOV r, { 0, 1, 2, 3 };
- * If swizzleOut is non-null we'll search the parameter list for an
- * existing instance of the constant which matches with a swizzle.
- *
- * \param paramList  the parameter list
- * \param values  four float values
- * \param swizzleOut  returns swizzle mask for accessing the constant
- * \return index/position of the new parameter in the parameter list.
- */
-GLint
-_mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList,
-                           const GLfloat values[4], GLuint size,
-                           GLuint *swizzleOut)
-{
-   GLint pos;
-   ASSERT(size >= 1);
-   ASSERT(size <= 4);
-
-   if (swizzleOut &&
-       _mesa_lookup_parameter_constant(paramList, values,
-                                       size, &pos, swizzleOut)) {
-      return pos;
-   }
-
-   /* Look for empty space in an already unnamed constant parameter
-    * to add this constant.  This will only work for single-element
-    * constants because we rely on smearing (i.e. .yyyy or .zzzz).
-    */
-   if (size == 1 && swizzleOut) {
-      for (pos = 0; pos < (GLint) paramList->NumParameters; pos++) {
-         struct gl_program_parameter *p = paramList->Parameters + pos;
-         if (p->Type == PROGRAM_CONSTANT && p->Size + size <= 4) {
-            /* ok, found room */
-            GLfloat *pVal = paramList->ParameterValues[pos];
-            GLuint swz = p->Size; /* 1, 2 or 3 for Y, Z, W */
-            pVal[p->Size] = values[0];
-            p->Size++;
-            *swizzleOut = MAKE_SWIZZLE4(swz, swz, swz, swz);
-            return pos;
-         }
-      }
-   }
-
-   /* add a new parameter to store this constant */
-   pos = _mesa_add_parameter(paramList, PROGRAM_CONSTANT, NULL,
-                             size, GL_NONE, values, NULL, 0x0);
-   if (pos >= 0 && swizzleOut) {
-      if (size == 1)
-         *swizzleOut = SWIZZLE_XXXX;
-      else
-         *swizzleOut = SWIZZLE_NOOP;
-   }
-   return pos;
-}
-
-
-/**
- * Add a uniform to the parameter list.
- * Note that if the uniform is an array, size may be greater than
- * what's implied by the datatype.
- * \param name  uniform's name
- * \param size  number of floats to allocate
- * \param datatype  GL_FLOAT_VEC3, GL_FLOAT_MAT4, etc.
- */
-GLint
-_mesa_add_uniform(struct gl_program_parameter_list *paramList,
-                  const char *name, GLuint size, GLenum datatype,
-                  const GLfloat *values)
-{
-   GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
-   ASSERT(datatype != GL_NONE);
-   if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_UNIFORM) {
-      ASSERT(paramList->Parameters[i].Size == size);
-      ASSERT(paramList->Parameters[i].DataType == datatype);
-      /* already in list */
-      return i;
-   }
-   else {
-      i = _mesa_add_parameter(paramList, PROGRAM_UNIFORM, name,
-                              size, datatype, values, NULL, 0x0);
-      return i;
-   }
-}
-
-
-/**
- * Mark the named uniform as 'used'.
- */
-void
-_mesa_use_uniform(struct gl_program_parameter_list *paramList,
-                  const char *name)
-{
-   GLuint i;
-   for (i = 0; i < paramList->NumParameters; i++) {
-      struct gl_program_parameter *p = paramList->Parameters + i;
-      if ((p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) &&
-          strcmp(p->Name, name) == 0) {
-         p->Used = GL_TRUE;
-         /* Note that large uniforms may occupy several slots so we're
-          * not done searching yet.
-          */
-      }
-   }
-}
-
-
-/**
- * Add a sampler to the parameter list.
- * \param name  uniform's name
- * \param datatype  GL_SAMPLER_2D, GL_SAMPLER_2D_RECT_ARB, etc.
- * \param index  the sampler number (as seen in TEX instructions)
- * \return  sampler index (starting at zero) or -1 if error
- */
-GLint
-_mesa_add_sampler(struct gl_program_parameter_list *paramList,
-                  const char *name, GLenum datatype)
-{
-   GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
-   if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_SAMPLER) {
-      ASSERT(paramList->Parameters[i].Size == 1);
-      ASSERT(paramList->Parameters[i].DataType == datatype);
-      /* already in list */
-      return (GLint) paramList->ParameterValues[i][0];
-   }
-   else {
-      GLuint i;
-      const GLint size = 1; /* a sampler is basically a texture unit number */
-      GLfloat value[4];
-      GLint numSamplers = 0;
-      for (i = 0; i < paramList->NumParameters; i++) {
-         if (paramList->Parameters[i].Type == PROGRAM_SAMPLER)
-            numSamplers++;
-      }
-      value[0] = (GLfloat) numSamplers;
-      value[1] = value[2] = value[3] = 0.0F;
-      (void) _mesa_add_parameter(paramList, PROGRAM_SAMPLER, name,
-                                 size, datatype, value, NULL, 0x0);
-      return numSamplers;
-   }
-}
-
-
-/**
- * Add parameter representing a varying variable.
- */
-GLint
-_mesa_add_varying(struct gl_program_parameter_list *paramList,
-                  const char *name, GLuint size, GLenum datatype,
-                  GLbitfield flags)
-{
-   GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
-   if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_VARYING) {
-      /* already in list */
-      return i;
-   }
-   else {
-      /*assert(size == 4);*/
-      i = _mesa_add_parameter(paramList, PROGRAM_VARYING, name,
-                              size, datatype, NULL, NULL, flags);
-      return i;
-   }
-}
-
-
-/**
- * Add parameter representing a vertex program attribute.
- * \param size  size of attribute (in floats), may be -1 if unknown
- * \param attrib  the attribute index, or -1 if unknown
- */
-GLint
-_mesa_add_attribute(struct gl_program_parameter_list *paramList,
-                    const char *name, GLint size, GLenum datatype, GLint attrib)
-{
-   GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
-   if (i >= 0) {
-      /* replace */
-      if (attrib < 0)
-         attrib = i;
-      paramList->Parameters[i].StateIndexes[0] = attrib;
-   }
-   else {
-      /* add */
-      gl_state_index state[STATE_LENGTH];
-      state[0] = (gl_state_index) attrib;
-      if (size < 0)
-         size = 4;
-      i = _mesa_add_parameter(paramList, PROGRAM_INPUT, name,
-                              size, datatype, NULL, state, 0x0);
-   }
-   return i;
-}
-
-
-
-#if 0 /* not used yet */
-/**
- * Returns the number of 4-component registers needed to store a piece
- * of GL state.  For matrices this may be as many as 4 registers,
- * everything else needs
- * just 1 register.
- */
-static GLuint
-sizeof_state_reference(const GLint *stateTokens)
-{
-   if (stateTokens[0] == STATE_MATRIX) {
-      GLuint rows = stateTokens[4] - stateTokens[3] + 1;
-      assert(rows >= 1);
-      assert(rows <= 4);
-      return rows;
-   }
-   else {
-      return 1;
-   }
-}
-#endif
-
-
-/**
- * Add a new state reference to the parameter list.
- * This will be used when the program contains something like this:
- *    PARAM ambient = state.material.front.ambient;
- *
- * \param paramList  the parameter list
- * \param stateTokens  an array of 5 (STATE_LENGTH) state tokens
- * \return index of the new parameter.
- */
-GLint
-_mesa_add_state_reference(struct gl_program_parameter_list *paramList,
-                          const gl_state_index stateTokens[STATE_LENGTH])
-{
-   const GLuint size = 4; /* XXX fix */
-   char *name;
-   GLint index;
-
-   /* Check if the state reference is already in the list */
-   for (index = 0; index < (GLint) paramList->NumParameters; index++) {
-      GLuint i, match = 0;
-      for (i = 0; i < STATE_LENGTH; i++) {
-         if (paramList->Parameters[index].StateIndexes[i] == stateTokens[i]) {
-            match++;
-         }
-         else {
-            break;
-         }
-      }
-      if (match == STATE_LENGTH) {
-         /* this state reference is already in the parameter list */
-         return index;
-      }
-   }
-
-   name = _mesa_program_state_string(stateTokens);
-   index = _mesa_add_parameter(paramList, PROGRAM_STATE_VAR, name,
-                               size, GL_NONE,
-                               NULL, (gl_state_index *) stateTokens, 0x0);
-   paramList->StateFlags |= _mesa_program_state_flags(stateTokens);
-
-   /* free name string here since we duplicated it in add_parameter() */
-   free(name);
-
-   return index;
-}
-
-
-/**
- * Lookup a parameter value by name in the given parameter list.
- * \return pointer to the float[4] values.
- */
-GLfloat *
-_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList,
-                             GLsizei nameLen, const char *name)
-{
-   GLint i = _mesa_lookup_parameter_index(paramList, nameLen, name);
-   if (i < 0)
-      return NULL;
-   else
-      return paramList->ParameterValues[i];
-}
-
-
-/**
- * Given a program parameter name, find its position in the list of parameters.
- * \param paramList  the parameter list to search
- * \param nameLen  length of name (in chars).
- *                 If length is negative, assume that name is null-terminated.
- * \param name  the name to search for
- * \return index of parameter in the list.
- */
-GLint
-_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList,
-                             GLsizei nameLen, const char *name)
-{
-   GLint i;
-
-   if (!paramList)
-      return -1;
-
-   if (nameLen == -1) {
-      /* name is null-terminated */
-      for (i = 0; i < (GLint) paramList->NumParameters; i++) {
-         if (paramList->Parameters[i].Name &&
-            strcmp(paramList->Parameters[i].Name, name) == 0)
-            return i;
-      }
-   }
-   else {
-      /* name is not null-terminated, use nameLen */
-      for (i = 0; i < (GLint) paramList->NumParameters; i++) {
-         if (paramList->Parameters[i].Name &&
-            strncmp(paramList->Parameters[i].Name, name, nameLen) == 0
-             && strlen(paramList->Parameters[i].Name) == (size_t)nameLen)
-            return i;
-      }
-   }
-   return -1;
-}
-
-
-/**
- * Look for a float vector in the given parameter list.  The float vector
- * may be of length 1, 2, 3 or 4.  If swizzleOut is non-null, we'll try
- * swizzling to find a match.
- * \param list  the parameter list to search
- * \param v  the float vector to search for
- * \param vSize  number of element in v
- * \param posOut  returns the position of the constant, if found
- * \param swizzleOut  returns a swizzle mask describing location of the
- *                    vector elements if found.
- * \return GL_TRUE if found, GL_FALSE if not found
- */
-GLboolean
-_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list,
-                                const GLfloat v[], GLuint vSize,
-                                GLint *posOut, GLuint *swizzleOut)
-{
-   GLuint i;
-
-   assert(vSize >= 1);
-   assert(vSize <= 4);
-
-   if (!list)
-      return -1;
-
-   for (i = 0; i < list->NumParameters; i++) {
-      if (list->Parameters[i].Type == PROGRAM_CONSTANT) {
-         if (!swizzleOut) {
-            /* swizzle not allowed */
-            GLuint j, match = 0;
-            for (j = 0; j < vSize; j++) {
-               if (v[j] == list->ParameterValues[i][j])
-                  match++;
-            }
-            if (match == vSize) {
-               *posOut = i;
-               return GL_TRUE;
-            }
-         }
-         else {
-            /* try matching w/ swizzle */
-             if (vSize == 1) {
-                /* look for v[0] anywhere within float[4] value */
-                GLuint j;
-                for (j = 0; j < list->Parameters[i].Size; j++) {
-                   if (list->ParameterValues[i][j] == v[0]) {
-                      /* found it */
-                      *posOut = i;
-                      *swizzleOut = MAKE_SWIZZLE4(j, j, j, j);
-                      return GL_TRUE;
-                   }
-                }
-             }
-             else if (vSize <= list->Parameters[i].Size) {
-                /* see if we can match this constant (with a swizzle) */
-                GLuint swz[4];
-                GLuint match = 0, j, k;
-                for (j = 0; j < vSize; j++) {
-                   if (v[j] == list->ParameterValues[i][j]) {
-                      swz[j] = j;
-                      match++;
-                   }
-                   else {
-                      for (k = 0; k < list->Parameters[i].Size; k++) {
-                         if (v[j] == list->ParameterValues[i][k]) {
-                            swz[j] = k;
-                            match++;
-                            break;
-                         }
-                      }
-                   }
-                }
-                /* smear last value to remaining positions */
-                for (; j < 4; j++)
-                   swz[j] = swz[j-1];
-
-                if (match == vSize) {
-                   *posOut = i;
-                   *swizzleOut = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
-                   return GL_TRUE;
-                }
-             }
-         }
-      }
-   }
-
-   *posOut = -1;
-   return GL_FALSE;
-}
-
-
-struct gl_program_parameter_list *
-_mesa_clone_parameter_list(const struct gl_program_parameter_list *list)
-{
-   struct gl_program_parameter_list *clone;
-   GLuint i;
-
-   clone = _mesa_new_parameter_list();
-   if (!clone)
-      return NULL;
-
-   /** Not too efficient, but correct */
-   for (i = 0; i < list->NumParameters; i++) {
-      struct gl_program_parameter *p = list->Parameters + i;
-      struct gl_program_parameter *pCopy;
-      GLuint size = MIN2(p->Size, 4);
-      GLint j = _mesa_add_parameter(clone, p->Type, p->Name, size, p->DataType,
-                                    list->ParameterValues[i], NULL, 0x0);
-      ASSERT(j >= 0);
-      pCopy = clone->Parameters + j;
-      pCopy->Used = p->Used;
-      pCopy->Flags = p->Flags;
-      /* copy state indexes */
-      if (p->Type == PROGRAM_STATE_VAR) {
-         GLint k;
-         for (k = 0; k < STATE_LENGTH; k++) {
-            pCopy->StateIndexes[k] = p->StateIndexes[k];
-         }
-      }
-      else {
-         clone->Parameters[j].Size = p->Size;
-      }
-      
-   }
-
-   clone->StateFlags = list->StateFlags;
-
-   return clone;
-}
-
-
-/**
- * Return a new parameter list which is listA + listB.
- */
-struct gl_program_parameter_list *
-_mesa_combine_parameter_lists(const struct gl_program_parameter_list *listA,
-                              const struct gl_program_parameter_list *listB)
-{
-   struct gl_program_parameter_list *list;
-
-   if (listA) {
-      list = _mesa_clone_parameter_list(listA);
-      if (list && listB) {
-         GLuint i;
-         for (i = 0; i < listB->NumParameters; i++) {
-            struct gl_program_parameter *param = listB->Parameters + i;
-            _mesa_add_parameter(list, param->Type, param->Name, param->Size,
-                                param->DataType,
-                                listB->ParameterValues[i],
-                                param->StateIndexes,
-                                param->Flags);
-         }
-      }
-   }
-   else if (listB) {
-      list = _mesa_clone_parameter_list(listB);
-   }
-   else {
-      list = NULL;
-   }
-   return list;
-}
-
-
-
-/**
- * Find longest name of all uniform parameters in list.
- */
-GLuint
-_mesa_longest_parameter_name(const struct gl_program_parameter_list *list,
-                             gl_register_file type)
-{
-   GLuint i, maxLen = 0;
-   if (!list)
-      return 0;
-   for (i = 0; i < list->NumParameters; i++) {
-      if (list->Parameters[i].Type == type) {
-         GLuint len = strlen(list->Parameters[i].Name);
-         if (len > maxLen)
-            maxLen = len;
-      }
-   }
-   return maxLen;
-}
-
-
-/**
- * Count the number of parameters in the last that match the given type.
- */
-GLuint
-_mesa_num_parameters_of_type(const struct gl_program_parameter_list *list,
-                             gl_register_file type)
-{
-   GLuint i, count = 0;
-   if (list) {
-      for (i = 0; i < list->NumParameters; i++) {
-         if (list->Parameters[i].Type == type)
-            count++;
-      }
-   }
-   return count;
-}
diff --git a/src/mesa/shader/prog_parameter.h b/src/mesa/shader/prog_parameter.h
deleted file mode 100644 (file)
index cc3378a..0000000
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.3
- *
- * Copyright (C) 1999-2008  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 prog_parameter.c
- * Program parameter lists and functions.
- * \author Brian Paul
- */
-
-#ifndef PROG_PARAMETER_H
-#define PROG_PARAMETER_H
-
-#include "main/mtypes.h"
-#include "prog_statevars.h"
-
-
-/**
- * Program parameter flags
- */
-/*@{*/
-#define PROG_PARAM_BIT_CENTROID   0x1  /**< for varying vars (GLSL 1.20) */
-#define PROG_PARAM_BIT_INVARIANT  0x2  /**< for varying vars (GLSL 1.20) */
-#define PROG_PARAM_BIT_FLAT       0x4  /**< for varying vars (GLSL 1.30) */
-#define PROG_PARAM_BIT_LINEAR     0x8  /**< for varying vars (GLSL 1.30) */
-#define PROG_PARAM_BIT_CYL_WRAP  0x10  /**< XXX gallium debug */
-/*@}*/
-
-
-
-/**
- * Program parameter.
- * Used by shaders/programs for uniforms, constants, varying vars, etc.
- */
-struct gl_program_parameter
-{
-   const char *Name;        /**< Null-terminated string */
-   gl_register_file Type;   /**< PROGRAM_NAMED_PARAM, CONSTANT or STATE_VAR */
-   GLenum DataType;         /**< GL_FLOAT, GL_FLOAT_VEC2, etc */
-   /**
-    * Number of components (1..4), or more.
-    * If the number of components is greater than 4,
-    * this parameter is part of a larger uniform like a GLSL matrix or array.
-    * The next program parameter's Size will be Size-4 of this parameter.
-    */
-   GLuint Size;
-   GLboolean Used;          /**< Helper flag for GLSL uniform tracking */
-   GLboolean Initialized;   /**< Has the ParameterValue[] been set? */
-   GLbitfield Flags;        /**< Bitmask of PROG_PARAM_*_BIT */
-   /**
-    * A sequence of STATE_* tokens and integers to identify GL state.
-    */
-   gl_state_index StateIndexes[STATE_LENGTH];
-};
-
-
-/**
- * List of gl_program_parameter instances.
- */
-struct gl_program_parameter_list
-{
-   GLuint Size;           /**< allocated size of Parameters, ParameterValues */
-   GLuint NumParameters;  /**< number of parameters in arrays */
-   struct gl_program_parameter *Parameters; /**< Array [Size] */
-   GLfloat (*ParameterValues)[4];        /**< Array [Size] of GLfloat[4] */
-   GLbitfield StateFlags; /**< _NEW_* flags indicating which state changes
-                               might invalidate ParameterValues[] */
-};
-
-
-extern struct gl_program_parameter_list *
-_mesa_new_parameter_list(void);
-
-extern struct gl_program_parameter_list *
-_mesa_new_parameter_list_sized(unsigned size);
-
-extern void
-_mesa_free_parameter_list(struct gl_program_parameter_list *paramList);
-
-extern struct gl_program_parameter_list *
-_mesa_clone_parameter_list(const struct gl_program_parameter_list *list);
-
-extern struct gl_program_parameter_list *
-_mesa_combine_parameter_lists(const struct gl_program_parameter_list *a,
-                              const struct gl_program_parameter_list *b);
-
-static INLINE GLuint
-_mesa_num_parameters(const struct gl_program_parameter_list *list)
-{
-   return list ? list->NumParameters : 0;
-}
-
-extern GLint
-_mesa_add_parameter(struct gl_program_parameter_list *paramList,
-                    gl_register_file type, const char *name,
-                    GLuint size, GLenum datatype, const GLfloat *values,
-                    const gl_state_index state[STATE_LENGTH],
-                    GLbitfield flags);
-
-extern GLint
-_mesa_add_named_parameter(struct gl_program_parameter_list *paramList,
-                          const char *name, const GLfloat values[4]);
-
-extern GLint
-_mesa_add_named_constant(struct gl_program_parameter_list *paramList,
-                         const char *name, const GLfloat values[4],
-                         GLuint size);
-
-extern GLint
-_mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList,
-                           const GLfloat values[4], GLuint size,
-                           GLuint *swizzleOut);
-
-extern GLint
-_mesa_add_uniform(struct gl_program_parameter_list *paramList,
-                  const char *name, GLuint size, GLenum datatype,
-                  const GLfloat *values);
-
-extern void
-_mesa_use_uniform(struct gl_program_parameter_list *paramList,
-                  const char *name);
-
-extern GLint
-_mesa_add_sampler(struct gl_program_parameter_list *paramList,
-                  const char *name, GLenum datatype);
-
-extern GLint
-_mesa_add_varying(struct gl_program_parameter_list *paramList,
-                  const char *name, GLuint size, GLenum datatype,
-                  GLbitfield flags);
-
-extern GLint
-_mesa_add_attribute(struct gl_program_parameter_list *paramList,
-                    const char *name, GLint size, GLenum datatype, GLint attrib);
-
-extern GLint
-_mesa_add_state_reference(struct gl_program_parameter_list *paramList,
-                          const gl_state_index stateTokens[STATE_LENGTH]);
-
-extern GLfloat *
-_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList,
-                             GLsizei nameLen, const char *name);
-
-extern GLint
-_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList,
-                             GLsizei nameLen, const char *name);
-
-extern GLboolean
-_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list,
-                                const GLfloat v[], GLuint vSize,
-                                GLint *posOut, GLuint *swizzleOut);
-
-extern GLuint
-_mesa_longest_parameter_name(const struct gl_program_parameter_list *list,
-                             gl_register_file type);
-
-extern GLuint
-_mesa_num_parameters_of_type(const struct gl_program_parameter_list *list,
-                             gl_register_file type);
-
-
-#endif /* PROG_PARAMETER_H */
diff --git a/src/mesa/shader/prog_parameter_layout.c b/src/mesa/shader/prog_parameter_layout.c
deleted file mode 100644 (file)
index a888573..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright Â© 2009 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION 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 prog_parameter_layout.c
- * \brief Helper functions to layout storage for program parameters
- *
- * \author Ian Romanick <ian.d.romanick@intel.com>
- */
-
-#include "main/mtypes.h"
-#include "prog_parameter.h"
-#include "prog_parameter_layout.h"
-#include "prog_instruction.h"
-#include "program_parser.h"
-
-unsigned
-_mesa_combine_swizzles(unsigned base, unsigned applied)
-{
-   unsigned swiz = 0;
-   unsigned i;
-
-   for (i = 0; i < 4; i++) {
-      const unsigned s = GET_SWZ(applied, i);
-
-      swiz |= ((s <= SWIZZLE_W) ? GET_SWZ(base, s) : s) << (i * 3);
-   }
-
-   return swiz;
-}
-
-
-/**
- * Copy indirect access array from one parameter list to another
- *
- * \param src   Parameter array copied from
- * \param dst   Parameter array copied to
- * \param first Index of first element in \c src to copy
- * \param count Number of elements to copy
- *
- * \return
- * The location in \c dst of the first element copied from \c src on
- * success.  -1 on failure.
- *
- * \warning
- * This function assumes that there is already enough space available in
- * \c dst to hold all of the elements that will be copied over.
- */
-static int
-copy_indirect_accessed_array(struct gl_program_parameter_list *src,
-                            struct gl_program_parameter_list *dst,
-                            unsigned first, unsigned count)
-{
-   const int base = dst->NumParameters;
-   unsigned i, j;
-
-   for (i = first; i < (first + count); i++) {
-      struct gl_program_parameter *curr = & src->Parameters[i];
-
-      if (curr->Type == PROGRAM_CONSTANT) {
-        j = dst->NumParameters;
-      } else {
-        for (j = 0; j < dst->NumParameters; j++) {
-           if (memcmp(dst->Parameters[j].StateIndexes, curr->StateIndexes, 
-                      sizeof(curr->StateIndexes)) == 0) {
-              return -1;
-           }
-        }
-      }
-
-      assert(j == dst->NumParameters);
-
-      /* copy src parameter [i] to dest parameter [j] */
-      memcpy(& dst->Parameters[j], curr,
-            sizeof(dst->Parameters[j]));
-      memcpy(dst->ParameterValues[j], src->ParameterValues[i],
-            sizeof(GLfloat) * 4);
-
-      /* Pointer to the string name was copied.  Null-out src param name
-       * to prevent double free later.
-       */
-      curr->Name = NULL;
-
-      dst->NumParameters++;
-   }
-
-   return base;
-}
-
-
-/**
- * XXX description???
- * \return GL_TRUE for success, GL_FALSE for failure
- */
-GLboolean
-_mesa_layout_parameters(struct asm_parser_state *state)
-{
-   struct gl_program_parameter_list *layout;
-   struct asm_instruction *inst;
-   unsigned i;
-
-   layout =
-      _mesa_new_parameter_list_sized(state->prog->Parameters->NumParameters);
-
-   /* PASS 1:  Move any parameters that are accessed indirectly from the
-    * original parameter list to the new parameter list.
-    */
-   for (inst = state->inst_head; inst != NULL; inst = inst->next) {
-      for (i = 0; i < 3; i++) {
-        if (inst->SrcReg[i].Base.RelAddr) {
-           /* Only attempt to add the to the new parameter list once.
-            */
-           if (!inst->SrcReg[i].Symbol->pass1_done) {
-              const int new_begin =
-                 copy_indirect_accessed_array(state->prog->Parameters, layout,
-                     inst->SrcReg[i].Symbol->param_binding_begin,
-                     inst->SrcReg[i].Symbol->param_binding_length);
-
-              if (new_begin < 0) {
-                 return GL_FALSE;
-              }
-
-              inst->SrcReg[i].Symbol->param_binding_begin = new_begin;
-              inst->SrcReg[i].Symbol->pass1_done = 1;
-           }
-
-           /* Previously the Index was just the offset from the parameter
-            * array.  Now that the base of the parameter array is known, the
-            * index can be updated to its actual value.
-            */
-           inst->Base.SrcReg[i] = inst->SrcReg[i].Base;
-           inst->Base.SrcReg[i].Index +=
-              inst->SrcReg[i].Symbol->param_binding_begin;
-        }
-      }
-   }
-
-   /* PASS 2:  Move any parameters that are not accessed indirectly from the
-    * original parameter list to the new parameter list.
-    */
-   for (inst = state->inst_head; inst != NULL; inst = inst->next) {
-      for (i = 0; i < 3; i++) {
-        const struct gl_program_parameter *p;
-        const int idx = inst->SrcReg[i].Base.Index;
-        unsigned swizzle = SWIZZLE_NOOP;
-
-        /* All relative addressed operands were processed on the first
-         * pass.  Just skip them here.
-         */
-        if (inst->SrcReg[i].Base.RelAddr) {
-           continue;
-        }
-
-        if ((inst->SrcReg[i].Base.File <= PROGRAM_VARYING )
-            || (inst->SrcReg[i].Base.File >= PROGRAM_WRITE_ONLY)) {
-           continue;
-        }
-
-        inst->Base.SrcReg[i] = inst->SrcReg[i].Base;
-        p = & state->prog->Parameters->Parameters[idx];
-
-        switch (p->Type) {
-        case PROGRAM_CONSTANT: {
-           const float *const v =
-              state->prog->Parameters->ParameterValues[idx];
-
-           inst->Base.SrcReg[i].Index =
-              _mesa_add_unnamed_constant(layout, v, p->Size, & swizzle);
-
-           inst->Base.SrcReg[i].Swizzle = 
-              _mesa_combine_swizzles(swizzle, inst->Base.SrcReg[i].Swizzle);
-           break;
-        }
-
-        case PROGRAM_STATE_VAR:
-           inst->Base.SrcReg[i].Index =
-              _mesa_add_state_reference(layout, p->StateIndexes);
-           break;
-
-        default:
-           break;
-        }
-
-        inst->SrcReg[i].Base.File = p->Type;
-        inst->Base.SrcReg[i].File = p->Type;
-      }
-   }
-
-   _mesa_free_parameter_list(state->prog->Parameters);
-   state->prog->Parameters = layout;
-
-   return GL_TRUE;
-}
diff --git a/src/mesa/shader/prog_parameter_layout.h b/src/mesa/shader/prog_parameter_layout.h
deleted file mode 100644 (file)
index 99a7b6c..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright Â© 2009 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION 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 prog_parameter_layout.h
- * \brief Helper functions to layout storage for program parameters
- *
- * \author Ian Romanick <ian.d.romanick@intel.com>
- */
-
-#pragma once
-
-#ifndef PROG_PARAMETER_LAYOUT_H
-#define PROG_PARAMETER_LAYOUT_H
-
-extern unsigned _mesa_combine_swizzles(unsigned base, unsigned applied);
-
-struct asm_parser_state;
-
-extern GLboolean _mesa_layout_parameters(struct asm_parser_state *state);
-
-#endif /* PROG_PARAMETER_LAYOUT_H */
diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c
deleted file mode 100644 (file)
index 05aae83..0000000
+++ /dev/null
@@ -1,1065 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.3
- *
- * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
- * Copyright (C) 2009  VMware, 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
- * 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 prog_print.c
- * Print vertex/fragment programs - for debugging.
- * \author Brian Paul
- */
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/imports.h"
-#include "prog_instruction.h"
-#include "prog_parameter.h"
-#include "prog_print.h"
-#include "prog_statevars.h"
-
-
-
-/**
- * Return string name for given program/register file.
- */
-static const char *
-file_string(gl_register_file f, gl_prog_print_mode mode)
-{
-   switch (f) {
-   case PROGRAM_TEMPORARY:
-      return "TEMP";
-   case PROGRAM_LOCAL_PARAM:
-      return "LOCAL";
-   case PROGRAM_ENV_PARAM:
-      return "ENV";
-   case PROGRAM_STATE_VAR:
-      return "STATE";
-   case PROGRAM_INPUT:
-      return "INPUT";
-   case PROGRAM_OUTPUT:
-      return "OUTPUT";
-   case PROGRAM_NAMED_PARAM:
-      return "NAMED";
-   case PROGRAM_CONSTANT:
-      return "CONST";
-   case PROGRAM_UNIFORM:
-      return "UNIFORM";
-   case PROGRAM_VARYING:
-      return "VARYING";
-   case PROGRAM_WRITE_ONLY:
-      return "WRITE_ONLY";
-   case PROGRAM_ADDRESS:
-      return "ADDR";
-   case PROGRAM_SAMPLER:
-      return "SAMPLER";
-   case PROGRAM_UNDEFINED:
-      return "UNDEFINED";
-   default:
-      {
-         static char s[20];
-         _mesa_snprintf(s, sizeof(s), "FILE%u", f);
-         return s;
-      }
-   }
-}
-
-
-/**
- * Return ARB_v/f_prog-style input attrib string.
- */
-static const char *
-arb_input_attrib_string(GLint index, GLenum progType)
-{
-   /*
-    * These strings should match the VERT_ATTRIB_x and FRAG_ATTRIB_x tokens.
-    */
-   const char *vertAttribs[] = {
-      "vertex.position",
-      "vertex.weight",
-      "vertex.normal",
-      "vertex.color.primary",
-      "vertex.color.secondary",
-      "vertex.fogcoord",
-      "vertex.(six)",
-      "vertex.(seven)",
-      "vertex.texcoord[0]",
-      "vertex.texcoord[1]",
-      "vertex.texcoord[2]",
-      "vertex.texcoord[3]",
-      "vertex.texcoord[4]",
-      "vertex.texcoord[5]",
-      "vertex.texcoord[6]",
-      "vertex.texcoord[7]",
-      "vertex.attrib[0]",
-      "vertex.attrib[1]",
-      "vertex.attrib[2]",
-      "vertex.attrib[3]",
-      "vertex.attrib[4]",
-      "vertex.attrib[5]",
-      "vertex.attrib[6]",
-      "vertex.attrib[7]",
-      "vertex.attrib[8]",
-      "vertex.attrib[9]",
-      "vertex.attrib[10]",
-      "vertex.attrib[11]",
-      "vertex.attrib[12]",
-      "vertex.attrib[13]",
-      "vertex.attrib[14]",
-      "vertex.attrib[15]"
-   };
-   const char *fragAttribs[] = {
-      "fragment.position",
-      "fragment.color.primary",
-      "fragment.color.secondary",
-      "fragment.fogcoord",
-      "fragment.texcoord[0]",
-      "fragment.texcoord[1]",
-      "fragment.texcoord[2]",
-      "fragment.texcoord[3]",
-      "fragment.texcoord[4]",
-      "fragment.texcoord[5]",
-      "fragment.texcoord[6]",
-      "fragment.texcoord[7]",
-      "fragment.varying[0]",
-      "fragment.varying[1]",
-      "fragment.varying[2]",
-      "fragment.varying[3]",
-      "fragment.varying[4]",
-      "fragment.varying[5]",
-      "fragment.varying[6]",
-      "fragment.varying[7]"
-   };
-
-   /* sanity checks */
-   assert(strcmp(vertAttribs[VERT_ATTRIB_TEX0], "vertex.texcoord[0]") == 0);
-   assert(strcmp(vertAttribs[VERT_ATTRIB_GENERIC15], "vertex.attrib[15]") == 0);
-
-   if (progType == GL_VERTEX_PROGRAM_ARB) {
-      assert(index < sizeof(vertAttribs) / sizeof(vertAttribs[0]));
-      return vertAttribs[index];
-   }
-   else {
-      assert(index < sizeof(fragAttribs) / sizeof(fragAttribs[0]));
-      return fragAttribs[index];
-   }
-}
-
-
-/**
- * Print a vertex program's InputsRead field in human-readable format.
- * For debugging.
- */
-void
-_mesa_print_vp_inputs(GLbitfield inputs)
-{
-   printf("VP Inputs 0x%x: \n", inputs);
-   while (inputs) {
-      GLint attr = _mesa_ffs(inputs) - 1;
-      const char *name = arb_input_attrib_string(attr,
-                                                 GL_VERTEX_PROGRAM_ARB);
-      printf("  %d: %s\n", attr, name);
-      inputs &= ~(1 << attr);
-   }
-}
-
-
-/**
- * Print a fragment program's InputsRead field in human-readable format.
- * For debugging.
- */
-void
-_mesa_print_fp_inputs(GLbitfield inputs)
-{
-   printf("FP Inputs 0x%x: \n", inputs);
-   while (inputs) {
-      GLint attr = _mesa_ffs(inputs) - 1;
-      const char *name = arb_input_attrib_string(attr,
-                                                 GL_FRAGMENT_PROGRAM_ARB);
-      printf("  %d: %s\n", attr, name);
-      inputs &= ~(1 << attr);
-   }
-}
-
-
-
-/**
- * Return ARB_v/f_prog-style output attrib string.
- */
-static const char *
-arb_output_attrib_string(GLint index, GLenum progType)
-{
-   /*
-    * These strings should match the VERT_RESULT_x and FRAG_RESULT_x tokens.
-    */
-   const char *vertResults[] = {
-      "result.position",
-      "result.color.primary",
-      "result.color.secondary",
-      "result.fogcoord",
-      "result.texcoord[0]",
-      "result.texcoord[1]",
-      "result.texcoord[2]",
-      "result.texcoord[3]",
-      "result.texcoord[4]",
-      "result.texcoord[5]",
-      "result.texcoord[6]",
-      "result.texcoord[7]",
-      "result.varying[0]",
-      "result.varying[1]",
-      "result.varying[2]",
-      "result.varying[3]",
-      "result.varying[4]",
-      "result.varying[5]",
-      "result.varying[6]",
-      "result.varying[7]"
-   };
-   const char *fragResults[] = {
-      "result.color",
-      "result.color(half)",
-      "result.depth",
-      "result.color[0]",
-      "result.color[1]",
-      "result.color[2]",
-      "result.color[3]"
-   };
-
-   if (progType == GL_VERTEX_PROGRAM_ARB) {
-      assert(index < sizeof(vertResults) / sizeof(vertResults[0]));
-      return vertResults[index];
-   }
-   else {
-      assert(index < sizeof(fragResults) / sizeof(fragResults[0]));
-      return fragResults[index];
-   }
-}
-
-
-/**
- * Return string representation of the given register.
- * Note that some types of registers (like PROGRAM_UNIFORM) aren't defined
- * by the ARB/NV program languages so we've taken some liberties here.
- * \param f  the register file (PROGRAM_INPUT, PROGRAM_TEMPORARY, etc)
- * \param index  number of the register in the register file
- * \param mode  the output format/mode/style
- * \param prog  pointer to containing program
- */
-static const char *
-reg_string(gl_register_file f, GLint index, gl_prog_print_mode mode,
-           GLboolean relAddr, const struct gl_program *prog)
-{
-   static char str[100];
-   const char *addr = relAddr ? "ADDR+" : "";
-
-   str[0] = 0;
-
-   switch (mode) {
-   case PROG_PRINT_DEBUG:
-      sprintf(str, "%s[%s%d]", file_string(f, mode), addr, index);
-      break;
-
-   case PROG_PRINT_ARB:
-      switch (f) {
-      case PROGRAM_INPUT:
-         sprintf(str, "%s", arb_input_attrib_string(index, prog->Target));
-         break;
-      case PROGRAM_OUTPUT:
-         sprintf(str, "%s", arb_output_attrib_string(index, prog->Target));
-         break;
-      case PROGRAM_TEMPORARY:
-         sprintf(str, "temp%d", index);
-         break;
-      case PROGRAM_ENV_PARAM:
-         sprintf(str, "program.env[%s%d]", addr, index);
-         break;
-      case PROGRAM_LOCAL_PARAM:
-         sprintf(str, "program.local[%s%d]", addr, index);
-         break;
-      case PROGRAM_VARYING: /* extension */
-         sprintf(str, "varying[%s%d]", addr, index);
-         break;
-      case PROGRAM_CONSTANT: /* extension */
-         sprintf(str, "constant[%s%d]", addr, index);
-         break;
-      case PROGRAM_UNIFORM: /* extension */
-         sprintf(str, "uniform[%s%d]", addr, index);
-         break;
-      case PROGRAM_STATE_VAR:
-         {
-            struct gl_program_parameter *param
-               = prog->Parameters->Parameters + index;
-            char *state = _mesa_program_state_string(param->StateIndexes);
-            sprintf(str, "%s", state);
-            free(state);
-         }
-         break;
-      case PROGRAM_ADDRESS:
-         sprintf(str, "A%d", index);
-         break;
-      default:
-         _mesa_problem(NULL, "bad file in reg_string()");
-      }
-      break;
-
-   case PROG_PRINT_NV:
-      switch (f) {
-      case PROGRAM_INPUT:
-         if (prog->Target == GL_VERTEX_PROGRAM_ARB)
-            sprintf(str, "v[%d]", index);
-         else
-            sprintf(str, "f[%d]", index);
-         break;
-      case PROGRAM_OUTPUT:
-         sprintf(str, "o[%d]", index);
-         break;
-      case PROGRAM_TEMPORARY:
-         sprintf(str, "R%d", index);
-         break;
-      case PROGRAM_ENV_PARAM:
-         sprintf(str, "c[%d]", index);
-         break;
-      case PROGRAM_VARYING: /* extension */
-         sprintf(str, "varying[%s%d]", addr, index);
-         break;
-      case PROGRAM_UNIFORM: /* extension */
-         sprintf(str, "uniform[%s%d]", addr, index);
-         break;
-      case PROGRAM_CONSTANT: /* extension */
-         sprintf(str, "constant[%s%d]", addr, index);
-         break;
-      case PROGRAM_STATE_VAR: /* extension */
-         sprintf(str, "state[%s%d]", addr, index);
-         break;
-      default:
-         _mesa_problem(NULL, "bad file in reg_string()");
-      }
-      break;
-
-   default:
-      _mesa_problem(NULL, "bad mode in reg_string()");
-   }
-
-   return str;
-}
-
-
-/**
- * Return a string representation of the given swizzle word.
- * If extended is true, use extended (comma-separated) format.
- * \param swizzle  the swizzle field
- * \param negateBase  4-bit negation vector
- * \param extended  if true, also allow 0, 1 values
- */
-const char *
-_mesa_swizzle_string(GLuint swizzle, GLuint negateMask, GLboolean extended)
-{
-   static const char swz[] = "xyzw01!?";  /* See SWIZZLE_x definitions */
-   static char s[20];
-   GLuint i = 0;
-
-   if (!extended && swizzle == SWIZZLE_NOOP && negateMask == 0)
-      return ""; /* no swizzle/negation */
-
-   if (!extended)
-      s[i++] = '.';
-
-   if (negateMask & NEGATE_X)
-      s[i++] = '-';
-   s[i++] = swz[GET_SWZ(swizzle, 0)];
-
-   if (extended) {
-      s[i++] = ',';
-   }
-
-   if (negateMask & NEGATE_Y)
-      s[i++] = '-';
-   s[i++] = swz[GET_SWZ(swizzle, 1)];
-
-   if (extended) {
-      s[i++] = ',';
-   }
-
-   if (negateMask & NEGATE_Z)
-      s[i++] = '-';
-   s[i++] = swz[GET_SWZ(swizzle, 2)];
-
-   if (extended) {
-      s[i++] = ',';
-   }
-
-   if (negateMask & NEGATE_W)
-      s[i++] = '-';
-   s[i++] = swz[GET_SWZ(swizzle, 3)];
-
-   s[i] = 0;
-   return s;
-}
-
-
-void
-_mesa_print_swizzle(GLuint swizzle)
-{
-   if (swizzle == SWIZZLE_XYZW) {
-      printf(".xyzw\n");
-   }
-   else {
-      const char *s = _mesa_swizzle_string(swizzle, 0, 0);
-      printf("%s\n", s);
-   }
-}
-
-
-const char *
-_mesa_writemask_string(GLuint writeMask)
-{
-   static char s[10];
-   GLuint i = 0;
-
-   if (writeMask == WRITEMASK_XYZW)
-      return "";
-
-   s[i++] = '.';
-   if (writeMask & WRITEMASK_X)
-      s[i++] = 'x';
-   if (writeMask & WRITEMASK_Y)
-      s[i++] = 'y';
-   if (writeMask & WRITEMASK_Z)
-      s[i++] = 'z';
-   if (writeMask & WRITEMASK_W)
-      s[i++] = 'w';
-
-   s[i] = 0;
-   return s;
-}
-
-
-const char *
-_mesa_condcode_string(GLuint condcode)
-{
-   switch (condcode) {
-   case COND_GT:  return "GT";
-   case COND_EQ:  return "EQ";
-   case COND_LT:  return "LT";
-   case COND_UN:  return "UN";
-   case COND_GE:  return "GE";
-   case COND_LE:  return "LE";
-   case COND_NE:  return "NE";
-   case COND_TR:  return "TR";
-   case COND_FL:  return "FL";
-   default: return "cond???";
-   }
-}
-
-
-static void
-fprint_dst_reg(FILE * f,
-               const struct prog_dst_register *dstReg,
-               gl_prog_print_mode mode,
-               const struct gl_program *prog)
-{
-   fprintf(f, "%s%s",
-          reg_string((gl_register_file) dstReg->File,
-                     dstReg->Index, mode, dstReg->RelAddr, prog),
-          _mesa_writemask_string(dstReg->WriteMask));
-   
-   if (dstReg->CondMask != COND_TR) {
-      fprintf(f, " (%s.%s)",
-             _mesa_condcode_string(dstReg->CondMask),
-             _mesa_swizzle_string(dstReg->CondSwizzle,
-                                  GL_FALSE, GL_FALSE));
-   }
-
-#if 0
-   fprintf(f, "%s[%d]%s",
-          file_string((gl_register_file) dstReg->File, mode),
-          dstReg->Index,
-          _mesa_writemask_string(dstReg->WriteMask));
-#endif
-}
-
-
-static void
-fprint_src_reg(FILE *f,
-               const struct prog_src_register *srcReg, 
-               gl_prog_print_mode mode,
-               const struct gl_program *prog)
-{
-   const char *abs = srcReg->Abs ? "|" : "";
-
-   fprintf(f, "%s%s%s%s",
-          abs,
-          reg_string((gl_register_file) srcReg->File,
-                     srcReg->Index, mode, srcReg->RelAddr, prog),
-          _mesa_swizzle_string(srcReg->Swizzle,
-                               srcReg->Negate, GL_FALSE),
-          abs);
-#if 0
-   fprintf(f, "%s[%d]%s",
-          file_string((gl_register_file) srcReg->File, mode),
-          srcReg->Index,
-          _mesa_swizzle_string(srcReg->Swizzle,
-                               srcReg->Negate, GL_FALSE));
-#endif
-}
-
-
-static void
-fprint_comment(FILE *f, const struct prog_instruction *inst)
-{
-   if (inst->Comment)
-      fprintf(f, ";  # %s\n", inst->Comment);
-   else
-      fprintf(f, ";\n");
-}
-
-
-static void
-fprint_alu_instruction(FILE *f,
-                       const struct prog_instruction *inst,
-                       const char *opcode_string, GLuint numRegs,
-                       gl_prog_print_mode mode,
-                       const struct gl_program *prog)
-{
-   GLuint j;
-
-   fprintf(f, "%s", opcode_string);
-   if (inst->CondUpdate)
-      fprintf(f, ".C");
-
-   /* frag prog only */
-   if (inst->SaturateMode == SATURATE_ZERO_ONE)
-      fprintf(f, "_SAT");
-
-   fprintf(f, " ");
-   if (inst->DstReg.File != PROGRAM_UNDEFINED) {
-      fprint_dst_reg(f, &inst->DstReg, mode, prog);
-   }
-   else {
-      fprintf(f, " ???");
-   }
-
-   if (numRegs > 0)
-      fprintf(f, ", ");
-
-   for (j = 0; j < numRegs; j++) {
-      fprint_src_reg(f, inst->SrcReg + j, mode, prog);
-      if (j + 1 < numRegs)
-        fprintf(f, ", ");
-   }
-
-   fprint_comment(f, inst);
-}
-
-
-void
-_mesa_print_alu_instruction(const struct prog_instruction *inst,
-                            const char *opcode_string, GLuint numRegs)
-{
-   fprint_alu_instruction(stderr, inst, opcode_string,
-                          numRegs, PROG_PRINT_DEBUG, NULL);
-}
-
-
-/**
- * Print a single vertex/fragment program instruction.
- */
-GLint
-_mesa_fprint_instruction_opt(FILE *f,
-                            const struct prog_instruction *inst,
-                            GLint indent,
-                            gl_prog_print_mode mode,
-                            const struct gl_program *prog)
-{
-   GLint i;
-
-   if (inst->Opcode == OPCODE_ELSE ||
-       inst->Opcode == OPCODE_ENDIF ||
-       inst->Opcode == OPCODE_ENDLOOP ||
-       inst->Opcode == OPCODE_ENDSUB) {
-      indent -= 3;
-   }
-   for (i = 0; i < indent; i++) {
-      fprintf(f, " ");
-   }
-
-   switch (inst->Opcode) {
-   case OPCODE_PRINT:
-      fprintf(f, "PRINT '%s'", (char *) inst->Data);
-      if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
-         fprintf(f, ", ");
-         fprintf(f, "%s[%d]%s",
-                file_string((gl_register_file) inst->SrcReg[0].File,
-                            mode),
-                inst->SrcReg[0].Index,
-                _mesa_swizzle_string(inst->SrcReg[0].Swizzle,
-                                     inst->SrcReg[0].Negate, GL_FALSE));
-      }
-      if (inst->Comment)
-         fprintf(f, "  # %s", inst->Comment);
-      fprint_comment(f, inst);
-      break;
-   case OPCODE_SWZ:
-      fprintf(f, "SWZ");
-      if (inst->SaturateMode == SATURATE_ZERO_ONE)
-         fprintf(f, "_SAT");
-      fprintf(f, " ");
-      fprint_dst_reg(f, &inst->DstReg, mode, prog);
-      fprintf(f, ", %s[%d], %s",
-             file_string((gl_register_file) inst->SrcReg[0].File,
-                         mode),
-             inst->SrcReg[0].Index,
-             _mesa_swizzle_string(inst->SrcReg[0].Swizzle,
-                                  inst->SrcReg[0].Negate, GL_TRUE));
-      fprint_comment(f, inst);
-      break;
-   case OPCODE_TEX:
-   case OPCODE_TXP:
-   case OPCODE_TXL:
-   case OPCODE_TXB:
-      fprintf(f, "%s", _mesa_opcode_string(inst->Opcode));
-      if (inst->SaturateMode == SATURATE_ZERO_ONE)
-         fprintf(f, "_SAT");
-      fprintf(f, " ");
-      fprint_dst_reg(f, &inst->DstReg, mode, prog);
-      fprintf(f, ", ");
-      fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
-      fprintf(f, ", texture[%d], ", inst->TexSrcUnit);
-      switch (inst->TexSrcTarget) {
-      case TEXTURE_1D_INDEX:   fprintf(f, "1D");    break;
-      case TEXTURE_2D_INDEX:   fprintf(f, "2D");    break;
-      case TEXTURE_3D_INDEX:   fprintf(f, "3D");    break;
-      case TEXTURE_CUBE_INDEX: fprintf(f, "CUBE");  break;
-      case TEXTURE_RECT_INDEX: fprintf(f, "RECT");  break;
-      case TEXTURE_1D_ARRAY_INDEX: fprintf(f, "1D_ARRAY"); break;
-      case TEXTURE_2D_ARRAY_INDEX: fprintf(f, "2D_ARRAY"); break;
-      default:
-         ;
-      }
-      if (inst->TexShadow)
-         fprintf(f, " SHADOW");
-      fprint_comment(f, inst);
-      break;
-
-   case OPCODE_KIL:
-      fprintf(f, "%s", _mesa_opcode_string(inst->Opcode));
-      fprintf(f, " ");
-      fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
-      fprint_comment(f, inst);
-      break;
-   case OPCODE_KIL_NV:
-      fprintf(f, "%s", _mesa_opcode_string(inst->Opcode));
-      fprintf(f, " ");
-      fprintf(f, "%s.%s",
-             _mesa_condcode_string(inst->DstReg.CondMask),
-             _mesa_swizzle_string(inst->DstReg.CondSwizzle,
-                                  GL_FALSE, GL_FALSE));
-      fprint_comment(f, inst);
-      break;
-
-   case OPCODE_ARL:
-      fprintf(f, "ARL ");
-      fprint_dst_reg(f, &inst->DstReg, mode, prog);
-      fprintf(f, ", ");
-      fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
-      fprint_comment(f, inst);
-      break;
-   case OPCODE_BRA:
-      fprintf(f, "BRA %d (%s%s)",
-             inst->BranchTarget,
-             _mesa_condcode_string(inst->DstReg.CondMask),
-             _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
-      fprint_comment(f, inst);
-      break;
-   case OPCODE_IF:
-      if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
-         /* Use ordinary register */
-         fprintf(f, "IF ");
-         fprint_src_reg(f, &inst->SrcReg[0], mode, prog);
-         fprintf(f, "; ");
-      }
-      else {
-         /* Use cond codes */
-         fprintf(f, "IF (%s%s);",
-                _mesa_condcode_string(inst->DstReg.CondMask),
-                _mesa_swizzle_string(inst->DstReg.CondSwizzle,
-                                     0, GL_FALSE));
-      }
-      fprintf(f, " # (if false, goto %d)", inst->BranchTarget);
-      fprint_comment(f, inst);
-      return indent + 3;
-   case OPCODE_ELSE:
-      fprintf(f, "ELSE; # (goto %d)\n", inst->BranchTarget);
-      return indent + 3;
-   case OPCODE_ENDIF:
-      fprintf(f, "ENDIF;\n");
-      break;
-   case OPCODE_BGNLOOP:
-      fprintf(f, "BGNLOOP; # (end at %d)\n", inst->BranchTarget);
-      return indent + 3;
-   case OPCODE_ENDLOOP:
-      fprintf(f, "ENDLOOP; # (goto %d)\n", inst->BranchTarget);
-      break;
-   case OPCODE_BRK:
-   case OPCODE_CONT:
-      fprintf(f, "%s (%s%s); # (goto %d)",
-             _mesa_opcode_string(inst->Opcode),
-             _mesa_condcode_string(inst->DstReg.CondMask),
-             _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE),
-             inst->BranchTarget);
-      fprint_comment(f, inst);
-      break;
-
-   case OPCODE_BGNSUB:
-      if (mode == PROG_PRINT_NV) {
-         fprintf(f, "%s:\n", inst->Comment); /* comment is label */
-         return indent;
-      }
-      else {
-         fprintf(f, "BGNSUB");
-         fprint_comment(f, inst);
-         return indent + 3;
-      }
-   case OPCODE_ENDSUB:
-      if (mode == PROG_PRINT_DEBUG) {
-         fprintf(f, "ENDSUB");
-         fprint_comment(f, inst);
-      }
-      break;
-   case OPCODE_CAL:
-      if (mode == PROG_PRINT_NV) {
-         fprintf(f, "CAL %s;  # (goto %d)\n", inst->Comment, inst->BranchTarget);
-      }
-      else {
-         fprintf(f, "CAL %u", inst->BranchTarget);
-         fprint_comment(f, inst);
-      }
-      break;
-   case OPCODE_RET:
-      fprintf(f, "RET (%s%s)",
-             _mesa_condcode_string(inst->DstReg.CondMask),
-             _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE));
-      fprint_comment(f, inst);
-      break;
-
-   case OPCODE_END:
-      fprintf(f, "END\n");
-      break;
-   case OPCODE_NOP:
-      if (mode == PROG_PRINT_DEBUG) {
-         fprintf(f, "NOP");
-         fprint_comment(f, inst);
-      }
-      else if (inst->Comment) {
-         /* ARB/NV extensions don't have NOP instruction */
-         fprintf(f, "# %s\n", inst->Comment);
-      }
-      break;
-   /* XXX may need other special-case instructions */
-   default:
-      if (inst->Opcode < MAX_OPCODE) {
-         /* typical alu instruction */
-         fprint_alu_instruction(f, inst,
-                                _mesa_opcode_string(inst->Opcode),
-                                _mesa_num_inst_src_regs(inst->Opcode),
-                                mode, prog);
-      }
-      else {
-         fprint_alu_instruction(f, inst,
-                                _mesa_opcode_string(inst->Opcode),
-                                3/*_mesa_num_inst_src_regs(inst->Opcode)*/,
-                                mode, prog);
-      }
-      break;
-   }
-   return indent;
-}
-
-
-GLint
-_mesa_print_instruction_opt(const struct prog_instruction *inst,
-                            GLint indent,
-                            gl_prog_print_mode mode,
-                            const struct gl_program *prog)
-{
-   return _mesa_fprint_instruction_opt(stderr, inst, indent, mode, prog);
-}
-
-
-void
-_mesa_print_instruction(const struct prog_instruction *inst)
-{
-   /* note: 4th param should be ignored for PROG_PRINT_DEBUG */
-   _mesa_fprint_instruction_opt(stderr, inst, 0, PROG_PRINT_DEBUG, NULL);
-}
-
-
-
-/**
- * Print program, with options.
- */
-void
-_mesa_fprint_program_opt(FILE *f,
-                         const struct gl_program *prog,
-                         gl_prog_print_mode mode,
-                         GLboolean lineNumbers)
-{
-   GLuint i, indent = 0;
-
-   switch (prog->Target) {
-   case GL_VERTEX_PROGRAM_ARB:
-      if (mode == PROG_PRINT_ARB)
-         fprintf(f, "!!ARBvp1.0\n");
-      else if (mode == PROG_PRINT_NV)
-         fprintf(f, "!!VP1.0\n");
-      else
-         fprintf(f, "# Vertex Program/Shader %u\n", prog->Id);
-      break;
-   case GL_FRAGMENT_PROGRAM_ARB:
-   case GL_FRAGMENT_PROGRAM_NV:
-      if (mode == PROG_PRINT_ARB)
-         fprintf(f, "!!ARBfp1.0\n");
-      else if (mode == PROG_PRINT_NV)
-         fprintf(f, "!!FP1.0\n");
-      else
-         fprintf(f, "# Fragment Program/Shader %u\n", prog->Id);
-      break;
-   }
-
-   for (i = 0; i < prog->NumInstructions; i++) {
-      if (lineNumbers)
-         fprintf(f, "%3d: ", i);
-      indent = _mesa_fprint_instruction_opt(f, prog->Instructions + i,
-                                           indent, mode, prog);
-   }
-}
-
-
-/**
- * Print program to stderr, default options.
- */
-void
-_mesa_print_program(const struct gl_program *prog)
-{
-   _mesa_fprint_program_opt(stderr, prog, PROG_PRINT_DEBUG, GL_TRUE);
-}
-
-
-/**
- * Return binary representation of 64-bit value (as a string).
- * Insert a comma to separate each group of 8 bits.
- * Note we return a pointer to local static storage so this is not
- * re-entrant, etc.
- * XXX move to imports.[ch] if useful elsewhere.
- */
-static const char *
-binary(GLbitfield64 val)
-{
-   static char buf[80];
-   GLint i, len = 0;
-   for (i = 63; i >= 0; --i) {
-      if (val & (BITFIELD64_BIT(i)))
-         buf[len++] = '1';
-      else if (len > 0 || i == 0)
-         buf[len++] = '0';
-      if (len > 0 && ((i-1) % 8) == 7)
-         buf[len++] = ',';
-   }
-   buf[len] = '\0';
-   return buf;
-}
-
-
-/**
- * Print all of a program's parameters/fields to given file.
- */
-static void
-_mesa_fprint_program_parameters(FILE *f,
-                                GLcontext *ctx,
-                                const struct gl_program *prog)
-{
-   GLuint i;
-
-   fprintf(f, "InputsRead: 0x%x (0b%s)\n",
-                 prog->InputsRead, binary(prog->InputsRead));
-   fprintf(f, "OutputsWritten: 0x%llx (0b%s)\n",
-                 prog->OutputsWritten, binary(prog->OutputsWritten));
-   fprintf(f, "NumInstructions=%d\n", prog->NumInstructions);
-   fprintf(f, "NumTemporaries=%d\n", prog->NumTemporaries);
-   fprintf(f, "NumParameters=%d\n", prog->NumParameters);
-   fprintf(f, "NumAttributes=%d\n", prog->NumAttributes);
-   fprintf(f, "NumAddressRegs=%d\n", prog->NumAddressRegs);
-   fprintf(f, "SamplersUsed: 0x%x (0b%s)\n",
-                 prog->SamplersUsed, binary(prog->SamplersUsed));
-   fprintf(f, "Samplers=[ ");
-   for (i = 0; i < MAX_SAMPLERS; i++) {
-      fprintf(f, "%d ", prog->SamplerUnits[i]);
-   }
-   fprintf(f, "]\n");
-
-   _mesa_load_state_parameters(ctx, prog->Parameters);
-
-#if 0
-   fprintf(f, "Local Params:\n");
-   for (i = 0; i < MAX_PROGRAM_LOCAL_PARAMS; i++){
-      const GLfloat *p = prog->LocalParams[i];
-      fprintf(f, "%2d: %f, %f, %f, %f\n", i, p[0], p[1], p[2], p[3]);
-   }
-#endif 
-   _mesa_print_parameter_list(prog->Parameters);
-}
-
-
-/**
- * Print all of a program's parameters/fields to stderr.
- */
-void
-_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog)
-{
-   _mesa_fprint_program_parameters(stderr, ctx, prog);
-}
-
-
-/**
- * Print a program parameter list to given file.
- */
-static void
-_mesa_fprint_parameter_list(FILE *f,
-                            const struct gl_program_parameter_list *list)
-{
-   const gl_prog_print_mode mode = PROG_PRINT_DEBUG;
-   GLuint i;
-
-   if (!list)
-      return;
-
-   if (0)
-      fprintf(f, "param list %p\n", (void *) list);
-   fprintf(f, "dirty state flags: 0x%x\n", list->StateFlags);
-   for (i = 0; i < list->NumParameters; i++){
-      struct gl_program_parameter *param = list->Parameters + i;
-      const GLfloat *v = list->ParameterValues[i];
-      fprintf(f, "param[%d] sz=%d %s %s = {%.3g, %.3g, %.3g, %.3g}",
-             i, param->Size,
-             file_string(list->Parameters[i].Type, mode),
-             param->Name, v[0], v[1], v[2], v[3]);
-      if (param->Flags & PROG_PARAM_BIT_CENTROID)
-         fprintf(f, " Centroid");
-      if (param->Flags & PROG_PARAM_BIT_INVARIANT)
-         fprintf(f, " Invariant");
-      if (param->Flags & PROG_PARAM_BIT_FLAT)
-         fprintf(f, " Flat");
-      if (param->Flags & PROG_PARAM_BIT_LINEAR)
-         fprintf(f, " Linear");
-      fprintf(f, "\n");
-   }
-}
-
-
-/**
- * Print a program parameter list to stderr.
- */
-void
-_mesa_print_parameter_list(const struct gl_program_parameter_list *list)
-{
-   _mesa_fprint_parameter_list(stderr, list);
-}
-
-
-/**
- * Write shader and associated info to a file.
- */
-void
-_mesa_write_shader_to_file(const struct gl_shader *shader)
-{
-   const char *type;
-   char filename[100];
-   FILE *f;
-
-   if (shader->Type == GL_FRAGMENT_SHADER)
-      type = "frag";
-   else
-      type = "vert";
-
-   _mesa_snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type);
-   f = fopen(filename, "w");
-   if (!f) {
-      fprintf(stderr, "Unable to open %s for writing\n", filename);
-      return;
-   }
-
-   fprintf(f, "/* Shader %u source, checksum %u */\n", shader->Name, shader->SourceChecksum);
-   fputs(shader->Source, f);
-   fprintf(f, "\n");
-
-   fprintf(f, "/* Compile status: %s */\n",
-           shader->CompileStatus ? "ok" : "fail");
-   if (!shader->CompileStatus) {
-      fprintf(f, "/* Log Info: */\n");
-      fputs(shader->InfoLog, f);
-   }
-   else {
-      fprintf(f, "/* GPU code */\n");
-      fprintf(f, "/*\n");
-      _mesa_fprint_program_opt(f, shader->Program, PROG_PRINT_DEBUG, GL_TRUE);
-      fprintf(f, "*/\n");
-      fprintf(f, "/* Parameters / constants */\n");
-      fprintf(f, "/*\n");
-      _mesa_fprint_parameter_list(f, shader->Program->Parameters);
-      fprintf(f, "*/\n");
-   }
-
-   fclose(f);
-}
-
-
-/**
- * Append the shader's uniform info/values to the shader log file.
- * The log file will typically have been created by the
- * _mesa_write_shader_to_file function.
- */
-void
-_mesa_append_uniforms_to_file(const struct gl_shader *shader,
-                              const struct gl_program *prog)
-{
-   const char *type;
-   char filename[100];
-   FILE *f;
-
-   if (shader->Type == GL_FRAGMENT_SHADER)
-      type = "frag";
-   else
-      type = "vert";
-
-   _mesa_snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type);
-   f = fopen(filename, "a"); /* append */
-   if (!f) {
-      fprintf(stderr, "Unable to open %s for appending\n", filename);
-      return;
-   }
-
-   fprintf(f, "/* First-draw parameters / constants */\n");
-   fprintf(f, "/*\n");
-   _mesa_fprint_parameter_list(f, prog->Parameters);
-   fprintf(f, "*/\n");
-
-   fclose(f);
-}
diff --git a/src/mesa/shader/prog_print.h b/src/mesa/shader/prog_print.h
deleted file mode 100644 (file)
index 9ab7456..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.3
- *
- * 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.
- */
-
-
-#ifndef PROG_PRINT_H
-#define PROG_PRINT_H
-
-
-/**
- * The output style to use when printing programs.
- */
-typedef enum {
-   PROG_PRINT_ARB,
-   PROG_PRINT_NV,
-   PROG_PRINT_DEBUG
-} gl_prog_print_mode;
-
-
-extern void
-_mesa_print_vp_inputs(GLbitfield inputs);
-
-extern void
-_mesa_print_fp_inputs(GLbitfield inputs);
-
-extern const char *
-_mesa_condcode_string(GLuint condcode);
-
-extern const char *
-_mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended);
-
-const char *
-_mesa_writemask_string(GLuint writeMask);
-
-extern void
-_mesa_print_swizzle(GLuint swizzle);
-
-extern void
-_mesa_print_alu_instruction(const struct prog_instruction *inst,
-                            const char *opcode_string, GLuint numRegs);
-
-extern void
-_mesa_print_instruction(const struct prog_instruction *inst);
-
-extern GLint
-_mesa_fprint_instruction_opt(FILE *f,
-                            const struct prog_instruction *inst,
-                            GLint indent,
-                            gl_prog_print_mode mode,
-                            const struct gl_program *prog);
-
-extern GLint
-_mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent,
-                            gl_prog_print_mode mode,
-                            const struct gl_program *prog);
-
-extern void
-_mesa_print_program(const struct gl_program *prog);
-
-extern void
-_mesa_fprint_program_opt(FILE *f,
-                         const struct gl_program *prog, gl_prog_print_mode mode,
-                         GLboolean lineNumbers);
-
-extern void
-_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog);
-
-extern void
-_mesa_print_parameter_list(const struct gl_program_parameter_list *list);
-
-
-extern void
-_mesa_write_shader_to_file(const struct gl_shader *shader);
-
-extern void
-_mesa_append_uniforms_to_file(const struct gl_shader *shader,
-                              const struct gl_program *prog);
-
-
-#endif /* PROG_PRINT_H */
diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c
deleted file mode 100644 (file)
index ead3ece..0000000
+++ /dev/null
@@ -1,1187 +0,0 @@
-/*
- * 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 prog_statevars.c
- * Program state variable management.
- * \author Brian Paul
- */
-
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/imports.h"
-#include "main/macros.h"
-#include "main/mtypes.h"
-#include "prog_statevars.h"
-#include "prog_parameter.h"
-
-
-/**
- * Use the list of tokens in the state[] array to find global GL state
- * and return it in <value>.  Usually, four values are returned in <value>
- * but matrix queries may return as many as 16 values.
- * This function is used for ARB vertex/fragment programs.
- * The program parser will produce the state[] values.
- */
-static void
-_mesa_fetch_state(GLcontext *ctx, const gl_state_index state[],
-                  GLfloat *value)
-{
-   switch (state[0]) {
-   case STATE_MATERIAL:
-      {
-         /* state[1] is either 0=front or 1=back side */
-         const GLuint face = (GLuint) state[1];
-         const struct gl_material *mat = &ctx->Light.Material;
-         ASSERT(face == 0 || face == 1);
-         /* we rely on tokens numbered so that _BACK_ == _FRONT_+ 1 */
-         ASSERT(MAT_ATTRIB_FRONT_AMBIENT + 1 == MAT_ATTRIB_BACK_AMBIENT);
-         /* XXX we could get rid of this switch entirely with a little
-          * work in arbprogparse.c's parse_state_single_item().
-          */
-         /* state[2] is the material attribute */
-         switch (state[2]) {
-         case STATE_AMBIENT:
-            COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_AMBIENT + face]);
-            return;
-         case STATE_DIFFUSE:
-            COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_DIFFUSE + face]);
-            return;
-         case STATE_SPECULAR:
-            COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_SPECULAR + face]);
-            return;
-         case STATE_EMISSION:
-            COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_EMISSION + face]);
-            return;
-         case STATE_SHININESS:
-            value[0] = mat->Attrib[MAT_ATTRIB_FRONT_SHININESS + face][0];
-            value[1] = 0.0F;
-            value[2] = 0.0F;
-            value[3] = 1.0F;
-            return;
-         default:
-            _mesa_problem(ctx, "Invalid material state in fetch_state");
-            return;
-         }
-      }
-   case STATE_LIGHT:
-      {
-         /* state[1] is the light number */
-         const GLuint ln = (GLuint) state[1];
-         /* state[2] is the light attribute */
-         switch (state[2]) {
-         case STATE_AMBIENT:
-            COPY_4V(value, ctx->Light.Light[ln].Ambient);
-            return;
-         case STATE_DIFFUSE:
-            COPY_4V(value, ctx->Light.Light[ln].Diffuse);
-            return;
-         case STATE_SPECULAR:
-            COPY_4V(value, ctx->Light.Light[ln].Specular);
-            return;
-         case STATE_POSITION:
-            COPY_4V(value, ctx->Light.Light[ln].EyePosition);
-            return;
-         case STATE_ATTENUATION:
-            value[0] = ctx->Light.Light[ln].ConstantAttenuation;
-            value[1] = ctx->Light.Light[ln].LinearAttenuation;
-            value[2] = ctx->Light.Light[ln].QuadraticAttenuation;
-            value[3] = ctx->Light.Light[ln].SpotExponent;
-            return;
-         case STATE_SPOT_DIRECTION:
-            COPY_3V(value, ctx->Light.Light[ln].SpotDirection);
-            value[3] = ctx->Light.Light[ln]._CosCutoff;
-            return;
-         case STATE_SPOT_CUTOFF:
-            value[0] = ctx->Light.Light[ln].SpotCutoff;
-            return;
-         case STATE_HALF_VECTOR:
-            {
-               static const GLfloat eye_z[] = {0, 0, 1};
-               GLfloat p[3];
-               /* Compute infinite half angle vector:
-                *   halfVector = normalize(normalize(lightPos) + (0, 0, 1))
-               * light.EyePosition.w should be 0 for infinite lights.
-                */
-               COPY_3V(p, ctx->Light.Light[ln].EyePosition);
-               NORMALIZE_3FV(p);
-              ADD_3V(value, p, eye_z);
-              NORMALIZE_3FV(value);
-              value[3] = 1.0;
-            }
-            return;
-         default:
-            _mesa_problem(ctx, "Invalid light state in fetch_state");
-            return;
-         }
-      }
-   case STATE_LIGHTMODEL_AMBIENT:
-      COPY_4V(value, ctx->Light.Model.Ambient);
-      return;
-   case STATE_LIGHTMODEL_SCENECOLOR:
-      if (state[1] == 0) {
-         /* front */
-         GLint i;
-         for (i = 0; i < 3; i++) {
-            value[i] = ctx->Light.Model.Ambient[i]
-               * ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT][i]
-               + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION][i];
-         }
-        value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
-      }
-      else {
-         /* back */
-         GLint i;
-         for (i = 0; i < 3; i++) {
-            value[i] = ctx->Light.Model.Ambient[i]
-               * ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_AMBIENT][i]
-               + ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_EMISSION][i];
-         }
-        value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
-      }
-      return;
-   case STATE_LIGHTPROD:
-      {
-         const GLuint ln = (GLuint) state[1];
-         const GLuint face = (GLuint) state[2];
-         GLint i;
-         ASSERT(face == 0 || face == 1);
-         switch (state[3]) {
-            case STATE_AMBIENT:
-               for (i = 0; i < 3; i++) {
-                  value[i] = ctx->Light.Light[ln].Ambient[i] *
-                     ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][i];
-               }
-               /* [3] = material alpha */
-               value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][3];
-               return;
-            case STATE_DIFFUSE:
-               for (i = 0; i < 3; i++) {
-                  value[i] = ctx->Light.Light[ln].Diffuse[i] *
-                     ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][i];
-               }
-               /* [3] = material alpha */
-               value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3];
-               return;
-            case STATE_SPECULAR:
-               for (i = 0; i < 3; i++) {
-                  value[i] = ctx->Light.Light[ln].Specular[i] *
-                     ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][i];
-               }
-               /* [3] = material alpha */
-               value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][3];
-               return;
-            default:
-               _mesa_problem(ctx, "Invalid lightprod state in fetch_state");
-               return;
-         }
-      }
-   case STATE_TEXGEN:
-      {
-         /* state[1] is the texture unit */
-         const GLuint unit = (GLuint) state[1];
-         /* state[2] is the texgen attribute */
-         switch (state[2]) {
-         case STATE_TEXGEN_EYE_S:
-            COPY_4V(value, ctx->Texture.Unit[unit].GenS.EyePlane);
-            return;
-         case STATE_TEXGEN_EYE_T:
-            COPY_4V(value, ctx->Texture.Unit[unit].GenT.EyePlane);
-            return;
-         case STATE_TEXGEN_EYE_R:
-            COPY_4V(value, ctx->Texture.Unit[unit].GenR.EyePlane);
-            return;
-         case STATE_TEXGEN_EYE_Q:
-            COPY_4V(value, ctx->Texture.Unit[unit].GenQ.EyePlane);
-            return;
-         case STATE_TEXGEN_OBJECT_S:
-            COPY_4V(value, ctx->Texture.Unit[unit].GenS.ObjectPlane);
-            return;
-         case STATE_TEXGEN_OBJECT_T:
-            COPY_4V(value, ctx->Texture.Unit[unit].GenT.ObjectPlane);
-            return;
-         case STATE_TEXGEN_OBJECT_R:
-            COPY_4V(value, ctx->Texture.Unit[unit].GenR.ObjectPlane);
-            return;
-         case STATE_TEXGEN_OBJECT_Q:
-            COPY_4V(value, ctx->Texture.Unit[unit].GenQ.ObjectPlane);
-            return;
-         default:
-            _mesa_problem(ctx, "Invalid texgen state in fetch_state");
-            return;
-         }
-      }
-   case STATE_TEXENV_COLOR:
-      {
-         /* state[1] is the texture unit */
-         const GLuint unit = (GLuint) state[1];
-         COPY_4V(value, ctx->Texture.Unit[unit].EnvColor);
-      }
-      return;
-   case STATE_FOG_COLOR:
-      COPY_4V(value, ctx->Fog.Color);
-      return;
-   case STATE_FOG_PARAMS:
-      value[0] = ctx->Fog.Density;
-      value[1] = ctx->Fog.Start;
-      value[2] = ctx->Fog.End;
-      value[3] = (ctx->Fog.End == ctx->Fog.Start)
-         ? 1.0f : (GLfloat)(1.0 / (ctx->Fog.End - ctx->Fog.Start));
-      return;
-   case STATE_CLIPPLANE:
-      {
-         const GLuint plane = (GLuint) state[1];
-         COPY_4V(value, ctx->Transform.EyeUserPlane[plane]);
-      }
-      return;
-   case STATE_POINT_SIZE:
-      value[0] = ctx->Point.Size;
-      value[1] = ctx->Point.MinSize;
-      value[2] = ctx->Point.MaxSize;
-      value[3] = ctx->Point.Threshold;
-      return;
-   case STATE_POINT_ATTENUATION:
-      value[0] = ctx->Point.Params[0];
-      value[1] = ctx->Point.Params[1];
-      value[2] = ctx->Point.Params[2];
-      value[3] = 1.0F;
-      return;
-   case STATE_MODELVIEW_MATRIX:
-   case STATE_PROJECTION_MATRIX:
-   case STATE_MVP_MATRIX:
-   case STATE_TEXTURE_MATRIX:
-   case STATE_PROGRAM_MATRIX:
-   case STATE_COLOR_MATRIX:
-      {
-         /* state[0] = modelview, projection, texture, etc. */
-         /* state[1] = which texture matrix or program matrix */
-         /* state[2] = first row to fetch */
-         /* state[3] = last row to fetch */
-         /* state[4] = transpose, inverse or invtrans */
-         const GLmatrix *matrix;
-         const gl_state_index mat = state[0];
-         const GLuint index = (GLuint) state[1];
-         const GLuint firstRow = (GLuint) state[2];
-         const GLuint lastRow = (GLuint) state[3];
-         const gl_state_index modifier = state[4];
-         const GLfloat *m;
-         GLuint row, i;
-         ASSERT(firstRow >= 0);
-         ASSERT(firstRow < 4);
-         ASSERT(lastRow >= 0);
-         ASSERT(lastRow < 4);
-         if (mat == STATE_MODELVIEW_MATRIX) {
-            matrix = ctx->ModelviewMatrixStack.Top;
-         }
-         else if (mat == STATE_PROJECTION_MATRIX) {
-            matrix = ctx->ProjectionMatrixStack.Top;
-         }
-         else if (mat == STATE_MVP_MATRIX) {
-            matrix = &ctx->_ModelProjectMatrix;
-         }
-         else if (mat == STATE_TEXTURE_MATRIX) {
-            ASSERT(index < Elements(ctx->TextureMatrixStack));
-            matrix = ctx->TextureMatrixStack[index].Top;
-         }
-         else if (mat == STATE_PROGRAM_MATRIX) {
-            ASSERT(index < Elements(ctx->ProgramMatrixStack));
-            matrix = ctx->ProgramMatrixStack[index].Top;
-         }
-         else if (mat == STATE_COLOR_MATRIX) {
-            matrix = ctx->ColorMatrixStack.Top;
-         }
-         else {
-            _mesa_problem(ctx, "Bad matrix name in _mesa_fetch_state()");
-            return;
-         }
-         if (modifier == STATE_MATRIX_INVERSE ||
-             modifier == STATE_MATRIX_INVTRANS) {
-            /* Be sure inverse is up to date:
-            */
-            _math_matrix_alloc_inv( (GLmatrix *) matrix );
-           _math_matrix_analyse( (GLmatrix*) matrix );
-            m = matrix->inv;
-         }
-         else {
-            m = matrix->m;
-         }
-         if (modifier == STATE_MATRIX_TRANSPOSE ||
-             modifier == STATE_MATRIX_INVTRANS) {
-            for (i = 0, row = firstRow; row <= lastRow; row++) {
-               value[i++] = m[row * 4 + 0];
-               value[i++] = m[row * 4 + 1];
-               value[i++] = m[row * 4 + 2];
-               value[i++] = m[row * 4 + 3];
-            }
-         }
-         else {
-            for (i = 0, row = firstRow; row <= lastRow; row++) {
-               value[i++] = m[row + 0];
-               value[i++] = m[row + 4];
-               value[i++] = m[row + 8];
-               value[i++] = m[row + 12];
-            }
-         }
-      }
-      return;
-   case STATE_DEPTH_RANGE:
-      value[0] = ctx->Viewport.Near;                     /* near       */
-      value[1] = ctx->Viewport.Far;                      /* far        */
-      value[2] = ctx->Viewport.Far - ctx->Viewport.Near; /* far - near */
-      value[3] = 1.0;
-      return;
-   case STATE_FRAGMENT_PROGRAM:
-      {
-         /* state[1] = {STATE_ENV, STATE_LOCAL} */
-         /* state[2] = parameter index          */
-         const int idx = (int) state[2];
-         switch (state[1]) {
-            case STATE_ENV:
-               COPY_4V(value, ctx->FragmentProgram.Parameters[idx]);
-               return;
-            case STATE_LOCAL:
-               COPY_4V(value, ctx->FragmentProgram.Current->Base.LocalParams[idx]);
-               return;
-            default:
-               _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()");
-               return;
-         }
-      }
-      return;
-
-   case STATE_VERTEX_PROGRAM:
-      {
-         /* state[1] = {STATE_ENV, STATE_LOCAL} */
-         /* state[2] = parameter index          */
-         const int idx = (int) state[2];
-         switch (state[1]) {
-            case STATE_ENV:
-               COPY_4V(value, ctx->VertexProgram.Parameters[idx]);
-               return;
-            case STATE_LOCAL:
-               COPY_4V(value, ctx->VertexProgram.Current->Base.LocalParams[idx]);
-               return;
-            default:
-               _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()");
-               return;
-         }
-      }
-      return;
-
-   case STATE_NORMAL_SCALE:
-      ASSIGN_4V(value, ctx->_ModelViewInvScale, 0, 0, 1);
-      return;
-
-   case STATE_INTERNAL:
-      switch (state[1]) {
-      case STATE_CURRENT_ATTRIB:
-         {
-            const GLuint idx = (GLuint) state[2];
-            COPY_4V(value, ctx->Current.Attrib[idx]);
-         }
-         return;
-
-      case STATE_NORMAL_SCALE:
-         ASSIGN_4V(value, 
-                   ctx->_ModelViewInvScale, 
-                   ctx->_ModelViewInvScale, 
-                   ctx->_ModelViewInvScale, 
-                   1);
-         return;
-
-      case STATE_TEXRECT_SCALE:
-         /* Value = { 1/texWidth, 1/texHeight, 0, 1 }.
-          * Used to convert unnormalized texcoords to normalized texcoords.
-          */
-         {
-            const int unit = (int) state[2];
-            const struct gl_texture_object *texObj
-               = ctx->Texture.Unit[unit]._Current;
-            if (texObj) {
-               struct gl_texture_image *texImage = texObj->Image[0][0];
-               ASSIGN_4V(value,
-                         (GLfloat) (1.0 / texImage->Width),
-                         (GLfloat) (1.0 / texImage->Height),
-                         0.0f, 1.0f);
-            }
-         }
-         return;
-
-      case STATE_FOG_PARAMS_OPTIMIZED:
-         /* for simpler per-vertex/pixel fog calcs. POW (for EXP/EXP2 fog)
-          * might be more expensive than EX2 on some hw, plus it needs
-          * another constant (e) anyway. Linear fog can now be done with a
-          * single MAD.
-          * linear: fogcoord * -1/(end-start) + end/(end-start)
-          * exp: 2^-(density/ln(2) * fogcoord)
-          * exp2: 2^-((density/(ln(2)^2) * fogcoord)^2)
-          */
-         value[0] = (ctx->Fog.End == ctx->Fog.Start)
-            ? 1.0f : (GLfloat)(-1.0F / (ctx->Fog.End - ctx->Fog.Start));
-         value[1] = ctx->Fog.End * -value[0];
-         value[2] = (GLfloat)(ctx->Fog.Density * ONE_DIV_LN2);
-         value[3] = (GLfloat)(ctx->Fog.Density * ONE_DIV_SQRT_LN2);
-         return;
-
-      case STATE_POINT_SIZE_CLAMPED:
-         {
-           /* this includes implementation dependent limits, to avoid
-            * another potentially necessary clamp.
-            * Note: for sprites, point smooth (point AA) is ignored
-            * and we'll clamp to MinPointSizeAA and MaxPointSize, because we
-            * expect drivers will want to say their minimum for AA size is 0.0
-            * but for non-AA it's 1.0 (because normal points with size below 1.0
-            * need to get rounded up to 1.0, hence never disappear). GL does
-            * not specify max clamp size for sprites, other than it needs to be
-            * at least as large as max AA size, hence use non-AA size there.
-            */
-            GLfloat minImplSize;
-            GLfloat maxImplSize;
-            if (ctx->Point.PointSprite) {
-               minImplSize = ctx->Const.MinPointSizeAA;
-               maxImplSize = ctx->Const.MaxPointSize;
-            }
-            else if (ctx->Point.SmoothFlag || ctx->Multisample._Enabled) {
-               minImplSize = ctx->Const.MinPointSizeAA;
-               maxImplSize = ctx->Const.MaxPointSizeAA;
-            }
-            else {
-               minImplSize = ctx->Const.MinPointSize;
-               maxImplSize = ctx->Const.MaxPointSize;
-            }
-            value[0] = ctx->Point.Size;
-            value[1] = ctx->Point.MinSize >= minImplSize ? ctx->Point.MinSize : minImplSize;
-            value[2] = ctx->Point.MaxSize <= maxImplSize ? ctx->Point.MaxSize : maxImplSize;
-            value[3] = ctx->Point.Threshold;
-         }
-         return;
-      case STATE_POINT_SIZE_IMPL_CLAMP:
-         {
-           /* for implementation clamp only in vs */
-            GLfloat minImplSize;
-            GLfloat maxImplSize;
-            if (ctx->Point.PointSprite) {
-               minImplSize = ctx->Const.MinPointSizeAA;
-               maxImplSize = ctx->Const.MaxPointSize;
-            }
-            else if (ctx->Point.SmoothFlag || ctx->Multisample._Enabled) {
-               minImplSize = ctx->Const.MinPointSizeAA;
-               maxImplSize = ctx->Const.MaxPointSizeAA;
-            }
-            else {
-               minImplSize = ctx->Const.MinPointSize;
-               maxImplSize = ctx->Const.MaxPointSize;
-            }
-            value[0] = ctx->Point.Size;
-            value[1] = minImplSize;
-            value[2] = maxImplSize;
-            value[3] = ctx->Point.Threshold;
-         }
-         return;
-      case STATE_LIGHT_SPOT_DIR_NORMALIZED:
-         {
-            /* here, state[2] is the light number */
-            /* pre-normalize spot dir */
-            const GLuint ln = (GLuint) state[2];
-            COPY_3V(value, ctx->Light.Light[ln]._NormSpotDirection);
-            value[3] = ctx->Light.Light[ln]._CosCutoff;
-         }
-         return;
-
-      case STATE_LIGHT_POSITION:
-         {
-            const GLuint ln = (GLuint) state[2];
-            COPY_4V(value, ctx->Light.Light[ln]._Position);
-         }
-         return;
-
-      case STATE_LIGHT_POSITION_NORMALIZED:
-         {
-            const GLuint ln = (GLuint) state[2];
-            COPY_4V(value, ctx->Light.Light[ln]._Position);
-            NORMALIZE_3FV( value );
-         }
-         return;
-
-      case STATE_LIGHT_HALF_VECTOR:
-         {
-            const GLuint ln = (GLuint) state[2];
-            GLfloat p[3];
-            /* Compute infinite half angle vector:
-             *   halfVector = normalize(normalize(lightPos) + (0, 0, 1))
-             * light.EyePosition.w should be 0 for infinite lights.
-             */
-            COPY_3V(p, ctx->Light.Light[ln]._Position);
-            NORMALIZE_3FV(p);
-            ADD_3V(value, p, ctx->_EyeZDir);
-            NORMALIZE_3FV(value);
-            value[3] = 1.0;
-         }
-         return;
-
-      case STATE_PT_SCALE:
-         value[0] = ctx->Pixel.RedScale;
-         value[1] = ctx->Pixel.GreenScale;
-         value[2] = ctx->Pixel.BlueScale;
-         value[3] = ctx->Pixel.AlphaScale;
-         return;
-
-      case STATE_PT_BIAS:
-         value[0] = ctx->Pixel.RedBias;
-         value[1] = ctx->Pixel.GreenBias;
-         value[2] = ctx->Pixel.BlueBias;
-         value[3] = ctx->Pixel.AlphaBias;
-         return;
-
-      case STATE_PCM_SCALE:
-         COPY_4V(value, ctx->Pixel.PostColorMatrixScale);
-         return;
-
-      case STATE_PCM_BIAS:
-         COPY_4V(value, ctx->Pixel.PostColorMatrixBias);
-         return;
-
-      case STATE_SHADOW_AMBIENT:
-         {
-            const int unit = (int) state[2];
-            const struct gl_texture_object *texObj
-               = ctx->Texture.Unit[unit]._Current;
-            if (texObj) {
-               value[0] =
-               value[1] =
-               value[2] =
-               value[3] = texObj->CompareFailValue;
-            }
-         }
-         return;
-
-      case STATE_FB_SIZE:
-         value[0] = (GLfloat) (ctx->DrawBuffer->Width - 1);
-         value[1] = (GLfloat) (ctx->DrawBuffer->Height - 1);
-         value[2] = 0.0F;
-         value[3] = 0.0F;
-         return;
-
-      case STATE_ROT_MATRIX_0:
-         {
-            const int unit = (int) state[2];
-            GLfloat *rotMat22 = ctx->Texture.Unit[unit].RotMatrix;
-            value[0] = rotMat22[0]; 
-            value[1] = rotMat22[2];
-            value[2] = 0.0;
-            value[3] = 0.0;
-         }
-         return;
-
-      case STATE_ROT_MATRIX_1:
-         {
-            const int unit = (int) state[2];
-            GLfloat *rotMat22 = ctx->Texture.Unit[unit].RotMatrix;
-            value[0] = rotMat22[1];
-            value[1] = rotMat22[3];
-            value[2] = 0.0;
-            value[3] = 0.0;
-         }
-         return;
-
-      /* XXX: make sure new tokens added here are also handled in the 
-       * _mesa_program_state_flags() switch, below.
-       */
-      default:
-         /* Unknown state indexes are silently ignored here.
-          * Drivers may do something special.
-          */
-         return;
-      }
-      return;
-
-   default:
-      _mesa_problem(ctx, "Invalid state in _mesa_fetch_state");
-      return;
-   }
-}
-
-
-/**
- * Return a bitmask of the Mesa state flags (_NEW_* values) which would
- * indicate that the given context state may have changed.
- * The bitmask is used during validation to determine if we need to update
- * vertex/fragment program parameters (like "state.material.color") when
- * some GL state has changed.
- */
-GLbitfield
-_mesa_program_state_flags(const gl_state_index state[STATE_LENGTH])
-{
-   switch (state[0]) {
-   case STATE_MATERIAL:
-   case STATE_LIGHT:
-   case STATE_LIGHTMODEL_AMBIENT:
-   case STATE_LIGHTMODEL_SCENECOLOR:
-   case STATE_LIGHTPROD:
-      return _NEW_LIGHT;
-
-   case STATE_TEXGEN:
-   case STATE_TEXENV_COLOR:
-      return _NEW_TEXTURE;
-
-   case STATE_FOG_COLOR:
-   case STATE_FOG_PARAMS:
-      return _NEW_FOG;
-
-   case STATE_CLIPPLANE:
-      return _NEW_TRANSFORM;
-
-   case STATE_POINT_SIZE:
-   case STATE_POINT_ATTENUATION:
-      return _NEW_POINT;
-
-   case STATE_MODELVIEW_MATRIX:
-      return _NEW_MODELVIEW;
-   case STATE_PROJECTION_MATRIX:
-      return _NEW_PROJECTION;
-   case STATE_MVP_MATRIX:
-      return _NEW_MODELVIEW | _NEW_PROJECTION;
-   case STATE_TEXTURE_MATRIX:
-      return _NEW_TEXTURE_MATRIX;
-   case STATE_PROGRAM_MATRIX:
-      return _NEW_TRACK_MATRIX;
-   case STATE_COLOR_MATRIX:
-      return _NEW_COLOR_MATRIX;
-
-   case STATE_DEPTH_RANGE:
-      return _NEW_VIEWPORT;
-
-   case STATE_FRAGMENT_PROGRAM:
-   case STATE_VERTEX_PROGRAM:
-      return _NEW_PROGRAM;
-
-   case STATE_NORMAL_SCALE:
-      return _NEW_MODELVIEW;
-
-   case STATE_INTERNAL:
-      switch (state[1]) {
-      case STATE_CURRENT_ATTRIB:
-         return _NEW_CURRENT_ATTRIB;
-
-      case STATE_NORMAL_SCALE:
-         return _NEW_MODELVIEW;
-
-      case STATE_TEXRECT_SCALE:
-      case STATE_SHADOW_AMBIENT:
-      case STATE_ROT_MATRIX_0:
-      case STATE_ROT_MATRIX_1:
-        return _NEW_TEXTURE;
-      case STATE_FOG_PARAMS_OPTIMIZED:
-        return _NEW_FOG;
-      case STATE_POINT_SIZE_CLAMPED:
-      case STATE_POINT_SIZE_IMPL_CLAMP:
-         return _NEW_POINT | _NEW_MULTISAMPLE;
-      case STATE_LIGHT_SPOT_DIR_NORMALIZED:
-      case STATE_LIGHT_POSITION:
-      case STATE_LIGHT_POSITION_NORMALIZED:
-      case STATE_LIGHT_HALF_VECTOR:
-         return _NEW_LIGHT;
-
-      case STATE_PT_SCALE:
-      case STATE_PT_BIAS:
-      case STATE_PCM_SCALE:
-      case STATE_PCM_BIAS:
-         return _NEW_PIXEL;
-
-      case STATE_FB_SIZE:
-         return _NEW_BUFFERS;
-
-      default:
-         /* unknown state indexes are silently ignored and
-         *  no flag set, since it is handled by the driver.
-         */
-        return 0;
-      }
-
-   default:
-      _mesa_problem(NULL, "unexpected state[0] in make_state_flags()");
-      return 0;
-   }
-}
-
-
-static void
-append(char *dst, const char *src)
-{
-   while (*dst)
-      dst++;
-   while (*src)
-     *dst++ = *src++;
-   *dst = 0;
-}
-
-
-/**
- * Convert token 'k' to a string, append it onto 'dst' string.
- */
-static void
-append_token(char *dst, gl_state_index k)
-{
-   switch (k) {
-   case STATE_MATERIAL:
-      append(dst, "material");
-      break;
-   case STATE_LIGHT:
-      append(dst, "light");
-      break;
-   case STATE_LIGHTMODEL_AMBIENT:
-      append(dst, "lightmodel.ambient");
-      break;
-   case STATE_LIGHTMODEL_SCENECOLOR:
-      break;
-   case STATE_LIGHTPROD:
-      append(dst, "lightprod");
-      break;
-   case STATE_TEXGEN:
-      append(dst, "texgen");
-      break;
-   case STATE_FOG_COLOR:
-      append(dst, "fog.color");
-      break;
-   case STATE_FOG_PARAMS:
-      append(dst, "fog.params");
-      break;
-   case STATE_CLIPPLANE:
-      append(dst, "clip");
-      break;
-   case STATE_POINT_SIZE:
-      append(dst, "point.size");
-      break;
-   case STATE_POINT_ATTENUATION:
-      append(dst, "point.attenuation");
-      break;
-   case STATE_MODELVIEW_MATRIX:
-      append(dst, "matrix.modelview");
-      break;
-   case STATE_PROJECTION_MATRIX:
-      append(dst, "matrix.projection");
-      break;
-   case STATE_MVP_MATRIX:
-      append(dst, "matrix.mvp");
-      break;
-   case STATE_TEXTURE_MATRIX:
-      append(dst, "matrix.texture");
-      break;
-   case STATE_PROGRAM_MATRIX:
-      append(dst, "matrix.program");
-      break;
-   case STATE_COLOR_MATRIX:
-      append(dst, "matrix.color");
-      break;
-   case STATE_MATRIX_INVERSE:
-      append(dst, ".inverse");
-      break;
-   case STATE_MATRIX_TRANSPOSE:
-      append(dst, ".transpose");
-      break;
-   case STATE_MATRIX_INVTRANS:
-      append(dst, ".invtrans");
-      break;
-   case STATE_AMBIENT:
-      append(dst, ".ambient");
-      break;
-   case STATE_DIFFUSE:
-      append(dst, ".diffuse");
-      break;
-   case STATE_SPECULAR:
-      append(dst, ".specular");
-      break;
-   case STATE_EMISSION:
-      append(dst, ".emission");
-      break;
-   case STATE_SHININESS:
-      append(dst, "lshininess");
-      break;
-   case STATE_HALF_VECTOR:
-      append(dst, ".half");
-      break;
-   case STATE_POSITION:
-      append(dst, ".position");
-      break;
-   case STATE_ATTENUATION:
-      append(dst, ".attenuation");
-      break;
-   case STATE_SPOT_DIRECTION:
-      append(dst, ".spot.direction");
-      break;
-   case STATE_SPOT_CUTOFF:
-      append(dst, ".spot.cutoff");
-      break;
-   case STATE_TEXGEN_EYE_S:
-      append(dst, ".eye.s");
-      break;
-   case STATE_TEXGEN_EYE_T:
-      append(dst, ".eye.t");
-      break;
-   case STATE_TEXGEN_EYE_R:
-      append(dst, ".eye.r");
-      break;
-   case STATE_TEXGEN_EYE_Q:
-      append(dst, ".eye.q");
-      break;
-   case STATE_TEXGEN_OBJECT_S:
-      append(dst, ".object.s");
-      break;
-   case STATE_TEXGEN_OBJECT_T:
-      append(dst, ".object.t");
-      break;
-   case STATE_TEXGEN_OBJECT_R:
-      append(dst, ".object.r");
-      break;
-   case STATE_TEXGEN_OBJECT_Q:
-      append(dst, ".object.q");
-      break;
-   case STATE_TEXENV_COLOR:
-      append(dst, "texenv");
-      break;
-   case STATE_DEPTH_RANGE:
-      append(dst, "depth.range");
-      break;
-   case STATE_VERTEX_PROGRAM:
-   case STATE_FRAGMENT_PROGRAM:
-      break;
-   case STATE_ENV:
-      append(dst, "env");
-      break;
-   case STATE_LOCAL:
-      append(dst, "local");
-      break;
-   /* BEGIN internal state vars */
-   case STATE_INTERNAL:
-      append(dst, ".internal.");
-      break;
-   case STATE_CURRENT_ATTRIB:
-      append(dst, "current");
-      break;
-   case STATE_NORMAL_SCALE:
-      append(dst, "normalScale");
-      break;
-   case STATE_TEXRECT_SCALE:
-      append(dst, "texrectScale");
-      break;
-   case STATE_FOG_PARAMS_OPTIMIZED:
-      append(dst, "fogParamsOptimized");
-      break;
-   case STATE_POINT_SIZE_CLAMPED:
-      append(dst, "pointSizeClamped");
-      break;
-   case STATE_POINT_SIZE_IMPL_CLAMP:
-      append(dst, "pointSizeImplClamp");
-      break;
-   case STATE_LIGHT_SPOT_DIR_NORMALIZED:
-      append(dst, "lightSpotDirNormalized");
-      break;
-   case STATE_LIGHT_POSITION:
-      append(dst, "lightPosition");
-      break;
-   case STATE_LIGHT_POSITION_NORMALIZED:
-      append(dst, "light.position.normalized");
-      break;
-   case STATE_LIGHT_HALF_VECTOR:
-      append(dst, "lightHalfVector");
-      break;
-   case STATE_PT_SCALE:
-      append(dst, "PTscale");
-      break;
-   case STATE_PT_BIAS:
-      append(dst, "PTbias");
-      break;
-   case STATE_PCM_SCALE:
-      append(dst, "PCMscale");
-      break;
-   case STATE_PCM_BIAS:
-      append(dst, "PCMbias");
-      break;
-   case STATE_SHADOW_AMBIENT:
-      append(dst, "CompareFailValue");
-      break;
-   case STATE_FB_SIZE:
-      append(dst, "FbSize");
-      break;
-   case STATE_ROT_MATRIX_0:
-      append(dst, "rotMatrixRow0");
-      break;
-   case STATE_ROT_MATRIX_1:
-      append(dst, "rotMatrixRow1");
-      break;
-   default:
-      /* probably STATE_INTERNAL_DRIVER+i (driver private state) */
-      append(dst, "driverState");
-   }
-}
-
-static void
-append_face(char *dst, GLint face)
-{
-   if (face == 0)
-      append(dst, "front.");
-   else
-      append(dst, "back.");
-}
-
-static void
-append_index(char *dst, GLint index)
-{
-   char s[20];
-   sprintf(s, "[%d]", index);
-   append(dst, s);
-}
-
-/**
- * Make a string from the given state vector.
- * For example, return "state.matrix.texture[2].inverse".
- * Use free() to deallocate the string.
- */
-char *
-_mesa_program_state_string(const gl_state_index state[STATE_LENGTH])
-{
-   char str[1000] = "";
-   char tmp[30];
-
-   append(str, "state.");
-   append_token(str, state[0]);
-
-   switch (state[0]) {
-   case STATE_MATERIAL:
-      append_face(str, state[1]);
-      append_token(str, state[2]);
-      break;
-   case STATE_LIGHT:
-      append_index(str, state[1]); /* light number [i]. */
-      append_token(str, state[2]); /* coefficients */
-      break;
-   case STATE_LIGHTMODEL_AMBIENT:
-      append(str, "lightmodel.ambient");
-      break;
-   case STATE_LIGHTMODEL_SCENECOLOR:
-      if (state[1] == 0) {
-         append(str, "lightmodel.front.scenecolor");
-      }
-      else {
-         append(str, "lightmodel.back.scenecolor");
-      }
-      break;
-   case STATE_LIGHTPROD:
-      append_index(str, state[1]); /* light number [i]. */
-      append_face(str, state[2]);
-      append_token(str, state[3]);
-      break;
-   case STATE_TEXGEN:
-      append_index(str, state[1]); /* tex unit [i] */
-      append_token(str, state[2]); /* plane coef */
-      break;
-   case STATE_TEXENV_COLOR:
-      append_index(str, state[1]); /* tex unit [i] */
-      append(str, "color");
-      break;
-   case STATE_CLIPPLANE:
-      append_index(str, state[1]); /* plane [i] */
-      append(str, ".plane");
-      break;
-   case STATE_MODELVIEW_MATRIX:
-   case STATE_PROJECTION_MATRIX:
-   case STATE_MVP_MATRIX:
-   case STATE_TEXTURE_MATRIX:
-   case STATE_PROGRAM_MATRIX:
-   case STATE_COLOR_MATRIX:
-      {
-         /* state[0] = modelview, projection, texture, etc. */
-         /* state[1] = which texture matrix or program matrix */
-         /* state[2] = first row to fetch */
-         /* state[3] = last row to fetch */
-         /* state[4] = transpose, inverse or invtrans */
-         const gl_state_index mat = state[0];
-         const GLuint index = (GLuint) state[1];
-         const GLuint firstRow = (GLuint) state[2];
-         const GLuint lastRow = (GLuint) state[3];
-         const gl_state_index modifier = state[4];
-         if (index ||
-             mat == STATE_TEXTURE_MATRIX ||
-             mat == STATE_PROGRAM_MATRIX)
-            append_index(str, index);
-         if (modifier)
-            append_token(str, modifier);
-         if (firstRow == lastRow)
-            sprintf(tmp, ".row[%d]", firstRow);
-         else
-            sprintf(tmp, ".row[%d..%d]", firstRow, lastRow);
-         append(str, tmp);
-      }
-      break;
-   case STATE_POINT_SIZE:
-      break;
-   case STATE_POINT_ATTENUATION:
-      break;
-   case STATE_FOG_PARAMS:
-      break;
-   case STATE_FOG_COLOR:
-      break;
-   case STATE_DEPTH_RANGE:
-      break;
-   case STATE_FRAGMENT_PROGRAM:
-   case STATE_VERTEX_PROGRAM:
-      /* state[1] = {STATE_ENV, STATE_LOCAL} */
-      /* state[2] = parameter index          */
-      append_token(str, state[1]);
-      append_index(str, state[2]);
-      break;
-   case STATE_INTERNAL:
-      append_token(str, state[1]);
-      if (state[1] == STATE_CURRENT_ATTRIB)
-         append_index(str, state[2]);
-       break;
-   default:
-      _mesa_problem(NULL, "Invalid state in _mesa_program_state_string");
-      break;
-   }
-
-   return _mesa_strdup(str);
-}
-
-
-/**
- * Loop over all the parameters in a parameter list.  If the parameter
- * is a GL state reference, look up the current value of that state
- * variable and put it into the parameter's Value[4] array.
- * This would be called at glBegin time when using a fragment program.
- */
-void
-_mesa_load_state_parameters(GLcontext *ctx,
-                            struct gl_program_parameter_list *paramList)
-{
-   GLuint i;
-
-   if (!paramList)
-      return;
-
-   /*assert(ctx->Driver.NeedFlush == 0);*/
-
-   for (i = 0; i < paramList->NumParameters; i++) {
-      if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) {
-         _mesa_fetch_state(ctx,
-                          (gl_state_index *) paramList->Parameters[i].StateIndexes,
-                           paramList->ParameterValues[i]);
-      }
-   }
-}
-
-
-/**
- * Copy the 16 elements of a matrix into four consecutive program
- * registers starting at 'pos'.
- */
-static void
-load_matrix(GLfloat registers[][4], GLuint pos, const GLfloat mat[16])
-{
-   GLuint i;
-   for (i = 0; i < 4; i++) {
-      registers[pos + i][0] = mat[0 + i];
-      registers[pos + i][1] = mat[4 + i];
-      registers[pos + i][2] = mat[8 + i];
-      registers[pos + i][3] = mat[12 + i];
-   }
-}
-
-
-/**
- * As above, but transpose the matrix.
- */
-static void
-load_transpose_matrix(GLfloat registers[][4], GLuint pos,
-                      const GLfloat mat[16])
-{
-   memcpy(registers[pos], mat, 16 * sizeof(GLfloat));
-}
-
-
-/**
- * Load current vertex program's parameter registers with tracked
- * matrices (if NV program).  This only needs to be done per
- * glBegin/glEnd, not per-vertex.
- */
-void
-_mesa_load_tracked_matrices(GLcontext *ctx)
-{
-   GLuint i;
-
-   for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) {
-      /* point 'mat' at source matrix */
-      GLmatrix *mat;
-      if (ctx->VertexProgram.TrackMatrix[i] == GL_MODELVIEW) {
-         mat = ctx->ModelviewMatrixStack.Top;
-      }
-      else if (ctx->VertexProgram.TrackMatrix[i] == GL_PROJECTION) {
-         mat = ctx->ProjectionMatrixStack.Top;
-      }
-      else if (ctx->VertexProgram.TrackMatrix[i] == GL_TEXTURE) {
-         GLuint unit = MIN2(ctx->Texture.CurrentUnit,
-                            Elements(ctx->TextureMatrixStack) - 1);
-         mat = ctx->TextureMatrixStack[unit].Top;
-      }
-      else if (ctx->VertexProgram.TrackMatrix[i] == GL_COLOR) {
-         mat = ctx->ColorMatrixStack.Top;
-      }
-      else if (ctx->VertexProgram.TrackMatrix[i]==GL_MODELVIEW_PROJECTION_NV) {
-         /* XXX verify the combined matrix is up to date */
-         mat = &ctx->_ModelProjectMatrix;
-      }
-      else if (ctx->VertexProgram.TrackMatrix[i] >= GL_MATRIX0_NV &&
-               ctx->VertexProgram.TrackMatrix[i] <= GL_MATRIX7_NV) {
-         GLuint n = ctx->VertexProgram.TrackMatrix[i] - GL_MATRIX0_NV;
-         ASSERT(n < Elements(ctx->ProgramMatrixStack));
-         mat = ctx->ProgramMatrixStack[n].Top;
-      }
-      else {
-         /* no matrix is tracked, but we leave the register values as-is */
-         assert(ctx->VertexProgram.TrackMatrix[i] == GL_NONE);
-         continue;
-      }
-
-      /* load the matrix values into sequential registers */
-      if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_IDENTITY_NV) {
-         load_matrix(ctx->VertexProgram.Parameters, i*4, mat->m);
-      }
-      else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_INVERSE_NV) {
-         _math_matrix_analyse(mat); /* update the inverse */
-         ASSERT(!_math_matrix_is_dirty(mat));
-         load_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv);
-      }
-      else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_TRANSPOSE_NV) {
-         load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->m);
-      }
-      else {
-         assert(ctx->VertexProgram.TrackMatrixTransform[i]
-                == GL_INVERSE_TRANSPOSE_NV);
-         _math_matrix_analyse(mat); /* update the inverse */
-         ASSERT(!_math_matrix_is_dirty(mat));
-         load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv);
-      }
-   }
-}
diff --git a/src/mesa/shader/prog_statevars.h b/src/mesa/shader/prog_statevars.h
deleted file mode 100644 (file)
index 1753471..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef PROG_STATEVARS_H
-#define PROG_STATEVARS_H
-
-#include "main/mtypes.h"
-
-
-/**
- * Number of STATE_* values we need to address any GL state.
- * Used to dimension arrays.
- */
-#define STATE_LENGTH 5
-
-
-/**
- * Used for describing GL state referenced from inside ARB vertex and
- * fragment programs.
- * A string such as "state.light[0].ambient" gets translated into a
- * sequence of tokens such as [ STATE_LIGHT, 0, STATE_AMBIENT ].
- *
- * For state that's an array, like STATE_CLIPPLANE, the 2nd token [1] should
- * always be the array index.
- */
-typedef enum gl_state_index_ {
-   STATE_MATERIAL = 100,  /* start at 100 so small ints are seen as ints */
-
-   STATE_LIGHT,
-   STATE_LIGHTMODEL_AMBIENT,
-   STATE_LIGHTMODEL_SCENECOLOR,
-   STATE_LIGHTPROD,
-
-   STATE_TEXGEN,
-
-   STATE_FOG_COLOR,
-   STATE_FOG_PARAMS,
-
-   STATE_CLIPPLANE,
-
-   STATE_POINT_SIZE,
-   STATE_POINT_ATTENUATION,
-
-   STATE_MODELVIEW_MATRIX,
-   STATE_PROJECTION_MATRIX,
-   STATE_MVP_MATRIX,
-   STATE_TEXTURE_MATRIX,
-   STATE_PROGRAM_MATRIX,
-   STATE_COLOR_MATRIX,
-   STATE_MATRIX_INVERSE,
-   STATE_MATRIX_TRANSPOSE,
-   STATE_MATRIX_INVTRANS,
-
-   STATE_AMBIENT,
-   STATE_DIFFUSE,
-   STATE_SPECULAR,
-   STATE_EMISSION,
-   STATE_SHININESS,
-   STATE_HALF_VECTOR,
-
-   STATE_POSITION,       /**< xyzw = position */
-   STATE_ATTENUATION,    /**< xyz = attenuation, w = spot exponent */
-   STATE_SPOT_DIRECTION, /**< xyz = direction, w = cos(cutoff) */
-   STATE_SPOT_CUTOFF,    /**< x = cutoff, yzw = undefined */
-
-   STATE_TEXGEN_EYE_S,
-   STATE_TEXGEN_EYE_T,
-   STATE_TEXGEN_EYE_R,
-   STATE_TEXGEN_EYE_Q,
-   STATE_TEXGEN_OBJECT_S,
-   STATE_TEXGEN_OBJECT_T,
-   STATE_TEXGEN_OBJECT_R,
-   STATE_TEXGEN_OBJECT_Q,
-
-   STATE_TEXENV_COLOR,
-
-   STATE_DEPTH_RANGE,
-
-   STATE_VERTEX_PROGRAM,
-   STATE_FRAGMENT_PROGRAM,
-
-   STATE_ENV,
-   STATE_LOCAL,
-
-   STATE_INTERNAL,             /* Mesa additions */
-   STATE_CURRENT_ATTRIB,        /* ctx->Current vertex attrib value */
-   STATE_NORMAL_SCALE,
-   STATE_TEXRECT_SCALE,
-   STATE_FOG_PARAMS_OPTIMIZED,  /* for faster fog calc */
-   STATE_POINT_SIZE_CLAMPED,    /* includes implementation dependent size clamp */
-   STATE_POINT_SIZE_IMPL_CLAMP, /* for implementation clamp only in vs */
-   STATE_LIGHT_SPOT_DIR_NORMALIZED,   /* pre-normalized spot dir */
-   STATE_LIGHT_POSITION,              /* object vs eye space */
-   STATE_LIGHT_POSITION_NORMALIZED,   /* object vs eye space */
-   STATE_LIGHT_HALF_VECTOR,           /* object vs eye space */
-   STATE_PT_SCALE,              /**< Pixel transfer RGBA scale */
-   STATE_PT_BIAS,               /**< Pixel transfer RGBA bias */
-   STATE_PCM_SCALE,             /**< Post color matrix RGBA scale */
-   STATE_PCM_BIAS,              /**< Post color matrix RGBA bias */
-   STATE_SHADOW_AMBIENT,        /**< ARB_shadow_ambient fail value; token[2] is texture unit index */
-   STATE_FB_SIZE,               /**< (width-1, height-1, 0, 0) */
-   STATE_ROT_MATRIX_0,          /**< ATI_envmap_bumpmap, rot matrix row 0 */
-   STATE_ROT_MATRIX_1,          /**< ATI_envmap_bumpmap, rot matrix row 1 */
-   STATE_INTERNAL_DRIVER       /* first available state index for drivers (must be last) */
-} gl_state_index;
-
-
-
-extern void
-_mesa_load_state_parameters(GLcontext *ctx,
-                            struct gl_program_parameter_list *paramList);
-
-
-extern GLbitfield
-_mesa_program_state_flags(const gl_state_index state[STATE_LENGTH]);
-
-
-extern char *
-_mesa_program_state_string(const gl_state_index state[STATE_LENGTH]);
-
-
-extern void
-_mesa_load_tracked_matrices(GLcontext *ctx);
-
-
-#endif /* PROG_STATEVARS_H */
diff --git a/src/mesa/shader/prog_uniform.c b/src/mesa/shader/prog_uniform.c
deleted file mode 100644 (file)
index c408a84..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.1
- *
- * Copyright (C) 1999-2008  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 prog_uniform.c
- * Shader uniform functions.
- * \author Brian Paul
- */
-
-#include "main/imports.h"
-#include "main/mtypes.h"
-#include "prog_uniform.h"
-
-
-struct gl_uniform_list *
-_mesa_new_uniform_list(void)
-{
-   return CALLOC_STRUCT(gl_uniform_list);
-}
-
-
-void
-_mesa_free_uniform_list(struct gl_uniform_list *list)
-{
-   GLuint i;
-   for (i = 0; i < list->NumUniforms; i++) {
-      free((void *) list->Uniforms[i].Name);
-   }
-   free(list->Uniforms);
-   free(list);
-}
-
-
-struct gl_uniform *
-_mesa_append_uniform(struct gl_uniform_list *list,
-                     const char *name, GLenum target, GLuint progPos)
-{
-   const GLuint oldNum = list->NumUniforms;
-   struct gl_uniform *uniform;
-   GLint index;
-
-   assert(target == GL_VERTEX_PROGRAM_ARB ||
-          target == GL_FRAGMENT_PROGRAM_ARB);
-
-   index = _mesa_lookup_uniform(list, name);
-   if (index < 0) {
-      /* not found - append to list */
-
-      if (oldNum + 1 > list->Size) {
-         /* Need to grow the list array (alloc some extra) */
-         list->Size += 4;
-
-         /* realloc arrays */
-         list->Uniforms = (struct gl_uniform *)
-            _mesa_realloc(list->Uniforms,
-                          oldNum * sizeof(struct gl_uniform),
-                          list->Size * sizeof(struct gl_uniform));
-      }
-
-      if (!list->Uniforms) {
-         /* out of memory */
-         list->NumUniforms = 0;
-         list->Size = 0;
-         return GL_FALSE;
-      }
-
-      uniform = list->Uniforms + oldNum;
-
-      uniform->Name = _mesa_strdup(name);
-      uniform->VertPos = -1;
-      uniform->FragPos = -1;
-      uniform->Initialized = GL_FALSE;
-
-      list->NumUniforms++;
-   }
-   else {
-      /* found */
-      uniform = list->Uniforms + index;
-   }
-
-   /* update position for the vertex or fragment program */
-   if (target == GL_VERTEX_PROGRAM_ARB) {
-      if (uniform->VertPos != -1) {
-         /* this uniform is already in the list - that shouldn't happen */
-         return GL_FALSE;
-      }
-      uniform->VertPos = progPos;
-   }
-   else {
-      if (uniform->FragPos != -1) {
-         /* this uniform is already in the list - that shouldn't happen */
-         return GL_FALSE;
-      }
-      uniform->FragPos = progPos;
-   }
-
-   return uniform;
-}
-
-
-/**
- * Return the location/index of the named uniform in the uniform list,
- * or -1 if not found.
- */
-GLint
-_mesa_lookup_uniform(const struct gl_uniform_list *list, const char *name)
-{
-   GLuint i;
-   for (i = 0; list && i < list->NumUniforms; i++) {
-      if (!strcmp(list->Uniforms[i].Name, name)) {
-         return i;
-      }
-   }
-   return -1;
-}
-
-
-GLint
-_mesa_longest_uniform_name(const struct gl_uniform_list *list)
-{
-   GLint max = 0;
-   GLuint i;
-   for (i = 0; list && i < list->NumUniforms; i++) {
-      GLint len = (GLint) strlen(list->Uniforms[i].Name);
-      if (len > max)
-         max = len;
-   }
-   return max;
-}
-
-
-void
-_mesa_print_uniforms(const struct gl_uniform_list *list)
-{
-   GLuint i;
-   printf("Uniform list %p:\n", (void *) list);
-   for (i = 0; i < list->NumUniforms; i++) {
-      printf("%d: %s %d %d\n",
-             i,
-             list->Uniforms[i].Name,
-             list->Uniforms[i].VertPos,
-             list->Uniforms[i].FragPos);
-   }
-}
diff --git a/src/mesa/shader/prog_uniform.h b/src/mesa/shader/prog_uniform.h
deleted file mode 100644 (file)
index 22a2bfd..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.1
- *
- * Copyright (C) 1999-2008  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 prog_uniform.c
- * Shader uniform functions.
- * \author Brian Paul
- */
-
-#ifndef PROG_UNIFORM_H
-#define PROG_UNIFORM_H
-
-#include "main/mtypes.h"
-#include "prog_statevars.h"
-
-
-/**
- * Shader program uniform variable.
- * The glGetUniformLocation() and glUniform() commands will use this
- * information.
- * Note that a uniform such as "binormal" might be used in both the
- * vertex shader and the fragment shader.  When glUniform() is called to
- * set the uniform's value, it must be updated in both the vertex and
- * fragment shaders.  The uniform may be in different locations in the
- * two shaders so we keep track of that here.
- */
-struct gl_uniform
-{
-   const char *Name;        /**< Null-terminated string */
-   GLint VertPos;
-   GLint FragPos;
-   GLboolean Initialized;   /**< For debug.  Has this uniform been set? */
-#if 0
-   GLenum DataType;         /**< GL_FLOAT, GL_FLOAT_VEC2, etc */
-   GLuint Size;             /**< Number of components (1..4) */
-#endif
-};
-
-
-/**
- * List of gl_uniforms
- */
-struct gl_uniform_list
-{
-   GLuint Size;                 /**< allocated size of Uniforms array */
-   GLuint NumUniforms;          /**< number of uniforms in the array */
-   struct gl_uniform *Uniforms; /**< Array [Size] */
-};
-
-
-extern struct gl_uniform_list *
-_mesa_new_uniform_list(void);
-
-extern void
-_mesa_free_uniform_list(struct gl_uniform_list *list);
-
-extern struct gl_uniform *
-_mesa_append_uniform(struct gl_uniform_list *list,
-                     const char *name, GLenum target, GLuint progPos);
-
-extern GLint
-_mesa_lookup_uniform(const struct gl_uniform_list *list, const char *name);
-
-extern GLint
-_mesa_longest_uniform_name(const struct gl_uniform_list *list);
-
-extern void
-_mesa_print_uniforms(const struct gl_uniform_list *list);
-
-
-#endif /* PROG_UNIFORM_H */
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
deleted file mode 100644 (file)
index a6ada8a..0000000
+++ /dev/null
@@ -1,913 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.3
- *
- * 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 program.c
- * Vertex and fragment program support functions.
- * \author Brian Paul
- */
-
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/hash.h"
-#include "program.h"
-#include "prog_cache.h"
-#include "prog_parameter.h"
-#include "prog_instruction.h"
-
-
-/**
- * A pointer to this dummy program is put into the hash table when
- * glGenPrograms is called.
- */
-struct gl_program _mesa_DummyProgram;
-
-
-/**
- * Init context's vertex/fragment program state
- */
-void
-_mesa_init_program(GLcontext *ctx)
-{
-   GLuint i;
-
-   /*
-    * If this assertion fails, we need to increase the field
-    * size for register indexes.
-    */
-   ASSERT(ctx->Const.VertexProgram.MaxUniformComponents / 4
-          <= (1 << INST_INDEX_BITS));
-   ASSERT(ctx->Const.FragmentProgram.MaxUniformComponents / 4
-          <= (1 << INST_INDEX_BITS));
-
-   /* If this fails, increase prog_instruction::TexSrcUnit size */
-   ASSERT(MAX_TEXTURE_UNITS < (1 << 5));
-
-   /* If this fails, increase prog_instruction::TexSrcTarget size */
-   ASSERT(NUM_TEXTURE_TARGETS < (1 << 3));
-
-   ctx->Program.ErrorPos = -1;
-   ctx->Program.ErrorString = _mesa_strdup("");
-
-#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
-   ctx->VertexProgram.Enabled = GL_FALSE;
-#if FEATURE_es2_glsl
-   ctx->VertexProgram.PointSizeEnabled =
-      (ctx->API == API_OPENGLES2) ? GL_TRUE : GL_FALSE;
-#else
-   ctx->VertexProgram.PointSizeEnabled = GL_FALSE;
-#endif
-   ctx->VertexProgram.TwoSideEnabled = GL_FALSE;
-   _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
-                            ctx->Shared->DefaultVertexProgram);
-   assert(ctx->VertexProgram.Current);
-   for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) {
-      ctx->VertexProgram.TrackMatrix[i] = GL_NONE;
-      ctx->VertexProgram.TrackMatrixTransform[i] = GL_IDENTITY_NV;
-   }
-   ctx->VertexProgram.Cache = _mesa_new_program_cache();
-#endif
-
-#if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program
-   ctx->FragmentProgram.Enabled = GL_FALSE;
-   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
-                            ctx->Shared->DefaultFragmentProgram);
-   assert(ctx->FragmentProgram.Current);
-   ctx->FragmentProgram.Cache = _mesa_new_program_cache();
-#endif
-
-
-   /* XXX probably move this stuff */
-#if FEATURE_ATI_fragment_shader
-   ctx->ATIFragmentShader.Enabled = GL_FALSE;
-   ctx->ATIFragmentShader.Current = ctx->Shared->DefaultFragmentShader;
-   assert(ctx->ATIFragmentShader.Current);
-   ctx->ATIFragmentShader.Current->RefCount++;
-#endif
-}
-
-
-/**
- * Free a context's vertex/fragment program state
- */
-void
-_mesa_free_program_data(GLcontext *ctx)
-{
-#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
-   _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL);
-   _mesa_delete_program_cache(ctx, ctx->VertexProgram.Cache);
-#endif
-#if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program
-   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL);
-   _mesa_delete_program_cache(ctx, ctx->FragmentProgram.Cache);
-#endif
-   /* XXX probably move this stuff */
-#if FEATURE_ATI_fragment_shader
-   if (ctx->ATIFragmentShader.Current) {
-      ctx->ATIFragmentShader.Current->RefCount--;
-      if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
-         free(ctx->ATIFragmentShader.Current);
-      }
-   }
-#endif
-   free((void *) ctx->Program.ErrorString);
-}
-
-
-/**
- * Update the default program objects in the given context to reference those
- * specified in the shared state and release those referencing the old
- * shared state.
- */
-void
-_mesa_update_default_objects_program(GLcontext *ctx)
-{
-#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
-   _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
-                            (struct gl_vertex_program *)
-                            ctx->Shared->DefaultVertexProgram);
-   assert(ctx->VertexProgram.Current);
-#endif
-
-#if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program
-   _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
-                            (struct gl_fragment_program *)
-                            ctx->Shared->DefaultFragmentProgram);
-   assert(ctx->FragmentProgram.Current);
-#endif
-
-   /* XXX probably move this stuff */
-#if FEATURE_ATI_fragment_shader
-   if (ctx->ATIFragmentShader.Current) {
-      ctx->ATIFragmentShader.Current->RefCount--;
-      if (ctx->ATIFragmentShader.Current->RefCount <= 0) {
-         free(ctx->ATIFragmentShader.Current);
-      }
-   }
-   ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) ctx->Shared->DefaultFragmentShader;
-   assert(ctx->ATIFragmentShader.Current);
-   ctx->ATIFragmentShader.Current->RefCount++;
-#endif
-}
-
-
-/**
- * Set the vertex/fragment program error state (position and error string).
- * This is generally called from within the parsers.
- */
-void
-_mesa_set_program_error(GLcontext *ctx, GLint pos, const char *string)
-{
-   ctx->Program.ErrorPos = pos;
-   free((void *) ctx->Program.ErrorString);
-   if (!string)
-      string = "";
-   ctx->Program.ErrorString = _mesa_strdup(string);
-}
-
-
-/**
- * Find the line number and column for 'pos' within 'string'.
- * Return a copy of the line which contains 'pos'.  Free the line with
- * free().
- * \param string  the program string
- * \param pos     the position within the string
- * \param line    returns the line number corresponding to 'pos'.
- * \param col     returns the column number corresponding to 'pos'.
- * \return copy of the line containing 'pos'.
- */
-const GLubyte *
-_mesa_find_line_column(const GLubyte *string, const GLubyte *pos,
-                       GLint *line, GLint *col)
-{
-   const GLubyte *lineStart = string;
-   const GLubyte *p = string;
-   GLubyte *s;
-   int len;
-
-   *line = 1;
-
-   while (p != pos) {
-      if (*p == (GLubyte) '\n') {
-         (*line)++;
-         lineStart = p + 1;
-      }
-      p++;
-   }
-
-   *col = (pos - lineStart) + 1;
-
-   /* return copy of this line */
-   while (*p != 0 && *p != '\n')
-      p++;
-   len = p - lineStart;
-   s = (GLubyte *) malloc(len + 1);
-   memcpy(s, lineStart, len);
-   s[len] = 0;
-
-   return s;
-}
-
-
-/**
- * Initialize a new vertex/fragment program object.
- */
-static struct gl_program *
-_mesa_init_program_struct( GLcontext *ctx, struct gl_program *prog,
-                           GLenum target, GLuint id)
-{
-   (void) ctx;
-   if (prog) {
-      GLuint i;
-      memset(prog, 0, sizeof(*prog));
-      prog->Id = id;
-      prog->Target = target;
-      prog->Resident = GL_TRUE;
-      prog->RefCount = 1;
-      prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB;
-
-      /* default mapping from samplers to texture units */
-      for (i = 0; i < MAX_SAMPLERS; i++)
-         prog->SamplerUnits[i] = i;
-   }
-
-   return prog;
-}
-
-
-/**
- * Initialize a new fragment program object.
- */
-struct gl_program *
-_mesa_init_fragment_program( GLcontext *ctx, struct gl_fragment_program *prog,
-                             GLenum target, GLuint id)
-{
-   if (prog)
-      return _mesa_init_program_struct( ctx, &prog->Base, target, id );
-   else
-      return NULL;
-}
-
-
-/**
- * Initialize a new vertex program object.
- */
-struct gl_program *
-_mesa_init_vertex_program( GLcontext *ctx, struct gl_vertex_program *prog,
-                           GLenum target, GLuint id)
-{
-   if (prog)
-      return _mesa_init_program_struct( ctx, &prog->Base, target, id );
-   else
-      return NULL;
-}
-
-
-/**
- * Allocate and initialize a new fragment/vertex program object but
- * don't put it into the program hash table.  Called via
- * ctx->Driver.NewProgram.  May be overridden (ie. replaced) by a
- * device driver function to implement OO deriviation with additional
- * types not understood by this function.
- *
- * \param ctx  context
- * \param id   program id/number
- * \param target  program target/type
- * \return  pointer to new program object
- */
-struct gl_program *
-_mesa_new_program(GLcontext *ctx, GLenum target, GLuint id)
-{
-   struct gl_program *prog;
-   switch (target) {
-   case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */
-   case GL_VERTEX_STATE_PROGRAM_NV:
-      prog = _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program),
-                                       target, id );
-      break;
-   case GL_FRAGMENT_PROGRAM_NV:
-   case GL_FRAGMENT_PROGRAM_ARB:
-      prog =_mesa_init_fragment_program(ctx,
-                                         CALLOC_STRUCT(gl_fragment_program),
-                                         target, id );
-      break;
-   default:
-      _mesa_problem(ctx, "bad target in _mesa_new_program");
-      prog = NULL;
-   }
-   return prog;
-}
-
-
-/**
- * Delete a program and remove it from the hash table, ignoring the
- * reference count.
- * Called via ctx->Driver.DeleteProgram.  May be wrapped (OO deriviation)
- * by a device driver function.
- */
-void
-_mesa_delete_program(GLcontext *ctx, struct gl_program *prog)
-{
-   (void) ctx;
-   ASSERT(prog);
-   ASSERT(prog->RefCount==0);
-
-   if (prog == &_mesa_DummyProgram)
-      return;
-
-   if (prog->String)
-      free(prog->String);
-
-   _mesa_free_instructions(prog->Instructions, prog->NumInstructions);
-
-   if (prog->Parameters) {
-      _mesa_free_parameter_list(prog->Parameters);
-   }
-   if (prog->Varying) {
-      _mesa_free_parameter_list(prog->Varying);
-   }
-   if (prog->Attributes) {
-      _mesa_free_parameter_list(prog->Attributes);
-   }
-
-   free(prog);
-}
-
-
-/**
- * Return the gl_program object for a given ID.
- * Basically just a wrapper for _mesa_HashLookup() to avoid a lot of
- * casts elsewhere.
- */
-struct gl_program *
-_mesa_lookup_program(GLcontext *ctx, GLuint id)
-{
-   if (id)
-      return (struct gl_program *) _mesa_HashLookup(ctx->Shared->Programs, id);
-   else
-      return NULL;
-}
-
-
-/**
- * Reference counting for vertex/fragment programs
- */
-void
-_mesa_reference_program(GLcontext *ctx,
-                        struct gl_program **ptr,
-                        struct gl_program *prog)
-{
-   assert(ptr);
-   if (*ptr && prog) {
-      /* sanity check */
-      if ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB)
-         ASSERT(prog->Target == GL_VERTEX_PROGRAM_ARB);
-      else if ((*ptr)->Target == GL_FRAGMENT_PROGRAM_ARB)
-         ASSERT(prog->Target == GL_FRAGMENT_PROGRAM_ARB ||
-                prog->Target == GL_FRAGMENT_PROGRAM_NV);
-   }
-   if (*ptr == prog) {
-      return;  /* no change */
-   }
-   if (*ptr) {
-      GLboolean deleteFlag;
-
-      /*_glthread_LOCK_MUTEX((*ptr)->Mutex);*/
-#if 0
-      printf("Program %p ID=%u Target=%s  Refcount-- to %d\n",
-             *ptr, (*ptr)->Id,
-             ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB ? "VP" : "FP"),
-             (*ptr)->RefCount - 1);
-#endif
-      ASSERT((*ptr)->RefCount > 0);
-      (*ptr)->RefCount--;
-
-      deleteFlag = ((*ptr)->RefCount == 0);
-      /*_glthread_UNLOCK_MUTEX((*ptr)->Mutex);*/
-
-      if (deleteFlag) {
-         ASSERT(ctx);
-         ctx->Driver.DeleteProgram(ctx, *ptr);
-      }
-
-      *ptr = NULL;
-   }
-
-   assert(!*ptr);
-   if (prog) {
-      /*_glthread_LOCK_MUTEX(prog->Mutex);*/
-      prog->RefCount++;
-#if 0
-      printf("Program %p ID=%u Target=%s  Refcount++ to %d\n",
-             prog, prog->Id,
-             (prog->Target == GL_VERTEX_PROGRAM_ARB ? "VP" : "FP"),
-             prog->RefCount);
-#endif
-      /*_glthread_UNLOCK_MUTEX(prog->Mutex);*/
-   }
-
-   *ptr = prog;
-}
-
-
-/**
- * Return a copy of a program.
- * XXX Problem here if the program object is actually OO-derivation
- * made by a device driver.
- */
-struct gl_program *
-_mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)
-{
-   struct gl_program *clone;
-
-   clone = ctx->Driver.NewProgram(ctx, prog->Target, prog->Id);
-   if (!clone)
-      return NULL;
-
-   assert(clone->Target == prog->Target);
-   assert(clone->RefCount == 1);
-
-   clone->String = (GLubyte *) _mesa_strdup((char *) prog->String);
-   clone->Format = prog->Format;
-   clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions);
-   if (!clone->Instructions) {
-      _mesa_reference_program(ctx, &clone, NULL);
-      return NULL;
-   }
-   _mesa_copy_instructions(clone->Instructions, prog->Instructions,
-                           prog->NumInstructions);
-   clone->InputsRead = prog->InputsRead;
-   clone->OutputsWritten = prog->OutputsWritten;
-   clone->SamplersUsed = prog->SamplersUsed;
-   clone->ShadowSamplers = prog->ShadowSamplers;
-   memcpy(clone->TexturesUsed, prog->TexturesUsed, sizeof(prog->TexturesUsed));
-
-   if (prog->Parameters)
-      clone->Parameters = _mesa_clone_parameter_list(prog->Parameters);
-   memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams));
-   if (prog->Varying)
-      clone->Varying = _mesa_clone_parameter_list(prog->Varying);
-   if (prog->Attributes)
-      clone->Attributes = _mesa_clone_parameter_list(prog->Attributes);
-   memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams));
-   clone->NumInstructions = prog->NumInstructions;
-   clone->NumTemporaries = prog->NumTemporaries;
-   clone->NumParameters = prog->NumParameters;
-   clone->NumAttributes = prog->NumAttributes;
-   clone->NumAddressRegs = prog->NumAddressRegs;
-   clone->NumNativeInstructions = prog->NumNativeInstructions;
-   clone->NumNativeTemporaries = prog->NumNativeTemporaries;
-   clone->NumNativeParameters = prog->NumNativeParameters;
-   clone->NumNativeAttributes = prog->NumNativeAttributes;
-   clone->NumNativeAddressRegs = prog->NumNativeAddressRegs;
-   clone->NumAluInstructions = prog->NumAluInstructions;
-   clone->NumTexInstructions = prog->NumTexInstructions;
-   clone->NumTexIndirections = prog->NumTexIndirections;
-   clone->NumNativeAluInstructions = prog->NumNativeAluInstructions;
-   clone->NumNativeTexInstructions = prog->NumNativeTexInstructions;
-   clone->NumNativeTexIndirections = prog->NumNativeTexIndirections;
-
-   switch (prog->Target) {
-   case GL_VERTEX_PROGRAM_ARB:
-      {
-         const struct gl_vertex_program *vp
-            = (const struct gl_vertex_program *) prog;
-         struct gl_vertex_program *vpc = (struct gl_vertex_program *) clone;
-         vpc->IsPositionInvariant = vp->IsPositionInvariant;
-         vpc->IsNVProgram = vp->IsNVProgram;
-      }
-      break;
-   case GL_FRAGMENT_PROGRAM_ARB:
-      {
-         const struct gl_fragment_program *fp
-            = (const struct gl_fragment_program *) prog;
-         struct gl_fragment_program *fpc = (struct gl_fragment_program *) clone;
-         fpc->FogOption = fp->FogOption;
-         fpc->UsesKill = fp->UsesKill;
-         fpc->OriginUpperLeft = fp->OriginUpperLeft;
-         fpc->PixelCenterInteger = fp->PixelCenterInteger;
-      }
-      break;
-   default:
-      _mesa_problem(NULL, "Unexpected target in _mesa_clone_program");
-   }
-
-   return clone;
-}
-
-
-/**
- * Insert 'count' NOP instructions at 'start' in the given program.
- * Adjust branch targets accordingly.
- */
-GLboolean
-_mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count)
-{
-   const GLuint origLen = prog->NumInstructions;
-   const GLuint newLen = origLen + count;
-   struct prog_instruction *newInst;
-   GLuint i;
-
-   /* adjust branches */
-   for (i = 0; i < prog->NumInstructions; i++) {
-      struct prog_instruction *inst = prog->Instructions + i;
-      if (inst->BranchTarget > 0) {
-         if ((GLuint)inst->BranchTarget >= start) {
-            inst->BranchTarget += count;
-         }
-      }
-   }
-
-   /* Alloc storage for new instructions */
-   newInst = _mesa_alloc_instructions(newLen);
-   if (!newInst) {
-      return GL_FALSE;
-   }
-
-   /* Copy 'start' instructions into new instruction buffer */
-   _mesa_copy_instructions(newInst, prog->Instructions, start);
-
-   /* init the new instructions */
-   _mesa_init_instructions(newInst + start, count);
-
-   /* Copy the remaining/tail instructions to new inst buffer */
-   _mesa_copy_instructions(newInst + start + count,
-                           prog->Instructions + start,
-                           origLen - start);
-
-   /* free old instructions */
-   _mesa_free_instructions(prog->Instructions, origLen);
-
-   /* install new instructions */
-   prog->Instructions = newInst;
-   prog->NumInstructions = newLen;
-
-   return GL_TRUE;
-}
-
-/**
- * Delete 'count' instructions at 'start' in the given program.
- * Adjust branch targets accordingly.
- */
-GLboolean
-_mesa_delete_instructions(struct gl_program *prog, GLuint start, GLuint count)
-{
-   const GLuint origLen = prog->NumInstructions;
-   const GLuint newLen = origLen - count;
-   struct prog_instruction *newInst;
-   GLuint i;
-
-   /* adjust branches */
-   for (i = 0; i < prog->NumInstructions; i++) {
-      struct prog_instruction *inst = prog->Instructions + i;
-      if (inst->BranchTarget > 0) {
-         if (inst->BranchTarget > (GLint) start) {
-            inst->BranchTarget -= count;
-         }
-      }
-   }
-
-   /* Alloc storage for new instructions */
-   newInst = _mesa_alloc_instructions(newLen);
-   if (!newInst) {
-      return GL_FALSE;
-   }
-
-   /* Copy 'start' instructions into new instruction buffer */
-   _mesa_copy_instructions(newInst, prog->Instructions, start);
-
-   /* Copy the remaining/tail instructions to new inst buffer */
-   _mesa_copy_instructions(newInst + start,
-                           prog->Instructions + start + count,
-                           newLen - start);
-
-   /* free old instructions */
-   _mesa_free_instructions(prog->Instructions, origLen);
-
-   /* install new instructions */
-   prog->Instructions = newInst;
-   prog->NumInstructions = newLen;
-
-   return GL_TRUE;
-}
-
-
-/**
- * Search instructions for registers that match (oldFile, oldIndex),
- * replacing them with (newFile, newIndex).
- */
-static void
-replace_registers(struct prog_instruction *inst, GLuint numInst,
-                  GLuint oldFile, GLuint oldIndex,
-                  GLuint newFile, GLuint newIndex)
-{
-   GLuint i, j;
-   for (i = 0; i < numInst; i++) {
-      /* src regs */
-      for (j = 0; j < _mesa_num_inst_src_regs(inst[i].Opcode); j++) {
-         if (inst[i].SrcReg[j].File == oldFile &&
-             inst[i].SrcReg[j].Index == oldIndex) {
-            inst[i].SrcReg[j].File = newFile;
-            inst[i].SrcReg[j].Index = newIndex;
-         }
-      }
-      /* dst reg */
-      if (inst[i].DstReg.File == oldFile && inst[i].DstReg.Index == oldIndex) {
-         inst[i].DstReg.File = newFile;
-         inst[i].DstReg.Index = newIndex;
-      }
-   }
-}
-
-
-/**
- * Search instructions for references to program parameters.  When found,
- * increment the parameter index by 'offset'.
- * Used when combining programs.
- */
-static void
-adjust_param_indexes(struct prog_instruction *inst, GLuint numInst,
-                     GLuint offset)
-{
-   GLuint i, j;
-   for (i = 0; i < numInst; i++) {
-      for (j = 0; j < _mesa_num_inst_src_regs(inst[i].Opcode); j++) {
-         GLuint f = inst[i].SrcReg[j].File;
-         if (f == PROGRAM_CONSTANT ||
-             f == PROGRAM_UNIFORM ||
-             f == PROGRAM_STATE_VAR) {
-            inst[i].SrcReg[j].Index += offset;
-         }
-      }
-   }
-}
-
-
-/**
- * Combine two programs into one.  Fix instructions so the outputs of
- * the first program go to the inputs of the second program.
- */
-struct gl_program *
-_mesa_combine_programs(GLcontext *ctx,
-                       const struct gl_program *progA,
-                       const struct gl_program *progB)
-{
-   struct prog_instruction *newInst;
-   struct gl_program *newProg;
-   const GLuint lenA = progA->NumInstructions - 1; /* omit END instr */
-   const GLuint lenB = progB->NumInstructions;
-   const GLuint numParamsA = _mesa_num_parameters(progA->Parameters);
-   const GLuint newLength = lenA + lenB;
-   GLboolean usedTemps[MAX_PROGRAM_TEMPS];
-   GLuint firstTemp = 0;
-   GLbitfield inputsB;
-   GLuint i;
-
-   ASSERT(progA->Target == progB->Target);
-
-   newInst = _mesa_alloc_instructions(newLength);
-   if (!newInst)
-      return GL_FALSE;
-
-   _mesa_copy_instructions(newInst, progA->Instructions, lenA);
-   _mesa_copy_instructions(newInst + lenA, progB->Instructions, lenB);
-
-   /* adjust branch / instruction addresses for B's instructions */
-   for (i = 0; i < lenB; i++) {
-      newInst[lenA + i].BranchTarget += lenA;
-   }
-
-   newProg = ctx->Driver.NewProgram(ctx, progA->Target, 0);
-   newProg->Instructions = newInst;
-   newProg->NumInstructions = newLength;
-
-   /* find used temp regs (we may need new temps below) */
-   _mesa_find_used_registers(newProg, PROGRAM_TEMPORARY,
-                             usedTemps, MAX_PROGRAM_TEMPS);
-
-   if (newProg->Target == GL_FRAGMENT_PROGRAM_ARB) {
-      struct gl_fragment_program *fprogA, *fprogB, *newFprog;
-      GLbitfield progB_inputsRead = progB->InputsRead;
-      GLint progB_colorFile, progB_colorIndex;
-
-      fprogA = (struct gl_fragment_program *) progA;
-      fprogB = (struct gl_fragment_program *) progB;
-      newFprog = (struct gl_fragment_program *) newProg;
-
-      newFprog->UsesKill = fprogA->UsesKill || fprogB->UsesKill;
-
-      /* We'll do a search and replace for instances
-       * of progB_colorFile/progB_colorIndex below...
-       */
-      progB_colorFile = PROGRAM_INPUT;
-      progB_colorIndex = FRAG_ATTRIB_COL0;
-
-      /*
-       * The fragment program may get color from a state var rather than
-       * a fragment input (vertex output) if it's constant.
-       * See the texenvprogram.c code.
-       * So, search the program's parameter list now to see if the program
-       * gets color from a state var instead of a conventional fragment
-       * input register.
-       */
-      for (i = 0; i < progB->Parameters->NumParameters; i++) {
-         struct gl_program_parameter *p = &progB->Parameters->Parameters[i];
-         if (p->Type == PROGRAM_STATE_VAR &&
-             p->StateIndexes[0] == STATE_INTERNAL &&
-             p->StateIndexes[1] == STATE_CURRENT_ATTRIB &&
-             p->StateIndexes[2] == VERT_ATTRIB_COLOR0) {
-            progB_inputsRead |= FRAG_BIT_COL0;
-            progB_colorFile = PROGRAM_STATE_VAR;
-            progB_colorIndex = i;
-            break;
-         }
-      }
-
-      /* Connect color outputs of fprogA to color inputs of fprogB, via a
-       * new temporary register.
-       */
-      if ((progA->OutputsWritten & (1 << FRAG_RESULT_COLOR)) &&
-          (progB_inputsRead & FRAG_BIT_COL0)) {
-         GLint tempReg = _mesa_find_free_register(usedTemps, MAX_PROGRAM_TEMPS,
-                                                  firstTemp);
-         if (tempReg < 0) {
-            _mesa_problem(ctx, "No free temp regs found in "
-                          "_mesa_combine_programs(), using 31");
-            tempReg = 31;
-         }
-         firstTemp = tempReg + 1;
-
-         /* replace writes to result.color[0] with tempReg */
-         replace_registers(newInst, lenA,
-                           PROGRAM_OUTPUT, FRAG_RESULT_COLOR,
-                           PROGRAM_TEMPORARY, tempReg);
-         /* replace reads from the input color with tempReg */
-         replace_registers(newInst + lenA, lenB,
-                           progB_colorFile, progB_colorIndex, /* search for */
-                           PROGRAM_TEMPORARY, tempReg  /* replace with */ );
-      }
-
-      /* compute combined program's InputsRead */
-      inputsB = progB_inputsRead;
-      if (progA->OutputsWritten & (1 << FRAG_RESULT_COLOR)) {
-         inputsB &= ~(1 << FRAG_ATTRIB_COL0);
-      }
-      newProg->InputsRead = progA->InputsRead | inputsB;
-      newProg->OutputsWritten = progB->OutputsWritten;
-      newProg->SamplersUsed = progA->SamplersUsed | progB->SamplersUsed;
-   }
-   else {
-      /* vertex program */
-      assert(0);      /* XXX todo */
-   }
-
-   /*
-    * Merge parameters (uniforms, constants, etc)
-    */
-   newProg->Parameters = _mesa_combine_parameter_lists(progA->Parameters,
-                                                       progB->Parameters);
-
-   adjust_param_indexes(newInst + lenA, lenB, numParamsA);
-
-
-   return newProg;
-}
-
-
-/**
- * Populate the 'used' array with flags indicating which registers (TEMPs,
- * INPUTs, OUTPUTs, etc, are used by the given program.
- * \param file  type of register to scan for
- * \param used  returns true/false flags for in use / free
- * \param usedSize  size of the 'used' array
- */
-void
-_mesa_find_used_registers(const struct gl_program *prog,
-                          gl_register_file file,
-                          GLboolean used[], GLuint usedSize)
-{
-   GLuint i, j;
-
-   memset(used, 0, usedSize);
-
-   for (i = 0; i < prog->NumInstructions; i++) {
-      const struct prog_instruction *inst = prog->Instructions + i;
-      const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
-
-      if (inst->DstReg.File == file) {
-         used[inst->DstReg.Index] = GL_TRUE;
-      }
-
-      for (j = 0; j < n; j++) {
-         if (inst->SrcReg[j].File == file) {
-            used[inst->SrcReg[j].Index] = GL_TRUE;
-         }
-      }
-   }
-}
-
-
-/**
- * Scan the given 'used' register flag array for the first entry
- * that's >= firstReg.
- * \param used  vector of flags indicating registers in use (as returned
- *              by _mesa_find_used_registers())
- * \param usedSize  size of the 'used' array
- * \param firstReg  first register to start searching at
- * \return index of unused register, or -1 if none.
- */
-GLint
-_mesa_find_free_register(const GLboolean used[],
-                         GLuint usedSize, GLuint firstReg)
-{
-   GLuint i;
-
-   assert(firstReg < usedSize);
-
-   for (i = firstReg; i < usedSize; i++)
-      if (!used[i])
-         return i;
-
-   return -1;
-}
-
-
-/**
- * "Post-process" a GPU program.  This is intended to be used for debugging.
- * Example actions include no-op'ing instructions or changing instruction
- * behaviour.
- */
-void
-_mesa_postprocess_program(GLcontext *ctx, struct gl_program *prog)
-{
-   static const GLfloat white[4] = { 0.5, 0.5, 0.5, 0.5 };
-   GLuint i;
-   GLuint whiteSwizzle;
-   GLint whiteIndex = _mesa_add_unnamed_constant(prog->Parameters,
-                                                 white, 4, &whiteSwizzle);
-
-   (void) whiteIndex;
-
-   for (i = 0; i < prog->NumInstructions; i++) {
-      struct prog_instruction *inst = prog->Instructions + i;
-      const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
-
-      (void) n;
-
-      if (_mesa_is_tex_instruction(inst->Opcode)) {
-#if 0
-         /* replace TEX/TXP/TXB with MOV */
-         inst->Opcode = OPCODE_MOV;
-         inst->DstReg.WriteMask = WRITEMASK_XYZW;
-         inst->SrcReg[0].Swizzle = SWIZZLE_XYZW;
-         inst->SrcReg[0].Negate = NEGATE_NONE;
-#endif
-
-#if 0
-         /* disable shadow texture mode */
-         inst->TexShadow = 0;
-#endif
-      }
-
-      if (inst->Opcode == OPCODE_TXP) {
-#if 0
-         inst->Opcode = OPCODE_MOV;
-         inst->DstReg.WriteMask = WRITEMASK_XYZW;
-         inst->SrcReg[0].File = PROGRAM_CONSTANT;
-         inst->SrcReg[0].Index = whiteIndex;
-         inst->SrcReg[0].Swizzle = SWIZZLE_XYZW;
-         inst->SrcReg[0].Negate = NEGATE_NONE;
-#endif
-#if 0
-         inst->TexShadow = 0;
-#endif
-#if 0
-         inst->Opcode = OPCODE_TEX;
-         inst->TexShadow = 0;
-#endif
-      }
-
-   }
-}
diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h
deleted file mode 100644 (file)
index af9f417..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.3
- *
- * 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 program.c
- * Vertex and fragment program support functions.
- * \author Brian Paul
- */
-
-
-/**
- * \mainpage Mesa vertex and fragment program module
- *
- * This module or directory contains most of the code for vertex and
- * fragment programs and shaders, including state management, parsers,
- * and (some) software routines for executing programs
- */
-
-#ifndef PROGRAM_H
-#define PROGRAM_H
-
-#include "main/mtypes.h"
-
-
-extern struct gl_program _mesa_DummyProgram;
-
-
-extern void
-_mesa_init_program(GLcontext *ctx);
-
-extern void
-_mesa_free_program_data(GLcontext *ctx);
-
-extern void
-_mesa_update_default_objects_program(GLcontext *ctx);
-
-extern void
-_mesa_set_program_error(GLcontext *ctx, GLint pos, const char *string);
-
-extern const GLubyte *
-_mesa_find_line_column(const GLubyte *string, const GLubyte *pos,
-                       GLint *line, GLint *col);
-
-
-extern struct gl_program *
-_mesa_init_vertex_program(GLcontext *ctx,
-                          struct gl_vertex_program *prog,
-                          GLenum target, GLuint id);
-
-extern struct gl_program *
-_mesa_init_fragment_program(GLcontext *ctx,
-                            struct gl_fragment_program *prog,
-                            GLenum target, GLuint id);
-
-extern struct gl_program *
-_mesa_new_program(GLcontext *ctx, GLenum target, GLuint id);
-
-extern void
-_mesa_delete_program(GLcontext *ctx, struct gl_program *prog);
-
-extern struct gl_program *
-_mesa_lookup_program(GLcontext *ctx, GLuint id);
-
-extern void
-_mesa_reference_program(GLcontext *ctx,
-                        struct gl_program **ptr,
-                        struct gl_program *prog);
-
-static INLINE void
-_mesa_reference_vertprog(GLcontext *ctx,
-                         struct gl_vertex_program **ptr,
-                         struct gl_vertex_program *prog)
-{
-   _mesa_reference_program(ctx, (struct gl_program **) ptr,
-                           (struct gl_program *) prog);
-}
-
-static INLINE void
-_mesa_reference_fragprog(GLcontext *ctx,
-                         struct gl_fragment_program **ptr,
-                         struct gl_fragment_program *prog)
-{
-   _mesa_reference_program(ctx, (struct gl_program **) ptr,
-                           (struct gl_program *) prog);
-}
-
-extern struct gl_program *
-_mesa_clone_program(GLcontext *ctx, const struct gl_program *prog);
-
-static INLINE struct gl_vertex_program *
-_mesa_clone_vertex_program(GLcontext *ctx,
-                           const struct gl_vertex_program *prog)
-{
-   return (struct gl_vertex_program *) _mesa_clone_program(ctx, &prog->Base);
-}
-
-
-static INLINE struct gl_fragment_program *
-_mesa_clone_fragment_program(GLcontext *ctx,
-                             const struct gl_fragment_program *prog)
-{
-   return (struct gl_fragment_program *) _mesa_clone_program(ctx, &prog->Base);
-}
-
-
-extern  GLboolean
-_mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count);
-
-extern  GLboolean
-_mesa_delete_instructions(struct gl_program *prog, GLuint start, GLuint count);
-
-extern struct gl_program *
-_mesa_combine_programs(GLcontext *ctx,
-                       const struct gl_program *progA,
-                       const struct gl_program *progB);
-
-extern void
-_mesa_find_used_registers(const struct gl_program *prog,
-                          gl_register_file file,
-                          GLboolean used[], GLuint usedSize);
-
-extern GLint
-_mesa_find_free_register(const GLboolean used[],
-                         GLuint maxRegs, GLuint firstReg);
-
-extern void
-_mesa_postprocess_program(GLcontext *ctx, struct gl_program *prog);
-
-
-#endif /* PROGRAM_H */
diff --git a/src/mesa/shader/program_lexer.l b/src/mesa/shader/program_lexer.l
deleted file mode 100644 (file)
index fe18272..0000000
+++ /dev/null
@@ -1,495 +0,0 @@
-%{
-/*
- * Copyright Â© 2009 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION 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/imports.h"
-#include "shader/prog_instruction.h"
-#include "shader/prog_statevars.h"
-
-#include "shader/symbol_table.h"
-#include "shader/program_parser.h"
-#include "shader/program_parse.tab.h"
-
-#define require_ARB_vp (yyextra->mode == ARB_vertex)
-#define require_ARB_fp (yyextra->mode == ARB_fragment)
-#define require_NV_fp  (yyextra->option.NV_fragment)
-#define require_shadow (yyextra->option.Shadow)
-#define require_rect   (yyextra->option.TexRect)
-#define require_texarray        (yyextra->option.TexArray)
-
-#ifndef HAVE_UNISTD_H
-#define YY_NO_UNISTD_H
-#endif
-
-#define return_token_or_IDENTIFIER(condition, token)   \
-   do {                                                        \
-      if (condition) {                                 \
-        return token;                                  \
-      } else {                                         \
-        return handle_ident(yyextra, yytext, yylval);  \
-      }                                                        \
-   } while (0)
-
-#define return_token_or_DOT(condition, token)          \
-   do {                                                        \
-      if (condition) {                                 \
-        return token;                                  \
-      } else {                                         \
-        yyless(1);                                     \
-        return DOT;                                    \
-      }                                                        \
-   } while (0)
-
-
-#define return_opcode(condition, token, opcode, len)   \
-   do {                                                        \
-      if (condition &&                                 \
-         _mesa_parse_instruction_suffix(yyextra,       \
-                                        yytext + len,  \
-                                        & yylval->temp_inst)) {        \
-        yylval->temp_inst.Opcode = OPCODE_ ## opcode;  \
-        return token;                                  \
-      } else {                                         \
-        return handle_ident(yyextra, yytext, yylval);  \
-      }                                                        \
-   } while (0)
-
-#define SWIZZLE_INVAL  MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
-                                    SWIZZLE_NIL, SWIZZLE_NIL)
-
-static unsigned
-mask_from_char(char c)
-{
-   switch (c) {
-   case 'x':
-   case 'r':
-      return WRITEMASK_X;
-   case 'y':
-   case 'g':
-      return WRITEMASK_Y;
-   case 'z':
-   case 'b':
-      return WRITEMASK_Z;
-   case 'w':
-   case 'a':
-      return WRITEMASK_W;
-   }
-
-   return 0;
-}
-
-static unsigned
-swiz_from_char(char c)
-{
-   switch (c) {
-   case 'x':
-   case 'r':
-      return SWIZZLE_X;
-   case 'y':
-   case 'g':
-      return SWIZZLE_Y;
-   case 'z':
-   case 'b':
-      return SWIZZLE_Z;
-   case 'w':
-   case 'a':
-      return SWIZZLE_W;
-   }
-
-   return 0;
-}
-
-static int
-handle_ident(struct asm_parser_state *state, const char *text, YYSTYPE *lval)
-{
-   lval->string = strdup(text);
-
-   return (_mesa_symbol_table_find_symbol(state->st, 0, text) == NULL)
-      ? IDENTIFIER : USED_IDENTIFIER;
-}
-
-#define YY_USER_ACTION                                                 \
-   do {                                                                        \
-      yylloc->first_column = yylloc->last_column;                      \
-      yylloc->last_column += yyleng;                                   \
-      if ((yylloc->first_line == 1)                                    \
-         && (yylloc->first_column == 1)) {                             \
-        yylloc->position = 1;                                          \
-      } else {                                                         \
-        yylloc->position += yylloc->last_column - yylloc->first_column; \
-      }                                                                        \
-   } while(0);
-
-#define YY_EXTRA_TYPE struct asm_parser_state *
-%}
-
-num    [0-9]+
-exp    [Ee][-+]?[0-9]+
-frac   "."[0-9]+
-dot    "."[ \t]*
-
-sz     [HRX]?
-szf    [HR]?
-cc     C?
-sat    (_SAT)?
-
-%option bison-bridge bison-locations reentrant noyywrap
-%%
-
-"!!ARBvp1.0"              { return ARBvp_10; }
-"!!ARBfp1.0"              { return ARBfp_10; }
-ADDRESS                   {
-   yylval->integer = at_address;
-   return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS);
-}
-ALIAS                     { return ALIAS; }
-ATTRIB                    { return ATTRIB; }
-END                       { return END; }
-OPTION                    { return OPTION; }
-OUTPUT                    { return OUTPUT; }
-PARAM                     { return PARAM; }
-TEMP                      { yylval->integer = at_temp; return TEMP; }
-
-ABS{sz}{cc}{sat}   { return_opcode(             1, VECTOR_OP, ABS, 3); }
-ADD{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, ADD, 3); }
-ARL                { return_opcode(require_ARB_vp, ARL, ARL, 3); }
-
-CMP{sat}           { return_opcode(require_ARB_fp, TRI_OP, CMP, 3); }
-COS{szf}{cc}{sat}  { return_opcode(require_ARB_fp, SCALAR_OP, COS, 3); }
-
-DDX{szf}{cc}{sat}  { return_opcode(require_NV_fp,  VECTOR_OP, DDX, 3); }
-DDY{szf}{cc}{sat}  { return_opcode(require_NV_fp,  VECTOR_OP, DDY, 3); }
-DP3{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, DP3, 3); }
-DP4{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, DP4, 3); }
-DPH{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, DPH, 3); }
-DST{szf}{cc}{sat}  { return_opcode(             1, BIN_OP, DST, 3); }
-
-EX2{szf}{cc}{sat}  { return_opcode(             1, SCALAR_OP, EX2, 3); }
-EXP                { return_opcode(require_ARB_vp, SCALAR_OP, EXP, 3); }
-
-FLR{sz}{cc}{sat}   { return_opcode(             1, VECTOR_OP, FLR, 3); }
-FRC{sz}{cc}{sat}   { return_opcode(             1, VECTOR_OP, FRC, 3); }
-
-KIL                { return_opcode(require_ARB_fp, KIL, KIL, 3); }
-
-LIT{szf}{cc}{sat}  { return_opcode(             1, VECTOR_OP, LIT, 3); }
-LG2{szf}{cc}{sat}  { return_opcode(             1, SCALAR_OP, LG2, 3); }
-LOG                { return_opcode(require_ARB_vp, SCALAR_OP, LOG, 3); }
-LRP{sz}{cc}{sat}   { return_opcode(require_ARB_fp, TRI_OP, LRP, 3); }
-
-MAD{sz}{cc}{sat}   { return_opcode(             1, TRI_OP, MAD, 3); }
-MAX{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, MAX, 3); }
-MIN{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, MIN, 3); }
-MOV{sz}{cc}{sat}   { return_opcode(             1, VECTOR_OP, MOV, 3); }
-MUL{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, MUL, 3); }
-
-PK2H               { return_opcode(require_NV_fp,  VECTOR_OP, PK2H, 4); }
-PK2US              { return_opcode(require_NV_fp,  VECTOR_OP, PK2US, 5); }
-PK4B               { return_opcode(require_NV_fp,  VECTOR_OP, PK4B, 4); }
-PK4UB              { return_opcode(require_NV_fp,  VECTOR_OP, PK4UB, 5); }
-POW{szf}{cc}{sat}  { return_opcode(             1, BINSC_OP, POW, 3); }
-
-RCP{szf}{cc}{sat}  { return_opcode(             1, SCALAR_OP, RCP, 3); }
-RFL{szf}{cc}{sat}  { return_opcode(require_NV_fp,  BIN_OP,    RFL, 3); }
-RSQ{szf}{cc}{sat}  { return_opcode(             1, SCALAR_OP, RSQ, 3); }
-
-SCS{sat}           { return_opcode(require_ARB_fp, SCALAR_OP, SCS, 3); }
-SEQ{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SEQ, 3); }
-SFL{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SFL, 3); }
-SGE{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, SGE, 3); }
-SGT{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SGT, 3); }
-SIN{szf}{cc}{sat}  { return_opcode(require_ARB_fp, SCALAR_OP, SIN, 3); }
-SLE{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SLE, 3); }
-SLT{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, SLT, 3); }
-SNE{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, SNE, 3); }
-STR{sz}{cc}{sat}   { return_opcode(require_NV_fp,  BIN_OP, STR, 3); }
-SUB{sz}{cc}{sat}   { return_opcode(             1, BIN_OP, SUB, 3); }
-SWZ{sat}           { return_opcode(             1, SWZ, SWZ, 3); }
-
-TEX{cc}{sat}       { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, 3); }
-TXB{cc}{sat}       { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, 3); }
-TXD{cc}{sat}       { return_opcode(require_NV_fp,  TXD_OP, TXD, 3); }
-TXP{cc}{sat}       { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, 3); }
-
-UP2H{cc}{sat}      { return_opcode(require_NV_fp,  SCALAR_OP, UP2H, 4); }
-UP2US{cc}{sat}     { return_opcode(require_NV_fp,  SCALAR_OP, UP2US, 5); }
-UP4B{cc}{sat}      { return_opcode(require_NV_fp,  SCALAR_OP, UP4B, 4); }
-UP4UB{cc}{sat}     { return_opcode(require_NV_fp,  SCALAR_OP, UP4UB, 5); }
-
-X2D{szf}{cc}{sat}  { return_opcode(require_NV_fp,  TRI_OP, X2D, 3); }
-XPD{sat}           { return_opcode(             1, BIN_OP, XPD, 3); }
-
-vertex                    { return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); }
-fragment                  { return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); }
-program                   { return PROGRAM; }
-state                     { return STATE; }
-result                    { return RESULT; }
-
-{dot}ambient              { return AMBIENT; }
-{dot}attenuation          { return ATTENUATION; }
-{dot}back                 { return BACK; }
-{dot}clip                 { return_token_or_DOT(require_ARB_vp, CLIP); }
-{dot}color                { return COLOR; }
-{dot}depth                { return_token_or_DOT(require_ARB_fp, DEPTH); }
-{dot}diffuse              { return DIFFUSE; }
-{dot}direction            { return DIRECTION; }
-{dot}emission             { return EMISSION; }
-{dot}env                  { return ENV; }
-{dot}eye                  { return EYE; }
-{dot}fogcoord             { return FOGCOORD; }
-{dot}fog                  { return FOG; }
-{dot}front                { return FRONT; }
-{dot}half                 { return HALF; }
-{dot}inverse              { return INVERSE; }
-{dot}invtrans             { return INVTRANS; }
-{dot}light                { return LIGHT; }
-{dot}lightmodel           { return LIGHTMODEL; }
-{dot}lightprod            { return LIGHTPROD; }
-{dot}local                { return LOCAL; }
-{dot}material             { return MATERIAL; }
-{dot}program              { return MAT_PROGRAM; }
-{dot}matrix               { return MATRIX; }
-{dot}matrixindex          { return_token_or_DOT(require_ARB_vp, MATRIXINDEX); }
-{dot}modelview            { return MODELVIEW; }
-{dot}mvp                  { return MVP; }
-{dot}normal               { return_token_or_DOT(require_ARB_vp, NORMAL); }
-{dot}object               { return OBJECT; }
-{dot}palette              { return PALETTE; }
-{dot}params               { return PARAMS; }
-{dot}plane                { return PLANE; }
-{dot}point                { return_token_or_DOT(require_ARB_vp, POINT_TOK); }
-{dot}pointsize            { return_token_or_DOT(require_ARB_vp, POINTSIZE); }
-{dot}position             { return POSITION; }
-{dot}primary              { return PRIMARY; }
-{dot}projection           { return PROJECTION; }
-{dot}range                { return_token_or_DOT(require_ARB_fp, RANGE); }
-{dot}row                  { return ROW; }
-{dot}scenecolor           { return SCENECOLOR; }
-{dot}secondary            { return SECONDARY; }
-{dot}shininess            { return SHININESS; }
-{dot}size                 { return_token_or_DOT(require_ARB_vp, SIZE_TOK); }
-{dot}specular             { return SPECULAR; }
-{dot}spot                 { return SPOT; }
-{dot}texcoord             { return TEXCOORD; }
-{dot}texenv               { return_token_or_DOT(require_ARB_fp, TEXENV); }
-{dot}texgen               { return_token_or_DOT(require_ARB_vp, TEXGEN); }
-{dot}q                    { return_token_or_DOT(require_ARB_vp, TEXGEN_Q); }
-{dot}s                    { return_token_or_DOT(require_ARB_vp, TEXGEN_S); }
-{dot}t                    { return_token_or_DOT(require_ARB_vp, TEXGEN_T); }
-{dot}texture              { return TEXTURE; }
-{dot}transpose            { return TRANSPOSE; }
-{dot}attrib               { return_token_or_DOT(require_ARB_vp, VTXATTRIB); }
-{dot}weight               { return_token_or_DOT(require_ARB_vp, WEIGHT); }
-
-texture                   { return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); }
-1D                        { return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); }
-2D                        { return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); }
-3D                        { return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); }
-CUBE                      { return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); }
-RECT                      { return_token_or_IDENTIFIER(require_ARB_fp && require_rect, TEX_RECT); }
-SHADOW1D                  { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW1D); }
-SHADOW2D                  { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW2D); }
-SHADOWRECT                { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_rect, TEX_SHADOWRECT); }
-ARRAY1D                   { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY1D); }
-ARRAY2D                   { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY2D); }
-ARRAYSHADOW1D             { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW1D); }
-ARRAYSHADOW2D             { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); }
-
-[_a-zA-Z$][_a-zA-Z0-9$]*  { return handle_ident(yyextra, yytext, yylval); }
-
-".."                      { return DOT_DOT; }
-
-{num}                     {
-   yylval->integer = strtol(yytext, NULL, 10);
-   return INTEGER;
-}
-{num}?{frac}{exp}?        {
-   yylval->real = _mesa_strtof(yytext, NULL);
-   return REAL;
-}
-{num}"."/[^.]             {
-   yylval->real = _mesa_strtof(yytext, NULL);
-   return REAL;
-}
-{num}{exp}                {
-   yylval->real = _mesa_strtof(yytext, NULL);
-   return REAL;
-}
-{num}"."{exp}             {
-   yylval->real = _mesa_strtof(yytext, NULL);
-   return REAL;
-}
-
-".xyzw"                   {
-   yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
-   yylval->swiz_mask.mask = WRITEMASK_XYZW;
-   return MASK4;
-}
-
-".xy"[zw]                 {
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_XY
-      | mask_from_char(yytext[3]);
-   return MASK3;
-}
-".xzw"                    {
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_XZW;
-   return MASK3;
-}
-".yzw"                    {
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_YZW;
-   return MASK3;
-}
-
-".x"[yzw]                 {
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_X
-      | mask_from_char(yytext[2]);
-   return MASK2;
-}
-".y"[zw]                  {
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_Y
-      | mask_from_char(yytext[2]);
-   return MASK2;
-}
-".zw"                     {
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_ZW;
-   return MASK2;
-}
-
-"."[xyzw]                 {
-   const unsigned s = swiz_from_char(yytext[1]);
-   yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
-   yylval->swiz_mask.mask = mask_from_char(yytext[1]);
-   return MASK1; 
-}
-
-"."[xyzw]{4}              {
-   yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
-                                           swiz_from_char(yytext[2]),
-                                           swiz_from_char(yytext[3]),
-                                           swiz_from_char(yytext[4]));
-   yylval->swiz_mask.mask = 0;
-   return SWIZZLE;
-}
-
-".rgba"                   {
-   yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
-   yylval->swiz_mask.mask = WRITEMASK_XYZW;
-   return_token_or_DOT(require_ARB_fp, MASK4);
-}
-
-".rg"[ba]                 {
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_XY
-      | mask_from_char(yytext[3]);
-   return_token_or_DOT(require_ARB_fp, MASK3);
-}
-".rba"                    {
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_XZW;
-   return_token_or_DOT(require_ARB_fp, MASK3);
-}
-".gba"                    {
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_YZW;
-   return_token_or_DOT(require_ARB_fp, MASK3);
-}
-
-".r"[gba]                 {
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_X
-      | mask_from_char(yytext[2]);
-   return_token_or_DOT(require_ARB_fp, MASK2);
-}
-".g"[ba]                  {
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_Y
-      | mask_from_char(yytext[2]);
-   return_token_or_DOT(require_ARB_fp, MASK2);
-}
-".ba"                     {
-   yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
-   yylval->swiz_mask.mask = WRITEMASK_ZW;
-   return_token_or_DOT(require_ARB_fp, MASK2);
-}
-
-"."[gba]                  {
-   const unsigned s = swiz_from_char(yytext[1]);
-   yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
-   yylval->swiz_mask.mask = mask_from_char(yytext[1]);
-   return_token_or_DOT(require_ARB_fp, MASK1);
-}
-
-
-".r"                      {
-   if (require_ARB_vp) {
-      return TEXGEN_R;
-   } else {
-      yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X,
-                                               SWIZZLE_X, SWIZZLE_X);
-      yylval->swiz_mask.mask = WRITEMASK_X;
-      return MASK1;
-   }
-}
-
-"."[rgba]{4}              {
-   yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
-                                           swiz_from_char(yytext[2]),
-                                           swiz_from_char(yytext[3]),
-                                           swiz_from_char(yytext[4]));
-   yylval->swiz_mask.mask = 0;
-   return_token_or_DOT(require_ARB_fp, SWIZZLE);
-}
-
-"."                       { return DOT; }
-
-\n                        {
-   yylloc->first_line++;
-   yylloc->first_column = 1;
-   yylloc->last_line++;
-   yylloc->last_column = 1;
-   yylloc->position++;
-}
-[ \t\r]+                  /* eat whitespace */ ;
-#.*$                      /* eat comments */ ;
-.                         { return yytext[0]; }
-%%
-
-void
-_mesa_program_lexer_ctor(void **scanner, struct asm_parser_state *state,
-                        const char *string, size_t len)
-{
-   yylex_init_extra(state, scanner);
-   yy_scan_bytes(string, len, *scanner);
-}
-
-void
-_mesa_program_lexer_dtor(void *scanner)
-{
-   yylex_destroy(scanner);
-}
diff --git a/src/mesa/shader/program_parse.tab.c b/src/mesa/shader/program_parse.tab.c
deleted file mode 100644 (file)
index 7da7226..0000000
+++ /dev/null
@@ -1,5729 +0,0 @@
-
-/* A Bison parser, made by GNU Bison 2.4.1.  */
-
-/* Skeleton implementation for Bison's Yacc-like parsers in C
-   
-      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, Inc.
-   
-   This program is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-/* As a special exception, you may create a larger work that contains
-   part or all of the Bison parser skeleton and distribute that work
-   under terms of your choice, so long as that work isn't itself a
-   parser generator using the skeleton or a modified version thereof
-   as a parser skeleton.  Alternatively, if you modify or redistribute
-   the parser skeleton itself, you may (at your option) remove this
-   special exception, which will cause the skeleton and the resulting
-   Bison output files to be licensed under the GNU General Public
-   License without this special exception.
-   
-   This special exception was added by the Free Software Foundation in
-   version 2.2 of Bison.  */
-
-/* C LALR(1) parser skeleton written by Richard Stallman, by
-   simplifying the original so-called "semantic" parser.  */
-
-/* All symbols defined below should begin with yy or YY, to avoid
-   infringing on user name space.  This should be done even for local
-   variables, as they might otherwise be expanded by user macros.
-   There are some unavoidable exceptions within include files to
-   define necessary library symbols; they are noted "INFRINGES ON
-   USER NAME SPACE" below.  */
-
-/* Identify Bison output.  */
-#define YYBISON 1
-
-/* Bison version.  */
-#define YYBISON_VERSION "2.4.1"
-
-/* Skeleton name.  */
-#define YYSKELETON_NAME "yacc.c"
-
-/* Pure parsers.  */
-#define YYPURE 1
-
-/* Push parsers.  */
-#define YYPUSH 0
-
-/* Pull parsers.  */
-#define YYPULL 1
-
-/* Using locations.  */
-#define YYLSP_NEEDED 1
-
-
-
-/* Copy the first part of user declarations.  */
-
-/* Line 189 of yacc.c  */
-#line 1 "program_parse.y"
-
-/*
- * Copyright Â© 2009 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "main/mtypes.h"
-#include "main/imports.h"
-#include "shader/program.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_parameter_layout.h"
-#include "shader/prog_statevars.h"
-#include "shader/prog_instruction.h"
-
-#include "shader/symbol_table.h"
-#include "shader/program_parser.h"
-
-extern void *yy_scan_string(char *);
-extern void yy_delete_buffer(void *);
-
-static struct asm_symbol *declare_variable(struct asm_parser_state *state,
-    char *name, enum asm_type t, struct YYLTYPE *locp);
-
-static int add_state_reference(struct gl_program_parameter_list *param_list,
-    const gl_state_index tokens[STATE_LENGTH]);
-
-static int initialize_symbol_from_state(struct gl_program *prog,
-    struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
-
-static int initialize_symbol_from_param(struct gl_program *prog,
-    struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
-
-static int initialize_symbol_from_const(struct gl_program *prog,
-    struct asm_symbol *param_var, const struct asm_vector *vec,
-    GLboolean allowSwizzle);
-
-static int yyparse(struct asm_parser_state *state);
-
-static char *make_error_string(const char *fmt, ...);
-
-static void yyerror(struct YYLTYPE *locp, struct asm_parser_state *state,
-    const char *s);
-
-static int validate_inputs(struct YYLTYPE *locp,
-    struct asm_parser_state *state);
-
-static void init_dst_reg(struct prog_dst_register *r);
-
-static void set_dst_reg(struct prog_dst_register *r,
-                        gl_register_file file, GLint index);
-
-static void init_src_reg(struct asm_src_register *r);
-
-static void set_src_reg(struct asm_src_register *r,
-                        gl_register_file file, GLint index);
-
-static void set_src_reg_swz(struct asm_src_register *r,
-                            gl_register_file file, GLint index, GLuint swizzle);
-
-static void asm_instruction_set_operands(struct asm_instruction *inst,
-    const struct prog_dst_register *dst, const struct asm_src_register *src0,
-    const struct asm_src_register *src1, const struct asm_src_register *src2);
-
-static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op,
-    const struct prog_dst_register *dst, const struct asm_src_register *src0,
-    const struct asm_src_register *src1, const struct asm_src_register *src2);
-
-static struct asm_instruction *asm_instruction_copy_ctor(
-    const struct prog_instruction *base, const struct prog_dst_register *dst,
-    const struct asm_src_register *src0, const struct asm_src_register *src1,
-    const struct asm_src_register *src2);
-
-#ifndef FALSE
-#define FALSE 0
-#define TRUE (!FALSE)
-#endif
-
-#define YYLLOC_DEFAULT(Current, Rhs, N)                                        \
-   do {                                                                        \
-      if (YYID(N)) {                                                   \
-        (Current).first_line = YYRHSLOC(Rhs, 1).first_line;            \
-        (Current).first_column = YYRHSLOC(Rhs, 1).first_column;        \
-        (Current).position = YYRHSLOC(Rhs, 1).position;                \
-        (Current).last_line = YYRHSLOC(Rhs, N).last_line;              \
-        (Current).last_column = YYRHSLOC(Rhs, N).last_column;          \
-      } else {                                                         \
-        (Current).first_line = YYRHSLOC(Rhs, 0).last_line;             \
-        (Current).last_line = (Current).first_line;                    \
-        (Current).first_column = YYRHSLOC(Rhs, 0).last_column;         \
-        (Current).last_column = (Current).first_column;                \
-        (Current).position = YYRHSLOC(Rhs, 0).position                 \
-           + (Current).first_column;                                   \
-      }                                                                        \
-   } while(YYID(0))
-
-#define YYLEX_PARAM state->scanner
-
-
-/* Line 189 of yacc.c  */
-#line 193 "program_parse.tab.c"
-
-/* Enabling traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-
-/* Enabling verbose error messages.  */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 1
-#endif
-
-/* Enabling the token table.  */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
-#endif
-
-
-/* Tokens.  */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
-   /* Put the tokens into the symbol table, so that GDB and other debuggers
-      know about them.  */
-   enum yytokentype {
-     ARBvp_10 = 258,
-     ARBfp_10 = 259,
-     ADDRESS = 260,
-     ALIAS = 261,
-     ATTRIB = 262,
-     OPTION = 263,
-     OUTPUT = 264,
-     PARAM = 265,
-     TEMP = 266,
-     END = 267,
-     BIN_OP = 268,
-     BINSC_OP = 269,
-     SAMPLE_OP = 270,
-     SCALAR_OP = 271,
-     TRI_OP = 272,
-     VECTOR_OP = 273,
-     ARL = 274,
-     KIL = 275,
-     SWZ = 276,
-     TXD_OP = 277,
-     INTEGER = 278,
-     REAL = 279,
-     AMBIENT = 280,
-     ATTENUATION = 281,
-     BACK = 282,
-     CLIP = 283,
-     COLOR = 284,
-     DEPTH = 285,
-     DIFFUSE = 286,
-     DIRECTION = 287,
-     EMISSION = 288,
-     ENV = 289,
-     EYE = 290,
-     FOG = 291,
-     FOGCOORD = 292,
-     FRAGMENT = 293,
-     FRONT = 294,
-     HALF = 295,
-     INVERSE = 296,
-     INVTRANS = 297,
-     LIGHT = 298,
-     LIGHTMODEL = 299,
-     LIGHTPROD = 300,
-     LOCAL = 301,
-     MATERIAL = 302,
-     MAT_PROGRAM = 303,
-     MATRIX = 304,
-     MATRIXINDEX = 305,
-     MODELVIEW = 306,
-     MVP = 307,
-     NORMAL = 308,
-     OBJECT = 309,
-     PALETTE = 310,
-     PARAMS = 311,
-     PLANE = 312,
-     POINT_TOK = 313,
-     POINTSIZE = 314,
-     POSITION = 315,
-     PRIMARY = 316,
-     PROGRAM = 317,
-     PROJECTION = 318,
-     RANGE = 319,
-     RESULT = 320,
-     ROW = 321,
-     SCENECOLOR = 322,
-     SECONDARY = 323,
-     SHININESS = 324,
-     SIZE_TOK = 325,
-     SPECULAR = 326,
-     SPOT = 327,
-     STATE = 328,
-     TEXCOORD = 329,
-     TEXENV = 330,
-     TEXGEN = 331,
-     TEXGEN_Q = 332,
-     TEXGEN_R = 333,
-     TEXGEN_S = 334,
-     TEXGEN_T = 335,
-     TEXTURE = 336,
-     TRANSPOSE = 337,
-     TEXTURE_UNIT = 338,
-     TEX_1D = 339,
-     TEX_2D = 340,
-     TEX_3D = 341,
-     TEX_CUBE = 342,
-     TEX_RECT = 343,
-     TEX_SHADOW1D = 344,
-     TEX_SHADOW2D = 345,
-     TEX_SHADOWRECT = 346,
-     TEX_ARRAY1D = 347,
-     TEX_ARRAY2D = 348,
-     TEX_ARRAYSHADOW1D = 349,
-     TEX_ARRAYSHADOW2D = 350,
-     VERTEX = 351,
-     VTXATTRIB = 352,
-     WEIGHT = 353,
-     IDENTIFIER = 354,
-     USED_IDENTIFIER = 355,
-     MASK4 = 356,
-     MASK3 = 357,
-     MASK2 = 358,
-     MASK1 = 359,
-     SWIZZLE = 360,
-     DOT_DOT = 361,
-     DOT = 362
-   };
-#endif
-
-
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-{
-
-/* Line 214 of yacc.c  */
-#line 126 "program_parse.y"
-
-   struct asm_instruction *inst;
-   struct asm_symbol *sym;
-   struct asm_symbol temp_sym;
-   struct asm_swizzle_mask swiz_mask;
-   struct asm_src_register src_reg;
-   struct prog_dst_register dst_reg;
-   struct prog_instruction temp_inst;
-   char *string;
-   unsigned result;
-   unsigned attrib;
-   int integer;
-   float real;
-   gl_state_index state[STATE_LENGTH];
-   int negate;
-   struct asm_vector vector;
-   gl_inst_opcode opcode;
-
-   struct {
-      unsigned swz;
-      unsigned rgba_valid:1;
-      unsigned xyzw_valid:1;
-      unsigned negate:1;
-   } ext_swizzle;
-
-
-
-/* Line 214 of yacc.c  */
-#line 364 "program_parse.tab.c"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-#endif
-
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE
-{
-  int first_line;
-  int first_column;
-  int last_line;
-  int last_column;
-} YYLTYPE;
-# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-#endif
-
-
-/* Copy the second part of user declarations.  */
-
-/* Line 264 of yacc.c  */
-#line 271 "program_parse.y"
-
-extern int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
-    void *yyscanner);
-
-
-/* Line 264 of yacc.c  */
-#line 395 "program_parse.tab.c"
-
-#ifdef short
-# undef short
-#endif
-
-#ifdef YYTYPE_UINT8
-typedef YYTYPE_UINT8 yytype_uint8;
-#else
-typedef unsigned char yytype_uint8;
-#endif
-
-#ifdef YYTYPE_INT8
-typedef YYTYPE_INT8 yytype_int8;
-#elif (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-typedef signed char yytype_int8;
-#else
-typedef short int yytype_int8;
-#endif
-
-#ifdef YYTYPE_UINT16
-typedef YYTYPE_UINT16 yytype_uint16;
-#else
-typedef unsigned short int yytype_uint16;
-#endif
-
-#ifdef YYTYPE_INT16
-typedef YYTYPE_INT16 yytype_int16;
-#else
-typedef short int yytype_int16;
-#endif
-
-#ifndef YYSIZE_T
-# ifdef __SIZE_TYPE__
-#  define YYSIZE_T __SIZE_TYPE__
-# elif defined size_t
-#  define YYSIZE_T size_t
-# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYSIZE_T size_t
-# else
-#  define YYSIZE_T unsigned int
-# endif
-#endif
-
-#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
-
-#ifndef YY_
-# if YYENABLE_NLS
-#  if ENABLE_NLS
-#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-#   define YY_(msgid) dgettext ("bison-runtime", msgid)
-#  endif
-# endif
-# ifndef YY_
-#  define YY_(msgid) msgid
-# endif
-#endif
-
-/* Suppress unused-variable warnings by "using" E.  */
-#if ! defined lint || defined __GNUC__
-# define YYUSE(e) ((void) (e))
-#else
-# define YYUSE(e) /* empty */
-#endif
-
-/* Identity function, used to suppress warnings about constant conditions.  */
-#ifndef lint
-# define YYID(n) (n)
-#else
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static int
-YYID (int yyi)
-#else
-static int
-YYID (yyi)
-    int yyi;
-#endif
-{
-  return yyi;
-}
-#endif
-
-#if ! defined yyoverflow || YYERROR_VERBOSE
-
-/* The parser invokes alloca or malloc; define the necessary symbols.  */
-
-# ifdef YYSTACK_USE_ALLOCA
-#  if YYSTACK_USE_ALLOCA
-#   ifdef __GNUC__
-#    define YYSTACK_ALLOC __builtin_alloca
-#   elif defined __BUILTIN_VA_ARG_INCR
-#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
-#   elif defined _AIX
-#    define YYSTACK_ALLOC __alloca
-#   elif defined _MSC_VER
-#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
-#    define alloca _alloca
-#   else
-#    define YYSTACK_ALLOC alloca
-#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#     ifndef _STDLIB_H
-#      define _STDLIB_H 1
-#     endif
-#    endif
-#   endif
-#  endif
-# endif
-
-# ifdef YYSTACK_ALLOC
-   /* Pacify GCC's `empty if-body' warning.  */
-#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
-#  ifndef YYSTACK_ALLOC_MAXIMUM
-    /* The OS might guarantee only one guard page at the bottom of the stack,
-       and a page size can be as small as 4096 bytes.  So we cannot safely
-       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
-       to allow for a few compiler-allocated temporary stack slots.  */
-#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
-#  endif
-# else
-#  define YYSTACK_ALLOC YYMALLOC
-#  define YYSTACK_FREE YYFREE
-#  ifndef YYSTACK_ALLOC_MAXIMUM
-#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
-#  endif
-#  if (defined __cplusplus && ! defined _STDLIB_H \
-       && ! ((defined YYMALLOC || defined malloc) \
-            && (defined YYFREE || defined free)))
-#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef _STDLIB_H
-#    define _STDLIB_H 1
-#   endif
-#  endif
-#  ifndef YYMALLOC
-#   define YYMALLOC malloc
-#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
-#   endif
-#  endif
-#  ifndef YYFREE
-#   define YYFREE free
-#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-void free (void *); /* INFRINGES ON USER NAME SPACE */
-#   endif
-#  endif
-# endif
-#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
-
-
-#if (! defined yyoverflow \
-     && (! defined __cplusplus \
-        || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
-            && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
-
-/* A type that is properly aligned for any stack member.  */
-union yyalloc
-{
-  yytype_int16 yyss_alloc;
-  YYSTYPE yyvs_alloc;
-  YYLTYPE yyls_alloc;
-};
-
-/* The size of the maximum gap between one aligned stack and the next.  */
-# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
-
-/* The size of an array large to enough to hold all stacks, each with
-   N elements.  */
-# define YYSTACK_BYTES(N) \
-     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
-      + 2 * YYSTACK_GAP_MAXIMUM)
-
-/* Copy COUNT objects from FROM to TO.  The source and destination do
-   not overlap.  */
-# ifndef YYCOPY
-#  if defined __GNUC__ && 1 < __GNUC__
-#   define YYCOPY(To, From, Count) \
-      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-#  else
-#   define YYCOPY(To, From, Count)             \
-      do                                       \
-       {                                       \
-         YYSIZE_T yyi;                         \
-         for (yyi = 0; yyi < (Count); yyi++)   \
-           (To)[yyi] = (From)[yyi];            \
-       }                                       \
-      while (YYID (0))
-#  endif
-# endif
-
-/* Relocate STACK from its old location to the new one.  The
-   local variables YYSIZE and YYSTACKSIZE give the old and new number of
-   elements in the stack, and YYPTR gives the new location of the
-   stack.  Advance YYPTR to a properly aligned location for the next
-   stack.  */
-# define YYSTACK_RELOCATE(Stack_alloc, Stack)                          \
-    do                                                                 \
-      {                                                                        \
-       YYSIZE_T yynewbytes;                                            \
-       YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
-       Stack = &yyptr->Stack_alloc;                                    \
-       yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
-       yyptr += yynewbytes / sizeof (*yyptr);                          \
-      }                                                                        \
-    while (YYID (0))
-
-#endif
-
-/* YYFINAL -- State number of the termination state.  */
-#define YYFINAL  5
-/* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   396
-
-/* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  120
-/* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  143
-/* YYNRULES -- Number of rules.  */
-#define YYNRULES  282
-/* YYNRULES -- Number of states.  */
-#define YYNSTATES  475
-
-/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
-#define YYUNDEFTOK  2
-#define YYMAXUTOK   362
-
-#define YYTRANSLATE(YYX)                                               \
-  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
-
-/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
-static const yytype_uint8 yytranslate[] =
-{
-       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     115,   116,     2,   113,   109,   114,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,   108,
-       2,   117,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,   111,     2,   112,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,   118,   110,   119,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
-       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
-      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
-      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
-      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
-      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
-      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
-      65,    66,    67,    68,    69,    70,    71,    72,    73,    74,
-      75,    76,    77,    78,    79,    80,    81,    82,    83,    84,
-      85,    86,    87,    88,    89,    90,    91,    92,    93,    94,
-      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
-     105,   106,   107
-};
-
-#if YYDEBUG
-/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
-   YYRHS.  */
-static const yytype_uint16 yyprhs[] =
-{
-       0,     0,     3,     8,    10,    12,    15,    16,    20,    23,
-      24,    27,    30,    32,    34,    36,    38,    40,    42,    44,
-      46,    48,    50,    52,    54,    59,    64,    69,    76,    83,
-      92,   101,   104,   107,   120,   123,   125,   127,   129,   131,
-     133,   135,   137,   139,   141,   143,   145,   147,   154,   157,
-     162,   165,   167,   171,   177,   181,   184,   192,   195,   197,
-     199,   201,   203,   208,   210,   212,   214,   216,   218,   220,
-     222,   226,   227,   230,   233,   235,   237,   239,   241,   243,
-     245,   247,   249,   251,   252,   254,   256,   258,   260,   261,
-     265,   269,   270,   273,   276,   278,   280,   282,   284,   286,
-     288,   290,   292,   297,   300,   303,   305,   308,   310,   313,
-     315,   318,   323,   328,   330,   331,   335,   337,   339,   342,
-     344,   347,   349,   351,   355,   362,   363,   365,   368,   373,
-     375,   379,   381,   383,   385,   387,   389,   391,   393,   395,
-     397,   399,   402,   405,   408,   411,   414,   417,   420,   423,
-     426,   429,   432,   435,   439,   441,   443,   445,   451,   453,
-     455,   457,   460,   462,   464,   467,   469,   472,   479,   481,
-     485,   487,   489,   491,   493,   495,   500,   502,   504,   506,
-     508,   510,   512,   515,   517,   519,   525,   527,   530,   532,
-     534,   540,   543,   544,   551,   555,   556,   558,   560,   562,
-     564,   566,   569,   571,   573,   576,   581,   586,   587,   591,
-     593,   595,   597,   600,   602,   604,   606,   608,   614,   616,
-     620,   626,   632,   634,   638,   644,   646,   648,   650,   652,
-     654,   656,   658,   660,   662,   666,   672,   680,   690,   693,
-     696,   698,   700,   701,   702,   707,   709,   710,   711,   715,
-     719,   721,   727,   730,   733,   736,   739,   743,   746,   750,
-     751,   753,   755,   756,   758,   760,   761,   763,   765,   766,
-     768,   770,   771,   775,   776,   780,   781,   785,   787,   789,
-     791,   796,   798
-};
-
-/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
-static const yytype_int16 yyrhs[] =
-{
-     121,     0,    -1,   122,   123,   125,    12,    -1,     3,    -1,
-       4,    -1,   123,   124,    -1,    -1,     8,   262,   108,    -1,
-     125,   126,    -1,    -1,   127,   108,    -1,   170,   108,    -1,
-     128,    -1,   129,    -1,   130,    -1,   131,    -1,   132,    -1,
-     133,    -1,   134,    -1,   135,    -1,   141,    -1,   136,    -1,
-     137,    -1,   138,    -1,    19,   146,   109,   142,    -1,    18,
-     145,   109,   144,    -1,    16,   145,   109,   142,    -1,    14,
-     145,   109,   142,   109,   142,    -1,    13,   145,   109,   144,
-     109,   144,    -1,    17,   145,   109,   144,   109,   144,   109,
-     144,    -1,    15,   145,   109,   144,   109,   139,   109,   140,
-      -1,    20,   144,    -1,    20,   166,    -1,    22,   145,   109,
-     144,   109,   144,   109,   144,   109,   139,   109,   140,    -1,
-      83,   256,    -1,    84,    -1,    85,    -1,    86,    -1,    87,
-      -1,    88,    -1,    89,    -1,    90,    -1,    91,    -1,    92,
-      -1,    93,    -1,    94,    -1,    95,    -1,    21,   145,   109,
-     150,   109,   147,    -1,   241,   143,    -1,   241,   110,   143,
-     110,    -1,   150,   162,    -1,   238,    -1,   241,   150,   163,
-      -1,   241,   110,   150,   163,   110,    -1,   151,   164,   165,
-      -1,   159,   161,    -1,   148,   109,   148,   109,   148,   109,
-     148,    -1,   241,   149,    -1,    23,    -1,   262,    -1,   100,
-      -1,   172,    -1,   152,   111,   153,   112,    -1,   186,    -1,
-     249,    -1,   100,    -1,   100,    -1,   154,    -1,   155,    -1,
-      23,    -1,   159,   160,   156,    -1,    -1,   113,   157,    -1,
-     114,   158,    -1,    23,    -1,    23,    -1,   100,    -1,   104,
-      -1,   104,    -1,   104,    -1,   104,    -1,   101,    -1,   105,
-      -1,    -1,   101,    -1,   102,    -1,   103,    -1,   104,    -1,
-      -1,   115,   166,   116,    -1,   115,   167,   116,    -1,    -1,
-     168,   163,    -1,   169,   163,    -1,    99,    -1,   100,    -1,
-     171,    -1,   178,    -1,   242,    -1,   245,    -1,   248,    -1,
-     261,    -1,     7,    99,   117,   172,    -1,    96,   173,    -1,
-      38,   177,    -1,    60,    -1,    98,   175,    -1,    53,    -1,
-      29,   254,    -1,    37,    -1,    74,   255,    -1,    50,   111,
-     176,   112,    -1,    97,   111,   174,   112,    -1,    23,    -1,
-      -1,   111,   176,   112,    -1,    23,    -1,    60,    -1,    29,
-     254,    -1,    37,    -1,    74,   255,    -1,   179,    -1,   180,
-      -1,    10,    99,   182,    -1,    10,    99,   111,   181,   112,
-     183,    -1,    -1,    23,    -1,   117,   185,    -1,   117,   118,
-     184,   119,    -1,   187,    -1,   184,   109,   187,    -1,   189,
-      -1,   225,    -1,   235,    -1,   189,    -1,   225,    -1,   236,
-      -1,   188,    -1,   226,    -1,   235,    -1,   189,    -1,    73,
-     213,    -1,    73,   190,    -1,    73,   192,    -1,    73,   195,
-      -1,    73,   197,    -1,    73,   203,    -1,    73,   199,    -1,
-      73,   206,    -1,    73,   208,    -1,    73,   210,    -1,    73,
-     212,    -1,    73,   224,    -1,    47,   253,   191,    -1,   201,
-      -1,    33,    -1,    69,    -1,    43,   111,   202,   112,   193,
-      -1,   201,    -1,    60,    -1,    26,    -1,    72,   194,    -1,
-      40,    -1,    32,    -1,    44,   196,    -1,    25,    -1,   253,
-      67,    -1,    45,   111,   202,   112,   253,   198,    -1,   201,
-      -1,    75,   257,   200,    -1,    29,    -1,    25,    -1,    31,
-      -1,    71,    -1,    23,    -1,    76,   255,   204,   205,    -1,
-      35,    -1,    54,    -1,    79,    -1,    80,    -1,    78,    -1,
-      77,    -1,    36,   207,    -1,    29,    -1,    56,    -1,    28,
-     111,   209,   112,    57,    -1,    23,    -1,    58,   211,    -1,
-      70,    -1,    26,    -1,   215,    66,   111,   218,   112,    -1,
-     215,   214,    -1,    -1,    66,   111,   218,   106,   218,   112,
-      -1,    49,   219,   216,    -1,    -1,   217,    -1,    41,    -1,
-      82,    -1,    42,    -1,    23,    -1,    51,   220,    -1,    63,
-      -1,    52,    -1,    81,   255,    -1,    55,   111,   222,   112,
-      -1,    48,   111,   223,   112,    -1,    -1,   111,   221,   112,
-      -1,    23,    -1,    23,    -1,    23,    -1,    30,    64,    -1,
-     229,    -1,   232,    -1,   227,    -1,   230,    -1,    62,    34,
-     111,   228,   112,    -1,   233,    -1,   233,   106,   233,    -1,
-      62,    34,   111,   233,   112,    -1,    62,    46,   111,   231,
-     112,    -1,   234,    -1,   234,   106,   234,    -1,    62,    46,
-     111,   234,   112,    -1,    23,    -1,    23,    -1,   237,    -1,
-     239,    -1,   238,    -1,   239,    -1,   240,    -1,    24,    -1,
-      23,    -1,   118,   240,   119,    -1,   118,   240,   109,   240,
-     119,    -1,   118,   240,   109,   240,   109,   240,   119,    -1,
-     118,   240,   109,   240,   109,   240,   109,   240,   119,    -1,
-     241,    24,    -1,   241,    23,    -1,   113,    -1,   114,    -1,
-      -1,    -1,   244,    11,   243,   247,    -1,   262,    -1,    -1,
-      -1,     5,   246,   247,    -1,   247,   109,    99,    -1,    99,
-      -1,   244,     9,    99,   117,   249,    -1,    65,    60,    -1,
-      65,    37,    -1,    65,   250,    -1,    65,    59,    -1,    65,
-      74,   255,    -1,    65,    30,    -1,    29,   251,   252,    -1,
-      -1,    39,    -1,    27,    -1,    -1,    61,    -1,    68,    -1,
-      -1,    39,    -1,    27,    -1,    -1,    61,    -1,    68,    -1,
-      -1,   111,   258,   112,    -1,    -1,   111,   259,   112,    -1,
-      -1,   111,   260,   112,    -1,    23,    -1,    23,    -1,    23,
-      -1,     6,    99,   117,   100,    -1,    99,    -1,   100,    -1
-};
-
-/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
-static const yytype_uint16 yyrline[] =
-{
-       0,   278,   278,   281,   289,   301,   302,   305,   329,   330,
-     333,   348,   351,   356,   363,   364,   365,   366,   367,   368,
-     369,   372,   373,   374,   377,   383,   389,   395,   402,   408,
-     415,   459,   464,   474,   518,   524,   525,   526,   527,   528,
-     529,   530,   531,   532,   533,   534,   535,   538,   550,   558,
-     575,   582,   601,   612,   632,   657,   664,   697,   704,   719,
-     774,   817,   826,   847,   857,   861,   890,   909,   909,   911,
-     918,   930,   931,   932,   935,   949,   963,   983,   994,  1006,
-    1008,  1009,  1010,  1011,  1014,  1014,  1014,  1014,  1015,  1018,
-    1022,  1027,  1034,  1041,  1048,  1071,  1094,  1095,  1096,  1097,
-    1098,  1099,  1102,  1121,  1125,  1131,  1135,  1139,  1143,  1152,
-    1161,  1165,  1170,  1176,  1187,  1187,  1188,  1190,  1194,  1198,
-    1202,  1208,  1208,  1210,  1228,  1254,  1257,  1268,  1274,  1280,
-    1281,  1288,  1294,  1300,  1308,  1314,  1320,  1328,  1334,  1340,
-    1348,  1349,  1352,  1353,  1354,  1355,  1356,  1357,  1358,  1359,
-    1360,  1361,  1362,  1365,  1374,  1378,  1382,  1388,  1397,  1401,
-    1405,  1414,  1418,  1424,  1430,  1437,  1442,  1450,  1460,  1462,
-    1470,  1476,  1480,  1484,  1490,  1501,  1510,  1514,  1519,  1523,
-    1527,  1531,  1537,  1544,  1548,  1554,  1562,  1573,  1580,  1584,
-    1590,  1600,  1611,  1615,  1633,  1642,  1645,  1651,  1655,  1659,
-    1665,  1676,  1681,  1686,  1691,  1696,  1701,  1709,  1712,  1717,
-    1730,  1738,  1749,  1757,  1757,  1759,  1759,  1761,  1771,  1776,
-    1783,  1793,  1802,  1807,  1814,  1824,  1834,  1846,  1846,  1847,
-    1847,  1849,  1859,  1867,  1877,  1885,  1893,  1902,  1913,  1917,
-    1923,  1924,  1925,  1928,  1928,  1931,  1966,  1970,  1970,  1973,
-    1980,  1989,  2003,  2012,  2021,  2025,  2034,  2043,  2054,  2061,
-    2066,  2075,  2087,  2090,  2099,  2110,  2111,  2112,  2115,  2116,
-    2117,  2120,  2121,  2124,  2125,  2128,  2129,  2132,  2143,  2154,
-    2165,  2191,  2192
-};
-#endif
-
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
-/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
-   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
-static const char *const yytname[] =
-{
-  "$end", "error", "$undefined", "ARBvp_10", "ARBfp_10", "ADDRESS",
-  "ALIAS", "ATTRIB", "OPTION", "OUTPUT", "PARAM", "TEMP", "END", "BIN_OP",
-  "BINSC_OP", "SAMPLE_OP", "SCALAR_OP", "TRI_OP", "VECTOR_OP", "ARL",
-  "KIL", "SWZ", "TXD_OP", "INTEGER", "REAL", "AMBIENT", "ATTENUATION",
-  "BACK", "CLIP", "COLOR", "DEPTH", "DIFFUSE", "DIRECTION", "EMISSION",
-  "ENV", "EYE", "FOG", "FOGCOORD", "FRAGMENT", "FRONT", "HALF", "INVERSE",
-  "INVTRANS", "LIGHT", "LIGHTMODEL", "LIGHTPROD", "LOCAL", "MATERIAL",
-  "MAT_PROGRAM", "MATRIX", "MATRIXINDEX", "MODELVIEW", "MVP", "NORMAL",
-  "OBJECT", "PALETTE", "PARAMS", "PLANE", "POINT_TOK", "POINTSIZE",
-  "POSITION", "PRIMARY", "PROGRAM", "PROJECTION", "RANGE", "RESULT", "ROW",
-  "SCENECOLOR", "SECONDARY", "SHININESS", "SIZE_TOK", "SPECULAR", "SPOT",
-  "STATE", "TEXCOORD", "TEXENV", "TEXGEN", "TEXGEN_Q", "TEXGEN_R",
-  "TEXGEN_S", "TEXGEN_T", "TEXTURE", "TRANSPOSE", "TEXTURE_UNIT", "TEX_1D",
-  "TEX_2D", "TEX_3D", "TEX_CUBE", "TEX_RECT", "TEX_SHADOW1D",
-  "TEX_SHADOW2D", "TEX_SHADOWRECT", "TEX_ARRAY1D", "TEX_ARRAY2D",
-  "TEX_ARRAYSHADOW1D", "TEX_ARRAYSHADOW2D", "VERTEX", "VTXATTRIB",
-  "WEIGHT", "IDENTIFIER", "USED_IDENTIFIER", "MASK4", "MASK3", "MASK2",
-  "MASK1", "SWIZZLE", "DOT_DOT", "DOT", "';'", "','", "'|'", "'['", "']'",
-  "'+'", "'-'", "'('", "')'", "'='", "'{'", "'}'", "$accept", "program",
-  "language", "optionSequence", "option", "statementSequence", "statement",
-  "instruction", "ALU_instruction", "TexInstruction", "ARL_instruction",
-  "VECTORop_instruction", "SCALARop_instruction", "BINSCop_instruction",
-  "BINop_instruction", "TRIop_instruction", "SAMPLE_instruction",
-  "KIL_instruction", "TXD_instruction", "texImageUnit", "texTarget",
-  "SWZ_instruction", "scalarSrcReg", "scalarUse", "swizzleSrcReg",
-  "maskedDstReg", "maskedAddrReg", "extendedSwizzle", "extSwizComp",
-  "extSwizSel", "srcReg", "dstReg", "progParamArray", "progParamArrayMem",
-  "progParamArrayAbs", "progParamArrayRel", "addrRegRelOffset",
-  "addrRegPosOffset", "addrRegNegOffset", "addrReg", "addrComponent",
-  "addrWriteMask", "scalarSuffix", "swizzleSuffix", "optionalMask",
-  "optionalCcMask", "ccTest", "ccTest2", "ccMaskRule", "ccMaskRule2",
-  "namingStatement", "ATTRIB_statement", "attribBinding", "vtxAttribItem",
-  "vtxAttribNum", "vtxOptWeightNum", "vtxWeightNum", "fragAttribItem",
-  "PARAM_statement", "PARAM_singleStmt", "PARAM_multipleStmt",
-  "optArraySize", "paramSingleInit", "paramMultipleInit",
-  "paramMultInitList", "paramSingleItemDecl", "paramSingleItemUse",
-  "paramMultipleItem", "stateMultipleItem", "stateSingleItem",
-  "stateMaterialItem", "stateMatProperty", "stateLightItem",
-  "stateLightProperty", "stateSpotProperty", "stateLightModelItem",
-  "stateLModProperty", "stateLightProdItem", "stateLProdProperty",
-  "stateTexEnvItem", "stateTexEnvProperty", "ambDiffSpecProperty",
-  "stateLightNumber", "stateTexGenItem", "stateTexGenType",
-  "stateTexGenCoord", "stateFogItem", "stateFogProperty",
-  "stateClipPlaneItem", "stateClipPlaneNum", "statePointItem",
-  "statePointProperty", "stateMatrixRow", "stateMatrixRows",
-  "optMatrixRows", "stateMatrixItem", "stateOptMatModifier",
-  "stateMatModifier", "stateMatrixRowNum", "stateMatrixName",
-  "stateOptModMatNum", "stateModMatNum", "statePaletteMatNum",
-  "stateProgramMatNum", "stateDepthItem", "programSingleItem",
-  "programMultipleItem", "progEnvParams", "progEnvParamNums",
-  "progEnvParam", "progLocalParams", "progLocalParamNums",
-  "progLocalParam", "progEnvParamNum", "progLocalParamNum",
-  "paramConstDecl", "paramConstUse", "paramConstScalarDecl",
-  "paramConstScalarUse", "paramConstVector", "signedFloatConstant",
-  "optionalSign", "TEMP_statement", "@1", "optVarSize",
-  "ADDRESS_statement", "@2", "varNameList", "OUTPUT_statement",
-  "resultBinding", "resultColBinding", "optResultFaceType",
-  "optResultColorType", "optFaceType", "optColorType",
-  "optTexCoordUnitNum", "optTexImageUnitNum", "optLegacyTexUnitNum",
-  "texCoordUnitNum", "texImageUnitNum", "legacyTexUnitNum",
-  "ALIAS_statement", "string", 0
-};
-#endif
-
-# ifdef YYPRINT
-/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
-   token YYLEX-NUM.  */
-static const yytype_uint16 yytoknum[] =
-{
-       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
-     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
-     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
-     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
-     295,   296,   297,   298,   299,   300,   301,   302,   303,   304,
-     305,   306,   307,   308,   309,   310,   311,   312,   313,   314,
-     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
-     325,   326,   327,   328,   329,   330,   331,   332,   333,   334,
-     335,   336,   337,   338,   339,   340,   341,   342,   343,   344,
-     345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
-     355,   356,   357,   358,   359,   360,   361,   362,    59,    44,
-     124,    91,    93,    43,    45,    40,    41,    61,   123,   125
-};
-# endif
-
-/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
-static const yytype_uint16 yyr1[] =
-{
-       0,   120,   121,   122,   122,   123,   123,   124,   125,   125,
-     126,   126,   127,   127,   128,   128,   128,   128,   128,   128,
-     128,   129,   129,   129,   130,   131,   132,   133,   134,   135,
-     136,   137,   137,   138,   139,   140,   140,   140,   140,   140,
-     140,   140,   140,   140,   140,   140,   140,   141,   142,   142,
-     143,   143,   144,   144,   145,   146,   147,   148,   149,   149,
-     150,   150,   150,   150,   151,   151,   152,   153,   153,   154,
-     155,   156,   156,   156,   157,   158,   159,   160,   161,   162,
-     163,   163,   163,   163,   164,   164,   164,   164,   164,   165,
-     165,   165,   166,   167,   168,   169,   170,   170,   170,   170,
-     170,   170,   171,   172,   172,   173,   173,   173,   173,   173,
-     173,   173,   173,   174,   175,   175,   176,   177,   177,   177,
-     177,   178,   178,   179,   180,   181,   181,   182,   183,   184,
-     184,   185,   185,   185,   186,   186,   186,   187,   187,   187,
-     188,   188,   189,   189,   189,   189,   189,   189,   189,   189,
-     189,   189,   189,   190,   191,   191,   191,   192,   193,   193,
-     193,   193,   193,   194,   195,   196,   196,   197,   198,   199,
-     200,   201,   201,   201,   202,   203,   204,   204,   205,   205,
-     205,   205,   206,   207,   207,   208,   209,   210,   211,   211,
-     212,   213,   214,   214,   215,   216,   216,   217,   217,   217,
-     218,   219,   219,   219,   219,   219,   219,   220,   220,   221,
-     222,   223,   224,   225,   225,   226,   226,   227,   228,   228,
-     229,   230,   231,   231,   232,   233,   234,   235,   235,   236,
-     236,   237,   238,   238,   239,   239,   239,   239,   240,   240,
-     241,   241,   241,   243,   242,   244,   244,   246,   245,   247,
-     247,   248,   249,   249,   249,   249,   249,   249,   250,   251,
-     251,   251,   252,   252,   252,   253,   253,   253,   254,   254,
-     254,   255,   255,   256,   256,   257,   257,   258,   259,   260,
-     261,   262,   262
-};
-
-/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
-static const yytype_uint8 yyr2[] =
-{
-       0,     2,     4,     1,     1,     2,     0,     3,     2,     0,
-       2,     2,     1,     1,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     1,     4,     4,     4,     6,     6,     8,
-       8,     2,     2,    12,     2,     1,     1,     1,     1,     1,
-       1,     1,     1,     1,     1,     1,     1,     6,     2,     4,
-       2,     1,     3,     5,     3,     2,     7,     2,     1,     1,
-       1,     1,     4,     1,     1,     1,     1,     1,     1,     1,
-       3,     0,     2,     2,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     0,     1,     1,     1,     1,     0,     3,
-       3,     0,     2,     2,     1,     1,     1,     1,     1,     1,
-       1,     1,     4,     2,     2,     1,     2,     1,     2,     1,
-       2,     4,     4,     1,     0,     3,     1,     1,     2,     1,
-       2,     1,     1,     3,     6,     0,     1,     2,     4,     1,
-       3,     1,     1,     1,     1,     1,     1,     1,     1,     1,
-       1,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     3,     1,     1,     1,     5,     1,     1,
-       1,     2,     1,     1,     2,     1,     2,     6,     1,     3,
-       1,     1,     1,     1,     1,     4,     1,     1,     1,     1,
-       1,     1,     2,     1,     1,     5,     1,     2,     1,     1,
-       5,     2,     0,     6,     3,     0,     1,     1,     1,     1,
-       1,     2,     1,     1,     2,     4,     4,     0,     3,     1,
-       1,     1,     2,     1,     1,     1,     1,     5,     1,     3,
-       5,     5,     1,     3,     5,     1,     1,     1,     1,     1,
-       1,     1,     1,     1,     3,     5,     7,     9,     2,     2,
-       1,     1,     0,     0,     4,     1,     0,     0,     3,     3,
-       1,     5,     2,     2,     2,     2,     3,     2,     3,     0,
-       1,     1,     0,     1,     1,     0,     1,     1,     0,     1,
-       1,     0,     3,     0,     3,     0,     3,     1,     1,     1,
-       4,     1,     1
-};
-
-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
-   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
-   means the default is an error.  */
-static const yytype_uint16 yydefact[] =
-{
-       0,     3,     4,     0,     6,     1,     9,     0,     5,   246,
-     281,   282,     0,   247,     0,     0,     0,     2,     0,     0,
-       0,     0,     0,     0,     0,   242,     0,     0,     8,     0,
-      12,    13,    14,    15,    16,    17,    18,    19,    21,    22,
-      23,    20,     0,    96,    97,   121,   122,    98,     0,    99,
-     100,   101,   245,     7,     0,     0,     0,     0,     0,    65,
-       0,    88,    64,     0,     0,     0,     0,     0,    76,     0,
-       0,    94,   240,   241,    31,    32,    83,     0,     0,     0,
-      10,    11,     0,   243,   250,   248,     0,     0,   125,   242,
-     123,   259,   257,   253,   255,   252,   271,   254,   242,    84,
-      85,    86,    87,    91,   242,   242,   242,   242,   242,   242,
-      78,    55,    81,    80,    82,    92,   233,   232,     0,     0,
-       0,     0,    60,     0,   242,    83,     0,    61,    63,   134,
-     135,   213,   214,   136,   229,   230,     0,   242,     0,     0,
-       0,   280,   102,   126,     0,   127,   131,   132,   133,   227,
-     228,   231,     0,   261,   260,   262,     0,   256,     0,     0,
-      54,     0,     0,     0,    26,     0,    25,    24,   268,   119,
-     117,   271,   104,     0,     0,     0,     0,     0,     0,   265,
-       0,   265,     0,     0,   275,   271,   142,   143,   144,   145,
-     147,   146,   148,   149,   150,   151,     0,   152,   268,   109,
-       0,   107,   105,   271,     0,   114,   103,    83,     0,    52,
-       0,     0,     0,     0,   244,   249,     0,   239,   238,   263,
-     264,   258,   277,     0,   242,    95,     0,     0,    83,   242,
-       0,    48,     0,    51,     0,   242,   269,   270,   118,   120,
-       0,     0,     0,   212,   183,   184,   182,     0,   165,   267,
-     266,   164,     0,     0,     0,     0,   207,   203,     0,   202,
-     271,   195,   189,   188,   187,     0,     0,     0,     0,   108,
-       0,   110,     0,     0,   106,     0,   242,   234,    69,     0,
-      67,    68,     0,   242,   242,   251,     0,   124,   272,    28,
-      89,    90,    93,    27,     0,    79,    50,   273,     0,     0,
-     225,     0,   226,     0,   186,     0,   174,     0,   166,     0,
-     171,   172,   155,   156,   173,   153,   154,     0,     0,   201,
-       0,   204,   197,   199,   198,   194,   196,   279,     0,   170,
-     169,   176,   177,     0,     0,   116,     0,   113,     0,     0,
-      53,     0,    62,    77,    71,    47,     0,     0,     0,   242,
-      49,     0,    34,     0,   242,   220,   224,     0,     0,   265,
-     211,     0,   209,     0,   210,     0,   276,   181,   180,   178,
-     179,   175,   200,     0,   111,   112,   115,   242,   235,     0,
-       0,    70,   242,    58,    57,    59,   242,     0,     0,     0,
-     129,   137,   140,   138,   215,   216,   139,   278,     0,    35,
-      36,    37,    38,    39,    40,    41,    42,    43,    44,    45,
-      46,    30,    29,   185,   160,   162,   159,     0,   157,   158,
-       0,   206,   208,   205,   190,     0,    74,    72,    75,    73,
-       0,     0,     0,     0,   141,   192,   242,   128,   274,   163,
-     161,   167,   168,   242,   236,   242,     0,     0,     0,     0,
-     191,   130,     0,     0,     0,     0,   218,     0,   222,     0,
-     237,   242,     0,   217,     0,   221,     0,     0,    56,    33,
-     219,   223,     0,     0,   193
-};
-
-/* YYDEFGOTO[NTERM-NUM].  */
-static const yytype_int16 yydefgoto[] =
-{
-      -1,     3,     4,     6,     8,     9,    28,    29,    30,    31,
-      32,    33,    34,    35,    36,    37,    38,    39,    40,   298,
-     411,    41,   161,   231,    74,    60,    69,   345,   346,   384,
-     232,    61,   126,   279,   280,   281,   381,   427,   429,    70,
-     344,   111,   296,   115,   103,   160,    75,   227,    76,   228,
-      42,    43,   127,   206,   338,   274,   336,   172,    44,    45,
-      46,   144,    90,   287,   389,   145,   128,   390,   391,   129,
-     186,   315,   187,   418,   440,   188,   251,   189,   441,   190,
-     330,   316,   307,   191,   333,   371,   192,   246,   193,   305,
-     194,   264,   195,   434,   450,   196,   325,   326,   373,   261,
-     319,   363,   365,   361,   197,   130,   393,   394,   455,   131,
-     395,   457,   132,   301,   303,   396,   133,   149,   134,   135,
-     151,    77,    47,   139,    48,    49,    54,    85,    50,    62,
-      97,   155,   221,   252,   238,   157,   352,   266,   223,   398,
-     328,    51,    12
-};
-
-/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
-   STATE-NUM.  */
-#define YYPACT_NINF -401
-static const yytype_int16 yypact[] =
-{
-     193,  -401,  -401,    27,  -401,  -401,    62,   143,  -401,    24,
-    -401,  -401,   -30,  -401,   -18,    12,    83,  -401,    15,    15,
-      15,    15,    15,    15,    67,    61,    15,    15,  -401,   127,
-    -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,
-    -401,  -401,   144,  -401,  -401,  -401,  -401,  -401,   204,  -401,
-    -401,  -401,  -401,  -401,   155,   136,   138,    34,   140,  -401,
-     147,   108,  -401,   150,   156,   157,   158,   160,  -401,   162,
-     159,  -401,  -401,  -401,  -401,  -401,   102,   -13,   163,   164,
-    -401,  -401,   165,  -401,  -401,   166,   170,    10,   235,     0,
-    -401,   141,  -401,  -401,  -401,  -401,   167,  -401,   131,  -401,
-    -401,  -401,  -401,   168,   131,   131,   131,   131,   131,   131,
-    -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,   104,    97,
-     114,    38,   169,    30,   131,   102,   171,  -401,  -401,  -401,
-    -401,  -401,  -401,  -401,  -401,  -401,    30,   131,   172,   155,
-     175,  -401,  -401,  -401,   173,  -401,  -401,  -401,  -401,  -401,
-    -401,  -401,   223,  -401,  -401,   123,   253,  -401,   177,   149,
-    -401,   178,   -10,   181,  -401,   182,  -401,  -401,   134,  -401,
-    -401,   167,  -401,   183,   184,   185,   213,    99,   186,   154,
-     187,   146,   153,     7,   188,   167,  -401,  -401,  -401,  -401,
-    -401,  -401,  -401,  -401,  -401,  -401,   215,  -401,   134,  -401,
-     190,  -401,  -401,   167,   191,   192,  -401,   102,   -48,  -401,
-       1,   195,   196,   214,   166,  -401,   189,  -401,  -401,  -401,
-    -401,  -401,  -401,   180,   131,  -401,   194,   197,   102,   131,
-      30,  -401,   203,   205,   201,   131,  -401,  -401,  -401,  -401,
-     285,   288,   289,  -401,  -401,  -401,  -401,   291,  -401,  -401,
-    -401,  -401,   248,   291,    33,   206,   207,  -401,   208,  -401,
-     167,    14,  -401,  -401,  -401,   293,   292,    92,   209,  -401,
-     299,  -401,   301,   299,  -401,   216,   131,  -401,  -401,   217,
-    -401,  -401,   221,   131,   131,  -401,   212,  -401,  -401,  -401,
-    -401,  -401,  -401,  -401,   218,  -401,  -401,   220,   224,   225,
-    -401,   226,  -401,   227,  -401,   228,  -401,   230,  -401,   231,
-    -401,  -401,  -401,  -401,  -401,  -401,  -401,   304,   309,  -401,
-     312,  -401,  -401,  -401,  -401,  -401,  -401,  -401,   232,  -401,
-    -401,  -401,  -401,   161,   313,  -401,   233,  -401,   234,   238,
-    -401,    13,  -401,  -401,   137,  -401,   242,   -15,   243,     3,
-    -401,   314,  -401,   133,   131,  -401,  -401,   296,    94,   146,
-    -401,   245,  -401,   246,  -401,   247,  -401,  -401,  -401,  -401,
-    -401,  -401,  -401,   249,  -401,  -401,  -401,   131,  -401,   332,
-     337,  -401,   131,  -401,  -401,  -401,   131,   142,   114,    28,
-    -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,   250,  -401,
-    -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,
-    -401,  -401,  -401,  -401,  -401,  -401,  -401,   331,  -401,  -401,
-      68,  -401,  -401,  -401,  -401,    43,  -401,  -401,  -401,  -401,
-     255,   256,   257,   258,  -401,   300,     3,  -401,  -401,  -401,
-    -401,  -401,  -401,   131,  -401,   131,   201,   285,   288,   259,
-    -401,  -401,   252,   264,   265,   263,   261,   266,   270,   313,
-    -401,   131,   133,  -401,   285,  -401,   288,    80,  -401,  -401,
-    -401,  -401,   313,   267,  -401
-};
-
-/* YYPGOTO[NTERM-NUM].  */
-static const yytype_int16 yypgoto[] =
-{
-    -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,
-    -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,   -69,
-     -82,  -401,  -100,   151,   -86,   210,  -401,  -401,  -366,  -401,
-     -54,  -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,   174,
-    -401,  -401,  -401,  -118,  -401,  -401,   229,  -401,  -401,  -401,
-    -401,  -401,   295,  -401,  -401,  -401,   110,  -401,  -401,  -401,
-    -401,  -401,  -401,  -401,  -401,  -401,  -401,   -51,  -401,   -88,
-    -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,  -401,
-    -401,  -311,   139,  -401,  -401,  -401,  -401,  -401,  -401,  -401,
-    -401,  -401,  -401,  -401,  -401,    -2,  -401,  -401,  -400,  -401,
-    -401,  -401,  -401,  -401,  -401,   298,  -401,  -401,  -401,  -401,
-    -401,  -401,  -401,  -390,  -295,   302,  -401,  -401,  -136,   -87,
-    -120,   -89,  -401,  -401,  -401,  -401,  -401,   251,  -401,   176,
-    -401,  -401,  -401,  -176,   198,  -153,  -401,  -401,  -401,  -401,
-    -401,  -401,    -6
-};
-
-/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
-   positive, shift that token.  If negative, reduce the rule which
-   number is the opposite.  If zero, do what YYDEFACT says.
-   If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -230
-static const yytype_int16 yytable[] =
-{
-     152,   146,   150,    52,   208,   254,   164,   209,   383,   167,
-     116,   117,   158,   116,   117,   162,   430,   162,   239,   163,
-     162,   165,   166,   125,   278,   118,   233,     5,   118,    13,
-      14,    15,   267,   262,    16,   152,    17,    18,    19,    20,
-      21,    22,    23,    24,    25,    26,    27,   419,   118,   119,
-     271,   212,   119,   116,   117,   322,   323,   456,   310,   467,
-     120,   276,   119,   120,   311,   387,   312,   198,   118,   207,
-       7,   277,   473,   120,   470,   199,   388,   263,    53,   453,
-      58,    55,   211,   121,    10,    11,   121,   122,   200,   275,
-     122,   201,   119,   310,   233,   468,   324,   123,   202,   311,
-     230,    68,   313,   120,   314,   124,   121,   321,   124,   442,
-     292,    56,   203,    72,    73,    59,    72,    73,   124,   310,
-     414,   124,   377,    10,    11,   311,   121,   331,   244,   293,
-     122,   173,   378,   168,   415,   204,   205,   436,   289,   314,
-     162,   169,   175,   174,   176,    88,   332,   437,   124,   299,
-     177,    89,   443,   458,   416,   245,   341,   178,   179,   180,
-      71,   181,   444,   182,   170,   314,   417,    68,   153,    91,
-      92,   471,   183,   249,    72,    73,   432,    93,   171,   248,
-     154,   249,    57,   420,   219,   250,   472,   152,   433,   184,
-     185,   220,   424,   250,   347,   236,     1,     2,   348,    94,
-      95,   255,   237,   112,   256,   257,   113,   114,   258,    99,
-     100,   101,   102,    82,    96,    83,   259,   399,   400,   401,
-     402,   403,   404,   405,   406,   407,   408,   409,   410,    63,
-      64,    65,    66,    67,   260,    80,    78,    79,   367,   368,
-     369,   370,    10,    11,    72,    73,   217,   218,    71,   225,
-     379,   380,    81,    86,    84,    87,    98,   425,   143,   104,
-     152,   392,   150,   110,   138,   105,   106,   107,   412,   108,
-     141,   109,   136,   137,   215,   140,   222,   243,   156,    58,
-     -66,   268,   210,   159,   297,   216,   224,   229,   152,   213,
-     234,   235,   288,   347,   240,   241,   242,   247,   253,   265,
-     431,   270,   272,   273,   283,   284,   286,   295,   300,  -229,
-     290,   302,   304,   291,   306,   308,   327,   317,   318,   320,
-     334,   329,   335,   452,   337,   343,   340,   360,   350,   342,
-     349,   351,   362,   353,   354,   364,   372,   397,   355,   356,
-     357,   385,   358,   359,   366,   374,   375,   152,   392,   150,
-     376,   382,   386,   413,   152,   426,   347,   421,   422,   423,
-     428,   424,   438,   439,   445,   446,   449,   464,   447,   448,
-     459,   460,   347,   461,   462,   463,   466,   454,   465,   474,
-     469,   294,   142,   339,   282,   451,   435,   147,   226,   285,
-     214,   148,   309,     0,     0,     0,   269
-};
-
-static const yytype_int16 yycheck[] =
-{
-      89,    89,    89,     9,   124,   181,   106,   125,    23,   109,
-      23,    24,    98,    23,    24,   104,   382,   106,   171,   105,
-     109,   107,   108,    77,    23,    38,   162,     0,    38,     5,
-       6,     7,   185,    26,    10,   124,    12,    13,    14,    15,
-      16,    17,    18,    19,    20,    21,    22,   358,    38,    62,
-     203,   137,    62,    23,    24,    41,    42,   447,    25,   459,
-      73,   109,    62,    73,    31,    62,    33,    29,    38,   123,
-       8,   119,   472,    73,   464,    37,    73,    70,   108,   445,
-      65,    99,   136,    96,    99,   100,    96,   100,    50,   207,
-     100,    53,    62,    25,   230,   461,    82,   110,    60,    31,
-     110,   100,    69,    73,    71,   118,    96,   260,   118,   420,
-     228,    99,    74,   113,   114,   100,   113,   114,   118,    25,
-      26,   118,   109,    99,   100,    31,    96,    35,    29,   229,
-     100,    34,   119,    29,    40,    97,    98,   109,   224,    71,
-     229,    37,    28,    46,    30,   111,    54,   119,   118,   235,
-      36,   117,   109,   448,    60,    56,   276,    43,    44,    45,
-      99,    47,   119,    49,    60,    71,    72,   100,    27,    29,
-      30,   466,    58,    27,   113,   114,    34,    37,    74,    25,
-      39,    27,    99,   359,    61,    39,   106,   276,    46,    75,
-      76,    68,   112,    39,   283,    61,     3,     4,   284,    59,
-      60,    48,    68,   101,    51,    52,   104,   105,    55,   101,
-     102,   103,   104,     9,    74,    11,    63,    84,    85,    86,
-      87,    88,    89,    90,    91,    92,    93,    94,    95,    19,
-      20,    21,    22,    23,    81,   108,    26,    27,    77,    78,
-      79,    80,    99,   100,   113,   114,    23,    24,    99,   100,
-     113,   114,   108,   117,    99,   117,   109,   377,    23,   109,
-     349,   349,   349,   104,    99,   109,   109,   109,   354,   109,
-     100,   109,   109,   109,    99,   109,    23,    64,   111,    65,
-     111,    66,   111,   115,    83,   112,   109,   109,   377,   117,
-     109,   109,   112,   382,   111,   111,   111,   111,   111,   111,
-     386,   111,   111,   111,   109,   109,   117,   104,    23,   104,
-     116,    23,    23,   116,    23,    67,    23,   111,   111,   111,
-     111,    29,    23,   443,    23,   104,   110,    23,   110,   112,
-     118,   111,    23,   109,   109,    23,    23,    23,   112,   112,
-     112,   347,   112,   112,   112,   112,   112,   436,   436,   436,
-     112,   109,   109,    57,   443,    23,   445,   112,   112,   112,
-      23,   112,   112,    32,   109,   109,    66,   106,   111,   111,
-     111,   119,   461,   109,   109,   112,   106,   446,   112,   112,
-     462,   230,    87,   273,   210,   436,   388,    89,   159,   213,
-     139,    89,   253,    -1,    -1,    -1,   198
-};
-
-/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
-   symbol of state STATE-NUM.  */
-static const yytype_uint16 yystos[] =
-{
-       0,     3,     4,   121,   122,     0,   123,     8,   124,   125,
-      99,   100,   262,     5,     6,     7,    10,    12,    13,    14,
-      15,    16,    17,    18,    19,    20,    21,    22,   126,   127,
-     128,   129,   130,   131,   132,   133,   134,   135,   136,   137,
-     138,   141,   170,   171,   178,   179,   180,   242,   244,   245,
-     248,   261,   262,   108,   246,    99,    99,    99,    65,   100,
-     145,   151,   249,   145,   145,   145,   145,   145,   100,   146,
-     159,    99,   113,   114,   144,   166,   168,   241,   145,   145,
-     108,   108,     9,    11,    99,   247,   117,   117,   111,   117,
-     182,    29,    30,    37,    59,    60,    74,   250,   109,   101,
-     102,   103,   104,   164,   109,   109,   109,   109,   109,   109,
-     104,   161,   101,   104,   105,   163,    23,    24,    38,    62,
-      73,    96,   100,   110,   118,   150,   152,   172,   186,   189,
-     225,   229,   232,   236,   238,   239,   109,   109,    99,   243,
-     109,   100,   172,    23,   181,   185,   189,   225,   235,   237,
-     239,   240,   241,    27,    39,   251,   111,   255,   144,   115,
-     165,   142,   241,   144,   142,   144,   144,   142,    29,    37,
-      60,    74,   177,    34,    46,    28,    30,    36,    43,    44,
-      45,    47,    49,    58,    75,    76,   190,   192,   195,   197,
-     199,   203,   206,   208,   210,   212,   215,   224,    29,    37,
-      50,    53,    60,    74,    97,    98,   173,   150,   240,   163,
-     111,   150,   144,   117,   247,    99,   112,    23,    24,    61,
-      68,   252,    23,   258,   109,   100,   166,   167,   169,   109,
-     110,   143,   150,   238,   109,   109,    61,    68,   254,   255,
-     111,   111,   111,    64,    29,    56,   207,   111,    25,    27,
-      39,   196,   253,   111,   253,    48,    51,    52,    55,    63,
-      81,   219,    26,    70,   211,   111,   257,   255,    66,   254,
-     111,   255,   111,   111,   175,   163,   109,   119,    23,   153,
-     154,   155,   159,   109,   109,   249,   117,   183,   112,   144,
-     116,   116,   163,   142,   143,   104,   162,    83,   139,   144,
-      23,   233,    23,   234,    23,   209,    23,   202,    67,   202,
-      25,    31,    33,    69,    71,   191,   201,   111,   111,   220,
-     111,   255,    41,    42,    82,   216,   217,    23,   260,    29,
-     200,    35,    54,   204,   111,    23,   176,    23,   174,   176,
-     110,   240,   112,   104,   160,   147,   148,   241,   144,   118,
-     110,   111,   256,   109,   109,   112,   112,   112,   112,   112,
-      23,   223,    23,   221,    23,   222,   112,    77,    78,    79,
-      80,   205,    23,   218,   112,   112,   112,   109,   119,   113,
-     114,   156,   109,    23,   149,   262,   109,    62,    73,   184,
-     187,   188,   189,   226,   227,   230,   235,    23,   259,    84,
-      85,    86,    87,    88,    89,    90,    91,    92,    93,    94,
-      95,   140,   144,    57,    26,    40,    60,    72,   193,   201,
-     253,   112,   112,   112,   112,   240,    23,   157,    23,   158,
-     148,   144,    34,    46,   213,   215,   109,   119,   112,    32,
-     194,   198,   201,   109,   119,   109,   109,   111,   111,    66,
-     214,   187,   240,   148,   139,   228,   233,   231,   234,   111,
-     119,   109,   109,   112,   106,   112,   106,   218,   148,   140,
-     233,   234,   106,   218,   112
-};
-
-#define yyerrok                (yyerrstatus = 0)
-#define yyclearin      (yychar = YYEMPTY)
-#define YYEMPTY                (-2)
-#define YYEOF          0
-
-#define YYACCEPT       goto yyacceptlab
-#define YYABORT                goto yyabortlab
-#define YYERROR                goto yyerrorlab
-
-
-/* Like YYERROR except do call yyerror.  This remains here temporarily
-   to ease the transition to the new meaning of YYERROR, for GCC.
-   Once GCC version 2 has supplanted version 1, this can go.  */
-
-#define YYFAIL         goto yyerrlab
-
-#define YYRECOVERING()  (!!yyerrstatus)
-
-#define YYBACKUP(Token, Value)                                 \
-do                                                             \
-  if (yychar == YYEMPTY && yylen == 1)                         \
-    {                                                          \
-      yychar = (Token);                                                \
-      yylval = (Value);                                                \
-      yytoken = YYTRANSLATE (yychar);                          \
-      YYPOPSTACK (1);                                          \
-      goto yybackup;                                           \
-    }                                                          \
-  else                                                         \
-    {                                                          \
-      yyerror (&yylloc, state, YY_("syntax error: cannot back up")); \
-      YYERROR;                                                 \
-    }                                                          \
-while (YYID (0))
-
-
-#define YYTERROR       1
-#define YYERRCODE      256
-
-
-/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
-   If N is 0, then set CURRENT to the empty location which ends
-   the previous symbol: RHS[0] (always defined).  */
-
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
-#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N)                               \
-    do                                                                 \
-      if (YYID (N))                                                    \
-       {                                                               \
-         (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
-         (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
-         (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
-         (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
-       }                                                               \
-      else                                                             \
-       {                                                               \
-         (Current).first_line   = (Current).last_line   =              \
-           YYRHSLOC (Rhs, 0).last_line;                                \
-         (Current).first_column = (Current).last_column =              \
-           YYRHSLOC (Rhs, 0).last_column;                              \
-       }                                                               \
-    while (YYID (0))
-#endif
-
-
-/* YY_LOCATION_PRINT -- Print the location on the stream.
-   This macro was not mandated originally: define only if we know
-   we won't break user code: when these are the locations we know.  */
-
-#ifndef YY_LOCATION_PRINT
-# if YYLTYPE_IS_TRIVIAL
-#  define YY_LOCATION_PRINT(File, Loc)                 \
-     fprintf (File, "%d.%d-%d.%d",                     \
-             (Loc).first_line, (Loc).first_column,     \
-             (Loc).last_line,  (Loc).last_column)
-# else
-#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
-#endif
-
-
-/* YYLEX -- calling `yylex' with the right arguments.  */
-
-#ifdef YYLEX_PARAM
-# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
-#else
-# define YYLEX yylex (&yylval, &yylloc, scanner)
-#endif
-
-/* Enable debugging if requested.  */
-#if YYDEBUG
-
-# ifndef YYFPRINTF
-#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
-#  define YYFPRINTF fprintf
-# endif
-
-# define YYDPRINTF(Args)                       \
-do {                                           \
-  if (yydebug)                                 \
-    YYFPRINTF Args;                            \
-} while (YYID (0))
-
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)                   \
-do {                                                                     \
-  if (yydebug)                                                           \
-    {                                                                    \
-      YYFPRINTF (stderr, "%s ", Title);                                          \
-      yy_symbol_print (stderr,                                           \
-                 Type, Value, Location, state); \
-      YYFPRINTF (stderr, "\n");                                                  \
-    }                                                                    \
-} while (YYID (0))
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
-
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct asm_parser_state *state)
-#else
-static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state)
-    FILE *yyoutput;
-    int yytype;
-    YYSTYPE const * const yyvaluep;
-    YYLTYPE const * const yylocationp;
-    struct asm_parser_state *state;
-#endif
-{
-  if (!yyvaluep)
-    return;
-  YYUSE (yylocationp);
-  YYUSE (state);
-# ifdef YYPRINT
-  if (yytype < YYNTOKENS)
-    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
-# else
-  YYUSE (yyoutput);
-# endif
-  switch (yytype)
-    {
-      default:
-       break;
-    }
-}
-
-
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct asm_parser_state *state)
-#else
-static void
-yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, state)
-    FILE *yyoutput;
-    int yytype;
-    YYSTYPE const * const yyvaluep;
-    YYLTYPE const * const yylocationp;
-    struct asm_parser_state *state;
-#endif
-{
-  if (yytype < YYNTOKENS)
-    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
-  else
-    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
-
-  YY_LOCATION_PRINT (yyoutput, *yylocationp);
-  YYFPRINTF (yyoutput, ": ");
-  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state);
-  YYFPRINTF (yyoutput, ")");
-}
-
-/*------------------------------------------------------------------.
-| yy_stack_print -- Print the state stack from its BOTTOM up to its |
-| TOP (included).                                                   |
-`------------------------------------------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static void
-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
-#else
-static void
-yy_stack_print (yybottom, yytop)
-    yytype_int16 *yybottom;
-    yytype_int16 *yytop;
-#endif
-{
-  YYFPRINTF (stderr, "Stack now");
-  for (; yybottom <= yytop; yybottom++)
-    {
-      int yybot = *yybottom;
-      YYFPRINTF (stderr, " %d", yybot);
-    }
-  YYFPRINTF (stderr, "\n");
-}
-
-# define YY_STACK_PRINT(Bottom, Top)                           \
-do {                                                           \
-  if (yydebug)                                                 \
-    yy_stack_print ((Bottom), (Top));                          \
-} while (YYID (0))
-
-
-/*------------------------------------------------.
-| Report that the YYRULE is going to be reduced.  |
-`------------------------------------------------*/
-
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static void
-yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, struct asm_parser_state *state)
-#else
-static void
-yy_reduce_print (yyvsp, yylsp, yyrule, state)
-    YYSTYPE *yyvsp;
-    YYLTYPE *yylsp;
-    int yyrule;
-    struct asm_parser_state *state;
-#endif
-{
-  int yynrhs = yyr2[yyrule];
-  int yyi;
-  unsigned long int yylno = yyrline[yyrule];
-  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
-            yyrule - 1, yylno);
-  /* The symbols being reduced.  */
-  for (yyi = 0; yyi < yynrhs; yyi++)
-    {
-      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
-      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
-                      &(yyvsp[(yyi + 1) - (yynrhs)])
-                      , &(yylsp[(yyi + 1) - (yynrhs)])                , state);
-      YYFPRINTF (stderr, "\n");
-    }
-}
-
-# define YY_REDUCE_PRINT(Rule)         \
-do {                                   \
-  if (yydebug)                         \
-    yy_reduce_print (yyvsp, yylsp, Rule, state); \
-} while (YYID (0))
-
-/* Nonzero means print parse trace.  It is left uninitialized so that
-   multiple parsers can coexist.  */
-int yydebug;
-#else /* !YYDEBUG */
-# define YYDPRINTF(Args)
-# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
-# define YY_STACK_PRINT(Bottom, Top)
-# define YY_REDUCE_PRINT(Rule)
-#endif /* !YYDEBUG */
-
-
-/* YYINITDEPTH -- initial size of the parser's stacks.  */
-#ifndef        YYINITDEPTH
-# define YYINITDEPTH 200
-#endif
-
-/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
-   if the built-in stack extension method is used).
-
-   Do not make this value too large; the results are undefined if
-   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
-   evaluated with infinite-precision integer arithmetic.  */
-
-#ifndef YYMAXDEPTH
-# define YYMAXDEPTH 10000
-#endif
-
-\f
-
-#if YYERROR_VERBOSE
-
-# ifndef yystrlen
-#  if defined __GLIBC__ && defined _STRING_H
-#   define yystrlen strlen
-#  else
-/* Return the length of YYSTR.  */
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static YYSIZE_T
-yystrlen (const char *yystr)
-#else
-static YYSIZE_T
-yystrlen (yystr)
-    const char *yystr;
-#endif
-{
-  YYSIZE_T yylen;
-  for (yylen = 0; yystr[yylen]; yylen++)
-    continue;
-  return yylen;
-}
-#  endif
-# endif
-
-# ifndef yystpcpy
-#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
-#   define yystpcpy stpcpy
-#  else
-/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
-   YYDEST.  */
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static char *
-yystpcpy (char *yydest, const char *yysrc)
-#else
-static char *
-yystpcpy (yydest, yysrc)
-    char *yydest;
-    const char *yysrc;
-#endif
-{
-  char *yyd = yydest;
-  const char *yys = yysrc;
-
-  while ((*yyd++ = *yys++) != '\0')
-    continue;
-
-  return yyd - 1;
-}
-#  endif
-# endif
-
-# ifndef yytnamerr
-/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
-   quotes and backslashes, so that it's suitable for yyerror.  The
-   heuristic is that double-quoting is unnecessary unless the string
-   contains an apostrophe, a comma, or backslash (other than
-   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
-   null, do not copy; instead, return the length of what the result
-   would have been.  */
-static YYSIZE_T
-yytnamerr (char *yyres, const char *yystr)
-{
-  if (*yystr == '"')
-    {
-      YYSIZE_T yyn = 0;
-      char const *yyp = yystr;
-
-      for (;;)
-       switch (*++yyp)
-         {
-         case '\'':
-         case ',':
-           goto do_not_strip_quotes;
-
-         case '\\':
-           if (*++yyp != '\\')
-             goto do_not_strip_quotes;
-           /* Fall through.  */
-         default:
-           if (yyres)
-             yyres[yyn] = *yyp;
-           yyn++;
-           break;
-
-         case '"':
-           if (yyres)
-             yyres[yyn] = '\0';
-           return yyn;
-         }
-    do_not_strip_quotes: ;
-    }
-
-  if (! yyres)
-    return yystrlen (yystr);
-
-  return yystpcpy (yyres, yystr) - yyres;
-}
-# endif
-
-/* Copy into YYRESULT an error message about the unexpected token
-   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
-   including the terminating null byte.  If YYRESULT is null, do not
-   copy anything; just return the number of bytes that would be
-   copied.  As a special case, return 0 if an ordinary "syntax error"
-   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
-   size calculation.  */
-static YYSIZE_T
-yysyntax_error (char *yyresult, int yystate, int yychar)
-{
-  int yyn = yypact[yystate];
-
-  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
-    return 0;
-  else
-    {
-      int yytype = YYTRANSLATE (yychar);
-      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
-      YYSIZE_T yysize = yysize0;
-      YYSIZE_T yysize1;
-      int yysize_overflow = 0;
-      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-      int yyx;
-
-# if 0
-      /* This is so xgettext sees the translatable formats that are
-        constructed on the fly.  */
-      YY_("syntax error, unexpected %s");
-      YY_("syntax error, unexpected %s, expecting %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
-# endif
-      char *yyfmt;
-      char const *yyf;
-      static char const yyunexpected[] = "syntax error, unexpected %s";
-      static char const yyexpecting[] = ", expecting %s";
-      static char const yyor[] = " or %s";
-      char yyformat[sizeof yyunexpected
-                   + sizeof yyexpecting - 1
-                   + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
-                      * (sizeof yyor - 1))];
-      char const *yyprefix = yyexpecting;
-
-      /* Start YYX at -YYN if negative to avoid negative indexes in
-        YYCHECK.  */
-      int yyxbegin = yyn < 0 ? -yyn : 0;
-
-      /* Stay within bounds of both yycheck and yytname.  */
-      int yychecklim = YYLAST - yyn + 1;
-      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-      int yycount = 1;
-
-      yyarg[0] = yytname[yytype];
-      yyfmt = yystpcpy (yyformat, yyunexpected);
-
-      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-       if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
-         {
-           if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-             {
-               yycount = 1;
-               yysize = yysize0;
-               yyformat[sizeof yyunexpected - 1] = '\0';
-               break;
-             }
-           yyarg[yycount++] = yytname[yyx];
-           yysize1 = yysize + yytnamerr (0, yytname[yyx]);
-           yysize_overflow |= (yysize1 < yysize);
-           yysize = yysize1;
-           yyfmt = yystpcpy (yyfmt, yyprefix);
-           yyprefix = yyor;
-         }
-
-      yyf = YY_(yyformat);
-      yysize1 = yysize + yystrlen (yyf);
-      yysize_overflow |= (yysize1 < yysize);
-      yysize = yysize1;
-
-      if (yysize_overflow)
-       return YYSIZE_MAXIMUM;
-
-      if (yyresult)
-       {
-         /* Avoid sprintf, as that infringes on the user's name space.
-            Don't have undefined behavior even if the translation
-            produced a string with the wrong number of "%s"s.  */
-         char *yyp = yyresult;
-         int yyi = 0;
-         while ((*yyp = *yyf) != '\0')
-           {
-             if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
-               {
-                 yyp += yytnamerr (yyp, yyarg[yyi++]);
-                 yyf += 2;
-               }
-             else
-               {
-                 yyp++;
-                 yyf++;
-               }
-           }
-       }
-      return yysize;
-    }
-}
-#endif /* YYERROR_VERBOSE */
-\f
-
-/*-----------------------------------------------.
-| Release the memory associated to this symbol.  |
-`-----------------------------------------------*/
-
-/*ARGSUSED*/
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-static void
-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, struct asm_parser_state *state)
-#else
-static void
-yydestruct (yymsg, yytype, yyvaluep, yylocationp, state)
-    const char *yymsg;
-    int yytype;
-    YYSTYPE *yyvaluep;
-    YYLTYPE *yylocationp;
-    struct asm_parser_state *state;
-#endif
-{
-  YYUSE (yyvaluep);
-  YYUSE (yylocationp);
-  YYUSE (state);
-
-  if (!yymsg)
-    yymsg = "Deleting";
-  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
-
-  switch (yytype)
-    {
-
-      default:
-       break;
-    }
-}
-
-/* Prevent warnings from -Wmissing-prototypes.  */
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
-int yyparse (struct asm_parser_state *state);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
-
-
-
-
-
-/*-------------------------.
-| yyparse or yypush_parse.  |
-`-------------------------*/
-
-#ifdef YYPARSE_PARAM
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (void *YYPARSE_PARAM)
-#else
-int
-yyparse (YYPARSE_PARAM)
-    void *YYPARSE_PARAM;
-#endif
-#else /* ! YYPARSE_PARAM */
-#if (defined __STDC__ || defined __C99__FUNC__ \
-     || defined __cplusplus || defined _MSC_VER)
-int
-yyparse (struct asm_parser_state *state)
-#else
-int
-yyparse (state)
-    struct asm_parser_state *state;
-#endif
-#endif
-{
-/* The lookahead symbol.  */
-int yychar;
-
-/* The semantic value of the lookahead symbol.  */
-YYSTYPE yylval;
-
-/* Location data for the lookahead symbol.  */
-YYLTYPE yylloc;
-
-    /* Number of syntax errors so far.  */
-    int yynerrs;
-
-    int yystate;
-    /* Number of tokens to shift before error messages enabled.  */
-    int yyerrstatus;
-
-    /* The stacks and their tools:
-       `yyss': related to states.
-       `yyvs': related to semantic values.
-       `yyls': related to locations.
-
-       Refer to the stacks thru separate pointers, to allow yyoverflow
-       to reallocate them elsewhere.  */
-
-    /* The state stack.  */
-    yytype_int16 yyssa[YYINITDEPTH];
-    yytype_int16 *yyss;
-    yytype_int16 *yyssp;
-
-    /* The semantic value stack.  */
-    YYSTYPE yyvsa[YYINITDEPTH];
-    YYSTYPE *yyvs;
-    YYSTYPE *yyvsp;
-
-    /* The location stack.  */
-    YYLTYPE yylsa[YYINITDEPTH];
-    YYLTYPE *yyls;
-    YYLTYPE *yylsp;
-
-    /* The locations where the error started and ended.  */
-    YYLTYPE yyerror_range[2];
-
-    YYSIZE_T yystacksize;
-
-  int yyn;
-  int yyresult;
-  /* Lookahead token as an internal (translated) token number.  */
-  int yytoken;
-  /* The variables used to return semantic value and location from the
-     action routines.  */
-  YYSTYPE yyval;
-  YYLTYPE yyloc;
-
-#if YYERROR_VERBOSE
-  /* Buffer for error messages, and its allocated size.  */
-  char yymsgbuf[128];
-  char *yymsg = yymsgbuf;
-  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
-#endif
-
-#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
-
-  /* The number of symbols on the RHS of the reduced rule.
-     Keep to zero when no symbol should be popped.  */
-  int yylen = 0;
-
-  yytoken = 0;
-  yyss = yyssa;
-  yyvs = yyvsa;
-  yyls = yylsa;
-  yystacksize = YYINITDEPTH;
-
-  YYDPRINTF ((stderr, "Starting parse\n"));
-
-  yystate = 0;
-  yyerrstatus = 0;
-  yynerrs = 0;
-  yychar = YYEMPTY; /* Cause a token to be read.  */
-
-  /* Initialize stack pointers.
-     Waste one element of value and location stack
-     so that they stay on the same level as the state stack.
-     The wasted elements are never initialized.  */
-  yyssp = yyss;
-  yyvsp = yyvs;
-  yylsp = yyls;
-
-#if YYLTYPE_IS_TRIVIAL
-  /* Initialize the default location before parsing starts.  */
-  yylloc.first_line   = yylloc.last_line   = 1;
-  yylloc.first_column = yylloc.last_column = 1;
-#endif
-
-  goto yysetstate;
-
-/*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate.  |
-`------------------------------------------------------------*/
- yynewstate:
-  /* In all cases, when you get here, the value and location stacks
-     have just been pushed.  So pushing a state here evens the stacks.  */
-  yyssp++;
-
- yysetstate:
-  *yyssp = yystate;
-
-  if (yyss + yystacksize - 1 <= yyssp)
-    {
-      /* Get the current used size of the three stacks, in elements.  */
-      YYSIZE_T yysize = yyssp - yyss + 1;
-
-#ifdef yyoverflow
-      {
-       /* Give user a chance to reallocate the stack.  Use copies of
-          these so that the &'s don't force the real ones into
-          memory.  */
-       YYSTYPE *yyvs1 = yyvs;
-       yytype_int16 *yyss1 = yyss;
-       YYLTYPE *yyls1 = yyls;
-
-       /* Each stack pointer address is followed by the size of the
-          data in use in that stack, in bytes.  This used to be a
-          conditional around just the two extra args, but that might
-          be undefined if yyoverflow is a macro.  */
-       yyoverflow (YY_("memory exhausted"),
-                   &yyss1, yysize * sizeof (*yyssp),
-                   &yyvs1, yysize * sizeof (*yyvsp),
-                   &yyls1, yysize * sizeof (*yylsp),
-                   &yystacksize);
-
-       yyls = yyls1;
-       yyss = yyss1;
-       yyvs = yyvs1;
-      }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
-      goto yyexhaustedlab;
-# else
-      /* Extend the stack our own way.  */
-      if (YYMAXDEPTH <= yystacksize)
-       goto yyexhaustedlab;
-      yystacksize *= 2;
-      if (YYMAXDEPTH < yystacksize)
-       yystacksize = YYMAXDEPTH;
-
-      {
-       yytype_int16 *yyss1 = yyss;
-       union yyalloc *yyptr =
-         (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
-       if (! yyptr)
-         goto yyexhaustedlab;
-       YYSTACK_RELOCATE (yyss_alloc, yyss);
-       YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-       YYSTACK_RELOCATE (yyls_alloc, yyls);
-#  undef YYSTACK_RELOCATE
-       if (yyss1 != yyssa)
-         YYSTACK_FREE (yyss1);
-      }
-# endif
-#endif /* no yyoverflow */
-
-      yyssp = yyss + yysize - 1;
-      yyvsp = yyvs + yysize - 1;
-      yylsp = yyls + yysize - 1;
-
-      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-                 (unsigned long int) yystacksize));
-
-      if (yyss + yystacksize - 1 <= yyssp)
-       YYABORT;
-    }
-
-  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
-
-  if (yystate == YYFINAL)
-    YYACCEPT;
-
-  goto yybackup;
-
-/*-----------.
-| yybackup.  |
-`-----------*/
-yybackup:
-
-  /* Do appropriate processing given the current state.  Read a
-     lookahead token if we need one and don't already have one.  */
-
-  /* First try to decide what to do without reference to lookahead token.  */
-  yyn = yypact[yystate];
-  if (yyn == YYPACT_NINF)
-    goto yydefault;
-
-  /* Not known => get a lookahead token if don't already have one.  */
-
-  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
-  if (yychar == YYEMPTY)
-    {
-      YYDPRINTF ((stderr, "Reading a token: "));
-      yychar = YYLEX;
-    }
-
-  if (yychar <= YYEOF)
-    {
-      yychar = yytoken = YYEOF;
-      YYDPRINTF ((stderr, "Now at end of input.\n"));
-    }
-  else
-    {
-      yytoken = YYTRANSLATE (yychar);
-      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
-    }
-
-  /* If the proper action on seeing token YYTOKEN is to reduce or to
-     detect an error, take that action.  */
-  yyn += yytoken;
-  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
-    goto yydefault;
-  yyn = yytable[yyn];
-  if (yyn <= 0)
-    {
-      if (yyn == 0 || yyn == YYTABLE_NINF)
-       goto yyerrlab;
-      yyn = -yyn;
-      goto yyreduce;
-    }
-
-  /* Count tokens shifted since error; after three, turn off error
-     status.  */
-  if (yyerrstatus)
-    yyerrstatus--;
-
-  /* Shift the lookahead token.  */
-  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
-
-  /* Discard the shifted token.  */
-  yychar = YYEMPTY;
-
-  yystate = yyn;
-  *++yyvsp = yylval;
-  *++yylsp = yylloc;
-  goto yynewstate;
-
-
-/*-----------------------------------------------------------.
-| yydefault -- do the default action for the current state.  |
-`-----------------------------------------------------------*/
-yydefault:
-  yyn = yydefact[yystate];
-  if (yyn == 0)
-    goto yyerrlab;
-  goto yyreduce;
-
-
-/*-----------------------------.
-| yyreduce -- Do a reduction.  |
-`-----------------------------*/
-yyreduce:
-  /* yyn is the number of a rule to reduce with.  */
-  yylen = yyr2[yyn];
-
-  /* If YYLEN is nonzero, implement the default value of the action:
-     `$$ = $1'.
-
-     Otherwise, the following line sets YYVAL to garbage.
-     This behavior is undocumented and Bison
-     users should not rely upon it.  Assigning to YYVAL
-     unconditionally makes the parser a bit smaller, and it avoids a
-     GCC warning that YYVAL may be used uninitialized.  */
-  yyval = yyvsp[1-yylen];
-
-  /* Default location.  */
-  YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
-  YY_REDUCE_PRINT (yyn);
-  switch (yyn)
-    {
-        case 3:
-
-/* Line 1455 of yacc.c  */
-#line 282 "program_parse.y"
-    {
-          if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid fragment program header");
-
-          }
-          state->mode = ARB_vertex;
-       ;}
-    break;
-
-  case 4:
-
-/* Line 1455 of yacc.c  */
-#line 290 "program_parse.y"
-    {
-          if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid vertex program header");
-          }
-          state->mode = ARB_fragment;
-
-          state->option.TexRect =
-             (state->ctx->Extensions.NV_texture_rectangle != GL_FALSE);
-       ;}
-    break;
-
-  case 7:
-
-/* Line 1455 of yacc.c  */
-#line 306 "program_parse.y"
-    {
-          int valid = 0;
-
-          if (state->mode == ARB_vertex) {
-             valid = _mesa_ARBvp_parse_option(state, (yyvsp[(2) - (3)].string));
-          } else if (state->mode == ARB_fragment) {
-             valid = _mesa_ARBfp_parse_option(state, (yyvsp[(2) - (3)].string));
-          }
-
-
-          free((yyvsp[(2) - (3)].string));
-
-          if (!valid) {
-             const char *const err_str = (state->mode == ARB_vertex)
-                ? "invalid ARB vertex program option"
-                : "invalid ARB fragment program option";
-
-             yyerror(& (yylsp[(2) - (3)]), state, err_str);
-             YYERROR;
-          }
-       ;}
-    break;
-
-  case 10:
-
-/* Line 1455 of yacc.c  */
-#line 334 "program_parse.y"
-    {
-          if ((yyvsp[(1) - (2)].inst) != NULL) {
-             if (state->inst_tail == NULL) {
-                state->inst_head = (yyvsp[(1) - (2)].inst);
-             } else {
-                state->inst_tail->next = (yyvsp[(1) - (2)].inst);
-             }
-
-             state->inst_tail = (yyvsp[(1) - (2)].inst);
-             (yyvsp[(1) - (2)].inst)->next = NULL;
-
-             state->prog->NumInstructions++;
-          }
-       ;}
-    break;
-
-  case 12:
-
-/* Line 1455 of yacc.c  */
-#line 352 "program_parse.y"
-    {
-          (yyval.inst) = (yyvsp[(1) - (1)].inst);
-          state->prog->NumAluInstructions++;
-       ;}
-    break;
-
-  case 13:
-
-/* Line 1455 of yacc.c  */
-#line 357 "program_parse.y"
-    {
-          (yyval.inst) = (yyvsp[(1) - (1)].inst);
-          state->prog->NumTexInstructions++;
-       ;}
-    break;
-
-  case 24:
-
-/* Line 1455 of yacc.c  */
-#line 378 "program_parse.y"
-    {
-          (yyval.inst) = asm_instruction_ctor(OPCODE_ARL, & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL);
-       ;}
-    break;
-
-  case 25:
-
-/* Line 1455 of yacc.c  */
-#line 384 "program_parse.y"
-    {
-          (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (4)].temp_inst), & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL);
-       ;}
-    break;
-
-  case 26:
-
-/* Line 1455 of yacc.c  */
-#line 390 "program_parse.y"
-    {
-          (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (4)].temp_inst), & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL);
-       ;}
-    break;
-
-  case 27:
-
-/* Line 1455 of yacc.c  */
-#line 396 "program_parse.y"
-    {
-          (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (6)].temp_inst), & (yyvsp[(2) - (6)].dst_reg), & (yyvsp[(4) - (6)].src_reg), & (yyvsp[(6) - (6)].src_reg), NULL);
-       ;}
-    break;
-
-  case 28:
-
-/* Line 1455 of yacc.c  */
-#line 403 "program_parse.y"
-    {
-          (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (6)].temp_inst), & (yyvsp[(2) - (6)].dst_reg), & (yyvsp[(4) - (6)].src_reg), & (yyvsp[(6) - (6)].src_reg), NULL);
-       ;}
-    break;
-
-  case 29:
-
-/* Line 1455 of yacc.c  */
-#line 410 "program_parse.y"
-    {
-          (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (8)].temp_inst), & (yyvsp[(2) - (8)].dst_reg), & (yyvsp[(4) - (8)].src_reg), & (yyvsp[(6) - (8)].src_reg), & (yyvsp[(8) - (8)].src_reg));
-       ;}
-    break;
-
-  case 30:
-
-/* Line 1455 of yacc.c  */
-#line 416 "program_parse.y"
-    {
-          (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (8)].temp_inst), & (yyvsp[(2) - (8)].dst_reg), & (yyvsp[(4) - (8)].src_reg), NULL, NULL);
-          if ((yyval.inst) != NULL) {
-             const GLbitfield tex_mask = (1U << (yyvsp[(6) - (8)].integer));
-             GLbitfield shadow_tex = 0;
-             GLbitfield target_mask = 0;
-
-
-             (yyval.inst)->Base.TexSrcUnit = (yyvsp[(6) - (8)].integer);
-
-             if ((yyvsp[(8) - (8)].integer) < 0) {
-                shadow_tex = tex_mask;
-
-                (yyval.inst)->Base.TexSrcTarget = -(yyvsp[(8) - (8)].integer);
-                (yyval.inst)->Base.TexShadow = 1;
-             } else {
-                (yyval.inst)->Base.TexSrcTarget = (yyvsp[(8) - (8)].integer);
-             }
-
-             target_mask = (1U << (yyval.inst)->Base.TexSrcTarget);
-
-             /* If this texture unit was previously accessed and that access
-              * had a different texture target, generate an error.
-              *
-              * If this texture unit was previously accessed and that access
-              * had a different shadow mode, generate an error.
-              */
-             if ((state->prog->TexturesUsed[(yyvsp[(6) - (8)].integer)] != 0)
-                 && ((state->prog->TexturesUsed[(yyvsp[(6) - (8)].integer)] != target_mask)
-                     || ((state->prog->ShadowSamplers & tex_mask)
-                         != shadow_tex))) {
-                yyerror(& (yylsp[(8) - (8)]), state,
-                        "multiple targets used on one texture image unit");
-                YYERROR;
-             }
-
-
-             state->prog->TexturesUsed[(yyvsp[(6) - (8)].integer)] |= target_mask;
-             state->prog->ShadowSamplers |= shadow_tex;
-          }
-       ;}
-    break;
-
-  case 31:
-
-/* Line 1455 of yacc.c  */
-#line 460 "program_parse.y"
-    {
-          (yyval.inst) = asm_instruction_ctor(OPCODE_KIL, NULL, & (yyvsp[(2) - (2)].src_reg), NULL, NULL);
-          state->fragment.UsesKill = 1;
-       ;}
-    break;
-
-  case 32:
-
-/* Line 1455 of yacc.c  */
-#line 465 "program_parse.y"
-    {
-          (yyval.inst) = asm_instruction_ctor(OPCODE_KIL_NV, NULL, NULL, NULL, NULL);
-          (yyval.inst)->Base.DstReg.CondMask = (yyvsp[(2) - (2)].dst_reg).CondMask;
-          (yyval.inst)->Base.DstReg.CondSwizzle = (yyvsp[(2) - (2)].dst_reg).CondSwizzle;
-          (yyval.inst)->Base.DstReg.CondSrc = (yyvsp[(2) - (2)].dst_reg).CondSrc;
-          state->fragment.UsesKill = 1;
-       ;}
-    break;
-
-  case 33:
-
-/* Line 1455 of yacc.c  */
-#line 475 "program_parse.y"
-    {
-          (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (12)].temp_inst), & (yyvsp[(2) - (12)].dst_reg), & (yyvsp[(4) - (12)].src_reg), & (yyvsp[(6) - (12)].src_reg), & (yyvsp[(8) - (12)].src_reg));
-          if ((yyval.inst) != NULL) {
-             const GLbitfield tex_mask = (1U << (yyvsp[(10) - (12)].integer));
-             GLbitfield shadow_tex = 0;
-             GLbitfield target_mask = 0;
-
-
-             (yyval.inst)->Base.TexSrcUnit = (yyvsp[(10) - (12)].integer);
-
-             if ((yyvsp[(12) - (12)].integer) < 0) {
-                shadow_tex = tex_mask;
-
-                (yyval.inst)->Base.TexSrcTarget = -(yyvsp[(12) - (12)].integer);
-                (yyval.inst)->Base.TexShadow = 1;
-             } else {
-                (yyval.inst)->Base.TexSrcTarget = (yyvsp[(12) - (12)].integer);
-             }
-
-             target_mask = (1U << (yyval.inst)->Base.TexSrcTarget);
-
-             /* If this texture unit was previously accessed and that access
-              * had a different texture target, generate an error.
-              *
-              * If this texture unit was previously accessed and that access
-              * had a different shadow mode, generate an error.
-              */
-             if ((state->prog->TexturesUsed[(yyvsp[(10) - (12)].integer)] != 0)
-                 && ((state->prog->TexturesUsed[(yyvsp[(10) - (12)].integer)] != target_mask)
-                     || ((state->prog->ShadowSamplers & tex_mask)
-                         != shadow_tex))) {
-                yyerror(& (yylsp[(12) - (12)]), state,
-                        "multiple targets used on one texture image unit");
-                YYERROR;
-             }
-
-
-             state->prog->TexturesUsed[(yyvsp[(10) - (12)].integer)] |= target_mask;
-             state->prog->ShadowSamplers |= shadow_tex;
-          }
-       ;}
-    break;
-
-  case 34:
-
-/* Line 1455 of yacc.c  */
-#line 519 "program_parse.y"
-    {
-          (yyval.integer) = (yyvsp[(2) - (2)].integer);
-       ;}
-    break;
-
-  case 35:
-
-/* Line 1455 of yacc.c  */
-#line 524 "program_parse.y"
-    { (yyval.integer) = TEXTURE_1D_INDEX; ;}
-    break;
-
-  case 36:
-
-/* Line 1455 of yacc.c  */
-#line 525 "program_parse.y"
-    { (yyval.integer) = TEXTURE_2D_INDEX; ;}
-    break;
-
-  case 37:
-
-/* Line 1455 of yacc.c  */
-#line 526 "program_parse.y"
-    { (yyval.integer) = TEXTURE_3D_INDEX; ;}
-    break;
-
-  case 38:
-
-/* Line 1455 of yacc.c  */
-#line 527 "program_parse.y"
-    { (yyval.integer) = TEXTURE_CUBE_INDEX; ;}
-    break;
-
-  case 39:
-
-/* Line 1455 of yacc.c  */
-#line 528 "program_parse.y"
-    { (yyval.integer) = TEXTURE_RECT_INDEX; ;}
-    break;
-
-  case 40:
-
-/* Line 1455 of yacc.c  */
-#line 529 "program_parse.y"
-    { (yyval.integer) = -TEXTURE_1D_INDEX; ;}
-    break;
-
-  case 41:
-
-/* Line 1455 of yacc.c  */
-#line 530 "program_parse.y"
-    { (yyval.integer) = -TEXTURE_2D_INDEX; ;}
-    break;
-
-  case 42:
-
-/* Line 1455 of yacc.c  */
-#line 531 "program_parse.y"
-    { (yyval.integer) = -TEXTURE_RECT_INDEX; ;}
-    break;
-
-  case 43:
-
-/* Line 1455 of yacc.c  */
-#line 532 "program_parse.y"
-    { (yyval.integer) = TEXTURE_1D_ARRAY_INDEX; ;}
-    break;
-
-  case 44:
-
-/* Line 1455 of yacc.c  */
-#line 533 "program_parse.y"
-    { (yyval.integer) = TEXTURE_2D_ARRAY_INDEX; ;}
-    break;
-
-  case 45:
-
-/* Line 1455 of yacc.c  */
-#line 534 "program_parse.y"
-    { (yyval.integer) = -TEXTURE_1D_ARRAY_INDEX; ;}
-    break;
-
-  case 46:
-
-/* Line 1455 of yacc.c  */
-#line 535 "program_parse.y"
-    { (yyval.integer) = -TEXTURE_2D_ARRAY_INDEX; ;}
-    break;
-
-  case 47:
-
-/* Line 1455 of yacc.c  */
-#line 539 "program_parse.y"
-    {
-          /* FIXME: Is this correct?  Should the extenedSwizzle be applied
-           * FIXME: to the existing swizzle?
-           */
-          (yyvsp[(4) - (6)].src_reg).Base.Swizzle = (yyvsp[(6) - (6)].swiz_mask).swizzle;
-          (yyvsp[(4) - (6)].src_reg).Base.Negate = (yyvsp[(6) - (6)].swiz_mask).mask;
-
-          (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (6)].temp_inst), & (yyvsp[(2) - (6)].dst_reg), & (yyvsp[(4) - (6)].src_reg), NULL, NULL);
-       ;}
-    break;
-
-  case 48:
-
-/* Line 1455 of yacc.c  */
-#line 551 "program_parse.y"
-    {
-          (yyval.src_reg) = (yyvsp[(2) - (2)].src_reg);
-
-          if ((yyvsp[(1) - (2)].negate)) {
-             (yyval.src_reg).Base.Negate = ~(yyval.src_reg).Base.Negate;
-          }
-       ;}
-    break;
-
-  case 49:
-
-/* Line 1455 of yacc.c  */
-#line 559 "program_parse.y"
-    {
-          (yyval.src_reg) = (yyvsp[(3) - (4)].src_reg);
-
-          if (!state->option.NV_fragment) {
-             yyerror(& (yylsp[(2) - (4)]), state, "unexpected character '|'");
-             YYERROR;
-          }
-
-          if ((yyvsp[(1) - (4)].negate)) {
-             (yyval.src_reg).Base.Negate = ~(yyval.src_reg).Base.Negate;
-          }
-
-          (yyval.src_reg).Base.Abs = 1;
-       ;}
-    break;
-
-  case 50:
-
-/* Line 1455 of yacc.c  */
-#line 576 "program_parse.y"
-    {
-          (yyval.src_reg) = (yyvsp[(1) - (2)].src_reg);
-
-          (yyval.src_reg).Base.Swizzle = _mesa_combine_swizzles((yyval.src_reg).Base.Swizzle,
-                                                   (yyvsp[(2) - (2)].swiz_mask).swizzle);
-       ;}
-    break;
-
-  case 51:
-
-/* Line 1455 of yacc.c  */
-#line 583 "program_parse.y"
-    {
-          struct asm_symbol temp_sym;
-
-          if (!state->option.NV_fragment) {
-             yyerror(& (yylsp[(1) - (1)]), state, "expected scalar suffix");
-             YYERROR;
-          }
-
-          memset(& temp_sym, 0, sizeof(temp_sym));
-          temp_sym.param_binding_begin = ~0;
-          initialize_symbol_from_const(state->prog, & temp_sym, & (yyvsp[(1) - (1)].vector), GL_TRUE);
-
-          set_src_reg_swz(& (yyval.src_reg), PROGRAM_CONSTANT,
-                           temp_sym.param_binding_begin,
-                           temp_sym.param_binding_swizzle);
-       ;}
-    break;
-
-  case 52:
-
-/* Line 1455 of yacc.c  */
-#line 602 "program_parse.y"
-    {
-          (yyval.src_reg) = (yyvsp[(2) - (3)].src_reg);
-
-          if ((yyvsp[(1) - (3)].negate)) {
-             (yyval.src_reg).Base.Negate = ~(yyval.src_reg).Base.Negate;
-          }
-
-          (yyval.src_reg).Base.Swizzle = _mesa_combine_swizzles((yyval.src_reg).Base.Swizzle,
-                                                   (yyvsp[(3) - (3)].swiz_mask).swizzle);
-       ;}
-    break;
-
-  case 53:
-
-/* Line 1455 of yacc.c  */
-#line 613 "program_parse.y"
-    {
-          (yyval.src_reg) = (yyvsp[(3) - (5)].src_reg);
-
-          if (!state->option.NV_fragment) {
-             yyerror(& (yylsp[(2) - (5)]), state, "unexpected character '|'");
-             YYERROR;
-          }
-
-          if ((yyvsp[(1) - (5)].negate)) {
-             (yyval.src_reg).Base.Negate = ~(yyval.src_reg).Base.Negate;
-          }
-
-          (yyval.src_reg).Base.Abs = 1;
-          (yyval.src_reg).Base.Swizzle = _mesa_combine_swizzles((yyval.src_reg).Base.Swizzle,
-                                                   (yyvsp[(4) - (5)].swiz_mask).swizzle);
-       ;}
-    break;
-
-  case 54:
-
-/* Line 1455 of yacc.c  */
-#line 633 "program_parse.y"
-    {
-          (yyval.dst_reg) = (yyvsp[(1) - (3)].dst_reg);
-          (yyval.dst_reg).WriteMask = (yyvsp[(2) - (3)].swiz_mask).mask;
-          (yyval.dst_reg).CondMask = (yyvsp[(3) - (3)].dst_reg).CondMask;
-          (yyval.dst_reg).CondSwizzle = (yyvsp[(3) - (3)].dst_reg).CondSwizzle;
-          (yyval.dst_reg).CondSrc = (yyvsp[(3) - (3)].dst_reg).CondSrc;
-
-          if ((yyval.dst_reg).File == PROGRAM_OUTPUT) {
-             /* Technically speaking, this should check that it is in
-              * vertex program mode.  However, PositionInvariant can never be
-              * set in fragment program mode, so it is somewhat irrelevant.
-              */
-             if (state->option.PositionInvariant
-              && ((yyval.dst_reg).Index == VERT_RESULT_HPOS)) {
-                yyerror(& (yylsp[(1) - (3)]), state, "position-invariant programs cannot "
-                        "write position");
-                YYERROR;
-             }
-
-             state->prog->OutputsWritten |= BITFIELD64_BIT((yyval.dst_reg).Index);
-          }
-       ;}
-    break;
-
-  case 55:
-
-/* Line 1455 of yacc.c  */
-#line 658 "program_parse.y"
-    {
-          set_dst_reg(& (yyval.dst_reg), PROGRAM_ADDRESS, 0);
-          (yyval.dst_reg).WriteMask = (yyvsp[(2) - (2)].swiz_mask).mask;
-       ;}
-    break;
-
-  case 56:
-
-/* Line 1455 of yacc.c  */
-#line 665 "program_parse.y"
-    {
-          const unsigned xyzw_valid =
-             ((yyvsp[(1) - (7)].ext_swizzle).xyzw_valid << 0)
-             | ((yyvsp[(3) - (7)].ext_swizzle).xyzw_valid << 1)
-             | ((yyvsp[(5) - (7)].ext_swizzle).xyzw_valid << 2)
-             | ((yyvsp[(7) - (7)].ext_swizzle).xyzw_valid << 3);
-          const unsigned rgba_valid =
-             ((yyvsp[(1) - (7)].ext_swizzle).rgba_valid << 0)
-             | ((yyvsp[(3) - (7)].ext_swizzle).rgba_valid << 1)
-             | ((yyvsp[(5) - (7)].ext_swizzle).rgba_valid << 2)
-             | ((yyvsp[(7) - (7)].ext_swizzle).rgba_valid << 3);
-
-          /* All of the swizzle components have to be valid in either RGBA
-           * or XYZW.  Note that 0 and 1 are valid in both, so both masks
-           * can have some bits set.
-           *
-           * We somewhat deviate from the spec here.  It would be really hard
-           * to figure out which component is the error, and there probably
-           * isn't a lot of benefit.
-           */
-          if ((rgba_valid != 0x0f) && (xyzw_valid != 0x0f)) {
-             yyerror(& (yylsp[(1) - (7)]), state, "cannot combine RGBA and XYZW swizzle "
-                     "components");
-             YYERROR;
-          }
-
-          (yyval.swiz_mask).swizzle = MAKE_SWIZZLE4((yyvsp[(1) - (7)].ext_swizzle).swz, (yyvsp[(3) - (7)].ext_swizzle).swz, (yyvsp[(5) - (7)].ext_swizzle).swz, (yyvsp[(7) - (7)].ext_swizzle).swz);
-          (yyval.swiz_mask).mask = ((yyvsp[(1) - (7)].ext_swizzle).negate) | ((yyvsp[(3) - (7)].ext_swizzle).negate << 1) | ((yyvsp[(5) - (7)].ext_swizzle).negate << 2)
-             | ((yyvsp[(7) - (7)].ext_swizzle).negate << 3);
-       ;}
-    break;
-
-  case 57:
-
-/* Line 1455 of yacc.c  */
-#line 698 "program_parse.y"
-    {
-          (yyval.ext_swizzle) = (yyvsp[(2) - (2)].ext_swizzle);
-          (yyval.ext_swizzle).negate = ((yyvsp[(1) - (2)].negate)) ? 1 : 0;
-       ;}
-    break;
-
-  case 58:
-
-/* Line 1455 of yacc.c  */
-#line 705 "program_parse.y"
-    {
-          if (((yyvsp[(1) - (1)].integer) != 0) && ((yyvsp[(1) - (1)].integer) != 1)) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid extended swizzle selector");
-             YYERROR;
-          }
-
-          (yyval.ext_swizzle).swz = ((yyvsp[(1) - (1)].integer) == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE;
-
-          /* 0 and 1 are valid for both RGBA swizzle names and XYZW
-           * swizzle names.
-           */
-          (yyval.ext_swizzle).xyzw_valid = 1;
-          (yyval.ext_swizzle).rgba_valid = 1;
-       ;}
-    break;
-
-  case 59:
-
-/* Line 1455 of yacc.c  */
-#line 720 "program_parse.y"
-    {
-          char s;
-
-          if (strlen((yyvsp[(1) - (1)].string)) > 1) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid extended swizzle selector");
-             YYERROR;
-          }
-
-          s = (yyvsp[(1) - (1)].string)[0];
-          free((yyvsp[(1) - (1)].string));
-
-          switch (s) {
-          case 'x':
-             (yyval.ext_swizzle).swz = SWIZZLE_X;
-             (yyval.ext_swizzle).xyzw_valid = 1;
-             break;
-          case 'y':
-             (yyval.ext_swizzle).swz = SWIZZLE_Y;
-             (yyval.ext_swizzle).xyzw_valid = 1;
-             break;
-          case 'z':
-             (yyval.ext_swizzle).swz = SWIZZLE_Z;
-             (yyval.ext_swizzle).xyzw_valid = 1;
-             break;
-          case 'w':
-             (yyval.ext_swizzle).swz = SWIZZLE_W;
-             (yyval.ext_swizzle).xyzw_valid = 1;
-             break;
-
-          case 'r':
-             (yyval.ext_swizzle).swz = SWIZZLE_X;
-             (yyval.ext_swizzle).rgba_valid = 1;
-             break;
-          case 'g':
-             (yyval.ext_swizzle).swz = SWIZZLE_Y;
-             (yyval.ext_swizzle).rgba_valid = 1;
-             break;
-          case 'b':
-             (yyval.ext_swizzle).swz = SWIZZLE_Z;
-             (yyval.ext_swizzle).rgba_valid = 1;
-             break;
-          case 'a':
-             (yyval.ext_swizzle).swz = SWIZZLE_W;
-             (yyval.ext_swizzle).rgba_valid = 1;
-             break;
-
-          default:
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid extended swizzle selector");
-             YYERROR;
-             break;
-          }
-       ;}
-    break;
-
-  case 60:
-
-/* Line 1455 of yacc.c  */
-#line 775 "program_parse.y"
-    {
-          struct asm_symbol *const s = (struct asm_symbol *)
-             _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
-
-          free((yyvsp[(1) - (1)].string));
-
-          if (s == NULL) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
-             YYERROR;
-          } else if ((s->type != at_param) && (s->type != at_temp)
-                     && (s->type != at_attrib)) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
-             YYERROR;
-          } else if ((s->type == at_param) && s->param_is_array) {
-             yyerror(& (yylsp[(1) - (1)]), state, "non-array access to array PARAM");
-             YYERROR;
-          }
-
-          init_src_reg(& (yyval.src_reg));
-          switch (s->type) {
-          case at_temp:
-             set_src_reg(& (yyval.src_reg), PROGRAM_TEMPORARY, s->temp_binding);
-             break;
-          case at_param:
-              set_src_reg_swz(& (yyval.src_reg), s->param_binding_type,
-                              s->param_binding_begin,
-                              s->param_binding_swizzle);
-             break;
-          case at_attrib:
-             set_src_reg(& (yyval.src_reg), PROGRAM_INPUT, s->attrib_binding);
-             state->prog->InputsRead |= (1U << (yyval.src_reg).Base.Index);
-
-             if (!validate_inputs(& (yylsp[(1) - (1)]), state)) {
-                YYERROR;
-             }
-             break;
-
-          default:
-             YYERROR;
-             break;
-          }
-       ;}
-    break;
-
-  case 61:
-
-/* Line 1455 of yacc.c  */
-#line 818 "program_parse.y"
-    {
-          set_src_reg(& (yyval.src_reg), PROGRAM_INPUT, (yyvsp[(1) - (1)].attrib));
-          state->prog->InputsRead |= (1U << (yyval.src_reg).Base.Index);
-
-          if (!validate_inputs(& (yylsp[(1) - (1)]), state)) {
-             YYERROR;
-          }
-       ;}
-    break;
-
-  case 62:
-
-/* Line 1455 of yacc.c  */
-#line 827 "program_parse.y"
-    {
-          if (! (yyvsp[(3) - (4)].src_reg).Base.RelAddr
-              && ((unsigned) (yyvsp[(3) - (4)].src_reg).Base.Index >= (yyvsp[(1) - (4)].sym)->param_binding_length)) {
-             yyerror(& (yylsp[(3) - (4)]), state, "out of bounds array access");
-             YYERROR;
-          }
-
-          init_src_reg(& (yyval.src_reg));
-          (yyval.src_reg).Base.File = (yyvsp[(1) - (4)].sym)->param_binding_type;
-
-          if ((yyvsp[(3) - (4)].src_reg).Base.RelAddr) {
-             (yyvsp[(1) - (4)].sym)->param_accessed_indirectly = 1;
-
-             (yyval.src_reg).Base.RelAddr = 1;
-             (yyval.src_reg).Base.Index = (yyvsp[(3) - (4)].src_reg).Base.Index;
-             (yyval.src_reg).Symbol = (yyvsp[(1) - (4)].sym);
-          } else {
-             (yyval.src_reg).Base.Index = (yyvsp[(1) - (4)].sym)->param_binding_begin + (yyvsp[(3) - (4)].src_reg).Base.Index;
-          }
-       ;}
-    break;
-
-  case 63:
-
-/* Line 1455 of yacc.c  */
-#line 848 "program_parse.y"
-    {
-           gl_register_file file = ((yyvsp[(1) - (1)].temp_sym).name != NULL) 
-             ? (yyvsp[(1) - (1)].temp_sym).param_binding_type
-             : PROGRAM_CONSTANT;
-           set_src_reg_swz(& (yyval.src_reg), file, (yyvsp[(1) - (1)].temp_sym).param_binding_begin,
-                           (yyvsp[(1) - (1)].temp_sym).param_binding_swizzle);
-       ;}
-    break;
-
-  case 64:
-
-/* Line 1455 of yacc.c  */
-#line 858 "program_parse.y"
-    {
-          set_dst_reg(& (yyval.dst_reg), PROGRAM_OUTPUT, (yyvsp[(1) - (1)].result));
-       ;}
-    break;
-
-  case 65:
-
-/* Line 1455 of yacc.c  */
-#line 862 "program_parse.y"
-    {
-          struct asm_symbol *const s = (struct asm_symbol *)
-             _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
-
-          free((yyvsp[(1) - (1)].string));
-
-          if (s == NULL) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
-             YYERROR;
-          } else if ((s->type != at_output) && (s->type != at_temp)) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
-             YYERROR;
-          }
-
-          switch (s->type) {
-          case at_temp:
-             set_dst_reg(& (yyval.dst_reg), PROGRAM_TEMPORARY, s->temp_binding);
-             break;
-          case at_output:
-             set_dst_reg(& (yyval.dst_reg), PROGRAM_OUTPUT, s->output_binding);
-             break;
-          default:
-             set_dst_reg(& (yyval.dst_reg), s->param_binding_type, s->param_binding_begin);
-             break;
-          }
-       ;}
-    break;
-
-  case 66:
-
-/* Line 1455 of yacc.c  */
-#line 891 "program_parse.y"
-    {
-          struct asm_symbol *const s = (struct asm_symbol *)
-             _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
-
-          free((yyvsp[(1) - (1)].string));
-
-          if (s == NULL) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
-             YYERROR;
-          } else if ((s->type != at_param) || !s->param_is_array) {
-             yyerror(& (yylsp[(1) - (1)]), state, "array access to non-PARAM variable");
-             YYERROR;
-          } else {
-             (yyval.sym) = s;
-          }
-       ;}
-    break;
-
-  case 69:
-
-/* Line 1455 of yacc.c  */
-#line 912 "program_parse.y"
-    {
-          init_src_reg(& (yyval.src_reg));
-          (yyval.src_reg).Base.Index = (yyvsp[(1) - (1)].integer);
-       ;}
-    break;
-
-  case 70:
-
-/* Line 1455 of yacc.c  */
-#line 919 "program_parse.y"
-    {
-          /* FINISHME: Add support for multiple address registers.
-           */
-          /* FINISHME: Add support for 4-component address registers.
-           */
-          init_src_reg(& (yyval.src_reg));
-          (yyval.src_reg).Base.RelAddr = 1;
-          (yyval.src_reg).Base.Index = (yyvsp[(3) - (3)].integer);
-       ;}
-    break;
-
-  case 71:
-
-/* Line 1455 of yacc.c  */
-#line 930 "program_parse.y"
-    { (yyval.integer) = 0; ;}
-    break;
-
-  case 72:
-
-/* Line 1455 of yacc.c  */
-#line 931 "program_parse.y"
-    { (yyval.integer) = (yyvsp[(2) - (2)].integer); ;}
-    break;
-
-  case 73:
-
-/* Line 1455 of yacc.c  */
-#line 932 "program_parse.y"
-    { (yyval.integer) = -(yyvsp[(2) - (2)].integer); ;}
-    break;
-
-  case 74:
-
-/* Line 1455 of yacc.c  */
-#line 936 "program_parse.y"
-    {
-          if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > 63)) {
-              char s[100];
-              _mesa_snprintf(s, sizeof(s),
-                             "relative address offset too large (%d)", (yyvsp[(1) - (1)].integer));
-             yyerror(& (yylsp[(1) - (1)]), state, s);
-             YYERROR;
-          } else {
-             (yyval.integer) = (yyvsp[(1) - (1)].integer);
-          }
-       ;}
-    break;
-
-  case 75:
-
-/* Line 1455 of yacc.c  */
-#line 950 "program_parse.y"
-    {
-          if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > 64)) {
-              char s[100];
-              _mesa_snprintf(s, sizeof(s),
-                             "relative address offset too large (%d)", (yyvsp[(1) - (1)].integer));
-             yyerror(& (yylsp[(1) - (1)]), state, s);
-             YYERROR;
-          } else {
-             (yyval.integer) = (yyvsp[(1) - (1)].integer);
-          }
-       ;}
-    break;
-
-  case 76:
-
-/* Line 1455 of yacc.c  */
-#line 964 "program_parse.y"
-    {
-          struct asm_symbol *const s = (struct asm_symbol *)
-             _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
-
-          free((yyvsp[(1) - (1)].string));
-
-          if (s == NULL) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid array member");
-             YYERROR;
-          } else if (s->type != at_address) {
-             yyerror(& (yylsp[(1) - (1)]), state,
-                     "invalid variable for indexed array access");
-             YYERROR;
-          } else {
-             (yyval.sym) = s;
-          }
-       ;}
-    break;
-
-  case 77:
-
-/* Line 1455 of yacc.c  */
-#line 984 "program_parse.y"
-    {
-          if ((yyvsp[(1) - (1)].swiz_mask).mask != WRITEMASK_X) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid address component selector");
-             YYERROR;
-          } else {
-             (yyval.swiz_mask) = (yyvsp[(1) - (1)].swiz_mask);
-          }
-       ;}
-    break;
-
-  case 78:
-
-/* Line 1455 of yacc.c  */
-#line 995 "program_parse.y"
-    {
-          if ((yyvsp[(1) - (1)].swiz_mask).mask != WRITEMASK_X) {
-             yyerror(& (yylsp[(1) - (1)]), state,
-                     "address register write mask must be \".x\"");
-             YYERROR;
-          } else {
-             (yyval.swiz_mask) = (yyvsp[(1) - (1)].swiz_mask);
-          }
-       ;}
-    break;
-
-  case 83:
-
-/* Line 1455 of yacc.c  */
-#line 1011 "program_parse.y"
-    { (yyval.swiz_mask).swizzle = SWIZZLE_NOOP; (yyval.swiz_mask).mask = WRITEMASK_XYZW; ;}
-    break;
-
-  case 88:
-
-/* Line 1455 of yacc.c  */
-#line 1015 "program_parse.y"
-    { (yyval.swiz_mask).swizzle = SWIZZLE_NOOP; (yyval.swiz_mask).mask = WRITEMASK_XYZW; ;}
-    break;
-
-  case 89:
-
-/* Line 1455 of yacc.c  */
-#line 1019 "program_parse.y"
-    {
-          (yyval.dst_reg) = (yyvsp[(2) - (3)].dst_reg);
-       ;}
-    break;
-
-  case 90:
-
-/* Line 1455 of yacc.c  */
-#line 1023 "program_parse.y"
-    {
-          (yyval.dst_reg) = (yyvsp[(2) - (3)].dst_reg);
-       ;}
-    break;
-
-  case 91:
-
-/* Line 1455 of yacc.c  */
-#line 1027 "program_parse.y"
-    {
-          (yyval.dst_reg).CondMask = COND_TR;
-          (yyval.dst_reg).CondSwizzle = SWIZZLE_NOOP;
-          (yyval.dst_reg).CondSrc = 0;
-       ;}
-    break;
-
-  case 92:
-
-/* Line 1455 of yacc.c  */
-#line 1035 "program_parse.y"
-    {
-          (yyval.dst_reg) = (yyvsp[(1) - (2)].dst_reg);
-          (yyval.dst_reg).CondSwizzle = (yyvsp[(2) - (2)].swiz_mask).swizzle;
-       ;}
-    break;
-
-  case 93:
-
-/* Line 1455 of yacc.c  */
-#line 1042 "program_parse.y"
-    {
-          (yyval.dst_reg) = (yyvsp[(1) - (2)].dst_reg);
-          (yyval.dst_reg).CondSwizzle = (yyvsp[(2) - (2)].swiz_mask).swizzle;
-       ;}
-    break;
-
-  case 94:
-
-/* Line 1455 of yacc.c  */
-#line 1049 "program_parse.y"
-    {
-          const int cond = _mesa_parse_cc((yyvsp[(1) - (1)].string));
-          if ((cond == 0) || ((yyvsp[(1) - (1)].string)[2] != '\0')) {
-             char *const err_str =
-                make_error_string("invalid condition code \"%s\"", (yyvsp[(1) - (1)].string));
-
-             yyerror(& (yylsp[(1) - (1)]), state, (err_str != NULL)
-                     ? err_str : "invalid condition code");
-
-             if (err_str != NULL) {
-                free(err_str);
-             }
-
-             YYERROR;
-          }
-
-          (yyval.dst_reg).CondMask = cond;
-          (yyval.dst_reg).CondSwizzle = SWIZZLE_NOOP;
-          (yyval.dst_reg).CondSrc = 0;
-       ;}
-    break;
-
-  case 95:
-
-/* Line 1455 of yacc.c  */
-#line 1072 "program_parse.y"
-    {
-          const int cond = _mesa_parse_cc((yyvsp[(1) - (1)].string));
-          if ((cond == 0) || ((yyvsp[(1) - (1)].string)[2] != '\0')) {
-             char *const err_str =
-                make_error_string("invalid condition code \"%s\"", (yyvsp[(1) - (1)].string));
-
-             yyerror(& (yylsp[(1) - (1)]), state, (err_str != NULL)
-                     ? err_str : "invalid condition code");
-
-             if (err_str != NULL) {
-                free(err_str);
-             }
-
-             YYERROR;
-          }
-
-          (yyval.dst_reg).CondMask = cond;
-          (yyval.dst_reg).CondSwizzle = SWIZZLE_NOOP;
-          (yyval.dst_reg).CondSrc = 0;
-       ;}
-    break;
-
-  case 102:
-
-/* Line 1455 of yacc.c  */
-#line 1103 "program_parse.y"
-    {
-          struct asm_symbol *const s =
-             declare_variable(state, (yyvsp[(2) - (4)].string), at_attrib, & (yylsp[(2) - (4)]));
-
-          if (s == NULL) {
-             free((yyvsp[(2) - (4)].string));
-             YYERROR;
-          } else {
-             s->attrib_binding = (yyvsp[(4) - (4)].attrib);
-             state->InputsBound |= (1U << s->attrib_binding);
-
-             if (!validate_inputs(& (yylsp[(4) - (4)]), state)) {
-                YYERROR;
-             }
-          }
-       ;}
-    break;
-
-  case 103:
-
-/* Line 1455 of yacc.c  */
-#line 1122 "program_parse.y"
-    {
-          (yyval.attrib) = (yyvsp[(2) - (2)].attrib);
-       ;}
-    break;
-
-  case 104:
-
-/* Line 1455 of yacc.c  */
-#line 1126 "program_parse.y"
-    {
-          (yyval.attrib) = (yyvsp[(2) - (2)].attrib);
-       ;}
-    break;
-
-  case 105:
-
-/* Line 1455 of yacc.c  */
-#line 1132 "program_parse.y"
-    {
-          (yyval.attrib) = VERT_ATTRIB_POS;
-       ;}
-    break;
-
-  case 106:
-
-/* Line 1455 of yacc.c  */
-#line 1136 "program_parse.y"
-    {
-          (yyval.attrib) = VERT_ATTRIB_WEIGHT;
-       ;}
-    break;
-
-  case 107:
-
-/* Line 1455 of yacc.c  */
-#line 1140 "program_parse.y"
-    {
-          (yyval.attrib) = VERT_ATTRIB_NORMAL;
-       ;}
-    break;
-
-  case 108:
-
-/* Line 1455 of yacc.c  */
-#line 1144 "program_parse.y"
-    {
-          if (!state->ctx->Extensions.EXT_secondary_color) {
-             yyerror(& (yylsp[(2) - (2)]), state, "GL_EXT_secondary_color not supported");
-             YYERROR;
-          }
-
-          (yyval.attrib) = VERT_ATTRIB_COLOR0 + (yyvsp[(2) - (2)].integer);
-       ;}
-    break;
-
-  case 109:
-
-/* Line 1455 of yacc.c  */
-#line 1153 "program_parse.y"
-    {
-          if (!state->ctx->Extensions.EXT_fog_coord) {
-             yyerror(& (yylsp[(1) - (1)]), state, "GL_EXT_fog_coord not supported");
-             YYERROR;
-          }
-
-          (yyval.attrib) = VERT_ATTRIB_FOG;
-       ;}
-    break;
-
-  case 110:
-
-/* Line 1455 of yacc.c  */
-#line 1162 "program_parse.y"
-    {
-          (yyval.attrib) = VERT_ATTRIB_TEX0 + (yyvsp[(2) - (2)].integer);
-       ;}
-    break;
-
-  case 111:
-
-/* Line 1455 of yacc.c  */
-#line 1166 "program_parse.y"
-    {
-          yyerror(& (yylsp[(1) - (4)]), state, "GL_ARB_matrix_palette not supported");
-          YYERROR;
-       ;}
-    break;
-
-  case 112:
-
-/* Line 1455 of yacc.c  */
-#line 1171 "program_parse.y"
-    {
-          (yyval.attrib) = VERT_ATTRIB_GENERIC0 + (yyvsp[(3) - (4)].integer);
-       ;}
-    break;
-
-  case 113:
-
-/* Line 1455 of yacc.c  */
-#line 1177 "program_parse.y"
-    {
-          if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxAttribs) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid vertex attribute reference");
-             YYERROR;
-          }
-
-          (yyval.integer) = (yyvsp[(1) - (1)].integer);
-       ;}
-    break;
-
-  case 117:
-
-/* Line 1455 of yacc.c  */
-#line 1191 "program_parse.y"
-    {
-          (yyval.attrib) = FRAG_ATTRIB_WPOS;
-       ;}
-    break;
-
-  case 118:
-
-/* Line 1455 of yacc.c  */
-#line 1195 "program_parse.y"
-    {
-          (yyval.attrib) = FRAG_ATTRIB_COL0 + (yyvsp[(2) - (2)].integer);
-       ;}
-    break;
-
-  case 119:
-
-/* Line 1455 of yacc.c  */
-#line 1199 "program_parse.y"
-    {
-          (yyval.attrib) = FRAG_ATTRIB_FOGC;
-       ;}
-    break;
-
-  case 120:
-
-/* Line 1455 of yacc.c  */
-#line 1203 "program_parse.y"
-    {
-          (yyval.attrib) = FRAG_ATTRIB_TEX0 + (yyvsp[(2) - (2)].integer);
-       ;}
-    break;
-
-  case 123:
-
-/* Line 1455 of yacc.c  */
-#line 1211 "program_parse.y"
-    {
-          struct asm_symbol *const s =
-             declare_variable(state, (yyvsp[(2) - (3)].string), at_param, & (yylsp[(2) - (3)]));
-
-          if (s == NULL) {
-             free((yyvsp[(2) - (3)].string));
-             YYERROR;
-          } else {
-             s->param_binding_type = (yyvsp[(3) - (3)].temp_sym).param_binding_type;
-             s->param_binding_begin = (yyvsp[(3) - (3)].temp_sym).param_binding_begin;
-             s->param_binding_length = (yyvsp[(3) - (3)].temp_sym).param_binding_length;
-              s->param_binding_swizzle = (yyvsp[(3) - (3)].temp_sym).param_binding_swizzle;
-             s->param_is_array = 0;
-          }
-       ;}
-    break;
-
-  case 124:
-
-/* Line 1455 of yacc.c  */
-#line 1229 "program_parse.y"
-    {
-          if (((yyvsp[(4) - (6)].integer) != 0) && ((unsigned) (yyvsp[(4) - (6)].integer) != (yyvsp[(6) - (6)].temp_sym).param_binding_length)) {
-             free((yyvsp[(2) - (6)].string));
-             yyerror(& (yylsp[(4) - (6)]), state, 
-                     "parameter array size and number of bindings must match");
-             YYERROR;
-          } else {
-             struct asm_symbol *const s =
-                declare_variable(state, (yyvsp[(2) - (6)].string), (yyvsp[(6) - (6)].temp_sym).type, & (yylsp[(2) - (6)]));
-
-             if (s == NULL) {
-                free((yyvsp[(2) - (6)].string));
-                YYERROR;
-             } else {
-                s->param_binding_type = (yyvsp[(6) - (6)].temp_sym).param_binding_type;
-                s->param_binding_begin = (yyvsp[(6) - (6)].temp_sym).param_binding_begin;
-                s->param_binding_length = (yyvsp[(6) - (6)].temp_sym).param_binding_length;
-                 s->param_binding_swizzle = SWIZZLE_XYZW;
-                s->param_is_array = 1;
-             }
-          }
-       ;}
-    break;
-
-  case 125:
-
-/* Line 1455 of yacc.c  */
-#line 1254 "program_parse.y"
-    {
-          (yyval.integer) = 0;
-       ;}
-    break;
-
-  case 126:
-
-/* Line 1455 of yacc.c  */
-#line 1258 "program_parse.y"
-    {
-          if (((yyvsp[(1) - (1)].integer) < 1) || ((unsigned) (yyvsp[(1) - (1)].integer) > state->limits->MaxParameters)) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid parameter array size");
-             YYERROR;
-          } else {
-             (yyval.integer) = (yyvsp[(1) - (1)].integer);
-          }
-       ;}
-    break;
-
-  case 127:
-
-/* Line 1455 of yacc.c  */
-#line 1269 "program_parse.y"
-    {
-          (yyval.temp_sym) = (yyvsp[(2) - (2)].temp_sym);
-       ;}
-    break;
-
-  case 128:
-
-/* Line 1455 of yacc.c  */
-#line 1275 "program_parse.y"
-    {
-          (yyval.temp_sym) = (yyvsp[(3) - (4)].temp_sym);
-       ;}
-    break;
-
-  case 130:
-
-/* Line 1455 of yacc.c  */
-#line 1282 "program_parse.y"
-    {
-          (yyvsp[(1) - (3)].temp_sym).param_binding_length += (yyvsp[(3) - (3)].temp_sym).param_binding_length;
-          (yyval.temp_sym) = (yyvsp[(1) - (3)].temp_sym);
-       ;}
-    break;
-
-  case 131:
-
-/* Line 1455 of yacc.c  */
-#line 1289 "program_parse.y"
-    {
-          memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
-          (yyval.temp_sym).param_binding_begin = ~0;
-          initialize_symbol_from_state(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
-       ;}
-    break;
-
-  case 132:
-
-/* Line 1455 of yacc.c  */
-#line 1295 "program_parse.y"
-    {
-          memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
-          (yyval.temp_sym).param_binding_begin = ~0;
-          initialize_symbol_from_param(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
-       ;}
-    break;
-
-  case 133:
-
-/* Line 1455 of yacc.c  */
-#line 1301 "program_parse.y"
-    {
-          memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
-          (yyval.temp_sym).param_binding_begin = ~0;
-          initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector), GL_TRUE);
-       ;}
-    break;
-
-  case 134:
-
-/* Line 1455 of yacc.c  */
-#line 1309 "program_parse.y"
-    {
-          memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
-          (yyval.temp_sym).param_binding_begin = ~0;
-          initialize_symbol_from_state(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
-       ;}
-    break;
-
-  case 135:
-
-/* Line 1455 of yacc.c  */
-#line 1315 "program_parse.y"
-    {
-          memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
-          (yyval.temp_sym).param_binding_begin = ~0;
-          initialize_symbol_from_param(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
-       ;}
-    break;
-
-  case 136:
-
-/* Line 1455 of yacc.c  */
-#line 1321 "program_parse.y"
-    {
-          memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
-          (yyval.temp_sym).param_binding_begin = ~0;
-          initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector), GL_TRUE);
-       ;}
-    break;
-
-  case 137:
-
-/* Line 1455 of yacc.c  */
-#line 1329 "program_parse.y"
-    {
-          memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
-          (yyval.temp_sym).param_binding_begin = ~0;
-          initialize_symbol_from_state(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
-       ;}
-    break;
-
-  case 138:
-
-/* Line 1455 of yacc.c  */
-#line 1335 "program_parse.y"
-    {
-          memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
-          (yyval.temp_sym).param_binding_begin = ~0;
-          initialize_symbol_from_param(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
-       ;}
-    break;
-
-  case 139:
-
-/* Line 1455 of yacc.c  */
-#line 1341 "program_parse.y"
-    {
-          memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
-          (yyval.temp_sym).param_binding_begin = ~0;
-          initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector), GL_FALSE);
-       ;}
-    break;
-
-  case 140:
-
-/* Line 1455 of yacc.c  */
-#line 1348 "program_parse.y"
-    { memcpy((yyval.state), (yyvsp[(1) - (1)].state), sizeof((yyval.state))); ;}
-    break;
-
-  case 141:
-
-/* Line 1455 of yacc.c  */
-#line 1349 "program_parse.y"
-    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
-    break;
-
-  case 142:
-
-/* Line 1455 of yacc.c  */
-#line 1352 "program_parse.y"
-    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
-    break;
-
-  case 143:
-
-/* Line 1455 of yacc.c  */
-#line 1353 "program_parse.y"
-    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
-    break;
-
-  case 144:
-
-/* Line 1455 of yacc.c  */
-#line 1354 "program_parse.y"
-    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
-    break;
-
-  case 145:
-
-/* Line 1455 of yacc.c  */
-#line 1355 "program_parse.y"
-    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
-    break;
-
-  case 146:
-
-/* Line 1455 of yacc.c  */
-#line 1356 "program_parse.y"
-    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
-    break;
-
-  case 147:
-
-/* Line 1455 of yacc.c  */
-#line 1357 "program_parse.y"
-    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
-    break;
-
-  case 148:
-
-/* Line 1455 of yacc.c  */
-#line 1358 "program_parse.y"
-    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
-    break;
-
-  case 149:
-
-/* Line 1455 of yacc.c  */
-#line 1359 "program_parse.y"
-    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
-    break;
-
-  case 150:
-
-/* Line 1455 of yacc.c  */
-#line 1360 "program_parse.y"
-    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
-    break;
-
-  case 151:
-
-/* Line 1455 of yacc.c  */
-#line 1361 "program_parse.y"
-    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
-    break;
-
-  case 152:
-
-/* Line 1455 of yacc.c  */
-#line 1362 "program_parse.y"
-    { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
-    break;
-
-  case 153:
-
-/* Line 1455 of yacc.c  */
-#line 1366 "program_parse.y"
-    {
-          memset((yyval.state), 0, sizeof((yyval.state)));
-          (yyval.state)[0] = STATE_MATERIAL;
-          (yyval.state)[1] = (yyvsp[(2) - (3)].integer);
-          (yyval.state)[2] = (yyvsp[(3) - (3)].integer);
-       ;}
-    break;
-
-  case 154:
-
-/* Line 1455 of yacc.c  */
-#line 1375 "program_parse.y"
-    {
-          (yyval.integer) = (yyvsp[(1) - (1)].integer);
-       ;}
-    break;
-
-  case 155:
-
-/* Line 1455 of yacc.c  */
-#line 1379 "program_parse.y"
-    {
-          (yyval.integer) = STATE_EMISSION;
-       ;}
-    break;
-
-  case 156:
-
-/* Line 1455 of yacc.c  */
-#line 1383 "program_parse.y"
-    {
-          (yyval.integer) = STATE_SHININESS;
-       ;}
-    break;
-
-  case 157:
-
-/* Line 1455 of yacc.c  */
-#line 1389 "program_parse.y"
-    {
-          memset((yyval.state), 0, sizeof((yyval.state)));
-          (yyval.state)[0] = STATE_LIGHT;
-          (yyval.state)[1] = (yyvsp[(3) - (5)].integer);
-          (yyval.state)[2] = (yyvsp[(5) - (5)].integer);
-       ;}
-    break;
-
-  case 158:
-
-/* Line 1455 of yacc.c  */
-#line 1398 "program_parse.y"
-    {
-          (yyval.integer) = (yyvsp[(1) - (1)].integer);
-       ;}
-    break;
-
-  case 159:
-
-/* Line 1455 of yacc.c  */
-#line 1402 "program_parse.y"
-    {
-          (yyval.integer) = STATE_POSITION;
-       ;}
-    break;
-
-  case 160:
-
-/* Line 1455 of yacc.c  */
-#line 1406 "program_parse.y"
-    {
-          if (!state->ctx->Extensions.EXT_point_parameters) {
-             yyerror(& (yylsp[(1) - (1)]), state, "GL_ARB_point_parameters not supported");
-             YYERROR;
-          }
-
-          (yyval.integer) = STATE_ATTENUATION;
-       ;}
-    break;
-
-  case 161:
-
-/* Line 1455 of yacc.c  */
-#line 1415 "program_parse.y"
-    {
-          (yyval.integer) = (yyvsp[(2) - (2)].integer);
-       ;}
-    break;
-
-  case 162:
-
-/* Line 1455 of yacc.c  */
-#line 1419 "program_parse.y"
-    {
-          (yyval.integer) = STATE_HALF_VECTOR;
-       ;}
-    break;
-
-  case 163:
-
-/* Line 1455 of yacc.c  */
-#line 1425 "program_parse.y"
-    {
-          (yyval.integer) = STATE_SPOT_DIRECTION;
-       ;}
-    break;
-
-  case 164:
-
-/* Line 1455 of yacc.c  */
-#line 1431 "program_parse.y"
-    {
-          (yyval.state)[0] = (yyvsp[(2) - (2)].state)[0];
-          (yyval.state)[1] = (yyvsp[(2) - (2)].state)[1];
-       ;}
-    break;
-
-  case 165:
-
-/* Line 1455 of yacc.c  */
-#line 1438 "program_parse.y"
-    {
-          memset((yyval.state), 0, sizeof((yyval.state)));
-          (yyval.state)[0] = STATE_LIGHTMODEL_AMBIENT;
-       ;}
-    break;
-
-  case 166:
-
-/* Line 1455 of yacc.c  */
-#line 1443 "program_parse.y"
-    {
-          memset((yyval.state), 0, sizeof((yyval.state)));
-          (yyval.state)[0] = STATE_LIGHTMODEL_SCENECOLOR;
-          (yyval.state)[1] = (yyvsp[(1) - (2)].integer);
-       ;}
-    break;
-
-  case 167:
-
-/* Line 1455 of yacc.c  */
-#line 1451 "program_parse.y"
-    {
-          memset((yyval.state), 0, sizeof((yyval.state)));
-          (yyval.state)[0] = STATE_LIGHTPROD;
-          (yyval.state)[1] = (yyvsp[(3) - (6)].integer);
-          (yyval.state)[2] = (yyvsp[(5) - (6)].integer);
-          (yyval.state)[3] = (yyvsp[(6) - (6)].integer);
-       ;}
-    break;
-
-  case 169:
-
-/* Line 1455 of yacc.c  */
-#line 1463 "program_parse.y"
-    {
-          memset((yyval.state), 0, sizeof((yyval.state)));
-          (yyval.state)[0] = (yyvsp[(3) - (3)].integer);
-          (yyval.state)[1] = (yyvsp[(2) - (3)].integer);
-       ;}
-    break;
-
-  case 170:
-
-/* Line 1455 of yacc.c  */
-#line 1471 "program_parse.y"
-    {
-          (yyval.integer) = STATE_TEXENV_COLOR;
-       ;}
-    break;
-
-  case 171:
-
-/* Line 1455 of yacc.c  */
-#line 1477 "program_parse.y"
-    {
-          (yyval.integer) = STATE_AMBIENT;
-       ;}
-    break;
-
-  case 172:
-
-/* Line 1455 of yacc.c  */
-#line 1481 "program_parse.y"
-    {
-          (yyval.integer) = STATE_DIFFUSE;
-       ;}
-    break;
-
-  case 173:
-
-/* Line 1455 of yacc.c  */
-#line 1485 "program_parse.y"
-    {
-          (yyval.integer) = STATE_SPECULAR;
-       ;}
-    break;
-
-  case 174:
-
-/* Line 1455 of yacc.c  */
-#line 1491 "program_parse.y"
-    {
-          if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxLights) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid light selector");
-             YYERROR;
-          }
-
-          (yyval.integer) = (yyvsp[(1) - (1)].integer);
-       ;}
-    break;
-
-  case 175:
-
-/* Line 1455 of yacc.c  */
-#line 1502 "program_parse.y"
-    {
-          memset((yyval.state), 0, sizeof((yyval.state)));
-          (yyval.state)[0] = STATE_TEXGEN;
-          (yyval.state)[1] = (yyvsp[(2) - (4)].integer);
-          (yyval.state)[2] = (yyvsp[(3) - (4)].integer) + (yyvsp[(4) - (4)].integer);
-       ;}
-    break;
-
-  case 176:
-
-/* Line 1455 of yacc.c  */
-#line 1511 "program_parse.y"
-    {
-          (yyval.integer) = STATE_TEXGEN_EYE_S;
-       ;}
-    break;
-
-  case 177:
-
-/* Line 1455 of yacc.c  */
-#line 1515 "program_parse.y"
-    {
-          (yyval.integer) = STATE_TEXGEN_OBJECT_S;
-       ;}
-    break;
-
-  case 178:
-
-/* Line 1455 of yacc.c  */
-#line 1520 "program_parse.y"
-    {
-          (yyval.integer) = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S;
-       ;}
-    break;
-
-  case 179:
-
-/* Line 1455 of yacc.c  */
-#line 1524 "program_parse.y"
-    {
-          (yyval.integer) = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S;
-       ;}
-    break;
-
-  case 180:
-
-/* Line 1455 of yacc.c  */
-#line 1528 "program_parse.y"
-    {
-          (yyval.integer) = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S;
-       ;}
-    break;
-
-  case 181:
-
-/* Line 1455 of yacc.c  */
-#line 1532 "program_parse.y"
-    {
-          (yyval.integer) = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S;
-       ;}
-    break;
-
-  case 182:
-
-/* Line 1455 of yacc.c  */
-#line 1538 "program_parse.y"
-    {
-          memset((yyval.state), 0, sizeof((yyval.state)));
-          (yyval.state)[0] = (yyvsp[(2) - (2)].integer);
-       ;}
-    break;
-
-  case 183:
-
-/* Line 1455 of yacc.c  */
-#line 1545 "program_parse.y"
-    {
-          (yyval.integer) = STATE_FOG_COLOR;
-       ;}
-    break;
-
-  case 184:
-
-/* Line 1455 of yacc.c  */
-#line 1549 "program_parse.y"
-    {
-          (yyval.integer) = STATE_FOG_PARAMS;
-       ;}
-    break;
-
-  case 185:
-
-/* Line 1455 of yacc.c  */
-#line 1555 "program_parse.y"
-    {
-          memset((yyval.state), 0, sizeof((yyval.state)));
-          (yyval.state)[0] = STATE_CLIPPLANE;
-          (yyval.state)[1] = (yyvsp[(3) - (5)].integer);
-       ;}
-    break;
-
-  case 186:
-
-/* Line 1455 of yacc.c  */
-#line 1563 "program_parse.y"
-    {
-          if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxClipPlanes) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid clip plane selector");
-             YYERROR;
-          }
-
-          (yyval.integer) = (yyvsp[(1) - (1)].integer);
-       ;}
-    break;
-
-  case 187:
-
-/* Line 1455 of yacc.c  */
-#line 1574 "program_parse.y"
-    {
-          memset((yyval.state), 0, sizeof((yyval.state)));
-          (yyval.state)[0] = (yyvsp[(2) - (2)].integer);
-       ;}
-    break;
-
-  case 188:
-
-/* Line 1455 of yacc.c  */
-#line 1581 "program_parse.y"
-    {
-          (yyval.integer) = STATE_POINT_SIZE;
-       ;}
-    break;
-
-  case 189:
-
-/* Line 1455 of yacc.c  */
-#line 1585 "program_parse.y"
-    {
-          (yyval.integer) = STATE_POINT_ATTENUATION;
-       ;}
-    break;
-
-  case 190:
-
-/* Line 1455 of yacc.c  */
-#line 1591 "program_parse.y"
-    {
-          (yyval.state)[0] = (yyvsp[(1) - (5)].state)[0];
-          (yyval.state)[1] = (yyvsp[(1) - (5)].state)[1];
-          (yyval.state)[2] = (yyvsp[(4) - (5)].integer);
-          (yyval.state)[3] = (yyvsp[(4) - (5)].integer);
-          (yyval.state)[4] = (yyvsp[(1) - (5)].state)[2];
-       ;}
-    break;
-
-  case 191:
-
-/* Line 1455 of yacc.c  */
-#line 1601 "program_parse.y"
-    {
-          (yyval.state)[0] = (yyvsp[(1) - (2)].state)[0];
-          (yyval.state)[1] = (yyvsp[(1) - (2)].state)[1];
-          (yyval.state)[2] = (yyvsp[(2) - (2)].state)[2];
-          (yyval.state)[3] = (yyvsp[(2) - (2)].state)[3];
-          (yyval.state)[4] = (yyvsp[(1) - (2)].state)[2];
-       ;}
-    break;
-
-  case 192:
-
-/* Line 1455 of yacc.c  */
-#line 1611 "program_parse.y"
-    {
-          (yyval.state)[2] = 0;
-          (yyval.state)[3] = 3;
-       ;}
-    break;
-
-  case 193:
-
-/* Line 1455 of yacc.c  */
-#line 1616 "program_parse.y"
-    {
-          /* It seems logical that the matrix row range specifier would have
-           * to specify a range or more than one row (i.e., $5 > $3).
-           * However, the ARB_vertex_program spec says "a program will fail
-           * to load if <a> is greater than <b>."  This means that $3 == $5
-           * is valid.
-           */
-          if ((yyvsp[(3) - (6)].integer) > (yyvsp[(5) - (6)].integer)) {
-             yyerror(& (yylsp[(3) - (6)]), state, "invalid matrix row range");
-             YYERROR;
-          }
-
-          (yyval.state)[2] = (yyvsp[(3) - (6)].integer);
-          (yyval.state)[3] = (yyvsp[(5) - (6)].integer);
-       ;}
-    break;
-
-  case 194:
-
-/* Line 1455 of yacc.c  */
-#line 1634 "program_parse.y"
-    {
-          (yyval.state)[0] = (yyvsp[(2) - (3)].state)[0];
-          (yyval.state)[1] = (yyvsp[(2) - (3)].state)[1];
-          (yyval.state)[2] = (yyvsp[(3) - (3)].integer);
-       ;}
-    break;
-
-  case 195:
-
-/* Line 1455 of yacc.c  */
-#line 1642 "program_parse.y"
-    {
-          (yyval.integer) = 0;
-       ;}
-    break;
-
-  case 196:
-
-/* Line 1455 of yacc.c  */
-#line 1646 "program_parse.y"
-    {
-          (yyval.integer) = (yyvsp[(1) - (1)].integer);
-       ;}
-    break;
-
-  case 197:
-
-/* Line 1455 of yacc.c  */
-#line 1652 "program_parse.y"
-    {
-          (yyval.integer) = STATE_MATRIX_INVERSE;
-       ;}
-    break;
-
-  case 198:
-
-/* Line 1455 of yacc.c  */
-#line 1656 "program_parse.y"
-    {
-          (yyval.integer) = STATE_MATRIX_TRANSPOSE;
-       ;}
-    break;
-
-  case 199:
-
-/* Line 1455 of yacc.c  */
-#line 1660 "program_parse.y"
-    {
-          (yyval.integer) = STATE_MATRIX_INVTRANS;
-       ;}
-    break;
-
-  case 200:
-
-/* Line 1455 of yacc.c  */
-#line 1666 "program_parse.y"
-    {
-          if ((yyvsp[(1) - (1)].integer) > 3) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid matrix row reference");
-             YYERROR;
-          }
-
-          (yyval.integer) = (yyvsp[(1) - (1)].integer);
-       ;}
-    break;
-
-  case 201:
-
-/* Line 1455 of yacc.c  */
-#line 1677 "program_parse.y"
-    {
-          (yyval.state)[0] = STATE_MODELVIEW_MATRIX;
-          (yyval.state)[1] = (yyvsp[(2) - (2)].integer);
-       ;}
-    break;
-
-  case 202:
-
-/* Line 1455 of yacc.c  */
-#line 1682 "program_parse.y"
-    {
-          (yyval.state)[0] = STATE_PROJECTION_MATRIX;
-          (yyval.state)[1] = 0;
-       ;}
-    break;
-
-  case 203:
-
-/* Line 1455 of yacc.c  */
-#line 1687 "program_parse.y"
-    {
-          (yyval.state)[0] = STATE_MVP_MATRIX;
-          (yyval.state)[1] = 0;
-       ;}
-    break;
-
-  case 204:
-
-/* Line 1455 of yacc.c  */
-#line 1692 "program_parse.y"
-    {
-          (yyval.state)[0] = STATE_TEXTURE_MATRIX;
-          (yyval.state)[1] = (yyvsp[(2) - (2)].integer);
-       ;}
-    break;
-
-  case 205:
-
-/* Line 1455 of yacc.c  */
-#line 1697 "program_parse.y"
-    {
-          yyerror(& (yylsp[(1) - (4)]), state, "GL_ARB_matrix_palette not supported");
-          YYERROR;
-       ;}
-    break;
-
-  case 206:
-
-/* Line 1455 of yacc.c  */
-#line 1702 "program_parse.y"
-    {
-          (yyval.state)[0] = STATE_PROGRAM_MATRIX;
-          (yyval.state)[1] = (yyvsp[(3) - (4)].integer);
-       ;}
-    break;
-
-  case 207:
-
-/* Line 1455 of yacc.c  */
-#line 1709 "program_parse.y"
-    {
-          (yyval.integer) = 0;
-       ;}
-    break;
-
-  case 208:
-
-/* Line 1455 of yacc.c  */
-#line 1713 "program_parse.y"
-    {
-          (yyval.integer) = (yyvsp[(2) - (3)].integer);
-       ;}
-    break;
-
-  case 209:
-
-/* Line 1455 of yacc.c  */
-#line 1718 "program_parse.y"
-    {
-          /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix
-           * zero is valid.
-           */
-          if ((yyvsp[(1) - (1)].integer) != 0) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid modelview matrix index");
-             YYERROR;
-          }
-
-          (yyval.integer) = (yyvsp[(1) - (1)].integer);
-       ;}
-    break;
-
-  case 210:
-
-/* Line 1455 of yacc.c  */
-#line 1731 "program_parse.y"
-    {
-          /* Since GL_ARB_matrix_palette isn't supported, just let any value
-           * through here.  The error will be generated later.
-           */
-          (yyval.integer) = (yyvsp[(1) - (1)].integer);
-       ;}
-    break;
-
-  case 211:
-
-/* Line 1455 of yacc.c  */
-#line 1739 "program_parse.y"
-    {
-          if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxProgramMatrices) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid program matrix selector");
-             YYERROR;
-          }
-
-          (yyval.integer) = (yyvsp[(1) - (1)].integer);
-       ;}
-    break;
-
-  case 212:
-
-/* Line 1455 of yacc.c  */
-#line 1750 "program_parse.y"
-    {
-          memset((yyval.state), 0, sizeof((yyval.state)));
-          (yyval.state)[0] = STATE_DEPTH_RANGE;
-       ;}
-    break;
-
-  case 217:
-
-/* Line 1455 of yacc.c  */
-#line 1762 "program_parse.y"
-    {
-          memset((yyval.state), 0, sizeof((yyval.state)));
-          (yyval.state)[0] = state->state_param_enum;
-          (yyval.state)[1] = STATE_ENV;
-          (yyval.state)[2] = (yyvsp[(4) - (5)].state)[0];
-          (yyval.state)[3] = (yyvsp[(4) - (5)].state)[1];
-       ;}
-    break;
-
-  case 218:
-
-/* Line 1455 of yacc.c  */
-#line 1772 "program_parse.y"
-    {
-          (yyval.state)[0] = (yyvsp[(1) - (1)].integer);
-          (yyval.state)[1] = (yyvsp[(1) - (1)].integer);
-       ;}
-    break;
-
-  case 219:
-
-/* Line 1455 of yacc.c  */
-#line 1777 "program_parse.y"
-    {
-          (yyval.state)[0] = (yyvsp[(1) - (3)].integer);
-          (yyval.state)[1] = (yyvsp[(3) - (3)].integer);
-       ;}
-    break;
-
-  case 220:
-
-/* Line 1455 of yacc.c  */
-#line 1784 "program_parse.y"
-    {
-          memset((yyval.state), 0, sizeof((yyval.state)));
-          (yyval.state)[0] = state->state_param_enum;
-          (yyval.state)[1] = STATE_ENV;
-          (yyval.state)[2] = (yyvsp[(4) - (5)].integer);
-          (yyval.state)[3] = (yyvsp[(4) - (5)].integer);
-       ;}
-    break;
-
-  case 221:
-
-/* Line 1455 of yacc.c  */
-#line 1794 "program_parse.y"
-    {
-          memset((yyval.state), 0, sizeof((yyval.state)));
-          (yyval.state)[0] = state->state_param_enum;
-          (yyval.state)[1] = STATE_LOCAL;
-          (yyval.state)[2] = (yyvsp[(4) - (5)].state)[0];
-          (yyval.state)[3] = (yyvsp[(4) - (5)].state)[1];
-       ;}
-    break;
-
-  case 222:
-
-/* Line 1455 of yacc.c  */
-#line 1803 "program_parse.y"
-    {
-          (yyval.state)[0] = (yyvsp[(1) - (1)].integer);
-          (yyval.state)[1] = (yyvsp[(1) - (1)].integer);
-       ;}
-    break;
-
-  case 223:
-
-/* Line 1455 of yacc.c  */
-#line 1808 "program_parse.y"
-    {
-          (yyval.state)[0] = (yyvsp[(1) - (3)].integer);
-          (yyval.state)[1] = (yyvsp[(3) - (3)].integer);
-       ;}
-    break;
-
-  case 224:
-
-/* Line 1455 of yacc.c  */
-#line 1815 "program_parse.y"
-    {
-          memset((yyval.state), 0, sizeof((yyval.state)));
-          (yyval.state)[0] = state->state_param_enum;
-          (yyval.state)[1] = STATE_LOCAL;
-          (yyval.state)[2] = (yyvsp[(4) - (5)].integer);
-          (yyval.state)[3] = (yyvsp[(4) - (5)].integer);
-       ;}
-    break;
-
-  case 225:
-
-/* Line 1455 of yacc.c  */
-#line 1825 "program_parse.y"
-    {
-          if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxEnvParams) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid environment parameter reference");
-             YYERROR;
-          }
-          (yyval.integer) = (yyvsp[(1) - (1)].integer);
-       ;}
-    break;
-
-  case 226:
-
-/* Line 1455 of yacc.c  */
-#line 1835 "program_parse.y"
-    {
-          if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxLocalParams) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid local parameter reference");
-             YYERROR;
-          }
-          (yyval.integer) = (yyvsp[(1) - (1)].integer);
-       ;}
-    break;
-
-  case 231:
-
-/* Line 1455 of yacc.c  */
-#line 1850 "program_parse.y"
-    {
-          (yyval.vector).count = 4;
-          (yyval.vector).data[0] = (yyvsp[(1) - (1)].real);
-          (yyval.vector).data[1] = (yyvsp[(1) - (1)].real);
-          (yyval.vector).data[2] = (yyvsp[(1) - (1)].real);
-          (yyval.vector).data[3] = (yyvsp[(1) - (1)].real);
-       ;}
-    break;
-
-  case 232:
-
-/* Line 1455 of yacc.c  */
-#line 1860 "program_parse.y"
-    {
-          (yyval.vector).count = 1;
-          (yyval.vector).data[0] = (yyvsp[(1) - (1)].real);
-          (yyval.vector).data[1] = (yyvsp[(1) - (1)].real);
-          (yyval.vector).data[2] = (yyvsp[(1) - (1)].real);
-          (yyval.vector).data[3] = (yyvsp[(1) - (1)].real);
-       ;}
-    break;
-
-  case 233:
-
-/* Line 1455 of yacc.c  */
-#line 1868 "program_parse.y"
-    {
-          (yyval.vector).count = 1;
-          (yyval.vector).data[0] = (float) (yyvsp[(1) - (1)].integer);
-          (yyval.vector).data[1] = (float) (yyvsp[(1) - (1)].integer);
-          (yyval.vector).data[2] = (float) (yyvsp[(1) - (1)].integer);
-          (yyval.vector).data[3] = (float) (yyvsp[(1) - (1)].integer);
-       ;}
-    break;
-
-  case 234:
-
-/* Line 1455 of yacc.c  */
-#line 1878 "program_parse.y"
-    {
-          (yyval.vector).count = 4;
-          (yyval.vector).data[0] = (yyvsp[(2) - (3)].real);
-          (yyval.vector).data[1] = 0.0f;
-          (yyval.vector).data[2] = 0.0f;
-          (yyval.vector).data[3] = 1.0f;
-       ;}
-    break;
-
-  case 235:
-
-/* Line 1455 of yacc.c  */
-#line 1886 "program_parse.y"
-    {
-          (yyval.vector).count = 4;
-          (yyval.vector).data[0] = (yyvsp[(2) - (5)].real);
-          (yyval.vector).data[1] = (yyvsp[(4) - (5)].real);
-          (yyval.vector).data[2] = 0.0f;
-          (yyval.vector).data[3] = 1.0f;
-       ;}
-    break;
-
-  case 236:
-
-/* Line 1455 of yacc.c  */
-#line 1895 "program_parse.y"
-    {
-          (yyval.vector).count = 4;
-          (yyval.vector).data[0] = (yyvsp[(2) - (7)].real);
-          (yyval.vector).data[1] = (yyvsp[(4) - (7)].real);
-          (yyval.vector).data[2] = (yyvsp[(6) - (7)].real);
-          (yyval.vector).data[3] = 1.0f;
-       ;}
-    break;
-
-  case 237:
-
-/* Line 1455 of yacc.c  */
-#line 1904 "program_parse.y"
-    {
-          (yyval.vector).count = 4;
-          (yyval.vector).data[0] = (yyvsp[(2) - (9)].real);
-          (yyval.vector).data[1] = (yyvsp[(4) - (9)].real);
-          (yyval.vector).data[2] = (yyvsp[(6) - (9)].real);
-          (yyval.vector).data[3] = (yyvsp[(8) - (9)].real);
-       ;}
-    break;
-
-  case 238:
-
-/* Line 1455 of yacc.c  */
-#line 1914 "program_parse.y"
-    {
-          (yyval.real) = ((yyvsp[(1) - (2)].negate)) ? -(yyvsp[(2) - (2)].real) : (yyvsp[(2) - (2)].real);
-       ;}
-    break;
-
-  case 239:
-
-/* Line 1455 of yacc.c  */
-#line 1918 "program_parse.y"
-    {
-          (yyval.real) = (float)(((yyvsp[(1) - (2)].negate)) ? -(yyvsp[(2) - (2)].integer) : (yyvsp[(2) - (2)].integer));
-       ;}
-    break;
-
-  case 240:
-
-/* Line 1455 of yacc.c  */
-#line 1923 "program_parse.y"
-    { (yyval.negate) = FALSE; ;}
-    break;
-
-  case 241:
-
-/* Line 1455 of yacc.c  */
-#line 1924 "program_parse.y"
-    { (yyval.negate) = TRUE;  ;}
-    break;
-
-  case 242:
-
-/* Line 1455 of yacc.c  */
-#line 1925 "program_parse.y"
-    { (yyval.negate) = FALSE; ;}
-    break;
-
-  case 243:
-
-/* Line 1455 of yacc.c  */
-#line 1928 "program_parse.y"
-    { (yyval.integer) = (yyvsp[(2) - (2)].integer); ;}
-    break;
-
-  case 245:
-
-/* Line 1455 of yacc.c  */
-#line 1932 "program_parse.y"
-    {
-          /* NV_fragment_program_option defines the size qualifiers in a
-           * fairly broken way.  "SHORT" or "LONG" can optionally be used
-           * before TEMP or OUTPUT.  However, neither is a reserved word!
-           * This means that we have to parse it as an identifier, then check
-           * to make sure it's one of the valid values.  *sigh*
-           *
-           * In addition, the grammar in the extension spec does *not* allow
-           * the size specifier to be optional, but all known implementations
-           * do.
-           */
-          if (!state->option.NV_fragment) {
-             yyerror(& (yylsp[(1) - (1)]), state, "unexpected IDENTIFIER");
-             YYERROR;
-          }
-
-          if (strcmp("SHORT", (yyvsp[(1) - (1)].string)) == 0) {
-          } else if (strcmp("LONG", (yyvsp[(1) - (1)].string)) == 0) {
-          } else {
-             char *const err_str =
-                make_error_string("invalid storage size specifier \"%s\"",
-                                  (yyvsp[(1) - (1)].string));
-
-             yyerror(& (yylsp[(1) - (1)]), state, (err_str != NULL)
-                     ? err_str : "invalid storage size specifier");
-
-             if (err_str != NULL) {
-                free(err_str);
-             }
-
-             YYERROR;
-          }
-       ;}
-    break;
-
-  case 246:
-
-/* Line 1455 of yacc.c  */
-#line 1966 "program_parse.y"
-    {
-       ;}
-    break;
-
-  case 247:
-
-/* Line 1455 of yacc.c  */
-#line 1970 "program_parse.y"
-    { (yyval.integer) = (yyvsp[(1) - (1)].integer); ;}
-    break;
-
-  case 249:
-
-/* Line 1455 of yacc.c  */
-#line 1974 "program_parse.y"
-    {
-          if (!declare_variable(state, (yyvsp[(3) - (3)].string), (yyvsp[(0) - (3)].integer), & (yylsp[(3) - (3)]))) {
-             free((yyvsp[(3) - (3)].string));
-             YYERROR;
-          }
-       ;}
-    break;
-
-  case 250:
-
-/* Line 1455 of yacc.c  */
-#line 1981 "program_parse.y"
-    {
-          if (!declare_variable(state, (yyvsp[(1) - (1)].string), (yyvsp[(0) - (1)].integer), & (yylsp[(1) - (1)]))) {
-             free((yyvsp[(1) - (1)].string));
-             YYERROR;
-          }
-       ;}
-    break;
-
-  case 251:
-
-/* Line 1455 of yacc.c  */
-#line 1990 "program_parse.y"
-    {
-          struct asm_symbol *const s =
-             declare_variable(state, (yyvsp[(3) - (5)].string), at_output, & (yylsp[(3) - (5)]));
-
-          if (s == NULL) {
-             free((yyvsp[(3) - (5)].string));
-             YYERROR;
-          } else {
-             s->output_binding = (yyvsp[(5) - (5)].result);
-          }
-       ;}
-    break;
-
-  case 252:
-
-/* Line 1455 of yacc.c  */
-#line 2004 "program_parse.y"
-    {
-          if (state->mode == ARB_vertex) {
-             (yyval.result) = VERT_RESULT_HPOS;
-          } else {
-             yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name");
-             YYERROR;
-          }
-       ;}
-    break;
-
-  case 253:
-
-/* Line 1455 of yacc.c  */
-#line 2013 "program_parse.y"
-    {
-          if (state->mode == ARB_vertex) {
-             (yyval.result) = VERT_RESULT_FOGC;
-          } else {
-             yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name");
-             YYERROR;
-          }
-       ;}
-    break;
-
-  case 254:
-
-/* Line 1455 of yacc.c  */
-#line 2022 "program_parse.y"
-    {
-          (yyval.result) = (yyvsp[(2) - (2)].result);
-       ;}
-    break;
-
-  case 255:
-
-/* Line 1455 of yacc.c  */
-#line 2026 "program_parse.y"
-    {
-          if (state->mode == ARB_vertex) {
-             (yyval.result) = VERT_RESULT_PSIZ;
-          } else {
-             yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name");
-             YYERROR;
-          }
-       ;}
-    break;
-
-  case 256:
-
-/* Line 1455 of yacc.c  */
-#line 2035 "program_parse.y"
-    {
-          if (state->mode == ARB_vertex) {
-             (yyval.result) = VERT_RESULT_TEX0 + (yyvsp[(3) - (3)].integer);
-          } else {
-             yyerror(& (yylsp[(2) - (3)]), state, "invalid program result name");
-             YYERROR;
-          }
-       ;}
-    break;
-
-  case 257:
-
-/* Line 1455 of yacc.c  */
-#line 2044 "program_parse.y"
-    {
-          if (state->mode == ARB_fragment) {
-             (yyval.result) = FRAG_RESULT_DEPTH;
-          } else {
-             yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name");
-             YYERROR;
-          }
-       ;}
-    break;
-
-  case 258:
-
-/* Line 1455 of yacc.c  */
-#line 2055 "program_parse.y"
-    {
-          (yyval.result) = (yyvsp[(2) - (3)].integer) + (yyvsp[(3) - (3)].integer);
-       ;}
-    break;
-
-  case 259:
-
-/* Line 1455 of yacc.c  */
-#line 2061 "program_parse.y"
-    {
-          (yyval.integer) = (state->mode == ARB_vertex)
-             ? VERT_RESULT_COL0
-             : FRAG_RESULT_COLOR;
-       ;}
-    break;
-
-  case 260:
-
-/* Line 1455 of yacc.c  */
-#line 2067 "program_parse.y"
-    {
-          if (state->mode == ARB_vertex) {
-             (yyval.integer) = VERT_RESULT_COL0;
-          } else {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name");
-             YYERROR;
-          }
-       ;}
-    break;
-
-  case 261:
-
-/* Line 1455 of yacc.c  */
-#line 2076 "program_parse.y"
-    {
-          if (state->mode == ARB_vertex) {
-             (yyval.integer) = VERT_RESULT_BFC0;
-          } else {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name");
-             YYERROR;
-          }
-       ;}
-    break;
-
-  case 262:
-
-/* Line 1455 of yacc.c  */
-#line 2087 "program_parse.y"
-    {
-          (yyval.integer) = 0; 
-       ;}
-    break;
-
-  case 263:
-
-/* Line 1455 of yacc.c  */
-#line 2091 "program_parse.y"
-    {
-          if (state->mode == ARB_vertex) {
-             (yyval.integer) = 0;
-          } else {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name");
-             YYERROR;
-          }
-       ;}
-    break;
-
-  case 264:
-
-/* Line 1455 of yacc.c  */
-#line 2100 "program_parse.y"
-    {
-          if (state->mode == ARB_vertex) {
-             (yyval.integer) = 1;
-          } else {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name");
-             YYERROR;
-          }
-       ;}
-    break;
-
-  case 265:
-
-/* Line 1455 of yacc.c  */
-#line 2110 "program_parse.y"
-    { (yyval.integer) = 0; ;}
-    break;
-
-  case 266:
-
-/* Line 1455 of yacc.c  */
-#line 2111 "program_parse.y"
-    { (yyval.integer) = 0; ;}
-    break;
-
-  case 267:
-
-/* Line 1455 of yacc.c  */
-#line 2112 "program_parse.y"
-    { (yyval.integer) = 1; ;}
-    break;
-
-  case 268:
-
-/* Line 1455 of yacc.c  */
-#line 2115 "program_parse.y"
-    { (yyval.integer) = 0; ;}
-    break;
-
-  case 269:
-
-/* Line 1455 of yacc.c  */
-#line 2116 "program_parse.y"
-    { (yyval.integer) = 0; ;}
-    break;
-
-  case 270:
-
-/* Line 1455 of yacc.c  */
-#line 2117 "program_parse.y"
-    { (yyval.integer) = 1; ;}
-    break;
-
-  case 271:
-
-/* Line 1455 of yacc.c  */
-#line 2120 "program_parse.y"
-    { (yyval.integer) = 0; ;}
-    break;
-
-  case 272:
-
-/* Line 1455 of yacc.c  */
-#line 2121 "program_parse.y"
-    { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;}
-    break;
-
-  case 273:
-
-/* Line 1455 of yacc.c  */
-#line 2124 "program_parse.y"
-    { (yyval.integer) = 0; ;}
-    break;
-
-  case 274:
-
-/* Line 1455 of yacc.c  */
-#line 2125 "program_parse.y"
-    { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;}
-    break;
-
-  case 275:
-
-/* Line 1455 of yacc.c  */
-#line 2128 "program_parse.y"
-    { (yyval.integer) = 0; ;}
-    break;
-
-  case 276:
-
-/* Line 1455 of yacc.c  */
-#line 2129 "program_parse.y"
-    { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;}
-    break;
-
-  case 277:
-
-/* Line 1455 of yacc.c  */
-#line 2133 "program_parse.y"
-    {
-          if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureCoordUnits) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid texture coordinate unit selector");
-             YYERROR;
-          }
-
-          (yyval.integer) = (yyvsp[(1) - (1)].integer);
-       ;}
-    break;
-
-  case 278:
-
-/* Line 1455 of yacc.c  */
-#line 2144 "program_parse.y"
-    {
-          if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureImageUnits) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid texture image unit selector");
-             YYERROR;
-          }
-
-          (yyval.integer) = (yyvsp[(1) - (1)].integer);
-       ;}
-    break;
-
-  case 279:
-
-/* Line 1455 of yacc.c  */
-#line 2155 "program_parse.y"
-    {
-          if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureUnits) {
-             yyerror(& (yylsp[(1) - (1)]), state, "invalid texture unit selector");
-             YYERROR;
-          }
-
-          (yyval.integer) = (yyvsp[(1) - (1)].integer);
-       ;}
-    break;
-
-  case 280:
-
-/* Line 1455 of yacc.c  */
-#line 2166 "program_parse.y"
-    {
-          struct asm_symbol *exist = (struct asm_symbol *)
-             _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(2) - (4)].string));
-          struct asm_symbol *target = (struct asm_symbol *)
-             _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(4) - (4)].string));
-
-          free((yyvsp[(4) - (4)].string));
-
-          if (exist != NULL) {
-             char m[1000];
-             _mesa_snprintf(m, sizeof(m), "redeclared identifier: %s", (yyvsp[(2) - (4)].string));
-             free((yyvsp[(2) - (4)].string));
-             yyerror(& (yylsp[(2) - (4)]), state, m);
-             YYERROR;
-          } else if (target == NULL) {
-             free((yyvsp[(2) - (4)].string));
-             yyerror(& (yylsp[(4) - (4)]), state,
-                     "undefined variable binding in ALIAS statement");
-             YYERROR;
-          } else {
-             _mesa_symbol_table_add_symbol(state->st, 0, (yyvsp[(2) - (4)].string), target);
-          }
-       ;}
-    break;
-
-
-
-/* Line 1455 of yacc.c  */
-#line 4937 "program_parse.tab.c"
-      default: break;
-    }
-  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
-
-  YYPOPSTACK (yylen);
-  yylen = 0;
-  YY_STACK_PRINT (yyss, yyssp);
-
-  *++yyvsp = yyval;
-  *++yylsp = yyloc;
-
-  /* Now `shift' the result of the reduction.  Determine what state
-     that goes to, based on the state we popped back to and the rule
-     number reduced by.  */
-
-  yyn = yyr1[yyn];
-
-  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
-  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
-    yystate = yytable[yystate];
-  else
-    yystate = yydefgoto[yyn - YYNTOKENS];
-
-  goto yynewstate;
-
-
-/*------------------------------------.
-| yyerrlab -- here on detecting error |
-`------------------------------------*/
-yyerrlab:
-  /* If not already recovering from an error, report this error.  */
-  if (!yyerrstatus)
-    {
-      ++yynerrs;
-#if ! YYERROR_VERBOSE
-      yyerror (&yylloc, state, YY_("syntax error"));
-#else
-      {
-       YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
-       if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
-         {
-           YYSIZE_T yyalloc = 2 * yysize;
-           if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
-             yyalloc = YYSTACK_ALLOC_MAXIMUM;
-           if (yymsg != yymsgbuf)
-             YYSTACK_FREE (yymsg);
-           yymsg = (char *) YYSTACK_ALLOC (yyalloc);
-           if (yymsg)
-             yymsg_alloc = yyalloc;
-           else
-             {
-               yymsg = yymsgbuf;
-               yymsg_alloc = sizeof yymsgbuf;
-             }
-         }
-
-       if (0 < yysize && yysize <= yymsg_alloc)
-         {
-           (void) yysyntax_error (yymsg, yystate, yychar);
-           yyerror (&yylloc, state, yymsg);
-         }
-       else
-         {
-           yyerror (&yylloc, state, YY_("syntax error"));
-           if (yysize != 0)
-             goto yyexhaustedlab;
-         }
-      }
-#endif
-    }
-
-  yyerror_range[0] = yylloc;
-
-  if (yyerrstatus == 3)
-    {
-      /* If just tried and failed to reuse lookahead token after an
-        error, discard it.  */
-
-      if (yychar <= YYEOF)
-       {
-         /* Return failure if at end of input.  */
-         if (yychar == YYEOF)
-           YYABORT;
-       }
-      else
-       {
-         yydestruct ("Error: discarding",
-                     yytoken, &yylval, &yylloc, state);
-         yychar = YYEMPTY;
-       }
-    }
-
-  /* Else will try to reuse lookahead token after shifting the error
-     token.  */
-  goto yyerrlab1;
-
-
-/*---------------------------------------------------.
-| yyerrorlab -- error raised explicitly by YYERROR.  |
-`---------------------------------------------------*/
-yyerrorlab:
-
-  /* Pacify compilers like GCC when the user code never invokes
-     YYERROR and the label yyerrorlab therefore never appears in user
-     code.  */
-  if (/*CONSTCOND*/ 0)
-     goto yyerrorlab;
-
-  yyerror_range[0] = yylsp[1-yylen];
-  /* Do not reclaim the symbols of the rule which action triggered
-     this YYERROR.  */
-  YYPOPSTACK (yylen);
-  yylen = 0;
-  YY_STACK_PRINT (yyss, yyssp);
-  yystate = *yyssp;
-  goto yyerrlab1;
-
-
-/*-------------------------------------------------------------.
-| yyerrlab1 -- common code for both syntax error and YYERROR.  |
-`-------------------------------------------------------------*/
-yyerrlab1:
-  yyerrstatus = 3;     /* Each real token shifted decrements this.  */
-
-  for (;;)
-    {
-      yyn = yypact[yystate];
-      if (yyn != YYPACT_NINF)
-       {
-         yyn += YYTERROR;
-         if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
-           {
-             yyn = yytable[yyn];
-             if (0 < yyn)
-               break;
-           }
-       }
-
-      /* Pop the current state because it cannot handle the error token.  */
-      if (yyssp == yyss)
-       YYABORT;
-
-      yyerror_range[0] = *yylsp;
-      yydestruct ("Error: popping",
-                 yystos[yystate], yyvsp, yylsp, state);
-      YYPOPSTACK (1);
-      yystate = *yyssp;
-      YY_STACK_PRINT (yyss, yyssp);
-    }
-
-  *++yyvsp = yylval;
-
-  yyerror_range[1] = yylloc;
-  /* Using YYLLOC is tempting, but would change the location of
-     the lookahead.  YYLOC is available though.  */
-  YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
-  *++yylsp = yyloc;
-
-  /* Shift the error token.  */
-  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
-
-  yystate = yyn;
-  goto yynewstate;
-
-
-/*-------------------------------------.
-| yyacceptlab -- YYACCEPT comes here.  |
-`-------------------------------------*/
-yyacceptlab:
-  yyresult = 0;
-  goto yyreturn;
-
-/*-----------------------------------.
-| yyabortlab -- YYABORT comes here.  |
-`-----------------------------------*/
-yyabortlab:
-  yyresult = 1;
-  goto yyreturn;
-
-#if !defined(yyoverflow) || YYERROR_VERBOSE
-/*-------------------------------------------------.
-| yyexhaustedlab -- memory exhaustion comes here.  |
-`-------------------------------------------------*/
-yyexhaustedlab:
-  yyerror (&yylloc, state, YY_("memory exhausted"));
-  yyresult = 2;
-  /* Fall through.  */
-#endif
-
-yyreturn:
-  if (yychar != YYEMPTY)
-     yydestruct ("Cleanup: discarding lookahead",
-                yytoken, &yylval, &yylloc, state);
-  /* Do not reclaim the symbols of the rule which action triggered
-     this YYABORT or YYACCEPT.  */
-  YYPOPSTACK (yylen);
-  YY_STACK_PRINT (yyss, yyssp);
-  while (yyssp != yyss)
-    {
-      yydestruct ("Cleanup: popping",
-                 yystos[*yyssp], yyvsp, yylsp, state);
-      YYPOPSTACK (1);
-    }
-#ifndef yyoverflow
-  if (yyss != yyssa)
-    YYSTACK_FREE (yyss);
-#endif
-#if YYERROR_VERBOSE
-  if (yymsg != yymsgbuf)
-    YYSTACK_FREE (yymsg);
-#endif
-  /* Make sure YYID is used.  */
-  return YYID (yyresult);
-}
-
-
-
-/* Line 1675 of yacc.c  */
-#line 2195 "program_parse.y"
-
-
-void
-asm_instruction_set_operands(struct asm_instruction *inst,
-                            const struct prog_dst_register *dst,
-                            const struct asm_src_register *src0,
-                            const struct asm_src_register *src1,
-                            const struct asm_src_register *src2)
-{
-   /* In the core ARB extensions only the KIL instruction doesn't have a
-    * destination register.
-    */
-   if (dst == NULL) {
-      init_dst_reg(& inst->Base.DstReg);
-   } else {
-      inst->Base.DstReg = *dst;
-   }
-
-   /* The only instruction that doesn't have any source registers is the
-    * condition-code based KIL instruction added by NV_fragment_program_option.
-    */
-   if (src0 != NULL) {
-      inst->Base.SrcReg[0] = src0->Base;
-      inst->SrcReg[0] = *src0;
-   } else {
-      init_src_reg(& inst->SrcReg[0]);
-   }
-
-   if (src1 != NULL) {
-      inst->Base.SrcReg[1] = src1->Base;
-      inst->SrcReg[1] = *src1;
-   } else {
-      init_src_reg(& inst->SrcReg[1]);
-   }
-
-   if (src2 != NULL) {
-      inst->Base.SrcReg[2] = src2->Base;
-      inst->SrcReg[2] = *src2;
-   } else {
-      init_src_reg(& inst->SrcReg[2]);
-   }
-}
-
-
-struct asm_instruction *
-asm_instruction_ctor(gl_inst_opcode op,
-                    const struct prog_dst_register *dst,
-                    const struct asm_src_register *src0,
-                    const struct asm_src_register *src1,
-                    const struct asm_src_register *src2)
-{
-   struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
-
-   if (inst) {
-      _mesa_init_instructions(& inst->Base, 1);
-      inst->Base.Opcode = op;
-
-      asm_instruction_set_operands(inst, dst, src0, src1, src2);
-   }
-
-   return inst;
-}
-
-
-struct asm_instruction *
-asm_instruction_copy_ctor(const struct prog_instruction *base,
-                         const struct prog_dst_register *dst,
-                         const struct asm_src_register *src0,
-                         const struct asm_src_register *src1,
-                         const struct asm_src_register *src2)
-{
-   struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
-
-   if (inst) {
-      _mesa_init_instructions(& inst->Base, 1);
-      inst->Base.Opcode = base->Opcode;
-      inst->Base.CondUpdate = base->CondUpdate;
-      inst->Base.CondDst = base->CondDst;
-      inst->Base.SaturateMode = base->SaturateMode;
-      inst->Base.Precision = base->Precision;
-
-      asm_instruction_set_operands(inst, dst, src0, src1, src2);
-   }
-
-   return inst;
-}
-
-
-void
-init_dst_reg(struct prog_dst_register *r)
-{
-   memset(r, 0, sizeof(*r));
-   r->File = PROGRAM_UNDEFINED;
-   r->WriteMask = WRITEMASK_XYZW;
-   r->CondMask = COND_TR;
-   r->CondSwizzle = SWIZZLE_NOOP;
-}
-
-
-/** Like init_dst_reg() but set the File and Index fields. */
-void
-set_dst_reg(struct prog_dst_register *r, gl_register_file file, GLint index)
-{
-   const GLint maxIndex = 1 << INST_INDEX_BITS;
-   const GLint minIndex = 0;
-   ASSERT(index >= minIndex);
-   (void) minIndex;
-   ASSERT(index <= maxIndex);
-   (void) maxIndex;
-   ASSERT(file == PROGRAM_TEMPORARY ||
-         file == PROGRAM_ADDRESS ||
-         file == PROGRAM_OUTPUT);
-   memset(r, 0, sizeof(*r));
-   r->File = file;
-   r->Index = index;
-   r->WriteMask = WRITEMASK_XYZW;
-   r->CondMask = COND_TR;
-   r->CondSwizzle = SWIZZLE_NOOP;
-}
-
-
-void
-init_src_reg(struct asm_src_register *r)
-{
-   memset(r, 0, sizeof(*r));
-   r->Base.File = PROGRAM_UNDEFINED;
-   r->Base.Swizzle = SWIZZLE_NOOP;
-   r->Symbol = NULL;
-}
-
-
-/** Like init_src_reg() but set the File and Index fields.
- * \return GL_TRUE if a valid src register, GL_FALSE otherwise
- */
-void
-set_src_reg(struct asm_src_register *r, gl_register_file file, GLint index)
-{
-   set_src_reg_swz(r, file, index, SWIZZLE_XYZW);
-}
-
-
-void
-set_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index,
-                GLuint swizzle)
-{
-   const GLint maxIndex = (1 << INST_INDEX_BITS) - 1;
-   const GLint minIndex = -(1 << INST_INDEX_BITS);
-   ASSERT(file < PROGRAM_FILE_MAX);
-   ASSERT(index >= minIndex);
-   (void) minIndex;
-   ASSERT(index <= maxIndex);
-   (void) maxIndex;
-   memset(r, 0, sizeof(*r));
-   r->Base.File = file;
-   r->Base.Index = index;
-   r->Base.Swizzle = swizzle;
-   r->Symbol = NULL;
-}
-
-
-/**
- * Validate the set of inputs used by a program
- *
- * Validates that legal sets of inputs are used by the program.  In this case
- * "used" included both reading the input or binding the input to a name using
- * the \c ATTRIB command.
- *
- * \return
- * \c TRUE if the combination of inputs used is valid, \c FALSE otherwise.
- */
-int
-validate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state)
-{
-   const int inputs = state->prog->InputsRead | state->InputsBound;
-
-   if (((inputs & 0x0ffff) & (inputs >> 16)) != 0) {
-      yyerror(locp, state, "illegal use of generic attribute and name attribute");
-      return 0;
-   }
-
-   return 1;
-}
-
-
-struct asm_symbol *
-declare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
-                struct YYLTYPE *locp)
-{
-   struct asm_symbol *s = NULL;
-   struct asm_symbol *exist = (struct asm_symbol *)
-      _mesa_symbol_table_find_symbol(state->st, 0, name);
-
-
-   if (exist != NULL) {
-      yyerror(locp, state, "redeclared identifier");
-   } else {
-      s = calloc(1, sizeof(struct asm_symbol));
-      s->name = name;
-      s->type = t;
-
-      switch (t) {
-      case at_temp:
-        if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
-           yyerror(locp, state, "too many temporaries declared");
-           free(s);
-           return NULL;
-        }
-
-        s->temp_binding = state->prog->NumTemporaries;
-        state->prog->NumTemporaries++;
-        break;
-
-      case at_address:
-        if (state->prog->NumAddressRegs >= state->limits->MaxAddressRegs) {
-           yyerror(locp, state, "too many address registers declared");
-           free(s);
-           return NULL;
-        }
-
-        /* FINISHME: Add support for multiple address registers.
-         */
-        state->prog->NumAddressRegs++;
-        break;
-
-      default:
-        break;
-      }
-
-      _mesa_symbol_table_add_symbol(state->st, 0, s->name, s);
-      s->next = state->sym;
-      state->sym = s;
-   }
-
-   return s;
-}
-
-
-int add_state_reference(struct gl_program_parameter_list *param_list,
-                       const gl_state_index tokens[STATE_LENGTH])
-{
-   const GLuint size = 4; /* XXX fix */
-   char *name;
-   GLint index;
-
-   name = _mesa_program_state_string(tokens);
-   index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name,
-                               size, GL_NONE, NULL, tokens, 0x0);
-   param_list->StateFlags |= _mesa_program_state_flags(tokens);
-
-   /* free name string here since we duplicated it in add_parameter() */
-   free(name);
-
-   return index;
-}
-
-
-int
-initialize_symbol_from_state(struct gl_program *prog,
-                            struct asm_symbol *param_var, 
-                            const gl_state_index tokens[STATE_LENGTH])
-{
-   int idx = -1;
-   gl_state_index state_tokens[STATE_LENGTH];
-
-
-   memcpy(state_tokens, tokens, sizeof(state_tokens));
-
-   param_var->type = at_param;
-   param_var->param_binding_type = PROGRAM_STATE_VAR;
-
-   /* If we are adding a STATE_MATRIX that has multiple rows, we need to
-    * unroll it and call add_state_reference() for each row
-    */
-   if ((state_tokens[0] == STATE_MODELVIEW_MATRIX ||
-       state_tokens[0] == STATE_PROJECTION_MATRIX ||
-       state_tokens[0] == STATE_MVP_MATRIX ||
-       state_tokens[0] == STATE_TEXTURE_MATRIX ||
-       state_tokens[0] == STATE_PROGRAM_MATRIX)
-       && (state_tokens[2] != state_tokens[3])) {
-      int row;
-      const int first_row = state_tokens[2];
-      const int last_row = state_tokens[3];
-
-      for (row = first_row; row <= last_row; row++) {
-        state_tokens[2] = state_tokens[3] = row;
-
-        idx = add_state_reference(prog->Parameters, state_tokens);
-        if (param_var->param_binding_begin == ~0U) {
-           param_var->param_binding_begin = idx;
-            param_var->param_binding_swizzle = SWIZZLE_XYZW;
-         }
-
-        param_var->param_binding_length++;
-      }
-   }
-   else {
-      idx = add_state_reference(prog->Parameters, state_tokens);
-      if (param_var->param_binding_begin == ~0U) {
-        param_var->param_binding_begin = idx;
-         param_var->param_binding_swizzle = SWIZZLE_XYZW;
-      }
-      param_var->param_binding_length++;
-   }
-
-   return idx;
-}
-
-
-int
-initialize_symbol_from_param(struct gl_program *prog,
-                            struct asm_symbol *param_var, 
-                            const gl_state_index tokens[STATE_LENGTH])
-{
-   int idx = -1;
-   gl_state_index state_tokens[STATE_LENGTH];
-
-
-   memcpy(state_tokens, tokens, sizeof(state_tokens));
-
-   assert((state_tokens[0] == STATE_VERTEX_PROGRAM)
-         || (state_tokens[0] == STATE_FRAGMENT_PROGRAM));
-   assert((state_tokens[1] == STATE_ENV)
-         || (state_tokens[1] == STATE_LOCAL));
-
-   /*
-    * The param type is STATE_VAR.  The program parameter entry will
-    * effectively be a pointer into the LOCAL or ENV parameter array.
-    */
-   param_var->type = at_param;
-   param_var->param_binding_type = PROGRAM_STATE_VAR;
-
-   /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements,
-    * we need to unroll it and call add_state_reference() for each row
-    */
-   if (state_tokens[2] != state_tokens[3]) {
-      int row;
-      const int first_row = state_tokens[2];
-      const int last_row = state_tokens[3];
-
-      for (row = first_row; row <= last_row; row++) {
-        state_tokens[2] = state_tokens[3] = row;
-
-        idx = add_state_reference(prog->Parameters, state_tokens);
-        if (param_var->param_binding_begin == ~0U) {
-           param_var->param_binding_begin = idx;
-            param_var->param_binding_swizzle = SWIZZLE_XYZW;
-         }
-        param_var->param_binding_length++;
-      }
-   }
-   else {
-      idx = add_state_reference(prog->Parameters, state_tokens);
-      if (param_var->param_binding_begin == ~0U) {
-        param_var->param_binding_begin = idx;
-         param_var->param_binding_swizzle = SWIZZLE_XYZW;
-      }
-      param_var->param_binding_length++;
-   }
-
-   return idx;
-}
-
-
-/**
- * Put a float/vector constant/literal into the parameter list.
- * \param param_var  returns info about the parameter/constant's location,
- *                   binding, type, etc.
- * \param vec  the vector/constant to add
- * \param allowSwizzle  if true, try to consolidate constants which only differ
- *                      by a swizzle.  We don't want to do this when building
- *                      arrays of constants that may be indexed indirectly.
- * \return index of the constant in the parameter list.
- */
-int
-initialize_symbol_from_const(struct gl_program *prog,
-                            struct asm_symbol *param_var, 
-                            const struct asm_vector *vec,
-                             GLboolean allowSwizzle)
-{
-   unsigned swizzle;
-   const int idx = _mesa_add_unnamed_constant(prog->Parameters,
-                                              vec->data, vec->count,
-                                              allowSwizzle ? &swizzle : NULL);
-
-   param_var->type = at_param;
-   param_var->param_binding_type = PROGRAM_CONSTANT;
-
-   if (param_var->param_binding_begin == ~0U) {
-      param_var->param_binding_begin = idx;
-      param_var->param_binding_swizzle = allowSwizzle ? swizzle : SWIZZLE_XYZW;
-   }
-   param_var->param_binding_length++;
-
-   return idx;
-}
-
-
-char *
-make_error_string(const char *fmt, ...)
-{
-   int length;
-   char *str;
-   va_list args;
-
-
-   /* Call vsnprintf once to determine how large the final string is.  Call it
-    * again to do the actual formatting.  from the vsnprintf manual page:
-    *
-    *    Upon successful return, these functions return the number of
-    *    characters printed  (not including the trailing '\0' used to end
-    *    output to strings).
-    */
-   va_start(args, fmt);
-   length = 1 + vsnprintf(NULL, 0, fmt, args);
-   va_end(args);
-
-   str = malloc(length);
-   if (str) {
-      va_start(args, fmt);
-      vsnprintf(str, length, fmt, args);
-      va_end(args);
-   }
-
-   return str;
-}
-
-
-void
-yyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s)
-{
-   char *err_str;
-
-
-   err_str = make_error_string("glProgramStringARB(%s)\n", s);
-   if (err_str) {
-      _mesa_error(state->ctx, GL_INVALID_OPERATION, err_str);
-      free(err_str);
-   }
-
-   err_str = make_error_string("line %u, char %u: error: %s\n",
-                              locp->first_line, locp->first_column, s);
-   _mesa_set_program_error(state->ctx, locp->position, err_str);
-
-   if (err_str) {
-      free(err_str);
-   }
-}
-
-
-GLboolean
-_mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str,
-                       GLsizei len, struct asm_parser_state *state)
-{
-   struct asm_instruction *inst;
-   unsigned i;
-   GLubyte *strz;
-   GLboolean result = GL_FALSE;
-   void *temp;
-   struct asm_symbol *sym;
-
-   state->ctx = ctx;
-   state->prog->Target = target;
-   state->prog->Parameters = _mesa_new_parameter_list();
-
-   /* Make a copy of the program string and force it to be NUL-terminated.
-    */
-   strz = (GLubyte *) malloc(len + 1);
-   if (strz == NULL) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
-      return GL_FALSE;
-   }
-   memcpy (strz, str, len);
-   strz[len] = '\0';
-
-   state->prog->String = strz;
-
-   state->st = _mesa_symbol_table_ctor();
-
-   state->limits = (target == GL_VERTEX_PROGRAM_ARB)
-      ? & ctx->Const.VertexProgram
-      : & ctx->Const.FragmentProgram;
-
-   state->MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits;
-   state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits;
-   state->MaxTextureUnits = ctx->Const.MaxTextureUnits;
-   state->MaxClipPlanes = ctx->Const.MaxClipPlanes;
-   state->MaxLights = ctx->Const.MaxLights;
-   state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices;
-
-   state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB)
-      ? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM;
-
-   _mesa_set_program_error(ctx, -1, NULL);
-
-   _mesa_program_lexer_ctor(& state->scanner, state, (const char *) str, len);
-   yyparse(state);
-   _mesa_program_lexer_dtor(state->scanner);
-
-
-   if (ctx->Program.ErrorPos != -1) {
-      goto error;
-   }
-
-   if (! _mesa_layout_parameters(state)) {
-      struct YYLTYPE loc;
-
-      loc.first_line = 0;
-      loc.first_column = 0;
-      loc.position = len;
-
-      yyerror(& loc, state, "invalid PARAM usage");
-      goto error;
-   }
-
-
-   
-   /* Add one instruction to store the "END" instruction.
-    */
-   state->prog->Instructions =
-      _mesa_alloc_instructions(state->prog->NumInstructions + 1);
-   inst = state->inst_head;
-   for (i = 0; i < state->prog->NumInstructions; i++) {
-      struct asm_instruction *const temp = inst->next;
-
-      state->prog->Instructions[i] = inst->Base;
-      inst = temp;
-   }
-
-   /* Finally, tag on an OPCODE_END instruction */
-   {
-      const GLuint numInst = state->prog->NumInstructions;
-      _mesa_init_instructions(state->prog->Instructions + numInst, 1);
-      state->prog->Instructions[numInst].Opcode = OPCODE_END;
-   }
-   state->prog->NumInstructions++;
-
-   state->prog->NumParameters = state->prog->Parameters->NumParameters;
-   state->prog->NumAttributes = _mesa_bitcount(state->prog->InputsRead);
-
-   /*
-    * Initialize native counts to logical counts.  The device driver may
-    * change them if program is translated into a hardware program.
-    */
-   state->prog->NumNativeInstructions = state->prog->NumInstructions;
-   state->prog->NumNativeTemporaries = state->prog->NumTemporaries;
-   state->prog->NumNativeParameters = state->prog->NumParameters;
-   state->prog->NumNativeAttributes = state->prog->NumAttributes;
-   state->prog->NumNativeAddressRegs = state->prog->NumAddressRegs;
-
-   result = GL_TRUE;
-
-error:
-   for (inst = state->inst_head; inst != NULL; inst = temp) {
-      temp = inst->next;
-      free(inst);
-   }
-
-   state->inst_head = NULL;
-   state->inst_tail = NULL;
-
-   for (sym = state->sym; sym != NULL; sym = temp) {
-      temp = sym->next;
-
-      free((void *) sym->name);
-      free(sym);
-   }
-   state->sym = NULL;
-
-   _mesa_symbol_table_dtor(state->st);
-   state->st = NULL;
-
-   return result;
-}
-
diff --git a/src/mesa/shader/program_parse.tab.h b/src/mesa/shader/program_parse.tab.h
deleted file mode 100644 (file)
index 045241d..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-
-/* A Bison parser, made by GNU Bison 2.4.1.  */
-
-/* Skeleton interface for Bison's Yacc-like parsers in C
-   
-      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, Inc.
-   
-   This program is free software: you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-   
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-   
-   You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
-
-/* As a special exception, you may create a larger work that contains
-   part or all of the Bison parser skeleton and distribute that work
-   under terms of your choice, so long as that work isn't itself a
-   parser generator using the skeleton or a modified version thereof
-   as a parser skeleton.  Alternatively, if you modify or redistribute
-   the parser skeleton itself, you may (at your option) remove this
-   special exception, which will cause the skeleton and the resulting
-   Bison output files to be licensed under the GNU General Public
-   License without this special exception.
-   
-   This special exception was added by the Free Software Foundation in
-   version 2.2 of Bison.  */
-
-
-/* Tokens.  */
-#ifndef YYTOKENTYPE
-# define YYTOKENTYPE
-   /* Put the tokens into the symbol table, so that GDB and other debuggers
-      know about them.  */
-   enum yytokentype {
-     ARBvp_10 = 258,
-     ARBfp_10 = 259,
-     ADDRESS = 260,
-     ALIAS = 261,
-     ATTRIB = 262,
-     OPTION = 263,
-     OUTPUT = 264,
-     PARAM = 265,
-     TEMP = 266,
-     END = 267,
-     BIN_OP = 268,
-     BINSC_OP = 269,
-     SAMPLE_OP = 270,
-     SCALAR_OP = 271,
-     TRI_OP = 272,
-     VECTOR_OP = 273,
-     ARL = 274,
-     KIL = 275,
-     SWZ = 276,
-     TXD_OP = 277,
-     INTEGER = 278,
-     REAL = 279,
-     AMBIENT = 280,
-     ATTENUATION = 281,
-     BACK = 282,
-     CLIP = 283,
-     COLOR = 284,
-     DEPTH = 285,
-     DIFFUSE = 286,
-     DIRECTION = 287,
-     EMISSION = 288,
-     ENV = 289,
-     EYE = 290,
-     FOG = 291,
-     FOGCOORD = 292,
-     FRAGMENT = 293,
-     FRONT = 294,
-     HALF = 295,
-     INVERSE = 296,
-     INVTRANS = 297,
-     LIGHT = 298,
-     LIGHTMODEL = 299,
-     LIGHTPROD = 300,
-     LOCAL = 301,
-     MATERIAL = 302,
-     MAT_PROGRAM = 303,
-     MATRIX = 304,
-     MATRIXINDEX = 305,
-     MODELVIEW = 306,
-     MVP = 307,
-     NORMAL = 308,
-     OBJECT = 309,
-     PALETTE = 310,
-     PARAMS = 311,
-     PLANE = 312,
-     POINT_TOK = 313,
-     POINTSIZE = 314,
-     POSITION = 315,
-     PRIMARY = 316,
-     PROGRAM = 317,
-     PROJECTION = 318,
-     RANGE = 319,
-     RESULT = 320,
-     ROW = 321,
-     SCENECOLOR = 322,
-     SECONDARY = 323,
-     SHININESS = 324,
-     SIZE_TOK = 325,
-     SPECULAR = 326,
-     SPOT = 327,
-     STATE = 328,
-     TEXCOORD = 329,
-     TEXENV = 330,
-     TEXGEN = 331,
-     TEXGEN_Q = 332,
-     TEXGEN_R = 333,
-     TEXGEN_S = 334,
-     TEXGEN_T = 335,
-     TEXTURE = 336,
-     TRANSPOSE = 337,
-     TEXTURE_UNIT = 338,
-     TEX_1D = 339,
-     TEX_2D = 340,
-     TEX_3D = 341,
-     TEX_CUBE = 342,
-     TEX_RECT = 343,
-     TEX_SHADOW1D = 344,
-     TEX_SHADOW2D = 345,
-     TEX_SHADOWRECT = 346,
-     TEX_ARRAY1D = 347,
-     TEX_ARRAY2D = 348,
-     TEX_ARRAYSHADOW1D = 349,
-     TEX_ARRAYSHADOW2D = 350,
-     VERTEX = 351,
-     VTXATTRIB = 352,
-     WEIGHT = 353,
-     IDENTIFIER = 354,
-     USED_IDENTIFIER = 355,
-     MASK4 = 356,
-     MASK3 = 357,
-     MASK2 = 358,
-     MASK1 = 359,
-     SWIZZLE = 360,
-     DOT_DOT = 361,
-     DOT = 362
-   };
-#endif
-
-
-
-#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
-typedef union YYSTYPE
-{
-
-/* Line 1676 of yacc.c  */
-#line 126 "program_parse.y"
-
-   struct asm_instruction *inst;
-   struct asm_symbol *sym;
-   struct asm_symbol temp_sym;
-   struct asm_swizzle_mask swiz_mask;
-   struct asm_src_register src_reg;
-   struct prog_dst_register dst_reg;
-   struct prog_instruction temp_inst;
-   char *string;
-   unsigned result;
-   unsigned attrib;
-   int integer;
-   float real;
-   gl_state_index state[STATE_LENGTH];
-   int negate;
-   struct asm_vector vector;
-   gl_inst_opcode opcode;
-
-   struct {
-      unsigned swz;
-      unsigned rgba_valid:1;
-      unsigned xyzw_valid:1;
-      unsigned negate:1;
-   } ext_swizzle;
-
-
-
-/* Line 1676 of yacc.c  */
-#line 187 "program_parse.tab.h"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
-# define yystype YYSTYPE /* obsolescent; will be withdrawn */
-# define YYSTYPE_IS_DECLARED 1
-#endif
-
-
-
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE
-{
-  int first_line;
-  int first_column;
-  int last_line;
-  int last_column;
-} YYLTYPE;
-# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-#endif
-
-
-
diff --git a/src/mesa/shader/program_parse.y b/src/mesa/shader/program_parse.y
deleted file mode 100644 (file)
index a2f34b8..0000000
+++ /dev/null
@@ -1,2767 +0,0 @@
-%{
-/*
- * Copyright Â© 2009 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "main/mtypes.h"
-#include "main/imports.h"
-#include "shader/program.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_parameter_layout.h"
-#include "shader/prog_statevars.h"
-#include "shader/prog_instruction.h"
-
-#include "shader/symbol_table.h"
-#include "shader/program_parser.h"
-
-extern void *yy_scan_string(char *);
-extern void yy_delete_buffer(void *);
-
-static struct asm_symbol *declare_variable(struct asm_parser_state *state,
-    char *name, enum asm_type t, struct YYLTYPE *locp);
-
-static int add_state_reference(struct gl_program_parameter_list *param_list,
-    const gl_state_index tokens[STATE_LENGTH]);
-
-static int initialize_symbol_from_state(struct gl_program *prog,
-    struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
-
-static int initialize_symbol_from_param(struct gl_program *prog,
-    struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
-
-static int initialize_symbol_from_const(struct gl_program *prog,
-    struct asm_symbol *param_var, const struct asm_vector *vec,
-    GLboolean allowSwizzle);
-
-static int yyparse(struct asm_parser_state *state);
-
-static char *make_error_string(const char *fmt, ...);
-
-static void yyerror(struct YYLTYPE *locp, struct asm_parser_state *state,
-    const char *s);
-
-static int validate_inputs(struct YYLTYPE *locp,
-    struct asm_parser_state *state);
-
-static void init_dst_reg(struct prog_dst_register *r);
-
-static void set_dst_reg(struct prog_dst_register *r,
-                        gl_register_file file, GLint index);
-
-static void init_src_reg(struct asm_src_register *r);
-
-static void set_src_reg(struct asm_src_register *r,
-                        gl_register_file file, GLint index);
-
-static void set_src_reg_swz(struct asm_src_register *r,
-                            gl_register_file file, GLint index, GLuint swizzle);
-
-static void asm_instruction_set_operands(struct asm_instruction *inst,
-    const struct prog_dst_register *dst, const struct asm_src_register *src0,
-    const struct asm_src_register *src1, const struct asm_src_register *src2);
-
-static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op,
-    const struct prog_dst_register *dst, const struct asm_src_register *src0,
-    const struct asm_src_register *src1, const struct asm_src_register *src2);
-
-static struct asm_instruction *asm_instruction_copy_ctor(
-    const struct prog_instruction *base, const struct prog_dst_register *dst,
-    const struct asm_src_register *src0, const struct asm_src_register *src1,
-    const struct asm_src_register *src2);
-
-#ifndef FALSE
-#define FALSE 0
-#define TRUE (!FALSE)
-#endif
-
-#define YYLLOC_DEFAULT(Current, Rhs, N)                                        \
-   do {                                                                        \
-      if (YYID(N)) {                                                   \
-        (Current).first_line = YYRHSLOC(Rhs, 1).first_line;            \
-        (Current).first_column = YYRHSLOC(Rhs, 1).first_column;        \
-        (Current).position = YYRHSLOC(Rhs, 1).position;                \
-        (Current).last_line = YYRHSLOC(Rhs, N).last_line;              \
-        (Current).last_column = YYRHSLOC(Rhs, N).last_column;          \
-      } else {                                                         \
-        (Current).first_line = YYRHSLOC(Rhs, 0).last_line;             \
-        (Current).last_line = (Current).first_line;                    \
-        (Current).first_column = YYRHSLOC(Rhs, 0).last_column;         \
-        (Current).last_column = (Current).first_column;                \
-        (Current).position = YYRHSLOC(Rhs, 0).position                 \
-           + (Current).first_column;                                   \
-      }                                                                        \
-   } while(YYID(0))
-
-#define YYLEX_PARAM state->scanner
-%}
-
-%pure-parser
-%locations
-%parse-param { struct asm_parser_state *state }
-%error-verbose
-%lex-param { void *scanner }
-
-%union {
-   struct asm_instruction *inst;
-   struct asm_symbol *sym;
-   struct asm_symbol temp_sym;
-   struct asm_swizzle_mask swiz_mask;
-   struct asm_src_register src_reg;
-   struct prog_dst_register dst_reg;
-   struct prog_instruction temp_inst;
-   char *string;
-   unsigned result;
-   unsigned attrib;
-   int integer;
-   float real;
-   gl_state_index state[STATE_LENGTH];
-   int negate;
-   struct asm_vector vector;
-   gl_inst_opcode opcode;
-
-   struct {
-      unsigned swz;
-      unsigned rgba_valid:1;
-      unsigned xyzw_valid:1;
-      unsigned negate:1;
-   } ext_swizzle;
-}
-
-%token ARBvp_10 ARBfp_10
-
-/* Tokens for assembler pseudo-ops */
-%token <integer> ADDRESS
-%token ALIAS ATTRIB
-%token OPTION OUTPUT
-%token PARAM
-%token <integer> TEMP
-%token END
-
- /* Tokens for instructions */
-%token <temp_inst> BIN_OP BINSC_OP SAMPLE_OP SCALAR_OP TRI_OP VECTOR_OP
-%token <temp_inst> ARL KIL SWZ TXD_OP
-
-%token <integer> INTEGER
-%token <real> REAL
-
-%token AMBIENT ATTENUATION
-%token BACK
-%token CLIP COLOR
-%token DEPTH DIFFUSE DIRECTION
-%token EMISSION ENV EYE
-%token FOG FOGCOORD FRAGMENT FRONT
-%token HALF
-%token INVERSE INVTRANS
-%token LIGHT LIGHTMODEL LIGHTPROD LOCAL
-%token MATERIAL MAT_PROGRAM MATRIX MATRIXINDEX MODELVIEW MVP
-%token NORMAL
-%token OBJECT
-%token PALETTE PARAMS PLANE POINT_TOK POINTSIZE POSITION PRIMARY PROGRAM PROJECTION
-%token RANGE RESULT ROW
-%token SCENECOLOR SECONDARY SHININESS SIZE_TOK SPECULAR SPOT STATE
-%token TEXCOORD TEXENV TEXGEN TEXGEN_Q TEXGEN_R TEXGEN_S TEXGEN_T TEXTURE TRANSPOSE
-%token TEXTURE_UNIT TEX_1D TEX_2D TEX_3D TEX_CUBE TEX_RECT
-%token TEX_SHADOW1D TEX_SHADOW2D TEX_SHADOWRECT
-%token TEX_ARRAY1D TEX_ARRAY2D TEX_ARRAYSHADOW1D TEX_ARRAYSHADOW2D 
-%token VERTEX VTXATTRIB
-%token WEIGHT
-
-%token <string> IDENTIFIER USED_IDENTIFIER
-%type <string> string
-%token <swiz_mask> MASK4 MASK3 MASK2 MASK1 SWIZZLE
-%token DOT_DOT
-%token DOT
-
-%type <inst> instruction ALU_instruction TexInstruction
-%type <inst> ARL_instruction VECTORop_instruction
-%type <inst> SCALARop_instruction BINSCop_instruction BINop_instruction
-%type <inst> TRIop_instruction TXD_instruction SWZ_instruction SAMPLE_instruction
-%type <inst> KIL_instruction
-
-%type <dst_reg> dstReg maskedDstReg maskedAddrReg
-%type <src_reg> srcReg scalarUse scalarSrcReg swizzleSrcReg
-%type <swiz_mask> scalarSuffix swizzleSuffix extendedSwizzle
-%type <ext_swizzle> extSwizComp extSwizSel
-%type <swiz_mask> optionalMask
-
-%type <sym> progParamArray
-%type <integer> addrRegRelOffset addrRegPosOffset addrRegNegOffset
-%type <src_reg> progParamArrayMem progParamArrayAbs progParamArrayRel
-%type <sym> addrReg
-%type <swiz_mask> addrComponent addrWriteMask
-
-%type <dst_reg> ccMaskRule ccTest ccMaskRule2 ccTest2 optionalCcMask
-
-%type <result> resultBinding resultColBinding
-%type <integer> optFaceType optColorType
-%type <integer> optResultFaceType optResultColorType
-
-%type <integer> optTexImageUnitNum texImageUnitNum
-%type <integer> optTexCoordUnitNum texCoordUnitNum
-%type <integer> optLegacyTexUnitNum legacyTexUnitNum
-%type <integer> texImageUnit texTarget
-%type <integer> vtxAttribNum
-
-%type <attrib> attribBinding vtxAttribItem fragAttribItem
-
-%type <temp_sym> paramSingleInit paramSingleItemDecl
-%type <integer> optArraySize
-
-%type <state> stateSingleItem stateMultipleItem
-%type <state> stateMaterialItem
-%type <state> stateLightItem stateLightModelItem stateLightProdItem
-%type <state> stateTexGenItem stateFogItem stateClipPlaneItem statePointItem
-%type <state> stateMatrixItem stateMatrixRow stateMatrixRows
-%type <state> stateTexEnvItem stateDepthItem
-
-%type <state> stateLModProperty
-%type <state> stateMatrixName optMatrixRows
-
-%type <integer> stateMatProperty
-%type <integer> stateLightProperty stateSpotProperty
-%type <integer> stateLightNumber stateLProdProperty
-%type <integer> stateTexGenType stateTexGenCoord
-%type <integer> stateTexEnvProperty
-%type <integer> stateFogProperty
-%type <integer> stateClipPlaneNum
-%type <integer> statePointProperty
-
-%type <integer> stateOptMatModifier stateMatModifier stateMatrixRowNum
-%type <integer> stateOptModMatNum stateModMatNum statePaletteMatNum 
-%type <integer> stateProgramMatNum
-
-%type <integer> ambDiffSpecProperty
-
-%type <state> programSingleItem progEnvParam progLocalParam
-%type <state> programMultipleItem progEnvParams progLocalParams
-
-%type <temp_sym> paramMultipleInit paramMultInitList paramMultipleItem
-%type <temp_sym> paramSingleItemUse
-
-%type <integer> progEnvParamNum progLocalParamNum
-%type <state> progEnvParamNums progLocalParamNums
-
-%type <vector> paramConstDecl paramConstUse
-%type <vector> paramConstScalarDecl paramConstScalarUse paramConstVector
-%type <real> signedFloatConstant
-%type <negate> optionalSign
-
-%{
-extern int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
-    void *yyscanner);
-%}
-
-%%
-
-program: language optionSequence statementSequence END
-       ;
-
-language: ARBvp_10
-       {
-          if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) {
-             yyerror(& @1, state, "invalid fragment program header");
-
-          }
-          state->mode = ARB_vertex;
-       }
-       | ARBfp_10
-       {
-          if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) {
-             yyerror(& @1, state, "invalid vertex program header");
-          }
-          state->mode = ARB_fragment;
-
-          state->option.TexRect =
-             (state->ctx->Extensions.NV_texture_rectangle != GL_FALSE);
-       }
-       ;
-
-optionSequence: optionSequence option
-       |
-       ;
-
-option: OPTION string ';'
-       {
-          int valid = 0;
-
-          if (state->mode == ARB_vertex) {
-             valid = _mesa_ARBvp_parse_option(state, $2);
-          } else if (state->mode == ARB_fragment) {
-             valid = _mesa_ARBfp_parse_option(state, $2);
-          }
-
-
-          free($2);
-
-          if (!valid) {
-             const char *const err_str = (state->mode == ARB_vertex)
-                ? "invalid ARB vertex program option"
-                : "invalid ARB fragment program option";
-
-             yyerror(& @2, state, err_str);
-             YYERROR;
-          }
-       }
-       ;
-
-statementSequence: statementSequence statement
-       |
-       ;
-
-statement: instruction ';'
-       {
-          if ($1 != NULL) {
-             if (state->inst_tail == NULL) {
-                state->inst_head = $1;
-             } else {
-                state->inst_tail->next = $1;
-             }
-
-             state->inst_tail = $1;
-             $1->next = NULL;
-
-             state->prog->NumInstructions++;
-          }
-       }
-       | namingStatement ';'
-       ;
-
-instruction: ALU_instruction
-       {
-          $$ = $1;
-          state->prog->NumAluInstructions++;
-       }
-       | TexInstruction
-       {
-          $$ = $1;
-          state->prog->NumTexInstructions++;
-       }
-       ;
-
-ALU_instruction: ARL_instruction
-       | VECTORop_instruction
-       | SCALARop_instruction
-       | BINSCop_instruction
-       | BINop_instruction
-       | TRIop_instruction
-       | SWZ_instruction
-       ;
-
-TexInstruction: SAMPLE_instruction
-       | KIL_instruction
-       | TXD_instruction
-       ;
-
-ARL_instruction: ARL maskedAddrReg ',' scalarSrcReg
-       {
-          $$ = asm_instruction_ctor(OPCODE_ARL, & $2, & $4, NULL, NULL);
-       }
-       ;
-
-VECTORop_instruction: VECTOR_OP maskedDstReg ',' swizzleSrcReg
-       {
-          $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
-       }
-       ;
-
-SCALARop_instruction: SCALAR_OP maskedDstReg ',' scalarSrcReg
-       {
-          $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
-       }
-       ;
-
-BINSCop_instruction: BINSC_OP maskedDstReg ',' scalarSrcReg ',' scalarSrcReg
-       {
-          $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL);
-       }
-       ;
-
-
-BINop_instruction: BIN_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg
-       {
-          $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL);
-       }
-       ;
-
-TRIop_instruction: TRI_OP maskedDstReg ','
-                   swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg
-       {
-          $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8);
-       }
-       ;
-
-SAMPLE_instruction: SAMPLE_OP maskedDstReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
-       {
-          $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
-          if ($$ != NULL) {
-             const GLbitfield tex_mask = (1U << $6);
-             GLbitfield shadow_tex = 0;
-             GLbitfield target_mask = 0;
-
-
-             $$->Base.TexSrcUnit = $6;
-
-             if ($8 < 0) {
-                shadow_tex = tex_mask;
-
-                $$->Base.TexSrcTarget = -$8;
-                $$->Base.TexShadow = 1;
-             } else {
-                $$->Base.TexSrcTarget = $8;
-             }
-
-             target_mask = (1U << $$->Base.TexSrcTarget);
-
-             /* If this texture unit was previously accessed and that access
-              * had a different texture target, generate an error.
-              *
-              * If this texture unit was previously accessed and that access
-              * had a different shadow mode, generate an error.
-              */
-             if ((state->prog->TexturesUsed[$6] != 0)
-                 && ((state->prog->TexturesUsed[$6] != target_mask)
-                     || ((state->prog->ShadowSamplers & tex_mask)
-                         != shadow_tex))) {
-                yyerror(& @8, state,
-                        "multiple targets used on one texture image unit");
-                YYERROR;
-             }
-
-
-             state->prog->TexturesUsed[$6] |= target_mask;
-             state->prog->ShadowSamplers |= shadow_tex;
-          }
-       }
-       ;
-
-KIL_instruction: KIL swizzleSrcReg
-       {
-          $$ = asm_instruction_ctor(OPCODE_KIL, NULL, & $2, NULL, NULL);
-          state->fragment.UsesKill = 1;
-       }
-       | KIL ccTest
-       {
-          $$ = asm_instruction_ctor(OPCODE_KIL_NV, NULL, NULL, NULL, NULL);
-          $$->Base.DstReg.CondMask = $2.CondMask;
-          $$->Base.DstReg.CondSwizzle = $2.CondSwizzle;
-          $$->Base.DstReg.CondSrc = $2.CondSrc;
-          state->fragment.UsesKill = 1;
-       }
-       ;
-
-TXD_instruction: TXD_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
-       {
-          $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8);
-          if ($$ != NULL) {
-             const GLbitfield tex_mask = (1U << $10);
-             GLbitfield shadow_tex = 0;
-             GLbitfield target_mask = 0;
-
-
-             $$->Base.TexSrcUnit = $10;
-
-             if ($12 < 0) {
-                shadow_tex = tex_mask;
-
-                $$->Base.TexSrcTarget = -$12;
-                $$->Base.TexShadow = 1;
-             } else {
-                $$->Base.TexSrcTarget = $12;
-             }
-
-             target_mask = (1U << $$->Base.TexSrcTarget);
-
-             /* If this texture unit was previously accessed and that access
-              * had a different texture target, generate an error.
-              *
-              * If this texture unit was previously accessed and that access
-              * had a different shadow mode, generate an error.
-              */
-             if ((state->prog->TexturesUsed[$10] != 0)
-                 && ((state->prog->TexturesUsed[$10] != target_mask)
-                     || ((state->prog->ShadowSamplers & tex_mask)
-                         != shadow_tex))) {
-                yyerror(& @12, state,
-                        "multiple targets used on one texture image unit");
-                YYERROR;
-             }
-
-
-             state->prog->TexturesUsed[$10] |= target_mask;
-             state->prog->ShadowSamplers |= shadow_tex;
-          }
-       }
-       ;
-
-texImageUnit: TEXTURE_UNIT optTexImageUnitNum
-       {
-          $$ = $2;
-       }
-       ;
-
-texTarget: TEX_1D  { $$ = TEXTURE_1D_INDEX; }
-       | TEX_2D   { $$ = TEXTURE_2D_INDEX; }
-       | TEX_3D   { $$ = TEXTURE_3D_INDEX; }
-       | TEX_CUBE { $$ = TEXTURE_CUBE_INDEX; }
-       | TEX_RECT { $$ = TEXTURE_RECT_INDEX; }
-       | TEX_SHADOW1D   { $$ = -TEXTURE_1D_INDEX; }
-       | TEX_SHADOW2D   { $$ = -TEXTURE_2D_INDEX; }
-       | TEX_SHADOWRECT { $$ = -TEXTURE_RECT_INDEX; }
-       | TEX_ARRAY1D         { $$ = TEXTURE_1D_ARRAY_INDEX; }
-       | TEX_ARRAY2D         { $$ = TEXTURE_2D_ARRAY_INDEX; }
-       | TEX_ARRAYSHADOW1D   { $$ = -TEXTURE_1D_ARRAY_INDEX; }
-       | TEX_ARRAYSHADOW2D   { $$ = -TEXTURE_2D_ARRAY_INDEX; }
-       ;
-
-SWZ_instruction: SWZ maskedDstReg ',' srcReg ',' extendedSwizzle
-       {
-          /* FIXME: Is this correct?  Should the extenedSwizzle be applied
-           * FIXME: to the existing swizzle?
-           */
-          $4.Base.Swizzle = $6.swizzle;
-          $4.Base.Negate = $6.mask;
-
-          $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL);
-       }
-       ;
-
-scalarSrcReg: optionalSign scalarUse
-       {
-          $$ = $2;
-
-          if ($1) {
-             $$.Base.Negate = ~$$.Base.Negate;
-          }
-       }
-       | optionalSign '|' scalarUse '|'
-       {
-          $$ = $3;
-
-          if (!state->option.NV_fragment) {
-             yyerror(& @2, state, "unexpected character '|'");
-             YYERROR;
-          }
-
-          if ($1) {
-             $$.Base.Negate = ~$$.Base.Negate;
-          }
-
-          $$.Base.Abs = 1;
-       }
-       ;
-
-scalarUse:  srcReg scalarSuffix
-       {
-          $$ = $1;
-
-          $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
-                                                   $2.swizzle);
-       }
-       | paramConstScalarUse
-       {
-          struct asm_symbol temp_sym;
-
-          if (!state->option.NV_fragment) {
-             yyerror(& @1, state, "expected scalar suffix");
-             YYERROR;
-          }
-
-          memset(& temp_sym, 0, sizeof(temp_sym));
-          temp_sym.param_binding_begin = ~0;
-          initialize_symbol_from_const(state->prog, & temp_sym, & $1, GL_TRUE);
-
-          set_src_reg_swz(& $$, PROGRAM_CONSTANT,
-                           temp_sym.param_binding_begin,
-                           temp_sym.param_binding_swizzle);
-       }
-       ;
-
-swizzleSrcReg: optionalSign srcReg swizzleSuffix
-       {
-          $$ = $2;
-
-          if ($1) {
-             $$.Base.Negate = ~$$.Base.Negate;
-          }
-
-          $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
-                                                   $3.swizzle);
-       }
-       | optionalSign '|' srcReg swizzleSuffix '|'
-       {
-          $$ = $3;
-
-          if (!state->option.NV_fragment) {
-             yyerror(& @2, state, "unexpected character '|'");
-             YYERROR;
-          }
-
-          if ($1) {
-             $$.Base.Negate = ~$$.Base.Negate;
-          }
-
-          $$.Base.Abs = 1;
-          $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
-                                                   $4.swizzle);
-       }
-
-       ;
-
-maskedDstReg: dstReg optionalMask optionalCcMask
-       {
-          $$ = $1;
-          $$.WriteMask = $2.mask;
-          $$.CondMask = $3.CondMask;
-          $$.CondSwizzle = $3.CondSwizzle;
-          $$.CondSrc = $3.CondSrc;
-
-          if ($$.File == PROGRAM_OUTPUT) {
-             /* Technically speaking, this should check that it is in
-              * vertex program mode.  However, PositionInvariant can never be
-              * set in fragment program mode, so it is somewhat irrelevant.
-              */
-             if (state->option.PositionInvariant
-              && ($$.Index == VERT_RESULT_HPOS)) {
-                yyerror(& @1, state, "position-invariant programs cannot "
-                        "write position");
-                YYERROR;
-             }
-
-             state->prog->OutputsWritten |= BITFIELD64_BIT($$.Index);
-          }
-       }
-       ;
-
-maskedAddrReg: addrReg addrWriteMask
-       {
-          set_dst_reg(& $$, PROGRAM_ADDRESS, 0);
-          $$.WriteMask = $2.mask;
-       }
-       ;
-
-extendedSwizzle: extSwizComp ',' extSwizComp ',' extSwizComp ',' extSwizComp
-       {
-          const unsigned xyzw_valid =
-             ($1.xyzw_valid << 0)
-             | ($3.xyzw_valid << 1)
-             | ($5.xyzw_valid << 2)
-             | ($7.xyzw_valid << 3);
-          const unsigned rgba_valid =
-             ($1.rgba_valid << 0)
-             | ($3.rgba_valid << 1)
-             | ($5.rgba_valid << 2)
-             | ($7.rgba_valid << 3);
-
-          /* All of the swizzle components have to be valid in either RGBA
-           * or XYZW.  Note that 0 and 1 are valid in both, so both masks
-           * can have some bits set.
-           *
-           * We somewhat deviate from the spec here.  It would be really hard
-           * to figure out which component is the error, and there probably
-           * isn't a lot of benefit.
-           */
-          if ((rgba_valid != 0x0f) && (xyzw_valid != 0x0f)) {
-             yyerror(& @1, state, "cannot combine RGBA and XYZW swizzle "
-                     "components");
-             YYERROR;
-          }
-
-          $$.swizzle = MAKE_SWIZZLE4($1.swz, $3.swz, $5.swz, $7.swz);
-          $$.mask = ($1.negate) | ($3.negate << 1) | ($5.negate << 2)
-             | ($7.negate << 3);
-       }
-       ;
-
-extSwizComp: optionalSign extSwizSel
-       {
-          $$ = $2;
-          $$.negate = ($1) ? 1 : 0;
-       }
-       ;
-
-extSwizSel: INTEGER
-       {
-          if (($1 != 0) && ($1 != 1)) {
-             yyerror(& @1, state, "invalid extended swizzle selector");
-             YYERROR;
-          }
-
-          $$.swz = ($1 == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE;
-
-          /* 0 and 1 are valid for both RGBA swizzle names and XYZW
-           * swizzle names.
-           */
-          $$.xyzw_valid = 1;
-          $$.rgba_valid = 1;
-       }
-       | string
-       {
-          char s;
-
-          if (strlen($1) > 1) {
-             yyerror(& @1, state, "invalid extended swizzle selector");
-             YYERROR;
-          }
-
-          s = $1[0];
-          free($1);
-
-          switch (s) {
-          case 'x':
-             $$.swz = SWIZZLE_X;
-             $$.xyzw_valid = 1;
-             break;
-          case 'y':
-             $$.swz = SWIZZLE_Y;
-             $$.xyzw_valid = 1;
-             break;
-          case 'z':
-             $$.swz = SWIZZLE_Z;
-             $$.xyzw_valid = 1;
-             break;
-          case 'w':
-             $$.swz = SWIZZLE_W;
-             $$.xyzw_valid = 1;
-             break;
-
-          case 'r':
-             $$.swz = SWIZZLE_X;
-             $$.rgba_valid = 1;
-             break;
-          case 'g':
-             $$.swz = SWIZZLE_Y;
-             $$.rgba_valid = 1;
-             break;
-          case 'b':
-             $$.swz = SWIZZLE_Z;
-             $$.rgba_valid = 1;
-             break;
-          case 'a':
-             $$.swz = SWIZZLE_W;
-             $$.rgba_valid = 1;
-             break;
-
-          default:
-             yyerror(& @1, state, "invalid extended swizzle selector");
-             YYERROR;
-             break;
-          }
-       }
-       ;
-
-srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */
-       {
-          struct asm_symbol *const s = (struct asm_symbol *)
-             _mesa_symbol_table_find_symbol(state->st, 0, $1);
-
-          free($1);
-
-          if (s == NULL) {
-             yyerror(& @1, state, "invalid operand variable");
-             YYERROR;
-          } else if ((s->type != at_param) && (s->type != at_temp)
-                     && (s->type != at_attrib)) {
-             yyerror(& @1, state, "invalid operand variable");
-             YYERROR;
-          } else if ((s->type == at_param) && s->param_is_array) {
-             yyerror(& @1, state, "non-array access to array PARAM");
-             YYERROR;
-          }
-
-          init_src_reg(& $$);
-          switch (s->type) {
-          case at_temp:
-             set_src_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding);
-             break;
-          case at_param:
-              set_src_reg_swz(& $$, s->param_binding_type,
-                              s->param_binding_begin,
-                              s->param_binding_swizzle);
-             break;
-          case at_attrib:
-             set_src_reg(& $$, PROGRAM_INPUT, s->attrib_binding);
-             state->prog->InputsRead |= (1U << $$.Base.Index);
-
-             if (!validate_inputs(& @1, state)) {
-                YYERROR;
-             }
-             break;
-
-          default:
-             YYERROR;
-             break;
-          }
-       }
-       | attribBinding
-       {
-          set_src_reg(& $$, PROGRAM_INPUT, $1);
-          state->prog->InputsRead |= (1U << $$.Base.Index);
-
-          if (!validate_inputs(& @1, state)) {
-             YYERROR;
-          }
-       }
-       | progParamArray '[' progParamArrayMem ']'
-       {
-          if (! $3.Base.RelAddr
-              && ((unsigned) $3.Base.Index >= $1->param_binding_length)) {
-             yyerror(& @3, state, "out of bounds array access");
-             YYERROR;
-          }
-
-          init_src_reg(& $$);
-          $$.Base.File = $1->param_binding_type;
-
-          if ($3.Base.RelAddr) {
-             $1->param_accessed_indirectly = 1;
-
-             $$.Base.RelAddr = 1;
-             $$.Base.Index = $3.Base.Index;
-             $$.Symbol = $1;
-          } else {
-             $$.Base.Index = $1->param_binding_begin + $3.Base.Index;
-          }
-       }
-       | paramSingleItemUse
-       {
-           gl_register_file file = ($1.name != NULL) 
-             ? $1.param_binding_type
-             : PROGRAM_CONSTANT;
-           set_src_reg_swz(& $$, file, $1.param_binding_begin,
-                           $1.param_binding_swizzle);
-       }
-       ;
-
-dstReg: resultBinding
-       {
-          set_dst_reg(& $$, PROGRAM_OUTPUT, $1);
-       }
-       | USED_IDENTIFIER /* temporaryReg | vertexResultReg */
-       {
-          struct asm_symbol *const s = (struct asm_symbol *)
-             _mesa_symbol_table_find_symbol(state->st, 0, $1);
-
-          free($1);
-
-          if (s == NULL) {
-             yyerror(& @1, state, "invalid operand variable");
-             YYERROR;
-          } else if ((s->type != at_output) && (s->type != at_temp)) {
-             yyerror(& @1, state, "invalid operand variable");
-             YYERROR;
-          }
-
-          switch (s->type) {
-          case at_temp:
-             set_dst_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding);
-             break;
-          case at_output:
-             set_dst_reg(& $$, PROGRAM_OUTPUT, s->output_binding);
-             break;
-          default:
-             set_dst_reg(& $$, s->param_binding_type, s->param_binding_begin);
-             break;
-          }
-       }
-       ;
-
-progParamArray: USED_IDENTIFIER
-       {
-          struct asm_symbol *const s = (struct asm_symbol *)
-             _mesa_symbol_table_find_symbol(state->st, 0, $1);
-
-          free($1);
-
-          if (s == NULL) {
-             yyerror(& @1, state, "invalid operand variable");
-             YYERROR;
-          } else if ((s->type != at_param) || !s->param_is_array) {
-             yyerror(& @1, state, "array access to non-PARAM variable");
-             YYERROR;
-          } else {
-             $$ = s;
-          }
-       }
-       ;
-
-progParamArrayMem: progParamArrayAbs | progParamArrayRel;
-
-progParamArrayAbs: INTEGER
-       {
-          init_src_reg(& $$);
-          $$.Base.Index = $1;
-       }
-       ;
-
-progParamArrayRel: addrReg addrComponent addrRegRelOffset
-       {
-          /* FINISHME: Add support for multiple address registers.
-           */
-          /* FINISHME: Add support for 4-component address registers.
-           */
-          init_src_reg(& $$);
-          $$.Base.RelAddr = 1;
-          $$.Base.Index = $3;
-       }
-       ;
-
-addrRegRelOffset:              { $$ = 0; }
-       | '+' addrRegPosOffset { $$ = $2; }
-       | '-' addrRegNegOffset { $$ = -$2; }
-       ;
-
-addrRegPosOffset: INTEGER
-       {
-          if (($1 < 0) || ($1 > 63)) {
-              char s[100];
-              _mesa_snprintf(s, sizeof(s),
-                             "relative address offset too large (%d)", $1);
-             yyerror(& @1, state, s);
-             YYERROR;
-          } else {
-             $$ = $1;
-          }
-       }
-       ;
-
-addrRegNegOffset: INTEGER
-       {
-          if (($1 < 0) || ($1 > 64)) {
-              char s[100];
-              _mesa_snprintf(s, sizeof(s),
-                             "relative address offset too large (%d)", $1);
-             yyerror(& @1, state, s);
-             YYERROR;
-          } else {
-             $$ = $1;
-          }
-       }
-       ;
-
-addrReg: USED_IDENTIFIER
-       {
-          struct asm_symbol *const s = (struct asm_symbol *)
-             _mesa_symbol_table_find_symbol(state->st, 0, $1);
-
-          free($1);
-
-          if (s == NULL) {
-             yyerror(& @1, state, "invalid array member");
-             YYERROR;
-          } else if (s->type != at_address) {
-             yyerror(& @1, state,
-                     "invalid variable for indexed array access");
-             YYERROR;
-          } else {
-             $$ = s;
-          }
-       }
-       ;
-
-addrComponent: MASK1
-       {
-          if ($1.mask != WRITEMASK_X) {
-             yyerror(& @1, state, "invalid address component selector");
-             YYERROR;
-          } else {
-             $$ = $1;
-          }
-       }
-       ;
-
-addrWriteMask: MASK1
-       {
-          if ($1.mask != WRITEMASK_X) {
-             yyerror(& @1, state,
-                     "address register write mask must be \".x\"");
-             YYERROR;
-          } else {
-             $$ = $1;
-          }
-       }
-       ;
-
-scalarSuffix: MASK1;
-
-swizzleSuffix: MASK1
-       | MASK4
-       | SWIZZLE
-       |              { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
-       ;
-
-optionalMask: MASK4 | MASK3 | MASK2 | MASK1 
-       |              { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
-       ;
-
-optionalCcMask: '(' ccTest ')'
-       {
-          $$ = $2;
-       }
-       | '(' ccTest2 ')'
-       {
-          $$ = $2;
-       }
-       |
-       {
-          $$.CondMask = COND_TR;
-          $$.CondSwizzle = SWIZZLE_NOOP;
-          $$.CondSrc = 0;
-       }
-       ;
-
-ccTest: ccMaskRule swizzleSuffix
-       {
-          $$ = $1;
-          $$.CondSwizzle = $2.swizzle;
-       }
-       ;
-
-ccTest2: ccMaskRule2 swizzleSuffix
-       {
-          $$ = $1;
-          $$.CondSwizzle = $2.swizzle;
-       }
-       ;
-
-ccMaskRule: IDENTIFIER
-       {
-          const int cond = _mesa_parse_cc($1);
-          if ((cond == 0) || ($1[2] != '\0')) {
-             char *const err_str =
-                make_error_string("invalid condition code \"%s\"", $1);
-
-             yyerror(& @1, state, (err_str != NULL)
-                     ? err_str : "invalid condition code");
-
-             if (err_str != NULL) {
-                free(err_str);
-             }
-
-             YYERROR;
-          }
-
-          $$.CondMask = cond;
-          $$.CondSwizzle = SWIZZLE_NOOP;
-          $$.CondSrc = 0;
-       }
-       ;
-
-ccMaskRule2: USED_IDENTIFIER
-       {
-          const int cond = _mesa_parse_cc($1);
-          if ((cond == 0) || ($1[2] != '\0')) {
-             char *const err_str =
-                make_error_string("invalid condition code \"%s\"", $1);
-
-             yyerror(& @1, state, (err_str != NULL)
-                     ? err_str : "invalid condition code");
-
-             if (err_str != NULL) {
-                free(err_str);
-             }
-
-             YYERROR;
-          }
-
-          $$.CondMask = cond;
-          $$.CondSwizzle = SWIZZLE_NOOP;
-          $$.CondSrc = 0;
-       }
-       ;
-
-namingStatement: ATTRIB_statement
-       | PARAM_statement
-       | TEMP_statement
-       | ADDRESS_statement
-       | OUTPUT_statement
-       | ALIAS_statement
-       ;
-
-ATTRIB_statement: ATTRIB IDENTIFIER '=' attribBinding
-       {
-          struct asm_symbol *const s =
-             declare_variable(state, $2, at_attrib, & @2);
-
-          if (s == NULL) {
-             free($2);
-             YYERROR;
-          } else {
-             s->attrib_binding = $4;
-             state->InputsBound |= (1U << s->attrib_binding);
-
-             if (!validate_inputs(& @4, state)) {
-                YYERROR;
-             }
-          }
-       }
-       ;
-
-attribBinding: VERTEX vtxAttribItem
-       {
-          $$ = $2;
-       }
-       | FRAGMENT fragAttribItem
-       {
-          $$ = $2;
-       }
-       ;
-
-vtxAttribItem: POSITION
-       {
-          $$ = VERT_ATTRIB_POS;
-       }
-       | WEIGHT vtxOptWeightNum
-       {
-          $$ = VERT_ATTRIB_WEIGHT;
-       }
-       | NORMAL
-       {
-          $$ = VERT_ATTRIB_NORMAL;
-       }
-       | COLOR optColorType
-       {
-          if (!state->ctx->Extensions.EXT_secondary_color) {
-             yyerror(& @2, state, "GL_EXT_secondary_color not supported");
-             YYERROR;
-          }
-
-          $$ = VERT_ATTRIB_COLOR0 + $2;
-       }
-       | FOGCOORD
-       {
-          if (!state->ctx->Extensions.EXT_fog_coord) {
-             yyerror(& @1, state, "GL_EXT_fog_coord not supported");
-             YYERROR;
-          }
-
-          $$ = VERT_ATTRIB_FOG;
-       }
-       | TEXCOORD optTexCoordUnitNum
-       {
-          $$ = VERT_ATTRIB_TEX0 + $2;
-       }
-       | MATRIXINDEX '[' vtxWeightNum ']'
-       {
-          yyerror(& @1, state, "GL_ARB_matrix_palette not supported");
-          YYERROR;
-       }
-       | VTXATTRIB '[' vtxAttribNum ']'
-       {
-          $$ = VERT_ATTRIB_GENERIC0 + $3;
-       }
-       ;
-
-vtxAttribNum: INTEGER
-       {
-          if ((unsigned) $1 >= state->limits->MaxAttribs) {
-             yyerror(& @1, state, "invalid vertex attribute reference");
-             YYERROR;
-          }
-
-          $$ = $1;
-       }
-       ;
-
-vtxOptWeightNum:  | '[' vtxWeightNum ']';
-vtxWeightNum: INTEGER;
-
-fragAttribItem: POSITION
-       {
-          $$ = FRAG_ATTRIB_WPOS;
-       }
-       | COLOR optColorType
-       {
-          $$ = FRAG_ATTRIB_COL0 + $2;
-       }
-       | FOGCOORD
-       {
-          $$ = FRAG_ATTRIB_FOGC;
-       }
-       | TEXCOORD optTexCoordUnitNum
-       {
-          $$ = FRAG_ATTRIB_TEX0 + $2;
-       }
-       ;
-
-PARAM_statement: PARAM_singleStmt | PARAM_multipleStmt;
-
-PARAM_singleStmt: PARAM IDENTIFIER paramSingleInit
-       {
-          struct asm_symbol *const s =
-             declare_variable(state, $2, at_param, & @2);
-
-          if (s == NULL) {
-             free($2);
-             YYERROR;
-          } else {
-             s->param_binding_type = $3.param_binding_type;
-             s->param_binding_begin = $3.param_binding_begin;
-             s->param_binding_length = $3.param_binding_length;
-              s->param_binding_swizzle = $3.param_binding_swizzle;
-             s->param_is_array = 0;
-          }
-       }
-       ;
-
-PARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit
-       {
-          if (($4 != 0) && ((unsigned) $4 != $6.param_binding_length)) {
-             free($2);
-             yyerror(& @4, state, 
-                     "parameter array size and number of bindings must match");
-             YYERROR;
-          } else {
-             struct asm_symbol *const s =
-                declare_variable(state, $2, $6.type, & @2);
-
-             if (s == NULL) {
-                free($2);
-                YYERROR;
-             } else {
-                s->param_binding_type = $6.param_binding_type;
-                s->param_binding_begin = $6.param_binding_begin;
-                s->param_binding_length = $6.param_binding_length;
-                 s->param_binding_swizzle = SWIZZLE_XYZW;
-                s->param_is_array = 1;
-             }
-          }
-       }
-       ;
-
-optArraySize:
-       {
-          $$ = 0;
-       }
-       | INTEGER
-        {
-          if (($1 < 1) || ((unsigned) $1 > state->limits->MaxParameters)) {
-             yyerror(& @1, state, "invalid parameter array size");
-             YYERROR;
-          } else {
-             $$ = $1;
-          }
-       }
-       ;
-
-paramSingleInit: '=' paramSingleItemDecl
-       {
-          $$ = $2;
-       }
-       ;
-
-paramMultipleInit: '=' '{' paramMultInitList '}'
-       {
-          $$ = $3;
-       }
-       ;
-
-paramMultInitList: paramMultipleItem
-       | paramMultInitList ',' paramMultipleItem
-       {
-          $1.param_binding_length += $3.param_binding_length;
-          $$ = $1;
-       }
-       ;
-
-paramSingleItemDecl: stateSingleItem
-       {
-          memset(& $$, 0, sizeof($$));
-          $$.param_binding_begin = ~0;
-          initialize_symbol_from_state(state->prog, & $$, $1);
-       }
-       | programSingleItem
-       {
-          memset(& $$, 0, sizeof($$));
-          $$.param_binding_begin = ~0;
-          initialize_symbol_from_param(state->prog, & $$, $1);
-       }
-       | paramConstDecl
-       {
-          memset(& $$, 0, sizeof($$));
-          $$.param_binding_begin = ~0;
-          initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE);
-       }
-       ;
-
-paramSingleItemUse: stateSingleItem
-       {
-          memset(& $$, 0, sizeof($$));
-          $$.param_binding_begin = ~0;
-          initialize_symbol_from_state(state->prog, & $$, $1);
-       }
-       | programSingleItem
-       {
-          memset(& $$, 0, sizeof($$));
-          $$.param_binding_begin = ~0;
-          initialize_symbol_from_param(state->prog, & $$, $1);
-       }
-       | paramConstUse
-       {
-          memset(& $$, 0, sizeof($$));
-          $$.param_binding_begin = ~0;
-          initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE);
-       }
-       ;
-
-paramMultipleItem: stateMultipleItem
-       {
-          memset(& $$, 0, sizeof($$));
-          $$.param_binding_begin = ~0;
-          initialize_symbol_from_state(state->prog, & $$, $1);
-       }
-       | programMultipleItem
-       {
-          memset(& $$, 0, sizeof($$));
-          $$.param_binding_begin = ~0;
-          initialize_symbol_from_param(state->prog, & $$, $1);
-       }
-       | paramConstDecl
-       {
-          memset(& $$, 0, sizeof($$));
-          $$.param_binding_begin = ~0;
-          initialize_symbol_from_const(state->prog, & $$, & $1, GL_FALSE);
-       }
-       ;
-
-stateMultipleItem: stateSingleItem        { memcpy($$, $1, sizeof($$)); }
-       | STATE stateMatrixRows           { memcpy($$, $2, sizeof($$)); }
-       ;
-
-stateSingleItem: STATE stateMaterialItem  { memcpy($$, $2, sizeof($$)); }
-       | STATE stateLightItem            { memcpy($$, $2, sizeof($$)); }
-       | STATE stateLightModelItem       { memcpy($$, $2, sizeof($$)); }
-       | STATE stateLightProdItem        { memcpy($$, $2, sizeof($$)); }
-       | STATE stateTexGenItem           { memcpy($$, $2, sizeof($$)); }
-       | STATE stateTexEnvItem           { memcpy($$, $2, sizeof($$)); }
-       | STATE stateFogItem              { memcpy($$, $2, sizeof($$)); }
-       | STATE stateClipPlaneItem        { memcpy($$, $2, sizeof($$)); }
-       | STATE statePointItem            { memcpy($$, $2, sizeof($$)); }
-       | STATE stateMatrixRow            { memcpy($$, $2, sizeof($$)); }
-       | STATE stateDepthItem            { memcpy($$, $2, sizeof($$)); }
-       ;
-
-stateMaterialItem: MATERIAL optFaceType stateMatProperty
-       {
-          memset($$, 0, sizeof($$));
-          $$[0] = STATE_MATERIAL;
-          $$[1] = $2;
-          $$[2] = $3;
-       }
-       ;
-
-stateMatProperty: ambDiffSpecProperty
-       {
-          $$ = $1;
-       }
-       | EMISSION
-       {
-          $$ = STATE_EMISSION;
-       }
-       | SHININESS
-       {
-          $$ = STATE_SHININESS;
-       }
-       ;
-
-stateLightItem: LIGHT '[' stateLightNumber ']' stateLightProperty
-       {
-          memset($$, 0, sizeof($$));
-          $$[0] = STATE_LIGHT;
-          $$[1] = $3;
-          $$[2] = $5;
-       }
-       ;
-
-stateLightProperty: ambDiffSpecProperty
-       {
-          $$ = $1;
-       }
-       | POSITION
-       {
-          $$ = STATE_POSITION;
-       }
-       | ATTENUATION
-       {
-          if (!state->ctx->Extensions.EXT_point_parameters) {
-             yyerror(& @1, state, "GL_ARB_point_parameters not supported");
-             YYERROR;
-          }
-
-          $$ = STATE_ATTENUATION;
-       }
-       | SPOT stateSpotProperty
-       {
-          $$ = $2;
-       }
-       | HALF
-       {
-          $$ = STATE_HALF_VECTOR;
-       }
-       ;
-
-stateSpotProperty: DIRECTION
-       {
-          $$ = STATE_SPOT_DIRECTION;
-       }
-       ;
-
-stateLightModelItem: LIGHTMODEL stateLModProperty
-       {
-          $$[0] = $2[0];
-          $$[1] = $2[1];
-       }
-       ;
-
-stateLModProperty: AMBIENT
-       {
-          memset($$, 0, sizeof($$));
-          $$[0] = STATE_LIGHTMODEL_AMBIENT;
-       }
-       | optFaceType SCENECOLOR
-       {
-          memset($$, 0, sizeof($$));
-          $$[0] = STATE_LIGHTMODEL_SCENECOLOR;
-          $$[1] = $1;
-       }
-       ;
-
-stateLightProdItem: LIGHTPROD '[' stateLightNumber ']' optFaceType stateLProdProperty
-       {
-          memset($$, 0, sizeof($$));
-          $$[0] = STATE_LIGHTPROD;
-          $$[1] = $3;
-          $$[2] = $5;
-          $$[3] = $6;
-       }
-       ;
-
-stateLProdProperty: ambDiffSpecProperty;
-
-stateTexEnvItem: TEXENV optLegacyTexUnitNum stateTexEnvProperty
-       {
-          memset($$, 0, sizeof($$));
-          $$[0] = $3;
-          $$[1] = $2;
-       }
-       ;
-
-stateTexEnvProperty: COLOR
-       {
-          $$ = STATE_TEXENV_COLOR;
-       }
-       ;
-
-ambDiffSpecProperty: AMBIENT
-       {
-          $$ = STATE_AMBIENT;
-       }
-       | DIFFUSE
-       {
-          $$ = STATE_DIFFUSE;
-       }
-       | SPECULAR
-       {
-          $$ = STATE_SPECULAR;
-       }
-       ;
-
-stateLightNumber: INTEGER
-       {
-          if ((unsigned) $1 >= state->MaxLights) {
-             yyerror(& @1, state, "invalid light selector");
-             YYERROR;
-          }
-
-          $$ = $1;
-       }
-       ;
-
-stateTexGenItem: TEXGEN optTexCoordUnitNum stateTexGenType stateTexGenCoord
-       {
-          memset($$, 0, sizeof($$));
-          $$[0] = STATE_TEXGEN;
-          $$[1] = $2;
-          $$[2] = $3 + $4;
-       }
-       ;
-
-stateTexGenType: EYE
-       {
-          $$ = STATE_TEXGEN_EYE_S;
-       }
-       | OBJECT
-       {
-          $$ = STATE_TEXGEN_OBJECT_S;
-       }
-       ;
-stateTexGenCoord: TEXGEN_S
-       {
-          $$ = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S;
-       }
-       | TEXGEN_T
-       {
-          $$ = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S;
-       }
-       | TEXGEN_R
-       {
-          $$ = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S;
-       }
-       | TEXGEN_Q
-       {
-          $$ = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S;
-       }
-       ;
-
-stateFogItem: FOG stateFogProperty
-       {
-          memset($$, 0, sizeof($$));
-          $$[0] = $2;
-       }
-       ;
-
-stateFogProperty: COLOR
-       {
-          $$ = STATE_FOG_COLOR;
-       }
-       | PARAMS
-       {
-          $$ = STATE_FOG_PARAMS;
-       }
-       ;
-
-stateClipPlaneItem: CLIP '[' stateClipPlaneNum ']' PLANE
-       {
-          memset($$, 0, sizeof($$));
-          $$[0] = STATE_CLIPPLANE;
-          $$[1] = $3;
-       }
-       ;
-
-stateClipPlaneNum: INTEGER
-       {
-          if ((unsigned) $1 >= state->MaxClipPlanes) {
-             yyerror(& @1, state, "invalid clip plane selector");
-             YYERROR;
-          }
-
-          $$ = $1;
-       }
-       ;
-
-statePointItem: POINT_TOK statePointProperty
-       {
-          memset($$, 0, sizeof($$));
-          $$[0] = $2;
-       }
-       ;
-
-statePointProperty: SIZE_TOK
-       {
-          $$ = STATE_POINT_SIZE;
-       }
-       | ATTENUATION
-       {
-          $$ = STATE_POINT_ATTENUATION;
-       }
-       ;
-
-stateMatrixRow: stateMatrixItem ROW '[' stateMatrixRowNum ']'
-       {
-          $$[0] = $1[0];
-          $$[1] = $1[1];
-          $$[2] = $4;
-          $$[3] = $4;
-          $$[4] = $1[2];
-       }
-       ;
-
-stateMatrixRows: stateMatrixItem optMatrixRows
-       {
-          $$[0] = $1[0];
-          $$[1] = $1[1];
-          $$[2] = $2[2];
-          $$[3] = $2[3];
-          $$[4] = $1[2];
-       }
-       ;
-
-optMatrixRows:
-       {
-          $$[2] = 0;
-          $$[3] = 3;
-       }
-       | ROW '[' stateMatrixRowNum DOT_DOT stateMatrixRowNum ']'
-       {
-          /* It seems logical that the matrix row range specifier would have
-           * to specify a range or more than one row (i.e., $5 > $3).
-           * However, the ARB_vertex_program spec says "a program will fail
-           * to load if <a> is greater than <b>."  This means that $3 == $5
-           * is valid.
-           */
-          if ($3 > $5) {
-             yyerror(& @3, state, "invalid matrix row range");
-             YYERROR;
-          }
-
-          $$[2] = $3;
-          $$[3] = $5;
-       }
-       ;
-
-stateMatrixItem: MATRIX stateMatrixName stateOptMatModifier
-       {
-          $$[0] = $2[0];
-          $$[1] = $2[1];
-          $$[2] = $3;
-       }
-       ;
-
-stateOptMatModifier: 
-       {
-          $$ = 0;
-       }
-       | stateMatModifier
-       {
-          $$ = $1;
-       }
-       ;
-
-stateMatModifier: INVERSE 
-       {
-          $$ = STATE_MATRIX_INVERSE;
-       }
-       | TRANSPOSE 
-       {
-          $$ = STATE_MATRIX_TRANSPOSE;
-       }
-       | INVTRANS
-       {
-          $$ = STATE_MATRIX_INVTRANS;
-       }
-       ;
-
-stateMatrixRowNum: INTEGER
-       {
-          if ($1 > 3) {
-             yyerror(& @1, state, "invalid matrix row reference");
-             YYERROR;
-          }
-
-          $$ = $1;
-       }
-       ;
-
-stateMatrixName: MODELVIEW stateOptModMatNum
-       {
-          $$[0] = STATE_MODELVIEW_MATRIX;
-          $$[1] = $2;
-       }
-       | PROJECTION
-       {
-          $$[0] = STATE_PROJECTION_MATRIX;
-          $$[1] = 0;
-       }
-       | MVP
-       {
-          $$[0] = STATE_MVP_MATRIX;
-          $$[1] = 0;
-       }
-       | TEXTURE optTexCoordUnitNum
-       {
-          $$[0] = STATE_TEXTURE_MATRIX;
-          $$[1] = $2;
-       }
-       | PALETTE '[' statePaletteMatNum ']'
-       {
-          yyerror(& @1, state, "GL_ARB_matrix_palette not supported");
-          YYERROR;
-       }
-       | MAT_PROGRAM '[' stateProgramMatNum ']'
-       {
-          $$[0] = STATE_PROGRAM_MATRIX;
-          $$[1] = $3;
-       }
-       ;
-
-stateOptModMatNum:
-       {
-          $$ = 0;
-       }
-       | '[' stateModMatNum ']'
-       {
-          $$ = $2;
-       }
-       ;
-stateModMatNum: INTEGER
-       {
-          /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix
-           * zero is valid.
-           */
-          if ($1 != 0) {
-             yyerror(& @1, state, "invalid modelview matrix index");
-             YYERROR;
-          }
-
-          $$ = $1;
-       }
-       ;
-statePaletteMatNum: INTEGER
-       {
-          /* Since GL_ARB_matrix_palette isn't supported, just let any value
-           * through here.  The error will be generated later.
-           */
-          $$ = $1;
-       }
-       ;
-stateProgramMatNum: INTEGER
-       {
-          if ((unsigned) $1 >= state->MaxProgramMatrices) {
-             yyerror(& @1, state, "invalid program matrix selector");
-             YYERROR;
-          }
-
-          $$ = $1;
-       }
-       ;
-
-stateDepthItem: DEPTH RANGE
-       {
-          memset($$, 0, sizeof($$));
-          $$[0] = STATE_DEPTH_RANGE;
-       }
-       ;
-
-
-programSingleItem: progEnvParam | progLocalParam;
-
-programMultipleItem: progEnvParams | progLocalParams;
-
-progEnvParams: PROGRAM ENV '[' progEnvParamNums ']'
-       {
-          memset($$, 0, sizeof($$));
-          $$[0] = state->state_param_enum;
-          $$[1] = STATE_ENV;
-          $$[2] = $4[0];
-          $$[3] = $4[1];
-       }
-       ;
-
-progEnvParamNums: progEnvParamNum
-       {
-          $$[0] = $1;
-          $$[1] = $1;
-       }
-       | progEnvParamNum DOT_DOT progEnvParamNum
-       {
-          $$[0] = $1;
-          $$[1] = $3;
-       }
-       ;
-
-progEnvParam: PROGRAM ENV '[' progEnvParamNum ']'
-       {
-          memset($$, 0, sizeof($$));
-          $$[0] = state->state_param_enum;
-          $$[1] = STATE_ENV;
-          $$[2] = $4;
-          $$[3] = $4;
-       }
-       ;
-
-progLocalParams: PROGRAM LOCAL '[' progLocalParamNums ']'
-       {
-          memset($$, 0, sizeof($$));
-          $$[0] = state->state_param_enum;
-          $$[1] = STATE_LOCAL;
-          $$[2] = $4[0];
-          $$[3] = $4[1];
-       }
-
-progLocalParamNums: progLocalParamNum
-       {
-          $$[0] = $1;
-          $$[1] = $1;
-       }
-       | progLocalParamNum DOT_DOT progLocalParamNum
-       {
-          $$[0] = $1;
-          $$[1] = $3;
-       }
-       ;
-
-progLocalParam: PROGRAM LOCAL '[' progLocalParamNum ']'
-       {
-          memset($$, 0, sizeof($$));
-          $$[0] = state->state_param_enum;
-          $$[1] = STATE_LOCAL;
-          $$[2] = $4;
-          $$[3] = $4;
-       }
-       ;
-
-progEnvParamNum: INTEGER
-       {
-          if ((unsigned) $1 >= state->limits->MaxEnvParams) {
-             yyerror(& @1, state, "invalid environment parameter reference");
-             YYERROR;
-          }
-          $$ = $1;
-       }
-       ;
-
-progLocalParamNum: INTEGER
-       {
-          if ((unsigned) $1 >= state->limits->MaxLocalParams) {
-             yyerror(& @1, state, "invalid local parameter reference");
-             YYERROR;
-          }
-          $$ = $1;
-       }
-       ;
-
-
-
-paramConstDecl: paramConstScalarDecl | paramConstVector;
-paramConstUse: paramConstScalarUse | paramConstVector;
-
-paramConstScalarDecl: signedFloatConstant
-       {
-          $$.count = 4;
-          $$.data[0] = $1;
-          $$.data[1] = $1;
-          $$.data[2] = $1;
-          $$.data[3] = $1;
-       }
-       ;
-
-paramConstScalarUse: REAL
-       {
-          $$.count = 1;
-          $$.data[0] = $1;
-          $$.data[1] = $1;
-          $$.data[2] = $1;
-          $$.data[3] = $1;
-       }
-       | INTEGER
-       {
-          $$.count = 1;
-          $$.data[0] = (float) $1;
-          $$.data[1] = (float) $1;
-          $$.data[2] = (float) $1;
-          $$.data[3] = (float) $1;
-       }
-       ;
-
-paramConstVector: '{' signedFloatConstant '}'
-       {
-          $$.count = 4;
-          $$.data[0] = $2;
-          $$.data[1] = 0.0f;
-          $$.data[2] = 0.0f;
-          $$.data[3] = 1.0f;
-       }
-       | '{' signedFloatConstant ',' signedFloatConstant '}'
-       {
-          $$.count = 4;
-          $$.data[0] = $2;
-          $$.data[1] = $4;
-          $$.data[2] = 0.0f;
-          $$.data[3] = 1.0f;
-       }
-       | '{' signedFloatConstant ',' signedFloatConstant ','
-              signedFloatConstant '}'
-       {
-          $$.count = 4;
-          $$.data[0] = $2;
-          $$.data[1] = $4;
-          $$.data[2] = $6;
-          $$.data[3] = 1.0f;
-       }
-       | '{' signedFloatConstant ',' signedFloatConstant ','
-              signedFloatConstant ',' signedFloatConstant '}'
-       {
-          $$.count = 4;
-          $$.data[0] = $2;
-          $$.data[1] = $4;
-          $$.data[2] = $6;
-          $$.data[3] = $8;
-       }
-       ;
-
-signedFloatConstant: optionalSign REAL
-       {
-          $$ = ($1) ? -$2 : $2;
-       }
-       | optionalSign INTEGER
-       {
-          $$ = (float)(($1) ? -$2 : $2);
-       }
-       ;
-
-optionalSign: '+'        { $$ = FALSE; }
-       | '-'            { $$ = TRUE;  }
-       |                { $$ = FALSE; }
-       ;
-
-TEMP_statement: optVarSize TEMP { $<integer>$ = $2; } varNameList
-       ;
-
-optVarSize: string
-       {
-          /* NV_fragment_program_option defines the size qualifiers in a
-           * fairly broken way.  "SHORT" or "LONG" can optionally be used
-           * before TEMP or OUTPUT.  However, neither is a reserved word!
-           * This means that we have to parse it as an identifier, then check
-           * to make sure it's one of the valid values.  *sigh*
-           *
-           * In addition, the grammar in the extension spec does *not* allow
-           * the size specifier to be optional, but all known implementations
-           * do.
-           */
-          if (!state->option.NV_fragment) {
-             yyerror(& @1, state, "unexpected IDENTIFIER");
-             YYERROR;
-          }
-
-          if (strcmp("SHORT", $1) == 0) {
-          } else if (strcmp("LONG", $1) == 0) {
-          } else {
-             char *const err_str =
-                make_error_string("invalid storage size specifier \"%s\"",
-                                  $1);
-
-             yyerror(& @1, state, (err_str != NULL)
-                     ? err_str : "invalid storage size specifier");
-
-             if (err_str != NULL) {
-                free(err_str);
-             }
-
-             YYERROR;
-          }
-       }
-       |
-       {
-       }
-       ;
-
-ADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList
-       ;
-
-varNameList: varNameList ',' IDENTIFIER
-       {
-          if (!declare_variable(state, $3, $<integer>0, & @3)) {
-             free($3);
-             YYERROR;
-          }
-       }
-       | IDENTIFIER
-       {
-          if (!declare_variable(state, $1, $<integer>0, & @1)) {
-             free($1);
-             YYERROR;
-          }
-       }
-       ;
-
-OUTPUT_statement: optVarSize OUTPUT IDENTIFIER '=' resultBinding
-       {
-          struct asm_symbol *const s =
-             declare_variable(state, $3, at_output, & @3);
-
-          if (s == NULL) {
-             free($3);
-             YYERROR;
-          } else {
-             s->output_binding = $5;
-          }
-       }
-       ;
-
-resultBinding: RESULT POSITION
-       {
-          if (state->mode == ARB_vertex) {
-             $$ = VERT_RESULT_HPOS;
-          } else {
-             yyerror(& @2, state, "invalid program result name");
-             YYERROR;
-          }
-       }
-       | RESULT FOGCOORD
-       {
-          if (state->mode == ARB_vertex) {
-             $$ = VERT_RESULT_FOGC;
-          } else {
-             yyerror(& @2, state, "invalid program result name");
-             YYERROR;
-          }
-       }
-       | RESULT resultColBinding
-       {
-          $$ = $2;
-       }
-       | RESULT POINTSIZE
-       {
-          if (state->mode == ARB_vertex) {
-             $$ = VERT_RESULT_PSIZ;
-          } else {
-             yyerror(& @2, state, "invalid program result name");
-             YYERROR;
-          }
-       }
-       | RESULT TEXCOORD optTexCoordUnitNum
-       {
-          if (state->mode == ARB_vertex) {
-             $$ = VERT_RESULT_TEX0 + $3;
-          } else {
-             yyerror(& @2, state, "invalid program result name");
-             YYERROR;
-          }
-       }
-       | RESULT DEPTH
-       {
-          if (state->mode == ARB_fragment) {
-             $$ = FRAG_RESULT_DEPTH;
-          } else {
-             yyerror(& @2, state, "invalid program result name");
-             YYERROR;
-          }
-       }
-       ;
-
-resultColBinding: COLOR optResultFaceType optResultColorType
-       {
-          $$ = $2 + $3;
-       }
-       ;
-
-optResultFaceType:
-       {
-          $$ = (state->mode == ARB_vertex)
-             ? VERT_RESULT_COL0
-             : FRAG_RESULT_COLOR;
-       }
-       | FRONT
-       {
-          if (state->mode == ARB_vertex) {
-             $$ = VERT_RESULT_COL0;
-          } else {
-             yyerror(& @1, state, "invalid program result name");
-             YYERROR;
-          }
-       }
-       | BACK
-       {
-          if (state->mode == ARB_vertex) {
-             $$ = VERT_RESULT_BFC0;
-          } else {
-             yyerror(& @1, state, "invalid program result name");
-             YYERROR;
-          }
-       }
-       ;
-
-optResultColorType:
-       {
-          $$ = 0; 
-       }
-       | PRIMARY
-       {
-          if (state->mode == ARB_vertex) {
-             $$ = 0;
-          } else {
-             yyerror(& @1, state, "invalid program result name");
-             YYERROR;
-          }
-       }
-       | SECONDARY
-       {
-          if (state->mode == ARB_vertex) {
-             $$ = 1;
-          } else {
-             yyerror(& @1, state, "invalid program result name");
-             YYERROR;
-          }
-       }
-       ;
-
-optFaceType:    { $$ = 0; }
-       | FRONT { $$ = 0; }
-       | BACK  { $$ = 1; }
-       ;
-
-optColorType:       { $$ = 0; }
-       | PRIMARY   { $$ = 0; }
-       | SECONDARY { $$ = 1; }
-       ;
-
-optTexCoordUnitNum:                { $$ = 0; }
-       | '[' texCoordUnitNum ']'  { $$ = $2; }
-       ;
-
-optTexImageUnitNum:                { $$ = 0; }
-       | '[' texImageUnitNum ']'  { $$ = $2; }
-       ;
-
-optLegacyTexUnitNum:               { $$ = 0; }
-       | '[' legacyTexUnitNum ']' { $$ = $2; }
-       ;
-
-texCoordUnitNum: INTEGER
-       {
-          if ((unsigned) $1 >= state->MaxTextureCoordUnits) {
-             yyerror(& @1, state, "invalid texture coordinate unit selector");
-             YYERROR;
-          }
-
-          $$ = $1;
-       }
-       ;
-
-texImageUnitNum: INTEGER
-       {
-          if ((unsigned) $1 >= state->MaxTextureImageUnits) {
-             yyerror(& @1, state, "invalid texture image unit selector");
-             YYERROR;
-          }
-
-          $$ = $1;
-       }
-       ;
-
-legacyTexUnitNum: INTEGER
-       {
-          if ((unsigned) $1 >= state->MaxTextureUnits) {
-             yyerror(& @1, state, "invalid texture unit selector");
-             YYERROR;
-          }
-
-          $$ = $1;
-       }
-       ;
-
-ALIAS_statement: ALIAS IDENTIFIER '=' USED_IDENTIFIER
-       {
-          struct asm_symbol *exist = (struct asm_symbol *)
-             _mesa_symbol_table_find_symbol(state->st, 0, $2);
-          struct asm_symbol *target = (struct asm_symbol *)
-             _mesa_symbol_table_find_symbol(state->st, 0, $4);
-
-          free($4);
-
-          if (exist != NULL) {
-             char m[1000];
-             _mesa_snprintf(m, sizeof(m), "redeclared identifier: %s", $2);
-             free($2);
-             yyerror(& @2, state, m);
-             YYERROR;
-          } else if (target == NULL) {
-             free($2);
-             yyerror(& @4, state,
-                     "undefined variable binding in ALIAS statement");
-             YYERROR;
-          } else {
-             _mesa_symbol_table_add_symbol(state->st, 0, $2, target);
-          }
-       }
-       ;
-
-string: IDENTIFIER
-       | USED_IDENTIFIER
-       ;
-
-%%
-
-void
-asm_instruction_set_operands(struct asm_instruction *inst,
-                            const struct prog_dst_register *dst,
-                            const struct asm_src_register *src0,
-                            const struct asm_src_register *src1,
-                            const struct asm_src_register *src2)
-{
-   /* In the core ARB extensions only the KIL instruction doesn't have a
-    * destination register.
-    */
-   if (dst == NULL) {
-      init_dst_reg(& inst->Base.DstReg);
-   } else {
-      inst->Base.DstReg = *dst;
-   }
-
-   /* The only instruction that doesn't have any source registers is the
-    * condition-code based KIL instruction added by NV_fragment_program_option.
-    */
-   if (src0 != NULL) {
-      inst->Base.SrcReg[0] = src0->Base;
-      inst->SrcReg[0] = *src0;
-   } else {
-      init_src_reg(& inst->SrcReg[0]);
-   }
-
-   if (src1 != NULL) {
-      inst->Base.SrcReg[1] = src1->Base;
-      inst->SrcReg[1] = *src1;
-   } else {
-      init_src_reg(& inst->SrcReg[1]);
-   }
-
-   if (src2 != NULL) {
-      inst->Base.SrcReg[2] = src2->Base;
-      inst->SrcReg[2] = *src2;
-   } else {
-      init_src_reg(& inst->SrcReg[2]);
-   }
-}
-
-
-struct asm_instruction *
-asm_instruction_ctor(gl_inst_opcode op,
-                    const struct prog_dst_register *dst,
-                    const struct asm_src_register *src0,
-                    const struct asm_src_register *src1,
-                    const struct asm_src_register *src2)
-{
-   struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
-
-   if (inst) {
-      _mesa_init_instructions(& inst->Base, 1);
-      inst->Base.Opcode = op;
-
-      asm_instruction_set_operands(inst, dst, src0, src1, src2);
-   }
-
-   return inst;
-}
-
-
-struct asm_instruction *
-asm_instruction_copy_ctor(const struct prog_instruction *base,
-                         const struct prog_dst_register *dst,
-                         const struct asm_src_register *src0,
-                         const struct asm_src_register *src1,
-                         const struct asm_src_register *src2)
-{
-   struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction);
-
-   if (inst) {
-      _mesa_init_instructions(& inst->Base, 1);
-      inst->Base.Opcode = base->Opcode;
-      inst->Base.CondUpdate = base->CondUpdate;
-      inst->Base.CondDst = base->CondDst;
-      inst->Base.SaturateMode = base->SaturateMode;
-      inst->Base.Precision = base->Precision;
-
-      asm_instruction_set_operands(inst, dst, src0, src1, src2);
-   }
-
-   return inst;
-}
-
-
-void
-init_dst_reg(struct prog_dst_register *r)
-{
-   memset(r, 0, sizeof(*r));
-   r->File = PROGRAM_UNDEFINED;
-   r->WriteMask = WRITEMASK_XYZW;
-   r->CondMask = COND_TR;
-   r->CondSwizzle = SWIZZLE_NOOP;
-}
-
-
-/** Like init_dst_reg() but set the File and Index fields. */
-void
-set_dst_reg(struct prog_dst_register *r, gl_register_file file, GLint index)
-{
-   const GLint maxIndex = 1 << INST_INDEX_BITS;
-   const GLint minIndex = 0;
-   ASSERT(index >= minIndex);
-   (void) minIndex;
-   ASSERT(index <= maxIndex);
-   (void) maxIndex;
-   ASSERT(file == PROGRAM_TEMPORARY ||
-         file == PROGRAM_ADDRESS ||
-         file == PROGRAM_OUTPUT);
-   memset(r, 0, sizeof(*r));
-   r->File = file;
-   r->Index = index;
-   r->WriteMask = WRITEMASK_XYZW;
-   r->CondMask = COND_TR;
-   r->CondSwizzle = SWIZZLE_NOOP;
-}
-
-
-void
-init_src_reg(struct asm_src_register *r)
-{
-   memset(r, 0, sizeof(*r));
-   r->Base.File = PROGRAM_UNDEFINED;
-   r->Base.Swizzle = SWIZZLE_NOOP;
-   r->Symbol = NULL;
-}
-
-
-/** Like init_src_reg() but set the File and Index fields.
- * \return GL_TRUE if a valid src register, GL_FALSE otherwise
- */
-void
-set_src_reg(struct asm_src_register *r, gl_register_file file, GLint index)
-{
-   set_src_reg_swz(r, file, index, SWIZZLE_XYZW);
-}
-
-
-void
-set_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index,
-                GLuint swizzle)
-{
-   const GLint maxIndex = (1 << INST_INDEX_BITS) - 1;
-   const GLint minIndex = -(1 << INST_INDEX_BITS);
-   ASSERT(file < PROGRAM_FILE_MAX);
-   ASSERT(index >= minIndex);
-   (void) minIndex;
-   ASSERT(index <= maxIndex);
-   (void) maxIndex;
-   memset(r, 0, sizeof(*r));
-   r->Base.File = file;
-   r->Base.Index = index;
-   r->Base.Swizzle = swizzle;
-   r->Symbol = NULL;
-}
-
-
-/**
- * Validate the set of inputs used by a program
- *
- * Validates that legal sets of inputs are used by the program.  In this case
- * "used" included both reading the input or binding the input to a name using
- * the \c ATTRIB command.
- *
- * \return
- * \c TRUE if the combination of inputs used is valid, \c FALSE otherwise.
- */
-int
-validate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state)
-{
-   const int inputs = state->prog->InputsRead | state->InputsBound;
-
-   if (((inputs & 0x0ffff) & (inputs >> 16)) != 0) {
-      yyerror(locp, state, "illegal use of generic attribute and name attribute");
-      return 0;
-   }
-
-   return 1;
-}
-
-
-struct asm_symbol *
-declare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
-                struct YYLTYPE *locp)
-{
-   struct asm_symbol *s = NULL;
-   struct asm_symbol *exist = (struct asm_symbol *)
-      _mesa_symbol_table_find_symbol(state->st, 0, name);
-
-
-   if (exist != NULL) {
-      yyerror(locp, state, "redeclared identifier");
-   } else {
-      s = calloc(1, sizeof(struct asm_symbol));
-      s->name = name;
-      s->type = t;
-
-      switch (t) {
-      case at_temp:
-        if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
-           yyerror(locp, state, "too many temporaries declared");
-           free(s);
-           return NULL;
-        }
-
-        s->temp_binding = state->prog->NumTemporaries;
-        state->prog->NumTemporaries++;
-        break;
-
-      case at_address:
-        if (state->prog->NumAddressRegs >= state->limits->MaxAddressRegs) {
-           yyerror(locp, state, "too many address registers declared");
-           free(s);
-           return NULL;
-        }
-
-        /* FINISHME: Add support for multiple address registers.
-         */
-        state->prog->NumAddressRegs++;
-        break;
-
-      default:
-        break;
-      }
-
-      _mesa_symbol_table_add_symbol(state->st, 0, s->name, s);
-      s->next = state->sym;
-      state->sym = s;
-   }
-
-   return s;
-}
-
-
-int add_state_reference(struct gl_program_parameter_list *param_list,
-                       const gl_state_index tokens[STATE_LENGTH])
-{
-   const GLuint size = 4; /* XXX fix */
-   char *name;
-   GLint index;
-
-   name = _mesa_program_state_string(tokens);
-   index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name,
-                               size, GL_NONE, NULL, tokens, 0x0);
-   param_list->StateFlags |= _mesa_program_state_flags(tokens);
-
-   /* free name string here since we duplicated it in add_parameter() */
-   free(name);
-
-   return index;
-}
-
-
-int
-initialize_symbol_from_state(struct gl_program *prog,
-                            struct asm_symbol *param_var, 
-                            const gl_state_index tokens[STATE_LENGTH])
-{
-   int idx = -1;
-   gl_state_index state_tokens[STATE_LENGTH];
-
-
-   memcpy(state_tokens, tokens, sizeof(state_tokens));
-
-   param_var->type = at_param;
-   param_var->param_binding_type = PROGRAM_STATE_VAR;
-
-   /* If we are adding a STATE_MATRIX that has multiple rows, we need to
-    * unroll it and call add_state_reference() for each row
-    */
-   if ((state_tokens[0] == STATE_MODELVIEW_MATRIX ||
-       state_tokens[0] == STATE_PROJECTION_MATRIX ||
-       state_tokens[0] == STATE_MVP_MATRIX ||
-       state_tokens[0] == STATE_TEXTURE_MATRIX ||
-       state_tokens[0] == STATE_PROGRAM_MATRIX)
-       && (state_tokens[2] != state_tokens[3])) {
-      int row;
-      const int first_row = state_tokens[2];
-      const int last_row = state_tokens[3];
-
-      for (row = first_row; row <= last_row; row++) {
-        state_tokens[2] = state_tokens[3] = row;
-
-        idx = add_state_reference(prog->Parameters, state_tokens);
-        if (param_var->param_binding_begin == ~0U) {
-           param_var->param_binding_begin = idx;
-            param_var->param_binding_swizzle = SWIZZLE_XYZW;
-         }
-
-        param_var->param_binding_length++;
-      }
-   }
-   else {
-      idx = add_state_reference(prog->Parameters, state_tokens);
-      if (param_var->param_binding_begin == ~0U) {
-        param_var->param_binding_begin = idx;
-         param_var->param_binding_swizzle = SWIZZLE_XYZW;
-      }
-      param_var->param_binding_length++;
-   }
-
-   return idx;
-}
-
-
-int
-initialize_symbol_from_param(struct gl_program *prog,
-                            struct asm_symbol *param_var, 
-                            const gl_state_index tokens[STATE_LENGTH])
-{
-   int idx = -1;
-   gl_state_index state_tokens[STATE_LENGTH];
-
-
-   memcpy(state_tokens, tokens, sizeof(state_tokens));
-
-   assert((state_tokens[0] == STATE_VERTEX_PROGRAM)
-         || (state_tokens[0] == STATE_FRAGMENT_PROGRAM));
-   assert((state_tokens[1] == STATE_ENV)
-         || (state_tokens[1] == STATE_LOCAL));
-
-   /*
-    * The param type is STATE_VAR.  The program parameter entry will
-    * effectively be a pointer into the LOCAL or ENV parameter array.
-    */
-   param_var->type = at_param;
-   param_var->param_binding_type = PROGRAM_STATE_VAR;
-
-   /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements,
-    * we need to unroll it and call add_state_reference() for each row
-    */
-   if (state_tokens[2] != state_tokens[3]) {
-      int row;
-      const int first_row = state_tokens[2];
-      const int last_row = state_tokens[3];
-
-      for (row = first_row; row <= last_row; row++) {
-        state_tokens[2] = state_tokens[3] = row;
-
-        idx = add_state_reference(prog->Parameters, state_tokens);
-        if (param_var->param_binding_begin == ~0U) {
-           param_var->param_binding_begin = idx;
-            param_var->param_binding_swizzle = SWIZZLE_XYZW;
-         }
-        param_var->param_binding_length++;
-      }
-   }
-   else {
-      idx = add_state_reference(prog->Parameters, state_tokens);
-      if (param_var->param_binding_begin == ~0U) {
-        param_var->param_binding_begin = idx;
-         param_var->param_binding_swizzle = SWIZZLE_XYZW;
-      }
-      param_var->param_binding_length++;
-   }
-
-   return idx;
-}
-
-
-/**
- * Put a float/vector constant/literal into the parameter list.
- * \param param_var  returns info about the parameter/constant's location,
- *                   binding, type, etc.
- * \param vec  the vector/constant to add
- * \param allowSwizzle  if true, try to consolidate constants which only differ
- *                      by a swizzle.  We don't want to do this when building
- *                      arrays of constants that may be indexed indirectly.
- * \return index of the constant in the parameter list.
- */
-int
-initialize_symbol_from_const(struct gl_program *prog,
-                            struct asm_symbol *param_var, 
-                            const struct asm_vector *vec,
-                             GLboolean allowSwizzle)
-{
-   unsigned swizzle;
-   const int idx = _mesa_add_unnamed_constant(prog->Parameters,
-                                              vec->data, vec->count,
-                                              allowSwizzle ? &swizzle : NULL);
-
-   param_var->type = at_param;
-   param_var->param_binding_type = PROGRAM_CONSTANT;
-
-   if (param_var->param_binding_begin == ~0U) {
-      param_var->param_binding_begin = idx;
-      param_var->param_binding_swizzle = allowSwizzle ? swizzle : SWIZZLE_XYZW;
-   }
-   param_var->param_binding_length++;
-
-   return idx;
-}
-
-
-char *
-make_error_string(const char *fmt, ...)
-{
-   int length;
-   char *str;
-   va_list args;
-
-
-   /* Call vsnprintf once to determine how large the final string is.  Call it
-    * again to do the actual formatting.  from the vsnprintf manual page:
-    *
-    *    Upon successful return, these functions return the number of
-    *    characters printed  (not including the trailing '\0' used to end
-    *    output to strings).
-    */
-   va_start(args, fmt);
-   length = 1 + vsnprintf(NULL, 0, fmt, args);
-   va_end(args);
-
-   str = malloc(length);
-   if (str) {
-      va_start(args, fmt);
-      vsnprintf(str, length, fmt, args);
-      va_end(args);
-   }
-
-   return str;
-}
-
-
-void
-yyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s)
-{
-   char *err_str;
-
-
-   err_str = make_error_string("glProgramStringARB(%s)\n", s);
-   if (err_str) {
-      _mesa_error(state->ctx, GL_INVALID_OPERATION, err_str);
-      free(err_str);
-   }
-
-   err_str = make_error_string("line %u, char %u: error: %s\n",
-                              locp->first_line, locp->first_column, s);
-   _mesa_set_program_error(state->ctx, locp->position, err_str);
-
-   if (err_str) {
-      free(err_str);
-   }
-}
-
-
-GLboolean
-_mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str,
-                       GLsizei len, struct asm_parser_state *state)
-{
-   struct asm_instruction *inst;
-   unsigned i;
-   GLubyte *strz;
-   GLboolean result = GL_FALSE;
-   void *temp;
-   struct asm_symbol *sym;
-
-   state->ctx = ctx;
-   state->prog->Target = target;
-   state->prog->Parameters = _mesa_new_parameter_list();
-
-   /* Make a copy of the program string and force it to be NUL-terminated.
-    */
-   strz = (GLubyte *) malloc(len + 1);
-   if (strz == NULL) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
-      return GL_FALSE;
-   }
-   memcpy (strz, str, len);
-   strz[len] = '\0';
-
-   state->prog->String = strz;
-
-   state->st = _mesa_symbol_table_ctor();
-
-   state->limits = (target == GL_VERTEX_PROGRAM_ARB)
-      ? & ctx->Const.VertexProgram
-      : & ctx->Const.FragmentProgram;
-
-   state->MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits;
-   state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits;
-   state->MaxTextureUnits = ctx->Const.MaxTextureUnits;
-   state->MaxClipPlanes = ctx->Const.MaxClipPlanes;
-   state->MaxLights = ctx->Const.MaxLights;
-   state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices;
-
-   state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB)
-      ? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM;
-
-   _mesa_set_program_error(ctx, -1, NULL);
-
-   _mesa_program_lexer_ctor(& state->scanner, state, (const char *) str, len);
-   yyparse(state);
-   _mesa_program_lexer_dtor(state->scanner);
-
-
-   if (ctx->Program.ErrorPos != -1) {
-      goto error;
-   }
-
-   if (! _mesa_layout_parameters(state)) {
-      struct YYLTYPE loc;
-
-      loc.first_line = 0;
-      loc.first_column = 0;
-      loc.position = len;
-
-      yyerror(& loc, state, "invalid PARAM usage");
-      goto error;
-   }
-
-
-   
-   /* Add one instruction to store the "END" instruction.
-    */
-   state->prog->Instructions =
-      _mesa_alloc_instructions(state->prog->NumInstructions + 1);
-   inst = state->inst_head;
-   for (i = 0; i < state->prog->NumInstructions; i++) {
-      struct asm_instruction *const temp = inst->next;
-
-      state->prog->Instructions[i] = inst->Base;
-      inst = temp;
-   }
-
-   /* Finally, tag on an OPCODE_END instruction */
-   {
-      const GLuint numInst = state->prog->NumInstructions;
-      _mesa_init_instructions(state->prog->Instructions + numInst, 1);
-      state->prog->Instructions[numInst].Opcode = OPCODE_END;
-   }
-   state->prog->NumInstructions++;
-
-   state->prog->NumParameters = state->prog->Parameters->NumParameters;
-   state->prog->NumAttributes = _mesa_bitcount(state->prog->InputsRead);
-
-   /*
-    * Initialize native counts to logical counts.  The device driver may
-    * change them if program is translated into a hardware program.
-    */
-   state->prog->NumNativeInstructions = state->prog->NumInstructions;
-   state->prog->NumNativeTemporaries = state->prog->NumTemporaries;
-   state->prog->NumNativeParameters = state->prog->NumParameters;
-   state->prog->NumNativeAttributes = state->prog->NumAttributes;
-   state->prog->NumNativeAddressRegs = state->prog->NumAddressRegs;
-
-   result = GL_TRUE;
-
-error:
-   for (inst = state->inst_head; inst != NULL; inst = temp) {
-      temp = inst->next;
-      free(inst);
-   }
-
-   state->inst_head = NULL;
-   state->inst_tail = NULL;
-
-   for (sym = state->sym; sym != NULL; sym = temp) {
-      temp = sym->next;
-
-      free((void *) sym->name);
-      free(sym);
-   }
-   state->sym = NULL;
-
-   _mesa_symbol_table_dtor(state->st);
-   state->st = NULL;
-
-   return result;
-}
diff --git a/src/mesa/shader/program_parse_extra.c b/src/mesa/shader/program_parse_extra.c
deleted file mode 100644 (file)
index ae98b78..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * Copyright Â© 2009 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION 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 <string.h>
-#include "main/mtypes.h"
-#include "prog_instruction.h"
-#include "program_parser.h"
-
-
-/**
- * Extra assembly-level parser routines
- *
- * \author Ian Romanick <ian.d.romanick@intel.com>
- */
-
-int
-_mesa_parse_instruction_suffix(const struct asm_parser_state *state,
-                              const char *suffix,
-                              struct prog_instruction *inst)
-{
-   inst->CondUpdate = 0;
-   inst->CondDst = 0;
-   inst->SaturateMode = SATURATE_OFF;
-   inst->Precision = FLOAT32;
-
-
-   /* The first possible suffix element is the precision specifier from
-    * NV_fragment_program_option.
-    */
-   if (state->option.NV_fragment) {
-      switch (suffix[0]) {
-      case 'H':
-        inst->Precision = FLOAT16;
-        suffix++;
-        break;
-      case 'R':
-        inst->Precision = FLOAT32;
-        suffix++;
-        break;
-      case 'X':
-        inst->Precision = FIXED12;
-        suffix++;
-        break;
-      default:
-        break;
-      }
-   }
-
-   /* The next possible suffix element is the condition code modifier selection
-    * from NV_fragment_program_option.
-    */
-   if (state->option.NV_fragment) {
-      if (suffix[0] == 'C') {
-        inst->CondUpdate = 1;
-        suffix++;
-      }
-   }
-
-
-   /* The final possible suffix element is the saturation selector from
-    * ARB_fragment_program.
-    */
-   if (state->mode == ARB_fragment) {
-      if (strcmp(suffix, "_SAT") == 0) {
-        inst->SaturateMode = SATURATE_ZERO_ONE;
-        suffix += 4;
-      }
-   }
-
-
-   /* It is an error for all of the suffix string not to be consumed.
-    */
-   return suffix[0] == '\0';
-}
-
-
-int
-_mesa_parse_cc(const char *s)
-{
-   int cond = 0;
-
-   switch (s[0]) {
-   case 'E':
-      if (s[1] == 'Q') {
-        cond = COND_EQ;
-      }
-      break;
-
-   case 'F':
-      if (s[1] == 'L') {
-        cond = COND_FL;
-      }
-      break;
-
-   case 'G':
-      if (s[1] == 'E') {
-        cond = COND_GE;
-      } else if (s[1] == 'T') {
-        cond = COND_GT;
-      }
-      break;
-
-   case 'L':
-      if (s[1] == 'E') {
-        cond = COND_LE;
-      } else if (s[1] == 'T') {
-        cond = COND_LT;
-      }
-      break;
-
-   case 'N':
-      if (s[1] == 'E') {
-        cond = COND_NE;
-      }
-      break;
-
-   case 'T':
-      if (s[1] == 'R') {
-        cond = COND_TR;
-      }
-      break;
-
-   default:
-      break;
-   }
-
-   return ((cond == 0) || (s[2] != '\0')) ? 0 : cond;
-}
-
-
-int
-_mesa_ARBvp_parse_option(struct asm_parser_state *state, const char *option)
-{
-   if (strcmp(option, "ARB_position_invariant") == 0) {
-      state->option.PositionInvariant = 1;
-      return 1;
-   }
-
-   return 0;
-}
-
-
-int
-_mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option)
-{
-   /* All of the options currently supported start with "ARB_".  The code is
-    * currently structured with nested if-statements because eventually options
-    * that start with "NV_" will be supported.  This structure will result in
-    * less churn when those options are added.
-    */
-   if (strncmp(option, "ARB_", 4) == 0) {
-      /* Advance the pointer past the "ARB_" prefix.
-       */
-      option += 4;
-
-
-      if (strncmp(option, "fog_", 4) == 0) {
-        option += 4;
-
-        if (state->option.Fog == OPTION_NONE) {
-           if (strcmp(option, "exp") == 0) {
-              state->option.Fog = OPTION_FOG_EXP;
-              return 1;
-           } else if (strcmp(option, "exp2") == 0) {
-              state->option.Fog = OPTION_FOG_EXP2;
-              return 1;
-           } else if (strcmp(option, "linear") == 0) {
-              state->option.Fog = OPTION_FOG_LINEAR;
-              return 1;
-           }
-        }
-
-        return 0;
-      } else if (strncmp(option, "precision_hint_", 15) == 0) {
-        option += 15;
-
-        if (state->option.PrecisionHint == OPTION_NONE) {
-           if (strcmp(option, "nicest") == 0) {
-              state->option.PrecisionHint = OPTION_NICEST;
-              return 1;
-           } else if (strcmp(option, "fastest") == 0) {
-              state->option.PrecisionHint = OPTION_FASTEST;
-              return 1;
-           }
-        }
-
-        return 0;
-      } else if (strcmp(option, "draw_buffers") == 0) {
-        /* Don't need to check extension availability because all Mesa-based
-         * drivers support GL_ARB_draw_buffers.
-         */
-        state->option.DrawBuffers = 1;
-        return 1;
-      } else if (strcmp(option, "fragment_program_shadow") == 0) {
-        if (state->ctx->Extensions.ARB_fragment_program_shadow) {
-           state->option.Shadow = 1;
-           return 1;
-        }
-      } else if (strncmp(option, "fragment_coord_", 15) == 0) {
-         option += 15;
-         if (state->ctx->Extensions.ARB_fragment_coord_conventions) {
-            if (strcmp(option, "origin_upper_left") == 0) {
-               state->option.OriginUpperLeft = 1;
-               return 1;
-            }
-            else if (strcmp(option, "pixel_center_integer") == 0) {
-               state->option.PixelCenterInteger = 1;
-               return 1;
-            }
-         }
-      }
-   } else if (strncmp(option, "NV_fragment_program", 19) == 0) {
-      option += 19;
-
-      /* Other NV_fragment_program strings may be supported later.
-       */
-      if (option[0] == '\0') {
-        if (state->ctx->Extensions.NV_fragment_program_option) {
-           state->option.NV_fragment = 1;
-           return 1;
-        }
-      }
-   } else if (strncmp(option, "MESA_", 5) == 0) {
-      option += 5;
-
-      if (strcmp(option, "texture_array") == 0) {
-        if (state->ctx->Extensions.MESA_texture_array) {
-           state->option.TexArray = 1;
-           return 1;
-        }
-      }
-   }
-
-   return 0;
-}
diff --git a/src/mesa/shader/program_parser.h b/src/mesa/shader/program_parser.h
deleted file mode 100644 (file)
index be952d4..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright Â© 2009 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-#pragma once
-
-#include "main/config.h"
-
-#ifndef MTYPES_H
-struct __GLcontextRec;
-typedef struct __GLcontextRec GLcontext;
-#endif
-
-enum asm_type {
-   at_none,
-   at_address,
-   at_attrib,
-   at_param,
-   at_temp,
-   at_output
-};
-
-struct asm_symbol {
-   struct asm_symbol *next;    /**< List linkage for freeing. */
-   const char *name;
-   enum asm_type type;
-   unsigned attrib_binding;
-   unsigned output_binding;   /**< Output / result register number. */
-
-   /**
-    * One of PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM, or PROGRAM_ENV_PARAM.
-    */
-   unsigned param_binding_type;
-
-   /** 
-    * Offset into the program_parameter_list where the tokens representing our
-    * bound state (or constants) start.
-    */
-   unsigned param_binding_begin;
-
-   /**
-    * Constants put into the parameter list may be swizzled.  This
-    * field contain's the symbol's swizzle. (SWIZZLE_X/Y/Z/W)
-    */
-   unsigned param_binding_swizzle;
-
-   /* This is how many entries in the program_parameter_list we take up
-    * with our state tokens or constants. Note that this is _not_ the same as
-    * the number of param registers we eventually use.
-    */
-   unsigned param_binding_length;
-
-   /**
-    * Index of the temp register assigned to this variable.
-    */
-   unsigned temp_binding;
-
-   /**
-    * Flag whether or not a PARAM is an array
-    */
-   unsigned param_is_array:1;
-
-
-   /**
-    * Flag whether or not a PARAM array is accessed indirectly
-    */
-   unsigned param_accessed_indirectly:1;
-
-
-   /**
-    * \brief Is first pass of parameter layout done with this variable?
-    *
-    * The parameter layout routine operates in two passes.  This flag tracks
-    * whether or not the first pass has handled this variable.
-    *
-    * \sa _mesa_layout_parameters
-    */
-   unsigned pass1_done:1;
-};
-
-
-struct asm_vector {
-   unsigned count;
-   float    data[4];
-};
-
-
-struct asm_swizzle_mask {
-   unsigned swizzle:12;
-   unsigned mask:4;
-};
-
-
-struct asm_src_register {
-   struct prog_src_register Base;
-
-   /**
-    * Symbol associated with indirect access to parameter arrays.
-    *
-    * If \c Base::RelAddr is 1, this will point to the symbol for the parameter
-    * that is being dereferenced.  Further, \c Base::Index will be the offset
-    * from the address register being used.
-    */
-   struct asm_symbol *Symbol;
-};
-
-
-struct asm_instruction {
-   struct prog_instruction Base;
-   struct asm_instruction *next;
-   struct asm_src_register SrcReg[3];
-};
-
-
-struct asm_parser_state {
-   GLcontext *ctx;
-   struct gl_program *prog;
-
-   /**
-    * Per-program target limits
-    */
-   struct gl_program_constants *limits;
-
-   struct _mesa_symbol_table *st;
-
-   /**
-    * Linked list of symbols
-    *
-    * This list is \b only used when cleaning up compiler state and freeing
-    * memory.
-    */
-   struct asm_symbol *sym;
-
-   /**
-    * State for the lexer.
-    */
-   void *scanner;
-
-   /**
-    * Linked list of instructions generated during parsing.
-    */
-   /*@{*/
-   struct asm_instruction *inst_head;
-   struct asm_instruction *inst_tail;
-   /*@}*/
-
-
-   /**
-    * Selected limits copied from gl_constants
-    *
-    * These are limits from the GL context, but various bits in the program
-    * must be validated against these values.
-    */
-   /*@{*/
-   unsigned MaxTextureCoordUnits;
-   unsigned MaxTextureImageUnits;
-   unsigned MaxTextureUnits;
-   unsigned MaxClipPlanes;
-   unsigned MaxLights;
-   unsigned MaxProgramMatrices;
-   /*@}*/
-
-   /**
-    * Value to use in state vector accessors for environment and local
-    * parameters
-    */
-   unsigned state_param_enum;
-
-
-   /**
-    * Input attributes bound to specific names
-    *
-    * This is only needed so that errors can be properly produced when
-    * multiple ATTRIB statements bind illegal combinations of vertex
-    * attributes.
-    */
-   unsigned InputsBound;
-
-   enum {
-      invalid_mode = 0,
-      ARB_vertex,
-      ARB_fragment
-   } mode;
-
-   struct {
-      unsigned PositionInvariant:1;
-      unsigned Fog:2;
-      unsigned PrecisionHint:2;
-      unsigned DrawBuffers:1;
-      unsigned Shadow:1;
-      unsigned TexRect:1;
-      unsigned TexArray:1;
-      unsigned NV_fragment:1;
-      unsigned OriginUpperLeft:1;
-      unsigned PixelCenterInteger:1;
-   } option;
-
-   struct {
-      unsigned UsesKill:1;
-   } fragment;
-};
-
-#define OPTION_NONE        0
-#define OPTION_FOG_EXP     1
-#define OPTION_FOG_EXP2    2
-#define OPTION_FOG_LINEAR  3
-#define OPTION_NICEST      1
-#define OPTION_FASTEST     2
-
-typedef struct YYLTYPE {
-   int first_line;
-   int first_column;
-   int last_line;
-   int last_column;
-   int position;
-} YYLTYPE;
-
-#define YYLTYPE_IS_DECLARED 1
-#define YYLTYPE_IS_TRIVIAL 1
-
-
-extern GLboolean _mesa_parse_arb_program(GLcontext *ctx, GLenum target,
-    const GLubyte *str, GLsizei len, struct asm_parser_state *state);
-
-
-
-/* From program_lexer.l. */
-extern void _mesa_program_lexer_dtor(void *scanner);
-
-extern void _mesa_program_lexer_ctor(void **scanner,
-    struct asm_parser_state *state, const char *string, size_t len);
-
-
-/**
- *\name From program_parse_extra.c
- */
-/*@{*/
-
-/**
- * Parses and processes an option string to an ARB vertex program
- *
- * \return
- * Non-zero on success, zero on failure.
- */
-extern int _mesa_ARBvp_parse_option(struct asm_parser_state *state,
-    const char *option);
-
-/**
- * Parses and processes an option string to an ARB fragment program
- *
- * \return
- * Non-zero on success, zero on failure.
- */
-extern int _mesa_ARBfp_parse_option(struct asm_parser_state *state,
-    const char *option);
-
-/**
- * Parses and processes instruction suffixes
- *
- * Instruction suffixes, such as \c _SAT, are processed.  The relevant bits
- * are set in \c inst.  If suffixes are encountered that are either not known
- * or not supported by the modes and options set in \c state, zero will be
- * returned.
- *
- * \return
- * Non-zero on success, zero on failure.
- */
-extern int _mesa_parse_instruction_suffix(const struct asm_parser_state *state,
-    const char *suffix, struct prog_instruction *inst);
-
-/**
- * Parses a condition code name
- *
- * The condition code names (e.g., \c LT, \c GT, \c NE) were added to assembly
- * shaders with the \c GL_NV_fragment_program_option extension.  This function
- * converts a string representation into one of the \c COND_ macros.
- *
- * \return
- * One of the \c COND_ macros defined in prog_instruction.h on success or zero
- * on failure.
- */
-extern int _mesa_parse_cc(const char *s);
-
-/*@}*/
diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c
deleted file mode 100644 (file)
index fb2ebe6..0000000
+++ /dev/null
@@ -1,669 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.3
- *
- * 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  programopt.c 
- * Vertex/Fragment program optimizations and transformations for program
- * options, etc.
- *
- * \author Brian Paul
- */
-
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "prog_parameter.h"
-#include "prog_statevars.h"
-#include "program.h"
-#include "programopt.h"
-#include "prog_instruction.h"
-
-
-/**
- * This function inserts instructions for coordinate modelview * projection
- * into a vertex program.
- * May be used to implement the position_invariant option.
- */
-static void
-_mesa_insert_mvp_dp4_code(GLcontext *ctx, struct gl_vertex_program *vprog)
-{
-   struct prog_instruction *newInst;
-   const GLuint origLen = vprog->Base.NumInstructions;
-   const GLuint newLen = origLen + 4;
-   GLuint i;
-
-   /*
-    * Setup state references for the modelview/projection matrix.
-    * XXX we should check if these state vars are already declared.
-    */
-   static const gl_state_index mvpState[4][STATE_LENGTH] = {
-      { STATE_MVP_MATRIX, 0, 0, 0, 0 },  /* state.matrix.mvp.row[0] */
-      { STATE_MVP_MATRIX, 0, 1, 1, 0 },  /* state.matrix.mvp.row[1] */
-      { STATE_MVP_MATRIX, 0, 2, 2, 0 },  /* state.matrix.mvp.row[2] */
-      { STATE_MVP_MATRIX, 0, 3, 3, 0 },  /* state.matrix.mvp.row[3] */
-   };
-   GLint mvpRef[4];
-
-   for (i = 0; i < 4; i++) {
-      mvpRef[i] = _mesa_add_state_reference(vprog->Base.Parameters,
-                                            mvpState[i]);
-   }
-
-   /* Alloc storage for new instructions */
-   newInst = _mesa_alloc_instructions(newLen);
-   if (!newInst) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY,
-                  "glProgramString(inserting position_invariant code)");
-      return;
-   }
-
-   /*
-    * Generated instructions:
-    * newInst[0] = DP4 result.position.x, mvp.row[0], vertex.position;
-    * newInst[1] = DP4 result.position.y, mvp.row[1], vertex.position;
-    * newInst[2] = DP4 result.position.z, mvp.row[2], vertex.position;
-    * newInst[3] = DP4 result.position.w, mvp.row[3], vertex.position;
-    */
-   _mesa_init_instructions(newInst, 4);
-   for (i = 0; i < 4; i++) {
-      newInst[i].Opcode = OPCODE_DP4;
-      newInst[i].DstReg.File = PROGRAM_OUTPUT;
-      newInst[i].DstReg.Index = VERT_RESULT_HPOS;
-      newInst[i].DstReg.WriteMask = (WRITEMASK_X << i);
-      newInst[i].SrcReg[0].File = PROGRAM_STATE_VAR;
-      newInst[i].SrcReg[0].Index = mvpRef[i];
-      newInst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP;
-      newInst[i].SrcReg[1].File = PROGRAM_INPUT;
-      newInst[i].SrcReg[1].Index = VERT_ATTRIB_POS;
-      newInst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP;
-   }
-
-   /* Append original instructions after new instructions */
-   _mesa_copy_instructions (newInst + 4, vprog->Base.Instructions, origLen);
-
-   /* free old instructions */
-   _mesa_free_instructions(vprog->Base.Instructions, origLen);
-
-   /* install new instructions */
-   vprog->Base.Instructions = newInst;
-   vprog->Base.NumInstructions = newLen;
-   vprog->Base.InputsRead |= VERT_BIT_POS;
-   vprog->Base.OutputsWritten |= BITFIELD64_BIT(VERT_RESULT_HPOS);
-}
-
-
-static void
-_mesa_insert_mvp_mad_code(GLcontext *ctx, struct gl_vertex_program *vprog)
-{
-   struct prog_instruction *newInst;
-   const GLuint origLen = vprog->Base.NumInstructions;
-   const GLuint newLen = origLen + 4;
-   GLuint hposTemp;
-   GLuint i;
-
-   /*
-    * Setup state references for the modelview/projection matrix.
-    * XXX we should check if these state vars are already declared.
-    */
-   static const gl_state_index mvpState[4][STATE_LENGTH] = {
-      { STATE_MVP_MATRIX, 0, 0, 0, STATE_MATRIX_TRANSPOSE },
-      { STATE_MVP_MATRIX, 0, 1, 1, STATE_MATRIX_TRANSPOSE },
-      { STATE_MVP_MATRIX, 0, 2, 2, STATE_MATRIX_TRANSPOSE },
-      { STATE_MVP_MATRIX, 0, 3, 3, STATE_MATRIX_TRANSPOSE },
-   };
-   GLint mvpRef[4];
-
-   for (i = 0; i < 4; i++) {
-      mvpRef[i] = _mesa_add_state_reference(vprog->Base.Parameters,
-                                            mvpState[i]);
-   }
-
-   /* Alloc storage for new instructions */
-   newInst = _mesa_alloc_instructions(newLen);
-   if (!newInst) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY,
-                  "glProgramString(inserting position_invariant code)");
-      return;
-   }
-
-   /* TEMP hposTemp; */
-   hposTemp = vprog->Base.NumTemporaries++;
-
-   /*
-    * Generated instructions:
-    *    emit_op2(p, OPCODE_MUL, tmp, 0, swizzle1(src,X), mat[0]);
-    *    emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Y), mat[1], tmp);
-    *    emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Z), mat[2], tmp);
-    *    emit_op3(p, OPCODE_MAD, dest, 0, swizzle1(src,W), mat[3], tmp);
-    */
-   _mesa_init_instructions(newInst, 4);
-
-   newInst[0].Opcode = OPCODE_MUL;
-   newInst[0].DstReg.File = PROGRAM_TEMPORARY;
-   newInst[0].DstReg.Index = hposTemp;
-   newInst[0].DstReg.WriteMask = WRITEMASK_XYZW;
-   newInst[0].SrcReg[0].File = PROGRAM_INPUT;
-   newInst[0].SrcReg[0].Index = VERT_ATTRIB_POS;
-   newInst[0].SrcReg[0].Swizzle = SWIZZLE_XXXX;
-   newInst[0].SrcReg[1].File = PROGRAM_STATE_VAR;
-   newInst[0].SrcReg[1].Index = mvpRef[0];
-   newInst[0].SrcReg[1].Swizzle = SWIZZLE_NOOP;
-
-   for (i = 1; i <= 2; i++) {
-      newInst[i].Opcode = OPCODE_MAD;
-      newInst[i].DstReg.File = PROGRAM_TEMPORARY;
-      newInst[i].DstReg.Index = hposTemp;
-      newInst[i].DstReg.WriteMask = WRITEMASK_XYZW;
-      newInst[i].SrcReg[0].File = PROGRAM_INPUT;
-      newInst[i].SrcReg[0].Index = VERT_ATTRIB_POS;
-      newInst[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(i,i,i,i);
-      newInst[i].SrcReg[1].File = PROGRAM_STATE_VAR;
-      newInst[i].SrcReg[1].Index = mvpRef[i];
-      newInst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP;
-      newInst[i].SrcReg[2].File = PROGRAM_TEMPORARY;
-      newInst[i].SrcReg[2].Index = hposTemp;
-      newInst[1].SrcReg[2].Swizzle = SWIZZLE_NOOP;
-   }
-
-   newInst[3].Opcode = OPCODE_MAD;
-   newInst[3].DstReg.File = PROGRAM_OUTPUT;
-   newInst[3].DstReg.Index = VERT_RESULT_HPOS;
-   newInst[3].DstReg.WriteMask = WRITEMASK_XYZW;
-   newInst[3].SrcReg[0].File = PROGRAM_INPUT;
-   newInst[3].SrcReg[0].Index = VERT_ATTRIB_POS;
-   newInst[3].SrcReg[0].Swizzle = SWIZZLE_WWWW;
-   newInst[3].SrcReg[1].File = PROGRAM_STATE_VAR;
-   newInst[3].SrcReg[1].Index = mvpRef[3];
-   newInst[3].SrcReg[1].Swizzle = SWIZZLE_NOOP;
-   newInst[3].SrcReg[2].File = PROGRAM_TEMPORARY;
-   newInst[3].SrcReg[2].Index = hposTemp;
-   newInst[3].SrcReg[2].Swizzle = SWIZZLE_NOOP;
-
-
-   /* Append original instructions after new instructions */
-   _mesa_copy_instructions (newInst + 4, vprog->Base.Instructions, origLen);
-
-   /* free old instructions */
-   _mesa_free_instructions(vprog->Base.Instructions, origLen);
-
-   /* install new instructions */
-   vprog->Base.Instructions = newInst;
-   vprog->Base.NumInstructions = newLen;
-   vprog->Base.InputsRead |= VERT_BIT_POS;
-   vprog->Base.OutputsWritten |= BITFIELD64_BIT(VERT_RESULT_HPOS);
-}
-
-
-void
-_mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog)
-{
-   if (ctx->mvp_with_dp4) 
-      _mesa_insert_mvp_dp4_code( ctx, vprog );
-   else
-      _mesa_insert_mvp_mad_code( ctx, vprog );
-}
-      
-
-
-
-
-
-/**
- * Append extra instructions onto the given fragment program to implement
- * the fog mode specified by fprog->FogOption.
- * The fragment.fogcoord input is used to compute the fog blend factor.
- *
- * XXX with a little work, this function could be adapted to add fog code
- * to vertex programs too.
- */
-void
-_mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog)
-{
-   static const gl_state_index fogPStateOpt[STATE_LENGTH]
-      = { STATE_INTERNAL, STATE_FOG_PARAMS_OPTIMIZED, 0, 0, 0 };
-   static const gl_state_index fogColorState[STATE_LENGTH]
-      = { STATE_FOG_COLOR, 0, 0, 0, 0};
-   struct prog_instruction *newInst, *inst;
-   const GLuint origLen = fprog->Base.NumInstructions;
-   const GLuint newLen = origLen + 5;
-   GLuint i;
-   GLint fogPRefOpt, fogColorRef; /* state references */
-   GLuint colorTemp, fogFactorTemp; /* temporary registerss */
-
-   if (fprog->FogOption == GL_NONE) {
-      _mesa_problem(ctx, "_mesa_append_fog_code() called for fragment program"
-                    " with FogOption == GL_NONE");
-      return;
-   }
-
-   /* Alloc storage for new instructions */
-   newInst = _mesa_alloc_instructions(newLen);
-   if (!newInst) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY,
-                  "glProgramString(inserting fog_option code)");
-      return;
-   }
-
-   /* Copy orig instructions into new instruction buffer */
-   _mesa_copy_instructions(newInst, fprog->Base.Instructions, origLen);
-
-   /* PARAM fogParamsRefOpt = internal optimized fog params; */
-   fogPRefOpt
-      = _mesa_add_state_reference(fprog->Base.Parameters, fogPStateOpt);
-   /* PARAM fogColorRef = state.fog.color; */
-   fogColorRef
-      = _mesa_add_state_reference(fprog->Base.Parameters, fogColorState);
-
-   /* TEMP colorTemp; */
-   colorTemp = fprog->Base.NumTemporaries++;
-   /* TEMP fogFactorTemp; */
-   fogFactorTemp = fprog->Base.NumTemporaries++;
-
-   /* Scan program to find where result.color is written */
-   inst = newInst;
-   for (i = 0; i < fprog->Base.NumInstructions; i++) {
-      if (inst->Opcode == OPCODE_END)
-         break;
-      if (inst->DstReg.File == PROGRAM_OUTPUT &&
-          inst->DstReg.Index == FRAG_RESULT_COLOR) {
-         /* change the instruction to write to colorTemp w/ clamping */
-         inst->DstReg.File = PROGRAM_TEMPORARY;
-         inst->DstReg.Index = colorTemp;
-         inst->SaturateMode = SATURATE_ZERO_ONE;
-         /* don't break (may be several writes to result.color) */
-      }
-      inst++;
-   }
-   assert(inst->Opcode == OPCODE_END); /* we'll overwrite this inst */
-
-   _mesa_init_instructions(inst, 5);
-
-   /* emit instructions to compute fog blending factor */
-   if (fprog->FogOption == GL_LINEAR) {
-      /* MAD fogFactorTemp.x, fragment.fogcoord.x, fogPRefOpt.x, fogPRefOpt.y; */
-      inst->Opcode = OPCODE_MAD;
-      inst->DstReg.File = PROGRAM_TEMPORARY;
-      inst->DstReg.Index = fogFactorTemp;
-      inst->DstReg.WriteMask = WRITEMASK_X;
-      inst->SrcReg[0].File = PROGRAM_INPUT;
-      inst->SrcReg[0].Index = FRAG_ATTRIB_FOGC;
-      inst->SrcReg[0].Swizzle = SWIZZLE_XXXX;
-      inst->SrcReg[1].File = PROGRAM_STATE_VAR;
-      inst->SrcReg[1].Index = fogPRefOpt;
-      inst->SrcReg[1].Swizzle = SWIZZLE_XXXX;
-      inst->SrcReg[2].File = PROGRAM_STATE_VAR;
-      inst->SrcReg[2].Index = fogPRefOpt;
-      inst->SrcReg[2].Swizzle = SWIZZLE_YYYY;
-      inst->SaturateMode = SATURATE_ZERO_ONE;
-      inst++;
-   }
-   else {
-      ASSERT(fprog->FogOption == GL_EXP || fprog->FogOption == GL_EXP2);
-      /* fogPRefOpt.z = d/ln(2), fogPRefOpt.w = d/sqrt(ln(2) */
-      /* EXP: MUL fogFactorTemp.x, fogPRefOpt.z, fragment.fogcoord.x; */
-      /* EXP2: MUL fogFactorTemp.x, fogPRefOpt.w, fragment.fogcoord.x; */
-      inst->Opcode = OPCODE_MUL;
-      inst->DstReg.File = PROGRAM_TEMPORARY;
-      inst->DstReg.Index = fogFactorTemp;
-      inst->DstReg.WriteMask = WRITEMASK_X;
-      inst->SrcReg[0].File = PROGRAM_STATE_VAR;
-      inst->SrcReg[0].Index = fogPRefOpt;
-      inst->SrcReg[0].Swizzle
-         = (fprog->FogOption == GL_EXP) ? SWIZZLE_ZZZZ : SWIZZLE_WWWW;
-      inst->SrcReg[1].File = PROGRAM_INPUT;
-      inst->SrcReg[1].Index = FRAG_ATTRIB_FOGC;
-      inst->SrcReg[1].Swizzle = SWIZZLE_XXXX;
-      inst++;
-      if (fprog->FogOption == GL_EXP2) {
-         /* MUL fogFactorTemp.x, fogFactorTemp.x, fogFactorTemp.x; */
-         inst->Opcode = OPCODE_MUL;
-         inst->DstReg.File = PROGRAM_TEMPORARY;
-         inst->DstReg.Index = fogFactorTemp;
-         inst->DstReg.WriteMask = WRITEMASK_X;
-         inst->SrcReg[0].File = PROGRAM_TEMPORARY;
-         inst->SrcReg[0].Index = fogFactorTemp;
-         inst->SrcReg[0].Swizzle = SWIZZLE_XXXX;
-         inst->SrcReg[1].File = PROGRAM_TEMPORARY;
-         inst->SrcReg[1].Index = fogFactorTemp;
-         inst->SrcReg[1].Swizzle = SWIZZLE_XXXX;
-         inst++;
-      }
-      /* EX2_SAT fogFactorTemp.x, -fogFactorTemp.x; */
-      inst->Opcode = OPCODE_EX2;
-      inst->DstReg.File = PROGRAM_TEMPORARY;
-      inst->DstReg.Index = fogFactorTemp;
-      inst->DstReg.WriteMask = WRITEMASK_X;
-      inst->SrcReg[0].File = PROGRAM_TEMPORARY;
-      inst->SrcReg[0].Index = fogFactorTemp;
-      inst->SrcReg[0].Negate = NEGATE_XYZW;
-      inst->SrcReg[0].Swizzle = SWIZZLE_XXXX;
-      inst->SaturateMode = SATURATE_ZERO_ONE;
-      inst++;
-   }
-   /* LRP result.color.xyz, fogFactorTemp.xxxx, colorTemp, fogColorRef; */
-   inst->Opcode = OPCODE_LRP;
-   inst->DstReg.File = PROGRAM_OUTPUT;
-   inst->DstReg.Index = FRAG_RESULT_COLOR;
-   inst->DstReg.WriteMask = WRITEMASK_XYZ;
-   inst->SrcReg[0].File = PROGRAM_TEMPORARY;
-   inst->SrcReg[0].Index = fogFactorTemp;
-   inst->SrcReg[0].Swizzle = SWIZZLE_XXXX;
-   inst->SrcReg[1].File = PROGRAM_TEMPORARY;
-   inst->SrcReg[1].Index = colorTemp;
-   inst->SrcReg[1].Swizzle = SWIZZLE_NOOP;
-   inst->SrcReg[2].File = PROGRAM_STATE_VAR;
-   inst->SrcReg[2].Index = fogColorRef;
-   inst->SrcReg[2].Swizzle = SWIZZLE_NOOP;
-   inst++;
-   /* MOV result.color.w, colorTemp.x;  # copy alpha */
-   inst->Opcode = OPCODE_MOV;
-   inst->DstReg.File = PROGRAM_OUTPUT;
-   inst->DstReg.Index = FRAG_RESULT_COLOR;
-   inst->DstReg.WriteMask = WRITEMASK_W;
-   inst->SrcReg[0].File = PROGRAM_TEMPORARY;
-   inst->SrcReg[0].Index = colorTemp;
-   inst->SrcReg[0].Swizzle = SWIZZLE_NOOP;
-   inst++;
-   /* END; */
-   inst->Opcode = OPCODE_END;
-   inst++;
-
-   /* free old instructions */
-   _mesa_free_instructions(fprog->Base.Instructions, origLen);
-
-   /* install new instructions */
-   fprog->Base.Instructions = newInst;
-   fprog->Base.NumInstructions = inst - newInst;
-   fprog->Base.InputsRead |= FRAG_BIT_FOGC;
-   /* XXX do this?  fprog->FogOption = GL_NONE; */
-}
-
-
-
-static GLboolean
-is_texture_instruction(const struct prog_instruction *inst)
-{
-   switch (inst->Opcode) {
-   case OPCODE_TEX:
-   case OPCODE_TXB:
-   case OPCODE_TXD:
-   case OPCODE_TXL:
-   case OPCODE_TXP:
-   case OPCODE_TXP_NV:
-      return GL_TRUE;
-   default:
-      return GL_FALSE;
-   }
-}
-      
-
-/**
- * Count the number of texure indirections in the given program.
- * The program's NumTexIndirections field will be updated.
- * See the GL_ARB_fragment_program spec (issue 24) for details.
- * XXX we count texture indirections in texenvprogram.c (maybe use this code
- * instead and elsewhere).
- */
-void
-_mesa_count_texture_indirections(struct gl_program *prog)
-{
-   GLuint indirections = 1;
-   GLbitfield tempsOutput = 0x0;
-   GLbitfield aluTemps = 0x0;
-   GLuint i;
-
-   for (i = 0; i < prog->NumInstructions; i++) {
-      const struct prog_instruction *inst = prog->Instructions + i;
-
-      if (is_texture_instruction(inst)) {
-         if (((inst->SrcReg[0].File == PROGRAM_TEMPORARY) && 
-              (tempsOutput & (1 << inst->SrcReg[0].Index))) ||
-             ((inst->Opcode != OPCODE_KIL) &&
-              (inst->DstReg.File == PROGRAM_TEMPORARY) && 
-              (aluTemps & (1 << inst->DstReg.Index)))) 
-            {
-               indirections++;
-               tempsOutput = 0x0;
-               aluTemps = 0x0;
-            }
-      }
-      else {
-         GLuint j;
-         for (j = 0; j < 3; j++) {
-            if (inst->SrcReg[j].File == PROGRAM_TEMPORARY)
-               aluTemps |= (1 << inst->SrcReg[j].Index);
-         }
-         if (inst->DstReg.File == PROGRAM_TEMPORARY)
-            aluTemps |= (1 << inst->DstReg.Index);
-      }
-
-      if ((inst->Opcode != OPCODE_KIL) && (inst->DstReg.File == PROGRAM_TEMPORARY))
-         tempsOutput |= (1 << inst->DstReg.Index);
-   }
-
-   prog->NumTexIndirections = indirections;
-}
-
-
-/**
- * Count number of texture instructions in given program and update the
- * program's NumTexInstructions field.
- */
-void
-_mesa_count_texture_instructions(struct gl_program *prog)
-{
-   GLuint i;
-   prog->NumTexInstructions = 0;
-   for (i = 0; i < prog->NumInstructions; i++) {
-      prog->NumTexInstructions += is_texture_instruction(prog->Instructions + i);
-   }
-}
-
-
-/**
- * Scan/rewrite program to remove reads of custom (output) registers.
- * The passed type has to be either PROGRAM_OUTPUT or PROGRAM_VARYING
- * (for vertex shaders).
- * In GLSL shaders, varying vars can be read and written.
- * On some hardware, trying to read an output register causes trouble.
- * So, rewrite the program to use a temporary register in this case.
- */
-void
-_mesa_remove_output_reads(struct gl_program *prog, gl_register_file type)
-{
-   GLuint i;
-   GLint outputMap[VERT_RESULT_MAX];
-   GLuint numVaryingReads = 0;
-   GLboolean usedTemps[MAX_PROGRAM_TEMPS];
-   GLuint firstTemp = 0;
-
-   _mesa_find_used_registers(prog, PROGRAM_TEMPORARY,
-                             usedTemps, MAX_PROGRAM_TEMPS);
-
-   assert(type == PROGRAM_VARYING || type == PROGRAM_OUTPUT);
-   assert(prog->Target == GL_VERTEX_PROGRAM_ARB || type != PROGRAM_VARYING);
-
-   for (i = 0; i < VERT_RESULT_MAX; i++)
-      outputMap[i] = -1;
-
-   /* look for instructions which read from varying vars */
-   for (i = 0; i < prog->NumInstructions; i++) {
-      struct prog_instruction *inst = prog->Instructions + i;
-      const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
-      GLuint j;
-      for (j = 0; j < numSrc; j++) {
-         if (inst->SrcReg[j].File == type) {
-            /* replace the read with a temp reg */
-            const GLuint var = inst->SrcReg[j].Index;
-            if (outputMap[var] == -1) {
-               numVaryingReads++;
-               outputMap[var] = _mesa_find_free_register(usedTemps,
-                                                         MAX_PROGRAM_TEMPS,
-                                                         firstTemp);
-               firstTemp = outputMap[var] + 1;
-            }
-            inst->SrcReg[j].File = PROGRAM_TEMPORARY;
-            inst->SrcReg[j].Index = outputMap[var];
-         }
-      }
-   }
-
-   if (numVaryingReads == 0)
-      return; /* nothing to be done */
-
-   /* look for instructions which write to the varying vars identified above */
-   for (i = 0; i < prog->NumInstructions; i++) {
-      struct prog_instruction *inst = prog->Instructions + i;
-      if (inst->DstReg.File == type &&
-          outputMap[inst->DstReg.Index] >= 0) {
-         /* change inst to write to the temp reg, instead of the varying */
-         inst->DstReg.File = PROGRAM_TEMPORARY;
-         inst->DstReg.Index = outputMap[inst->DstReg.Index];
-      }
-   }
-
-   /* insert new instructions to copy the temp vars to the varying vars */
-   {
-      struct prog_instruction *inst;
-      GLint endPos, var;
-
-      /* Look for END instruction and insert the new varying writes */
-      endPos = -1;
-      for (i = 0; i < prog->NumInstructions; i++) {
-         struct prog_instruction *inst = prog->Instructions + i;
-         if (inst->Opcode == OPCODE_END) {
-            endPos = i;
-            _mesa_insert_instructions(prog, i, numVaryingReads);
-            break;
-         }
-      }
-
-      assert(endPos >= 0);
-
-      /* insert new MOV instructions here */
-      inst = prog->Instructions + endPos;
-      for (var = 0; var < VERT_RESULT_MAX; var++) {
-         if (outputMap[var] >= 0) {
-            /* MOV VAR[var], TEMP[tmp]; */
-            inst->Opcode = OPCODE_MOV;
-            inst->DstReg.File = type;
-            inst->DstReg.Index = var;
-            inst->SrcReg[0].File = PROGRAM_TEMPORARY;
-            inst->SrcReg[0].Index = outputMap[var];
-            inst++;
-         }
-      }
-   }
-}
-
-
-/**
- * Make the given fragment program into a "no-op" shader.
- * Actually, just copy the incoming fragment color (or texcoord)
- * to the output color.
- * This is for debug/test purposes.
- */
-void
-_mesa_nop_fragment_program(GLcontext *ctx, struct gl_fragment_program *prog)
-{
-   struct prog_instruction *inst;
-   GLuint inputAttr;
-
-   inst = _mesa_alloc_instructions(2);
-   if (!inst) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "_mesa_nop_fragment_program");
-      return;
-   }
-
-   _mesa_init_instructions(inst, 2);
-
-   inst[0].Opcode = OPCODE_MOV;
-   inst[0].DstReg.File = PROGRAM_OUTPUT;
-   inst[0].DstReg.Index = FRAG_RESULT_COLOR;
-   inst[0].SrcReg[0].File = PROGRAM_INPUT;
-   if (prog->Base.InputsRead & FRAG_BIT_COL0)
-      inputAttr = FRAG_ATTRIB_COL0;
-   else
-      inputAttr = FRAG_ATTRIB_TEX0;
-   inst[0].SrcReg[0].Index = inputAttr;
-
-   inst[1].Opcode = OPCODE_END;
-
-   _mesa_free_instructions(prog->Base.Instructions,
-                           prog->Base.NumInstructions);
-
-   prog->Base.Instructions = inst;
-   prog->Base.NumInstructions = 2;
-   prog->Base.InputsRead = 1 << inputAttr;
-   prog->Base.OutputsWritten = BITFIELD64_BIT(FRAG_RESULT_COLOR);
-}
-
-
-/**
- * \sa _mesa_nop_fragment_program
- * Replace the given vertex program with a "no-op" program that just
- * transforms vertex position and emits color.
- */
-void
-_mesa_nop_vertex_program(GLcontext *ctx, struct gl_vertex_program *prog)
-{
-   struct prog_instruction *inst;
-   GLuint inputAttr;
-
-   /*
-    * Start with a simple vertex program that emits color.
-    */
-   inst = _mesa_alloc_instructions(2);
-   if (!inst) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "_mesa_nop_vertex_program");
-      return;
-   }
-
-   _mesa_init_instructions(inst, 2);
-
-   inst[0].Opcode = OPCODE_MOV;
-   inst[0].DstReg.File = PROGRAM_OUTPUT;
-   inst[0].DstReg.Index = VERT_RESULT_COL0;
-   inst[0].SrcReg[0].File = PROGRAM_INPUT;
-   if (prog->Base.InputsRead & VERT_BIT_COLOR0)
-      inputAttr = VERT_ATTRIB_COLOR0;
-   else
-      inputAttr = VERT_ATTRIB_TEX0;
-   inst[0].SrcReg[0].Index = inputAttr;
-
-   inst[1].Opcode = OPCODE_END;
-
-   _mesa_free_instructions(prog->Base.Instructions,
-                           prog->Base.NumInstructions);
-
-   prog->Base.Instructions = inst;
-   prog->Base.NumInstructions = 2;
-   prog->Base.InputsRead = 1 << inputAttr;
-   prog->Base.OutputsWritten = BITFIELD64_BIT(VERT_RESULT_COL0);
-
-   /*
-    * Now insert code to do standard modelview/projection transformation.
-    */
-   _mesa_insert_mvp_code(ctx, prog);
-}
diff --git a/src/mesa/shader/programopt.h b/src/mesa/shader/programopt.h
deleted file mode 100644 (file)
index 21fac07..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.3
- *
- * 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.
- */
-
-
-#ifndef PROGRAMOPT_H
-#define PROGRAMOPT_H 1
-
-
-extern void
-_mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog);
-
-extern void
-_mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog);
-
-extern void
-_mesa_count_texture_indirections(struct gl_program *prog);
-
-extern void
-_mesa_count_texture_instructions(struct gl_program *prog);
-
-extern void
-_mesa_remove_output_reads(struct gl_program *prog, gl_register_file type);
-
-extern void
-_mesa_nop_fragment_program(GLcontext *ctx, struct gl_fragment_program *prog);
-
-extern void
-_mesa_nop_vertex_program(GLcontext *ctx, struct gl_vertex_program *prog);
-
-
-#endif /* PROGRAMOPT_H */
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
deleted file mode 100644 (file)
index 1c16653..0000000
+++ /dev/null
@@ -1,1421 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.6
- *
- * Copyright (C) 2004-2008  Brian Paul   All Rights Reserved.
- * Copyright (C) 2009  VMware, 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
- * 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 shader_api.c
- * Implementation of GLSL-related API functions
- * \author Brian Paul
- */
-
-/**
- * XXX things to do:
- * 1. Check that the right error code is generated for all _mesa_error() calls.
- * 2. Insert FLUSH_VERTICES calls in various places
- */
-
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/hash.h"
-#include "shader/program.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_uniform.h"
-#include "shader/shader_api.h"
-#include "shader/uniforms.h"
-#include "talloc.h"
-
-/**
- * Allocate a new gl_shader_program object, initialize it.
- */
-static struct gl_shader_program *
-_mesa_new_shader_program(GLcontext *ctx, GLuint name)
-{
-   struct gl_shader_program *shProg;
-   shProg = talloc_zero(NULL, struct gl_shader_program);
-   if (shProg) {
-      shProg->Type = GL_SHADER_PROGRAM_MESA;
-      shProg->Name = name;
-      shProg->RefCount = 1;
-      shProg->Attributes = _mesa_new_parameter_list();
-   }
-   return shProg;
-}
-
-
-/**
- * Clear (free) the shader program state that gets produced by linking.
- */
-void
-_mesa_clear_shader_program_data(GLcontext *ctx,
-                                struct gl_shader_program *shProg)
-{
-   _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
-   _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
-
-   if (shProg->Uniforms) {
-      _mesa_free_uniform_list(shProg->Uniforms);
-      shProg->Uniforms = NULL;
-   }
-
-   if (shProg->Varying) {
-      _mesa_free_parameter_list(shProg->Varying);
-      shProg->Varying = NULL;
-   }
-}
-
-
-/**
- * Free all the data that hangs off a shader program object, but not the
- * object itself.
- */
-void
-_mesa_free_shader_program_data(GLcontext *ctx,
-                               struct gl_shader_program *shProg)
-{
-   GLuint i;
-
-   assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
-
-   _mesa_clear_shader_program_data(ctx, shProg);
-
-   if (shProg->Attributes) {
-      _mesa_free_parameter_list(shProg->Attributes);
-      shProg->Attributes = NULL;
-   }
-
-   /* detach shaders */
-   for (i = 0; i < shProg->NumShaders; i++) {
-      _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
-   }
-   shProg->NumShaders = 0;
-
-   if (shProg->Shaders) {
-      free(shProg->Shaders);
-      shProg->Shaders = NULL;
-   }
-
-   if (shProg->InfoLog) {
-      talloc_free(shProg->InfoLog);
-      shProg->InfoLog = NULL;
-   }
-
-   /* Transform feedback varying vars */
-   for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
-      free(shProg->TransformFeedback.VaryingNames[i]);
-   }
-   free(shProg->TransformFeedback.VaryingNames);
-   shProg->TransformFeedback.VaryingNames = NULL;
-   shProg->TransformFeedback.NumVarying = 0;
-}
-
-
-/**
- * Free/delete a shader program object.
- */
-void
-_mesa_free_shader_program(GLcontext *ctx, struct gl_shader_program *shProg)
-{
-   _mesa_free_shader_program_data(ctx, shProg);
-
-   talloc_free(shProg);
-}
-
-
-/**
- * Set ptr to point to shProg.
- * If ptr is pointing to another object, decrement its refcount (and delete
- * if refcount hits zero).
- * Then set ptr to point to shProg, incrementing its refcount.
- */
-/* XXX this could be static */
-void
-_mesa_reference_shader_program(GLcontext *ctx,
-                               struct gl_shader_program **ptr,
-                               struct gl_shader_program *shProg)
-{
-   assert(ptr);
-   if (*ptr == shProg) {
-      /* no-op */
-      return;
-   }
-   if (*ptr) {
-      /* Unreference the old shader program */
-      GLboolean deleteFlag = GL_FALSE;
-      struct gl_shader_program *old = *ptr;
-
-      ASSERT(old->RefCount > 0);
-      old->RefCount--;
-#if 0
-      printf("ShaderProgram %p ID=%u  RefCount-- to %d\n",
-             (void *) old, old->Name, old->RefCount);
-#endif
-      deleteFlag = (old->RefCount == 0);
-
-      if (deleteFlag) {
-         _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
-         _mesa_free_shader_program(ctx, old);
-      }
-
-      *ptr = NULL;
-   }
-   assert(!*ptr);
-
-   if (shProg) {
-      shProg->RefCount++;
-#if 0
-      printf("ShaderProgram %p ID=%u  RefCount++ to %d\n",
-             (void *) shProg, shProg->Name, shProg->RefCount);
-#endif
-      *ptr = shProg;
-   }
-}
-
-
-/**
- * Lookup a GLSL program object.
- */
-struct gl_shader_program *
-_mesa_lookup_shader_program(GLcontext *ctx, GLuint name)
-{
-   struct gl_shader_program *shProg;
-   if (name) {
-      shProg = (struct gl_shader_program *)
-         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
-      /* Note that both gl_shader and gl_shader_program objects are kept
-       * in the same hash table.  Check the object's type to be sure it's
-       * what we're expecting.
-       */
-      if (shProg && shProg->Type != GL_SHADER_PROGRAM_MESA) {
-         return NULL;
-      }
-      return shProg;
-   }
-   return NULL;
-}
-
-
-/**
- * As above, but record an error if program is not found.
- */
-struct gl_shader_program *
-_mesa_lookup_shader_program_err(GLcontext *ctx, GLuint name,
-                                const char *caller)
-{
-   if (!name) {
-      _mesa_error(ctx, GL_INVALID_VALUE, caller);
-      return NULL;
-   }
-   else {
-      struct gl_shader_program *shProg = (struct gl_shader_program *)
-         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
-      if (!shProg) {
-         _mesa_error(ctx, GL_INVALID_VALUE, caller);
-         return NULL;
-      }
-      if (shProg->Type != GL_SHADER_PROGRAM_MESA) {
-         _mesa_error(ctx, GL_INVALID_OPERATION, caller);
-         return NULL;
-      }
-      return shProg;
-   }
-}
-
-
-
-
-/**
- * Allocate a new gl_shader object, initialize it.
- */
-struct gl_shader *
-_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type)
-{
-   struct gl_shader *shader;
-   assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER);
-   shader = talloc_zero(NULL, struct gl_shader);
-   if (shader) {
-      shader->Type = type;
-      shader->Name = name;
-      shader->RefCount = 1;
-   }
-   return shader;
-}
-
-
-void
-_mesa_free_shader(GLcontext *ctx, struct gl_shader *sh)
-{
-   if (sh->Source)
-      free((void *) sh->Source);
-   _mesa_reference_program(ctx, &sh->Program, NULL);
-   talloc_free(sh);
-}
-
-
-/**
- * Set ptr to point to sh.
- * If ptr is pointing to another shader, decrement its refcount (and delete
- * if refcount hits zero).
- * Then set ptr to point to sh, incrementing its refcount.
- */
-/* XXX this could be static */
-void
-_mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr,
-                       struct gl_shader *sh)
-{
-   assert(ptr);
-   if (*ptr == sh) {
-      /* no-op */
-      return;
-   }
-   if (*ptr) {
-      /* Unreference the old shader */
-      GLboolean deleteFlag = GL_FALSE;
-      struct gl_shader *old = *ptr;
-
-      ASSERT(old->RefCount > 0);
-      old->RefCount--;
-      /*printf("SHADER DECR %p (%d) to %d\n",
-        (void*) old, old->Name, old->RefCount);*/
-      deleteFlag = (old->RefCount == 0);
-
-      if (deleteFlag) {
-         _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
-         _mesa_free_shader(ctx, old);
-      }
-
-      *ptr = NULL;
-   }
-   assert(!*ptr);
-
-   if (sh) {
-      /* reference new */
-      sh->RefCount++;
-      /*printf("SHADER INCR %p (%d) to %d\n",
-        (void*) sh, sh->Name, sh->RefCount);*/
-      *ptr = sh;
-   }
-}
-
-
-/**
- * Lookup a GLSL shader object.
- */
-struct gl_shader *
-_mesa_lookup_shader(GLcontext *ctx, GLuint name)
-{
-   if (name) {
-      struct gl_shader *sh = (struct gl_shader *)
-         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
-      /* Note that both gl_shader and gl_shader_program objects are kept
-       * in the same hash table.  Check the object's type to be sure it's
-       * what we're expecting.
-       */
-      if (sh && sh->Type == GL_SHADER_PROGRAM_MESA) {
-         return NULL;
-      }
-      return sh;
-   }
-   return NULL;
-}
-
-
-/**
- * As above, but record an error if shader is not found.
- */
-static struct gl_shader *
-_mesa_lookup_shader_err(GLcontext *ctx, GLuint name, const char *caller)
-{
-   if (!name) {
-      _mesa_error(ctx, GL_INVALID_VALUE, caller);
-      return NULL;
-   }
-   else {
-      struct gl_shader *sh = (struct gl_shader *)
-         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
-      if (!sh) {
-         _mesa_error(ctx, GL_INVALID_VALUE, caller);
-         return NULL;
-      }
-      if (sh->Type == GL_SHADER_PROGRAM_MESA) {
-         _mesa_error(ctx, GL_INVALID_OPERATION, caller);
-         return NULL;
-      }
-      return sh;
-   }
-}
-
-
-/**
- * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
- */
-static GLbitfield
-get_shader_flags(void)
-{
-   GLbitfield flags = 0x0;
-   const char *env = _mesa_getenv("MESA_GLSL");
-
-   if (env) {
-      if (strstr(env, "dump"))
-         flags |= GLSL_DUMP;
-      if (strstr(env, "log"))
-         flags |= GLSL_LOG;
-      if (strstr(env, "nopvert"))
-         flags |= GLSL_NOP_VERT;
-      if (strstr(env, "nopfrag"))
-         flags |= GLSL_NOP_FRAG;
-      if (strstr(env, "nopt"))
-         flags |= GLSL_NO_OPT;
-      else if (strstr(env, "opt"))
-         flags |= GLSL_OPT;
-      if (strstr(env, "uniform"))
-         flags |= GLSL_UNIFORMS;
-      if (strstr(env, "useprog"))
-         flags |= GLSL_USE_PROG;
-   }
-
-   return flags;
-}
-
-
-/**
- * Find the length of the longest transform feedback varying name
- * which was specified with glTransformFeedbackVaryings().
- */
-static GLint
-longest_feedback_varying_name(const struct gl_shader_program *shProg)
-{
-   GLuint i;
-   GLint max = 0;
-   for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
-      GLint len = strlen(shProg->TransformFeedback.VaryingNames[i]);
-      if (len > max)
-         max = len;
-   }
-   return max;
-}
-
-
-
-/**
- * Initialize context's shader state.
- */
-void
-_mesa_init_shader_state(GLcontext * ctx)
-{
-   /* Device drivers may override these to control what kind of instructions
-    * are generated by the GLSL compiler.
-    */
-   ctx->Shader.EmitHighLevelInstructions = GL_TRUE;
-   ctx->Shader.EmitContReturn = GL_TRUE;
-   ctx->Shader.EmitCondCodes = GL_FALSE;
-   ctx->Shader.EmitComments = GL_FALSE;
-   ctx->Shader.EmitNoIfs = GL_FALSE;
-   ctx->Shader.Flags = get_shader_flags();
-
-   /* Default pragma settings */
-   ctx->Shader.DefaultPragmas.IgnoreOptimize = GL_FALSE;
-   ctx->Shader.DefaultPragmas.IgnoreDebug = GL_FALSE;
-   ctx->Shader.DefaultPragmas.Optimize = GL_TRUE;
-   ctx->Shader.DefaultPragmas.Debug = GL_FALSE;
-}
-
-
-/**
- * Free the per-context shader-related state.
- */
-void
-_mesa_free_shader_state(GLcontext *ctx)
-{
-   _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, NULL);
-}
-
-
-/**
- * Copy string from <src> to <dst>, up to maxLength characters, returning
- * length of <dst> in <length>.
- * \param src  the strings source
- * \param maxLength  max chars to copy
- * \param length  returns number of chars copied
- * \param dst  the string destination
- */
-void
-_mesa_copy_string(GLchar *dst, GLsizei maxLength,
-                  GLsizei *length, const GLchar *src)
-{
-   GLsizei len;
-   for (len = 0; len < maxLength - 1 && src && src[len]; len++)
-      dst[len] = src[len];
-   if (maxLength > 0)
-      dst[len] = 0;
-   if (length)
-      *length = len;
-}
-
-
-static GLboolean
-_mesa_is_program(GLcontext *ctx, GLuint name)
-{
-   struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name);
-   return shProg ? GL_TRUE : GL_FALSE;
-}
-
-
-static GLboolean
-_mesa_is_shader(GLcontext *ctx, GLuint name)
-{
-   struct gl_shader *shader = _mesa_lookup_shader(ctx, name);
-   return shader ? GL_TRUE : GL_FALSE;
-}
-
-
-/**
- * Called via ctx->Driver.AttachShader()
- */
-static void
-_mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader)
-{
-   struct gl_shader_program *shProg;
-   struct gl_shader *sh;
-   GLuint i, n;
-
-   shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader");
-   if (!shProg)
-      return;
-
-   sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader");
-   if (!sh) {
-      return;
-   }
-
-   n = shProg->NumShaders;
-   for (i = 0; i < n; i++) {
-      if (shProg->Shaders[i] == sh) {
-         /* The shader is already attched to this program.  The
-          * GL_ARB_shader_objects spec says:
-          *
-          *     "The error INVALID_OPERATION is generated by AttachObjectARB
-          *     if <obj> is already attached to <containerObj>."
-          */
-         _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader");
-         return;
-      }
-   }
-
-   /* grow list */
-   shProg->Shaders = (struct gl_shader **)
-      _mesa_realloc(shProg->Shaders,
-                    n * sizeof(struct gl_shader *),
-                    (n + 1) * sizeof(struct gl_shader *));
-   if (!shProg->Shaders) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader");
-      return;
-   }
-
-   /* append */
-   shProg->Shaders[n] = NULL; /* since realloc() didn't zero the new space */
-   _mesa_reference_shader(ctx, &shProg->Shaders[n], sh);
-   shProg->NumShaders++;
-}
-
-
-static GLint
-_mesa_get_attrib_location(GLcontext *ctx, GLuint program,
-                          const GLchar *name)
-{
-   struct gl_shader_program *shProg
-      = _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation");
-
-   if (!shProg) {
-      return -1;
-   }
-
-   if (!shProg->LinkStatus) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glGetAttribLocation(program not linked)");
-      return -1;
-   }
-
-   if (!name)
-      return -1;
-
-   if (shProg->VertexProgram) {
-      const struct gl_program_parameter_list *attribs =
-         shProg->VertexProgram->Base.Attributes;
-      if (attribs) {
-         GLint i = _mesa_lookup_parameter_index(attribs, -1, name);
-         if (i >= 0) {
-            return attribs->Parameters[i].StateIndexes[0];
-         }
-      }
-   }
-   return -1;
-}
-
-
-static void
-_mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index,
-                           const GLchar *name)
-{
-   struct gl_shader_program *shProg;
-   const GLint size = -1; /* unknown size */
-   GLint i, oldIndex;
-   GLenum datatype = GL_FLOAT_VEC4;
-
-   shProg = _mesa_lookup_shader_program_err(ctx, program,
-                                            "glBindAttribLocation");
-   if (!shProg) {
-      return;
-   }
-
-   if (!name)
-      return;
-
-   if (strncmp(name, "gl_", 3) == 0) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glBindAttribLocation(illegal name)");
-      return;
-   }
-
-   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(index)");
-      return;
-   }
-
-   if (shProg->LinkStatus) {
-      /* get current index/location for the attribute */
-      oldIndex = _mesa_get_attrib_location(ctx, program, name);
-   }
-   else {
-      oldIndex = -1;
-   }
-
-   /* this will replace the current value if it's already in the list */
-   i = _mesa_add_attribute(shProg->Attributes, name, size, datatype, index);
-   if (i < 0) {
-      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindAttribLocation");
-      return;
-   }
-
-   /*
-    * Note that this attribute binding won't go into effect until
-    * glLinkProgram is called again.
-    */
-}
-
-
-static GLuint
-_mesa_create_shader(GLcontext *ctx, GLenum type)
-{
-   struct gl_shader *sh;
-   GLuint name;
-
-   name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
-
-   switch (type) {
-   case GL_FRAGMENT_SHADER:
-   case GL_VERTEX_SHADER:
-      sh = _mesa_new_shader(ctx, name, type);
-      break;
-   default:
-      _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)");
-      return 0;
-   }
-
-   _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh);
-
-   return name;
-}
-
-
-static GLuint 
-_mesa_create_program(GLcontext *ctx)
-{
-   GLuint name;
-   struct gl_shader_program *shProg;
-
-   name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
-   shProg = _mesa_new_shader_program(ctx, name);
-
-   _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg);
-
-   assert(shProg->RefCount == 1);
-
-   return name;
-}
-
-
-/**
- * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's
- * DeleteProgramARB.
- */
-static void
-_mesa_delete_program2(GLcontext *ctx, GLuint name)
-{
-   /*
-    * NOTE: deleting shaders/programs works a bit differently than
-    * texture objects (and buffer objects, etc).  Shader/program
-    * handles/IDs exist in the hash table until the object is really
-    * deleted (refcount==0).  With texture objects, the handle/ID is
-    * removed from the hash table in glDeleteTextures() while the tex
-    * object itself might linger until its refcount goes to zero.
-    */
-   struct gl_shader_program *shProg;
-
-   shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram");
-   if (!shProg)
-      return;
-
-   shProg->DeletePending = GL_TRUE;
-
-   /* effectively, decr shProg's refcount */
-   _mesa_reference_shader_program(ctx, &shProg, NULL);
-}
-
-
-static void
-_mesa_delete_shader(GLcontext *ctx, GLuint shader)
-{
-   struct gl_shader *sh;
-
-   sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader");
-   if (!sh)
-      return;
-
-   sh->DeletePending = GL_TRUE;
-
-   /* effectively, decr sh's refcount */
-   _mesa_reference_shader(ctx, &sh, NULL);
-}
-
-
-static void
-_mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader)
-{
-   struct gl_shader_program *shProg;
-   GLuint n;
-   GLuint i, j;
-
-   shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader");
-   if (!shProg)
-      return;
-
-   n = shProg->NumShaders;
-
-   for (i = 0; i < n; i++) {
-      if (shProg->Shaders[i]->Name == shader) {
-         /* found it */
-         struct gl_shader **newList;
-
-         /* release */
-         _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
-
-         /* alloc new, smaller array */
-         newList = (struct gl_shader **)
-            malloc((n - 1) * sizeof(struct gl_shader *));
-         if (!newList) {
-            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader");
-            return;
-         }
-         for (j = 0; j < i; j++) {
-            newList[j] = shProg->Shaders[j];
-         }
-         while (++i < n)
-            newList[j++] = shProg->Shaders[i];
-         free(shProg->Shaders);
-
-         shProg->Shaders = newList;
-         shProg->NumShaders = n - 1;
-
-#ifdef DEBUG
-         /* sanity check */
-         {
-            for (j = 0; j < shProg->NumShaders; j++) {
-               assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER ||
-                      shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER);
-               assert(shProg->Shaders[j]->RefCount > 0);
-            }
-         }
-#endif
-
-         return;
-      }
-   }
-
-   /* not found */
-   {
-      GLenum err;
-      if (_mesa_is_shader(ctx, shader))
-         err = GL_INVALID_OPERATION;
-      else if (_mesa_is_program(ctx, shader))
-         err = GL_INVALID_OPERATION;
-      else
-         err = GL_INVALID_VALUE;
-      _mesa_error(ctx, err, "glDetachProgram(shader)");
-      return;
-   }
-}
-
-
-/**
- * Return the size of the given GLSL datatype, in floats (components).
- */
-GLint
-_mesa_sizeof_glsl_type(GLenum type)
-{
-   switch (type) {
-   case GL_FLOAT:
-   case GL_INT:
-   case GL_BOOL:
-   case GL_SAMPLER_1D:
-   case GL_SAMPLER_2D:
-   case GL_SAMPLER_3D:
-   case GL_SAMPLER_CUBE:
-   case GL_SAMPLER_1D_SHADOW:
-   case GL_SAMPLER_2D_SHADOW:
-   case GL_SAMPLER_2D_RECT_ARB:
-   case GL_SAMPLER_2D_RECT_SHADOW_ARB:
-   case GL_SAMPLER_1D_ARRAY_EXT:
-   case GL_SAMPLER_2D_ARRAY_EXT:
-   case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
-   case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
-   case GL_SAMPLER_CUBE_SHADOW_EXT:
-      return 1;
-   case GL_FLOAT_VEC2:
-   case GL_INT_VEC2:
-   case GL_UNSIGNED_INT_VEC2:
-   case GL_BOOL_VEC2:
-      return 2;
-   case GL_FLOAT_VEC3:
-   case GL_INT_VEC3:
-   case GL_UNSIGNED_INT_VEC3:
-   case GL_BOOL_VEC3:
-      return 3;
-   case GL_FLOAT_VEC4:
-   case GL_INT_VEC4:
-   case GL_UNSIGNED_INT_VEC4:
-   case GL_BOOL_VEC4:
-      return 4;
-   case GL_FLOAT_MAT2:
-   case GL_FLOAT_MAT2x3:
-   case GL_FLOAT_MAT2x4:
-      return 8; /* two float[4] vectors */
-   case GL_FLOAT_MAT3:
-   case GL_FLOAT_MAT3x2:
-   case GL_FLOAT_MAT3x4:
-      return 12; /* three float[4] vectors */
-   case GL_FLOAT_MAT4:
-   case GL_FLOAT_MAT4x2:
-   case GL_FLOAT_MAT4x3:
-      return 16;  /* four float[4] vectors */
-   default:
-      _mesa_problem(NULL, "Invalid type in _mesa_sizeof_glsl_type()");
-      return 1;
-   }
-}
-
-
-static void
-_mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
-                        GLsizei maxLength, GLsizei *length, GLint *size,
-                        GLenum *type, GLchar *nameOut)
-{
-   const struct gl_program_parameter_list *attribs = NULL;
-   struct gl_shader_program *shProg;
-
-   shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib");
-   if (!shProg)
-      return;
-
-   if (shProg->VertexProgram)
-      attribs = shProg->VertexProgram->Base.Attributes;
-
-   if (!attribs || index >= attribs->NumParameters) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)");
-      return;
-   }
-
-   _mesa_copy_string(nameOut, maxLength, length,
-                     attribs->Parameters[index].Name);
-
-   if (size)
-      *size = attribs->Parameters[index].Size
-         / _mesa_sizeof_glsl_type(attribs->Parameters[index].DataType);
-
-   if (type)
-      *type = attribs->Parameters[index].DataType;
-}
-
-
-/**
- * Called via ctx->Driver.GetAttachedShaders().
- */
-static void
-_mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount,
-                           GLsizei *count, GLuint *obj)
-{
-   struct gl_shader_program *shProg =
-      _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders");
-   if (shProg) {
-      GLuint i;
-      for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) {
-         obj[i] = shProg->Shaders[i]->Name;
-      }
-      if (count)
-         *count = i;
-   }
-}
-
-
-/** glGetHandleARB() - return ID/name of currently bound shader program */
-static GLuint
-_mesa_get_handle(GLcontext *ctx, GLenum pname)
-{
-   if (pname == GL_PROGRAM_OBJECT_ARB) {
-      if (ctx->Shader.CurrentProgram)
-         return ctx->Shader.CurrentProgram->Name;
-      else
-         return 0;
-   }
-   else {
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
-      return 0;
-   }
-}
-
-
-/**
- * glGetProgramiv() - get shader program state.
- * Note that this is for GLSL shader programs, not ARB vertex/fragment
- * programs (see glGetProgramivARB).
- */
-static void
-_mesa_get_programiv(GLcontext *ctx, GLuint program,
-                    GLenum pname, GLint *params)
-{
-   const struct gl_program_parameter_list *attribs;
-   struct gl_shader_program *shProg
-      = _mesa_lookup_shader_program(ctx, program);
-
-   if (!shProg) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)");
-      return;
-   }
-
-   if (shProg->VertexProgram)
-      attribs = shProg->VertexProgram->Base.Attributes;
-   else
-      attribs = NULL;
-
-   switch (pname) {
-   case GL_DELETE_STATUS:
-      *params = shProg->DeletePending;
-      break; 
-   case GL_LINK_STATUS:
-      *params = shProg->LinkStatus;
-      break;
-   case GL_VALIDATE_STATUS:
-      *params = shProg->Validated;
-      break;
-   case GL_INFO_LOG_LENGTH:
-      *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0;
-      break;
-   case GL_ATTACHED_SHADERS:
-      *params = shProg->NumShaders;
-      break;
-   case GL_ACTIVE_ATTRIBUTES:
-      *params = attribs ? attribs->NumParameters : 0;
-      break;
-   case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
-      *params = _mesa_longest_parameter_name(attribs, PROGRAM_INPUT) + 1;
-      break;
-   case GL_ACTIVE_UNIFORMS:
-      *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0;
-      break;
-   case GL_ACTIVE_UNIFORM_MAX_LENGTH:
-      *params = _mesa_longest_uniform_name(shProg->Uniforms);
-      if (*params > 0)
-         (*params)++;  /* add one for terminating zero */
-      break;
-   case GL_PROGRAM_BINARY_LENGTH_OES:
-      *params = 0;
-      break;
-#if FEATURE_EXT_transform_feedback
-   case GL_TRANSFORM_FEEDBACK_VARYINGS:
-      *params = shProg->TransformFeedback.NumVarying;
-      break;
-   case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
-      *params = longest_feedback_varying_name(shProg) + 1;
-      break;
-   case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
-      *params = shProg->TransformFeedback.BufferMode;
-      break;
-#endif
-   default:
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
-      return;
-   }
-}
-
-
-/** glGetShaderiv() - get GLSL shader state */
-static void
-_mesa_get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params)
-{
-   struct gl_shader *shader = _mesa_lookup_shader_err(ctx, name, "glGetShaderiv");
-
-   if (!shader) {
-      return;
-   }
-
-   switch (pname) {
-   case GL_SHADER_TYPE:
-      *params = shader->Type;
-      break;
-   case GL_DELETE_STATUS:
-      *params = shader->DeletePending;
-      break;
-   case GL_COMPILE_STATUS:
-      *params = shader->CompileStatus;
-      break;
-   case GL_INFO_LOG_LENGTH:
-      *params = shader->InfoLog ? strlen(shader->InfoLog) + 1 : 0;
-      break;
-   case GL_SHADER_SOURCE_LENGTH:
-      *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0;
-      break;
-   default:
-      _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
-      return;
-   }
-}
-
-
-static void
-_mesa_get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize,
-                           GLsizei *length, GLchar *infoLog)
-{
-   struct gl_shader_program *shProg
-      = _mesa_lookup_shader_program(ctx, program);
-   if (!shProg) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)");
-      return;
-   }
-   _mesa_copy_string(infoLog, bufSize, length, shProg->InfoLog);
-}
-
-
-static void
-_mesa_get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize,
-                          GLsizei *length, GLchar *infoLog)
-{
-   struct gl_shader *sh = _mesa_lookup_shader(ctx, shader);
-   if (!sh) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)");
-      return;
-   }
-   _mesa_copy_string(infoLog, bufSize, length, sh->InfoLog);
-}
-
-
-/**
- * Called via ctx->Driver.GetShaderSource().
- */
-static void
-_mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
-                        GLsizei *length, GLchar *sourceOut)
-{
-   struct gl_shader *sh;
-   sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource");
-   if (!sh) {
-      return;
-   }
-   _mesa_copy_string(sourceOut, maxLength, length, sh->Source);
-}
-
-
-/**
- * Called via ctx->Driver.ShaderSource()
- */
-static void
-_mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source)
-{
-   struct gl_shader *sh;
-
-   sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource");
-   if (!sh)
-      return;
-
-   /* free old shader source string and install new one */
-   if (sh->Source) {
-      free((void *) sh->Source);
-   }
-   sh->Source = source;
-   sh->CompileStatus = GL_FALSE;
-#ifdef DEBUG
-   sh->SourceChecksum = _mesa_str_checksum(sh->Source);
-#endif
-}
-
-
-/**
- * Called via ctx->Driver.CompileShader()
- */
-static void
-_mesa_compile_shader(GLcontext *ctx, GLuint shaderObj)
-{
-   struct gl_shader *sh;
-
-   sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader");
-   if (!sh)
-      return;
-
-   /* set default pragma state for shader */
-   sh->Pragmas = ctx->Shader.DefaultPragmas;
-
-   /* this call will set the sh->CompileStatus field to indicate if
-    * compilation was successful.
-    */
-   _mesa_glsl_compile_shader(ctx, sh);
-}
-
-
-/**
- * Called via ctx->Driver.LinkProgram()
- */
-static void
-_mesa_link_program(GLcontext *ctx, GLuint program)
-{
-   struct gl_shader_program *shProg;
-   struct gl_transform_feedback_object *obj =
-      ctx->TransformFeedback.CurrentObject;
-
-   shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram");
-   if (!shProg)
-      return;
-
-   if (obj->Active && shProg == ctx->Shader.CurrentProgram) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glLinkProgram(transform feedback active");
-      return;
-   }
-
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM);
-
-   _mesa_glsl_link_shader(ctx, shProg);
-
-   /* debug code */
-   if (0) {
-      GLuint i;
-
-      printf("Link %u shaders in program %u: %s\n",
-                   shProg->NumShaders, shProg->Name,
-                   shProg->LinkStatus ? "Success" : "Failed");
-
-      for (i = 0; i < shProg->NumShaders; i++) {
-         printf(" shader %u, type 0x%x\n",
-                      shProg->Shaders[i]->Name,
-                      shProg->Shaders[i]->Type);
-      }
-   }
-}
-
-
-/**
- * Print basic shader info (for debug).
- */
-static void
-print_shader_info(const struct gl_shader_program *shProg)
-{
-   GLuint i;
-
-   printf("Mesa: glUseProgram(%u)\n", shProg->Name);
-   for (i = 0; i < shProg->NumShaders; i++) {
-      const char *s;
-      switch (shProg->Shaders[i]->Type) {
-      case GL_VERTEX_SHADER:
-         s = "vertex";
-         break;
-      case GL_FRAGMENT_SHADER:
-         s = "fragment";
-         break;
-      case GL_GEOMETRY_SHADER:
-         s = "geometry";
-         break;
-      default:
-         s = "";
-      }
-      printf("  %s shader %u, checksum %u\n", s, 
-            shProg->Shaders[i]->Name,
-            shProg->Shaders[i]->SourceChecksum);
-   }
-   if (shProg->VertexProgram)
-      printf("  vert prog %u\n", shProg->VertexProgram->Base.Id);
-   if (shProg->FragmentProgram)
-      printf("  frag prog %u\n", shProg->FragmentProgram->Base.Id);
-}
-
-
-/**
- * Called via ctx->Driver.UseProgram()
- */
-void
-_mesa_use_program(GLcontext *ctx, GLuint program)
-{
-   struct gl_shader_program *shProg;
-   struct gl_transform_feedback_object *obj =
-      ctx->TransformFeedback.CurrentObject;
-
-   if (obj->Active) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glUseProgram(transform feedback active)");
-      return;
-   }
-
-   if (ctx->Shader.CurrentProgram &&
-       ctx->Shader.CurrentProgram->Name == program) {
-      /* no-op */
-      return;
-   }
-
-   if (program) {
-      shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram");
-      if (!shProg) {
-         return;
-      }
-      if (!shProg->LinkStatus) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glUseProgram(program %u not linked)", program);
-         return;
-      }
-
-      /* debug code */
-      if (ctx->Shader.Flags & GLSL_USE_PROG) {
-         print_shader_info(shProg);
-      }
-   }
-   else {
-      shProg = NULL;
-   }
-
-   if (ctx->Shader.CurrentProgram != shProg) {
-      FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
-      _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, shProg);
-   }
-}
-
-
-
-/**
- * Update the vertex/fragment program's TexturesUsed array.
- *
- * This needs to be called after glUniform(set sampler var) is called.
- * A call to glUniform(samplerVar, value) causes a sampler to point to a
- * particular texture unit.  We know the sampler's texture target
- * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
- * set by glUniform() calls.
- *
- * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
- * information to update the prog->TexturesUsed[] values.
- * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
- * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
- * We'll use that info for state validation before rendering.
- */
-void
-_mesa_update_shader_textures_used(struct gl_program *prog)
-{
-   GLuint s;
-
-   memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
-
-   for (s = 0; s < MAX_SAMPLERS; s++) {
-      if (prog->SamplersUsed & (1 << s)) {
-         GLuint unit = prog->SamplerUnits[s];
-         GLuint tgt = prog->SamplerTargets[s];
-         assert(unit < MAX_TEXTURE_IMAGE_UNITS);
-         assert(tgt < NUM_TEXTURE_TARGETS);
-         prog->TexturesUsed[unit] |= (1 << tgt);
-      }
-   }
-}
-
-
-/**
- * Validate a program's samplers.
- * Specifically, check that there aren't two samplers of different types
- * pointing to the same texture unit.
- * \return GL_TRUE if valid, GL_FALSE if invalid
- */
-static GLboolean
-validate_samplers(GLcontext *ctx, const struct gl_program *prog, char *errMsg)
-{
-   static const char *targetName[] = {
-      "TEXTURE_2D_ARRAY",
-      "TEXTURE_1D_ARRAY",
-      "TEXTURE_CUBE",
-      "TEXTURE_3D",
-      "TEXTURE_RECT",
-      "TEXTURE_2D",
-      "TEXTURE_1D",
-   };
-   GLint targetUsed[MAX_TEXTURE_IMAGE_UNITS];
-   GLbitfield samplersUsed = prog->SamplersUsed;
-   GLuint i;
-
-   assert(Elements(targetName) == NUM_TEXTURE_TARGETS);
-
-   if (samplersUsed == 0x0)
-      return GL_TRUE;
-
-   for (i = 0; i < Elements(targetUsed); i++)
-      targetUsed[i] = -1;
-
-   /* walk over bits which are set in 'samplers' */
-   while (samplersUsed) {
-      GLuint unit;
-      gl_texture_index target;
-      GLint sampler = _mesa_ffs(samplersUsed) - 1;
-      assert(sampler >= 0);
-      assert(sampler < MAX_TEXTURE_IMAGE_UNITS);
-      unit = prog->SamplerUnits[sampler];
-      target = prog->SamplerTargets[sampler];
-      if (targetUsed[unit] != -1 && targetUsed[unit] != target) {
-         _mesa_snprintf(errMsg, 100,
-                 "Texture unit %d is accessed both as %s and %s",
-                 unit, targetName[targetUsed[unit]], targetName[target]);
-         return GL_FALSE;
-      }
-      targetUsed[unit] = target;
-      samplersUsed ^= (1 << sampler);
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Do validation of the given shader program.
- * \param errMsg  returns error message if validation fails.
- * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
- */
-GLboolean
-_mesa_validate_shader_program(GLcontext *ctx,
-                              const struct gl_shader_program *shProg,
-                              char *errMsg)
-{
-   const struct gl_vertex_program *vp = shProg->VertexProgram;
-   const struct gl_fragment_program *fp = shProg->FragmentProgram;
-
-   if (!shProg->LinkStatus) {
-      return GL_FALSE;
-   }
-
-   /* From the GL spec, a program is invalid if any of these are true:
-
-     any two active samplers in the current program object are of
-     different types, but refer to the same texture image unit,
-
-     any active sampler in the current program object refers to a texture
-     image unit where fixed-function fragment processing accesses a
-     texture target that does not match the sampler type, or 
-
-     the sum of the number of active samplers in the program and the
-     number of texture image units enabled for fixed-function fragment
-     processing exceeds the combined limit on the total number of texture
-     image units allowed.
-   */
-
-
-   /*
-    * Check: any two active samplers in the current program object are of
-    * different types, but refer to the same texture image unit,
-    */
-   if (vp && !validate_samplers(ctx, &vp->Base, errMsg)) {
-      return GL_FALSE;
-   }
-   if (fp && !validate_samplers(ctx, &fp->Base, errMsg)) {
-      return GL_FALSE;
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Called via glValidateProgram()
- */
-static void
-_mesa_validate_program(GLcontext *ctx, GLuint program)
-{
-   struct gl_shader_program *shProg;
-   char errMsg[100];
-
-   shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
-   if (!shProg) {
-      return;
-   }
-
-   shProg->Validated = _mesa_validate_shader_program(ctx, shProg, errMsg);
-   if (!shProg->Validated) {
-      /* update info log */
-      if (shProg->InfoLog) {
-         talloc_free(shProg->InfoLog);
-      }
-      shProg->InfoLog = talloc_strdup(shProg, errMsg);
-   }
-}
-
-
-/**
- * Plug in Mesa's GLSL functions into the device driver function table.
- */
-void
-_mesa_init_glsl_driver_functions(struct dd_function_table *driver)
-{
-   driver->AttachShader = _mesa_attach_shader;
-   driver->BindAttribLocation = _mesa_bind_attrib_location;
-   driver->CompileShader = _mesa_compile_shader;
-   driver->CreateProgram = _mesa_create_program;
-   driver->CreateShader = _mesa_create_shader;
-   driver->DeleteProgram2 = _mesa_delete_program2;
-   driver->DeleteShader = _mesa_delete_shader;
-   driver->DetachShader = _mesa_detach_shader;
-   driver->GetActiveAttrib = _mesa_get_active_attrib;
-   driver->GetAttachedShaders = _mesa_get_attached_shaders;
-   driver->GetAttribLocation = _mesa_get_attrib_location;
-   driver->GetHandle = _mesa_get_handle;
-   driver->GetProgramiv = _mesa_get_programiv;
-   driver->GetProgramInfoLog = _mesa_get_program_info_log;
-   driver->GetShaderiv = _mesa_get_shaderiv;
-   driver->GetShaderInfoLog = _mesa_get_shader_info_log;
-   driver->GetShaderSource = _mesa_get_shader_source;
-   driver->IsProgram = _mesa_is_program;
-   driver->IsShader = _mesa_is_shader;
-   driver->LinkProgram = _mesa_link_program;
-   driver->ShaderSource = _mesa_shader_source;
-   driver->UseProgram = _mesa_use_program;
-   driver->ValidateProgram = _mesa_validate_program;
-
-   _mesa_init_uniform_functions(driver);
-}
diff --git a/src/mesa/shader/shader_api.h b/src/mesa/shader/shader_api.h
deleted file mode 100644 (file)
index 22f582a..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.6
- *
- * Copyright (C) 2004-2006  Brian Paul   All Rights Reserved.
- * Copyright (C) 2009  VMware, 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
- * 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 SHADER_API_H
-#define SHADER_API_H
-
-
-#include "main/glheader.h"
-#include "main/mtypes.h"
-#include "ir_to_mesa.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-/**
- * Internal functions
- */
-
-extern void
-_mesa_init_shader_state(GLcontext * ctx);
-
-extern void
-_mesa_free_shader_state(GLcontext *ctx);
-
-
-extern void
-_mesa_copy_string(GLchar *dst, GLsizei maxLength,
-                  GLsizei *length, const GLchar *src);
-
-extern GLint
-_mesa_sizeof_glsl_type(GLenum type);
-
-
-/*
-extern struct gl_shader_program *
-_mesa_new_shader_program(GLcontext *ctx, GLuint name);
-*/
-extern void
-_mesa_clear_shader_program_data(GLcontext *ctx,
-                                struct gl_shader_program *shProg);
-
-extern void
-_mesa_free_shader_program_data(GLcontext *ctx,
-                               struct gl_shader_program *shProg);
-
-extern void
-_mesa_free_shader_program(GLcontext *ctx, struct gl_shader_program *shProg);
-
-extern void
-_mesa_reference_shader_program(GLcontext *ctx,
-                               struct gl_shader_program **ptr,
-                               struct gl_shader_program *shProg);
-
-extern struct gl_shader_program *
-_mesa_lookup_shader_program(GLcontext *ctx, GLuint name);
-
-
-extern struct gl_shader_program *
-_mesa_lookup_shader_program_err(GLcontext *ctx, GLuint name,
-                                const char *caller);
-
-extern struct gl_shader *
-_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type);
-
-extern void
-_mesa_free_shader(GLcontext *ctx, struct gl_shader *sh);
-
-extern void
-_mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr,
-                       struct gl_shader *sh);
-
-extern struct gl_shader *
-_mesa_lookup_shader(GLcontext *ctx, GLuint name);
-
-
-extern void
-_mesa_update_shader_textures_used(struct gl_program *prog);
-
-
-extern void
-_mesa_use_program(GLcontext *ctx, GLuint program);
-
-
-extern GLboolean
-_mesa_validate_shader_program(GLcontext *ctx,
-                              const struct gl_shader_program *shProg,
-                              char *errMsg);
-
-extern void
-_mesa_init_glsl_driver_functions(struct dd_function_table *driver);
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif /* SHADER_API_H */
diff --git a/src/mesa/shader/slang/descrip.mms b/src/mesa/shader/slang/descrip.mms
deleted file mode 100644 (file)
index 674b786..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-# Makefile for core library for VMS
-# contributed by Jouk Jansen  joukj@hrem.nano.tudelft.nl
-# Last revision : 3 October 2007
-
-.first
-       define gl [----.include.gl]
-       define math [--.math]
-       define swrast [--.swrast]
-       define array_cache [--.array_cache]
-       define main [--.main]
-       define glapi [--.glapi]
-       define shader [--.shader]
-
-.include [----]mms-config.
-
-##### MACROS #####
-
-VPATH = RCS
-
-INCDIR = [----.include],[--.main],[--.glapi],[-.slang],[-]
-LIBDIR = [----.lib]
-CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short)/float=ieee/ieee=denorm
-
-SOURCES = \
-       slang_compile.c
-
-OBJECTS = slang_builtin.obj,slang_codegen.obj,slang_compile.obj,\
-       slang_compile_function.obj,slang_compile_operation.obj,\
-       slang_compile_struct.obj,slang_compile_variable.obj,slang_emit.obj,\
-       slang_ir.obj,slang_label.obj,slang_library_noise.obj,slang_link.obj,\
-       slang_log.obj,slang_mem.obj,slang_preprocess.obj,slang_print.obj,\
-       slang_simplify.obj,slang_storage.obj,slang_typeinfo.obj,\
-       slang_utility.obj,slang_vartable.obj
-
-##### RULES #####
-
-VERSION=Mesa V3.4
-
-##### TARGETS #####
-# Make the library
-$(LIBDIR)$(GL_LIB) : $(OBJECTS)
-  @ library $(LIBDIR)$(GL_LIB) $(OBJECTS)
-
-clean :
-       purge
-       delete *.obj;*
-
-slang_builtin.obj : slang_builtin.c
-slang_codegen.obj : slang_codegen.c
-slang_compile.obj : slang_compile.c
-slang_compile_function.obj : slang_compile_function.c
-slang_compile_operation.obj : slang_compile_operation.c
-slang_compile_struct.obj : slang_compile_struct.c
-slang_compile_variable.obj : slang_compile_variable.c
-slang_emit.obj : slang_emit.c
-slang_ir.obj : slang_ir.c
-slang_label.obj : slang_label.c
-slang_library_noise.obj : slang_library_noise.c
-slang_link.obj : slang_link.c
-slang_log.obj : slang_log.c
-slang_mem.obj : slang_mem.c
-slang_print.obj : slang_print.c
-slang_simplify.obj : slang_simplify.c
-slang_storage.obj : slang_storage.c
-slang_typeinfo.obj : slang_typeinfo.c
-slang_utility.obj : slang_utility.c
-slang_vartable.obj : slang_vartable.c
diff --git a/src/mesa/shader/slang/library/.gitignore b/src/mesa/shader/slang/library/.gitignore
deleted file mode 100644 (file)
index 02a89fc..0000000
+++ /dev/null
@@ -1 +0,0 @@
-*_gc.h
diff --git a/src/mesa/shader/slang/library/Makefile b/src/mesa/shader/slang/library/Makefile
deleted file mode 100644 (file)
index c696451..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-# src/mesa/shader/slang/library/Makefile
-
-TOP = ../../../../..
-
-include $(TOP)/configs/current
-
-GLSL_CL = $(TOP)/src/glsl/apps/compile
-
-#
-# targets
-#
-
-.PHONY: default clean
-
-default: builtin
-
-clean:
-       -rm -f *_gc.h
-
-builtin: builtin_110 builtin_120
-
-#
-# builtin library sources
-#
-
-builtin_110: slang_common_builtin_gc.h slang_core_gc.h slang_fragment_builtin_gc.h slang_vertex_builtin_gc.h
-
-builtin_120: slang_120_core_gc.h slang_builtin_120_common_gc.h slang_builtin_120_fragment_gc.h
-
-
-slang_120_core_gc.h: slang_120_core.gc
-       $(GLSL_CL) fragment slang_120_core.gc slang_120_core_gc.h
-
-slang_builtin_120_common_gc.h: slang_builtin_120_common.gc
-       $(GLSL_CL) fragment slang_builtin_120_common.gc slang_builtin_120_common_gc.h
-
-slang_builtin_120_fragment_gc.h: slang_builtin_120_fragment.gc
-       $(GLSL_CL) fragment slang_builtin_120_fragment.gc slang_builtin_120_fragment_gc.h
-
-slang_common_builtin_gc.h: slang_common_builtin.gc
-       $(GLSL_CL) fragment slang_common_builtin.gc slang_common_builtin_gc.h
-
-slang_core_gc.h: slang_core.gc
-       $(GLSL_CL) fragment slang_core.gc slang_core_gc.h
-
-slang_fragment_builtin_gc.h: slang_fragment_builtin.gc
-       $(GLSL_CL) fragment slang_fragment_builtin.gc slang_fragment_builtin_gc.h
-
-slang_vertex_builtin_gc.h: slang_vertex_builtin.gc
-       $(GLSL_CL) vertex slang_vertex_builtin.gc slang_vertex_builtin_gc.h
-
diff --git a/src/mesa/shader/slang/library/SConscript b/src/mesa/shader/slang/library/SConscript
deleted file mode 100644 (file)
index 0b25467..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#######################################################################
-# SConscript for GLSL builtin library
-
-Import('*')
-
-env = env.Clone()
-
-# See also http://www.scons.org/wiki/UsingCodeGenerators
-
-def glsl_compile_emitter(target, source, env):
-       env.Depends(target, glsl_compile)
-       return (target, source)
-bld_frag = Builder(
-       action = Action(glsl_compile[0].abspath + ' fragment $SOURCE $TARGET', '$CODEGENCODESTR'),
-       emitter = glsl_compile_emitter,
-       suffix = '.gc',
-       src_suffix = '_gc.h')
-       
-bld_vert = Builder(
-       action = Action(glsl_compile[0].abspath + ' vertex $SOURCE $TARGET', '$CODEGENCODESTR'),
-       emitter = glsl_compile_emitter,
-       suffix = '.gc',
-       src_suffix = '_gc.h')
-
-env['BUILDERS']['bld_frag'] = bld_frag
-env['BUILDERS']['bld_vert'] = bld_vert
-
-# Generate GLSL builtin library binaries
-env.bld_frag(
-       '#src/mesa/shader/slang/library/slang_core_gc.h',
-       '#src/mesa/shader/slang/library/slang_core.gc')
-env.bld_frag(
-       '#src/mesa/shader/slang/library/slang_common_builtin_gc.h',
-       '#src/mesa/shader/slang/library/slang_common_builtin.gc')
-env.bld_frag(
-       '#src/mesa/shader/slang/library/slang_fragment_builtin_gc.h',
-       '#src/mesa/shader/slang/library/slang_fragment_builtin.gc')
-env.bld_vert(
-       '#src/mesa/shader/slang/library/slang_vertex_builtin_gc.h',
-       '#src/mesa/shader/slang/library/slang_vertex_builtin.gc')
-
-# Generate GLSL 1.20 builtin library binaries
-env.bld_frag(
-       '#src/mesa/shader/slang/library/slang_120_core_gc.h',
-       '#src/mesa/shader/slang/library/slang_120_core.gc')
-env.bld_frag(
-       '#src/mesa/shader/slang/library/slang_builtin_120_common_gc.h',
-       '#src/mesa/shader/slang/library/slang_builtin_120_common.gc')
-env.bld_frag(
-       '#src/mesa/shader/slang/library/slang_builtin_120_fragment_gc.h',
-       '#src/mesa/shader/slang/library/slang_builtin_120_fragment.gc')
diff --git a/src/mesa/shader/slang/library/slang_120_core.gc b/src/mesa/shader/slang/library/slang_120_core.gc
deleted file mode 100644 (file)
index 04c5ec2..0000000
+++ /dev/null
@@ -1,1978 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5
- *
- * Copyright (C) 2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-//
-// Constructors and operators introduced in GLSL 1.20 - mostly on new
-// (non-square) types of matrices.
-//
-// One important change in the language is that when a matrix is used
-// as an argument to a matrix constructor, it must be the only argument
-// for the constructor. The compiler takes care of it by itself and
-// here we only care to re-introduce constructors for old (square)
-// types of matrices.
-//
-
-//
-// From Shader Spec, ver. 1.20, rev. 6
-//
-
-//// mat2x3: 2 columns of vec3
-
-mat2x3 __constructor(const float f00, const float f10, const float f20,
-                     const float f01, const float f11, const float f21)
-{
-   __retVal[0].x = f00;
-   __retVal[0].y = f10;
-   __retVal[0].z = f20;
-   __retVal[1].x = f01;
-   __retVal[1].y = f11;
-   __retVal[1].z = f21;
-}
-
-mat2x3 __constructor(const float f)
-{
-   __retVal = mat2x3(  f, 0.0, 0.0,
-                     0.0,   f, 0.0);
-}
-
-mat2x3 __constructor(const int  i)
-{
-   const float f = float(i);
-   __retVal = mat2x3(f);
-}
-
-mat2x3 __constructor(const bool b)
-{
-   const float f = float(b);
-   __retVal = mat2x3(f);
-}
-
-mat2x3 __constructor(const vec3 c0, const vec3 c1)
-{
-   __retVal[0] = c0;
-   __retVal[1] = c1;
-}
-
-
-
-//// mat2x4: 2 columns of vec4
-
-mat2x4 __constructor(const float f00, const float f10, const float f20, const float f30,
-                     const float f01, const float f11, const float f21, const float f31)
-{
-   __retVal[0].x = f00;
-   __retVal[0].y = f10;
-   __retVal[0].z = f20;
-   __retVal[0].w = f30;
-   __retVal[1].x = f01;
-   __retVal[1].y = f11;
-   __retVal[1].z = f21;
-   __retVal[1].w = f31;
-}
-
-mat2x4 __constructor(const float f)
-{
-   __retVal = mat2x4(  f, 0.0, 0.0, 0.0,
-                     0.0,   f, 0.0, 0.0);
-}
-
-mat2x4 __constructor(const int i)
-{
-   const float f = float(i);
-   __retVal = mat2x4(f);
-}
-
-mat2x4 __constructor(const bool b)
-{
-   const float f = float(b);
-   __retVal = mat2x4(f);
-}
-
-mat2x4 __constructor(const vec4 c0, const vec4 c1)
-{
-   __retVal[0] = c0;
-   __retVal[1] = c1;
-}
-
-
-
-//// mat3x2: 3 columns of vec2
-
-mat3x2 __constructor(const float f00, const float f10,
-                     const float f01, const float f11,
-                     const float f02, const float f12)
-{
-   __retVal[0].x = f00;
-   __retVal[0].y = f10;
-   __retVal[1].x = f01;
-   __retVal[1].y = f11;
-   __retVal[2].x = f02;
-   __retVal[2].y = f12;
-}
-
-mat3x2 __constructor(const float f)
-{
-   __retVal = mat3x2(  f, 0.0,
-                     0.0,   f,
-                     0.0, 0.0);
-}
-
-mat3x2 __constructor(const int i)
-{
-   const float f = float(i);
-   __retVal = mat3x2(f);
-}
-
-mat3x2 __constructor(const bool b)
-{
-   const float f = float(b);
-   __retVal = mat3x2(f);
-}
-
-mat3x2 __constructor(const vec2 c0, const vec2 c1, const vec2 c2)
-{
-   __retVal[0] = c0;
-   __retVal[1] = c1;
-   __retVal[2] = c2;
-}
-
-
-
-//// mat3x4: 3 columns of vec4
-
-mat3x4 __constructor(const float f00, const float f10, const float f20, const float f30,
-                     const float f01, const float f11, const float f21, const float f31,
-                    const float f02, const float f12, const float f22, const float f32)
-{
-   __retVal[0].x = f00;
-   __retVal[0].y = f10;
-   __retVal[0].z = f20;
-   __retVal[0].w = f30;
-   __retVal[1].x = f01;
-   __retVal[1].y = f11;
-   __retVal[1].z = f21;
-   __retVal[1].w = f31;
-   __retVal[2].x = f02;
-   __retVal[2].y = f12;
-   __retVal[2].z = f22;
-   __retVal[2].w = f32;
-}
-
-mat3x4 __constructor(const float f)
-{
-   __retVal = mat3x4(  f, 0.0, 0.0, 0.0,
-                     0.0,   f, 0.0, 0.0,
-                     0.0, 0.0,   f, 0.0);
-}
-
-mat3x4 __constructor(const int i)
-{
-   const float f = float(i);
-   __retVal = mat3x4(f);
-}
-
-mat3x4 __constructor(const bool b)
-{
-   const float f = float(b);
-   __retVal = mat3x4(f);
-}
-
-mat3x4 __constructor(const vec4 c0, const vec4 c1, const vec4 c2)
-{
-   __retVal[0] = c0;
-   __retVal[1] = c1;
-   __retVal[2] = c2;
-}
-
-
-
-//// mat4x2: 4 columns of vec2
-
-mat4x2 __constructor(const float f00, const float f10,
-                     const float f01, const float f11,
-                    const float f02, const float f12,
-                    const float f03, const float f13)
-{
-   __retVal[0].x = f00;
-   __retVal[0].y = f10;
-   __retVal[1].x = f01;
-   __retVal[1].y = f11;
-   __retVal[2].x = f02;
-   __retVal[2].y = f12;
-   __retVal[3].x = f03;
-   __retVal[3].y = f13;
-}
-
-mat4x2 __constructor(const float f)
-{
-   __retVal = mat4x2(  f, 0.0,
-                     0.0,   4,
-                     0.0, 0.0,
-                     0.0, 0.0);
-}
-
-mat4x2 __constructor(const int i)
-{
-   const float f = float(i);
-   __retVal = mat4x2(f);
-}
-
-mat4x2 __constructor(const bool b)
-{
-   const float f = float(b);
-   __retVal = mat4x2(f);
-}
-
-mat4x2 __constructor(const vec2 c0, const vec2 c1, const vec2 c2, const vec2 c3)
-{
-   __retVal[0] = c0;
-   __retVal[1] = c1;
-   __retVal[2] = c2;
-   __retVal[3] = c3;
-}
-
-
-
-//// mat4x3: 4 columns of vec3
-
-mat4x3 __constructor(const float f00, const float f10, const float f20,
-                     const float f01, const float f11, const float f21,
-                    const float f02, const float f12, const float f22,
-                    const float f03, const float f13, const float f23)
-{
-   __retVal[0].x = f00;
-   __retVal[0].y = f10;
-   __retVal[0].z = f20;
-   __retVal[1].x = f01;
-   __retVal[1].y = f11;
-   __retVal[1].z = f21;
-   __retVal[2].x = f02;
-   __retVal[2].y = f12;
-   __retVal[2].z = f22;
-   __retVal[3].x = f03;
-   __retVal[3].y = f13;
-   __retVal[3].z = f23;
-}
-
-mat4x3 __constructor(const float f)
-{
-   __retVal = mat4x3(  f, 0.0, 0.0,
-                     0.0,   f, 0.0,
-                     0.0, 0.0,   f,
-                     0.0, 0.0, 0.0);
-}
-
-mat4x3 __constructor(const int i)
-{
-   const float f = float(i);
-   __retVal = mat4x3(f);
-}
-
-mat4x3 __constructor(const bool b)
-{
-   const float f = float(b);
-   __retVal = mat4x3(f);
-}
-
-mat4x3 __constructor(const vec3 c0, const vec3 c1, const vec3 c2, const vec3 c3)
-{
-   __retVal[0] = c0;
-   __retVal[1] = c1;
-   __retVal[2] = c2;
-   __retVal[3] = c3;
-}
-
-
-
-//// misc assorted matrix constructors
-
-mat2 __constructor(const mat2 m)
-{
-   __retVal = m;
-}
-
-mat2 __constructor(const mat3x2 m)
-{
-   __retVal = mat2(m[0], m[1]);
-}
-
-mat2 __constructor(const mat4x2 m)
-{
-   __retVal = mat2(m[0], m[1]);
-}
-
-mat2 __constructor(const mat2x3 m)
-{
-   __retVal = mat2(m[0].xy, m[1].xy);
-}
-
-mat2 __constructor(const mat2x4 m)
-{
-   __retVal = mat2(m[0].xy, m[1].xy);
-}
-
-mat2 __constructor(const mat3 m)
-{
-   __retVal = mat2(m[0].xy, m[1].xy);
-}
-
-mat2 __constructor(const mat3x4 m)
-{
-   __retVal = mat2(m[0].xy, m[1].xy);
-}
-
-mat2 __constructor(const mat4x3 m)
-{
-   __retVal = mat2(m[0].xy, m[1].xy);
-}
-
-mat2 __constructor(const mat4 m)
-{
-   __retVal = mat2(m[0].xy, m[1].xy);
-}
-
-
-
-mat2x3 __constructor(const mat2x3 m)
-{
-   __retVal = m;
-}
-
-mat2x3 __constructor(const mat3 m)
-{
-   __retVal = mat2x3(m[0], m[1]);
-}
-
-mat2x3 __constructor(const mat4x3 m)
-{
-   __retVal = mat2x3(m[0], m[1]);
-}
-
-mat2x3 __constructor(const mat2x4 m)
-{
-   __retVal = mat2x3(m[0].xyz, m[1].xyz);
-}
-
-mat2x3 __constructor(const mat3x4 m)
-{
-   __retVal = mat2x3(m[0].xyz, m[1].xyz);
-}
-
-mat2x3 __constructor(const mat4 m)
-{
-   __retVal = mat2x3(m[0].xyz, m[1].xyz);
-}
-
-mat2x3 __constructor(const mat2 m)
-{
-   __retVal = mat2x3(m[0].x, m[0].y, 0.0,
-                     m[1].x, m[1].y, 0.0);
-}
-
-mat2x3 __constructor(const mat3x2 m)
-{
-   __retVal = mat2x3(m[0].x, m[0].y, 0.0,
-                     m[1].x, m[1].y, 0.0);
-}
-
-mat2x3 __constructor(const mat4x2 m)
-{
-   __retVal = mat2x3(m[0].x, m[0].y, 0.0,
-                     m[1].x, m[1].y, 0.0);
-}
-
-
-
-mat2x4 __constructor(const mat2x4 m)
-{
-   __retVal = m;
-}
-
-mat2x4 __constructor(const mat3x4 m)
-{
-   __retVal = mat2x4(m[0], m[1]);
-}
-
-mat2x4 __constructor(const mat4 m)
-{
-   __retVal = mat2x4(m[0], m[1]);
-}
-
-mat2x4 __constructor(const mat2x3 m)
-{
-   __retVal = mat2x4(m[0].x, m[0].y, m[0].z, 0.0,
-                     m[1].x, m[1].y, m[1].z, 0.0);
-}
-
-mat2x4 __constructor(const mat3 m)
-{
-   __retVal = mat2x4(m[0].x, m[0].y, m[0].z, 0.0,
-                     m[1].x, m[1].y, m[1].z, 0.0);
-}
-
-mat2x4 __constructor(const mat4x3 m)
-{
-   __retVal = mat2x4(m[0].x, m[0].y, m[0].z, 0.0,
-                     m[1].x, m[1].y, m[1].z, 0.0);
-}
-
-mat2x4 __constructor(const mat2 m)
-{
-   __retVal = mat2x4(m[0].x, m[1].y, 0.0, 0.0,
-                     m[1].x, m[1].y, 0.0, 0.0);
-}
-
-mat2x4 __constructor(const mat3x2 m)
-{
-   __retVal = mat2x4(m[0].x, m[0].y, 0.0, 0.0,
-                     m[1].x, m[1].y, 0.0, 0.0);
-}
-
-mat2x4 __constructor(const mat4x2 m)
-{
-   __retVal = mat2x4(m[0].x, m[0].y, 0.0, 0.0,
-                     m[1].x, m[1].y, 0.0, 0.0);
-}
-
-
-
-mat3x2 __constructor(const mat3x2 m)
-{
-   __retVal = m;
-}
-
-mat3x2 __constructor(const mat4x2 m)
-{
-   __retVal = mat3x2(m[0], m[1], m[2]);
-}
-
-mat3x2 __constructor(const mat3 m)
-{
-   __retVal = mat3x2(m[0], m[1], m[2]);
-}
-
-mat3x2 __constructor(const mat3x4 m)
-{
-   __retVal = mat3x2(m[0].x, m[0].y,
-                     m[1].x, m[1].y,
-                     m[2].x, m[2].y);
-}
-
-mat3x2 __constructor(const mat4x3 m)
-{
-   __retVal = mat3x2(m[0].x, m[0].y,
-                     m[1].x, m[1].y,
-                     m[2].x, m[2].y);
-}
-
-mat3x2 __constructor(const mat4 m)
-{
-   __retVal = mat3x2(m[0].x, m[0].y,
-                     m[1].x, m[1].y,
-                        0.0,    0.0);
-}
-
-mat3x2 __constructor(const mat2 m)
-{
-   __retVal = mat3x2(m[0], m[1], vec2(0.0));
-}
-
-mat3x2 __constructor(const mat2x3 m)
-{
-   __retVal = mat3x2(m[0].x, m[0].y,
-                     m[1].x, m[1].y,
-                        0.0,    0.0);
-}
-
-mat3x2 __constructor(const mat2x4 m)
-{
-   __retVal = mat3x2(m[0].x, m[0].y,
-                     m[1].x, m[1].y,
-                        0.0,    0.0);
-}
-
-
-
-
-mat3 __constructor(const mat3 m)
-{
-   __retVal = m;
-}
-
-mat3 __constructor(const mat4x3 m)
-{
-   __retVal = mat3 (
-        m[0],
-        m[1],
-        m[2]
-    );
-}
-
-mat3 __constructor(const mat3x4 m)
-{
-   __retVal = mat3 (
-        m[0].xyz,
-        m[1].xyz,
-        m[2].xyz
-    );
-}
-
-mat3 __constructor(const mat4 m)
-{
-   __retVal = mat3 (
-        m[0].xyz,
-        m[1].xyz,
-        m[2].xyz
-    );
-}
-
-mat3 __constructor(const mat2x3 m)
-{
-   __retVal = mat3 (
-        m[0],
-        m[1],
-        0., 0., 1.
-    );
-}
-
-mat3 __constructor(const mat2x4 m)
-{
-   __retVal = mat3 (
-        m[0].xyz,
-        m[1].xyz,
-        0., 0., 1.
-    );
-}
-
-mat3 __constructor(const mat3x2 m)
-{
-   __retVal = mat3 (
-        m[0], 0.,
-        m[1], 0.,
-        m[2], 1.
-    );
-}
-
-mat3 __constructor(const mat4x2 m)
-{
-   __retVal = mat3 (
-        m[0], 0.,
-        m[1], 0.,
-        m[2], 1.
-    );
-}
-
-mat3 __constructor(const mat2 m)
-{
-   __retVal = mat3 (
-        m[0], 0.,
-        m[1], 0.,
-        0., 0., 1.
-    );
-}
-
-
-mat3x4 __constructor(const mat3x4 m)
-{
-   __retVal = m;
-}
-
-mat3x4 __constructor(const mat4 m)
-{
-   __retVal = mat3x4 (
-        m[0],
-        m[1],
-        m[2]
-    );
-}
-
-mat3x4 __constructor(const mat3 m)
-{
-   __retVal = mat3x4 (
-        m[0], 0.,
-        m[1], 0.,
-        m[2], 0.
-    );
-}
-
-mat3x4 __constructor(const mat4x3 m)
-{
-   __retVal = mat3x4 (
-        m[0], 0.,
-        m[1], 0.,
-        m[2], 0.
-    );
-}
-
-mat3x4 __constructor(const mat2x4 m)
-{
-   __retVal = mat3x4 (
-        m[0],
-        m[1],
-        0., 0., 1., 0.
-    );
-}
-
-mat3x4 __constructor(const mat2x3 m)
-{
-   __retVal = mat3x4 (
-        m[0], 0.,
-        m[1], 0.,
-        0., 0., 1., 0.
-    );
-}
-
-mat3x4 __constructor(const mat3x2 m)
-{
-   __retVal = mat3x4 (
-        m[0], 0., 0.,
-        m[1], 0., 0.,
-        m[2], 1., 0.
-    );
-}
-
-mat3x4 __constructor(const mat4x2 m)
-{
-   __retVal = mat3x4 (
-        m[0], 0., 0.,
-        m[1], 0., 0.,
-        m[2], 1., 0.
-    );
-}
-
-mat3x4 __constructor(const mat2 m)
-{
-   __retVal = mat3x4 (
-        m[0], 0., 0.,
-        m[1], 0., 0.,
-        0., 0., 1., 0.
-    );
-}
-
-
-mat4x2 __constructor(const mat4x2 m)
-{
-   __retVal = m;
-}
-
-mat4x2 __constructor(const mat4x3 m)
-{
-   __retVal = mat4x2 (
-        m[0].xy,
-        m[1].xy,
-        m[2].xy,
-        m[3].xy
-    );
-}
-
-mat4x2 __constructor(const mat4 m)
-{
-   __retVal = mat4x2 (
-        m[0].xy,
-        m[1].xy,
-        m[2].xy,
-        m[3].xy
-    );
-}
-
-mat4x2 __constructor(const mat3x2 m)
-{
-   __retVal = mat4x2 (
-        m[0],
-        m[1],
-        0., 0.
-    );
-}
-
-mat4x2 __constructor(const mat3 m)
-{
-   __retVal = mat4x2 (
-        m[0].xy,
-        m[1].xy,
-        m[2].xy,
-        0., 0.
-    );
-}
-
-mat4x2 __constructor(const mat3x4 m)
-{
-   __retVal = mat4x2 (
-        m[0].xy,
-        m[1].xy,
-        m[2].xy,
-        0., 0.
-    );
-}
-
-mat4x2 __constructor(const mat2 m)
-{
-   __retVal = mat4x2 (
-        m[0],
-        m[1],
-        0., 0.,
-        0., 0.
-    );
-}
-
-mat4x2 __constructor(const mat2x3 m)
-{
-   __retVal = mat4x2 (
-        m[0].xy,
-        m[1].xy,
-        0., 0.,
-        0., 0.
-    );
-}
-
-mat4x2 __constructor(const mat2x4 m)
-{
-   __retVal = mat4x2 (
-        m[0].xy,
-        m[1].xy,
-        0., 0.,
-        0., 0.
-    );
-}
-
-
-mat4x3 __constructor(const mat4x3 m)
-{
-   __retVal = m;
-}
-
-mat4x3 __constructor(const mat4 m)
-{
-   __retVal = mat4x3 (
-        m[0].xyz,
-        m[1].xyz,
-        m[2].xyz,
-        m[3].xyz
-    );
-}
-
-mat4x3 __constructor(const mat3 m)
-{
-   __retVal = mat4x3 (
-        m[0],
-        m[1],
-        m[2],
-        0., 0., 0.
-    );
-}
-
-mat4x3 __constructor(const mat3x4 m)
-{
-   __retVal = mat4x3 (
-        m[0].xyz,
-        m[1].xyz,
-        m[2].xyz,
-        0., 0., 0.
-    );
-}
-
-mat4x3 __constructor(const mat4x2 m)
-{
-   __retVal = mat4x3 (
-        m[0], 0.,
-        m[1], 0.,
-        m[2], 1.,
-        m[3], 0.
-    );
-}
-
-mat4x3 __constructor(const mat2x3 m)
-{
-   __retVal = mat4x3 (
-        m[0],
-        m[1],
-        0., 0., 1.,
-        0., 0., 0.
-    );
-}
-
-mat4x3 __constructor(const mat3x2 m)
-{
-   __retVal = mat4x3 (
-        m[0], 0.,
-        m[1], 0.,
-        m[2], 1.,
-        0., 0., 0.
-    );
-}
-
-mat4x3 __constructor(const mat2x4 m)
-{
-   __retVal = mat4x3 (
-        m[0].xyz,
-        m[1].xyz,
-        0., 0., 1.,
-        0., 0., 0.
-    );
-}
-
-mat4x3 __constructor(const mat2 m)
-{
-   __retVal = mat4x3 (
-        m[0], 0.,
-        m[1], 0.,
-        0., 0., 1.,
-        0., 0., 0.
-    );
-}
-
-
-mat4 __constructor(const mat4 m)
-{
-   __retVal = m;
-}
-
-mat4 __constructor(const mat3x4 m)
-{
-   __retVal = mat4 (
-        m[0],
-        m[1],
-        m[2],
-        0., 0., 0., 1.
-    );
-}
-
-mat4 __constructor(const mat4x3 m)
-{
-   __retVal = mat4 (
-        m[0], 0.,
-        m[1], 0.,
-        m[2], 0.,
-        m[3], 1.
-    );
-}
-
-mat4 __constructor(const mat2x4 m)
-{
-   __retVal = mat4 (
-        m[0],
-        m[1],
-        0., 0., 1., 0.,
-        0., 0., 0., 1.
-    );
-}
-
-mat4 __constructor(const mat4x2 m)
-{
-   __retVal = mat4 (
-        m[0], 0., 0.,
-        m[1], 0., 0.,
-        m[2], 1., 0.,
-        m[3], 0., 1.
-    );
-}
-
-mat4 __constructor(const mat3 m)
-{
-   __retVal = mat4 (
-        m[0], 0.,
-        m[1], 0.,
-        m[2], 0.,
-        0., 0., 0., 1.
-    );
-}
-
-mat4 __constructor(const mat2x3 m)
-{
-   __retVal = mat4 (
-        m[0], 0.,
-        m[1], 0.,
-        0., 0., 1., 0.,
-        0., 0., 0., 1.
-    );
-}
-
-mat4 __constructor(const mat3x2 m)
-{
-   __retVal = mat4 (
-        m[0], 0., 0.,
-        m[1], 0., 0.,
-        m[2], 1., 0.,
-        0., 0., 0., 1.
-    );
-}
-
-mat4 __constructor(const mat2 m)
-{
-   __retVal = mat4 (
-        m[0], 0., 0.,
-        m[1], 0., 0.,
-        0., 0., 1., 0.,
-        0., 0., 0., 1.
-    );
-}
-
-
-void __operator += (inout mat2x3 m, const mat2x3 n) {
-    m[0] += n[0];
-    m[1] += n[1];
-}
-
-void __operator += (inout mat2x4 m, const mat2x4 n) {
-    m[0] += n[0];
-    m[1] += n[1];
-}
-
-void __operator += (inout mat3x2 m, const mat3x2 n) {
-    m[0] += n[0];
-    m[1] += n[1];
-    m[2] += n[2];
-}
-
-void __operator += (inout mat3x4 m, const mat3x4 n) {
-    m[0] += n[0];
-    m[1] += n[1];
-    m[2] += n[2];
-}
-
-void __operator += (inout mat4x2 m, const mat4x2 n) {
-    m[0] += n[0];
-    m[1] += n[1];
-    m[2] += n[2];
-    m[3] += n[3];
-}
-
-void __operator += (inout mat4x3 m, const mat4x3 n) {
-    m[0] += n[0];
-    m[1] += n[1];
-    m[2] += n[2];
-    m[3] += n[3];
-}
-
-
-void __operator -= (inout mat2x3 m, const mat2x3 n) {
-    m[0] -= n[0];
-    m[1] -= n[1];
-}
-
-void __operator -= (inout mat2x4 m, const mat2x4 n) {
-    m[0] -= n[0];
-    m[1] -= n[1];
-}
-
-void __operator -= (inout mat3x2 m, const mat3x2 n) {
-    m[0] -= n[0];
-    m[1] -= n[1];
-    m[2] -= n[2];
-}
-
-void __operator -= (inout mat3x4 m, const mat3x4 n) {
-    m[0] -= n[0];
-    m[1] -= n[1];
-    m[2] -= n[2];
-}
-
-void __operator -= (inout mat4x2 m, const mat4x2 n) {
-    m[0] -= n[0];
-    m[1] -= n[1];
-    m[2] -= n[2];
-    m[3] -= n[3];
-}
-
-void __operator -= (inout mat4x3 m, const mat4x3 n) {
-    m[0] -= n[0];
-    m[1] -= n[1];
-    m[2] -= n[2];
-    m[3] -= n[3];
-}
-
-
-void __operator /= (inout mat2x3 m, const mat2x3 n) {
-    m[0] /= n[0];
-    m[1] /= n[1];
-}
-
-void __operator /= (inout mat2x4 m, const mat2x4 n) {
-    m[0] /= n[0];
-    m[1] /= n[1];
-}
-
-void __operator /= (inout mat3x2 m, const mat3x2 n) {
-    m[0] /= n[0];
-    m[1] /= n[1];
-    m[2] /= n[2];
-}
-
-void __operator /= (inout mat3x4 m, const mat3x4 n) {
-    m[0] /= n[0];
-    m[1] /= n[1];
-    m[2] /= n[2];
-}
-
-void __operator /= (inout mat4x2 m, const mat4x2 n) {
-    m[0] /= n[0];
-    m[1] /= n[1];
-    m[2] /= n[2];
-    m[3] /= n[3];
-}
-
-void __operator /= (inout mat4x3 m, const mat4x3 n) {
-    m[0] /= n[0];
-    m[1] /= n[1];
-    m[2] /= n[2];
-    m[3] /= n[3];
-}
-
-
-vec3 __operator * (const mat2x3 m, const vec2 v)
-{
-   __retVal.x = v.x * m[0].x + v.y * m[1].x;
-   __retVal.y = v.x * m[0].y + v.y * m[1].y;
-   __retVal.z = v.x * m[0].z + v.y * m[1].z;
-}
-
-vec4 __operator * (const mat2x4 m, const vec2 v)
-{
-   __retVal.x = v.x * m[0].x + v.y * m[1].x;
-   __retVal.y = v.x * m[0].y + v.y * m[1].y;
-   __retVal.z = v.x * m[0].z + v.y * m[1].z;
-   __retVal.w = v.x * m[0].w + v.y * m[1].w;
-}
-
-vec2 __operator * (const mat3x2 m, const vec3 v)
-{
-   __retVal.x = v.x * m[0].x + v.y * m[1].x + v.z * m[2].x;
-   __retVal.y = v.x * m[0].y + v.y * m[1].y + v.z * m[2].y;
-}
-
-vec4 __operator * (const mat3x4 m, const vec3 v)
-{
-   __retVal.x = v.x * m[0].x + v.y * m[1].x + v.z * m[2].x;
-   __retVal.y = v.x * m[0].y + v.y * m[1].y + v.z * m[2].y;
-   __retVal.z = v.x * m[0].z + v.y * m[1].z + v.z * m[2].z;
-   __retVal.w = v.x * m[0].w + v.y * m[1].w + v.z * m[2].w;
-}
-
-vec2 __operator * (const mat4x2 m, const vec4 v)
-{
-   __retVal.x = v.x * m[0].x + v.y * m[1].x + v.z * m[2].x + v.w * m[3].x;
-   __retVal.y = v.x * m[0].y + v.y * m[1].y + v.z * m[2].y + v.w * m[3].y;
-}
-
-vec3 __operator * (const mat4x3 m, const vec4 v)
-{
-   __retVal.x = v.x * m[0].x + v.y * m[1].x + v.z * m[2].x + v.w * m[3].x;
-   __retVal.y = v.x * m[0].y + v.y * m[1].y + v.z * m[2].y + v.w * m[3].y;
-   __retVal.z = v.x * m[0].z + v.y * m[1].z + v.z * m[2].z + v.w * m[3].z;
-}
-
-
-mat3x2 __operator * (const mat2 m, const mat3x2 n)
-{
-   //return mat3x2 (m * n[0], m * n[1], m * n[2]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-   __retVal[2] = m * n[2];
-}
-
-mat4x2 __operator * (const mat2 m, const mat4x2 n)
-{
-   //return mat4x2 (m * n[0], m * n[1], m * n[2], m * n[3]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-   __retVal[2] = m * n[2];
-   __retVal[3] = m * n[3];
-}
-
-
-mat2x3 __operator * (const mat2x3 m, const mat2 n)
-{
-   //return mat2x3 (m * n[0], m * n[1]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-}
-
-mat3 __operator * (const mat2x3 m, const mat3x2 n)
-{
-   //return mat3 (m * n[0], m * n[1], m * n[2]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-   __retVal[2] = m * n[2];
-}
-
-mat4x3 __operator * (const mat2x3 m, const mat4x2 n)
-{
-   //return mat4x3 (m * n[0], m * n[1], m * n[2], m * n[3]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-   __retVal[2] = m * n[2];
-   __retVal[3] = m * n[3];
-}
-
-
-mat2x4 __operator * (const mat2x4 m, const mat2 n)
-{
-   //return mat2x4 (m * n[0], m * n[1]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-}
-
-mat3x4 __operator * (const mat2x4 m, const mat3x2 n)
-{
-   //return mat3x4 (m * n[0], m * n[1], m * n[2]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-   __retVal[2] = m * n[2];
-}
-
-mat4 __operator * (const mat2x4 m, const mat4x2 n)
-{
-   //return mat4 (m * n[0], m * n[1], m * n[2], m * n[3]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-   __retVal[2] = m * n[2];
-   __retVal[3] = m * n[3];
-}
-
-
-mat2 __operator * (const mat3x2 m, const mat2x3 n)
-{
-   //return mat2 (m * n[0], m * n[1]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-}
-
-mat3x2 __operator * (const mat3x2 m, const mat3 n)
-{
-   //return mat3x2 (m * n[0], m * n[1], m * n[2]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-   __retVal[2] = m * n[2];
-}
-
-mat4x2 __operator * (const mat3x2 m, const mat4x3 n)
-{
-   //return mat4x2 (m * n[0], m * n[1], m * n[2], m * n[3]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-   __retVal[2] = m * n[2];
-   __retVal[3] = m * n[3];
-}
-
-
-mat2x3 __operator * (const mat3 m, const mat2x3 n)
-{
-   //return mat2x3 (m * n[0], m * n[1]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-}
-
-mat4x3 __operator * (const mat3 m, const mat4x3 n)
-{
-   //return mat4x3 (m * n[0], m * n[1], m * n[2], m * n[3]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-   __retVal[2] = m * n[2];
-   __retVal[3] = m * n[3];
-}
-
-
-mat2x4 __operator * (const mat3x4 m, const mat2x3 n)
-{
-   //return mat2x4 (m * n[0], m * n[1]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-}
-
-mat3x4 __operator * (const mat3x4 m, const mat3 n)
-{
-   //return mat3x4 (m * n[0], m * n[1], m * n[2]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-   __retVal[2] = m * n[2];
-}
-
-mat4 __operator * (const mat3x4 m, const mat4x3 n)
-{
-   //return mat4 (m * n[0], m * n[1], m * n[2], m * n[3]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-   __retVal[2] = m * n[2];
-   __retVal[3] = m * n[3];
-}
-
-
-mat2 __operator * (const mat4x2 m, const mat2x4 n)
-{
-   //return = mat2 (m * n[0], m * n[1]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-}
-
-mat3x2 __operator * (const mat4x2 m, const mat3x4 n)
-{
-   //return mat3x2 (m * n[0], m * n[1], m * n[2]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-   __retVal[2] = m * n[2];
-}
-
-mat4x2 __operator * (const mat4x2 m, const mat4 n)
-{
-   //return mat4x2 (m * n[0], m * n[1], m * n[2], m * n[3]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-   __retVal[2] = m * n[2];
-   __retVal[3] = m * n[3];
-}
-
-
-mat2x3 __operator * (const mat4x3 m, const mat2x4 n)
-{
-   //return mat2x3 (m * n[0], m * n[1]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-}
-
-mat3 __operator * (const mat4x3 m, const mat3x4 n)
-{
-   //return mat3 (m * n[0], m * n[1], m * n[2]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-   __retVal[2] = m * n[2];
-}
-
-mat4x3 __operator * (const mat4x3 m, const mat4 n)
-{
-   //return mat4x3 (m * n[0], m * n[1], m * n[2], m * n[3]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-   __retVal[2] = m * n[2];
-   __retVal[3] = m * n[3];
-}
-
-
-mat2x4 __operator * (const mat4 m, const mat2x4 n)
-{
-   //return mat2x4 (m * n[0], m * n[1]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-}
-
-mat3x4 __operator * (const mat4 m, const mat3x4 n)
-{
-   //return mat3x4 (m * n[0], m * n[1], m * n[2]);
-   __retVal[0] = m * n[0];
-   __retVal[1] = m * n[1];
-   __retVal[2] = m * n[2];
-}
-
-
-void __operator *= (inout mat2x3 m, const mat2 n) {
-    m = m * n;
-}
-
-void __operator *= (inout mat2x4 m, const mat2 n) {
-    m = m * n;
-}
-
-void __operator *= (inout mat3x2 m, const mat3 n) {
-    m = m * n;
-}
-
-void __operator *= (inout mat3x4 m, const mat3 n) {
-    m = m * n;
-}
-
-void __operator *= (inout mat4x2 m, const mat4 n) {
-    m = m * n;
-}
-
-void __operator *= (inout mat4x3 m, const mat4 n) {
-    m = m * n;
-}
-
-
-vec3 __operator * (const vec2 v, const mat3x2 m)
-{
-   __retVal.x = dot(v, m[0]);
-   __retVal.y = dot(v, m[1]);
-   __retVal.z = dot(v, m[2]);
-}
-
-vec4 __operator * (const vec2 v, const mat4x2 m)
-{
-   __retVal.x = dot(v, m[0]);
-   __retVal.y = dot(v, m[1]);
-   __retVal.z = dot(v, m[2]);
-   __retVal.w = dot(v, m[3]);
-}
-
-vec2 __operator * (const vec3 v, const mat2x3 m)
-{
-   __retVal.x = dot(v, m[0]);
-   __retVal.y = dot(v, m[1]);
-}
-
-vec4 __operator * (const vec3 v, const mat4x3 m)
-{
-   __retVal.x = dot(v, m[0]);
-   __retVal.y = dot(v, m[1]);
-   __retVal.z = dot(v, m[2]);
-   __retVal.w = dot(v, m[3]);
-}
-
-vec2 __operator * (const vec4 v, const mat2x4 m)
-{
-   __retVal.x = dot(v, m[0]);
-   __retVal.y = dot(v, m[1]);
-}
-
-vec3 __operator * (const vec4 v, const mat3x4 m)
-{
-   __retVal.x = dot(v, m[0]);
-   __retVal.y = dot(v, m[1]);
-   __retVal.z = dot(v, m[2]);
-}
-
-
-void __operator += (inout mat2x3 m, const float a) {
-    m[0] += a;
-    m[1] += a;
-}
-
-void __operator += (inout mat2x4 m, const float a) {
-    m[0] += a;
-    m[1] += a;
-}
-
-void __operator += (inout mat3x2 m, const float a) {
-    m[0] += a;
-    m[1] += a;
-    m[2] += a;
-}
-
-void __operator += (inout mat3x4 m, const float a) {
-    m[0] += a;
-    m[1] += a;
-    m[2] += a;
-}
-
-void __operator += (inout mat4x2 m, const float a) {
-    m[0] += a;
-    m[1] += a;
-    m[2] += a;
-    m[3] += a;
-}
-
-void __operator += (inout mat4x3 m, const float a) {
-    m[0] += a;
-    m[1] += a;
-    m[2] += a;
-    m[3] += a;
-}
-
-
-void __operator -= (inout mat2x3 m, const float a) {
-    m[0] -= a;
-    m[1] -= a;
-}
-
-void __operator -= (inout mat2x4 m, const float a) {
-    m[0] -= a;
-    m[1] -= a;
-}
-
-void __operator -= (inout mat3x2 m, const float a) {
-    m[0] -= a;
-    m[1] -= a;
-    m[2] -= a;
-}
-
-void __operator -= (inout mat3x4 m, const float a) {
-    m[0] -= a;
-    m[1] -= a;
-    m[2] -= a;
-}
-
-void __operator -= (inout mat4x2 m, const float a) {
-    m[0] -= a;
-    m[1] -= a;
-    m[2] -= a;
-    m[3] -= a;
-}
-
-void __operator -= (inout mat4x3 m, const float a) {
-    m[0] -= a;
-    m[1] -= a;
-    m[2] -= a;
-    m[3] -= a;
-}
-
-
-void __operator *= (inout mat2x3 m, const float a) {
-    m[0] *= a;
-    m[1] *= a;
-}
-
-void __operator *= (inout mat2x4 m, const float a) {
-    m[0] *= a;
-    m[1] *= a;
-}
-
-void __operator *= (inout mat3x2 m, const float a) {
-    m[0] *= a;
-    m[1] *= a;
-    m[2] *= a;
-}
-
-void __operator *= (inout mat3x4 m, const float a) {
-    m[0] *= a;
-    m[1] *= a;
-    m[2] *= a;
-}
-
-void __operator *= (inout mat4x2 m, const float a) {
-    m[0] *= a;
-    m[1] *= a;
-    m[2] *= a;
-    m[3] *= a;
-}
-
-void __operator *= (inout mat4x3 m, const float a) {
-    m[0] *= a;
-    m[1] *= a;
-    m[2] *= a;
-    m[3] *= a;
-}
-
-
-void __operator /= (inout mat2x3 m, const float a) {
-    m[0] /= a;
-    m[1] /= a;
-}
-
-void __operator /= (inout mat2x4 m, const float a) {
-    m[0] /= a;
-    m[1] /= a;
-}
-
-void __operator /= (inout mat3x2 m, const float a) {
-    m[0] /= a;
-    m[1] /= a;
-    m[2] /= a;
-}
-
-void __operator /= (inout mat3x4 m, const float a) {
-    m[0] /= a;
-    m[1] /= a;
-    m[2] /= a;
-}
-
-void __operator /= (inout mat4x2 m, const float a) {
-    m[0] /= a;
-    m[1] /= a;
-    m[2] /= a;
-    m[3] /= a;
-}
-
-void __operator /= (inout mat4x3 m, const float a) {
-    m[0] /= a;
-    m[1] /= a;
-    m[2] /= a;
-    m[3] /= a;
-}
-
-
-mat2x3 __operator + (const mat2x3 m, const mat2x3 n) {
-    return mat2x3 (m[0] + n[0], m[1] + n[1]);
-}
-
-mat2x4 __operator + (const mat2x4 m, const mat2x4 n) {
-    return mat2x4 (m[0] + n[0], m[1] + n[1]);
-}
-
-mat3x2 __operator + (const mat3x2 m, const mat3x2 n) {
-    return mat3x2 (m[0] + n[0], m[1] + n[1], m[2] + n[2]);
-}
-
-mat3x4 __operator + (const mat3x4 m, const mat3x4 n) {
-    return mat3x4 (m[0] + n[0], m[1] + n[1], m[2] + n[2]);
-}
-
-mat4x2 __operator + (const mat4x2 m, const mat4x2 n) {
-    return mat4x2 (m[0] + n[0], m[1] + n[1], m[2] + n[2], m[3] + n[3]);
-}
-
-mat4x3 __operator + (const mat4x3 m, const mat4x3 n) {
-    return mat4x3 (m[0] + n[0], m[1] + n[1], m[2] + n[2], m[3] + n[3]);
-}
-
-
-mat2x3 __operator - (const mat2x3 m, const mat2x3 n) {
-    return mat2x3 (m[0] - n[0], m[1] - n[1]);
-}
-
-mat2x4 __operator - (const mat2x4 m, const mat2x4 n) {
-    return mat2x4 (m[0] - n[0], m[1] - n[1]);
-}
-
-mat3x2 __operator - (const mat3x2 m, const mat3x2 n) {
-    return mat3x2 (m[0] - n[0], m[1] - n[1], m[2] - n[2]);
-}
-
-mat3x4 __operator - (const mat3x4 m, const mat3x4 n) {
-    return mat3x4 (m[0] - n[0], m[1] - n[1], m[2] - n[2]);
-}
-
-mat4x2 __operator - (const mat4x2 m, const mat4x2 n) {
-    return mat4x2 (m[0] - n[0], m[1] - n[1], m[2] - n[2], m[3] - n[3]);
-}
-
-mat4x3 __operator - (const mat4x3 m, const mat4x3 n) {
-    return mat4x3 (m[0] - n[0], m[1] - n[1], m[2] - n[2], m[3] - n[3]);
-}
-
-
-mat2x3 __operator / (const mat2x3 m, const mat2x3 n) {
-    return mat2x3 (m[0] / n[0], m[1] / n[1]);
-}
-
-mat2x4 __operator / (const mat2x4 m, const mat2x4 n) {
-    return mat2x4 (m[0] / n[0], m[1] / n[1]);
-}
-
-mat3x2 __operator / (const mat3x2 m, const mat3x2 n) {
-    return mat3x2 (m[0] / n[0], m[1] / n[1], m[2] / n[2]);
-}
-
-mat3x4 __operator / (const mat3x4 m, const mat3x4 n) {
-    return mat3x4 (m[0] / n[0], m[1] / n[1], m[2] / n[2]);
-}
-
-mat4x2 __operator / (const mat4x2 m, const mat4x2 n) {
-    return mat4x2 (m[0] / n[0], m[1] / n[1], m[2] / n[2], m[3] / n[3]);
-}
-
-mat4x3 __operator / (const mat4x3 m, const mat4x3 n) {
-    return mat4x3 (m[0] / n[0], m[1] / n[1], m[2] / n[2], m[3] / n[3]);
-}
-
-
-mat2x3 __operator + (const float a, const mat2x3 n) {
-    return mat2x3 (a + n[0], a + n[1]);
-}
-
-mat2x3 __operator + (const mat2x3 m, const float b) {
-    return mat2x3 (m[0] + b, m[1] + b);
-}
-
-mat2x4 __operator + (const float a, const mat2x4 n) {
-    return mat2x4 (a + n[0], a + n[1]);
-}
-
-mat2x4 __operator + (const mat2x4 m, const float b) {
-    return mat2x4 (m[0] + b, m[1] + b);
-}
-
-mat3x2 __operator + (const float a, const mat3x2 n) {
-    return mat3x2 (a + n[0], a + n[1], a + n[2]);
-}
-
-mat3x2 __operator + (const mat3x2 m, const float b) {
-    return mat3x2 (m[0] + b, m[1] + b, m[2] + b);
-}
-
-mat3x4 __operator + (const float a, const mat3x4 n) {
-    return mat3x4 (a + n[0], a + n[1], a + n[2]);
-}
-
-mat3x4 __operator + (const mat3x4 m, const float b) {
-    return mat3x4 (m[0] + b, m[1] + b, m[2] + b);
-}
-
-mat4x2 __operator + (const mat4x2 m, const float b) {
-    return mat4x2 (m[0] + b, m[1] + b, m[2] + b, m[3] + b);
-}
-
-mat4x2 __operator + (const float a, const mat4x2 n) {
-    return mat4x2 (a + n[0], a + n[1], a + n[2], a + n[3]);
-}
-
-mat4x3 __operator + (const mat4x3 m, const float b) {
-    return mat4x3 (m[0] + b, m[1] + b, m[2] + b, m[3] + b);
-}
-
-mat4x3 __operator + (const float a, const mat4x3 n) {
-    return mat4x3 (a + n[0], a + n[1], a + n[2], a + n[3]);
-}
-
-
-mat2x3 __operator - (const float a, const mat2x3 n) {
-    return mat2x3 (a - n[0], a - n[1]);
-}
-
-mat2x3 __operator - (const mat2x3 m, const float b) {
-    return mat2x3 (m[0] - b, m[1] - b);
-}
-
-mat2x4 __operator - (const float a, const mat2x4 n) {
-    return mat2x4 (a - n[0], a - n[1]);
-}
-
-mat2x4 __operator - (const mat2x4 m, const float b) {
-    return mat2x4 (m[0] - b, m[1] - b);
-}
-
-mat3x2 __operator - (const float a, const mat3x2 n) {
-    return mat3x2 (a - n[0], a - n[1], a - n[2]);
-}
-
-mat3x2 __operator - (const mat3x2 m, const float b) {
-    return mat3x2 (m[0] - b, m[1] - b, m[2] - b);
-}
-
-mat3x4 __operator - (const float a, const mat3x4 n) {
-    return mat3x4 (a - n[0], a - n[1], a - n[2]);
-}
-
-mat3x4 __operator - (const mat3x4 m, const float b) {
-    return mat3x4 (m[0] - b, m[1] - b, m[2] - b);
-}
-
-mat4x2 __operator - (const mat4x2 m, const float b) {
-    return mat4x2 (m[0] - b, m[1] - b, m[2] - b, m[3] - b);
-}
-
-mat4x2 __operator - (const float a, const mat4x2 n) {
-    return mat4x2 (a - n[0], a - n[1], a - n[2], a - n[3]);
-}
-
-mat4x3 __operator - (const mat4x3 m, const float b) {
-    return mat4x3 (m[0] - b, m[1] - b, m[2] - b, m[3] - b);
-}
-
-mat4x3 __operator - (const float a, const mat4x3 n) {
-    return mat4x3 (a - n[0], a - n[1], a - n[2], a - n[3]);
-}
-
-
-mat2x3 __operator * (const float a, const mat2x3 n)
-{
-   //return mat2x3 (a * n[0], a * n[1]);
-   __retVal[0] = a * n[0];
-   __retVal[1] = a * n[1];
-}
-
-mat2x3 __operator * (const mat2x3 m, const float b)
-{
-   //return mat2x3 (m[0] * b, m[1] * b);
-   __retVal[0] = m[0] * b;
-   __retVal[1] = m[1] * b;
-}
-
-mat2x4 __operator * (const float a, const mat2x4 n)
-{
-   //return mat2x4 (a * n[0], a * n[1]);
-   __retVal[0] = a * n[0];
-   __retVal[1] = a * n[1];
-}
-
-mat2x4 __operator * (const mat2x4 m, const float b)
-{
-   //return mat2x4 (m[0] * b, m[1] * b);
-   __retVal[0] = m[0] * b;
-   __retVal[1] = m[1] * b;
-}
-
-mat3x2 __operator * (const float a, const mat3x2 n)
-{
-   //return mat3x2 (a * n[0], a * n[1], a * n[2]);
-   __retVal[0] = a * n[0];
-   __retVal[1] = a * n[1];
-   __retVal[2] = a * n[2];
-}
-
-mat3x2 __operator * (const mat3x2 m, const float b)
-{
-   //return mat3x2 (m[0] * b, m[1] * b, m[2] * b);
-   __retVal[0] = m[0] * b;
-   __retVal[1] = m[1] * b;
-   __retVal[2] = m[2] * b;
-}
-
-mat3x4 __operator * (const float a, const mat3x4 n)
-{
-   //return mat3x4 (a * n[0], a * n[1], a * n[2]);
-   __retVal[0] = a * n[0];
-   __retVal[1] = a * n[1];
-   __retVal[2] = a * n[2];
-}
-
-mat3x4 __operator * (const mat3x4 m, const float b)
-{
-   //return mat3x4 (m[0] * b, m[1] * b, m[2] * b);
-   __retVal[0] = m[0] * b;
-   __retVal[1] = m[1] * b;
-   __retVal[2] = m[2] * b;
-}
-
-mat4x2 __operator * (const mat4x2 m, const float b)
-{
-   //return mat4x2 (m[0] * b, m[1] * b, m[2] * b, m[3] * b);
-   __retVal[0] = m[0] * b;
-   __retVal[1] = m[1] * b;
-   __retVal[2] = m[2] * b;
-   __retVal[3] = m[3] * b;
-}
-
-mat4x2 __operator * (const float a, const mat4x2 n)
-{
-   //return mat4x2 (a * n[0], a * n[1], a * n[2], a * n[3]);
-   __retVal[0] = a * n[0];
-   __retVal[1] = a * n[1];
-   __retVal[2] = a * n[2];
-   __retVal[3] = a * n[3];
-}
-
-mat4x3 __operator * (const mat4x3 m, const float b)
-{
-   //return mat4x3 (m[0] * b, m[1] * b, m[2] * b, m[3] * b);
-   __retVal[0] = m[0] * b;
-   __retVal[1] = m[1] * b;
-   __retVal[2] = m[2] * b;
-   __retVal[3] = m[3] * b;
-}
-
-mat4x3 __operator * (const float a, const mat4x3 n)
-{
-   //return mat4x3 (a * n[0], a * n[1], a * n[2], a * n[3]);
-   __retVal[0] = a * n[0];
-   __retVal[1] = a * n[1];
-   __retVal[2] = a * n[2];
-   __retVal[3] = a * n[3];
-}
-
-
-mat2x3 __operator / (const float a, const mat2x3 n)
-{
-   //return mat2x3 (a / n[0], a / n[1]);
-   const float inv = 1.0 / a;
-   __retVal[0] = inv * n[0];
-   __retVal[1] = inv * n[1];
-}
-
-mat2x3 __operator / (const mat2x3 m, const float b)
-{
-   //return mat2x3 (m[0] / b, m[1] / b);
-   const float inv = 1.0 / b;
-   __retVal[0] = m[0] * inv;
-   __retVal[1] = m[1] * inv;
-}
-
-mat2x4 __operator / (const float a, const mat2x4 n)
-{
-   //return mat2x4 (a / n[0], a / n[1]);
-   const float inv = 1.0 / a;
-   __retVal[0] = inv * n[0];
-   __retVal[1] = inv * n[1];
-}
-
-mat2x4 __operator / (const mat2x4 m, const float b)
-{
-   //return mat2x4 (m[0] / b, m[1] / b);
-   const float inv = 1.0 / b;
-   __retVal[0] = m[0] * inv;
-   __retVal[1] = m[1] * inv;
-}
-
-mat3x2 __operator / (const float a, const mat3x2 n)
-{
-   //return mat3x2 (a / n[0], a / n[1], a / n[2]);
-   const float inv = 1.0 / a;
-   __retVal[0] = inv * n[0];
-   __retVal[1] = inv * n[1];
-   __retVal[2] = inv * n[2];
-}
-
-mat3x2 __operator / (const mat3x2 m, const float b)
-{
-   //return mat3x2 (m[0] / b, m[1] / b, m[2] / b);
-   const float inv = 1.0 / b;
-   __retVal[0] = m[0] * inv;
-   __retVal[1] = m[1] * inv;
-   __retVal[2] = m[2] * inv;
-}
-
-mat3x4 __operator / (const float a, const mat3x4 n)
-{
-   //return mat3x4 (a / n[0], a / n[1], a / n[2]);
-   const float inv = 1.0 / a;
-   __retVal[0] = inv * n[0];
-   __retVal[1] = inv * n[1];
-   __retVal[2] = inv * n[2];
-}
-
-mat3x4 __operator / (const mat3x4 m, const float b)
-{
-   //return mat3x4 (m[0] / b, m[1] / b, m[2] / b);
-   const float inv = 1.0 / b;
-   __retVal[0] = m[0] * inv;
-   __retVal[1] = m[1] * inv;
-   __retVal[2] = m[2] * inv;
-}
-
-mat4x2 __operator / (const mat4x2 m, const float b)
-{
-   //return mat4x2 (m[0] / b, m[1] / b, m[2] / b, m[3] / b);
-   const float inv = 1.0 / b;
-   __retVal[0] = m[0] * inv;
-   __retVal[1] = m[1] * inv;
-   __retVal[2] = m[2] * inv;
-   __retVal[3] = m[3] * inv;
-}
-
-mat4x2 __operator / (const float a, const mat4x2 n)
-{
-   //return mat4x2 (a / n[0], a / n[1], a / n[2], a / n[3]);
-   const float inv = 1.0 / a;
-   __retVal[0] = inv * n[0];
-   __retVal[1] = inv * n[1];
-   __retVal[2] = inv * n[2];
-   __retVal[3] = inv * n[3];
-}
-
-mat4x3 __operator / (const mat4x3 m, const float b)
-{
-   //return mat4x3 (m[0] / b, m[1] / b, m[2] / b, m[3] / b);
-   const float inv = 1.0 / b;
-   __retVal[0] = m[0] * inv;
-   __retVal[1] = m[1] * inv;
-   __retVal[2] = m[2] * inv;
-   __retVal[3] = m[3] * inv;
-}
-
-mat4x3 __operator / (const float a, const mat4x3 n)
-{
-   //return mat4x3 (a / n[0], a / n[1], a / n[2], a / n[3]);
-   const float inv = 1.0 / a;
-   __retVal[0] = inv * n[0];
-   __retVal[1] = inv * n[1];
-   __retVal[2] = inv * n[2];
-   __retVal[3] = inv * n[3];
-}
-
-
-mat2x3 __operator - (const mat2x3 m) {
-    return mat2x3 (-m[0], -m[1]);
-}
-
-mat2x4 __operator - (const mat2x4 m) {
-    return mat2x4 (-m[0], -m[1]);
-}
-
-mat3x2 __operator - (const mat3x2 m) {
-    return mat3x2 (-m[0], -m[1], -m[2]);
-}
-
-mat3x4 __operator - (const mat3x4 m) {
-    return mat3x4 (-m[0], -m[1], -m[2]);
-}
-
-mat4x2 __operator - (const mat4x2 m) {
-    return mat4x2 (-m[0], -m[1], -m[2], -m[3]);
-}
-
-mat4x3 __operator - (const mat4x3 m) {
-    return mat4x3 (-m[0], -m[1], -m[2], -m[3]);
-}
-
-
-void __operator -- (inout mat2x3 m) {
-    --m[0];
-    --m[1];
-}
-
-void __operator -- (inout mat2x4 m) {
-    --m[0];
-    --m[1];
-}
-
-void __operator -- (inout mat3x2 m) {
-    --m[0];
-    --m[1];
-    --m[2];
-}
-
-void __operator -- (inout mat3x4 m) {
-    --m[0];
-    --m[1];
-    --m[2];
-}
-
-void __operator -- (inout mat4x2 m) {
-    --m[0];
-    --m[1];
-    --m[2];
-    --m[3];
-}
-
-void __operator -- (inout mat4x3 m) {
-    --m[0];
-    --m[1];
-    --m[2];
-    --m[3];
-}
-
-
-void __operator ++ (inout mat2x3 m) {
-    ++m[0];
-    ++m[1];
-}
-
-void __operator ++ (inout mat2x4 m) {
-    ++m[0];
-    ++m[1];
-}
-
-void __operator ++ (inout mat3x2 m) {
-    ++m[0];
-    ++m[1];
-    ++m[2];
-}
-
-void __operator ++ (inout mat3x4 m) {
-    ++m[0];
-    ++m[1];
-    ++m[2];
-}
-
-void __operator ++ (inout mat4x2 m) {
-    ++m[0];
-    ++m[1];
-    ++m[2];
-    ++m[3];
-}
-
-void __operator ++ (inout mat4x3 m) {
-    ++m[0];
-    ++m[1];
-    ++m[2];
-    ++m[3];
-}
-
diff --git a/src/mesa/shader/slang/library/slang_builtin_120_common.gc b/src/mesa/shader/slang/library/slang_builtin_120_common.gc
deleted file mode 100644 (file)
index c6264c3..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.6
- *
- * Copyright (C) 2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-//
-// From Shader Spec, ver. 1.20, rev. 6
-//
-
-//
-// 8.5 Matrix Functions
-//
-
-mat2x3 matrixCompMult (mat2x3 m, mat2x3 n) {
-    return mat2x3 (m[0] * n[0], m[1] * n[1]);
-}
-
-mat2x4 matrixCompMult (mat2x4 m, mat2x4 n) {
-    return mat2x4 (m[0] * n[0], m[1] * n[1]);
-}
-
-mat3x2 matrixCompMult (mat3x2 m, mat3x2 n) {
-    return mat3x2 (m[0] * n[0], m[1] * n[1], m[2] * n[2]);
-}
-
-mat3x4 matrixCompMult (mat3x4 m, mat3x4 n) {
-    return mat3x4 (m[0] * n[0], m[1] * n[1], m[2] * n[2]);
-}
-
-mat4x2 matrixCompMult (mat4x2 m, mat4x2 n) {
-    return mat4x2 (m[0] * n[0], m[1] * n[1], m[2] * n[2], m[3] * n[3]);
-}
-
-mat4x3 matrixCompMult (mat4x3 m, mat4x3 n) {
-    return mat4x3 (m[0] * n[0], m[1] * n[1], m[2] * n[2], m[3] * n[3]);
-}
-
-mat2 outerProduct (vec2 c, vec2 r) {
-    return mat2 (
-        c.x * r.x, c.y * r.x,
-        c.x * r.y, c.y * r.y
-    );
-}
-
-mat3 outerProduct (vec3 c, vec3 r) {
-    return mat3 (
-        c.x * r.x, c.y * r.x, c.z * r.x,
-        c.x * r.y, c.y * r.y, c.z * r.y,
-        c.x * r.z, c.y * r.z, c.z * r.z
-    );
-}
-
-mat4 outerProduct (vec4 c, vec4 r) {
-    return mat4 (
-        c.x * r.x, c.y * r.x, c.z * r.x, c.w * r.x,
-        c.x * r.y, c.y * r.y, c.z * r.y, c.w * r.y,
-        c.x * r.z, c.y * r.z, c.z * r.z, c.w * r.z,
-        c.x * r.w, c.y * r.w, c.z * r.w, c.w * r.w
-    );
-}
-
-mat2x3 outerProduct (vec3 c, vec2 r) {
-    return mat2x3 (
-        c.x * r.x, c.y * r.x, c.z * r.x,
-        c.x * r.y, c.y * r.y, c.z * r.y
-    );
-}
-
-mat3x2 outerProduct (vec2 c, vec3 r) {
-    return mat3x2 (
-        c.x * r.x, c.y * r.x,
-        c.x * r.y, c.y * r.y,
-        c.x * r.z, c.y * r.z
-    );
-}
-
-mat2x4 outerProduct (vec4 c, vec2 r) {
-    return mat2x4 (
-        c.x * r.x, c.y * r.x, c.z * r.x, c.w * r.x,
-        c.x * r.y, c.y * r.y, c.z * r.y, c.w * r.y
-    );
-}
-
-mat4x2 outerProduct (vec2 c, vec4 r) {
-    return mat4x2 (
-        c.x * r.x, c.y * r.x,
-        c.x * r.y, c.y * r.y,
-        c.x * r.z, c.y * r.z,
-        c.x * r.w, c.y * r.w
-    );
-}
-
-mat3x4 outerProduct (vec4 c, vec3 r) {
-    return mat3x4 (
-        c.x * r.x, c.y * r.x, c.z * r.x, c.w * r.x,
-        c.x * r.y, c.y * r.y, c.z * r.y, c.w * r.y,
-        c.x * r.z, c.y * r.z, c.z * r.z, c.w * r.z
-    );
-}
-
-mat4x3 outerProduct (vec3 c, vec4 r) {
-    return mat4x3 (
-        c.x * r.x, c.y * r.x, c.z * r.x,
-        c.x * r.y, c.y * r.y, c.z * r.y,
-        c.x * r.z, c.y * r.z, c.z * r.z,
-        c.x * r.w, c.y * r.w, c.z * r.w
-    );
-}
-
-mat2 transpose (mat2 m) {
-    return mat2 (
-        m[0].x, m[1].x,
-        m[0].y, m[1].y
-    );
-}
-
-mat3 transpose (mat3 m) {
-    return mat3 (
-        m[0].x, m[1].x, m[2].x,
-        m[0].y, m[1].y, m[2].y,
-        m[0].z, m[1].z, m[2].z
-    );
-}
-
-mat4 transpose (mat4 m) {
-    return mat4 (
-        m[0].x, m[1].x, m[2].x, m[3].x,
-        m[0].y, m[1].y, m[2].y, m[3].y,
-        m[0].z, m[1].z, m[2].z, m[3].z,
-        m[0].w, m[1].w, m[2].w, m[3].w
-    );
-}
-
-mat2x3 transpose (mat3x2 m) {
-    return mat2x3 (
-        m[0].x, m[1].x, m[2].x,
-        m[0].y, m[1].y, m[2].y
-    );
-}
-
-mat3x2 transpose (mat2x3 m) {
-    return mat3x2 (
-        m[0].x, m[1].x,
-        m[0].y, m[1].y,
-        m[0].z, m[1].z
-    );
-}
-
-mat2x4 transpose (mat4x2 m) {
-    return mat2x4 (
-        m[0].x, m[1].x, m[2].x, m[3].x,
-        m[0].y, m[1].y, m[2].y, m[3].y
-    );
-}
-
-mat4x2 transpose (mat2x4 m) {
-    return mat4x2 (
-        m[0].x, m[1].x,
-        m[0].y, m[1].y,
-        m[0].z, m[1].z,
-        m[0].w, m[1].w
-    );
-}
-
-mat3x4 transpose (mat4x3 m) {
-    return mat3x4 (
-        m[0].x, m[1].x, m[2].x, m[3].x,
-        m[0].y, m[1].y, m[2].y, m[3].y,
-        m[0].z, m[1].z, m[2].z, m[3].z
-    );
-}
-
-mat4x3 transpose (mat3x4 m) {
-    return mat4x3 (
-        m[0].x, m[1].x, m[2].x,
-        m[0].y, m[1].y, m[2].y,
-        m[0].z, m[1].z, m[2].z,
-        m[0].w, m[1].w, m[2].w
-    );
-}
-
diff --git a/src/mesa/shader/slang/library/slang_builtin_120_fragment.gc b/src/mesa/shader/slang/library/slang_builtin_120_fragment.gc
deleted file mode 100644 (file)
index 7d51604..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5
- *
- * Copyright (C) 2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-//
-// From Shader Spec, ver. 1.20, rev. 6
-//
-
-varying vec2 gl_PointCoord;
-
diff --git a/src/mesa/shader/slang/library/slang_common_builtin.gc b/src/mesa/shader/slang/library/slang_common_builtin.gc
deleted file mode 100644 (file)
index d75354d..0000000
+++ /dev/null
@@ -1,1887 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.3
- *
- * Copyright (C) 2006  Brian Paul   All Rights Reserved.
- * Copyright (C) 2008  VMware, 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
- * 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.
- */
-
-//
-// From Shader Spec, ver. 1.10, rev. 59
-//
-
-// Note: the values assigned to these constants here aren't actually used.
-// They're set by the compiler according to the GL context limits.
-// See slang_simplify.c
-const int gl_MaxLights = 8;
-const int gl_MaxClipPlanes = 6;
-const int gl_MaxTextureUnits = 8;
-const int gl_MaxTextureCoords = 8;
-const int gl_MaxVertexAttribs = 16;
-const int gl_MaxVertexUniformComponents = 512;
-const int gl_MaxVaryingFloats = 32;
-const int gl_MaxVertexTextureImageUnits = 0;
-const int gl_MaxCombinedTextureImageUnits = 2;
-const int gl_MaxTextureImageUnits = 2;
-const int gl_MaxFragmentUniformComponents = 64;
-const int gl_MaxDrawBuffers = 1;
-
-uniform mat4 gl_ModelViewMatrix;
-uniform mat4 gl_ProjectionMatrix;
-uniform mat4 gl_ModelViewProjectionMatrix;
-uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords];
-
-uniform mat3 gl_NormalMatrix;
-
-uniform mat4 gl_ModelViewMatrixInverse;
-uniform mat4 gl_ProjectionMatrixInverse;
-uniform mat4 gl_ModelViewProjectionMatrixInverse;
-uniform mat4 gl_TextureMatrixInverse[gl_MaxTextureCoords];
-
-uniform mat4 gl_ModelViewMatrixTranspose;
-uniform mat4 gl_ProjectionMatrixTranspose;
-uniform mat4 gl_ModelViewProjectionMatrixTranspose;
-uniform mat4 gl_TextureMatrixTranspose[gl_MaxTextureCoords];
-
-uniform mat4 gl_ModelViewMatrixInverseTranspose;
-uniform mat4 gl_ProjectionMatrixInverseTranspose;
-uniform mat4 gl_ModelViewProjectionMatrixInverseTranspose;
-uniform mat4 gl_TextureMatrixInverseTranspose[gl_MaxTextureCoords];
-
-uniform float gl_NormalScale;
-
-struct gl_DepthRangeParameters {
-    float near;
-    float far;
-    float diff;
-};
-
-uniform gl_DepthRangeParameters gl_DepthRange;
-
-uniform vec4 gl_ClipPlane[gl_MaxClipPlanes];
-
-struct gl_PointParameters {
-    float size;
-    float sizeMin;
-    float sizeMax;
-    float fadeThresholdSize;
-    float distanceConstantAttenuation;
-    float distanceLinearAttenuation;
-    float distanceQuadraticAttenuation;
-};
-
-uniform gl_PointParameters gl_Point;
-
-struct gl_MaterialParameters {
-    vec4 emission;
-    vec4 ambient;
-    vec4 diffuse;
-    vec4 specular;
-    float shininess;
-};
-
-uniform gl_MaterialParameters gl_FrontMaterial;
-uniform gl_MaterialParameters gl_BackMaterial;
-
-/* NOTE: the order of these fields is significant!
- * See the definition of the lighting state vars such as STATE_SPOT_DIRECTION.
- */
-struct gl_LightSourceParameters {
-    vec4 ambient;
-    vec4 diffuse;
-    vec4 specular;
-    vec4 position;
-    vec4 halfVector;
-    vec3 spotDirection;
-    float spotCosCutoff;
-
-    float constantAttenuation;
-    float linearAttenuation;
-    float quadraticAttenuation;
-    float spotExponent;
-
-    float spotCutoff;
-};
-
-uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights];
-
-struct gl_LightModelParameters {
-    vec4 ambient;
-};
-
-uniform gl_LightModelParameters gl_LightModel;
-
-struct gl_LightModelProducts {
-    vec4 sceneColor;
-};
-
-uniform gl_LightModelProducts gl_FrontLightModelProduct;
-uniform gl_LightModelProducts gl_BackLightModelProduct;
-
-struct gl_LightProducts {
-    vec4 ambient;
-    vec4 diffuse;
-    vec4 specular;
-};
-
-uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights];
-uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights];
-
-uniform vec4 gl_TextureEnvColor[gl_MaxTextureImageUnits];
-uniform vec4 gl_EyePlaneS[gl_MaxTextureCoords];
-uniform vec4 gl_EyePlaneT[gl_MaxTextureCoords];
-uniform vec4 gl_EyePlaneR[gl_MaxTextureCoords];
-uniform vec4 gl_EyePlaneQ[gl_MaxTextureCoords];
-uniform vec4 gl_ObjectPlaneS[gl_MaxTextureCoords];
-uniform vec4 gl_ObjectPlaneT[gl_MaxTextureCoords];
-uniform vec4 gl_ObjectPlaneR[gl_MaxTextureCoords];
-uniform vec4 gl_ObjectPlaneQ[gl_MaxTextureCoords];
-
-struct gl_FogParameters {
-    vec4 color;
-    float density;
-    float start;
-    float end;
-    float scale;
-};
-
-uniform gl_FogParameters gl_Fog;
-
-
-
-
-
-//
-// 8.1 Angle and Trigonometry Functions
-//
-
-//// radians
-
-float radians(const float deg)
-{
-   const float c = 3.1415926 / 180.0;
-   __asm vec4_multiply __retVal, deg, c;
-}
-
-vec2 radians(const vec2 deg)
-{
-   const float c = 3.1415926 / 180.0;
-   __asm vec4_multiply __retVal.xy, deg.xy, c.xx;
-}
-
-vec3 radians(const vec3 deg)
-{
-   const float c = 3.1415926 / 180.0;
-   __asm vec4_multiply __retVal.xyz, deg.xyz, c.xxx;
-}
-
-vec4 radians(const vec4 deg)
-{
-   const float c = 3.1415926 / 180.0;
-   __asm vec4_multiply __retVal, deg, c.xxxx;
-}
-
-
-//// degrees
-
-float degrees(const float rad)
-{
-   const float c = 180.0 / 3.1415926;
-   __asm vec4_multiply __retVal, rad, c;
-}
-
-vec2 degrees(const vec2 rad)
-{
-   const float c = 180.0 / 3.1415926;
-   __asm vec4_multiply __retVal.xy, rad.xy, c.xx;
-}
-
-vec3 degrees(const vec3 rad)
-{
-   const float c = 180.0 / 3.1415926;
-   __asm vec4_multiply __retVal.xyz, rad.xyz, c.xxx;
-}
-
-vec4 degrees(const vec4 rad)
-{
-   const float c = 180.0 / 3.1415926;
-   __asm vec4_multiply __retVal, rad, c.xxxx;
-}
-
-
-//// sin
-
-float sin(const float radians)
-{
-   __asm float_sine __retVal, radians;
-}
-
-vec2 sin(const vec2 radians)
-{
-   __asm float_sine __retVal.x, radians.x;
-   __asm float_sine __retVal.y, radians.y;
-}
-
-vec3 sin(const vec3 radians)
-{
-   __asm float_sine __retVal.x, radians.x;
-   __asm float_sine __retVal.y, radians.y;
-   __asm float_sine __retVal.z, radians.z;
-}
-
-vec4 sin(const vec4 radians)
-{
-   __asm float_sine __retVal.x, radians.x;
-   __asm float_sine __retVal.y, radians.y;
-   __asm float_sine __retVal.z, radians.z;
-   __asm float_sine __retVal.w, radians.w;
-}
-
-
-//// cos
-
-float cos(const float radians)
-{
-   __asm float_cosine __retVal, radians;
-}
-
-vec2 cos(const vec2 radians)
-{
-   __asm float_cosine __retVal.x, radians.x;
-   __asm float_cosine __retVal.y, radians.y;
-}
-
-vec3 cos(const vec3 radians)
-{
-   __asm float_cosine __retVal.x, radians.x;
-   __asm float_cosine __retVal.y, radians.y;
-   __asm float_cosine __retVal.z, radians.z;
-}
-
-vec4 cos(const vec4 radians)
-{
-   __asm float_cosine __retVal.x, radians.x;
-   __asm float_cosine __retVal.y, radians.y;
-   __asm float_cosine __retVal.z, radians.z;
-   __asm float_cosine __retVal.w, radians.w;
-}
-
-
-
-//// tan
-
-float tan(const float angle)
-{
-   const float s = sin(angle);
-   const float c = cos(angle);
-   return s / c;
-}
-
-vec2 tan(const vec2 angle)
-{
-   const vec2 s = sin(angle);
-   const vec2 c = cos(angle);
-   return s / c;
-}
-
-vec3 tan(const vec3 angle)
-{
-   const vec3 s = sin(angle);
-   const vec3 c = cos(angle);
-   return s / c;
-}
-
-vec4 tan(const vec4 angle)
-{
-   const vec4 s = sin(angle);
-   const vec4 c = cos(angle);
-   return s / c;
-}
-
-
-
-float asin(const float x)
-{
-   const float a0 = 1.5707288;  // PI/2?
-   const float a1 = -0.2121144;
-   const float a2 = 0.0742610;
-   //const float a3 = -0.0187293;
-   const float halfPi = 3.1415926 * 0.5;
-   const float y = abs(x);
-   // three terms seem to be enough:
-   __retVal = (halfPi - sqrt(1.0 - y) * (a0 + y * (a1 + a2 * y))) * sign(x);
-   // otherwise, try four:
-   //__retVal = (halfPi - sqrt(1.0 - y) * (a0 + y * (a1 + y * (a2 + y * a3)))) * sign(x);
-}
-
-vec2 asin(const vec2 v)
-{
-   __retVal.x = asin(v.x);
-   __retVal.y = asin(v.y);
-}
-
-vec3 asin(const vec3 v)
-{
-   __retVal.x = asin(v.x);
-   __retVal.y = asin(v.y);
-   __retVal.z = asin(v.z);
-}
-
-vec4 asin(const vec4 v)
-{
-   __retVal.x = asin(v.x);
-   __retVal.y = asin(v.y);
-   __retVal.z = asin(v.z);
-   __retVal.w = asin(v.w);
-}
-
-float acos(const float x)
-{
-   const float halfPi = 3.1415926 * 0.5;
-   __retVal = halfPi - asin(x);
-}
-
-vec2 acos(const vec2 v)
-{
-   __retVal.x = acos(v.x);
-   __retVal.y = acos(v.y);
-}
-
-vec3 acos(const vec3 v)
-{
-   __retVal.x = acos(v.x);
-   __retVal.y = acos(v.y);
-   __retVal.z = acos(v.z);
-}
-
-vec4 acos(const vec4 v)
-{
-   __retVal.x = acos(v.x);
-   __retVal.y = acos(v.y);
-   __retVal.z = acos(v.z);
-   __retVal.w = acos(v.w);
-}
-
-float atan(const float x)
-{
-   __retVal = asin(x * inversesqrt(x * x + 1.0));
-}
-
-vec2 atan(const vec2 y_over_x)
-{
-   __retVal.x = atan(y_over_x.x);
-   __retVal.y = atan(y_over_x.y);
-}
-
-vec3 atan(const vec3 y_over_x)
-{
-   __retVal.x = atan(y_over_x.x);
-   __retVal.y = atan(y_over_x.y);
-   __retVal.z = atan(y_over_x.z);
-}
-
-vec4 atan(const vec4 y_over_x)
-{
-   __retVal.x = atan(y_over_x.x);
-   __retVal.y = atan(y_over_x.y);
-   __retVal.z = atan(y_over_x.z);
-   __retVal.w = atan(y_over_x.w);
-}
-
-float atan(const float y, const float x)
-{
-   float r;
-   if (abs(x) > 1.0e-4) {
-      r = atan(y / x);
-      if (x < 0.0) {
-         r = r + sign(y) * 3.141593;
-      }
-   }
-   else {
-      r = sign(y) * 1.5707965;  // pi/2
-   }
-   return r;
-}
-
-vec2 atan(const vec2 u, const vec2 v)
-{
-   __retVal.x = atan(u.x, v.x);
-   __retVal.y = atan(u.y, v.y);
-}
-
-vec3 atan(const vec3 u, const vec3 v)
-{
-   __retVal.x = atan(u.x, v.x);
-   __retVal.y = atan(u.y, v.y);
-   __retVal.z = atan(u.z, v.z);
-}
-
-vec4 atan(const vec4 u, const vec4 v)
-{
-   __retVal.x = atan(u.x, v.x);
-   __retVal.y = atan(u.y, v.y);
-   __retVal.z = atan(u.z, v.z);
-   __retVal.w = atan(u.w, v.w);
-}
-
-
-//
-// 8.2 Exponential Functions
-//
-
-//// pow
-
-float pow(const float a, const float b)
-{
-   __asm float_power __retVal, a, b;
-}
-
-vec2 pow(const vec2 a, const vec2 b)
-{
-   __asm float_power __retVal.x, a.x, b.x;
-   __asm float_power __retVal.y, a.y, b.y;
-}
-
-vec3 pow(const vec3 a, const vec3 b)
-{
-   __asm float_power __retVal.x, a.x, b.x;
-   __asm float_power __retVal.y, a.y, b.y;
-   __asm float_power __retVal.z, a.z, b.z;
-}
-
-vec4 pow(const vec4 a, const vec4 b)
-{
-   __asm float_power __retVal.x, a.x, b.x;
-   __asm float_power __retVal.y, a.y, b.y;
-   __asm float_power __retVal.z, a.z, b.z;
-   __asm float_power __retVal.w, a.w, b.w;
-}
-
-
-//// exp
-
-float exp(const float a)
-{
-   // NOTE: log2(e) = 1.44269502
-   float t = a * 1.44269502;
-   __asm float_exp2 __retVal, t;
-}
-
-vec2 exp(const vec2 a)
-{
-   vec2 t = a * 1.44269502;
-   __asm float_exp2 __retVal.x, t.x;
-   __asm float_exp2 __retVal.y, t.y;
-}
-
-vec3 exp(const vec3 a)
-{
-   vec3 t = a * 1.44269502;
-   __asm float_exp2 __retVal.x, t.x;
-   __asm float_exp2 __retVal.y, t.y;
-   __asm float_exp2 __retVal.z, t.z;
-}
-
-vec4 exp(const vec4 a)
-{
-   vec4 t = a * 1.44269502;
-   __asm float_exp2 __retVal.x, t.x;
-   __asm float_exp2 __retVal.y, t.y;
-   __asm float_exp2 __retVal.z, t.z;
-   __asm float_exp2 __retVal.w, t.w;
-}
-
-
-
-//// log2
-
-float log2(const float x)
-{
-   __asm float_log2 __retVal, x;
-}
-
-vec2 log2(const vec2 v)
-{
-   __asm float_log2 __retVal.x, v.x;
-   __asm float_log2 __retVal.y, v.y;
-}
-
-vec3 log2(const vec3 v)
-{
-   __asm float_log2 __retVal.x, v.x;
-   __asm float_log2 __retVal.y, v.y;
-   __asm float_log2 __retVal.z, v.z;
-}
-
-vec4 log2(const vec4 v)
-{
-   __asm float_log2 __retVal.x, v.x;
-   __asm float_log2 __retVal.y, v.y;
-   __asm float_log2 __retVal.z, v.z;
-   __asm float_log2 __retVal.w, v.w;
-}
-
-
-//// log  (natural log)
-
-float log(const float x)
-{
-   // note:  logBaseB(x) = logBaseN(x) / logBaseN(B)
-   // compute log(x) = log2(x) / log2(e)
-   // c = 1.0 / log2(e) = 0.693147181
-   const float c = 0.693147181;
-   return log2(x) * c;
-}
-
-vec2 log(const vec2 v)
-{
-   const float c = 0.693147181;
-   return log2(v) * c;
-}
-
-vec3 log(const vec3 v)
-{
-   const float c = 0.693147181;
-   return log2(v) * c;
-}
-
-vec4 log(const vec4 v)
-{
-   const float c = 0.693147181;
-   return log2(v) * c;
-}
-
-
-//// exp2
-
-float exp2(const float a)
-{
-   __asm float_exp2 __retVal, a;
-}
-
-vec2 exp2(const vec2 a)
-{
-   __asm float_exp2 __retVal.x, a.x;
-   __asm float_exp2 __retVal.y, a.y;
-}
-
-vec3 exp2(const vec3 a)
-{
-   __asm float_exp2 __retVal.x, a.x;
-   __asm float_exp2 __retVal.y, a.y;
-   __asm float_exp2 __retVal.z, a.z;
-}
-
-vec4 exp2(const vec4 a)
-{
-   __asm float_exp2 __retVal.x, a.x;
-   __asm float_exp2 __retVal.y, a.y;
-   __asm float_exp2 __retVal.z, a.z;
-   __asm float_exp2 __retVal.w, a.w;
-}
-
-
-//// sqrt
-
-float sqrt(const float x)
-{
-   const float nx = -x;
-   float r;
-   __asm float_rsq r, x;
-   r = r * x;
-   __asm vec4_cmp __retVal, nx, r, 0.0;
-}
-
-vec2 sqrt(const vec2 x)
-{
-   const vec2 nx = -x, zero = vec2(0.0);
-   vec2 r;
-   __asm float_rsq r.x, x.x;
-   __asm float_rsq r.y, x.y;
-   r = r * x;
-   __asm vec4_cmp __retVal, nx, r, zero;
-}
-
-vec3 sqrt(const vec3 x)
-{
-   const vec3 nx = -x, zero = vec3(0.0);
-   vec3 r;
-   __asm float_rsq r.x, x.x;
-   __asm float_rsq r.y, x.y;
-   __asm float_rsq r.z, x.z;
-   r = r * x;
-   __asm vec4_cmp __retVal, nx, r, zero;
-}
-
-vec4 sqrt(const vec4 x)
-{
-   const vec4 nx = -x, zero = vec4(0.0);
-   vec4 r;
-   __asm float_rsq r.x, x.x;
-   __asm float_rsq r.y, x.y;
-   __asm float_rsq r.z, x.z;
-   __asm float_rsq r.w, x.w;
-   r = r * x;
-   __asm vec4_cmp __retVal, nx, r, zero;
-}
-
-
-//// inversesqrt
-
-float inversesqrt(const float x)
-{
-   __asm float_rsq __retVal.x, x;
-}
-
-vec2 inversesqrt(const vec2 v)
-{
-   __asm float_rsq __retVal.x, v.x;
-   __asm float_rsq __retVal.y, v.y;
-}
-
-vec3 inversesqrt(const vec3 v)
-{
-   __asm float_rsq __retVal.x, v.x;
-   __asm float_rsq __retVal.y, v.y;
-   __asm float_rsq __retVal.z, v.z;
-}
-
-vec4 inversesqrt(const vec4 v)
-{
-   __asm float_rsq __retVal.x, v.x;
-   __asm float_rsq __retVal.y, v.y;
-   __asm float_rsq __retVal.z, v.z;
-   __asm float_rsq __retVal.w, v.w;
-}
-
-
-//// normalize
-
-float normalize(const float x)
-{
-   __retVal = 1.0;
-}
-
-vec2 normalize(const vec2 v)
-{
-   const float s = inversesqrt(dot(v, v));
-   __asm vec4_multiply __retVal.xy, v, s;
-}
-
-vec3 normalize(const vec3 v)
-{
-//   const float s = inversesqrt(dot(v, v));
-//   __retVal = v * s;
-// XXX note, we _could_ use __retVal.w instead of tmp and save a
-// register, but that's actually a compilation error because v is a vec3
-// and the .w suffix is illegal.  Oh well.
-   float tmp;
-   __asm vec3_dot tmp, v, v;
-   __asm float_rsq tmp, tmp;
-   __asm vec4_multiply __retVal.xyz, v, tmp;
-}
-
-vec4 normalize(const vec4 v)
-{
-   float tmp;
-   __asm vec4_dot tmp, v, v;
-   __asm float_rsq tmp, tmp;
-   __asm vec4_multiply __retVal.xyz, v, tmp;
-}
-
-
-
-//
-// 8.3 Common Functions
-//
-
-
-//// abs
-
-float abs(const float a)
-{
-   __asm vec4_abs __retVal, a;
-}
-
-vec2 abs(const vec2 a)
-{
-   __asm vec4_abs __retVal.xy, a;
-}
-
-vec3 abs(const vec3 a)
-{
-   __asm vec4_abs __retVal.xyz, a;
-}
-
-vec4 abs(const vec4 a)
-{
-   __asm vec4_abs __retVal, a;
-}
-
-
-//// sign
-
-float sign(const float x)
-{
-   float p, n;
-   __asm vec4_sgt p, x, 0.0;            // p = (x > 0)
-   __asm vec4_sgt n, 0.0, x;            // n = (x < 0)
-   __asm vec4_subtract __retVal, p, n;  // sign = p - n
-}
-
-vec2 sign(const vec2 v)
-{
-   vec2 p, n;
-   __asm vec4_sgt p.xy, v, 0.0;
-   __asm vec4_sgt n.xy, 0.0, v;
-   __asm vec4_subtract __retVal.xy, p, n;
-}
-
-vec3 sign(const vec3 v)
-{
-   vec3 p, n;
-   __asm vec4_sgt p.xyz, v, 0.0;
-   __asm vec4_sgt n.xyz, 0.0, v;
-   __asm vec4_subtract __retVal.xyz, p, n;
-}
-
-vec4 sign(const vec4 v)
-{
-   vec4 p, n;
-   __asm vec4_sgt p, v, 0.0;
-   __asm vec4_sgt n, 0.0, v;
-   __asm vec4_subtract __retVal, p, n;
-}
-
-
-//// floor
-
-float floor(const float a)
-{
-   __asm vec4_floor __retVal, a;
-}
-
-vec2 floor(const vec2 a)
-{
-   __asm vec4_floor __retVal.xy, a;
-}
-
-vec3 floor(const vec3 a)
-{
-   __asm vec4_floor __retVal.xyz, a;
-}
-
-vec4 floor(const vec4 a)
-{
-   __asm vec4_floor __retVal, a;
-}
-
-
-//// ceil
-
-float ceil(const float a)
-{
-   // XXX this could be improved
-   float b = -a;
-   __asm vec4_floor b, b;
-   __retVal = -b;
-}
-
-vec2 ceil(const vec2 a)
-{
-   vec2 b = -a;
-   __asm vec4_floor b, b;
-   __retVal.xy = -b;
-}
-
-vec3 ceil(const vec3 a)
-{
-   vec3 b = -a;
-   __asm vec4_floor b, b;
-   __retVal.xyz = -b;
-}
-
-vec4 ceil(const vec4 a)
-{
-   vec4 b = -a;
-   __asm vec4_floor b, b;
-   __retVal = -b;
-}
-
-
-//// fract
-
-float fract(const float a)
-{
-   __asm vec4_frac __retVal, a;
-}
-
-vec2 fract(const vec2 a)
-{
-   __asm vec4_frac __retVal.xy, a;
-}
-
-vec3 fract(const vec3 a)
-{
-   __asm vec4_frac __retVal.xyz, a;
-}
-
-vec4 fract(const vec4 a)
-{
-   __asm vec4_frac __retVal, a;
-}
-
-
-//// mod  (very untested!)
-
-float mod(const float a, const float b)
-{
-    float oneOverB;
-    __asm float_rcp oneOverB, b;
-    __retVal = a - b * floor(a * oneOverB);
-}
-
-vec2 mod(const vec2 a, const float b)
-{
-    float oneOverB;
-    __asm float_rcp oneOverB, b;
-    __retVal.xy = a - b * floor(a * oneOverB);
-}
-
-vec3 mod(const vec3 a, const float b)
-{
-    float oneOverB;
-    __asm float_rcp oneOverB, b;
-    __retVal.xyz = a - b * floor(a * oneOverB);
-}
-
-vec4 mod(const vec4 a, const float b)
-{
-    float oneOverB;
-    __asm float_rcp oneOverB, b;
-    __retVal = a - b * floor(a * oneOverB);
-}
-
-vec2 mod(const vec2 a, const vec2 b)
-{
-    vec2 oneOverB;
-    __asm float_rcp oneOverB.x, b.x;
-    __asm float_rcp oneOverB.y, b.y;
-    __retVal = a - b * floor(a * oneOverB);
-}
-
-vec3 mod(const vec3 a, const vec3 b)
-{
-    vec3 oneOverB;
-    __asm float_rcp oneOverB.x, b.x;
-    __asm float_rcp oneOverB.y, b.y;
-    __asm float_rcp oneOverB.z, b.z;
-    __retVal = a - b * floor(a * oneOverB);
-}
-
-vec4 mod(const vec4 a, const vec4 b)
-{
-    vec4 oneOverB;
-    __asm float_rcp oneOverB.x, b.x;
-    __asm float_rcp oneOverB.y, b.y;
-    __asm float_rcp oneOverB.z, b.z;
-    __asm float_rcp oneOverB.w, b.w;
-    __retVal = a - b * floor(a * oneOverB);
-}
-
-
-//// min
-
-float min(const float a, const float b)
-{
-   __asm vec4_min __retVal, a, b;
-}
-
-vec2 min(const vec2 a, const vec2 b)
-{
-   __asm vec4_min __retVal.xy, a.xy, b.xy;
-}
-
-vec3 min(const vec3 a, const vec3 b)
-{
-   __asm vec4_min __retVal.xyz, a.xyz, b.xyz;
-}
-
-vec4 min(const vec4 a, const vec4 b)
-{
-   __asm vec4_min __retVal, a, b;
-}
-
-vec2 min(const vec2 a, const float b)
-{
-   __asm vec4_min __retVal, a.xy, b;
-}
-
-vec3 min(const vec3 a, const float b)
-{
-   __asm vec4_min __retVal, a.xyz, b;
-}
-
-vec4 min(const vec4 a, const float b)
-{
-   __asm vec4_min __retVal, a, b;
-}
-
-
-//// max
-
-float max(const float a, const float b)
-{
-   __asm vec4_max __retVal, a, b;
-}
-
-vec2 max(const vec2 a, const vec2 b)
-{
-   __asm vec4_max __retVal.xy, a.xy, b.xy;
-}
-
-vec3 max(const vec3 a, const vec3 b)
-{
-   __asm vec4_max __retVal.xyz, a.xyz, b.xyz;
-}
-
-vec4 max(const vec4 a, const vec4 b)
-{
-   __asm vec4_max __retVal, a, b;
-}
-
-vec2 max(const vec2 a, const float b)
-{
-   __asm vec4_max __retVal, a.xy, b;
-}
-
-vec3 max(const vec3 a, const float b)
-{
-   __asm vec4_max __retVal, a.xyz, b;
-}
-
-vec4 max(const vec4 a, const float b)
-{
-   __asm vec4_max __retVal, a, b;
-}
-
-
-//// clamp
-
-float clamp(const float val, const float minVal, const float maxVal)
-{
-   __asm vec4_clamp __retVal, val, minVal, maxVal;
-}
-
-vec2 clamp(const vec2 val, const float minVal, const float maxVal)
-{
-   __asm vec4_clamp __retVal, val, minVal, maxVal;
-}
-
-vec3 clamp(const vec3 val, const float minVal, const float maxVal)
-{
-   __asm vec4_clamp __retVal, val, minVal, maxVal;
-}
-
-vec4 clamp(const vec4 val, const float minVal, const float maxVal)
-{
-   __asm vec4_clamp __retVal, val, minVal, maxVal;
-}
-
-vec2 clamp(const vec2 val, const vec2 minVal, const vec2 maxVal)
-{
-   __asm vec4_clamp __retVal, val, minVal, maxVal;
-}
-
-vec3 clamp(const vec3 val, const vec3 minVal, const vec3 maxVal)
-{
-   __asm vec4_clamp __retVal, val, minVal, maxVal;
-}
-
-vec4 clamp(const vec4 val, const vec4 minVal, const vec4 maxVal)
-{
-   __asm vec4_clamp __retVal, val, minVal, maxVal;
-}
-
-
-//// mix
-
-float mix(const float x, const float y, const float a)
-{
-   __asm vec4_lrp __retVal, a, y, x;
-}
-
-vec2 mix(const vec2 x, const vec2 y, const float a)
-{
-   __asm vec4_lrp __retVal, a, y, x;
-}
-
-vec3 mix(const vec3 x, const vec3 y, const float a)
-{
-   __asm vec4_lrp __retVal, a, y, x;
-}
-
-vec4 mix(const vec4 x, const vec4 y, const float a)
-{
-   __asm vec4_lrp __retVal, a, y, x;
-}
-
-vec2 mix(const vec2 x, const vec2 y, const vec2 a)
-{
-   __asm vec4_lrp __retVal, a, y, x;
-}
-
-vec3 mix(const vec3 x, const vec3 y, const vec3 a)
-{
-   __asm vec4_lrp __retVal, a, y, x;
-}
-
-vec4 mix(const vec4 x, const vec4 y, const vec4 a)
-{
-   __asm vec4_lrp __retVal, a, y, x;
-}
-
-
-//// step
-
-float step(const float edge, const float x)
-{
-   __asm vec4_sge __retVal, x, edge;
-}
-
-vec2 step(const vec2 edge, const vec2 x)
-{
-   __asm vec4_sge __retVal.xy, x, edge;
-}
-
-vec3 step(const vec3 edge, const vec3 x)
-{
-   __asm vec4_sge __retVal.xyz, x, edge;
-}
-
-vec4 step(const vec4 edge, const vec4 x)
-{
-   __asm vec4_sge __retVal, x, edge;
-}
-
-vec2 step(const float edge, const vec2 v)
-{
-   __asm vec4_sge __retVal.xy, v, edge;
-}
-
-vec3 step(const float edge, const vec3 v)
-{
-   __asm vec4_sge __retVal.xyz, v, edge;
-}
-
-vec4 step(const float edge, const vec4 v)
-{
-   __asm vec4_sge __retVal, v, edge;
-}
-
-
-//// smoothstep
-
-float smoothstep(const float edge0, const float edge1, const float x)
-{
-    float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
-    return t * t * (3.0 - 2.0 * t);
-}
-
-vec2 smoothstep(const vec2 edge0, const vec2 edge1, const vec2 v)
-{
-   vec2 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0);
-   return t * t * (3.0 - 2.0 * t);
-}
-
-vec3 smoothstep(const vec3 edge0, const vec3 edge1, const vec3 v)
-{
-   vec3 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0);
-   return t * t * (3.0 - 2.0 * t);
-}
-
-vec4 smoothstep(const vec4 edge0, const vec4 edge1, const vec4 v)
-{
-   vec4 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0);
-   return t * t * (3.0 - 2.0 * t);
-}
-
-vec2 smoothstep(const float edge0, const float edge1, const vec2 v)
-{
-   vec2 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0);
-   return t * t * (3.0 - 2.0 * t);
-}
-
-vec3 smoothstep(const float edge0, const float edge1, const vec3 v)
-{
-   vec3 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0);
-   return t * t * (3.0 - 2.0 * t);
-}
-
-vec4 smoothstep(const float edge0, const float edge1, const vec4 v)
-{
-   vec4 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0);
-   return t * t * (3.0 - 2.0 * t);
-}
-
-
-
-//
-// 8.4 Geometric Functions
-//
-
-
-//// length
-
-float length(const float x)
-{
-   return abs(x);
-}
-
-float length(const vec2 v)
-{
-   float r;
-   const float p = dot(v, v);      // p = v.x * v.x + v.y * v.y
-   __asm float_rsq r, p;           // r = 1 / sqrt(p)
-   __retVal = p * r;               // p * r = sqrt(p);
-}
-
-float length(const vec3 v)
-{
-   float r;
-   const float p = dot(v, v);      // p = v.x * v.x + v.y * v.y + v.z * v.z
-   __asm float_rsq r, p;           // r = 1 / sqrt(p)
-   __retVal = p * r;               // p * r = sqrt(p);
-}
-
-float length(const vec4 v)
-{
-   float r;
-   const float p = dot(v, v);      // p = v.x * v.x + v.y * v.y + ...
-   __asm float_rsq r, p;           // r = 1 / sqrt(p)
-   __retVal = p * r;               // p * r = sqrt(p);
-}
-
-
-//// distance
-
-float distance(const float x, const float y)
-{
-   const float d = x - y;
-   __retVal = length(d);
-}
-
-float distance(const vec2 v, const vec2 u)
-{
-   const vec2 d2 = v - u;
-   __retVal = length(d2);
-}
-
-float distance(const vec3 v, const vec3 u)
-{
-   const vec3 d3 = v - u;
-   __retVal = length(d3);
-}
-
-float distance(const vec4 v, const vec4 u)
-{
-   const vec4 d4 = v - u;
-   __retVal = length(d4);
-}
-
-
-//// cross
-
-vec3 cross(const vec3 v, const vec3 u)
-{
-   __asm vec3_cross __retVal.xyz, v, u;
-}
-
-
-//// faceforward
-
-float faceforward(const float N, const float I, const float Nref)
-{
-    // this could probably be done better
-    const float d = dot(Nref, I);
-    float s;
-    __asm vec4_sgt s, 0.0, d;  // s = (0.0 > d) ? 1 : 0
-    return mix(-N, N, s);
-}
-
-vec2 faceforward(const vec2 N, const vec2 I, const vec2 Nref)
-{
-    // this could probably be done better
-    const float d = dot(Nref, I);
-    float s;
-    __asm vec4_sgt s, 0.0, d;  // s = (0.0 > d) ? 1 : 0
-    return mix(-N, N, s);
-}
-
-vec3 faceforward(const vec3 N, const vec3 I, const vec3 Nref)
-{
-    // this could probably be done better
-    const float d = dot(Nref, I);
-    float s;
-    __asm vec4_sgt s, 0.0, d;  // s = (0.0 > d) ? 1 : 0
-    return mix(-N, N, s);
-}
-
-vec4 faceforward(const vec4 N, const vec4 I, const vec4 Nref)
-{
-    // this could probably be done better
-    const float d = dot(Nref, I);
-    float s;
-    __asm vec4_sgt s, 0.0, d;  // s = (0.0 > d) ? 1 : 0
-    return mix(-N, N, s);
-}
-
-
-//// reflect
-
-float reflect(const float I, const float N)
-{
-   return I - 2.0 * dot(N, I) * N;
-}
-
-vec2 reflect(const vec2 I, const vec2 N)
-{
-   return I - 2.0 * dot(N, I) * N;
-}
-
-vec3 reflect(const vec3 I, const vec3 N)
-{
-   return I - 2.0 * dot(N, I) * N;
-}
-
-vec4 reflect(const vec4 I, const vec4 N)
-{
-   return I - 2.0 * dot(N, I) * N;
-}
-
-//// refract
-
-float refract(const float I, const float N, const float eta)
-{
-   float n_dot_i = dot(N, I);
-   float k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i);
-   float retval;
-   if (k < 0.0)
-      retval = 0.0;
-   else
-      retval = eta * I - (eta * n_dot_i + sqrt(k)) * N;
-   return retval;
-}
-
-vec2 refract(const vec2 I, const vec2 N, const float eta)
-{
-   float n_dot_i = dot(N, I);
-   float k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i);
-   vec2 retval;
-   if (k < 0.0)
-      retval = vec2(0.0);
-   else
-      retval = eta * I - (eta * n_dot_i + sqrt(k)) * N;
-   return retval;
-}
-
-vec3 refract(const vec3 I, const vec3 N, const float eta)
-{
-   float n_dot_i = dot(N, I);
-   float k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i);
-   vec3 retval;
-   if (k < 0.0)
-      retval = vec3(0.0);
-   else
-      retval = eta * I - (eta * n_dot_i + sqrt(k)) * N;
-   return retval;
-}
-
-vec4 refract(const vec4 I, const vec4 N, const float eta)
-{
-   float n_dot_i = dot(N, I);
-   float k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i);
-   vec4 retval;
-   if (k < 0.0)
-      retval = vec4(0.0);
-   else
-      retval = eta * I - (eta * n_dot_i + sqrt(k)) * N;
-   return retval;
-}
-
-
-
-
-//
-// 8.5 Matrix Functions
-//
-
-mat2 matrixCompMult (mat2 m, mat2 n) {
-    return mat2 (m[0] * n[0], m[1] * n[1]);
-}
-
-mat3 matrixCompMult (mat3 m, mat3 n) {
-    return mat3 (m[0] * n[0], m[1] * n[1], m[2] * n[2]);
-}
-
-mat4 matrixCompMult (mat4 m, mat4 n) {
-    return mat4 (m[0] * n[0], m[1] * n[1], m[2] * n[2], m[3] * n[3]);
-}
-
-
-
-
-//
-// 8.6 Vector Relational Functions
-//
-
-//// lessThan
-
-bvec2 lessThan(const vec2 u, const vec2 v)
-{
-   __asm vec4_slt __retVal.xy, u, v;
-}
-
-bvec3 lessThan(const vec3 u, const vec3 v)
-{
-   __asm vec4_slt __retVal.xyz, u, v;
-}
-
-bvec4 lessThan(const vec4 u, const vec4 v)
-{
-   __asm vec4_slt __retVal, u, v;
-}
-
-bvec2 lessThan(const ivec2 u, const ivec2 v)
-{
-   __asm vec4_slt __retVal.xy, u, v;
-}
-
-bvec3 lessThan(const ivec3 u, const ivec3 v)
-{
-   __asm vec4_slt __retVal.xyz, u, v;
-}
-
-bvec4 lessThan(const ivec4 u, const ivec4 v)
-{
-   __asm vec4_slt __retVal, u, v;
-}
-
-
-//// lessThanEqual
-
-bvec2 lessThanEqual(const vec2 u, const vec2 v)
-{
-   __asm vec4_sle __retVal.xy, u, v;
-}
-
-bvec3 lessThanEqual(const vec3 u, const vec3 v)
-{
-   __asm vec4_sle __retVal.xyz, u, v;
-}
-
-bvec4 lessThanEqual(const vec4 u, const vec4 v)
-{
-   __asm vec4_sle __retVal, u, v;
-}
-
-bvec2 lessThanEqual(const ivec2 u, const ivec2 v)
-{
-   __asm vec4_sle __retVal.xy, u, v;
-}
-
-bvec3 lessThanEqual(const ivec3 u, const ivec3 v)
-{
-   __asm vec4_sle __retVal.xyz, u, v;
-}
-
-bvec4 lessThanEqual(const ivec4 u, const ivec4 v)
-{
-   __asm vec4_sle __retVal, u, v;
-}
-
-
-//// greaterThan
-
-bvec2 greaterThan(const vec2 u, const vec2 v)
-{
-   __asm vec4_sgt __retVal.xy, u, v;
-}
-
-bvec3 greaterThan(const vec3 u, const vec3 v)
-{
-   __asm vec4_sgt __retVal.xyz, u, v;
-}
-
-bvec4 greaterThan(const vec4 u, const vec4 v)
-{
-   __asm vec4_sgt __retVal, u, v;
-}
-
-bvec2 greaterThan(const ivec2 u, const ivec2 v)
-{
-   __asm vec4_sgt __retVal.xy, u.xy, v.xy;
-}
-
-bvec3 greaterThan(const ivec3 u, const ivec3 v)
-{
-   __asm vec4_sgt __retVal.xyz, u, v;
-}
-
-bvec4 greaterThan(const ivec4 u, const ivec4 v)
-{
-   __asm vec4_sgt __retVal, u, v;
-}
-
-
-//// greaterThanEqual
-
-bvec2 greaterThanEqual(const vec2 u, const vec2 v)
-{
-   __asm vec4_sge __retVal.xy, u, v;
-}
-
-bvec3 greaterThanEqual(const vec3 u, const vec3 v)
-{
-   __asm vec4_sge __retVal.xyz, u, v;
-}
-
-bvec4 greaterThanEqual(const vec4 u, const vec4 v)
-{
-   __asm vec4_sge __retVal, u, v;
-}
-
-bvec2 greaterThanEqual(const ivec2 u, const ivec2 v)
-{
-   __asm vec4_sge __retVal.xy, u, v;
-}
-
-bvec3 greaterThanEqual(const ivec3 u, const ivec3 v)
-{
-   __asm vec4_sge __retVal.xyz, u, v;
-}
-
-bvec4 greaterThanEqual(const ivec4 u, const ivec4 v)
-{
-   __asm vec4_sge __retVal, u, v;
-}
-
-
-//// equal
-
-bvec2 equal(const vec2 u, const vec2 v)
-{
-   __asm vec4_seq __retVal.xy, u, v;
-}
-
-bvec3 equal(const vec3 u, const vec3 v)
-{
-   __asm vec4_seq __retVal.xyz, u, v;
-}
-
-bvec4 equal(const vec4 u, const vec4 v)
-{
-   __asm vec4_seq __retVal, u, v;
-}
-
-bvec2 equal(const ivec2 u, const ivec2 v)
-{
-   __asm vec4_seq __retVal.xy, u, v;
-}
-
-bvec3 equal(const ivec3 u, const ivec3 v)
-{
-   __asm vec4_seq __retVal.xyz, u, v;
-}
-
-bvec4 equal(const ivec4 u, const ivec4 v)
-{
-   __asm vec4_seq __retVal, u, v;
-}
-
-bvec2 equal(const bvec2 u, const bvec2 v)
-{
-   __asm vec4_seq __retVal.xy, u, v;
-}
-
-bvec3 equal(const bvec3 u, const bvec3 v)
-{
-   __asm vec4_seq __retVal.xyz, u, v;
-}
-
-bvec4 equal(const bvec4 u, const bvec4 v)
-{
-   __asm vec4_seq __retVal, u, v;
-}
-
-
-
-
-//// notEqual
-
-bvec2 notEqual(const vec2 u, const vec2 v)
-{
-   __asm vec4_sne __retVal.xy, u, v;
-}
-
-bvec3 notEqual(const vec3 u, const vec3 v)
-{
-   __asm vec4_sne __retVal.xyz, u, v;
-}
-
-bvec4 notEqual(const vec4 u, const vec4 v)
-{
-   __asm vec4_sne __retVal, u, v;
-}
-
-bvec2 notEqual(const ivec2 u, const ivec2 v)
-{
-   __asm vec4_sne __retVal.xy, u, v;
-}
-
-bvec3 notEqual(const ivec3 u, const ivec3 v)
-{
-   __asm vec4_sne __retVal.xyz, u, v;
-}
-
-bvec4 notEqual(const ivec4 u, const ivec4 v)
-{
-   __asm vec4_sne __retVal, u, v;
-}
-
-bvec2 notEqual(const bvec2 u, const bvec2 v)
-{
-   __asm vec4_sne __retVal.xy, u, v;
-}
-
-bvec3 notEqual(const bvec3 u, const bvec3 v)
-{
-   __asm vec4_sne __retVal.xyz, u, v;
-}
-
-bvec4 notEqual(const bvec4 u, const bvec4 v)
-{
-   __asm vec4_sne __retVal, u, v;
-}
-
-
-
-//// any
-
-bool any(const bvec2 v)
-{
-   float sum;
-   __asm vec4_add sum.x, v.x, v.y;
-   __asm vec4_sne __retVal.x, sum.x, 0.0;
-}
-
-bool any(const bvec3 v)
-{
-   float sum;
-   __asm vec4_add sum.x, v.x, v.y;
-   __asm vec4_add sum.x, sum.x, v.z;
-   __asm vec4_sne __retVal.x, sum.x, 0.0;
-}
-
-bool any(const bvec4 v)
-{
-   float sum;
-   __asm vec4_add sum.x, v.x, v.y;
-   __asm vec4_add sum.x, sum.x, v.z;
-   __asm vec4_add sum.x, sum.x, v.w;
-   __asm vec4_sne __retVal.x, sum.x, 0.0;
-}
-
-
-//// all
-
-bool all (const bvec2 v)
-{
-   float prod;
-   __asm vec4_multiply prod, v.x, v.y;
-   __asm vec4_sne __retVal, prod, 0.0;
-}
-
-bool all (const bvec3 v)
-{
-   float prod;
-   __asm vec4_multiply prod, v.x, v.y;
-   __asm vec4_multiply prod, prod, v.z;
-   __asm vec4_sne __retVal, prod, 0.0;
-}
-
-bool all (const bvec4 v)
-{
-   float prod;
-   __asm vec4_multiply prod, v.x, v.y;
-   __asm vec4_multiply prod, prod, v.z;
-   __asm vec4_multiply prod, prod, v.w;
-   __asm vec4_sne __retVal, prod, 0.0;
-}
-
-
-
-//// not
-
-bvec2 not (const bvec2 v)
-{
-   __asm vec4_seq __retVal.xy, v, 0.0;
-}
-
-bvec3 not (const bvec3 v)
-{
-   __asm vec4_seq __retVal.xyz, v, 0.0;
-}
-
-bvec4 not (const bvec4 v)
-{
-   __asm vec4_seq __retVal, v, 0.0;
-}
-
-
-
-//// Texture Lookup Functions  (for both fragment and vertex shaders)
-
-vec4 texture1D(const sampler1D sampler, const float coord)
-{
-   __asm vec4_tex_1d __retVal, sampler, coord;
-}
-
-vec4 texture1DProj(const sampler1D sampler, const vec2 coord)
-{
-   // need to swizzle .y into .w
-   __asm vec4_tex_1d_proj __retVal, sampler, coord.xyyy;
-}
-
-vec4 texture1DProj(const sampler1D sampler, const vec4 coord)
-{
-   __asm vec4_tex_1d_proj __retVal, sampler, coord;
-}
-
-
-vec4 texture2D(const sampler2D sampler, const vec2 coord)
-{
-   __asm vec4_tex_2d __retVal, sampler, coord;
-}
-
-vec4 texture2DProj(const sampler2D sampler, const vec3 coord)
-{
-   // need to swizzle 'z' into 'w'.
-   __asm vec4_tex_2d_proj __retVal, sampler, coord.xyzz;
-}
-
-vec4 texture2DProj(const sampler2D sampler, const vec4 coord)
-{
-   __asm vec4_tex_2d_proj __retVal, sampler, coord;
-}
-
-
-vec4 texture3D(const sampler3D sampler, const vec3 coord)
-{
-   __asm vec4_tex_3d __retVal, sampler, coord;
-}
-
-vec4 texture3DProj(const sampler3D sampler, const vec4 coord)
-{
-   __asm vec4_tex_3d_proj __retVal, sampler, coord;
-}
-
-
-vec4 textureCube(const samplerCube sampler, const vec3 coord)
-{
-   __asm vec4_tex_cube __retVal, sampler, coord;
-}
-
-
-
-vec4 shadow1D(const sampler1DShadow sampler, const vec3 coord)
-{
-   __asm vec4_tex_1d_shadow __retVal, sampler, coord;
-}
-
-vec4 shadow1DProj(const sampler1DShadow sampler, const vec4 coord)
-{
-   // .s and .p will be divided by .q
-   __asm vec4_tex_1d_proj_shadow __retVal, sampler, coord;
-}
-
-vec4 shadow2D(const sampler2DShadow sampler, const vec3 coord)
-{
-   __asm vec4_tex_2d_shadow __retVal, sampler, coord;
-}
-
-vec4 shadow2DProj(const sampler2DShadow sampler, const vec4 coord)
-{
-   // .s, .t and .p will be divided by .q
-   __asm vec4_tex_2d_proj_shadow __retVal, sampler, coord;
-}
-
-
-//// GL_ARB_texture_rectangle:
-vec4 texture2DRect(const sampler2DRect sampler, const vec2 coord)
-{
-   __asm vec4_tex_rect __retVal, sampler, coord;
-}
-
-vec4 texture2DRectProj(const sampler2DRect sampler, const vec3 coord)
-{
-   // need to swizzle .y into .w
-   __asm vec4_tex_rect_proj __retVal, sampler, coord.xyzz;
-}
-
-vec4 texture2DRectProj(const sampler2DRect sampler, const vec4 coord)
-{
-   __asm vec4_tex_rect_proj __retVal, sampler, ccoord;
-}
-
-vec4 shadow2DRect(const sampler2DRectShadow sampler, const vec3 coord)
-{
-   __asm vec4_tex_rect_shadow __retVal, sampler, coord;
-}
-
-vec4 shadow2DRectProj(const sampler2DRectShadow sampler, const vec4 coord)
-{
-   __asm vec4_tex_rect_proj_shadow __retVal, sampler, coord;
-}
-
-
-
-//// GL_EXT_texture_array
-vec4 texture1DArray(const sampler1DArray sampler, const vec2 coord)
-{
-   __asm vec4_tex_1d_array __retVal, sampler, coord;
-}
-
-vec4 texture2DArray(const sampler2DArray sampler, const vec3 coord)
-{
-   __asm vec4_tex_2d_array __retVal, sampler, coord;
-}
-
-
-//
-// 8.9 Noise Functions
-//
-// AUTHOR: Stefan Gustavson (stegu@itn.liu.se), Nov 26, 2005
-//
-
-float noise1(const float x)
-{
-   __asm float_noise1 __retVal, x;
-}
-
-
-float noise1(const vec2 x)
-{
-    __asm float_noise2 __retVal, x;
-}
-
-float noise1(const vec3 x)
-{
-    __asm float_noise3 __retVal, x;
-}
-
-float noise1(const vec4 x)
-{
-    __asm float_noise4 __retVal, x;
-}
-
-vec2 noise2(const float x)
-{
-   __retVal.x = noise1(x);
-   __retVal.y = noise1(x + 19.34);
-}
-
-vec2 noise2(const vec2 x)
-{
-   __retVal.x = noise1(x);
-   __retVal.y = noise1(x + vec2(19.34, 7.66));
-}
-
-vec2 noise2(const vec3 x)
-{
-   __retVal.x = noise1(x);
-   __retVal.y = noise1(x + vec3(19.34, 7.66, 3.23));
-}
-
-vec2 noise2(const vec4 x)
-{
-   __retVal.x = noise1(x);
-   __retVal.y = noise1(x + vec4(19.34, 7.66, 3.23, 2.77));
-}
-
-vec3 noise3(const float x)
-{
-   __retVal.x = noise1(x);
-   __retVal.y = noise1(x + 19.34);
-   __retVal.z = noise1(x + 5.47);
-}
-
-vec3 noise3(const vec2 x)
-{
-   __retVal.x = noise1(x);
-   __retVal.y = noise1(x + vec2(19.34, 7.66));
-   __retVal.z = noise1(x + vec2(5.47, 17.85));
-}
-
-vec3 noise3(const vec3 x)
-{
-   __retVal.x = noise1(x);
-   __retVal.y = noise1(x + vec3(19.34, 7.66, 3.23));
-   __retVal.z = noise1(x + vec3(5.47, 17.85, 11.04));
-}
-
-vec3 noise3(const vec4 x)
-{
-   __retVal.x = noise1(x);
-   __retVal.y = noise1(x + vec4(19.34, 7.66, 3.23, 2.77));
-   __retVal.z = noise1(x + vec4(5.47, 17.85, 11.04, 13.19));
-}
-
-vec4 noise4(const float x)
-{
-   __retVal.x = noise1(x);
-   __retVal.y = noise1(x + 19.34);
-   __retVal.z = noise1(x + 5.47);
-   __retVal.w = noise1(x + 23.54);
-}
-
-vec4 noise4(const vec2 x)
-{
-   __retVal.x = noise1(x);
-   __retVal.y = noise1(x + vec2 (19.34, 7.66));
-   __retVal.z = noise1(x + vec2 (5.47, 17.85));
-   __retVal.w = noise1(x + vec2 (23.54, 29.11));
-}
-
-vec4 noise4(const vec3 x)
-{
-   __retVal.x = noise1(x);
-   __retVal.y = noise1(x + vec3(19.34, 7.66, 3.23));
-   __retVal.z = noise1(x + vec3(5.47, 17.85, 11.04));
-   __retVal.w = noise1(x + vec3(23.54, 29.11, 31.91));
-}
-
-vec4 noise4(const vec4 x)
-{
-   __retVal.x = noise1(x);
-   __retVal.y = noise1(x + vec4(19.34, 7.66, 3.23, 2.77));
-   __retVal.z = noise1(x + vec4(5.47, 17.85, 11.04, 13.19));
-   __retVal.w = noise1(x + vec4(23.54, 29.11, 31.91, 37.48));
-}
diff --git a/src/mesa/shader/slang/library/slang_core.gc b/src/mesa/shader/slang/library/slang_core.gc
deleted file mode 100644 (file)
index 0a0d159..0000000
+++ /dev/null
@@ -1,2619 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5
- *
- * Copyright (C) 2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-//
-// This file defines nearly all constructors and operators for built-in data
-// types, using extended language syntax. In general, compiler treats
-// constructors and operators as ordinary functions with some exceptions.
-// For example, the language does not allow functions to be called in
-// constant expressions - here the exception is made to allow it.
-//
-// Each implementation provides its own version of this file. Each
-// implementation can define the required set of operators and constructors
-// in its own fashion.
-//
-// The extended language syntax is only present when compiling this file.
-// It is implicitly included at the very beginning of the compiled shader,
-// so no built-in functions can be used.
-//
-// To communicate with the implementation, a special extended "__asm" keyword
-// is used, followed by an instruction name (any valid identifier), a
-// destination variable identifier and a list of zero or more source
-// variable identifiers.
-//
-// A variable identifier is a variable name declared earlier in the code
-// (as a function parameter, local or global variable).
-//
-// An instruction name designates an instruction that must be exported
-// by the implementation.  Each instruction receives data from source
-// variable identifiers and returns data in the destination variable
-// identifier.
-//
-// It is up to the implementation how to define a particular operator
-// or constructor. If it is expected to being used rarely, it can be
-// defined in terms of other operators and constructors,
-// for example:
-//
-// ivec2 __operator + (const ivec2 x, const ivec2 y) {
-//    return ivec2 (x[0] + y[0], x[1] + y[1]);
-// }
-//
-// If a particular operator or constructor is expected to be used very
-// often or is an atomic operation (that is, an operation that cannot be
-// expressed in terms of other operations or would create a dependency
-// cycle) it must be defined using one or more __asm constructs.
-//
-// Each implementation must define constructors for all scalar types
-// (bool, float, int).  There are 9 scalar-to-scalar constructors
-// (including identity constructors). However, since the language
-// introduces special constructors (like matrix constructor with a single
-// scalar value), implementations must also implement these cases.
-// The compiler provides the following algorithm when resolving a constructor:
-// - try to find a constructor with a prototype matching ours,
-// - if no constructor is found and this is a scalar-to-scalar constructor,
-//   raise an error,
-// - if a constructor is found, execute it and return,
-// - count the size of the constructor parameter list - if it is less than
-//   the size of our constructor's type, raise an error,
-// - for each parameter in the list do a recursive constructor matching for
-//   appropriate scalar fields in the constructed variable,
-//
-// Each implementation must also define a set of operators that deal with
-// built-in data types.
-// There are four kinds of operators:
-// 1) Operators that are implemented only by the compiler: "()" (function
-//    call), "," (sequence) and "?:" (selection).
-// 2) Operators that are implemented by the compiler by expressing it in
-//    terms of other operators:
-//    - "." (field selection) - translated to subscript access,
-//    - "&&" (logical and) - translated to "<left_expr> ? <right_expr> :
-//      false",
-//    - "||" (logical or) - translated to "<left_expr> ? true : <right_expr>",
-// 3) Operators that can be defined by the implementation and if the required
-//    prototype is not found, standard behaviour is used:
-//    - "==", "!=", "=" (equality, assignment) - compare or assign
-//      matching fields one-by-one;
-//      note that at least operators for scalar data types must be defined
-//      by the implementation to get it work,
-// 4) All other operators not mentioned above. If no required prototype is
-//    found, an error is raised. An implementation must follow the language
-//    specification to provide all valid operator prototypes.
-//
-
-
-
-//// Basic, scalar constructors/casts
-
-int __constructor(const float f)
-{
-   __asm vec4_to_ivec4 __retVal, f;
-}
-
-int __constructor(const bool b)
-{
-   __retVal = b;
-}
-
-int __constructor(const int i)
-{
-   __retVal = i;
-}
-
-bool __constructor(const int i)
-{
-   __asm vec4_sne __retVal, i, 0.0;
-}
-
-bool __constructor(const float f)
-{
-   __asm vec4_sne __retVal, f, 0.0;
-}
-
-bool __constructor(const bool b)
-{
-   __retVal = b;
-}
-
-float __constructor(const int i)
-{
-    __asm ivec4_to_vec4 __retVal, i;
-}
-
-float __constructor(const bool b)
-{
-    __asm ivec4_to_vec4 __retVal, b;
-}
-
-float __constructor(const float f)
-{
-   __retVal = f;
-}
-
-
-//// vec2 constructors
-
-vec2 __constructor(const float x, const float y)
-{
-   __retVal.x = x;
-   __retVal.y = y;
-}
-
-vec2 __constructor(const float f)
-{
-   __asm vec4_move __retVal.xy, f;
-}
-
-vec2 __constructor(const int i)
-{
-   __asm ivec4_to_vec4 __retVal.xy, i;
-}
-
-vec2 __constructor(const bool b)
-{
-   __asm ivec4_to_vec4 __retVal.xy, b;
-}
-
-vec2 __constructor(const bvec2 b)
-{
-//   __retVal = b;
-   __asm ivec4_to_vec4 __retVal.xy, b;
-}
-
-vec2 __constructor(const vec3 v)
-{
-   __asm vec4_move __retVal.xy, v.xy;
-}
-
-vec2 __constructor(const vec4 v)
-{
-   __asm vec4_move __retVal.xy, v.xy;
-}
-
-
-//// vec3 constructors
-
-vec3 __constructor(const float x, const float y, const float z)
-{
-   __retVal.x = x;
-   __retVal.y = y;
-   __retVal.z = z;
-}
-
-vec3 __constructor(const float f)
-{
-   // Note: this could be "__retVal.xyz = f" but that's an illegal assignment
-   __asm vec4_move __retVal.xyz, f;
-}
-
-vec3 __constructor(const int i)
-{
-   __asm ivec4_to_vec4 __retVal.xyz, i;
-}
-
-vec3 __constructor(const bool b)
-{
-   __asm ivec4_to_vec4 __retVal.xyz, b;
-}
-
-vec3 __constructor(const bvec3 b)
-{
-   __asm ivec4_to_vec4 __retVal.xyz, b;
-}
-
-vec3 __constructor(const vec4 v)
-{
-   __asm vec4_move __retVal.xyz, v;
-}
-
-
-//// vec4 constructors
-
-vec4 __constructor(const float x, const float y, const float z, const float w)
-{
-   __retVal.x = x;
-   __retVal.y = y;
-   __retVal.z = z;
-   __retVal.w = w;
-}
-
-vec4 __constructor(const float f)
-{
-   // Note: this could be "__retVal = f" but that's an illegal assignment
-   __asm vec4_move __retVal, f;
-}
-
-vec4 __constructor(const int i)
-{
-   __asm ivec4_to_vec4 __retVal, i;
-}
-
-vec4 __constructor(const bool b)
-{
-   __asm ivec4_to_vec4 __retVal, b;
-}
-
-vec4 __constructor(const bvec4 b)
-{
-   __asm ivec4_to_vec4 __retVal, b;
-}
-
-vec4 __constructor(const ivec4 i)
-{
-   __asm ivec4_to_vec4 __retVal, i;
-}
-
-vec4 __constructor(const vec3 v3, const float f)
-{
-   // XXX this constructor shouldn't be needed anymore
-   __retVal.xyz = v3;
-   __retVal.w = f;
-}
-
-vec4 __constructor(const vec2 v2, const float f1, const float f2)
-{
-   // XXX this constructor shouldn't be needed anymore
-   __retVal.xy = v2;
-   __retVal.z = f1;
-   __retVal.w = f2;
-}
-
-
-//// ivec2 constructors
-
-ivec2 __constructor(const int i, const int j)
-{
-   __retVal.x = i;
-   __retVal.y = j;
-}
-
-ivec2 __constructor(const int i)
-{
-   __asm vec4_move __retVal.xy, i;
-}
-
-ivec2 __constructor(const float f)
-{
-   __asm vec4_to_ivec4 __retVal.xy, f;
-}
-
-ivec2 __constructor(const bool b)
-{
-   __asm vec4_to_ivec4 __retVal.xy, b;
-}
-
-
-//// ivec3 constructors
-
-ivec3 __constructor(const int i, const int j, const int k)
-{
-   __retVal.x = i;
-   __retVal.y = j;
-   __retVal.z = k;
-}
-
-ivec3 __constructor(const int i)
-{
-   __asm vec4_move __retVal.xyz, i;
-}
-
-ivec3 __constructor(const float f)
-{
-   __asm vec4_to_ivec4 __retVal.xyz, f;
-}
-
-ivec3 __constructor(const bool b)
-{
-   __asm vec4_move __retVal.xyz, b;
-}
-
-
-//// ivec4 constructors
-
-ivec4 __constructor(const int x, const int y, const int z, const int w)
-{
-   __retVal.x = x;
-   __retVal.y = y;
-   __retVal.z = z;
-   __retVal.w = w;
-}
-
-ivec4 __constructor(const int i)
-{
-   __asm vec4_move __retVal, i;
-}
-
-ivec4 __constructor(const float f)
-{
-   __asm vec4_to_ivec4 __retVal, f;
-}
-
-ivec4 __constructor(const bool b)
-{
-   __asm vec4_to_ivec4 __retVal, b;
-}
-
-
-//// bvec2 constructors
-
-bvec2 __constructor(const bool b1, const bool b2)
-{
-   __retVal.x = b1;
-   __retVal.y = b2;
-}
-
-bvec2 __constructor(const int i1, const int i2)
-{
-   __asm vec4_sne __retVal.x, i1, 0.0;
-   __asm vec4_sne __retVal.y, i2, 0.0;
-}
-
-
-bvec2 __constructor(const bool b)
-{
-   __asm vec4_move __retVal.xy, b;
-}
-
-bvec2 __constructor(const float f)
-{
-   __asm vec4_sne __retVal.xy, f, 0.0;
-}
-
-bvec2 __constructor(const int i)
-{
-   __asm vec4_sne __retVal.xy, i, 0.0;
-}
-
-bvec2 __constructor(const vec2 v)
-{
-   __asm vec4_sne __retVal.xy, v, 0.0;
-}
-
-bvec2 __constructor(const ivec2 v)
-{
-   __asm vec4_sne __retVal.xy, v, 0.0;
-}
-
-
-
-//// bvec3 constructors
-
-bvec3 __constructor(const bool b1, const bool b2, const bool b3)
-{
-   __retVal.x = b1;
-   __retVal.y = b2;
-   __retVal.z = b3;
-}
-
-bvec3 __constructor(const float f1, const float f2, const float f3)
-{
-   __asm vec4_sne __retVal.x, f1, 0.0;
-   __asm vec4_sne __retVal.y, f2, 0.0;
-   __asm vec4_sne __retVal.z, f3, 0.0;
-}
-
-bvec3 __constructor(const bool b)
-{
-   __asm vec4_move __retVal.xyz, b;
-}
-
-bvec3 __constructor(const float f)
-{
-   __asm vec4_sne __retVal.xyz, f, 0.0;
-}
-
-bvec3 __constructor(const int i)
-{
-   __asm vec4_sne __retVal.xyz, i, 0.0;
-}
-
-bvec3 __constructor(const vec3 v)
-{
-   __asm vec4_sne __retVal.xyz, v, 0.0;
-}
-
-bvec3 __constructor(const ivec3 v)
-{
-   __asm vec4_sne __retVal.xyz, v, 0.0;
-}
-
-
-
-//// bvec4 constructors
-
-bvec4 __constructor(const bool b1, const bool b2, const bool b3, const bool b4)
-{
-   __retVal.x = b1;
-   __retVal.y = b2;
-   __retVal.z = b3;
-   __retVal.w = b4;
-}
-
-bvec4 __constructor(const float f1, const float f2, const float f3, const float f4)
-{
-   const float zero = 0.0;
-   __asm vec4_sne __retVal.x, f1, zero;   
-   __asm vec4_sne __retVal.y, f2, zero;   
-   __asm vec4_sne __retVal.z, f3, zero;   
-   __asm vec4_sne __retVal.w, f4, zero;   
-}
-
-bvec4 __constructor(const bool b)
-{
-   __asm vec4_move __retVal.xyzw, b;
-}
-
-bvec4 __constructor(const float f)
-{
-   __asm vec4_sne __retVal.xyzw, f, 0.0;
-}
-
-bvec4 __constructor(const int i)
-{
-   __asm vec4_sne __retVal.xyzw, i, 0.0;
-}
-
-bvec4 __constructor(const vec4 v)
-{
-   __asm vec4_sne __retVal.xyzw, v, 0.0;
-}
-
-bvec4 __constructor(const ivec4 v)
-{
-   __asm vec4_sne __retVal.xyzw, v, 0.0;
-}
-
-
-
-//// mat2 constructors
-
-mat2 __constructor(const float m00, const float m10,
-                   const float m01, const float m11)
-{
-   __retVal[0].x = m00;
-   __retVal[0].y = m10;
-   __retVal[1].x = m01;
-   __retVal[1].y = m11;
-}
-
-mat2 __constructor(const float f)
-{
-   __retVal[0].x = f;
-   __retVal[0].y = 0.0;
-   __retVal[1].x = 0.0;
-   __retVal[1].y = f;
-}
-
-mat2 __constructor(const int i)
-{
-   return mat2(float(i));
-}
-
-mat2 __constructor(const bool b)
-{
-   return mat2(float(b));
-}
-
-mat2 __constructor(const vec2 c0, const vec2 c1)
-{
-   __retVal[0] = c0;
-   __retVal[1] = c1;
-}
-
-
-//// mat3 constructors
-
-mat3 __constructor(const float m00, const float m10, const float m20,
-                   const float m01, const float m11, const float m21,
-                   const float m02, const float m12, const float m22)
-{
-   __retVal[0].x = m00;
-   __retVal[0].y = m10;
-   __retVal[0].z = m20;
-   __retVal[1].x = m01;
-   __retVal[1].y = m11;
-   __retVal[1].z = m21;
-   __retVal[2].x = m02;
-   __retVal[2].y = m12;
-   __retVal[2].z = m22;
-}
-
-mat3 __constructor(const float f)
-{
-   vec2 v = vec2(f, 0.0);
-   __retVal[0] = v.xyy;
-   __retVal[1] = v.yxy;
-   __retVal[2] = v.yyx;
-}
-
-mat3 __constructor(const int i)
-{
-   return mat3(float(i));
-}
-
-mat3 __constructor(const bool b)
-{
-   return mat3(float(b));
-}
-
-mat3 __constructor(const vec3 c0, const vec3 c1, const vec3 c2)
-{
-   __retVal[0] = c0;
-   __retVal[1] = c1;
-   __retVal[2] = c2;
-}
-
-
-//// mat4 constructors
-
-mat4 __constructor(const float m00, const float m10, const float m20, const float m30,
-                   const float m01, const float m11, const float m21, const float m31,
-                   const float m02, const float m12, const float m22, const float m32,
-                   const float m03, const float m13, const float m23, const float m33)
-{
-   __retVal[0].x = m00;
-   __retVal[0].y = m10;
-   __retVal[0].z = m20;
-   __retVal[0].w = m30;
-   __retVal[1].x = m01;
-   __retVal[1].y = m11;
-   __retVal[1].z = m21;
-   __retVal[1].w = m31;
-   __retVal[2].x = m02;
-   __retVal[2].y = m12;
-   __retVal[2].z = m22;
-   __retVal[2].w = m32;
-   __retVal[3].x = m03;
-   __retVal[3].y = m13;
-   __retVal[3].z = m23;
-   __retVal[3].w = m33;
-}
-
-
-mat4 __constructor(const float f)
-{
-   vec2 v = vec2(f, 0.0);
-   __retVal[0] = v.xyyy;
-   __retVal[1] = v.yxyy;
-   __retVal[2] = v.yyxy;
-   __retVal[3] = v.yyyx;
-}
-
-mat4 __constructor(const int i)
-{
-   return mat4(float(i));
-}
-
-mat4 __constructor(const bool b)
-{
-   return mat4(float(b));
-}
-
-mat4 __constructor(const vec4 c0, const vec4 c1, const vec4 c2, const vec4 c3)
-{
-   __retVal[0] = c0;
-   __retVal[1] = c1;
-   __retVal[2] = c2;
-   __retVal[3] = c3;
-}
-
-
-
-//// Basic int operators
-
-int __operator + (const int a, const int b)
-{
-   __asm vec4_add __retVal, a, b;
-}
-
-int __operator - (const int a, const int b)
-{
-   __asm vec4_subtract __retVal, a, b;
-}
-
-int __operator * (const int a, const int b)
-{
-   __asm vec4_multiply __retVal, a, b;
-}
-
-int __operator / (const int a, const int b)
-{
-   float bInv, x;
-   __asm float_rcp bInv, b;
-   __asm vec4_multiply x, a, bInv;
-   __asm vec4_to_ivec4 __retVal, x;
-}
-
-
-//// Basic ivec2 operators
-
-ivec2 __operator + (const ivec2 a, const ivec2 b)
-{
-   __asm vec4_add __retVal, a, b;
-}
-
-ivec2 __operator - (const ivec2 a, const ivec2 b)
-{
-   __asm vec4_subtract __retVal, a, b;
-}
-
-ivec2 __operator * (const ivec2 a, const ivec2 b)
-{
-   __asm vec4_multiply __retVal, a, b;
-}
-
-ivec2 __operator / (const ivec2 a, const ivec2 b)
-{
-   vec2 bInv, x;
-   __asm float_rcp bInv.x, b.x;
-   __asm float_rcp bInv.y, b.y;
-   __asm vec4_multiply x, a, bInv;
-   __asm vec4_to_ivec4 __retVal, x;
-}
-
-
-//// Basic ivec3 operators
-
-ivec3 __operator + (const ivec3 a, const ivec3 b)
-{
-   __asm vec4_add __retVal, a, b;
-}
-
-ivec3 __operator - (const ivec3 a, const ivec3 b)
-{
-   __asm vec4_subtract __retVal, a, b;
-}
-
-ivec3 __operator * (const ivec3 a, const ivec3 b)
-{
-   __asm vec4_multiply __retVal, a, b;
-}
-
-ivec3 __operator / (const ivec3 a, const ivec3 b)
-{
-   vec3 bInv, x;
-   __asm float_rcp bInv.x, b.x;
-   __asm float_rcp bInv.y, b.y;
-   __asm float_rcp bInv.z, b.z;
-   __asm vec4_multiply x, a, bInv;
-   __asm vec4_to_ivec4 __retVal, x;
-}
-
-
-//// Basic ivec4 operators
-
-ivec4 __operator + (const ivec4 a, const ivec4 b)
-{
-   __asm vec4_add __retVal, a, b;
-}
-
-ivec4 __operator - (const ivec4 a, const ivec4 b)
-{
-   __asm vec4_subtract __retVal, a, b;
-}
-
-ivec4 __operator * (const ivec4 a, const ivec4 b)
-{
-   __asm vec4_multiply __retVal, a, b;
-}
-
-ivec4 __operator / (const ivec4 a, const ivec4 b)
-{
-   vec4 bInv, x;
-   __asm float_rcp bInv.x, b.x;
-   __asm float_rcp bInv.y, b.y;
-   __asm float_rcp bInv.z, b.z;
-   __asm float_rcp bInv.w, b.w;
-   __asm vec4_multiply x, a, bInv;
-   __asm vec4_to_ivec4 __retVal, x;
-}
-
-
-//// Basic float operators
-
-float __operator + (const float a, const float b)
-{
-   __asm vec4_add __retVal, a, b;
-}
-
-float __operator - (const float a, const float b)
-{
-   __asm vec4_subtract __retVal, a, b;
-}
-
-float __operator * (const float a, const float b)
-{
-    __asm vec4_multiply __retVal, a, b;
-}
-
-float __operator / (const float a, const float b)
-{
-   float bInv;
-   __asm float_rcp bInv.x, b;
-   __asm vec4_multiply __retVal, a, bInv;
-}
-
-
-//// Basic vec2 operators
-
-vec2 __operator + (const vec2 v, const vec2 u)
-{
-   __asm vec4_add __retVal.xy, v, u;
-}
-
-vec2 __operator - (const vec2 v, const vec2 u)
-{
-    __asm vec4_subtract __retVal.xy, v, u;
-}
-
-vec2 __operator * (const vec2 v, const vec2 u)
-{
-    __asm vec4_multiply __retVal.xy, v, u;
-}
-
-vec2 __operator / (const vec2 v, const vec2 u)
-{
-   vec2 w; // = 1 / u
-   __asm float_rcp w.x, u.x;
-   __asm float_rcp w.y, u.y;
-   __asm vec4_multiply __retVal.xy, v, w;
-}
-
-
-//// Basic vec3 operators
-
-vec3 __operator + (const vec3 v, const vec3 u)
-{
-   __asm vec4_add __retVal.xyz, v, u;
-}
-
-vec3 __operator - (const vec3 v, const vec3 u)
-{
-    __asm vec4_subtract __retVal.xyz, v, u;
-}
-
-vec3 __operator * (const vec3 v, const vec3 u)
-{
-    __asm vec4_multiply __retVal.xyz, v, u;
-}
-
-vec3 __operator / (const vec3 v, const vec3 u)
-{
-   vec3 w; // = 1 / u
-   __asm float_rcp w.x, u.x;
-   __asm float_rcp w.y, u.y;
-   __asm float_rcp w.z, u.z;
-   __asm vec4_multiply __retVal.xyz, v, w;
-}
-
-
-//// Basic vec4 operators
-
-vec4 __operator + (const vec4 v, const vec4 u)
-{
-   __asm vec4_add __retVal, v, u;
-}
-
-vec4 __operator - (const vec4 v, const vec4 u)
-{
-    __asm vec4_subtract __retVal, v, u;
-}
-
-vec4 __operator * (const vec4 v, const vec4 u)
-{
-    __asm vec4_multiply __retVal, v, u;
-}
-
-vec4 __operator / (const vec4 v, const vec4 u)
-{
-   vec4 w; // = 1 / u
-   __asm float_rcp w.x, u.x;
-   __asm float_rcp w.y, u.y;
-   __asm float_rcp w.z, u.z;
-   __asm float_rcp w.w, u.w;
-   __asm vec4_multiply __retVal, v, w;
-}
-
-
-
-
-//// Basic vec2/float operators
-
-vec2 __operator + (const float a, const vec2 u)
-{
-   __asm vec4_add __retVal.xy, a, u.xy;
-}
-
-vec2 __operator + (const vec2 v, const float b)
-{
-   __asm vec4_add __retVal.xy, v.xy, b;
-}
-
-vec2 __operator - (const float a, const vec2 u)
-{
-   __asm vec4_subtract __retVal.xy, a, u.xy;
-}
-
-vec2 __operator - (const vec2 v, const float b)
-{
-   __asm vec4_subtract __retVal.xy, v.xy, b;
-}
-
-vec2 __operator * (const float a, const vec2 u)
-{
-   __asm vec4_multiply __retVal.xy, a, u.xy;
-}
-
-vec2 __operator * (const vec2 v, const float b)
-{
-   __asm vec4_multiply __retVal.xy, v.xy, b;
-}
-
-vec2 __operator / (const float a, const vec2 u)
-{
-   vec2 invU;
-   __asm float_rcp invU.x, u.x;
-   __asm float_rcp invU.y, u.y;
-   __asm vec4_multiply __retVal.xy, a, invU.xy;
-}
-
-vec2 __operator / (const vec2 v, const float b)
-{
-   float invB;
-   __asm float_rcp invB, b;
-   __asm vec4_multiply __retVal.xy, v.xy, invB;
-}
-
-
-//// Basic vec3/float operators
-
-vec3 __operator + (const float a, const vec3 u)
-{
-   __asm vec4_add __retVal.xyz, a, u.xyz;
-}
-
-vec3 __operator + (const vec3 v, const float b)
-{
-   __asm vec4_add __retVal.xyz, v.xyz, b;
-}
-
-vec3 __operator - (const float a, const vec3 u)
-{
-   __asm vec4_subtract __retVal.xyz, a, u.xyz;
-}
-
-vec3 __operator - (const vec3 v, const float b)
-{
-   __asm vec4_subtract __retVal.xyz, v.xyz, b;
-}
-
-vec3 __operator * (const float a, const vec3 u)
-{
-   __asm vec4_multiply __retVal.xyz, a, u.xyz;
-}
-
-vec3 __operator * (const vec3 v, const float b)
-{
-   __asm vec4_multiply __retVal.xyz, v.xyz, b;
-}
-
-vec3 __operator / (const float a, const vec3 u)
-{
-   vec3 invU;
-   __asm float_rcp invU.x, u.x;
-   __asm float_rcp invU.y, u.y;
-   __asm float_rcp invU.z, u.z;
-   __asm vec4_multiply __retVal.xyz, a, invU.xyz;
-}
-
-vec3 __operator / (const vec3 v, const float b)
-{
-   float invB;
-   __asm float_rcp invB, b;
-   __asm vec4_multiply __retVal.xyz, v.xyz, invB;
-}
-
-
-//// Basic vec4/float operators
-
-vec4 __operator + (const float a, const vec4 u)
-{
-   __asm vec4_add __retVal, a, u;
-}
-
-vec4 __operator + (const vec4 v, const float b)
-{
-   __asm vec4_add __retVal, v, b;
-}
-
-vec4 __operator - (const float a, const vec4 u)
-{
-   __asm vec4_subtract __retVal, a, u;
-}
-
-vec4 __operator - (const vec4 v, const float b)
-{
-   __asm vec4_subtract __retVal, v, b;
-}
-
-vec4 __operator * (const float a, const vec4 u)
-{
-   __asm vec4_multiply __retVal, a, u;
-}
-
-vec4 __operator * (const vec4 v, const float b)
-{
-   __asm vec4_multiply __retVal, v, b;
-}
-
-vec4 __operator / (const float a, const vec4 u)
-{
-   vec4 invU;
-   __asm float_rcp invU.x, u.x;
-   __asm float_rcp invU.y, u.y;
-   __asm float_rcp invU.z, u.z;
-   __asm float_rcp invU.w, u.w;
-   __asm vec4_multiply __retVal, a, invU;
-}
-
-vec4 __operator / (const vec4 v, const float b)
-{
-   float invB;
-   __asm float_rcp invB, b;
-   __asm vec4_multiply __retVal, v, invB;
-}
-
-
-
-//// Basic ivec2/int operators
-
-ivec2 __operator + (const int a, const ivec2 u)
-{
-   __retVal = ivec2(a) + u;
-}
-
-ivec2 __operator + (const ivec2 v, const int b)
-{
-   __retVal = v + ivec2(b);
-}
-
-ivec2 __operator - (const int a, const ivec2 u)
-{
-   __retVal = ivec2(a) - u;
-}
-
-ivec2 __operator - (const ivec2 v, const int b)
-{
-   __retVal = v - ivec2(b);
-}
-
-ivec2 __operator * (const int a, const ivec2 u)
-{
-   __retVal = ivec2(a) * u;
-}
-
-ivec2 __operator * (const ivec2 v, const int b)
-{
-   __retVal = v * ivec2(b);
-}
-
-ivec2 __operator / (const int a, const ivec2 u)
-{
-   __retVal = ivec2(a) / u;
-}
-
-ivec2 __operator / (const ivec2 v, const int b)
-{
-   __retVal = v / ivec2(b);
-}
-
-
-//// Basic ivec3/int operators
-
-ivec3 __operator + (const int a, const ivec3 u)
-{
-   __retVal = ivec3(a) + u;
-}
-
-ivec3 __operator + (const ivec3 v, const int b)
-{
-   __retVal = v + ivec3(b);
-}
-
-ivec3 __operator - (const int a, const ivec3 u)
-{
-   __retVal = ivec3(a) - u;
-}
-
-ivec3 __operator - (const ivec3 v, const int b)
-{
-   __retVal = v - ivec3(b);
-}
-
-ivec3 __operator * (const int a, const ivec3 u)
-{
-   __retVal = ivec3(a) * u;
-}
-
-ivec3 __operator * (const ivec3 v, const int b)
-{
-   __retVal = v * ivec3(b);
-}
-
-ivec3 __operator / (const int a, const ivec3 u)
-{
-   __retVal = ivec3(a) / u;
-}
-
-ivec3 __operator / (const ivec3 v, const int b)
-{
-   __retVal = v / ivec3(b);
-}
-
-
-//// Basic ivec4/int operators
-
-ivec4 __operator + (const int a, const ivec4 u)
-{
-   __retVal = ivec4(a) + u;
-}
-
-ivec4 __operator + (const ivec4 v, const int b)
-{
-   __retVal = v + ivec4(b);
-}
-
-ivec4 __operator - (const int a, const ivec4 u)
-{
-   __retVal = ivec4(a) - u;
-}
-
-ivec4 __operator - (const ivec4 v, const int b)
-{
-   __retVal = v - ivec4(b);
-}
-
-ivec4 __operator * (const int a, const ivec4 u)
-{
-   __retVal = ivec4(a) * u;
-}
-
-ivec4 __operator * (const ivec4 v, const int b)
-{
-   __retVal = v * ivec4(b);
-}
-
-ivec4 __operator / (const int a, const ivec4 u)
-{
-   __retVal = ivec4(a) / u;
-}
-
-ivec4 __operator / (const ivec4 v, const int b)
-{
-   __retVal = v / ivec4(b);
-}
-
-
-
-
-//// Unary negation operator
-
-int __operator - (const int a)
-{
-   __asm vec4_negate __retVal.x, a;
-}
-
-ivec2 __operator - (const ivec2 v)
-{
-   __asm vec4_negate __retVal, v;
-}
-
-ivec3 __operator - (const ivec3 v)
-{
-   __asm vec4_negate __retVal, v;
-}
-
-ivec4 __operator - (const ivec4 v)
-{
-   __asm vec4_negate __retVal, v;
-}
-
-float __operator - (const float a)
-{
-   __asm vec4_negate __retVal.x, a;
-}
-
-vec2 __operator - (const vec2 v)
-{
-   __asm vec4_negate __retVal.xy, v.xy;
-}
-
-vec3 __operator - (const vec3 v)
-{
-   __asm vec4_negate __retVal.xyz, v.xyz;
-}
-
-vec4 __operator - (const vec4 v)
-{
-   __asm vec4_negate __retVal, v;
-}
-
-mat2 __operator - (const mat2 m)
-{
-   __retVal[0] = -m[0];
-   __retVal[1] = -m[1];
-}
-
-mat3 __operator - (const mat3 m)
-{
-   __retVal[0] = -m[0];
-   __retVal[1] = -m[1];
-   __retVal[2] = -m[2];
-}
-
-mat4 __operator - (const mat4 m)
-{
-   __retVal[0] = -m[0];
-   __retVal[1] = -m[1];
-   __retVal[2] = -m[2];
-   __retVal[3] = -m[3];
-}
-
-
-
-//// dot product
-
-float dot(const float a, const float b)
-{
-   __retVal = a * b;
-}
-
-float dot(const vec2 a, const vec2 b)
-{
-   __retVal = a.x * b.x + a.y * b.y;
-}
-
-float dot(const vec3 a, const vec3 b)
-{
-    __asm vec3_dot __retVal, a, b;
-}
-
-float dot(const vec4 a, const vec4 b)
-{
-    __asm vec4_dot __retVal, a, b;
-}
-
-
-
-//// int assignment operators
-
-int __operator += (inout int a, const int b)
-{
-   a = a + b;
-   return a;
-}
-
-int __operator -= (inout int a, const int b)
-{
-   a = a - b;
-   return a;
-}
-
-int __operator *= (inout int a, const int b)
-{
-   a = a * b;
-   return a;
-}
-
-int __operator /= (inout int a, const int b)
-{
-   a = a / b;
-   return a;
-}
-
-
-//// ivec2 assignment operators
-
-ivec2 __operator += (inout ivec2 v, const ivec2 u)
-{
-   v = v + u;
-   return v;
-}
-
-ivec2 __operator -= (inout ivec2 v, const ivec2 u)
-{
-   v = v - u;
-   return v;
-}
-
-ivec2 __operator *= (inout ivec2 v, const ivec2 u)
-{
-   v = v * u;
-   return v;
-}
-
-ivec2 __operator /= (inout ivec2 v, const ivec2 u)
-{
-   v = v / u;
-   return v;
-}
-
-
-//// ivec3 assignment operators
-
-ivec3 __operator += (inout ivec3 v, const ivec3 u)
-{
-   v = v + u;
-   return v;
-}
-
-ivec3 __operator -= (inout ivec3 v, const ivec3 u)
-{
-   v = v - u;
-   return v;
-}
-
-ivec3 __operator *= (inout ivec3 v, const ivec3 u)
-{
-   v = v * u;
-   return v;
-}
-
-ivec3 __operator /= (inout ivec3 v, const ivec3 u)
-{
-   v = v / u;
-   return v;
-}
-
-
-//// ivec4 assignment operators
-
-ivec4 __operator += (inout ivec4 v, const ivec4 u)
-{
-   v = v + u;
-   return v;
-}
-
-ivec4 __operator -= (inout ivec4 v, const ivec4 u)
-{
-   v = v - u;
-   return v;
-}
-
-ivec4 __operator *= (inout ivec4 v, const ivec4 u)
-{
-   v = v * u;
-   return v;
-}
-
-ivec4 __operator /= (inout ivec4 v, const ivec4 u)
-{
-   v = v / u;
-   return v;
-}
-
-
-//// float assignment operators
-
-float __operator += (inout float a, const float b)
-{
-   a = a + b;
-   return a;
-}
-
-float __operator -= (inout float a, const float b)
-{
-   a = a - b;
-   return a;
-}
-
-float __operator *= (inout float a, const float b)
-{
-   a = a * b;
-   return a;
-}
-
-float __operator /= (inout float a, const float b)
-{
-   a = a / b;
-   return a;
-}
-
-
-//// vec2 assignment operators
-
-vec2 __operator += (inout vec2 v, const vec2 u)
-{
-   v = v + u;
-   return v;
-}
-
-vec2 __operator -= (inout vec2 v, const vec2 u)
-{
-   v = v - u;
-   return v;
-}
-
-vec2 __operator *= (inout vec2 v, const vec2 u)
-{
-   v = v * u;
-   return v;
-}
-
-vec2 __operator /= (inout vec2 v, const vec2 u)
-{
-   v = v / u;
-   return v;
-}
-
-
-//// vec3 assignment operators
-
-vec3 __operator += (inout vec3 v, const vec3 u)
-{
-   v = v + u;
-   return v;
-}
-
-vec3 __operator -= (inout vec3 v, const vec3 u)
-{
-   v = v - u;
-   return v;
-}
-
-vec3 __operator *= (inout vec3 v, const vec3 u)
-{
-   v = v * u;
-   return v;
-}
-
-vec3 __operator /= (inout vec3 v, const vec3 u)
-{
-   v = v / u;
-   return v;
-}
-
-
-//// vec4 assignment operators
-
-vec4 __operator += (inout vec4 v, const vec4 u)
-{
-   v = v + u;
-   return v;
-}
-
-vec4 __operator -= (inout vec4 v, const vec4 u)
-{
-   v = v - u;
-   return v;
-}
-
-vec4 __operator *= (inout vec4 v, const vec4 u)
-{
-   v = v * u;
-   return v;
-}
-
-vec4 __operator /= (inout vec4 v, const vec4 u)
-{
-   v = v / u;
-   return v;
-}
-
-
-
-//// ivec2/int assignment operators
-
-ivec2 __operator += (inout ivec2 v, const int a)
-{
-   v = v + ivec2(a);
-   return v;
-}
-
-ivec2 __operator -= (inout ivec2 v, const int a)
-{
-   v = v - ivec2(a);
-   return v;
-}
-
-ivec2 __operator *= (inout ivec2 v, const int a)
-{
-   v = v * ivec2(a);
-   return v;
-}
-
-ivec2 __operator /= (inout ivec2 v, const int a)
-{
-   v = v / ivec2(a);
-   return v;
-}
-
-
-//// ivec3/int assignment operators
-
-ivec3 __operator += (inout ivec3 v, const int a)
-{
-   v = v + ivec3(a);
-   return v;
-}
-
-ivec3 __operator -= (inout ivec3 v, const int a)
-{
-   v = v - ivec3(a);
-   return v;
-}
-
-ivec3 __operator *= (inout ivec3 v, const int a)
-{
-   v = v * ivec3(a);
-   return v;
-}
-
-ivec4 __operator /= (inout ivec3 v, const int a)
-{
-   v = v / ivec3(a);
-   return v;
-}
-
-
-//// ivec4/int assignment operators
-
-ivec4 __operator += (inout ivec4 v, const int a)
-{
-   v = v + ivec4(a);
-   return v;
-}
-
-ivec4 __operator -= (inout ivec4 v, const int a)
-{
-   v = v - ivec4(a);
-   return v;
-}
-
-ivec4 __operator *= (inout ivec4 v, const int a)
-{
-   v = v * ivec4(a);
-   return v;
-}
-
-ivec4 __operator /= (inout ivec4 v, const int a)
-{
-   v = v / ivec4(a);
-   return v;
-}
-
-
-
-//// vec2/float assignment operators
-
-vec2 __operator += (inout vec2 v, const float a)
-{
-   v = v + vec2(a);
-   return v;
-}
-
-vec2 __operator -= (inout vec2 v, const float a)
-{
-   v = v - vec2(a);
-   return v;
-}
-
-vec2 __operator *= (inout vec2 v, const float a)
-{
-   v = v * vec2(a);
-   return v;
-}
-
-vec2 __operator /= (inout vec2 v, const float a)
-{
-   v = v / vec2(a);
-   return v;
-}
-
-
-//// vec3/float assignment operators
-
-vec3 __operator += (inout vec3 v, const float a)
-{
-   v = v + vec3(a);
-   return v;
-}
-
-vec3 __operator -= (inout vec3 v, const float a)
-{
-   v = v - vec3(a);
-   return v;
-}
-
-vec3 __operator *= (inout vec3 v, const float a)
-{
-   v = v * vec3(a);
-   return v;
-}
-
-vec3 __operator /= (inout vec3 v, const float a)
-{
-   v = v / vec3(a);
-   return v;
-}
-
-
-//// vec4/float assignment operators
-
-vec4 __operator += (inout vec4 v, const float a)
-{
-   v = v + vec4(a);
-   return v;
-}
-
-vec4 __operator -= (inout vec4 v, const float a)
-{
-   v = v - vec4(a);
-   return v;
-}
-
-vec4 __operator *= (inout vec4 v, const float a)
-{
-   v = v * vec4(a);
-   return v;
-}
-
-vec4 __operator /= (inout vec4 v, const float a)
-{
-   v = v / vec4(a);
-   return v;
-}
-
-
-
-
-
-//// Basic mat2 operations
-
-mat2 __operator + (const mat2 m, const mat2 n)
-{
-   __retVal[0] = m[0] + n[0];
-   __retVal[1] = m[1] + n[1];
-}
-
-mat2 __operator - (const mat2 m, const mat2 n)
-{
-   __retVal[0] = m[0] - n[0];
-   __retVal[1] = m[1] - n[1];
-}
-
-mat2 __operator * (const mat2 m, const mat2 n)
-{
-   __retVal[0] = m[0] * n[0].xx + m[1] * n[0].yy;
-   __retVal[1] = m[0] * n[1].xx + m[1] * n[1].yy;
-}
-
-mat2 __operator / (const mat2 m, const mat2 n)
-{
-   __retVal[0] = m[0] / n[0];
-   __retVal[1] = m[1] / n[1];
-}
-
-
-//// Basic mat3 operations
-
-mat3 __operator + (const mat3 m, const mat3 n)
-{
-   __retVal[0] = m[0] + n[0];
-   __retVal[1] = m[1] + n[1];
-   __retVal[2] = m[2] + n[2];
-}
-
-mat3 __operator - (const mat3 m, const mat3 n)
-{
-   __retVal[0] = m[0] - n[0];
-   __retVal[1] = m[1] - n[1];
-   __retVal[2] = m[2] - n[2];
-}
-
-mat3 __operator * (const mat3 m, const mat3 n)
-{
-   __retVal[0] = m[0] * n[0].xxx + m[1] * n[0].yyy + m[2] * n[0].zzz;
-   __retVal[1] = m[0] * n[1].xxx + m[1] * n[1].yyy + m[2] * n[1].zzz;
-   __retVal[2] = m[0] * n[2].xxx + m[1] * n[2].yyy + m[2] * n[2].zzz;
-}
-
-mat3 __operator / (const mat3 m, const mat3 n)
-{
-    __retVal[0] = m[0] / n[0];
-    __retVal[1] = m[1] / n[1];
-    __retVal[2] = m[2] / n[2];
-}
-
-
-//// Basic mat4 operations
-
-mat4 __operator + (const mat4 m, const mat4 n)
-{
-   __retVal[0] = m[0] + n[0];
-   __retVal[1] = m[1] + n[1];
-   __retVal[2] = m[2] + n[2];
-   __retVal[3] = m[3] + n[3];
-}
-
-mat4 __operator - (const mat4 m, const mat4 n)
-{
-   __retVal[0] = m[0] - n[0];
-   __retVal[1] = m[1] - n[1];
-   __retVal[2] = m[2] - n[2];
-   __retVal[3] = m[3] - n[3];
-}
-
-mat4 __operator * (const mat4 m, const mat4 n)
-{
-   __retVal[0] = m[0] * n[0].xxxx + m[1] * n[0].yyyy + m[2] * n[0].zzzz + m[3] * n[0].wwww;
-   __retVal[1] = m[0] * n[1].xxxx + m[1] * n[1].yyyy + m[2] * n[1].zzzz + m[3] * n[1].wwww;
-   __retVal[2] = m[0] * n[2].xxxx + m[1] * n[2].yyyy + m[2] * n[2].zzzz + m[3] * n[2].wwww;
-   __retVal[3] = m[0] * n[3].xxxx + m[1] * n[3].yyyy + m[2] * n[3].zzzz + m[3] * n[3].wwww;
-}
-
-mat4 __operator / (const mat4 m, const mat4 n)
-{
-    __retVal[0] = m[0] / n[0];
-    __retVal[1] = m[1] / n[1];
-    __retVal[2] = m[2] / n[2];
-    __retVal[3] = m[3] / n[3];
-}
-
-
-//// mat2/float operations
-
-mat2 __operator + (const float a, const mat2 n)
-{
-   __retVal[0] = a + n[0];
-   __retVal[1] = a + n[1];
-}
-
-mat2 __operator + (const mat2 m, const float b)
-{
-   __retVal[0] = m[0] + b;
-   __retVal[1] = m[1] + b;
-}
-
-mat2 __operator - (const float a, const mat2 n)
-{
-   __retVal[0] = a - n[0];
-   __retVal[1] = a - n[1];
-}
-
-mat2 __operator - (const mat2 m, const float b)
-{
-   __retVal[0] = m[0] - b;
-   __retVal[1] = m[1] - b;
-}
-
-mat2 __operator * (const float a, const mat2 n)
-{
-   __retVal[0] = a * n[0];
-   __retVal[1] = a * n[1];
-}
-
-mat2 __operator * (const mat2 m, const float b)
-{
-   __retVal[0] = m[0] * b;
-   __retVal[1] = m[1] * b;
-}
-
-mat2 __operator / (const float a, const mat2 n)
-{
-   __retVal[0] = a / n[0];
-   __retVal[1] = a / n[1];
-}
-
-mat2 __operator / (const mat2 m, const float b)
-{
-   __retVal[0] = m[0] / b;
-   __retVal[1] = m[1] / b;
-}
-
-
-//// mat3/float operations
-
-mat3 __operator + (const float a, const mat3 n)
-{
-   __retVal[0] = a + n[0];
-   __retVal[1] = a + n[1];
-   __retVal[2] = a + n[2];
-}
-
-mat3 __operator + (const mat3 m, const float b)
-{
-   __retVal[0] = m[0] + b;
-   __retVal[1] = m[1] + b;
-   __retVal[2] = m[2] + b;
-}
-
-mat3 __operator - (const float a, const mat3 n)
-{
-   __retVal[0] = a - n[0];
-   __retVal[1] = a - n[1];
-   __retVal[2] = a - n[2];
-}
-
-mat3 __operator - (const mat3 m, const float b)
-{
-   __retVal[0] = m[0] - b;
-   __retVal[1] = m[1] - b;
-   __retVal[2] = m[2] - b;
-}
-
-mat3 __operator * (const float a, const mat3 n)
-{
-   __retVal[0] = a * n[0];
-   __retVal[1] = a * n[1];
-   __retVal[2] = a * n[2];
-}
-
-mat3 __operator * (const mat3 m, const float b)
-{
-   __retVal[0] = m[0] * b;
-   __retVal[1] = m[1] * b;
-   __retVal[2] = m[2] * b;
-}
-
-mat3 __operator / (const float a, const mat3 n)
-{
-   __retVal[0] = a / n[0];
-   __retVal[1] = a / n[1];
-   __retVal[2] = a / n[2];
-}
-
-mat3 __operator / (const mat3 m, const float b)
-{
-   __retVal[0] = m[0] / b;
-   __retVal[1] = m[1] / b;
-   __retVal[2] = m[2] / b;
-}
-
-
-//// mat4/float operations
-
-mat4 __operator + (const float a, const mat4 n)
-{
-   __retVal[0] = a + n[0];
-   __retVal[1] = a + n[1];
-   __retVal[2] = a + n[2];
-   __retVal[3] = a + n[3];
-}
-
-mat4 __operator + (const mat4 m, const float b)
-{
-   __retVal[0] = m[0] + b;
-   __retVal[1] = m[1] + b;
-   __retVal[2] = m[2] + b;
-   __retVal[3] = m[3] + b;
-}
-
-mat4 __operator - (const float a, const mat4 n)
-{
-   __retVal[0] = a - n[0];
-   __retVal[1] = a - n[1];
-   __retVal[2] = a - n[2];
-   __retVal[3] = a - n[3];
-}
-
-mat4 __operator - (const mat4 m, const float b)
-{
-   __retVal[0] = m[0] - b;
-   __retVal[1] = m[1] - b;
-   __retVal[2] = m[2] - b;
-   __retVal[3] = m[3] - b;
-}
-
-mat4 __operator * (const float a, const mat4 n)
-{
-   __retVal[0] = a * n[0];
-   __retVal[1] = a * n[1];
-   __retVal[2] = a * n[2];
-   __retVal[3] = a * n[3];
-}
-
-mat4 __operator * (const mat4 m, const float b)
-{
-   __retVal[0] = m[0] * b;
-   __retVal[1] = m[1] * b;
-   __retVal[2] = m[2] * b;
-   __retVal[3] = m[3] * b;
-}
-
-mat4 __operator / (const float a, const mat4 n)
-{
-   __retVal[0] = a / n[0];
-   __retVal[1] = a / n[1];
-   __retVal[2] = a / n[2];
-   __retVal[3] = a / n[3];
-}
-
-mat4 __operator / (const mat4 m, const float b)
-{
-   __retVal[0] = m[0] / b;
-   __retVal[1] = m[1] / b;
-   __retVal[2] = m[2] / b;
-   __retVal[3] = m[3] / b;
-}
-
-
-
-//// matrix / vector products
-
-vec2 __operator * (const mat2 m, const vec2 v)
-{
-   __retVal = m[0] * v.xx
-            + m[1] * v.yy;
-}
-
-vec2 __operator * (const vec2 v, const mat2 m)
-{
-   __retVal.x = dot(v, m[0]);
-   __retVal.y = dot(v, m[1]);
-}
-
-vec3 __operator * (const mat3 m, const vec3 v)
-{
-   __retVal = m[0] * v.xxx
-            + m[1] * v.yyy
-            + m[2] * v.zzz;
-}
-
-vec3 __operator * (const vec3 v, const mat3 m)
-{
-   __retVal.x = dot(v, m[0]);
-   __retVal.y = dot(v, m[1]);
-   __retVal.z = dot(v, m[2]);
-}
-
-vec4 __operator * (const mat4 m, const vec4 v)
-{
-   __retVal = m[0] * v.xxxx
-            + m[1] * v.yyyy
-            + m[2] * v.zzzz
-            + m[3] * v.wwww;
-}
-
-vec4 __operator * (const vec4 v, const mat4 m)
-{
-   __retVal.x = dot(v, m[0]);
-   __retVal.y = dot(v, m[1]);
-   __retVal.z = dot(v, m[2]);
-   __retVal.w = dot(v, m[3]);
-}
-
-
-
-//// mat2 assignment operators
-
-mat2 __operator += (inout mat2 m, const mat2 n)
-{
-   m[0] = m[0] + n[0];
-   m[1] = m[1] + n[1];
-   return m;
-}
-
-mat2 __operator -= (inout mat2 m, const mat2 n)
-{
-   m[0] = m[0] - n[0];
-   m[1] = m[1] - n[1];
-   return m;
-}
-
-mat2 __operator *= (inout mat2 m, const mat2 n)
-{
-   m = m * n;
-   return m;
-}
-
-mat2 __operator /= (inout mat2 m, const mat2 n)
-{
-   m[0] = m[0] / n[0];
-   m[1] = m[1] / n[1];
-   return m;
-}
-
-
-//// mat3 assignment operators
-
-mat3 __operator += (inout mat3 m, const mat3 n)
-{
-   m[0] = m[0] + n[0];
-   m[1] = m[1] + n[1];
-   m[2] = m[2] + n[2];
-   return m;
-}
-
-mat3 __operator -= (inout mat3 m, const mat3 n)
-{
-   m[0] = m[0] - n[0];
-   m[1] = m[1] - n[1];
-   m[2] = m[2] - n[2];
-   return m;
-}
-
-mat3 __operator *= (inout mat3 m, const mat3 n)
-{
-   m = m * n;
-   return m;
-}
-
-mat3 __operator /= (inout mat3 m, const mat3 n)
-{
-   m[0] = m[0] / n[0];
-   m[1] = m[1] / n[1];
-   m[2] = m[2] / n[2];
-   return m;
-}
-
-
-// mat4 assignment operators
-
-mat4 __operator += (inout mat4 m, const mat4 n)
-{
-   m[0] = m[0] + n[0];
-   m[1] = m[1] + n[1];
-   m[2] = m[2] + n[2];
-   m[3] = m[3] + n[3];
-   return m;
-}
-
-mat4 __operator -= (inout mat4 m, const mat4 n)
-{
-   m[0] = m[0] - n[0];
-   m[1] = m[1] - n[1];
-   m[2] = m[2] - n[2];
-   m[3] = m[3] - n[3];
-   return m;
-}
-
-mat4 __operator *= (inout mat4 m, const mat4 n)
-{
-   m = m * n;
-   return m;
-}
-
-mat4 __operator /= (inout mat4 m, const mat4 n)
-{
-   m[0] = m[0] / n[0];
-   m[1] = m[1] / n[1];
-   m[2] = m[2] / n[2];
-   m[3] = m[3] / n[3];
-   return m;
-}
-
-
-//// mat2/float assignment operators
-
-mat2 __operator += (inout mat2 m, const float a)
-{
-   vec2 v = vec2(a);
-   m[0] = m[0] + v;
-   m[1] = m[1] + v;
-   return m;
-}
-
-mat2 __operator -= (inout mat2 m, const float a)
-{
-   vec2 v = vec2(a);
-   m[0] = m[0] - v;
-   m[1] = m[1] - v;
-   return m;
-}
-
-mat2 __operator *= (inout mat2 m, const float a)
-{
-   vec2 v = vec2(a);
-   m[0] = m[0] * v;
-   m[1] = m[1] * v;
-   return m;
-}
-
-mat2 __operator /= (inout mat2 m, const float a)
-{
-   vec2 v = vec2(1.0 / a);
-   m[0] = m[0] * v;
-   m[1] = m[1] * v;
-   return m;
-}
-
-
-//// mat3/float assignment operators
-
-mat3 __operator += (inout mat3 m, const float a)
-{
-   vec3 v = vec3(a);
-   m[0] = m[0] + v;
-   m[1] = m[1] + v;
-   m[2] = m[2] + v;
-   return m;
-}
-
-mat3 __operator -= (inout mat3 m, const float a)
-{
-   vec3 v = vec3(a);
-   m[0] = m[0] - v;
-   m[1] = m[1] - v;
-   m[2] = m[2] - v;
-   return m;
-}
-
-mat3 __operator *= (inout mat3 m, const float a)
-{
-   vec3 v = vec3(a);
-   m[0] = m[0] * v;
-   m[1] = m[1] * v;
-   m[2] = m[2] * v;
-   return m;
-}
-
-mat3 __operator /= (inout mat3 m, const float a)
-{
-   vec3 v = vec3(1.0 / a);
-   m[0] = m[0] * v;
-   m[1] = m[1] * v;
-   m[2] = m[2] * v;
-   return m;
-}
-
-
-//// mat4/float assignment operators
-
-mat4 __operator += (inout mat4 m, const float a)
-{
-   vec4 v = vec4(a);
-   m[0] = m[0] + v;
-   m[1] = m[1] + v;
-   m[2] = m[2] + v;
-   m[3] = m[3] + v;
-   return m;
-}
-
-mat4 __operator -= (inout mat4 m, const float a)
-{
-   vec4 v = vec4(a);
-   m[0] = m[0] - v;
-   m[1] = m[1] - v;
-   m[2] = m[2] - v;
-   m[3] = m[3] - v;
-   return m;
-}
-
-mat4 __operator *= (inout mat4 m, const float a)
-{
-   vec4 v = vec4(a);
-   m[0] = m[0] * v;
-   m[1] = m[1] * v;
-   m[2] = m[2] * v;
-   m[3] = m[3] * v;
-   return m;
-}
-
-mat4 __operator /= (inout mat4 m, const float a)
-{
-   vec4 v = vec4(1.0 / a);
-   m[0] = m[0] * v;
-   m[1] = m[1] * v;
-   m[2] = m[2] * v;
-   m[3] = m[3] * v;
-   return m;
-}
-
-
-
-//// vec/mat assignment operators
-
-vec2 __operator *= (inout vec2 v, const mat2 m)
-{
-   v = v * m;
-   return v;
-}
-
-vec3 __operator *= (inout vec3 v, const mat3 m)
-{
-   v = v * m;
-   return v;
-}
-
-vec4 __operator *= (inout vec4 v, const mat4 m)
-{
-   v = v * m;
-   return v;
-}
-
-
-
-//// pre-decrement operators
-
-int __operator --(inout int a)
-{
-    a = a - 1;
-   __retVal = a;
-}
-
-ivec2 __operator --(inout ivec2 v)
-{
-   v = v - ivec2(1);
-   __retVal = v;
-}
-
-ivec3 __operator --(inout ivec3 v)
-{
-   v = v - ivec3(1);
-   __retVal = v;
-}
-
-ivec4 __operator --(inout ivec4 v)
-{
-   v = v - ivec4(1);
-   __retVal = v;
-}
-
-
-float __operator --(inout float a)
-{
-   a = a - 1.0;
-   __retVal = a;
-}
-
-vec2 __operator --(inout vec2 v)
-{
-   v = v - vec2(1.0);
-   __retVal = v;
-}
-
-vec3 __operator --(inout vec3 v)
-{
-   v = v - vec3(1.0);
-   __retVal = v;
-}
-
-vec4 __operator --(inout vec4 v)
-{
-   v = v - vec4(1.0);
-   __retVal = v;
-}
-
-
-mat2 __operator --(inout mat2 m)
-{
-   m[0] = m[0] - vec2(1.0);
-   m[1] = m[1] - vec2(1.0);
-   __retVal = m;
-}
-
-mat3 __operator --(inout mat3 m)
-{
-   m[0] = m[0] - vec3(1.0);
-   m[1] = m[1] - vec3(1.0);
-   m[2] = m[2] - vec3(1.0);
-   __retVal = m;
-}
-
-mat4 __operator --(inout mat4 m)
-{
-   m[0] = m[0] - vec4(1.0);
-   m[1] = m[1] - vec4(1.0);
-   m[2] = m[2] - vec4(1.0);
-   m[3] = m[3] - vec4(1.0);
-   __retVal = m;
-}
-
-
-//// pre-increment operators
-
-int __operator ++(inout int a)
-{
-    a = a + 1;
-    __retVal = a;
-}
-
-ivec2 __operator ++(inout ivec2 v)
-{
-   v = v + ivec2(1);
-   __retVal = v;
-}
-
-ivec3 __operator ++(inout ivec3 v)
-{
-   v = v + ivec3(1);
-   __retVal = v;
-}
-
-ivec4 __operator ++(inout ivec4 v)
-{
-   v = v + ivec4(1);
-   __retVal = v;
-}
-
-
-float __operator ++(inout float a)
-{
-    a = a + 1.0;
-    __retVal = a;
-}
-
-vec2 __operator ++(inout vec2 v)
-{
-   v = v + vec2(1.0);
-   __retVal = v;
-}
-
-vec3 __operator ++(inout vec3 v)
-{
-   v = v + vec3(1.0);
-   __retVal = v;
-}
-
-vec4 __operator ++(inout vec4 v)
-{
-   v = v + vec4(1.0);
-   __retVal = v;
-}
-
-
-mat2 __operator ++(inout mat2 m)
-{
-   m[0] = m[0] + vec2(1.0);
-   m[1] = m[1] + vec2(1.0);
-   __retVal = m;
-}
-
-mat3 __operator ++(inout mat3 m)
-{
-   m[0] = m[0] + vec3(1.0);
-   m[1] = m[1] + vec3(1.0);
-   m[2] = m[2] + vec3(1.0);
-   __retVal = m;
-}
-
-mat4 __operator ++(inout mat4 m)
-{
-   m[0] = m[0] + vec4(1.0);
-   m[1] = m[1] + vec4(1.0);
-   m[2] = m[2] + vec4(1.0);
-   m[3] = m[3] + vec4(1.0);
-   __retVal = m;
-}
-
-
-
-//// post-decrement
-
-int __postDecr(inout int a)
-{
-   __retVal = a;
-   a = a - 1;
-}
-
-ivec2 __postDecr(inout ivec2 v)
-{
-   __retVal = v;
-   v = v - ivec2(1);
-}
-
-ivec3 __postDecr(inout ivec3 v)
-{
-   __retVal = v;
-   v = v - ivec3(1);
-}
-
-ivec4 __postDecr(inout ivec4 v)
-{
-   __retVal = v;
-   v = v - ivec4(1);
-}
-
-
-float __postDecr(inout float a)
-{
-   __retVal = a;
-   a = a - 1.0;
-}
-
-vec2 __postDecr(inout vec2 v)
-{
-   __retVal = v;
-   v = v - vec2(1.0);
-}
-
-vec3 __postDecr(inout vec3 v)
-{
-   __retVal = v;
-   v = v - vec3(1.0);
-}
-
-vec4 __postDecr(inout vec4 v)
-{
-   __retVal = v;
-   v = v - vec4(1.0);
-}
-
-
-mat2 __postDecr(inout mat2 m)
-{
-   __retVal = m;
-   m[0] = m[0] - vec2(1.0);
-   m[1] = m[1] - vec2(1.0);
-}
-
-mat3 __postDecr(inout mat3 m)
-{
-   __retVal = m;
-   m[0] = m[0] - vec3(1.0);
-   m[1] = m[1] - vec3(1.0);
-   m[2] = m[2] - vec3(1.0);
-}
-
-mat4 __postDecr(inout mat4 m)
-{
-   __retVal = m;
-   m[0] = m[0] - vec4(1.0);
-   m[1] = m[1] - vec4(1.0);
-   m[2] = m[2] - vec4(1.0);
-   m[3] = m[3] - vec4(1.0);
-}
-
-
-//// post-increment
-
-float __postIncr(inout float a)
-{
-   __retVal = a;
-   a = a + 1;
-}
-
-vec2 __postIncr(inout vec2 v)
-{
-   __retVal = v;
-   v = v + vec2(1.0);
-}
-
-vec3 __postIncr(inout vec3 v)
-{
-   __retVal = v;
-   v = v + vec3(1.0);
-}
-
-vec4 __postIncr(inout vec4 v)
-{
-   __retVal = v;
-   v = v + vec4(1.0);
-}
-
-
-int __postIncr(inout int a)
-{
-   __retVal = a;
-   a = a + 1;
-}
-
-ivec2 __postIncr(inout ivec2 v)
-{
-   __retVal = v;
-   v = v + ivec2(1);
-}
-
-ivec3 __postIncr(inout ivec3 v)
-{
-   __retVal = v;
-   v = v + ivec3(1);
-}
-
-ivec4 __postIncr(inout ivec4 v)
-{
-   __retVal = v;
-   v = v + ivec3(1);
-}
-
-
-mat2 __postIncr(inout mat2 m)
-{
-   mat2 n = m;
-   m[0] = m[0] + vec2(1.0);
-   m[1] = m[1] + vec2(1.0);
-   return n;
-}
-
-mat3 __postIncr(inout mat3 m)
-{
-   mat3 n = m;
-   m[0] = m[0] + vec3(1.0);
-   m[1] = m[1] + vec3(1.0);
-   m[2] = m[2] + vec3(1.0);
-   return n;
-}
-
-mat4 __postIncr(inout mat4 m)
-{
-   mat4 n = m;
-   m[0] = m[0] + vec4(1.0);
-   m[1] = m[1] + vec4(1.0);
-   m[2] = m[2] + vec4(1.0);
-   m[3] = m[3] + vec4(1.0);
-   return n;
-}
-
-
-
-//// inequality operators
-
-
-// XXX are the inequality operators for floats/ints really needed????
-bool __operator < (const float a, const float b)
-{
-   __asm vec4_sgt __retVal.x, b, a;
-}
-
-
-bool __operator < (const int a, const int b) {
-    return float (a) < float (b);
-}
-
-bool __operator > (const float a, const float b) {
-    bool c;
-    __asm float_less c, b, a;
-    return c;
-}
-
-bool __operator > (const int a, const int b) {
-    return float (a) > float (b);
-}
-
-bool __operator >= (const float a, const float b) {
-    bool g, e;
-    __asm float_less  g, b, a;
-    __asm float_equal e, a, b;
-    return g || e;
-}
-
-bool __operator >= (const int a, const int b) {
-    return float (a) >= float (b);
-}
-
-bool __operator <= (const float a, const float b) {
-    bool g, e;
-    __asm float_less  g, a, b;
-    __asm float_equal e, a, b;
-    return g || e;
-}
-
-bool __operator <= (const int a, const int b) {
-    return float (a) <= float (b);
-}
-
-
-
-//
-// MESA-specific extension functions.
-//
-
-void printMESA (const float f) {
-    __asm float_print f;
-}
-
-void printMESA (const int i) {
-    __asm int_print i;
-}
-
-void printMESA (const bool b) {
-    __asm bool_print b;
-}
-
-void printMESA (const vec2 v) {
-    printMESA (v.x);
-    printMESA (v.y);
-}
-
-void printMESA (const vec3 v) {
-    printMESA (v.x);
-    printMESA (v.y);
-    printMESA (v.z);
-}
-
-void printMESA (const vec4 v) {
-    printMESA (v.x);
-    printMESA (v.y);
-    printMESA (v.z);
-    printMESA (v.w);
-}
-
-void printMESA (const ivec2 v) {
-    printMESA (v.x);
-    printMESA (v.y);
-}
-
-void printMESA (const ivec3 v) {
-    printMESA (v.x);
-    printMESA (v.y);
-    printMESA (v.z);
-}
-
-void printMESA (const ivec4 v) {
-    printMESA (v.x);
-    printMESA (v.y);
-    printMESA (v.z);
-    printMESA (v.w);
-}
-
-void printMESA (const bvec2 v) {
-    printMESA (v.x);
-    printMESA (v.y);
-}
-
-void printMESA (const bvec3 v) {
-    printMESA (v.x);
-    printMESA (v.y);
-    printMESA (v.z);
-}
-
-void printMESA (const bvec4 v) {
-    printMESA (v.x);
-    printMESA (v.y);
-    printMESA (v.z);
-    printMESA (v.w);
-}
-
-void printMESA (const mat2 m) {
-    printMESA (m[0]);
-    printMESA (m[1]);
-}
-
-void printMESA (const mat3 m) {
-    printMESA (m[0]);
-    printMESA (m[1]);
-    printMESA (m[2]);
-}
-
-void printMESA (const mat4 m) {
-    printMESA (m[0]);
-    printMESA (m[1]);
-    printMESA (m[2]);
-    printMESA (m[3]);
-}
-
-void printMESA (const sampler1D e) {
-    __asm int_print e;
-}
-
-void printMESA (const sampler2D e) {
-    __asm int_print e;
-}
-
-void printMESA (const sampler3D e) {
-    __asm int_print e;
-}
-
-void printMESA (const samplerCube e) {
-    __asm int_print e;
-}
-
-void printMESA (const sampler1DShadow e) {
-    __asm int_print e;
-}
-
-void printMESA (const sampler2DShadow e) {
-    __asm int_print e;
-}
-
diff --git a/src/mesa/shader/slang/library/slang_fragment_builtin.gc b/src/mesa/shader/slang/library/slang_fragment_builtin.gc
deleted file mode 100644 (file)
index 54a80ea..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5
- *
- * Copyright (C) 2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-//
-// From Shader Spec, ver. 1.10, rev. 59
-//
-
-__fixed_input vec4 gl_FragCoord;
-__fixed_input bool gl_FrontFacing;
-__fixed_output vec4 gl_FragColor;
-__fixed_output vec4 gl_FragData[gl_MaxDrawBuffers];
-__fixed_output float gl_FragDepth;
-
-varying vec4 gl_Color;
-varying vec4 gl_SecondaryColor;
-varying vec4 gl_TexCoord[gl_MaxTextureCoords];
-varying float gl_FogFragCoord;
-
-
-
-//// 8.7 Texture Lookup Functions (with bias)
-
-vec4 texture1D(const sampler1D sampler, const float coord, const float bias)
-{
-   vec4 coord4;
-   coord4.x = coord;
-   coord4.w = bias;
-   __asm vec4_tex_1d_bias __retVal, sampler, coord4;
-}
-
-vec4 texture1DProj(const sampler1D sampler, const vec2 coord, const float bias)
-{
-   // do projection here (there's no vec4_texbp1d instruction)
-   vec4 pcoord;
-   pcoord.x = coord.x / coord.y;
-   pcoord.w = bias;
-   __asm vec4_tex_1d_bias __retVal, sampler, pcoord;
-}
-
-vec4 texture1DProj(const sampler1D sampler, const vec4 coord, const float bias)
-{
-   // do projection here (there's no vec4_texbp1d instruction)
-   vec4 pcoord;
-   pcoord.x = coord.x / coord.z;
-   pcoord.w = bias;
-   __asm vec4_tex_1d_bias __retVal, sampler, pcoord;
-}
-
-
-
-
-vec4 texture2D(const sampler2D sampler, const vec2 coord, const float bias)
-{
-   vec4 coord4;
-   coord4.xy = coord.xy;
-   coord4.w = bias;
-   __asm vec4_tex_2d_bias __retVal, sampler, coord4;
-}
-
-vec4 texture2DProj(const sampler2D sampler, const vec3 coord, const float bias)
-{
-   // do projection here (there's no vec4_texbp2d instruction)
-   vec4 pcoord;
-   pcoord.xy = coord.xy / coord.z;
-   pcoord.w = bias;
-   __asm vec4_tex_2d_bias __retVal, sampler, pcoord;
-}
-
-vec4 texture2DProj(const sampler2D sampler, const vec4 coord, const float bias)
-{
-   // do projection here (there's no vec4_texbp2d instruction)
-   vec4 pcoord;
-   pcoord.xy = coord.xy / coord.w;
-   pcoord.w = bias;
-   __asm vec4_tex_2d_bias __retVal, sampler, pcoord;
-}
-
-
-
-
-vec4 texture3D(const sampler3D sampler, const vec3 coord, const float bias)
-{
-   vec4 coord4;
-   coord4.xyz = coord.xyz;
-   coord4.w = bias;
-   __asm vec4_tex_3d_bias __retVal, sampler, coord4;
-}
-
-vec4 texture3DProj(const sampler3D sampler, const vec4 coord, const float bias)
-{
-   // do projection here (there's no vec4_texbp3d instruction)
-   vec4 pcoord;
-   pcoord.xyz = coord.xyz / coord.w;
-   pcoord.w = bias;
-   __asm vec4_tex_3d_bias __retVal, sampler, pcoord;
-}
-
-
-
-
-vec4 textureCube(const samplerCube sampler, const vec3 coord, const float bias)
-{
-   vec4 coord4;
-   coord4.xyz = coord;
-   coord4.w = bias;
-   __asm vec4_tex_cube __retVal, sampler, coord4;
-}
-
-
-
-vec4 shadow1D(const sampler1DShadow sampler, const vec3 coord, const float bias)
-{
-   vec4 coord4;
-   coord4.xyz = coord;
-   coord4.w = bias;
-   __asm vec4_tex_1d_bias_shadow __retVal, sampler, coord4;
-}
-
-vec4 shadow1DProj(const sampler1DShadow sampler, const vec4 coord, const float bias)
-{
-   vec4 pcoord;
-   pcoord.x = coord.x / coord.w;
-   pcoord.z = coord.z;
-   pcoord.w = bias;
-   __asm vec4_tex_1d_bias_shadow __retVal, sampler, pcoord;
-}
-
-vec4 shadow2D(const sampler2DShadow sampler, const vec3 coord, const float bias)
-{
-   vec4 coord4;
-   coord4.xyz = coord;
-   coord4.w = bias;
-   __asm vec4_tex_2d_bias_shadow __retVal, sampler, coord4;
-}
-
-vec4 shadow2DProj(const sampler2DShadow sampler, const vec4 coord, const float bias)
-{
-   vec4 pcoord;
-   pcoord.xy = coord.xy / coord.w;
-   pcoord.z = coord.z;
-   pcoord.w = bias;
-   __asm vec4_tex_2d_bias_shadow __retVal, sampler, pcoord;
-}
-
-
-
-//// GL_EXT_texture_array
-
-vec4 texture1DArray(const sampler1DArray sampler, const vec2 coord)
-{
-   vec4 coord4;
-   coord4.xy = coord;
-   __asm vec4_tex_1d_array __retVal, sampler, coord4;
-}
-
-vec4 texture1DArray(const sampler1DArray sampler, const vec2 coord, const float bias)
-{
-   vec4 coord4;
-   coord4.xy = coord;
-   coord4.w = bias;
-   __asm vec4_tex_1d_array_bias __retVal, sampler, coord4;
-}
-
-vec4 texure2DArray(const sampler2DArray sampler, const vec3 coord)
-{
-   vec4 coord4;
-   coord4.xyz = coord;
-   __asm vec4_tex_2d_array __retVal, sampler, coord4;
-}
-
-vec4 texture2DArray(const sampler2DArray sampler, const vec3 coord, const float bias)
-{
-   vec4 coord4;
-   coord4.xyz = coord;
-   coord4.w = bias;
-   __asm vec4_tex_2d_array_bias __retVal, sampler, coord4;
-}
-
-vec4 shadow1DArray(const sampler1DArrayShadow sampler, const vec2 coord)
-{
-   vec4 coord4;
-   coord4.xy = coord;
-   __asm vec4_tex_1d_array_shadow __retVal, sampler, coord4;
-}
-
-vec4 shadow1DArray(const sampler1DArrayShadow sampler, const vec2 coord, const float bias)
-{
-   vec4 coord4;
-   coord4.xy = coord;
-   coord4.w = bias;
-   __asm vec4_tex_1d_array_bias_shadow __retVal, sampler, coord4;
-}
-
-vec4 shadow2DArray(const sampler2DArrayShadow sampler, const vec3 coord)
-{
-   vec4 coord4;
-   coord4.xyz = coord;
-   __asm vec4_tex_2d_array_shadow __retVal, sampler, coord4;
-}
-
-vec4 shadow2DArray(const sampler2DArrayShadow sampler, const vec3 coord, const float bias)
-{
-   vec4 coord4;
-   coord4.xyz = coord;
-   coord4.w = bias;
-   __asm vec4_tex_2d_array_bias_shadow __retVal, sampler, coord4;
-}
-
-
-
-//
-// 8.8 Fragment Processing Functions
-//
-
-float dFdx(const float p)
-{
-   __asm vec4_ddx __retVal.x, p.xxxx;
-}
-
-vec2 dFdx(const vec2 p)
-{
-   __asm vec4_ddx __retVal.xy, p.xyyy;
-}
-
-vec3 dFdx(const vec3 p)
-{
-   __asm vec4_ddx __retVal.xyz, p.xyzz;
-}
-
-vec4 dFdx(const vec4 p)
-{
-   __asm vec4_ddx __retVal, p;
-}
-
-float dFdy(const float p)
-{
-   __asm vec4_ddy __retVal.x, p.xxxx;
-}
-
-vec2 dFdy(const vec2 p)
-{
-   __asm vec4_ddy __retVal.xy, p.xyyy;
-}
-
-vec3 dFdy(const vec3 p)
-{
-   __asm vec4_ddy __retVal.xyz, p.xyzz;
-}
-
-vec4 dFdy(const vec4 p)
-{
-   __asm vec4_ddy __retVal, p;
-}
-
-float fwidth (const float p)
-{
-   // XXX hand-write with __asm
-   return abs(dFdx(p)) + abs(dFdy(p));
-}
-
-vec2 fwidth(const vec2 p)
-{
-   // XXX hand-write with __asm
-   return abs(dFdx(p)) + abs(dFdy(p));
-}
-
-vec3 fwidth(const vec3 p)
-{
-   // XXX hand-write with __asm
-   return abs(dFdx(p)) + abs(dFdy(p));
-}
-
-vec4 fwidth(const vec4 p)
-{
-   // XXX hand-write with __asm
-   return abs(dFdx(p)) + abs(dFdy(p));
-}
-
diff --git a/src/mesa/shader/slang/library/slang_vertex_builtin.gc b/src/mesa/shader/slang/library/slang_vertex_builtin.gc
deleted file mode 100644 (file)
index 0c67c2e..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5
- *
- * Copyright (C) 2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-//
-// From Shader Spec, ver. 1.10, rev. 59
-//
-
-__fixed_output vec4 gl_Position;
-__fixed_output float gl_PointSize;
-__fixed_output vec4 gl_ClipVertex;
-
-attribute vec4 gl_Color;
-attribute vec4 gl_SecondaryColor;
-attribute vec3 gl_Normal;
-attribute vec4 gl_Vertex;
-attribute vec4 gl_MultiTexCoord0;
-attribute vec4 gl_MultiTexCoord1;
-attribute vec4 gl_MultiTexCoord2;
-attribute vec4 gl_MultiTexCoord3;
-attribute vec4 gl_MultiTexCoord4;
-attribute vec4 gl_MultiTexCoord5;
-attribute vec4 gl_MultiTexCoord6;
-attribute vec4 gl_MultiTexCoord7;
-attribute float gl_FogCoord;
-
-varying vec4 gl_FrontColor;
-varying vec4 gl_BackColor;
-varying vec4 gl_FrontSecondaryColor;
-varying vec4 gl_BackSecondaryColor;
-varying vec4 gl_TexCoord[gl_MaxTextureCoords];
-varying float gl_FogFragCoord;
-
-//
-// Geometric Functions
-//
-
-vec4 ftransform()
-{
-   __retVal = gl_ModelViewProjectionMatrix[0] * gl_Vertex.xxxx
-            + gl_ModelViewProjectionMatrix[1] * gl_Vertex.yyyy
-            + gl_ModelViewProjectionMatrix[2] * gl_Vertex.zzzz
-            + gl_ModelViewProjectionMatrix[3] * gl_Vertex.wwww;
-}
-
-
-
-//
-// 8.7 Texture Lookup Functions
-// These are pretty much identical to the ones in slang_fragment_builtin.gc
-// When used in a vertex program, the texture sample instructions should not
-// be using a LOD term so it's effectively zero.  Adding 'lod' to that does
-// what we want.
-//
-
-vec4 texture1DLod(const sampler1D sampler, const float coord, const float lod)
-{
-   vec4 coord4;
-   coord4.x = coord;
-   coord4.w = lod;
-   __asm vec4_tex_1d_bias __retVal, sampler, coord4;
-}
-
-vec4 texture1DProjLod(const sampler1D sampler, const vec2 coord, const float lod)
-{
-   vec4 pcoord;
-   pcoord.x = coord.x / coord.y;
-   pcoord.w = lod;
-   __asm vec4_tex_1d_bias __retVal, sampler, pcoord;
-}
-
-vec4 texture1DProjLod(const sampler1D sampler, const vec4 coord, const float lod)
-{
-   vec4 pcoord;
-   pcoord.x = coord.x / coord.z;
-   pcoord.w = lod;
-   __asm vec4_tex_1d_bias __retVal, sampler, pcoord;
-}
-
-
-
-vec4 texture2DLod(const sampler2D sampler, const vec2 coord, const float lod)
-{
-   vec4 coord4;
-   coord4.xy = coord.xy;
-   coord4.w = lod;
-   __asm vec4_tex_2d_bias __retVal, sampler, coord4;
-}
-
-vec4 texture2DProjLod(const sampler2D sampler, const vec3 coord, const float lod)
-{
-   vec4 pcoord;
-   pcoord.xy = coord.xy / coord.z;
-   pcoord.w = lod;
-   __asm vec4_tex_2d_bias __retVal, sampler, pcoord;
-}
-
-vec4 texture2DProjLod(const sampler2D sampler, const vec4 coord, const float lod)
-{
-   vec4 pcoord;
-   pcoord.xy = coord.xy / coord.z;
-   pcoord.w = lod;
-   __asm vec4_tex_2d_bias __retVal, sampler, pcoord;
-}
-
-
-vec4 texture3DLod(const sampler3D sampler, const vec3 coord, const float lod)
-{
-   vec4 coord4;
-   coord4.xyz = coord.xyz;
-   coord4.w = lod;
-   __asm vec4_tex_3d_bias __retVal, sampler, coord4;
-}
-
-vec4 texture3DProjLod(const sampler3D sampler, const vec4 coord, const float lod)
-{
-   // do projection here (there's no vec4_tex_3d_bias_proj instruction)
-   vec4 pcoord;
-   pcoord.xyz = coord.xyz / coord.w;
-   pcoord.w = lod;
-   __asm vec4_tex_3d_bias __retVal, sampler, pcoord;
-}
-
-
-vec4 textureCubeLod(const samplerCube sampler, const vec3 coord, const float lod)
-{
-   vec4 coord4;
-   coord4.xyz = coord;
-   coord4.w = lod;
-   __asm vec4_tex_cube __retVal, sampler, coord4;
-}
-
-
-vec4 shadow1DLod(const sampler1DShadow sampler, const vec3 coord, const float lod)
-{
-   vec4 coord4;
-   coord4.xyz = coord;
-   coord4.w = lod;
-   __asm vec4_tex_1d_bias_shadow __retVal, sampler, coord4;
-}
-
-vec4 shadow1DProjLod(const sampler1DShadow sampler, const vec4 coord,
-                     const float lod)
-{
-   vec4 pcoord;
-   pcoord.x = coord.x / coord.w;
-   pcoord.z = coord.z;
-   pcoord.w = lod;
-   __asm vec4_tex_1d_bias_shadow __retVal, sampler, pcoord;
-}
-
-
-vec4 shadow2DLod(const sampler2DShadow sampler, const vec3 coord, const float lod)
-{
-   vec4 coord4;
-   coord4.xyz = coord;
-   coord4.w = lod;
-   __asm vec4_tex_2d_bias_shadow __retVal, sampler, coord4;
-}
-
-vec4 shadow2DProjLod(const sampler2DShadow sampler, const vec4 coord,
-                     const float lod)
-{
-   vec4 pcoord;
-   pcoord.xy = coord.xy / coord.w;
-   pcoord.z = coord.z;
-   pcoord.w = lod;
-   __asm vec4_tex_2d_bias_shadow __retVal, sampler, pcoord;
-}
-
-
-//// GL_EXT_texture_array
-
-vec4 texture1DArrayLod(const sampler1DArray sampler, const vec2 coord, const float lod)
-{
-   vec4 coord4;
-   coord4.xy = coord;
-   coord4.w = lod;
-   __asm vec4_tex_1d_array_bias __retVal, sampler, coord4;
-}
-
-
-vec4 texture2DArrayLod(const sampler2DArray sampler, const vec3 coord, const float lod)
-{
-   vec4 coord4;
-   coord4.xyz = coord;
-   coord4.w = lod;
-   __asm vec4_tex_2d_array_bias __retVal, sampler, coord4;
-}
-
diff --git a/src/mesa/shader/slang/slang_builtin.c b/src/mesa/shader/slang/slang_builtin.c
deleted file mode 100644 (file)
index b7bf4e0..0000000
+++ /dev/null
@@ -1,937 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.3
- *
- * Copyright (C) 2005-2007  Brian Paul   All Rights Reserved.
- * Copyright (C) 2008  VMware, 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
- * 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 slang_builtin.c
- * Resolve built-in uniform vars.
- * \author Brian Paul
- */
-
-#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"
-
-
-/** special state token (see below) */
-#define STATE_ARRAY ((gl_state_index) 0xfffff)
-
-
-/**
- * Lookup GL state given a variable name, 0, 1 or 2 indexes and a field.
- * Allocate room for the state in the given param list and return position
- * in the list.
- * Yes, this is kind of ugly, but it works.
- */
-static GLint
-lookup_statevar(const char *var, GLint index1, GLint index2, const char *field,
-                GLuint *swizzleOut,
-                struct gl_program_parameter_list *paramList)
-{
-   /*
-    * NOTE: The ARB_vertex_program extension specified that matrices get
-    * loaded in registers in row-major order.  With GLSL, we want column-
-    * major order.  So, we need to transpose all matrices here...
-    */
-   static const struct {
-      const char *name;
-      gl_state_index matrix;
-      gl_state_index modifier;
-   } matrices[] = {
-      { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE },
-      { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS },
-      { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 },
-      { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
-
-      { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE },
-      { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS },
-      { "gl_ProjectionMatrixTranspose", STATE_PROJECTION_MATRIX, 0 },
-      { "gl_ProjectionMatrixInverseTranspose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE },
-
-      { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE },
-      { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS },
-      { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 },
-      { "gl_ModelViewProjectionMatrixInverseTranspose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE },
-
-      { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE },
-      { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS },
-      { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 },
-      { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE },
-
-      { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
-
-      { NULL, 0, 0 }
-   };
-   gl_state_index tokens[STATE_LENGTH];
-   GLuint i;
-   GLboolean isMatrix = GL_FALSE;
-
-   for (i = 0; i < STATE_LENGTH; i++) {
-      tokens[i] = 0;
-   }
-   *swizzleOut = SWIZZLE_NOOP;
-
-   /* first, look if var is a pre-defined matrix */
-   for (i = 0; matrices[i].name; i++) {
-      if (strcmp(var, matrices[i].name) == 0) {
-         tokens[0] = matrices[i].matrix;
-         /* tokens[1], [2] and [3] filled below */
-         tokens[4] = matrices[i].modifier;
-         isMatrix = GL_TRUE;
-         break;
-      }
-   }
-
-   if (isMatrix) {
-      if (tokens[0] == STATE_TEXTURE_MATRIX) {
-         /* texture_matrix[index1][index2] */
-         tokens[1] = index1 >= 0 ? index1 : 0; /* which texture matrix */
-         index1 = index2; /* move matrix row value to index1 */
-      }
-      if (index1 < 0) {
-         /* index1 is unused: prevent extra addition at end of function */
-         index1 = 0;
-      }
-   }
-   else if (strcmp(var, "gl_DepthRange") == 0) {
-      tokens[0] = STATE_DEPTH_RANGE;
-      assert(field);
-      if (strcmp(field, "near") == 0) {
-         *swizzleOut = SWIZZLE_XXXX;
-      }
-      else if (strcmp(field, "far") == 0) {
-         *swizzleOut = SWIZZLE_YYYY;
-      }
-      else if (strcmp(field, "diff") == 0) {
-         *swizzleOut = SWIZZLE_ZZZZ;
-      }
-      else {
-         return -1;
-      }
-   }
-   else if (strcmp(var, "gl_ClipPlane") == 0) {
-      if (index1 < 0)
-         return -1;
-      tokens[0] = STATE_CLIPPLANE;
-      tokens[1] = index1;
-   }
-   else if (strcmp(var, "gl_Point") == 0) {
-      assert(field);
-      if (strcmp(field, "size") == 0) {
-         tokens[0] = STATE_POINT_SIZE;
-         *swizzleOut = SWIZZLE_XXXX;
-      }
-      else if (strcmp(field, "sizeMin") == 0) {
-         tokens[0] = STATE_POINT_SIZE;
-         *swizzleOut = SWIZZLE_YYYY;
-      }
-      else if (strcmp(field, "sizeMax") == 0) {
-         tokens[0] = STATE_POINT_SIZE;
-         *swizzleOut = SWIZZLE_ZZZZ;
-      }
-      else if (strcmp(field, "fadeThresholdSize") == 0) {
-         tokens[0] = STATE_POINT_SIZE;
-         *swizzleOut = SWIZZLE_WWWW;
-      }
-      else if (strcmp(field, "distanceConstantAttenuation") == 0) {
-         tokens[0] = STATE_POINT_ATTENUATION;
-         *swizzleOut = SWIZZLE_XXXX;
-      }
-      else if (strcmp(field, "distanceLinearAttenuation") == 0) {
-         tokens[0] = STATE_POINT_ATTENUATION;
-         *swizzleOut = SWIZZLE_YYYY;
-      }
-      else if (strcmp(field, "distanceQuadraticAttenuation") == 0) {
-         tokens[0] = STATE_POINT_ATTENUATION;
-         *swizzleOut = SWIZZLE_ZZZZ;
-      }
-      else {
-         return -1;
-      }
-   }
-   else if (strcmp(var, "gl_FrontMaterial") == 0 ||
-            strcmp(var, "gl_BackMaterial") == 0) {
-      tokens[0] = STATE_MATERIAL;
-      if (strcmp(var, "gl_FrontMaterial") == 0)
-         tokens[1] = 0;
-      else
-         tokens[1] = 1;
-      assert(field);
-      if (strcmp(field, "emission") == 0) {
-         tokens[2] = STATE_EMISSION;
-      }
-      else if (strcmp(field, "ambient") == 0) {
-         tokens[2] = STATE_AMBIENT;
-      }
-      else if (strcmp(field, "diffuse") == 0) {
-         tokens[2] = STATE_DIFFUSE;
-      }
-      else if (strcmp(field, "specular") == 0) {
-         tokens[2] = STATE_SPECULAR;
-      }
-      else if (strcmp(field, "shininess") == 0) {
-         tokens[2] = STATE_SHININESS;
-         *swizzleOut = SWIZZLE_XXXX;
-      }
-      else {
-         return -1;
-      }
-   }
-   else if (strcmp(var, "gl_LightSource") == 0) {
-      if (!field || index1 < 0)
-         return -1;
-
-      tokens[0] = STATE_LIGHT;
-      tokens[1] = index1;
-
-      if (strcmp(field, "ambient") == 0) {
-         tokens[2] = STATE_AMBIENT;
-      }
-      else if (strcmp(field, "diffuse") == 0) {
-         tokens[2] = STATE_DIFFUSE;
-      }
-      else if (strcmp(field, "specular") == 0) {
-         tokens[2] = STATE_SPECULAR;
-      }
-      else if (strcmp(field, "position") == 0) {
-         tokens[2] = STATE_POSITION;
-      }
-      else if (strcmp(field, "halfVector") == 0) {
-         tokens[2] = STATE_HALF_VECTOR;
-      }
-      else if (strcmp(field, "spotDirection") == 0) {
-         tokens[2] = STATE_SPOT_DIRECTION;
-      }
-      else if (strcmp(field, "spotCosCutoff") == 0) {
-         tokens[2] = STATE_SPOT_DIRECTION;
-         *swizzleOut = SWIZZLE_WWWW;
-      }
-      else if (strcmp(field, "spotCutoff") == 0) {
-         tokens[2] = STATE_SPOT_CUTOFF;
-         *swizzleOut = SWIZZLE_XXXX;
-      }
-      else if (strcmp(field, "spotExponent") == 0) {
-         tokens[2] = STATE_ATTENUATION;
-         *swizzleOut = SWIZZLE_WWWW;
-      }
-      else if (strcmp(field, "constantAttenuation") == 0) {
-         tokens[2] = STATE_ATTENUATION;
-         *swizzleOut = SWIZZLE_XXXX;
-      }
-      else if (strcmp(field, "linearAttenuation") == 0) {
-         tokens[2] = STATE_ATTENUATION;
-         *swizzleOut = SWIZZLE_YYYY;
-      }
-      else if (strcmp(field, "quadraticAttenuation") == 0) {
-         tokens[2] = STATE_ATTENUATION;
-         *swizzleOut = SWIZZLE_ZZZZ;
-      }
-      else {
-         return -1;
-      }
-   }
-   else if (strcmp(var, "gl_LightModel") == 0) {
-      if (strcmp(field, "ambient") == 0) {
-         tokens[0] = STATE_LIGHTMODEL_AMBIENT;
-      }
-      else {
-         return -1;
-      }
-   }
-   else if (strcmp(var, "gl_FrontLightModelProduct") == 0) {
-      if (strcmp(field, "sceneColor") == 0) {
-         tokens[0] = STATE_LIGHTMODEL_SCENECOLOR;
-         tokens[1] = 0;
-      }
-      else {
-         return -1;
-      }
-   }
-   else if (strcmp(var, "gl_BackLightModelProduct") == 0) {
-      if (strcmp(field, "sceneColor") == 0) {
-         tokens[0] = STATE_LIGHTMODEL_SCENECOLOR;
-         tokens[1] = 1;
-      }
-      else {
-         return -1;
-      }
-   }
-   else if (strcmp(var, "gl_FrontLightProduct") == 0 ||
-            strcmp(var, "gl_BackLightProduct") == 0) {
-      if (index1 < 0 || !field)
-         return -1;
-
-      tokens[0] = STATE_LIGHTPROD;
-      tokens[1] = index1; /* light number */
-      if (strcmp(var, "gl_FrontLightProduct") == 0) {
-         tokens[2] = 0; /* front */
-      }
-      else {
-         tokens[2] = 1; /* back */
-      }
-      if (strcmp(field, "ambient") == 0) {
-         tokens[3] = STATE_AMBIENT;
-      }
-      else if (strcmp(field, "diffuse") == 0) {
-         tokens[3] = STATE_DIFFUSE;
-      }
-      else if (strcmp(field, "specular") == 0) {
-         tokens[3] = STATE_SPECULAR;
-      }
-      else {
-         return -1;
-      }
-   }
-   else if (strcmp(var, "gl_TextureEnvColor") == 0) {
-      if (index1 < 0)
-         return -1;
-      tokens[0] = STATE_TEXENV_COLOR;
-      tokens[1] = index1;
-   }
-   else if (strcmp(var, "gl_EyePlaneS") == 0) {
-      if (index1 < 0)
-         return -1;
-      tokens[0] = STATE_TEXGEN;
-      tokens[1] = index1; /* tex unit */
-      tokens[2] = STATE_TEXGEN_EYE_S;
-   }
-   else if (strcmp(var, "gl_EyePlaneT") == 0) {
-      if (index1 < 0)
-         return -1;
-      tokens[0] = STATE_TEXGEN;
-      tokens[1] = index1; /* tex unit */
-      tokens[2] = STATE_TEXGEN_EYE_T;
-   }
-   else if (strcmp(var, "gl_EyePlaneR") == 0) {
-      if (index1 < 0)
-         return -1;
-      tokens[0] = STATE_TEXGEN;
-      tokens[1] = index1; /* tex unit */
-      tokens[2] = STATE_TEXGEN_EYE_R;
-   }
-   else if (strcmp(var, "gl_EyePlaneQ") == 0) {
-      if (index1 < 0)
-         return -1;
-      tokens[0] = STATE_TEXGEN;
-      tokens[1] = index1; /* tex unit */
-      tokens[2] = STATE_TEXGEN_EYE_Q;
-   }
-   else if (strcmp(var, "gl_ObjectPlaneS") == 0) {
-      if (index1 < 0)
-         return -1;
-      tokens[0] = STATE_TEXGEN;
-      tokens[1] = index1; /* tex unit */
-      tokens[2] = STATE_TEXGEN_OBJECT_S;
-   }
-   else if (strcmp(var, "gl_ObjectPlaneT") == 0) {
-      if (index1 < 0)
-         return -1;
-      tokens[0] = STATE_TEXGEN;
-      tokens[1] = index1; /* tex unit */
-      tokens[2] = STATE_TEXGEN_OBJECT_T;
-   }
-   else if (strcmp(var, "gl_ObjectPlaneR") == 0) {
-      if (index1 < 0)
-         return -1;
-      tokens[0] = STATE_TEXGEN;
-      tokens[1] = index1; /* tex unit */
-      tokens[2] = STATE_TEXGEN_OBJECT_R;
-   }
-   else if (strcmp(var, "gl_ObjectPlaneQ") == 0) {
-      if (index1 < 0)
-         return -1;
-      tokens[0] = STATE_TEXGEN;
-      tokens[1] = index1; /* tex unit */
-      tokens[2] = STATE_TEXGEN_OBJECT_Q;
-   }
-   else if (strcmp(var, "gl_Fog") == 0) {
-      if (strcmp(field, "color") == 0) {
-         tokens[0] = STATE_FOG_COLOR;
-      }
-      else if (strcmp(field, "density") == 0) {
-         tokens[0] = STATE_FOG_PARAMS;
-         *swizzleOut = SWIZZLE_XXXX;
-      }
-      else if (strcmp(field, "start") == 0) {
-         tokens[0] = STATE_FOG_PARAMS;
-         *swizzleOut = SWIZZLE_YYYY;
-      }
-      else if (strcmp(field, "end") == 0) {
-         tokens[0] = STATE_FOG_PARAMS;
-         *swizzleOut = SWIZZLE_ZZZZ;
-      }
-      else if (strcmp(field, "scale") == 0) {
-         tokens[0] = STATE_FOG_PARAMS;
-         *swizzleOut = SWIZZLE_WWWW;
-      }
-      else {
-         return -1;
-      }
-   }
-   else {
-      return -1;
-   }
-
-   if (isMatrix) {
-      /* load all four columns of matrix */
-      GLint pos[4];
-      GLuint j;
-      for (j = 0; j < 4; j++) {
-         tokens[2] = tokens[3] = j; /* jth row of matrix */
-         pos[j] = _mesa_add_state_reference(paramList, tokens);
-         assert(pos[j] >= 0);
-         ASSERT(pos[j] >= 0);
-      }
-      return pos[0] + index1;
-   }
-   else {
-      /* allocate a single register */
-      GLint pos = _mesa_add_state_reference(paramList, tokens);
-      ASSERT(pos >= 0);
-      return pos;
-   }
-}
-
-
-
-/**
- * Given a variable name and datatype, emit uniform/constant buffer
- * entries which will store that state variable.
- * For example, if name="gl_LightSource" we'll emit 64 state variable
- * vectors/references and return position where that data starts.  This will
- * allow run-time array indexing into the light source array.
- *
- * Note that this is a recursive function.
- *
- * \return -1 if error, else index of start of data in the program parameter list
- */
-static GLint
-emit_statevars(const char *name, int array_len,
-               const slang_type_specifier *type,
-               gl_state_index tokens[STATE_LENGTH],
-               struct gl_program_parameter_list *paramList)
-{
-   if (type->type == SLANG_SPEC_ARRAY) {
-      GLint i, pos = -1;
-      assert(array_len > 0);
-      if (strcmp(name, "gl_ClipPlane") == 0) {
-         tokens[0] = STATE_CLIPPLANE;
-      }
-      else if (strcmp(name, "gl_LightSource") == 0) {
-         tokens[0] = STATE_LIGHT;
-      }
-      else if (strcmp(name, "gl_FrontLightProduct") == 0) {
-         tokens[0] = STATE_LIGHTPROD;
-         tokens[2] = 0; /* front */
-      }
-      else if (strcmp(name, "gl_BackLightProduct") == 0) {
-         tokens[0] = STATE_LIGHTPROD;
-         tokens[2] = 1; /* back */
-      }
-      else if (strcmp(name, "gl_TextureEnvColor") == 0) {
-         tokens[0] = STATE_TEXENV_COLOR;
-      }
-      else if (strcmp(name, "gl_EyePlaneS") == 0) {
-         tokens[0] = STATE_TEXGEN;
-         tokens[2] = STATE_TEXGEN_EYE_S;
-      }
-      else if (strcmp(name, "gl_EyePlaneT") == 0) {
-         tokens[0] = STATE_TEXGEN;
-         tokens[2] = STATE_TEXGEN_EYE_T;
-      }
-      else if (strcmp(name, "gl_EyePlaneR") == 0) {
-         tokens[0] = STATE_TEXGEN;
-         tokens[2] = STATE_TEXGEN_EYE_R;
-      }
-      else if (strcmp(name, "gl_EyePlaneQ") == 0) {
-         tokens[0] = STATE_TEXGEN;
-         tokens[2] = STATE_TEXGEN_EYE_Q;
-      }
-      else if (strcmp(name, "gl_ObjectPlaneS") == 0) {
-         tokens[0] = STATE_TEXGEN;
-         tokens[2] = STATE_TEXGEN_OBJECT_S;
-      }
-      else if (strcmp(name, "gl_ObjectPlaneT") == 0) {
-         tokens[0] = STATE_TEXGEN;
-         tokens[2] = STATE_TEXGEN_OBJECT_T;
-      }
-      else if (strcmp(name, "gl_ObjectPlaneR") == 0) {
-         tokens[0] = STATE_TEXGEN;
-         tokens[2] = STATE_TEXGEN_OBJECT_R;
-      }
-      else if (strcmp(name, "gl_ObjectPlaneQ") == 0) {
-         tokens[0] = STATE_TEXGEN;
-         tokens[2] = STATE_TEXGEN_OBJECT_Q;
-      }
-      else {
-         return -1; /* invalid array name */
-      }
-      for (i = 0; i < array_len; i++) {
-         GLint p;
-         tokens[1] = i;
-         p = emit_statevars(NULL, 0, type->_array, tokens, paramList);
-         if (i == 0)
-            pos = p;
-      }
-      return pos;
-   }
-   else if (type->type == SLANG_SPEC_STRUCT) {
-      const slang_variable_scope *fields = type->_struct->fields;
-      GLuint i, pos = 0;
-      for (i = 0; i < fields->num_variables; i++) {
-         const slang_variable *var = fields->variables[i];
-         GLint p = emit_statevars(var->a_name, 0, &var->type.specifier,
-                                  tokens, paramList);
-         if (i == 0)
-            pos = p;
-      }
-      return pos;
-   }
-   else {
-      GLint pos;
-      assert(type->type == SLANG_SPEC_VEC4 ||
-             type->type == SLANG_SPEC_VEC3 ||
-             type->type == SLANG_SPEC_VEC2 ||
-             type->type == SLANG_SPEC_FLOAT ||
-             type->type == SLANG_SPEC_IVEC4 ||
-             type->type == SLANG_SPEC_IVEC3 ||
-             type->type == SLANG_SPEC_IVEC2 ||
-             type->type == SLANG_SPEC_INT);
-      if (name) {
-         GLint t;
-
-         if (tokens[0] == STATE_LIGHT)
-            t = 2;
-         else if (tokens[0] == STATE_LIGHTPROD)
-            t = 3;
-         else
-            return -1; /* invalid array name */
-
-         if (strcmp(name, "ambient") == 0) {
-            tokens[t] = STATE_AMBIENT;
-         }
-         else if (strcmp(name, "diffuse") == 0) {
-            tokens[t] = STATE_DIFFUSE;
-         }
-         else if (strcmp(name, "specular") == 0) {
-            tokens[t] = STATE_SPECULAR;
-         }
-         else if (strcmp(name, "position") == 0) {
-            tokens[t] = STATE_POSITION;
-         }
-         else if (strcmp(name, "halfVector") == 0) {
-            tokens[t] = STATE_HALF_VECTOR;
-         }
-         else if (strcmp(name, "spotDirection") == 0) {
-            tokens[t] = STATE_SPOT_DIRECTION; /* xyz components */
-         }
-         else if (strcmp(name, "spotCosCutoff") == 0) {
-            tokens[t] = STATE_SPOT_DIRECTION; /* w component */
-         }
-
-         else if (strcmp(name, "constantAttenuation") == 0) {
-            tokens[t] = STATE_ATTENUATION; /* x component */
-         }
-         else if (strcmp(name, "linearAttenuation") == 0) {
-            tokens[t] = STATE_ATTENUATION; /* y component */
-         }
-         else if (strcmp(name, "quadraticAttenuation") == 0) {
-            tokens[t] = STATE_ATTENUATION; /* z component */
-         }
-         else if (strcmp(name, "spotExponent") == 0) {
-            tokens[t] = STATE_ATTENUATION; /* w = spot exponent */
-         }
-
-         else if (strcmp(name, "spotCutoff") == 0) {
-            tokens[t] = STATE_SPOT_CUTOFF; /* x component */
-         }
-
-         else {
-            return -1; /* invalid field name */
-         }
-      }
-
-      pos = _mesa_add_state_reference(paramList, tokens);
-      return pos;
-   }
-
-   return 1;
-}
-
-
-/**
- * Unroll the named built-in uniform variable into a sequence of state
- * vars in the given parameter list.
- */
-static GLint
-alloc_state_var_array(const slang_variable *var,
-                      struct gl_program_parameter_list *paramList)
-{
-   gl_state_index tokens[STATE_LENGTH];
-   GLuint i;
-   GLint pos;
-
-   /* Initialize the state tokens array.  This is very important.
-    * When we call _mesa_add_state_reference() it'll searches the parameter
-    * list to see if the given statevar token sequence is already present.
-    * This is normally a good thing since it prevents redundant values in the
-    * constant buffer.
-    *
-    * But when we're building arrays of state this can be bad.  For example,
-    * consider this fragment of GLSL code:
-    *   foo = gl_LightSource[3].diffuse;
-    *   ...
-    *   bar = gl_LightSource[i].diffuse;
-    *
-    * When we unroll the gl_LightSource array (for "bar") we want to re-emit
-    * gl_LightSource[3].diffuse and not re-use the first instance (from "foo")
-    * since that would upset the array layout.  We handle this situation by
-    * setting the last token in the state var token array to the special
-    * value STATE_ARRAY.
-    * This token will only be set for array state.  We can hijack the last
-    * element in the array for this since it's never used for light, clipplane
-    * or texture env array state.
-    */
-   for (i = 0; i < STATE_LENGTH; i++)
-      tokens[i] = 0;
-   tokens[STATE_LENGTH - 1] = STATE_ARRAY;
-
-   pos = emit_statevars(var->a_name, var->array_len, &var->type.specifier,
-                        tokens, paramList);
-
-   return pos;
-}
-
-
-
-/**
- * Allocate storage for a pre-defined uniform (a GL state variable).
- * As a memory-saving optimization, we try to only allocate storage for
- * state vars that are actually used.
- *
- * Arrays such as gl_LightSource are handled specially.  For an expression
- * like "gl_LightSource[2].diffuse", we can allocate a single uniform/constant
- * slot and return the index.  In this case, we return direct=TRUE.
- *
- * Buf for something like "gl_LightSource[i].diffuse" we don't know the value
- * of 'i' at compile time so we need to "unroll" the gl_LightSource array
- * into a consecutive sequence of uniform/constant slots so it can be indexed
- * at runtime.  In this case, we return direct=FALSE.
- *
- * Currently, all pre-defined uniforms are in one of these forms:
- *   var
- *   var[i]
- *   var.field
- *   var[i].field
- *   var[i][j]
- *
- * \return -1 upon error, else position in paramList of the state variable/data
- */
-GLint
-_slang_alloc_statevar(slang_ir_node *n,
-                      struct gl_program_parameter_list *paramList,
-                      GLboolean *direct)
-{
-   slang_ir_node *n0 = n;
-   const char *field = NULL;
-   GLint index1 = -1, index2 = -1;
-   GLuint swizzle;
-
-   *direct = GL_TRUE;
-
-   if (n->Opcode == IR_FIELD) {
-      field = n->Field;
-      n = n->Children[0];
-   }
-
-   if (n->Opcode == IR_ELEMENT) {
-      if (n->Children[1]->Opcode == IR_FLOAT) {
-         index1 = (GLint) n->Children[1]->Value[0];
-      }
-      else {
-         *direct = GL_FALSE;
-      }
-      n = n->Children[0];
-   }
-
-   if (n->Opcode == IR_ELEMENT) {
-      /* XXX can only handle constant indexes for now */
-      if (n->Children[1]->Opcode == IR_FLOAT) {
-         /* two-dimensional array index: mat[i][j] */
-         index2 = index1;
-         index1 = (GLint) n->Children[1]->Value[0];
-      }
-      else {
-         *direct = GL_FALSE;
-      }
-      n = n->Children[0];
-   }
-
-   assert(n->Opcode == IR_VAR);
-
-   if (*direct) {
-      const char *var = (const char *) n->Var->a_name;
-      GLint pos =
-         lookup_statevar(var, index1, index2, field, &swizzle, paramList);
-      if (pos >= 0) {
-         /* newly resolved storage for the statevar/constant/uniform */
-         n0->Store->File = PROGRAM_STATE_VAR;
-         n0->Store->Index = pos;
-         n0->Store->Swizzle = swizzle;
-         n0->Store->Parent = NULL;
-         return pos;
-      }
-   }
-
-   *direct = GL_FALSE;
-   return alloc_state_var_array(n->Var, paramList);
-}
-
-
-
-
-#define SWIZZLE_ZWWW MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W)
-
-
-/** Predefined shader inputs */
-struct input_info
-{
-   const char *Name;
-   GLuint Attrib;
-   GLenum Type;
-   GLuint Swizzle;
-};
-
-/** Predefined vertex shader inputs/attributes */
-static const struct input_info vertInputs[] = {
-   { "gl_Vertex", VERT_ATTRIB_POS, GL_FLOAT_VEC4, SWIZZLE_NOOP },
-   { "gl_Normal", VERT_ATTRIB_NORMAL, GL_FLOAT_VEC3, SWIZZLE_NOOP },
-   { "gl_Color", VERT_ATTRIB_COLOR0, GL_FLOAT_VEC4, SWIZZLE_NOOP },
-   { "gl_SecondaryColor", VERT_ATTRIB_COLOR1, GL_FLOAT_VEC4, SWIZZLE_NOOP },
-   { "gl_FogCoord", VERT_ATTRIB_FOG, GL_FLOAT, SWIZZLE_XXXX },
-   { "gl_MultiTexCoord0", VERT_ATTRIB_TEX0, GL_FLOAT_VEC4, SWIZZLE_NOOP },
-   { "gl_MultiTexCoord1", VERT_ATTRIB_TEX1, GL_FLOAT_VEC4, SWIZZLE_NOOP },
-   { "gl_MultiTexCoord2", VERT_ATTRIB_TEX2, GL_FLOAT_VEC4, SWIZZLE_NOOP },
-   { "gl_MultiTexCoord3", VERT_ATTRIB_TEX3, GL_FLOAT_VEC4, SWIZZLE_NOOP },
-   { "gl_MultiTexCoord4", VERT_ATTRIB_TEX4, GL_FLOAT_VEC4, SWIZZLE_NOOP },
-   { "gl_MultiTexCoord5", VERT_ATTRIB_TEX5, GL_FLOAT_VEC4, SWIZZLE_NOOP },
-   { "gl_MultiTexCoord6", VERT_ATTRIB_TEX6, GL_FLOAT_VEC4, SWIZZLE_NOOP },
-   { "gl_MultiTexCoord7", VERT_ATTRIB_TEX7, GL_FLOAT_VEC4, SWIZZLE_NOOP },
-   { NULL, 0, GL_NONE, SWIZZLE_NOOP }
-};
-
-/** Predefined fragment shader inputs */
-static const struct input_info fragInputs[] = {
-   { "gl_FragCoord", FRAG_ATTRIB_WPOS, GL_FLOAT_VEC4, SWIZZLE_NOOP },
-   { "gl_Color", FRAG_ATTRIB_COL0, GL_FLOAT_VEC4, SWIZZLE_NOOP },
-   { "gl_SecondaryColor", FRAG_ATTRIB_COL1, GL_FLOAT_VEC4, SWIZZLE_NOOP },
-   { "gl_TexCoord", FRAG_ATTRIB_TEX0, GL_FLOAT_VEC4, SWIZZLE_NOOP },
-   { "gl_FogFragCoord", FRAG_ATTRIB_FOGC, GL_FLOAT, SWIZZLE_XXXX },
-   { "gl_FrontFacing", FRAG_ATTRIB_FACE, GL_FLOAT, SWIZZLE_XXXX },
-   { "gl_PointCoord", FRAG_ATTRIB_PNTC, GL_FLOAT_VEC2, SWIZZLE_XYZW },
-   { NULL, 0, GL_NONE, SWIZZLE_NOOP }
-};
-
-
-/**
- * Return the VERT_ATTRIB_* or FRAG_ATTRIB_* value that corresponds to
- * a vertex or fragment program input variable.  Return -1 if the input
- * name is invalid.
- * XXX return size too
- */
-GLint
-_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut)
-{
-   const struct input_info *inputs;
-   GLuint i;
-
-   switch (target) {
-   case GL_VERTEX_PROGRAM_ARB:
-      inputs = vertInputs;
-      break;
-   case GL_FRAGMENT_PROGRAM_ARB:
-      inputs = fragInputs;
-      break;
-   /* XXX geom program */
-   default:
-      _mesa_problem(NULL, "bad target in _slang_input_index");
-      return -1;
-   }
-
-   ASSERT(MAX_TEXTURE_COORD_UNITS == 8); /* if this fails, fix vertInputs above */
-
-   for (i = 0; inputs[i].Name; i++) {
-      if (strcmp(inputs[i].Name, name) == 0) {
-         /* found */
-         *swizzleOut = inputs[i].Swizzle;
-         return inputs[i].Attrib;
-      }
-   }
-   return -1;
-}
-
-
-/**
- * Return name of the given vertex attribute (VERT_ATTRIB_x).
- */
-const char *
-_slang_vert_attrib_name(GLuint attrib)
-{
-   GLuint i;
-   assert(attrib < VERT_ATTRIB_GENERIC0);
-   for (i = 0; vertInputs[i].Name; i++) {
-      if (vertInputs[i].Attrib == attrib)
-         return vertInputs[i].Name;
-   }
-   return NULL;
-}
-
-
-/**
- * Return type (GL_FLOAT, GL_FLOAT_VEC2, etc) of the given vertex
- * attribute (VERT_ATTRIB_x).
- */
-GLenum
-_slang_vert_attrib_type(GLuint attrib)
-{
-   GLuint i;
-   assert(attrib < VERT_ATTRIB_GENERIC0);
-   for (i = 0; vertInputs[i].Name; i++) {
-      if (vertInputs[i].Attrib == attrib)
-         return vertInputs[i].Type;
-   }
-   return GL_NONE;
-}
-
-
-
-
-
-/** Predefined shader output info */
-struct output_info
-{
-   const char *Name;
-   GLuint Attrib;
-   GLenum Type;
-};
-
-/** Predefined vertex shader outputs */
-static const struct output_info vertOutputs[] = {
-   { "gl_Position", VERT_RESULT_HPOS, GL_FLOAT_VEC4 },
-   { "gl_FrontColor", VERT_RESULT_COL0, GL_FLOAT_VEC4 },
-   { "gl_BackColor", VERT_RESULT_BFC0, GL_FLOAT_VEC4 },
-   { "gl_FrontSecondaryColor", VERT_RESULT_COL1, GL_FLOAT_VEC4 },
-   { "gl_BackSecondaryColor", VERT_RESULT_BFC1, GL_FLOAT_VEC4 },
-   { "gl_TexCoord", VERT_RESULT_TEX0, GL_FLOAT_VEC4 },
-   { "gl_FogFragCoord", VERT_RESULT_FOGC, GL_FLOAT },
-   { "gl_PointSize", VERT_RESULT_PSIZ, GL_FLOAT },
-   { NULL, 0, GL_NONE }
-};
-
-/** Predefined fragment shader outputs */
-static const struct output_info fragOutputs[] = {
-   { "gl_FragColor", FRAG_RESULT_COLOR, GL_FLOAT_VEC4 },
-   { "gl_FragDepth", FRAG_RESULT_DEPTH, GL_FLOAT },
-   { "gl_FragData", FRAG_RESULT_DATA0, GL_FLOAT_VEC4 },
-   { NULL, 0, GL_NONE }
-};
-
-
-/**
- * Return the VERT_RESULT_* or FRAG_RESULT_* value that corresponds to
- * a vertex or fragment program output variable.  Return -1 for an invalid
- * output name.
- */
-GLint
-_slang_output_index(const char *name, GLenum target)
-{
-   const struct output_info *outputs;
-   GLuint i;
-
-   switch (target) {
-   case GL_VERTEX_PROGRAM_ARB:
-      outputs = vertOutputs;
-      break;
-   case GL_FRAGMENT_PROGRAM_ARB:
-      outputs = fragOutputs;
-      break;
-   /* XXX geom program */
-   default:
-      _mesa_problem(NULL, "bad target in _slang_output_index");
-      return -1;
-   }
-
-   for (i = 0; outputs[i].Name; i++) {
-      if (strcmp(outputs[i].Name, name) == 0) {
-         /* found */
-         return outputs[i].Attrib;
-      }
-   }
-   return -1;
-}
-
-
-/**
- * Given a VERT_RESULT_x index, return the corresponding string name.
- */
-const char *
-_slang_vertex_output_name(gl_vert_result index)
-{
-   if (index < Elements(vertOutputs))
-      return vertOutputs[index].Name;
-   else
-      return NULL;
-}
-
-
-/**
- * Given a FRAG_RESULT_x index, return the corresponding string name.
- */
-const char *
-_slang_fragment_output_name(gl_frag_result index)
-{
-   if (index < Elements(fragOutputs))
-      return fragOutputs[index].Name;
-   else
-      return NULL;
-}
-
-
-/**
- * Given a VERT_RESULT_x index, return the corresponding varying
- * var's datatype.
- */
-GLenum
-_slang_vertex_output_type(gl_vert_result index)
-{
-   if (index < Elements(vertOutputs))
-      return vertOutputs[index].Type;
-   else
-      return GL_NONE;
-}
diff --git a/src/mesa/shader/slang/slang_builtin.h b/src/mesa/shader/slang/slang_builtin.h
deleted file mode 100644 (file)
index c3021ca..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.3
- *
- * Copyright (C) 2005-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.
- */
-
-
-#ifndef SLANG_BUILTIN_H
-#define SLANG_BUILTIN_H
-
-#include "shader/prog_parameter.h"
-#include "slang_utility.h"
-#include "slang_ir.h"
-
-
-extern GLint
-_slang_alloc_statevar(slang_ir_node *n,
-                      struct gl_program_parameter_list *paramList,
-                      GLboolean *direct);
-
-
-extern GLint
-_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut);
-
-extern GLint
-_slang_output_index(const char *name, GLenum target);
-
-
-extern const char *
-_slang_vert_attrib_name(GLuint attrib);
-
-extern GLenum
-_slang_vert_attrib_type(GLuint attrib);
-
-
-const char *
-_slang_vertex_output_name(gl_vert_result index);
-
-const char *
-_slang_fragment_output_name(gl_frag_result index);
-
-GLenum
-_slang_vertex_output_type(gl_vert_result index);
-
-
-#endif /* SLANG_BUILTIN_H */
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
deleted file mode 100644 (file)
index 0504d47..0000000
+++ /dev/null
@@ -1,5357 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2005-2007  Brian Paul   All Rights Reserved.
- * Copyright (C) 2008 VMware, 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
- * 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 slang_codegen.c
- * Generate IR tree from AST.
- * \author Brian Paul
- */
-
-
-/***
- *** NOTES:
- *** The new_() functions return a new instance of a simple IR node.
- *** The gen_() functions generate larger IR trees from the simple nodes.
- ***/
-
-
-
-#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_print.h"
-#include "shader/prog_statevars.h"
-#include "slang_typeinfo.h"
-#include "slang_builtin.h"
-#include "slang_codegen.h"
-#include "slang_compile.h"
-#include "slang_label.h"
-#include "slang_mem.h"
-#include "slang_simplify.h"
-#include "slang_emit.h"
-#include "slang_vartable.h"
-#include "slang_ir.h"
-#include "slang_print.h"
-
-
-/** Max iterations to unroll */
-const GLuint MAX_FOR_LOOP_UNROLL_ITERATIONS = 32;
-
-/** Max for-loop body size (in slang operations) to unroll */
-const GLuint MAX_FOR_LOOP_UNROLL_BODY_SIZE = 50;
-
-/** Max for-loop body complexity to unroll.
- * We'll compute complexity as the product of the number of iterations
- * and the size of the body.  So long-ish loops with very simple bodies
- * can be unrolled, as well as short loops with larger bodies.
- */
-const GLuint MAX_FOR_LOOP_UNROLL_COMPLEXITY = 256;
-
-
-
-static slang_ir_node *
-_slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper);
-
-static void
-slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
-                 GLuint substCount, slang_variable **substOld,
-                slang_operation **substNew, GLboolean isLHS);
-
-
-/**
- * Retrieves type information about an operation.
- * Returns GL_TRUE on success.
- * Returns GL_FALSE otherwise.
- */
-static GLboolean
-typeof_operation(const struct slang_assemble_ctx_ *A,
-                 slang_operation *op,
-                 slang_typeinfo *ti)
-{
-   return _slang_typeof_operation(op, &A->space, ti, A->atoms, A->log);
-}
-
-
-static GLboolean
-is_sampler_type(const slang_fully_specified_type *t)
-{
-   switch (t->specifier.type) {
-   case SLANG_SPEC_SAMPLER_1D:
-   case SLANG_SPEC_SAMPLER_2D:
-   case SLANG_SPEC_SAMPLER_3D:
-   case SLANG_SPEC_SAMPLER_CUBE:
-   case SLANG_SPEC_SAMPLER_1D_SHADOW:
-   case SLANG_SPEC_SAMPLER_2D_SHADOW:
-   case SLANG_SPEC_SAMPLER_RECT:
-   case SLANG_SPEC_SAMPLER_RECT_SHADOW:
-   case SLANG_SPEC_SAMPLER_1D_ARRAY:
-   case SLANG_SPEC_SAMPLER_2D_ARRAY:
-   case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW:
-   case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW:
-      return GL_TRUE;
-   default:
-      return GL_FALSE;
-   }
-}
-
-
-/**
- * Return the offset (in floats or ints) of the named field within
- * the given struct.  Return -1 if field not found.
- * If field is NULL, return the size of the struct instead.
- */
-static GLint
-_slang_field_offset(const slang_type_specifier *spec, slang_atom field)
-{
-   GLint offset = 0;
-   GLuint i;
-   for (i = 0; i < spec->_struct->fields->num_variables; i++) {
-      const slang_variable *v = spec->_struct->fields->variables[i];
-      const GLuint sz = _slang_sizeof_type_specifier(&v->type.specifier);
-      if (sz > 1) {
-         /* types larger than 1 float are register (4-float) aligned */
-         offset = (offset + 3) & ~3;
-      }
-      if (field && v->a_name == field) {
-         return offset;
-      }
-      offset += sz;
-   }
-   if (field)
-      return -1; /* field not found */
-   else
-      return offset;  /* struct size */
-}
-
-
-/**
- * Return the size (in floats) of the given type specifier.
- * If the size is greater than 4, the size should be a multiple of 4
- * so that the correct number of 4-float registers are allocated.
- * For example, a mat3x2 is size 12 because we want to store the
- * 3 columns in 3 float[4] registers.
- */
-GLuint
-_slang_sizeof_type_specifier(const slang_type_specifier *spec)
-{
-   GLuint sz;
-   switch (spec->type) {
-   case SLANG_SPEC_VOID:
-      sz = 0;
-      break;
-   case SLANG_SPEC_BOOL:
-      sz = 1;
-      break;
-   case SLANG_SPEC_BVEC2:
-      sz = 2;
-      break;
-   case SLANG_SPEC_BVEC3:
-      sz = 3;
-      break;
-   case SLANG_SPEC_BVEC4:
-      sz = 4;
-      break;
-   case SLANG_SPEC_INT:
-      sz = 1;
-      break;
-   case SLANG_SPEC_IVEC2:
-      sz = 2;
-      break;
-   case SLANG_SPEC_IVEC3:
-      sz = 3;
-      break;
-   case SLANG_SPEC_IVEC4:
-      sz = 4;
-      break;
-   case SLANG_SPEC_FLOAT:
-      sz = 1;
-      break;
-   case SLANG_SPEC_VEC2:
-      sz = 2;
-      break;
-   case SLANG_SPEC_VEC3:
-      sz = 3;
-      break;
-   case SLANG_SPEC_VEC4:
-      sz = 4;
-      break;
-   case SLANG_SPEC_MAT2:
-      sz = 2 * 4; /* 2 columns (regs) */
-      break;
-   case SLANG_SPEC_MAT3:
-      sz = 3 * 4;
-      break;
-   case SLANG_SPEC_MAT4:
-      sz = 4 * 4;
-      break;
-   case SLANG_SPEC_MAT23:
-      sz = 2 * 4; /* 2 columns (regs) */
-      break;
-   case SLANG_SPEC_MAT32:
-      sz = 3 * 4; /* 3 columns (regs) */
-      break;
-   case SLANG_SPEC_MAT24:
-      sz = 2 * 4;
-      break;
-   case SLANG_SPEC_MAT42:
-      sz = 4 * 4; /* 4 columns (regs) */
-      break;
-   case SLANG_SPEC_MAT34:
-      sz = 3 * 4;
-      break;
-   case SLANG_SPEC_MAT43:
-      sz = 4 * 4; /* 4 columns (regs) */
-      break;
-   case SLANG_SPEC_SAMPLER_1D:
-   case SLANG_SPEC_SAMPLER_2D:
-   case SLANG_SPEC_SAMPLER_3D:
-   case SLANG_SPEC_SAMPLER_CUBE:
-   case SLANG_SPEC_SAMPLER_1D_SHADOW:
-   case SLANG_SPEC_SAMPLER_2D_SHADOW:
-   case SLANG_SPEC_SAMPLER_RECT:
-   case SLANG_SPEC_SAMPLER_RECT_SHADOW:
-   case SLANG_SPEC_SAMPLER_1D_ARRAY:
-   case SLANG_SPEC_SAMPLER_2D_ARRAY:
-   case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW:
-   case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW:
-      sz = 1; /* a sampler is basically just an integer index */
-      break;
-   case SLANG_SPEC_STRUCT:
-      sz = _slang_field_offset(spec, 0); /* special use */
-      if (sz == 1) {
-         /* 1-float structs are actually troublesome to deal with since they
-          * might get placed at R.x, R.y, R.z or R.z.  Return size=2 to
-          * ensure the object is placed at R.x
-          */
-         sz = 2;
-      }
-      else if (sz > 4) {
-         sz = (sz + 3) & ~0x3; /* round up to multiple of four */
-      }
-      break;
-   case SLANG_SPEC_ARRAY:
-      sz = _slang_sizeof_type_specifier(spec->_array);
-      break;
-   default:
-      _mesa_problem(NULL, "Unexpected type in _slang_sizeof_type_specifier()");
-      sz = 0;
-   }
-
-   if (sz > 4) {
-      /* if size is > 4, it should be a multiple of four */
-      assert((sz & 0x3) == 0);
-   }
-   return sz;
-}
-
-
-/**
- * Query variable/array length (number of elements).
- * This is slightly non-trivial because there are two ways to express
- * arrays: "float x[3]" vs. "float[3] x".
- * \return the length of the array for the given variable, or 0 if not an array
- */
-static GLint
-_slang_array_length(const slang_variable *var)
-{
-   if (var->type.array_len > 0) {
-      /* Ex: float[4] x; */
-      return var->type.array_len;
-   }
-   if (var->array_len > 0) {
-      /* Ex: float x[4]; */
-      return var->array_len;
-   }
-   return 0;
-}
-
-
-/**
- * Compute total size of array give size of element, number of elements.
- * \return size in floats
- */
-static GLint
-_slang_array_size(GLint elemSize, GLint arrayLen)
-{
-   GLint total;
-   assert(elemSize > 0);
-   if (arrayLen > 1) {
-      /* round up base type to multiple of 4 */
-      total = ((elemSize + 3) & ~0x3) * MAX2(arrayLen, 1);
-   }
-   else {
-      total = elemSize;
-   }
-   return total;
-}
-
-
-/**
- * Return the TEXTURE_*_INDEX value that corresponds to a sampler type,
- * or -1 if the type is not a sampler.
- */
-static GLint
-sampler_to_texture_index(const slang_type_specifier_type type)
-{
-   switch (type) {
-   case SLANG_SPEC_SAMPLER_1D:
-      return TEXTURE_1D_INDEX;
-   case SLANG_SPEC_SAMPLER_2D:
-      return TEXTURE_2D_INDEX;
-   case SLANG_SPEC_SAMPLER_3D:
-      return TEXTURE_3D_INDEX;
-   case SLANG_SPEC_SAMPLER_CUBE:
-      return TEXTURE_CUBE_INDEX;
-   case SLANG_SPEC_SAMPLER_1D_SHADOW:
-      return TEXTURE_1D_INDEX; /* XXX fix */
-   case SLANG_SPEC_SAMPLER_2D_SHADOW:
-      return TEXTURE_2D_INDEX; /* XXX fix */
-   case SLANG_SPEC_SAMPLER_RECT:
-      return TEXTURE_RECT_INDEX;
-   case SLANG_SPEC_SAMPLER_RECT_SHADOW:
-      return TEXTURE_RECT_INDEX; /* XXX fix */
-   case SLANG_SPEC_SAMPLER_1D_ARRAY:
-      return TEXTURE_1D_ARRAY_INDEX;
-   case SLANG_SPEC_SAMPLER_2D_ARRAY:
-      return TEXTURE_2D_ARRAY_INDEX;
-   case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW:
-      return TEXTURE_1D_ARRAY_INDEX;
-   case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW:
-      return TEXTURE_2D_ARRAY_INDEX;
-   default:
-      return -1;
-   }
-}
-
-
-/** helper to build a SLANG_OPER_IDENTIFIER node */
-static void
-slang_operation_identifier(slang_operation *oper,
-                           slang_assemble_ctx *A,
-                           const char *name)
-{
-   oper->type = SLANG_OPER_IDENTIFIER;
-   oper->a_id = slang_atom_pool_atom(A->atoms, name);
-}
-
-
-/**
- * Called when we begin code/IR generation for a new while/do/for loop.
- */
-static void
-push_loop(slang_assemble_ctx *A, slang_operation *loopOper, slang_ir_node *loopIR)
-{
-   A->LoopOperStack[A->LoopDepth] = loopOper;
-   A->LoopIRStack[A->LoopDepth] = loopIR;
-   A->LoopDepth++;
-}
-
-
-/**
- * Called when we end code/IR generation for a new while/do/for loop.
- */
-static void
-pop_loop(slang_assemble_ctx *A)
-{
-   assert(A->LoopDepth > 0);
-   A->LoopDepth--;
-}
-
-
-/**
- * Return pointer to slang_operation for the loop we're currently inside,
- * or NULL if not in a loop.
- */
-static const slang_operation *
-current_loop_oper(const slang_assemble_ctx *A)
-{
-   if (A->LoopDepth > 0)
-      return A->LoopOperStack[A->LoopDepth - 1];
-   else
-      return NULL;
-}
-
-
-/**
- * Return pointer to slang_ir_node for the loop we're currently inside,
- * or NULL if not in a loop.
- */
-static slang_ir_node *
-current_loop_ir(const slang_assemble_ctx *A)
-{
-   if (A->LoopDepth > 0)
-      return A->LoopIRStack[A->LoopDepth - 1];
-   else
-      return NULL;
-}
-
-
-/**********************************************************************/
-
-
-/**
- * Map "_asm foo" to IR_FOO, etc.
- */
-typedef struct
-{
-   const char *Name;
-   slang_ir_opcode Opcode;
-   GLuint HaveRetValue, NumParams;
-} slang_asm_info;
-
-
-static slang_asm_info AsmInfo[] = {
-   /* vec4 binary op */
-   { "vec4_add", IR_ADD, 1, 2 },
-   { "vec4_subtract", IR_SUB, 1, 2 },
-   { "vec4_multiply", IR_MUL, 1, 2 },
-   { "vec4_dot", IR_DOT4, 1, 2 },
-   { "vec3_dot", IR_DOT3, 1, 2 },
-   { "vec2_dot", IR_DOT2, 1, 2 },
-   { "vec3_nrm", IR_NRM3, 1, 1 },
-   { "vec4_nrm", IR_NRM4, 1, 1 },
-   { "vec3_cross", IR_CROSS, 1, 2 },
-   { "vec4_lrp", IR_LRP, 1, 3 },
-   { "vec4_min", IR_MIN, 1, 2 },
-   { "vec4_max", IR_MAX, 1, 2 },
-   { "vec4_cmp", IR_CMP, 1, 3 },
-   { "vec4_clamp", IR_CLAMP, 1, 3 },
-   { "vec4_seq", IR_SEQUAL, 1, 2 },
-   { "vec4_sne", IR_SNEQUAL, 1, 2 },
-   { "vec4_sge", IR_SGE, 1, 2 },
-   { "vec4_sgt", IR_SGT, 1, 2 },
-   { "vec4_sle", IR_SLE, 1, 2 },
-   { "vec4_slt", IR_SLT, 1, 2 },
-   /* vec4 unary */
-   { "vec4_move", IR_MOVE, 1, 1 },
-   { "vec4_floor", IR_FLOOR, 1, 1 },
-   { "vec4_frac", IR_FRAC, 1, 1 },
-   { "vec4_abs", IR_ABS, 1, 1 },
-   { "vec4_negate", IR_NEG, 1, 1 },
-   { "vec4_ddx", IR_DDX, 1, 1 },
-   { "vec4_ddy", IR_DDY, 1, 1 },
-   /* float binary op */
-   { "float_power", IR_POW, 1, 2 },
-   /* texture / sampler */
-   { "vec4_tex_1d", IR_TEX, 1, 2 },
-   { "vec4_tex_1d_bias", IR_TEXB, 1, 2 },  /* 1d w/ bias */
-   { "vec4_tex_1d_proj", IR_TEXP, 1, 2 },  /* 1d w/ projection */
-   { "vec4_tex_2d", IR_TEX, 1, 2 },
-   { "vec4_tex_2d_bias", IR_TEXB, 1, 2 },  /* 2d w/ bias */
-   { "vec4_tex_2d_proj", IR_TEXP, 1, 2 },  /* 2d w/ projection */
-   { "vec4_tex_3d", IR_TEX, 1, 2 },
-   { "vec4_tex_3d_bias", IR_TEXB, 1, 2 },  /* 3d w/ bias */
-   { "vec4_tex_3d_proj", IR_TEXP, 1, 2 },  /* 3d w/ projection */
-   { "vec4_tex_cube", IR_TEX, 1, 2 },      /* cubemap */
-   { "vec4_tex_rect", IR_TEX, 1, 2 },      /* rectangle */
-   { "vec4_tex_rect_bias", IR_TEX, 1, 2 }, /* rectangle w/ projection */
-   { "vec4_tex_1d_array", IR_TEX, 1, 2 },
-   { "vec4_tex_1d_array_bias", IR_TEXB, 1, 2 },
-   { "vec4_tex_1d_array_shadow", IR_TEX, 1, 2 },
-   { "vec4_tex_1d_array_bias_shadow", IR_TEXB, 1, 2 },
-   { "vec4_tex_2d_array", IR_TEX, 1, 2 },
-   { "vec4_tex_2d_array_bias", IR_TEXB, 1, 2 },
-   { "vec4_tex_2d_array_shadow", IR_TEX, 1, 2 },
-   { "vec4_tex_2d_array_bias_shadow", IR_TEXB, 1, 2 },
-
-   /* texture / sampler but with shadow comparison */
-   { "vec4_tex_1d_shadow", IR_TEX_SH, 1, 2 },
-   { "vec4_tex_1d_bias_shadow", IR_TEXB_SH, 1, 2 },
-   { "vec4_tex_1d_proj_shadow", IR_TEXP_SH, 1, 2 },
-   { "vec4_tex_2d_shadow", IR_TEX_SH, 1, 2 },
-   { "vec4_tex_2d_bias_shadow", IR_TEXB_SH, 1, 2 },
-   { "vec4_tex_2d_proj_shadow", IR_TEXP_SH, 1, 2 },
-   { "vec4_tex_rect_shadow", IR_TEX_SH, 1, 2 },
-   { "vec4_tex_rect_proj_shadow", IR_TEXP_SH, 1, 2 },
-
-   /* unary op */
-   { "ivec4_to_vec4", IR_I_TO_F, 1, 1 }, /* int[4] to float[4] */
-   { "vec4_to_ivec4", IR_F_TO_I, 1, 1 },  /* float[4] to int[4] */
-   { "float_exp", IR_EXP, 1, 1 },
-   { "float_exp2", IR_EXP2, 1, 1 },
-   { "float_log2", IR_LOG2, 1, 1 },
-   { "float_rsq", IR_RSQ, 1, 1 },
-   { "float_rcp", IR_RCP, 1, 1 },
-   { "float_sine", IR_SIN, 1, 1 },
-   { "float_cosine", IR_COS, 1, 1 },
-   { "float_noise1", IR_NOISE1, 1, 1},
-   { "float_noise2", IR_NOISE2, 1, 1},
-   { "float_noise3", IR_NOISE3, 1, 1},
-   { "float_noise4", IR_NOISE4, 1, 1},
-
-   { NULL, IR_NOP, 0, 0 }
-};
-
-
-static slang_ir_node *
-new_node3(slang_ir_opcode op,
-          slang_ir_node *c0, slang_ir_node *c1, slang_ir_node *c2)
-{
-   slang_ir_node *n = (slang_ir_node *) _slang_alloc(sizeof(slang_ir_node));
-   if (n) {
-      n->Opcode = op;
-      n->Children[0] = c0;
-      n->Children[1] = c1;
-      n->Children[2] = c2;
-      n->InstLocation = -1;
-   }
-   return n;
-}
-
-static slang_ir_node *
-new_node2(slang_ir_opcode op, slang_ir_node *c0, slang_ir_node *c1)
-{
-   return new_node3(op, c0, c1, NULL);
-}
-
-static slang_ir_node *
-new_node1(slang_ir_opcode op, slang_ir_node *c0)
-{
-   return new_node3(op, c0, NULL, NULL);
-}
-
-static slang_ir_node *
-new_node0(slang_ir_opcode op)
-{
-   return new_node3(op, NULL, NULL, NULL);
-}
-
-
-/**
- * Create sequence of two nodes.
- */
-static slang_ir_node *
-new_seq(slang_ir_node *left, slang_ir_node *right)
-{
-   if (!left)
-      return right;
-   if (!right)
-      return left;
-   return new_node2(IR_SEQ, left, right);
-}
-
-static slang_ir_node *
-new_label(slang_label *label)
-{
-   slang_ir_node *n = new_node0(IR_LABEL);
-   assert(label);
-   if (n)
-      n->Label = label;
-   return n;
-}
-
-static slang_ir_node *
-new_float_literal(const float v[4], GLuint size)
-{
-   slang_ir_node *n = new_node0(IR_FLOAT);
-   assert(size <= 4);
-   COPY_4V(n->Value, v);
-   /* allocate a storage object, but compute actual location (Index) later */
-   n->Store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, size);
-   return n;
-}
-
-
-static slang_ir_node *
-new_not(slang_ir_node *n)
-{
-   return new_node1(IR_NOT, n);
-}
-
-
-/**
- * Non-inlined function call.
- */
-static slang_ir_node *
-new_function_call(slang_ir_node *code, slang_label *name)
-{
-   slang_ir_node *n = new_node1(IR_CALL, code);
-   assert(name);
-   if (n)
-      n->Label = name;
-   return n;
-}
-
-
-/**
- * Unconditional jump.
- */
-static slang_ir_node *
-new_return(slang_label *dest)
-{
-   slang_ir_node *n = new_node0(IR_RETURN);
-   assert(dest);
-   if (n)
-      n->Label = dest;
-   return n;
-}
-
-
-static slang_ir_node *
-new_loop(slang_ir_node *body)
-{
-   return new_node1(IR_LOOP, body);
-}
-
-
-static slang_ir_node *
-new_break(slang_ir_node *loopNode)
-{
-   slang_ir_node *n = new_node0(IR_BREAK);
-   assert(loopNode);
-   assert(loopNode->Opcode == IR_LOOP);
-   if (n) {
-      /* insert this node at head of linked list of cont/break instructions */
-      n->List = loopNode->List;
-      loopNode->List = n;
-   }
-   return n;
-}
-
-
-/**
- * Make new IR_BREAK_IF_TRUE.
- */
-static slang_ir_node *
-new_break_if_true(slang_assemble_ctx *A, slang_ir_node *cond)
-{
-   slang_ir_node *loopNode = current_loop_ir(A);
-   slang_ir_node *n;
-   assert(loopNode);
-   assert(loopNode->Opcode == IR_LOOP);
-   n = new_node1(IR_BREAK_IF_TRUE, cond);
-   if (n) {
-      /* insert this node at head of linked list of cont/break instructions */
-      n->List = loopNode->List;
-      loopNode->List = n;
-   }
-   return n;
-}
-
-
-/**
- * Make new IR_CONT_IF_TRUE node.
- */
-static slang_ir_node *
-new_cont_if_true(slang_assemble_ctx *A, slang_ir_node *cond)
-{
-   slang_ir_node *loopNode = current_loop_ir(A);
-   slang_ir_node *n;
-   assert(loopNode);
-   assert(loopNode->Opcode == IR_LOOP);
-   n = new_node1(IR_CONT_IF_TRUE, cond);
-   if (n) {
-      n->Parent = loopNode; /* pointer to containing loop */
-      /* insert this node at head of linked list of cont/break instructions */
-      n->List = loopNode->List;
-      loopNode->List = n;
-   }
-   return n;
-}
-
-
-static slang_ir_node *
-new_cond(slang_ir_node *n)
-{
-   slang_ir_node *c = new_node1(IR_COND, n);
-   return c;
-}
-
-
-static slang_ir_node *
-new_if(slang_ir_node *cond, slang_ir_node *ifPart, slang_ir_node *elsePart)
-{
-   return new_node3(IR_IF, cond, ifPart, elsePart);
-}
-
-
-/**
- * New IR_VAR node - a reference to a previously declared variable.
- */
-static slang_ir_node *
-new_var(slang_assemble_ctx *A, slang_variable *var)
-{
-   slang_ir_node *n = new_node0(IR_VAR);
-   if (n) {
-      ASSERT(var);
-      ASSERT(var->store);
-      ASSERT(!n->Store);
-      ASSERT(!n->Var);
-
-      /* Set IR node's Var and Store pointers */
-      n->Var = var;
-      n->Store = var->store;
-   }
-   return n;
-}
-
-
-/**
- * Check if the given function is really just a wrapper for a
- * basic assembly instruction.
- */
-static GLboolean
-slang_is_asm_function(const slang_function *fun)
-{
-   if (fun->body->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE &&
-       fun->body->num_children == 1 &&
-       fun->body->children[0].type == SLANG_OPER_ASM) {
-      return GL_TRUE;
-   }
-   return GL_FALSE;
-}
-
-
-static GLboolean
-_slang_is_noop(const slang_operation *oper)
-{
-   if (!oper ||
-       oper->type == SLANG_OPER_VOID ||
-       (oper->num_children == 1 && oper->children[0].type == SLANG_OPER_VOID))
-      return GL_TRUE;
-   else
-      return GL_FALSE;
-}
-
-
-/**
- * Recursively search tree for a node of the given type.
- */
-#if 0
-static slang_operation *
-_slang_find_node_type(slang_operation *oper, slang_operation_type type)
-{
-   GLuint i;
-   if (oper->type == type)
-      return oper;
-   for (i = 0; i < oper->num_children; i++) {
-      slang_operation *p = _slang_find_node_type(&oper->children[i], type);
-      if (p)
-         return p;
-   }
-   return NULL;
-}
-#endif
-
-
-/**
- * Count the number of operations of the given time rooted at 'oper'.
- */
-static GLuint
-_slang_count_node_type(const slang_operation *oper, slang_operation_type type)
-{
-   GLuint i, count = 0;
-   if (oper->type == type) {
-      return 1;
-   }
-   for (i = 0; i < oper->num_children; i++) {
-      count += _slang_count_node_type(&oper->children[i], type);
-   }
-   return count;
-}
-
-
-/**
- * Check if the 'return' statement found under 'oper' is a "tail return"
- * that can be no-op'd.  For example:
- *
- * void func(void)
- * {
- *    .. do something ..
- *    return;   // this is a no-op
- * }
- *
- * This is used when determining if a function can be inlined.  If the
- * 'return' is not the last statement, we can't inline the function since
- * we still need the semantic behaviour of the 'return' but we don't want
- * to accidentally return from the _calling_ function.  We'd need to use an
- * unconditional branch, but we don't have such a GPU instruction (not
- * always, at least).
- */
-static GLboolean
-_slang_is_tail_return(const slang_operation *oper)
-{
-   GLuint k = oper->num_children;
-
-   while (k > 0) {
-      const slang_operation *last = &oper->children[k - 1];
-      if (last->type == SLANG_OPER_RETURN)
-         return GL_TRUE;
-      else if (last->type == SLANG_OPER_IDENTIFIER ||
-               last->type == SLANG_OPER_LABEL)
-         k--; /* try prev child */
-      else if (last->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE ||
-               last->type == SLANG_OPER_BLOCK_NEW_SCOPE)
-         /* try sub-children */
-         return _slang_is_tail_return(last);
-      else
-         break;
-   }
-
-   return GL_FALSE;
-}
-
-
-/**
- * Generate a variable declaration opeartion.
- * I.e.: generate AST code for "bool flag = false;"
- */
-static void
-slang_generate_declaration(slang_assemble_ctx *A,
-                           slang_variable_scope *scope,
-                           slang_operation *decl,
-                           slang_type_specifier_type type,
-                           const char *name,
-                           GLint initValue)
-{
-   slang_variable *var;
-
-   assert(type == SLANG_SPEC_BOOL ||
-          type == SLANG_SPEC_INT);
-
-   decl->type = SLANG_OPER_VARIABLE_DECL;
-
-   var = slang_variable_scope_grow(scope);
-
-   slang_fully_specified_type_construct(&var->type);
-
-   var->type.specifier.type = type;
-   var->a_name = slang_atom_pool_atom(A->atoms, name);
-   decl->a_id = var->a_name;
-   var->initializer = slang_operation_new(1);
-   slang_operation_literal_bool(var->initializer, initValue);
-}
-
-
-static void
-slang_resolve_variable(slang_operation *oper)
-{
-   if (oper->type == SLANG_OPER_IDENTIFIER && !oper->var) {
-      oper->var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE);
-   }
-}
-
-
-/**
- * Rewrite AST code for "return expression;".
- *
- * We return values from functions by assinging the returned value to
- * the hidden __retVal variable which is an extra 'out' parameter we add
- * to the function signature.
- * This code basically converts "return expr;" into "__retVal = expr; return;"
- *
- * \return the new AST code.
- */
-static slang_operation *
-gen_return_with_expression(slang_assemble_ctx *A, slang_operation *oper)
-{
-   slang_operation *blockOper, *assignOper;
-
-   assert(oper->type == SLANG_OPER_RETURN);
-
-   if (A->CurFunction->header.type.specifier.type == SLANG_SPEC_VOID) {
-      slang_info_log_error(A->log, "illegal return expression");
-      return NULL;
-   }
-
-   blockOper = slang_operation_new(1);
-   blockOper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
-   blockOper->locals->outer_scope = oper->locals->outer_scope;
-   slang_operation_add_children(blockOper, 2);
-
-   if (A->UseReturnFlag) {
-      /* Emit:
-       *    {
-       *       if (__notRetFlag)
-       *          __retVal = expr;
-       *       __notRetFlag = 0;
-       *    }
-       */
-      {
-         slang_operation *ifOper = slang_oper_child(blockOper, 0);
-         ifOper->type = SLANG_OPER_IF;
-         slang_operation_add_children(ifOper, 3);
-         {
-            slang_operation *cond = slang_oper_child(ifOper, 0);
-            cond->type = SLANG_OPER_IDENTIFIER;
-            cond->a_id = slang_atom_pool_atom(A->atoms, "__notRetFlag");
-         }
-         {
-            slang_operation *elseOper = slang_oper_child(ifOper, 2);
-            elseOper->type = SLANG_OPER_VOID;
-         }
-         assignOper = slang_oper_child(ifOper, 1);
-      }
-      {
-         slang_operation *setOper = slang_oper_child(blockOper, 1);
-         setOper->type = SLANG_OPER_ASSIGN;
-         slang_operation_add_children(setOper, 2);
-         {
-            slang_operation *lhs = slang_oper_child(setOper, 0);
-            lhs->type = SLANG_OPER_IDENTIFIER;
-            lhs->a_id = slang_atom_pool_atom(A->atoms, "__notRetFlag");
-         }
-         {
-            slang_operation *rhs = slang_oper_child(setOper, 1);
-            slang_operation_literal_bool(rhs, GL_FALSE);
-         }
-      }
-   }
-   else {
-      /* Emit:
-       *    {
-       *       __retVal = expr;
-       *       return_inlined;
-       *    }
-       */
-      assignOper = slang_oper_child(blockOper, 0);
-      {
-         slang_operation *returnOper = slang_oper_child(blockOper, 1);
-         returnOper->type = SLANG_OPER_RETURN_INLINED;
-         assert(returnOper->num_children == 0);
-      }
-   }
-
-   /* __retVal = expression; */
-   assignOper->type = SLANG_OPER_ASSIGN;
-   slang_operation_add_children(assignOper, 2);
-   {
-      slang_operation *lhs = slang_oper_child(assignOper, 0);
-      lhs->type = SLANG_OPER_IDENTIFIER;
-      lhs->a_id = slang_atom_pool_atom(A->atoms, "__retVal");
-   }
-   {
-      slang_operation *rhs = slang_oper_child(assignOper, 1);
-      slang_operation_copy(rhs, &oper->children[0]);
-   }
-
-   /*blockOper->locals->outer_scope = oper->locals->outer_scope;*/
-
-   /*slang_print_tree(blockOper, 0);*/
-
-   return blockOper;
-}
-
-
-/**
- * Rewrite AST code for "return;" (no expression).
- */
-static slang_operation *
-gen_return_without_expression(slang_assemble_ctx *A, slang_operation *oper)
-{
-   slang_operation *newRet;
-
-   assert(oper->type == SLANG_OPER_RETURN);
-
-   if (A->CurFunction->header.type.specifier.type != SLANG_SPEC_VOID) {
-      slang_info_log_error(A->log, "return statement requires an expression");
-      return NULL;
-   }
-
-   if (A->UseReturnFlag) {
-      /* Emit:
-       *    __notRetFlag = 0;
-       */
-      {
-         newRet = slang_operation_new(1);
-         newRet->locals->outer_scope = oper->locals->outer_scope;
-         newRet->type = SLANG_OPER_ASSIGN;
-         slang_operation_add_children(newRet, 2);
-         {
-            slang_operation *lhs = slang_oper_child(newRet, 0);
-            lhs->type = SLANG_OPER_IDENTIFIER;
-            lhs->a_id = slang_atom_pool_atom(A->atoms, "__notRetFlag");
-         }
-         {
-            slang_operation *rhs = slang_oper_child(newRet, 1);
-            slang_operation_literal_bool(rhs, GL_FALSE);
-         }
-      }
-   }
-   else {
-      /* Emit:
-       *    return_inlined;
-       */
-      newRet = slang_operation_new(1);
-      newRet->locals->outer_scope = oper->locals->outer_scope;
-      newRet->type = SLANG_OPER_RETURN_INLINED;
-   }
-
-   /*slang_print_tree(newRet, 0);*/
-
-   return newRet;
-}
-
-
-
-
-/**
- * Replace particular variables (SLANG_OPER_IDENTIFIER) with new expressions.
- */
-static void
-slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
-                 GLuint substCount, slang_variable **substOld,
-                slang_operation **substNew, GLboolean isLHS)
-{
-   switch (oper->type) {
-   case SLANG_OPER_VARIABLE_DECL:
-      {
-         slang_variable *v = _slang_variable_locate(oper->locals,
-                                                    oper->a_id, GL_TRUE);
-         assert(v);
-         if (v->initializer && oper->num_children == 0) {
-            /* set child of oper to copy of initializer */
-            oper->num_children = 1;
-            oper->children = slang_operation_new(1);
-            slang_operation_copy(&oper->children[0], v->initializer);
-         }
-         if (oper->num_children == 1) {
-            /* the initializer */
-            slang_substitute(A, &oper->children[0], substCount,
-                             substOld, substNew, GL_FALSE);
-         }
-      }
-      break;
-   case SLANG_OPER_IDENTIFIER:
-      assert(oper->num_children == 0);
-      if (1/**!isLHS XXX FIX */) {
-         slang_atom id = oper->a_id;
-         slang_variable *v;
-        GLuint i;
-         v = _slang_variable_locate(oper->locals, id, GL_TRUE);
-        if (!v) {
-            if (strcmp((char *) oper->a_id, "__notRetFlag"))
-               _mesa_problem(NULL, "var %s not found!\n", (char *) oper->a_id);
-            return;
-        }
-
-        /* look for a substitution */
-        for (i = 0; i < substCount; i++) {
-           if (v == substOld[i]) {
-               /* OK, replace this SLANG_OPER_IDENTIFIER with a new expr */
-#if 0 /* DEBUG only */
-              if (substNew[i]->type == SLANG_OPER_IDENTIFIER) {
-                  assert(substNew[i]->var);
-                  assert(substNew[i]->var->a_name);
-                 printf("Substitute %s with %s in id node %p\n",
-                        (char*)v->a_name, (char*) substNew[i]->var->a_name,
-                        (void*) oper);
-               }
-              else {
-                 printf("Substitute %s with %f in id node %p\n",
-                        (char*)v->a_name, substNew[i]->literal[0],
-                        (void*) oper);
-               }
-#endif
-              slang_operation_copy(oper, substNew[i]);
-              break;
-           }
-        }
-      }
-      break;
-
-   case SLANG_OPER_RETURN:
-      {
-         slang_operation *newReturn;
-         /* generate new 'return' code' */
-         if (slang_oper_child(oper, 0)->type == SLANG_OPER_VOID)
-            newReturn = gen_return_without_expression(A, oper);
-         else
-            newReturn = gen_return_with_expression(A, oper);
-
-         if (!newReturn)
-            return;
-
-         /* do substitutions on the new 'return' code */
-         slang_substitute(A, newReturn,
-                          substCount, substOld, substNew, GL_FALSE);
-
-         /* install new 'return' code */
-         slang_operation_copy(oper, newReturn);
-         slang_operation_destruct(newReturn);
-      }
-      break;
-
-   case SLANG_OPER_ASSIGN:
-   case SLANG_OPER_SUBSCRIPT:
-      /* special case:
-       * child[0] can't have substitutions but child[1] can.
-       */
-      slang_substitute(A, &oper->children[0],
-                       substCount, substOld, substNew, GL_TRUE);
-      slang_substitute(A, &oper->children[1],
-                       substCount, substOld, substNew, GL_FALSE);
-      break;
-   case SLANG_OPER_FIELD:
-      /* XXX NEW - test */
-      slang_substitute(A, &oper->children[0],
-                       substCount, substOld, substNew, GL_TRUE);
-      break;
-   default:
-      {
-         GLuint i;
-         for (i = 0; i < oper->num_children; i++) 
-            slang_substitute(A, &oper->children[i],
-                             substCount, substOld, substNew, GL_FALSE);
-      }
-   }
-}
-
-
-/**
- * Produce inline code for a call to an assembly instruction.
- * This is typically used to compile a call to a built-in function like this:
- *
- * vec4 mix(const vec4 x, const vec4 y, const vec4 a)
- * {
- *    __asm vec4_lrp __retVal, a, y, x;
- * }
- *
- *
- * A call to
- *     r = mix(p1, p2, p3);
- *
- * Becomes:
- *
- *              mov
- *             /   \
- *            r   vec4_lrp
- *                 /  |  \
- *                p3  p2  p1
- *
- * We basically translate a SLANG_OPER_CALL into a SLANG_OPER_ASM.
- */
-static slang_operation *
-slang_inline_asm_function(slang_assemble_ctx *A,
-                          slang_function *fun, slang_operation *oper)
-{
-   const GLuint numArgs = oper->num_children;
-   GLuint i;
-   slang_operation *inlined;
-   const GLboolean haveRetValue = _slang_function_has_return_value(fun);
-   slang_variable **substOld;
-   slang_operation **substNew;
-
-   ASSERT(slang_is_asm_function(fun));
-   ASSERT(fun->param_count == numArgs + haveRetValue);
-
-   /*
-   printf("Inline %s as %s\n",
-          (char*) fun->header.a_name,
-          (char*) fun->body->children[0].a_id);
-   */
-
-   /*
-    * We'll substitute formal params with actual args in the asm call.
-    */
-   substOld = (slang_variable **)
-      _slang_alloc(numArgs * sizeof(slang_variable *));
-   substNew = (slang_operation **)
-      _slang_alloc(numArgs * sizeof(slang_operation *));
-   for (i = 0; i < numArgs; i++) {
-      substOld[i] = fun->parameters->variables[i];
-      substNew[i] = oper->children + i;
-   }
-
-   /* make a copy of the code to inline */
-   inlined = slang_operation_new(1);
-   slang_operation_copy(inlined, &fun->body->children[0]);
-   if (haveRetValue) {
-      /* get rid of the __retVal child */
-      inlined->num_children--;
-      for (i = 0; i < inlined->num_children; i++) {
-         inlined->children[i] = inlined->children[i + 1];
-      }
-   }
-
-   /* now do formal->actual substitutions */
-   slang_substitute(A, inlined, numArgs, substOld, substNew, GL_FALSE);
-
-   _slang_free(substOld);
-   _slang_free(substNew);
-
-#if 0
-   printf("+++++++++++++ inlined asm function %s +++++++++++++\n",
-          (char *) fun->header.a_name);
-   slang_print_tree(inlined, 3);
-   printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
-#endif
-
-   return inlined;
-}
-
-
-/**
- * Inline the given function call operation.
- * Return a new slang_operation that corresponds to the inlined code.
- */
-static slang_operation *
-slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
-                          slang_operation *oper, slang_operation *returnOper)
-{
-   typedef enum {
-      SUBST = 1,
-      COPY_IN,
-      COPY_OUT
-   } ParamMode;
-   ParamMode *paramMode;
-   const GLboolean haveRetValue = _slang_function_has_return_value(fun);
-   const GLuint numArgs = oper->num_children;
-   const GLuint totalArgs = numArgs + haveRetValue;
-   slang_operation *args = oper->children;
-   slang_operation *inlined, *top;
-   slang_variable **substOld;
-   slang_operation **substNew;
-   GLuint substCount, numCopyIn, i;
-   slang_function *prevFunction;
-   slang_variable_scope *newScope = NULL;
-
-   /* save / push */
-   prevFunction = A->CurFunction;
-   A->CurFunction = fun;
-
-   /*assert(oper->type == SLANG_OPER_CALL); (or (matrix) multiply, etc) */
-   assert(fun->param_count == totalArgs);
-
-   /* allocate temporary arrays */
-   paramMode = (ParamMode *)
-      _slang_alloc(totalArgs * sizeof(ParamMode));
-   substOld = (slang_variable **)
-      _slang_alloc(totalArgs * sizeof(slang_variable *));
-   substNew = (slang_operation **)
-      _slang_alloc(totalArgs * sizeof(slang_operation *));
-
-#if 0
-   printf("\nInline call to %s  (total vars=%d  nparams=%d)\n",
-         (char *) fun->header.a_name,
-         fun->parameters->num_variables, numArgs);
-#endif
-
-   if (haveRetValue && !returnOper) {
-      /* Create 3-child comma sequence for inlined code:
-       * child[0]:  declare __resultTmp
-       * child[1]:  inlined function body
-       * child[2]:  __resultTmp
-       */
-      slang_operation *commaSeq;
-      slang_operation *declOper = NULL;
-      slang_variable *resultVar;
-
-      commaSeq = slang_operation_new(1);
-      commaSeq->type = SLANG_OPER_SEQUENCE;
-      assert(commaSeq->locals);
-      commaSeq->locals->outer_scope = oper->locals->outer_scope;
-      commaSeq->num_children = 3;
-      commaSeq->children = slang_operation_new(3);
-      /* allocate the return var */
-      resultVar = slang_variable_scope_grow(commaSeq->locals);
-      /*
-      printf("Alloc __resultTmp in scope %p for retval of calling %s\n",
-             (void*)commaSeq->locals, (char *) fun->header.a_name);
-      */
-
-      resultVar->a_name = slang_atom_pool_atom(A->atoms, "__resultTmp");
-      resultVar->type = fun->header.type; /* XXX copy? */
-      resultVar->isTemp = GL_TRUE;
-
-      /* child[0] = __resultTmp declaration */
-      declOper = &commaSeq->children[0];
-      declOper->type = SLANG_OPER_VARIABLE_DECL;
-      declOper->a_id = resultVar->a_name;
-      declOper->locals->outer_scope = commaSeq->locals;
-
-      /* child[1] = function body */
-      inlined = &commaSeq->children[1];
-      inlined->locals->outer_scope = commaSeq->locals;
-
-      /* child[2] = __resultTmp reference */
-      returnOper = &commaSeq->children[2];
-      returnOper->type = SLANG_OPER_IDENTIFIER;
-      returnOper->a_id = resultVar->a_name;
-      returnOper->locals->outer_scope = commaSeq->locals;
-
-      top = commaSeq;
-   }
-   else {
-      top = inlined = slang_operation_new(1);
-      /* XXXX this may be inappropriate!!!! */
-      inlined->locals->outer_scope = oper->locals->outer_scope;
-   }
-
-
-   assert(inlined->locals);
-
-   /* Examine the parameters, look for inout/out params, look for possible
-    * substitutions, etc:
-    *    param type      behaviour
-    *     in             copy actual to local
-    *     const in       substitute param with actual
-    *     out            copy out
-    */
-   substCount = 0;
-   for (i = 0; i < totalArgs; i++) {
-      slang_variable *p = fun->parameters->variables[i];
-      /*
-      printf("Param %d: %s %s \n", i,
-             slang_type_qual_string(p->type.qualifier),
-            (char *) p->a_name);
-      */
-      if (p->type.qualifier == SLANG_QUAL_INOUT ||
-         p->type.qualifier == SLANG_QUAL_OUT) {
-        /* an output param */
-         slang_operation *arg;
-         if (i < numArgs)
-            arg = &args[i];
-         else
-            arg = returnOper;
-        paramMode[i] = SUBST;
-
-        if (arg->type == SLANG_OPER_IDENTIFIER)
-            slang_resolve_variable(arg);
-
-         /* replace parameter 'p' with argument 'arg' */
-        substOld[substCount] = p;
-        substNew[substCount] = arg; /* will get copied */
-        substCount++;
-      }
-      else if (p->type.qualifier == SLANG_QUAL_CONST) {
-        /* a constant input param */
-         if (args[i].type == SLANG_OPER_IDENTIFIER ||
-             args[i].type == SLANG_OPER_LITERAL_FLOAT ||
-             args[i].type == SLANG_OPER_SUBSCRIPT) {
-           /* replace all occurances of this parameter variable with the
-            * actual argument variable or a literal.
-            */
-           paramMode[i] = SUBST;
-            slang_resolve_variable(&args[i]);
-           substOld[substCount] = p;
-           substNew[substCount] = &args[i]; /* will get copied */
-           substCount++;
-        }
-        else {
-           paramMode[i] = COPY_IN;
-        }
-      }
-      else {
-        paramMode[i] = COPY_IN;
-      }
-      assert(paramMode[i]);
-   }
-
-   /* actual code inlining: */
-   slang_operation_copy(inlined, fun->body);
-
-   /*** XXX review this */
-   assert(inlined->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE ||
-          inlined->type == SLANG_OPER_BLOCK_NEW_SCOPE);
-   inlined->type = SLANG_OPER_BLOCK_NEW_SCOPE;
-
-#if 0
-   printf("======================= orig body code ======================\n");
-   printf("=== params scope = %p\n", (void*) fun->parameters);
-   slang_print_tree(fun->body, 8);
-   printf("======================= copied code =========================\n");
-   slang_print_tree(inlined, 8);
-#endif
-
-   /* do parameter substitution in inlined code: */
-   slang_substitute(A, inlined, substCount, substOld, substNew, GL_FALSE);
-
-#if 0
-   printf("======================= subst code ==========================\n");
-   slang_print_tree(inlined, 8);
-   printf("=============================================================\n");
-#endif
-
-   /* New prolog statements: (inserted before the inlined code)
-    * Copy the 'in' arguments.
-    */
-   numCopyIn = 0;
-   for (i = 0; i < numArgs; i++) {
-      if (paramMode[i] == COPY_IN) {
-        slang_variable *p = fun->parameters->variables[i];
-        /* declare parameter 'p' */
-        slang_operation *decl = slang_operation_insert(&inlined->num_children,
-                                                       &inlined->children,
-                                                       numCopyIn);
-
-        decl->type = SLANG_OPER_VARIABLE_DECL;
-         assert(decl->locals);
-         decl->locals->outer_scope = inlined->locals;
-        decl->a_id = p->a_name;
-        decl->num_children = 1;
-        decl->children = slang_operation_new(1);
-
-         /* child[0] is the var's initializer */
-         slang_operation_copy(&decl->children[0], args + i);
-
-         /* add parameter 'p' to the local variable scope here */
-         {
-            slang_variable *pCopy = slang_variable_scope_grow(inlined->locals);
-            pCopy->type = p->type;
-            pCopy->a_name = p->a_name;
-            pCopy->array_len = p->array_len;
-         }
-
-         newScope = inlined->locals;
-        numCopyIn++;
-      }
-   }
-
-   /* Now add copies of the function's local vars to the new variable scope */
-   for (i = totalArgs; i < fun->parameters->num_variables; i++) {
-      slang_variable *p = fun->parameters->variables[i];
-      slang_variable *pCopy = slang_variable_scope_grow(inlined->locals);
-      pCopy->type = p->type;
-      pCopy->a_name = p->a_name;
-      pCopy->array_len = p->array_len;
-   }
-
-
-   /* New epilog statements:
-    * 1. Create end of function label to jump to from return statements.
-    * 2. Copy the 'out' parameter vars
-    */
-   {
-      slang_operation *lab = slang_operation_insert(&inlined->num_children,
-                                                    &inlined->children,
-                                                    inlined->num_children);
-      lab->type = SLANG_OPER_LABEL;
-      lab->label = A->curFuncEndLabel;
-   }
-
-   for (i = 0; i < totalArgs; i++) {
-      if (paramMode[i] == COPY_OUT) {
-        const slang_variable *p = fun->parameters->variables[i];
-        /* actualCallVar = outParam */
-        /*if (i > 0 || !haveRetValue)*/
-        slang_operation *ass = slang_operation_insert(&inlined->num_children,
-                                                      &inlined->children,
-                                                      inlined->num_children);
-        ass->type = SLANG_OPER_ASSIGN;
-        ass->num_children = 2;
-         ass->locals->outer_scope = inlined->locals;
-        ass->children = slang_operation_new(2);
-        ass->children[0] = args[i]; /*XXX copy */
-        ass->children[1].type = SLANG_OPER_IDENTIFIER;
-        ass->children[1].a_id = p->a_name;
-         ass->children[1].locals->outer_scope = ass->locals;
-      }
-   }
-
-   _slang_free(paramMode);
-   _slang_free(substOld);
-   _slang_free(substNew);
-
-   /* Update scoping to use the new local vars instead of the
-    * original function's vars.  This is especially important
-    * for nested inlining.
-    */
-   if (newScope)
-      slang_replace_scope(inlined, fun->parameters, newScope);
-
-#if 0
-   printf("Done Inline call to %s  (total vars=%d  nparams=%d)\n\n",
-         (char *) fun->header.a_name,
-         fun->parameters->num_variables, numArgs);
-   slang_print_tree(top, 0);
-#endif
-
-   /* pop */
-   A->CurFunction = prevFunction;
-
-   return top;
-}
-
-
-/**
- * Insert declaration for "bool __notRetFlag" in given block operation.
- * This is used when we can't emit "early" return statements in subroutines.
- */
-static void
-declare_return_flag(slang_assemble_ctx *A, slang_operation *oper)
-{
-   slang_operation *decl;
-
-   assert(oper->type == SLANG_OPER_BLOCK_NEW_SCOPE ||
-          oper->type == SLANG_OPER_SEQUENCE);
-
-   decl = slang_operation_insert_child(oper, 1);
-
-   slang_generate_declaration(A, oper->locals, decl,
-                              SLANG_SPEC_BOOL, "__notRetFlag", GL_TRUE);
-
-   /*slang_print_tree(oper, 0);*/
-}
-
-
-/**
- * Recursively replace instances of the old node type with the new type.
- */
-static void
-replace_node_type(slang_operation *oper, slang_operation_type oldType,
-                  slang_operation_type newType)
-{
-   GLuint i;
-
-   if (oper->type == oldType)
-      oper->type = newType;
-
-   for (i = 0; i < slang_oper_num_children(oper); i++) {
-      replace_node_type(slang_oper_child(oper, i), oldType, newType);
-   }
-}
-
-
-
-/**
- * Test if the given function body has an "early return".  That is, there's
- * a 'return' statement that's not the very last instruction in the body.
- */
-static GLboolean
-has_early_return(const slang_operation *funcBody)
-{
-   GLuint retCount = _slang_count_node_type(funcBody, SLANG_OPER_RETURN);
-   if (retCount == 0)
-      return GL_FALSE;
-   else if (retCount == 1 && _slang_is_tail_return(funcBody))
-      return GL_FALSE;
-   else
-      return GL_TRUE;
-}
-
-
-/**
- * Emit IR code for a function call.  This does one of two things:
- * 1. Inline the function's code
- * 2. Create an IR for the function's body and create a real call to it.
- */
-static slang_ir_node *
-_slang_gen_function_call(slang_assemble_ctx *A, slang_function *fun,
-                         slang_operation *oper, slang_operation *dest)
-{
-   slang_ir_node *n;
-   slang_operation *instance;
-   slang_label *prevFuncEndLabel;
-   char name[200];
-
-   prevFuncEndLabel = A->curFuncEndLabel;
-   _mesa_snprintf(name, sizeof(name), "__endOfFunc_%s_", (char *) fun->header.a_name);
-   A->curFuncEndLabel = _slang_label_new(name);
-   assert(A->curFuncEndLabel);
-
-   /*
-    * 'instance' is basically a copy of the function's body with various
-    * transformations.
-    */
-
-   if (slang_is_asm_function(fun) && !dest) {
-      /* assemble assembly function - tree style */
-      instance = slang_inline_asm_function(A, fun, oper);
-   }
-   else {
-      /* non-assembly function */
-      /* We always generate an "inline-able" block of code here.
-       * We may either:
-       *  1. insert the inline code
-       *  2. Generate a call to the "inline" code as a subroutine
-       */
-      const GLboolean earlyReturn = has_early_return(fun->body);
-
-      if (earlyReturn && !A->EmitContReturn) {
-         A->UseReturnFlag = GL_TRUE;
-      }
-
-      instance = slang_inline_function_call(A, fun, oper, dest);
-      if (!instance)
-         return NULL;
-
-      if (earlyReturn) {
-         /* The function we're calling has one or more 'return' statements
-          * that prevent us from inlining the function's code.
-          *
-          * In this case, change the function's body type from
-          * SLANG_OPER_BLOCK_NEW_SCOPE to SLANG_OPER_NON_INLINED_CALL.
-          * During code emit this will result in a true subroutine call.
-          *
-          * Also, convert SLANG_OPER_RETURN_INLINED nodes to SLANG_OPER_RETURN.
-          */
-         slang_operation *callOper;
-
-         assert(instance->type == SLANG_OPER_BLOCK_NEW_SCOPE ||
-                instance->type == SLANG_OPER_SEQUENCE);
-
-         if (_slang_function_has_return_value(fun) && !dest) {
-            assert(instance->children[0].type == SLANG_OPER_VARIABLE_DECL);
-            assert(instance->children[2].type == SLANG_OPER_IDENTIFIER);
-            callOper = &instance->children[1];
-         }
-         else {
-            callOper = instance;
-         }
-
-         if (A->UseReturnFlag) {
-            /* Early returns not supported.  Create a _returnFlag variable
-             * that's set upon 'return' and tested elsewhere to no-op any
-             * remaining instructions in the subroutine.
-             */
-            assert(callOper->type == SLANG_OPER_BLOCK_NEW_SCOPE ||
-                   callOper->type == SLANG_OPER_SEQUENCE);
-            declare_return_flag(A, callOper);
-         }
-         else {
-            /* We can emit real 'return' statements.  If we generated any
-             * 'inline return' statements during function instantiation,
-             * change them back to regular 'return' statements.
-             */
-            replace_node_type(instance, SLANG_OPER_RETURN_INLINED,
-                              SLANG_OPER_RETURN);
-         }
-
-         callOper->type = SLANG_OPER_NON_INLINED_CALL;
-         callOper->fun = fun;
-         callOper->label = _slang_label_new_unique((char*) fun->header.a_name);
-      }
-      else {
-         /* If there are any 'return' statements remaining, they're at the
-          * very end of the function and can effectively become no-ops.
-          */
-         replace_node_type(instance, SLANG_OPER_RETURN_INLINED,
-                           SLANG_OPER_VOID);
-      }
-   }
-
-   if (!instance)
-      return NULL;
-
-   /* Replace the function call with the instance block (or new CALL stmt) */
-   slang_operation_destruct(oper);
-   *oper = *instance;
-   _slang_free(instance);
-
-#if 0
-   assert(instance->locals);
-   printf("*** Inlined code for call to %s:\n", (char*) fun->header.a_name);
-   slang_print_tree(oper, 10);
-   printf("\n");
-#endif
-
-   n = _slang_gen_operation(A, oper);
-
-   /*_slang_label_delete(A->curFuncEndLabel);*/
-   A->curFuncEndLabel = prevFuncEndLabel;
-
-   if (A->pragmas->Debug) {
-      char s[1000];
-      _mesa_snprintf(s, sizeof(s), "Call/inline %s()", (char *) fun->header.a_name);
-      n->Comment = _slang_strdup(s);
-   }
-
-   A->UseReturnFlag = GL_FALSE;
-
-   return n;
-}
-
-
-static slang_asm_info *
-slang_find_asm_info(const char *name)
-{
-   GLuint i;
-   for (i = 0; AsmInfo[i].Name; i++) {
-      if (strcmp(AsmInfo[i].Name, name) == 0) {
-         return AsmInfo + i;
-      }
-   }
-   return NULL;
-}
-
-
-/**
- * Some write-masked assignments are simple, but others are hard.
- * Simple example:
- *    vec3 v;
- *    v.xy = vec2(a, b);
- * Hard example:
- *    vec3 v;
- *    v.zy = vec2(a, b);
- * this gets transformed/swizzled into:
- *    v.zy = vec2(a, b).*yx*         (* = don't care)
- * This function helps to determine simple vs. non-simple.
- */
-static GLboolean
-_slang_simple_writemask(GLuint writemask, GLuint swizzle)
-{
-   switch (writemask) {
-   case WRITEMASK_X:
-      return GET_SWZ(swizzle, 0) == SWIZZLE_X;
-   case WRITEMASK_Y:
-      return GET_SWZ(swizzle, 1) == SWIZZLE_Y;
-   case WRITEMASK_Z:
-      return GET_SWZ(swizzle, 2) == SWIZZLE_Z;
-   case WRITEMASK_W:
-      return GET_SWZ(swizzle, 3) == SWIZZLE_W;
-   case WRITEMASK_XY:
-      return (GET_SWZ(swizzle, 0) == SWIZZLE_X)
-         && (GET_SWZ(swizzle, 1) == SWIZZLE_Y);
-   case WRITEMASK_XYZ:
-      return (GET_SWZ(swizzle, 0) == SWIZZLE_X)
-         && (GET_SWZ(swizzle, 1) == SWIZZLE_Y)
-         && (GET_SWZ(swizzle, 2) == SWIZZLE_Z);
-   case WRITEMASK_XYZW:
-      return swizzle == SWIZZLE_NOOP;
-   default:
-      return GL_FALSE;
-   }
-}
-
-
-/**
- * Convert the given swizzle into a writemask.  In some cases this
- * is trivial, in other cases, we'll need to also swizzle the right
- * hand side to put components in the right places.
- * See comment above for more info.
- * XXX this function could be simplified and should probably be renamed.
- * \param swizzle  the incoming swizzle
- * \param writemaskOut  returns the writemask
- * \param swizzleOut  swizzle to apply to the right-hand-side
- * \return GL_FALSE for simple writemasks, GL_TRUE for non-simple
- */
-static GLboolean
-swizzle_to_writemask(slang_assemble_ctx *A, GLuint swizzle,
-                     GLuint *writemaskOut, GLuint *swizzleOut)
-{
-   GLuint mask = 0x0, newSwizzle[4];
-   GLint i, size;
-
-   /* make new dst writemask, compute size */
-   for (i = 0; i < 4; i++) {
-      const GLuint swz = GET_SWZ(swizzle, i);
-      if (swz == SWIZZLE_NIL) {
-         /* end */
-         break;
-      }
-      assert(swz <= 3);
-
-      if (swizzle != SWIZZLE_XXXX &&
-          swizzle != SWIZZLE_YYYY &&
-          swizzle != SWIZZLE_ZZZZ &&
-          swizzle != SWIZZLE_WWWW &&
-          (mask & (1 << swz))) {
-         /* a channel can't be specified twice (ex: ".xyyz") */
-         slang_info_log_error(A->log, "Invalid writemask '%s'",
-                              _mesa_swizzle_string(swizzle, 0, 0));
-         return GL_FALSE;
-      }
-
-      mask |= (1 << swz);
-   }
-   assert(mask <= 0xf);
-   size = i;  /* number of components in mask/swizzle */
-
-   *writemaskOut = mask;
-
-   /* make new src swizzle, by inversion */
-   for (i = 0; i < 4; i++) {
-      newSwizzle[i] = i; /*identity*/
-   }
-   for (i = 0; i < size; i++) {
-      const GLuint swz = GET_SWZ(swizzle, i);
-      newSwizzle[swz] = i;
-   }
-   *swizzleOut = MAKE_SWIZZLE4(newSwizzle[0],
-                               newSwizzle[1],
-                               newSwizzle[2],
-                               newSwizzle[3]);
-
-   if (_slang_simple_writemask(mask, *swizzleOut)) {
-      if (size >= 1)
-         assert(GET_SWZ(*swizzleOut, 0) == SWIZZLE_X);
-      if (size >= 2)
-         assert(GET_SWZ(*swizzleOut, 1) == SWIZZLE_Y);
-      if (size >= 3)
-         assert(GET_SWZ(*swizzleOut, 2) == SWIZZLE_Z);
-      if (size >= 4)
-         assert(GET_SWZ(*swizzleOut, 3) == SWIZZLE_W);
-      return GL_TRUE;
-   }
-   else
-      return GL_FALSE;
-}
-
-
-#if 0 /* not used, but don't remove just yet */
-/**
- * Recursively traverse 'oper' to produce a swizzle mask in the event
- * of any vector subscripts and swizzle suffixes.
- * Ex:  for "vec4 v",  "v[2].x" resolves to v.z
- */
-static GLuint
-resolve_swizzle(const slang_operation *oper)
-{
-   if (oper->type == SLANG_OPER_FIELD) {
-      /* writemask from .xyzw suffix */
-      slang_swizzle swz;
-      if (_slang_is_swizzle((char*) oper->a_id, 4, &swz)) {
-         GLuint swizzle = MAKE_SWIZZLE4(swz.swizzle[0],
-                                        swz.swizzle[1],
-                                        swz.swizzle[2],
-                                        swz.swizzle[3]);
-         GLuint child_swizzle = resolve_swizzle(&oper->children[0]);
-         GLuint s = _slang_swizzle_swizzle(child_swizzle, swizzle);
-         return s;
-      }
-      else
-         return SWIZZLE_XYZW;
-   }
-   else if (oper->type == SLANG_OPER_SUBSCRIPT &&
-            oper->children[1].type == SLANG_OPER_LITERAL_INT) {
-      /* writemask from [index] */
-      GLuint child_swizzle = resolve_swizzle(&oper->children[0]);
-      GLuint i = (GLuint) oper->children[1].literal[0];
-      GLuint swizzle;
-      GLuint s;
-      switch (i) {
-      case 0:
-         swizzle = SWIZZLE_XXXX;
-         break;
-      case 1:
-         swizzle = SWIZZLE_YYYY;
-         break;
-      case 2:
-         swizzle = SWIZZLE_ZZZZ;
-         break;
-      case 3:
-         swizzle = SWIZZLE_WWWW;
-         break;
-      default:
-         swizzle = SWIZZLE_XYZW;
-      }
-      s = _slang_swizzle_swizzle(child_swizzle, swizzle);
-      return s;
-   }
-   else {
-      return SWIZZLE_XYZW;
-   }
-}
-#endif
-
-
-#if 0
-/**
- * Recursively descend through swizzle nodes to find the node's storage info.
- */
-static slang_ir_storage *
-get_store(const slang_ir_node *n)
-{
-   if (n->Opcode == IR_SWIZZLE) {
-      return get_store(n->Children[0]);
-   }
-   return n->Store;
-}
-#endif
-
-
-/**
- * Generate IR tree for an asm instruction/operation such as:
- *    __asm vec4_dot __retVal.x, v1, v2;
- */
-static slang_ir_node *
-_slang_gen_asm(slang_assemble_ctx *A, slang_operation *oper,
-               slang_operation *dest)
-{
-   const slang_asm_info *info;
-   slang_ir_node *kids[3], *n;
-   GLuint j, firstOperand;
-
-   assert(oper->type == SLANG_OPER_ASM);
-
-   info = slang_find_asm_info((char *) oper->a_id);
-   if (!info) {
-      _mesa_problem(NULL, "undefined __asm function %s\n",
-                    (char *) oper->a_id);
-      assert(info);
-      return NULL;
-   }
-   assert(info->NumParams <= 3);
-
-   if (info->NumParams == oper->num_children) {
-      /* Storage for result is not specified.
-       * Children[0], [1], [2] are the operands.
-       */
-      firstOperand = 0;
-   }
-   else {
-      /* Storage for result (child[0]) is specified.
-       * Children[1], [2], [3] are the operands.
-       */
-      firstOperand = 1;
-   }
-
-   /* assemble child(ren) */
-   kids[0] = kids[1] = kids[2] = NULL;
-   for (j = 0; j < info->NumParams; j++) {
-      kids[j] = _slang_gen_operation(A, &oper->children[firstOperand + j]);
-      if (!kids[j])
-         return NULL;
-   }
-
-   n = new_node3(info->Opcode, kids[0], kids[1], kids[2]);
-
-   if (firstOperand) {
-      /* Setup n->Store to be a particular location.  Otherwise, storage
-       * for the result (a temporary) will be allocated later.
-       */
-      slang_operation *dest_oper;
-      slang_ir_node *n0;
-
-      dest_oper = &oper->children[0];
-
-      n0 = _slang_gen_operation(A, dest_oper);
-      if (!n0)
-         return NULL;
-
-      assert(!n->Store);
-      n->Store = n0->Store;
-
-      assert(n->Store->File != PROGRAM_UNDEFINED || n->Store->Parent);
-
-      _slang_free(n0);
-   }
-
-   return n;
-}
-
-
-#if 0
-static void
-print_funcs(struct slang_function_scope_ *scope, const char *name)
-{
-   GLuint i;
-   for (i = 0; i < scope->num_functions; i++) {
-      slang_function *f = &scope->functions[i];
-      if (!name || strcmp(name, (char*) f->header.a_name) == 0)
-          printf("  %s (%d args)\n", name, f->param_count);
-
-   }
-   if (scope->outer_scope)
-      print_funcs(scope->outer_scope, name);
-}
-#endif
-
-
-/**
- * Find a function of the given name, taking 'numArgs' arguments.
- * This is the function we'll try to call when there is no exact match
- * between function parameters and call arguments.
- *
- * XXX we should really create a list of candidate functions and try
- * all of them...
- */
-static slang_function *
-_slang_find_function_by_argc(slang_function_scope *scope,
-                             const char *name, int numArgs)
-{
-   while (scope) {
-      GLuint i;
-      for (i = 0; i < scope->num_functions; i++) {
-         slang_function *f = &scope->functions[i];
-         if (strcmp(name, (char*) f->header.a_name) == 0) {
-            int haveRetValue = _slang_function_has_return_value(f);
-            if (numArgs == f->param_count - haveRetValue)
-               return f;
-         }
-      }
-      scope = scope->outer_scope;
-   }
-
-   return NULL;
-}
-
-
-static slang_function *
-_slang_find_function_by_max_argc(slang_function_scope *scope,
-                                 const char *name)
-{
-   slang_function *maxFunc = NULL;
-   GLuint maxArgs = 0;
-
-   while (scope) {
-      GLuint i;
-      for (i = 0; i < scope->num_functions; i++) {
-         slang_function *f = &scope->functions[i];
-         if (strcmp(name, (char*) f->header.a_name) == 0) {
-            if (f->param_count > maxArgs) {
-               maxArgs = f->param_count;
-               maxFunc = f;
-            }
-         }
-      }
-      scope = scope->outer_scope;
-   }
-
-   return maxFunc;
-}
-
-
-/**
- * Generate a new slang_function which is a constructor for a user-defined
- * struct type.
- */
-static slang_function *
-_slang_make_struct_constructor(slang_assemble_ctx *A, slang_struct *str)
-{
-   const GLint numFields = str->fields->num_variables;
-   slang_function *fun = slang_function_new(SLANG_FUNC_CONSTRUCTOR);
-
-   /* function header (name, return type) */
-   fun->header.a_name = str->a_name;
-   fun->header.type.qualifier = SLANG_QUAL_NONE;
-   fun->header.type.specifier.type = SLANG_SPEC_STRUCT;
-   fun->header.type.specifier._struct = str;
-
-   /* function parameters (= struct's fields) */
-   {
-      GLint i;
-      for (i = 0; i < numFields; i++) {
-         /*
-         printf("Field %d: %s\n", i, (char*) str->fields->variables[i]->a_name);
-         */
-         slang_variable *p = slang_variable_scope_grow(fun->parameters);
-         *p = *str->fields->variables[i]; /* copy the variable and type */
-         p->type.qualifier = SLANG_QUAL_CONST;
-      }
-      fun->param_count = fun->parameters->num_variables;
-   }
-
-   /* Add __retVal to params */
-   {
-      slang_variable *p = slang_variable_scope_grow(fun->parameters);
-      slang_atom a_retVal = slang_atom_pool_atom(A->atoms, "__retVal");
-      assert(a_retVal);
-      p->a_name = a_retVal;
-      p->type = fun->header.type;
-      p->type.qualifier = SLANG_QUAL_OUT;
-      fun->param_count++;
-   }
-
-   /* function body is:
-    *    block:
-    *       declare T;
-    *       T.f1 = p1;
-    *       T.f2 = p2;
-    *       ...
-    *       T.fn = pn;
-    *       return T;
-    */
-   {
-      slang_variable_scope *scope;
-      slang_variable *var;
-      GLint i;
-
-      fun->body = slang_operation_new(1);
-      fun->body->type = SLANG_OPER_BLOCK_NEW_SCOPE;
-      fun->body->num_children = numFields + 2;
-      fun->body->children = slang_operation_new(numFields + 2);
-
-      scope = fun->body->locals;
-      scope->outer_scope = fun->parameters;
-
-      /* create local var 't' */
-      var = slang_variable_scope_grow(scope);
-      var->a_name = slang_atom_pool_atom(A->atoms, "t");
-      var->type = fun->header.type;
-
-      /* declare t */
-      {
-         slang_operation *decl;
-
-         decl = &fun->body->children[0];
-         decl->type = SLANG_OPER_VARIABLE_DECL;
-         decl->locals = _slang_variable_scope_new(scope);
-         decl->a_id = var->a_name;
-      }
-
-      /* assign params to fields of t */
-      for (i = 0; i < numFields; i++) {
-         slang_operation *assign = &fun->body->children[1 + i];
-
-         assign->type = SLANG_OPER_ASSIGN;
-         assign->locals = _slang_variable_scope_new(scope);
-         assign->num_children = 2;
-         assign->children = slang_operation_new(2);
-         
-         {
-            slang_operation *lhs = &assign->children[0];
-
-            lhs->type = SLANG_OPER_FIELD;
-            lhs->locals = _slang_variable_scope_new(scope);
-            lhs->num_children = 1;
-            lhs->children = slang_operation_new(1);
-            lhs->a_id = str->fields->variables[i]->a_name;
-
-            lhs->children[0].type = SLANG_OPER_IDENTIFIER;
-            lhs->children[0].a_id = var->a_name;
-            lhs->children[0].locals = _slang_variable_scope_new(scope);
-
-#if 0
-            lhs->children[1].num_children = 1;
-            lhs->children[1].children = slang_operation_new(1);
-            lhs->children[1].children[0].type = SLANG_OPER_IDENTIFIER;
-            lhs->children[1].children[0].a_id = str->fields->variables[i]->a_name;
-            lhs->children[1].children->locals = _slang_variable_scope_new(scope);
-#endif
-         }
-
-         {
-            slang_operation *rhs = &assign->children[1];
-
-            rhs->type = SLANG_OPER_IDENTIFIER;
-            rhs->locals = _slang_variable_scope_new(scope);
-            rhs->a_id = str->fields->variables[i]->a_name;
-         }         
-      }
-
-      /* return t; */
-      {
-         slang_operation *ret = &fun->body->children[numFields + 1];
-
-         ret->type = SLANG_OPER_RETURN;
-         ret->locals = _slang_variable_scope_new(scope);
-         ret->num_children = 1;
-         ret->children = slang_operation_new(1);
-         ret->children[0].type = SLANG_OPER_IDENTIFIER;
-         ret->children[0].a_id = var->a_name;
-         ret->children[0].locals = _slang_variable_scope_new(scope);
-      }
-   }
-   /*
-   slang_print_function(fun, 1);
-   */
-   return fun;
-}
-
-
-/**
- * Find/create a function (constructor) for the given structure name.
- */
-static slang_function *
-_slang_locate_struct_constructor(slang_assemble_ctx *A, const char *name)
-{
-   unsigned int i;
-   for (i = 0; i < A->space.structs->num_structs; i++) {
-      slang_struct *str = &A->space.structs->structs[i];
-      if (strcmp(name, (const char *) str->a_name) == 0) {
-         /* found a structure type that matches the function name */
-         if (!str->constructor) {
-            /* create the constructor function now */
-            str->constructor = _slang_make_struct_constructor(A, str);
-         }
-         return str->constructor;
-      }
-   }
-   return NULL;
-}
-
-
-/**
- * Generate a new slang_function to satisfy a call to an array constructor.
- * Ex:  float[3](1., 2., 3.)
- */
-static slang_function *
-_slang_make_array_constructor(slang_assemble_ctx *A, slang_operation *oper)
-{
-   slang_type_specifier_type baseType;
-   slang_function *fun;
-   int num_elements;
-
-   fun = slang_function_new(SLANG_FUNC_CONSTRUCTOR);
-   if (!fun)
-      return NULL;
-
-   baseType = slang_type_specifier_type_from_string((char *) oper->a_id);
-
-   num_elements = oper->num_children;
-
-   /* function header, return type */
-   {
-      fun->header.a_name = oper->a_id;
-      fun->header.type.qualifier = SLANG_QUAL_NONE;
-      fun->header.type.specifier.type = SLANG_SPEC_ARRAY;
-      fun->header.type.specifier._array =
-         slang_type_specifier_new(baseType, NULL, NULL);
-      fun->header.type.array_len = num_elements;
-   }
-
-   /* function parameters (= number of elements) */
-   {
-      GLint i;
-      for (i = 0; i < num_elements; i++) {
-         /*
-         printf("Field %d: %s\n", i, (char*) str->fields->variables[i]->a_name);
-         */
-         slang_variable *p = slang_variable_scope_grow(fun->parameters);
-         char name[10];
-         _mesa_snprintf(name, sizeof(name), "p%d", i);
-         p->a_name = slang_atom_pool_atom(A->atoms, name);
-         p->type.qualifier = SLANG_QUAL_CONST;
-         p->type.specifier.type = baseType;
-      }
-      fun->param_count = fun->parameters->num_variables;
-   }
-
-   /* Add __retVal to params */
-   {
-      slang_variable *p = slang_variable_scope_grow(fun->parameters);
-      slang_atom a_retVal = slang_atom_pool_atom(A->atoms, "__retVal");
-      assert(a_retVal);
-      p->a_name = a_retVal;
-      p->type = fun->header.type;
-      p->type.qualifier = SLANG_QUAL_OUT;
-      p->type.specifier.type = baseType;
-      fun->param_count++;
-   }
-
-   /* function body is:
-    *    block:
-    *       declare T;
-    *       T[0] = p0;
-    *       T[1] = p1;
-    *       ...
-    *       T[n] = pn;
-    *       return T;
-    */
-   {
-      slang_variable_scope *scope;
-      slang_variable *var;
-      GLint i;
-
-      fun->body = slang_operation_new(1);
-      fun->body->type = SLANG_OPER_BLOCK_NEW_SCOPE;
-      fun->body->num_children = num_elements + 2;
-      fun->body->children = slang_operation_new(num_elements + 2);
-
-      scope = fun->body->locals;
-      scope->outer_scope = fun->parameters;
-
-      /* create local var 't' */
-      var = slang_variable_scope_grow(scope);
-      var->a_name = slang_atom_pool_atom(A->atoms, "ttt");
-      var->type = fun->header.type;/*XXX copy*/
-
-      /* declare t */
-      {
-         slang_operation *decl;
-
-         decl = &fun->body->children[0];
-         decl->type = SLANG_OPER_VARIABLE_DECL;
-         decl->locals = _slang_variable_scope_new(scope);
-         decl->a_id = var->a_name;
-      }
-
-      /* assign params to elements of t */
-      for (i = 0; i < num_elements; i++) {
-         slang_operation *assign = &fun->body->children[1 + i];
-
-         assign->type = SLANG_OPER_ASSIGN;
-         assign->locals = _slang_variable_scope_new(scope);
-         assign->num_children = 2;
-         assign->children = slang_operation_new(2);
-         
-         {
-            slang_operation *lhs = &assign->children[0];
-
-            lhs->type = SLANG_OPER_SUBSCRIPT;
-            lhs->locals = _slang_variable_scope_new(scope);
-            lhs->num_children = 2;
-            lhs->children = slang_operation_new(2);
-            lhs->children[0].type = SLANG_OPER_IDENTIFIER;
-            lhs->children[0].a_id = var->a_name;
-            lhs->children[0].locals = _slang_variable_scope_new(scope);
-
-            lhs->children[1].type = SLANG_OPER_LITERAL_INT;
-            lhs->children[1].literal[0] = (GLfloat) i;
-         }
-
-         {
-            slang_operation *rhs = &assign->children[1];
-
-            rhs->type = SLANG_OPER_IDENTIFIER;
-            rhs->locals = _slang_variable_scope_new(scope);
-            rhs->a_id = fun->parameters->variables[i]->a_name;
-         }         
-      }
-
-      /* return t; */
-      {
-         slang_operation *ret = &fun->body->children[num_elements + 1];
-
-         ret->type = SLANG_OPER_RETURN;
-         ret->locals = _slang_variable_scope_new(scope);
-         ret->num_children = 1;
-         ret->children = slang_operation_new(1);
-         ret->children[0].type = SLANG_OPER_IDENTIFIER;
-         ret->children[0].a_id = var->a_name;
-         ret->children[0].locals = _slang_variable_scope_new(scope);
-      }
-   }
-
-   /*
-   slang_print_function(fun, 1);
-   */
-
-   return fun;
-}
-
-
-static GLboolean
-_slang_is_vec_mat_type(const char *name)
-{
-   static const char *vecmat_types[] = {
-      "float", "int", "bool",
-      "vec2", "vec3", "vec4",
-      "ivec2", "ivec3", "ivec4",
-      "bvec2", "bvec3", "bvec4",
-      "mat2", "mat3", "mat4",
-      "mat2x3", "mat2x4", "mat3x2", "mat3x4", "mat4x2", "mat4x3",
-      NULL
-   };
-   int i;
-   for (i = 0; vecmat_types[i]; i++)
-      if (strcmp(name, vecmat_types[i]) == 0)
-         return GL_TRUE;
-   return GL_FALSE;
-}
-
-
-/**
- * Assemble a function call, given a particular function name.
- * \param name  the function's name (operators like '*' are possible).
- */
-static slang_ir_node *
-_slang_gen_function_call_name(slang_assemble_ctx *A, const char *name,
-                              slang_operation *oper, slang_operation *dest)
-{
-   slang_operation *params = oper->children;
-   const GLuint param_count = oper->num_children;
-   slang_atom atom;
-   slang_function *fun;
-   slang_ir_node *n;
-
-   atom = slang_atom_pool_atom(A->atoms, name);
-   if (atom == SLANG_ATOM_NULL)
-      return NULL;
-
-   if (oper->array_constructor) {
-      /* this needs special handling */
-      fun = _slang_make_array_constructor(A, oper);
-   }
-   else {
-      /* Try to find function by name and exact argument type matching */
-      GLboolean error = GL_FALSE;
-      fun = _slang_function_locate(A->space.funcs, atom, params, param_count,
-                                   &A->space, A->atoms, A->log, &error);
-      if (error) {
-         slang_info_log_error(A->log,
-                              "Function '%s' not found (check argument types)",
-                              name);
-         return NULL;
-      }
-   }
-
-   if (!fun) {
-      /* Next, try locating a constructor function for a user-defined type */
-      fun = _slang_locate_struct_constructor(A, name);
-   }
-
-   /*
-    * At this point, some heuristics are used to try to find a function
-    * that matches the calling signature by means of casting or "unrolling"
-    * of constructors.
-    */
-
-   if (!fun && _slang_is_vec_mat_type(name)) {
-      /* Next, if this call looks like a vec() or mat() constructor call,
-       * try "unwinding" the args to satisfy a constructor.
-       */
-      fun = _slang_find_function_by_max_argc(A->space.funcs, name);
-      if (fun) {
-         if (!_slang_adapt_call(oper, fun, &A->space, A->atoms, A->log)) {
-            slang_info_log_error(A->log,
-                                 "Function '%s' not found (check argument types)",
-                                 name);
-            return NULL;
-         }
-      }
-   }
-
-   if (!fun && _slang_is_vec_mat_type(name)) {
-      /* Next, try casting args to the types of the formal parameters */
-      int numArgs = oper->num_children;
-      fun = _slang_find_function_by_argc(A->space.funcs, name, numArgs);
-      if (!fun || !_slang_cast_func_params(oper, fun, &A->space, A->atoms, A->log)) {
-         slang_info_log_error(A->log,
-                              "Function '%s' not found (check argument types)",
-                              name);
-         return NULL;
-      }
-      assert(fun);
-   }
-
-   if (!fun) {
-      slang_info_log_error(A->log,
-                           "Function '%s' not found (check argument types)",
-                           name);
-      return NULL;
-   }
-
-   if (!fun->body) {
-      /* The function body may be in another compilation unit.
-       * We'll try concatenating the shaders and recompile at link time.
-       */
-      A->UnresolvedRefs = GL_TRUE;
-      return new_node1(IR_NOP, NULL);
-   }
-
-   /* type checking to be sure function's return type matches 'dest' type */
-   if (dest) {
-      slang_typeinfo t0;
-
-      slang_typeinfo_construct(&t0);
-      typeof_operation(A, dest, &t0);
-
-      if (!slang_type_specifier_equal(&t0.spec, &fun->header.type.specifier)) {
-         slang_info_log_error(A->log,
-                              "Incompatible type returned by call to '%s'",
-                              name);
-         return NULL;
-      }
-   }
-
-   n = _slang_gen_function_call(A, fun, oper, dest);
-
-   if (n && !n->Store && !dest
-       && fun->header.type.specifier.type != SLANG_SPEC_VOID) {
-      /* setup n->Store for the result of the function call */
-      GLint size = _slang_sizeof_type_specifier(&fun->header.type.specifier);
-      n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, size);
-      /*printf("Alloc storage for function result, size %d \n", size);*/
-   }
-
-   if (oper->array_constructor) {
-      /* free the temporary array constructor function now */
-      slang_function_destruct(fun);
-   }
-
-   return n;
-}
-
-
-static slang_ir_node *
-_slang_gen_method_call(slang_assemble_ctx *A, slang_operation *oper)
-{
-   slang_atom *a_length = slang_atom_pool_atom(A->atoms, "length");
-   slang_ir_node *n;
-   slang_variable *var;
-
-   /* NOTE: In GLSL 1.20, there's only one kind of method
-    * call: array.length().  Anything else is an error.
-    */
-   if (oper->a_id != a_length) {
-      slang_info_log_error(A->log,
-                           "Undefined method call '%s'", (char *) oper->a_id);
-      return NULL;
-   }
-
-   /* length() takes no arguments */
-   if (oper->num_children > 0) {
-      slang_info_log_error(A->log, "Invalid arguments to length() method");
-      return NULL;
-   }
-
-   /* lookup the object/variable */
-   var = _slang_variable_locate(oper->locals, oper->a_obj, GL_TRUE);
-   if (!var || var->type.specifier.type != SLANG_SPEC_ARRAY) {
-      slang_info_log_error(A->log,
-                           "Undefined object '%s'", (char *) oper->a_obj);
-      return NULL;
-   }
-
-   /* Create a float/literal IR node encoding the array length */
-   n = new_node0(IR_FLOAT);
-   if (n) {
-      n->Value[0] = (float) _slang_array_length(var);
-      n->Store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, 1);
-   }
-   return n;
-}
-
-
-static GLboolean
-_slang_is_constant_cond(const slang_operation *oper, GLboolean *value)
-{
-   if (oper->type == SLANG_OPER_LITERAL_FLOAT ||
-       oper->type == SLANG_OPER_LITERAL_INT ||
-       oper->type == SLANG_OPER_LITERAL_BOOL) {
-      if (oper->literal[0])
-         *value = GL_TRUE;
-      else
-         *value = GL_FALSE;
-      return GL_TRUE;
-   }
-   else if (oper->type == SLANG_OPER_EXPRESSION &&
-            oper->num_children == 1) {
-      return _slang_is_constant_cond(&oper->children[0], value);
-   }
-   return GL_FALSE;
-}
-
-
-/**
- * Test if an operation is a scalar or boolean.
- */
-static GLboolean
-_slang_is_scalar_or_boolean(slang_assemble_ctx *A, slang_operation *oper)
-{
-   slang_typeinfo type;
-   GLint size;
-
-   slang_typeinfo_construct(&type);
-   typeof_operation(A, oper, &type);
-   size = _slang_sizeof_type_specifier(&type.spec);
-   slang_typeinfo_destruct(&type);
-   return size == 1;
-}
-
-
-/**
- * Test if an operation is boolean.
- */
-static GLboolean
-_slang_is_boolean(slang_assemble_ctx *A, slang_operation *oper)
-{
-   slang_typeinfo type;
-   GLboolean isBool;
-
-   slang_typeinfo_construct(&type);
-   typeof_operation(A, oper, &type);
-   isBool = (type.spec.type == SLANG_SPEC_BOOL);
-   slang_typeinfo_destruct(&type);
-   return isBool;
-}
-
-
-/**
- * Check if a loop contains a 'continue' statement.
- * Stop looking if we find a nested loop.
- */
-static GLboolean
-_slang_loop_contains_continue(const slang_operation *oper)
-{
-   switch (oper->type) {
-   case SLANG_OPER_CONTINUE:
-      return GL_TRUE;
-   case SLANG_OPER_FOR:
-   case SLANG_OPER_DO:
-   case SLANG_OPER_WHILE:
-      /* stop upon finding a nested loop */
-      return GL_FALSE;
-   default:
-       /* recurse */
-      {
-         GLuint i;
-         for (i = 0; i < oper->num_children; i++) {
-            const slang_operation *child = slang_oper_child_const(oper, i);
-            if (_slang_loop_contains_continue(child))
-               return GL_TRUE;
-         }
-      }
-      return GL_FALSE;
-   }
-}
-
-
-/**
- * Check if a loop contains a 'continue' or 'break' statement.
- * Stop looking if we find a nested loop.
- */
-static GLboolean
-_slang_loop_contains_continue_or_break(const slang_operation *oper)
-{
-   switch (oper->type) {
-   case SLANG_OPER_CONTINUE:
-   case SLANG_OPER_BREAK:
-      return GL_TRUE;
-   case SLANG_OPER_FOR:
-   case SLANG_OPER_DO:
-   case SLANG_OPER_WHILE:
-      /* stop upon finding a nested loop */
-      return GL_FALSE;
-   default:
-       /* recurse */
-      {
-         GLuint i;
-         for (i = 0; i < oper->num_children; i++) {
-            const slang_operation *child = slang_oper_child_const(oper, i);
-            if (_slang_loop_contains_continue_or_break(child))
-               return GL_TRUE;
-         }
-      }
-      return GL_FALSE;
-   }
-}
-
-
-/**
- * Replace 'break' and 'continue' statements inside a do and while loops.
- * This is a recursive helper function used by
- * _slang_gen_do/while_without_continue().
- */
-static void
-replace_break_and_cont(slang_assemble_ctx *A, slang_operation *oper)
-{
-   switch (oper->type) {
-   case SLANG_OPER_BREAK:
-      /* replace 'break' with "_notBreakFlag = false; break" */
-      {
-         slang_operation *block = oper;
-         block->type = SLANG_OPER_BLOCK_NEW_SCOPE;
-         slang_operation_add_children(block, 2);
-         {
-            slang_operation *assign = slang_oper_child(block, 0);
-            assign->type = SLANG_OPER_ASSIGN;
-            slang_operation_add_children(assign, 2);
-            {
-               slang_operation *lhs = slang_oper_child(assign, 0);
-               slang_operation_identifier(lhs, A, "_notBreakFlag");
-            }
-            {
-               slang_operation *rhs = slang_oper_child(assign, 1);
-               slang_operation_literal_bool(rhs, GL_FALSE);
-            }
-         }
-         {
-            slang_operation *brk = slang_oper_child(block, 1);
-            brk->type = SLANG_OPER_BREAK;
-            assert(!brk->children);
-         }
-      }
-      break;
-   case SLANG_OPER_CONTINUE:
-      /* convert continue into a break */
-      oper->type = SLANG_OPER_BREAK;
-      break;
-   case SLANG_OPER_FOR:
-   case SLANG_OPER_DO:
-   case SLANG_OPER_WHILE:
-      /* stop upon finding a nested loop */
-      break;
-   default:
-      /* recurse */
-      {
-         GLuint i;
-         for (i = 0; i < oper->num_children; i++) {
-            replace_break_and_cont(A, slang_oper_child(oper, i));
-         }
-      }
-   }
-}
-
-
-/**
- * Transform a while-loop so that continue statements are converted to breaks.
- * Then do normal IR code generation.
- *
- * Before:
- * 
- * while (LOOPCOND) {
- *    A;
- *    if (IFCOND)
- *       continue;
- *    B;
- *    break;
- *    C;
- * }
- * 
- * After:
- * 
- * {
- *    bool _notBreakFlag = 1;
- *    while (_notBreakFlag && LOOPCOND) {
- *       do {
- *          A;
- *          if (IFCOND) {
- *             break;  // was continue
- *          }
- *          B;
- *          _notBreakFlag = 0; // was
- *          break;             // break
- *          C;
- *       } while (0)
- *    }
- * }
- */
-static slang_ir_node *
-_slang_gen_while_without_continue(slang_assemble_ctx *A, slang_operation *oper)
-{
-   slang_operation *top;
-   slang_operation *innerBody;
-
-   assert(oper->type == SLANG_OPER_WHILE);
-
-   top = slang_operation_new(1);
-   top->type = SLANG_OPER_BLOCK_NEW_SCOPE;
-   top->locals->outer_scope = oper->locals->outer_scope;
-   slang_operation_add_children(top, 2);
-
-   /* declare: bool _notBreakFlag = true */
-   {
-      slang_operation *condDecl = slang_oper_child(top, 0);
-      slang_generate_declaration(A, top->locals, condDecl,
-                                 SLANG_SPEC_BOOL, "_notBreakFlag", GL_TRUE);
-   }
-
-   /* build outer while-loop:  while (_notBreakFlag && LOOPCOND) { ... } */
-   {
-      slang_operation *outerWhile = slang_oper_child(top, 1);
-      outerWhile->type = SLANG_OPER_WHILE;
-      slang_operation_add_children(outerWhile, 2);
-
-      /* _notBreakFlag && LOOPCOND */
-      {
-         slang_operation *cond = slang_oper_child(outerWhile, 0);
-         cond->type = SLANG_OPER_LOGICALAND;
-         slang_operation_add_children(cond, 2);
-         {
-            slang_operation *notBreak = slang_oper_child(cond, 0);
-            slang_operation_identifier(notBreak, A, "_notBreakFlag");
-         }
-         {
-            slang_operation *origCond = slang_oper_child(cond, 1);
-            slang_operation_copy(origCond, slang_oper_child(oper, 0));
-         }
-      }
-
-      /* inner loop */
-      {
-         slang_operation *innerDo = slang_oper_child(outerWhile, 1);
-         innerDo->type = SLANG_OPER_DO;
-         slang_operation_add_children(innerDo, 2);
-
-         /* copy original do-loop body into inner do-loop's body */
-         innerBody = slang_oper_child(innerDo, 0);
-         slang_operation_copy(innerBody, slang_oper_child(oper, 1));
-         innerBody->locals->outer_scope = innerDo->locals;
-
-         /* inner do-loop's condition is constant/false */
-         {
-            slang_operation *constFalse = slang_oper_child(innerDo, 1);
-            slang_operation_literal_bool(constFalse, GL_FALSE);
-         }
-      }
-   }
-
-   /* Finally, in innerBody,
-    *   replace "break" with "_notBreakFlag = 0; break"
-    *   replace "continue" with "break"
-    */
-   replace_break_and_cont(A, innerBody);
-
-   /*slang_print_tree(top, 0);*/
-
-   return _slang_gen_operation(A, top);
-
-   return NULL;
-}
-
-
-/**
- * Generate loop code using high-level IR_LOOP instruction
- */
-static slang_ir_node *
-_slang_gen_while(slang_assemble_ctx * A, slang_operation *oper)
-{
-   /*
-    * LOOP:
-    *    BREAK if !expr (child[0])
-    *    body code (child[1])
-    */
-   slang_ir_node *loop, *breakIf, *body;
-   GLboolean isConst, constTrue = GL_FALSE;
-
-   if (!A->EmitContReturn) {
-      /* We don't want to emit CONT instructions.  If this while-loop has
-       * a continue, translate it away.
-       */
-      if (_slang_loop_contains_continue(slang_oper_child(oper, 1))) {
-         return _slang_gen_while_without_continue(A, oper);
-      }
-   }
-
-   /* type-check expression */
-   if (!_slang_is_boolean(A, &oper->children[0])) {
-      slang_info_log_error(A->log, "scalar/boolean expression expected for 'while'");
-      return NULL;
-   }
-
-   /* Check if loop condition is a constant */
-   isConst = _slang_is_constant_cond(&oper->children[0], &constTrue);
-
-   if (isConst && !constTrue) {
-      /* loop is never executed! */
-      return new_node0(IR_NOP);
-   }
-
-   /* Begin new loop */
-   loop = new_loop(NULL);
-
-   /* save loop state */
-   push_loop(A, oper, loop);
-
-   if (isConst && constTrue) {
-      /* while(nonzero constant), no conditional break */
-      breakIf = NULL;
-   }
-   else {
-      slang_ir_node *cond
-         = new_cond(new_not(_slang_gen_operation(A, &oper->children[0])));
-      breakIf = new_break_if_true(A, cond);
-   }
-   body = _slang_gen_operation(A, &oper->children[1]);
-   loop->Children[0] = new_seq(breakIf, body);
-
-   /* Do infinite loop detection */
-   /* loop->List is head of linked list of break/continue nodes */
-   if (!loop->List && isConst && constTrue) {
-      /* infinite loop detected */
-      pop_loop(A);
-      slang_info_log_error(A->log, "Infinite loop detected!");
-      return NULL;
-   }
-
-   /* restore loop state */
-   pop_loop(A);
-
-   return loop;
-}
-
-
-/**
- * Transform a do-while-loop so that continue statements are converted to breaks.
- * Then do normal IR code generation.
- *
- * Before:
- * 
- * do {
- *    A;
- *    if (IFCOND)
- *       continue;
- *    B;
- *    break;
- *    C;
- * } while (LOOPCOND);
- * 
- * After:
- * 
- * {
- *    bool _notBreakFlag = 1;
- *    do {
- *       do {
- *          A;
- *          if (IFCOND) {
- *             break;  // was continue
- *          }
- *          B;
- *          _notBreakFlag = 0; // was
- *          break;             // break
- *          C;
- *       } while (0)
- *    } while (_notBreakFlag && LOOPCOND);
- * }
- */
-static slang_ir_node *
-_slang_gen_do_without_continue(slang_assemble_ctx *A, slang_operation *oper)
-{
-   slang_operation *top;
-   slang_operation *innerBody;
-
-   assert(oper->type == SLANG_OPER_DO);
-
-   top = slang_operation_new(1);
-   top->type = SLANG_OPER_BLOCK_NEW_SCOPE;
-   top->locals->outer_scope = oper->locals->outer_scope;
-   slang_operation_add_children(top, 2);
-
-   /* declare: bool _notBreakFlag = true */
-   {
-      slang_operation *condDecl = slang_oper_child(top, 0);
-      slang_generate_declaration(A, top->locals, condDecl,
-                                 SLANG_SPEC_BOOL, "_notBreakFlag", GL_TRUE);
-   }
-
-   /* build outer do-loop:  do { ... } while (_notBreakFlag && LOOPCOND) */
-   {
-      slang_operation *outerDo = slang_oper_child(top, 1);
-      outerDo->type = SLANG_OPER_DO;
-      slang_operation_add_children(outerDo, 2);
-
-      /* inner do-loop */
-      {
-         slang_operation *innerDo = slang_oper_child(outerDo, 0);
-         innerDo->type = SLANG_OPER_DO;
-         slang_operation_add_children(innerDo, 2);
-
-         /* copy original do-loop body into inner do-loop's body */
-         innerBody = slang_oper_child(innerDo, 0);
-         slang_operation_copy(innerBody, slang_oper_child(oper, 0));
-         innerBody->locals->outer_scope = innerDo->locals;
-
-         /* inner do-loop's condition is constant/false */
-         {
-            slang_operation *constFalse = slang_oper_child(innerDo, 1);
-            slang_operation_literal_bool(constFalse, GL_FALSE);
-         }
-      }
-
-      /* _notBreakFlag && LOOPCOND */
-      {
-         slang_operation *cond = slang_oper_child(outerDo, 1);
-         cond->type = SLANG_OPER_LOGICALAND;
-         slang_operation_add_children(cond, 2);
-         {
-            slang_operation *notBreak = slang_oper_child(cond, 0);
-            slang_operation_identifier(notBreak, A, "_notBreakFlag");
-         }
-         {
-            slang_operation *origCond = slang_oper_child(cond, 1);
-            slang_operation_copy(origCond, slang_oper_child(oper, 1));
-         }
-      }
-   }
-
-   /* Finally, in innerBody,
-    *   replace "break" with "_notBreakFlag = 0; break"
-    *   replace "continue" with "break"
-    */
-   replace_break_and_cont(A, innerBody);
-
-   /*slang_print_tree(top, 0);*/
-
-   return _slang_gen_operation(A, top);
-}
-
-
-/**
- * Generate IR tree for a do-while loop using high-level LOOP, IF instructions.
- */
-static slang_ir_node *
-_slang_gen_do(slang_assemble_ctx * A, slang_operation *oper)
-{
-   /*
-    * LOOP:
-    *    body code (child[0])
-    *    tail code:
-    *       BREAK if !expr (child[1])
-    */
-   slang_ir_node *loop;
-   GLboolean isConst, constTrue;
-
-   if (!A->EmitContReturn) {
-      /* We don't want to emit CONT instructions.  If this do-loop has
-       * a continue, translate it away.
-       */
-      if (_slang_loop_contains_continue(slang_oper_child(oper, 0))) {
-         return _slang_gen_do_without_continue(A, oper);
-      }
-   }
-
-   /* type-check expression */
-   if (!_slang_is_boolean(A, &oper->children[1])) {
-      slang_info_log_error(A->log, "scalar/boolean expression expected for 'do/while'");
-      return NULL;
-   }
-
-   loop = new_loop(NULL);
-
-   /* save loop state */
-   push_loop(A, oper, loop);
-
-   /* loop body: */
-   loop->Children[0] = _slang_gen_operation(A, &oper->children[0]);
-
-   /* Check if loop condition is a constant */
-   isConst = _slang_is_constant_cond(&oper->children[1], &constTrue);
-   if (isConst && constTrue) {
-      /* do { } while(1)   ==> no conditional break */
-      loop->Children[1] = NULL; /* no tail code */
-   }
-   else {
-      slang_ir_node *cond
-         = new_cond(new_not(_slang_gen_operation(A, &oper->children[1])));
-      loop->Children[1] = new_break_if_true(A, cond);
-   }
-
-   /* XXX we should do infinite loop detection, as above */
-
-   /* restore loop state */
-   pop_loop(A);
-
-   return loop;
-}
-
-
-/**
- * Recursively count the number of operations rooted at 'oper'.
- * This gives some kind of indication of the size/complexity of an operation.
- */
-static GLuint
-sizeof_operation(const slang_operation *oper)
-{
-   if (oper) {
-      GLuint count = 1; /* me */
-      GLuint i;
-      for (i = 0; i < oper->num_children; i++) {
-         count += sizeof_operation(&oper->children[i]);
-      }
-      return count;
-   }
-   else {
-      return 0;
-   }
-}
-
-
-/**
- * Determine if a for-loop can be unrolled.
- * At this time, only a rather narrow class of for loops can be unrolled.
- * See code for details.
- * When a loop can't be unrolled because it's too large we'll emit a
- * message to the log.
- */
-static GLboolean
-_slang_can_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper)
-{
-   GLuint bodySize;
-   GLint start, end;
-   const char *varName;
-   slang_atom varId;
-
-   if (oper->type != SLANG_OPER_FOR)
-      return GL_FALSE;
-
-   assert(oper->num_children == 4);
-
-   if (_slang_loop_contains_continue_or_break(slang_oper_child_const(oper, 3)))
-      return GL_FALSE;
-
-   /* children[0] must be either "int i=constant" or "i=constant" */
-   if (oper->children[0].type == SLANG_OPER_BLOCK_NO_NEW_SCOPE) {
-      slang_variable *var;
-
-      if (oper->children[0].children[0].type != SLANG_OPER_VARIABLE_DECL)
-         return GL_FALSE;
-
-      varId = oper->children[0].children[0].a_id;
-
-      var = _slang_variable_locate(oper->children[0].children[0].locals,
-                                   varId, GL_TRUE);
-      if (!var)
-         return GL_FALSE;
-      if (!var->initializer)
-         return GL_FALSE;
-      if (var->initializer->type != SLANG_OPER_LITERAL_INT)
-         return GL_FALSE;
-      start = (GLint) var->initializer->literal[0];
-   }
-   else if (oper->children[0].type == SLANG_OPER_EXPRESSION) {
-      if (oper->children[0].children[0].type != SLANG_OPER_ASSIGN)
-         return GL_FALSE;
-      if (oper->children[0].children[0].children[0].type != SLANG_OPER_IDENTIFIER)
-         return GL_FALSE;
-      if (oper->children[0].children[0].children[1].type != SLANG_OPER_LITERAL_INT)
-         return GL_FALSE;
-
-      varId = oper->children[0].children[0].children[0].a_id;
-
-      start = (GLint) oper->children[0].children[0].children[1].literal[0];
-   }
-   else {
-      return GL_FALSE;
-   }
-
-   /* children[1] must be "i<constant" */
-   if (oper->children[1].type != SLANG_OPER_EXPRESSION)
-      return GL_FALSE;
-   if (oper->children[1].children[0].type != SLANG_OPER_LESS)
-      return GL_FALSE;
-   if (oper->children[1].children[0].children[0].type != SLANG_OPER_IDENTIFIER)
-      return GL_FALSE;
-   if (oper->children[1].children[0].children[1].type != SLANG_OPER_LITERAL_INT)
-      return GL_FALSE;
-
-   end = (GLint) oper->children[1].children[0].children[1].literal[0];
-
-   /* children[2] must be "i++" or "++i" */
-   if (oper->children[2].type != SLANG_OPER_POSTINCREMENT &&
-       oper->children[2].type != SLANG_OPER_PREINCREMENT)
-      return GL_FALSE;
-   if (oper->children[2].children[0].type != SLANG_OPER_IDENTIFIER)
-      return GL_FALSE;
-
-   /* make sure the same variable name is used in all places */
-   if ((oper->children[1].children[0].children[0].a_id != varId) ||
-       (oper->children[2].children[0].a_id != varId))
-      return GL_FALSE;
-
-   varName = (const char *) varId;
-
-   /* children[3], the loop body, can't be too large */
-   bodySize = sizeof_operation(&oper->children[3]);
-   if (bodySize > MAX_FOR_LOOP_UNROLL_BODY_SIZE) {
-      slang_info_log_print(A->log,
-                           "Note: 'for (%s ... )' body is too large/complex"
-                           " to unroll",
-                           varName);
-      return GL_FALSE;
-   }
-
-   if (start >= end)
-      return GL_FALSE; /* degenerate case */
-
-   if ((GLuint)(end - start) > MAX_FOR_LOOP_UNROLL_ITERATIONS) {
-      slang_info_log_print(A->log,
-                           "Note: 'for (%s=%d; %s<%d; ++%s)' is too"
-                           " many iterations to unroll",
-                           varName, start, varName, end, varName);
-      return GL_FALSE;
-   }
-
-   if ((end - start) * bodySize > MAX_FOR_LOOP_UNROLL_COMPLEXITY) {
-      slang_info_log_print(A->log,
-                           "Note: 'for (%s=%d; %s<%d; ++%s)' will generate"
-                           " too much code to unroll",
-                           varName, start, varName, end, varName);
-      return GL_FALSE;
-   }
-
-   return GL_TRUE; /* we can unroll the loop */
-}
-
-
-/**
- * Unroll a for-loop.
- * First we determine the number of iterations to unroll.
- * Then for each iteration:
- *   make a copy of the loop body
- *   replace instances of the loop variable with the current iteration value
- *   generate IR code for the body
- * \return pointer to generated IR code or NULL if error, out of memory, etc.
- */
-static slang_ir_node *
-_slang_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper)
-{
-   GLint start, end, iter;
-   slang_ir_node *n, *root = NULL;
-   slang_atom varId;
-
-   if (oper->children[0].type == SLANG_OPER_BLOCK_NO_NEW_SCOPE) {
-      /* for (int i=0; ... */
-      slang_variable *var;
-
-      varId = oper->children[0].children[0].a_id;
-      var = _slang_variable_locate(oper->children[0].children[0].locals,
-                                   varId, GL_TRUE);
-      assert(var);
-      start = (GLint) var->initializer->literal[0];
-   }
-   else {
-      /* for (i=0; ... */
-      varId = oper->children[0].children[0].children[0].a_id;
-      start = (GLint) oper->children[0].children[0].children[1].literal[0];
-   }
-
-   end = (GLint) oper->children[1].children[0].children[1].literal[0];
-
-   for (iter = start; iter < end; iter++) {
-      slang_operation *body;
-
-      /* make a copy of the loop body */
-      body = slang_operation_new(1);
-      if (!body)
-         return NULL;
-
-      if (!slang_operation_copy(body, &oper->children[3]))
-         return NULL;
-
-      /* in body, replace instances of 'varId' with literal 'iter' */
-      {
-         slang_variable *oldVar;
-         slang_operation *newOper;
-
-         oldVar = _slang_variable_locate(oper->locals, varId, GL_TRUE);
-         if (!oldVar) {
-            /* undeclared loop variable */
-            slang_operation_delete(body);
-            return NULL;
-         }
-
-         newOper = slang_operation_new(1);
-         newOper->type = SLANG_OPER_LITERAL_INT;
-         newOper->literal_size = 1;
-         newOper->literal[0] = (GLfloat) iter;
-
-         /* replace instances of the loop variable with newOper */
-         slang_substitute(A, body, 1, &oldVar, &newOper, GL_FALSE);
-      }
-
-      /* do IR codegen for body */
-      n = _slang_gen_operation(A, body);
-      if (!n)
-         return NULL;
-
-      root = new_seq(root, n);
-
-      slang_operation_delete(body);
-   }
-
-   return root;
-}
-
-
-/**
- * Replace 'continue' statement with 'break' inside a for-loop.
- * This is a recursive helper function used by _slang_gen_for_without_continue().
- */
-static void
-replace_continue_with_break(slang_assemble_ctx *A, slang_operation *oper)
-{
-   switch (oper->type) {
-   case SLANG_OPER_CONTINUE:
-      oper->type = SLANG_OPER_BREAK;
-      break;
-   case SLANG_OPER_FOR:
-   case SLANG_OPER_DO:
-   case SLANG_OPER_WHILE:
-      /* stop upon finding a nested loop */
-      break;
-   default:
-      /* recurse */
-      {
-         GLuint i;
-         for (i = 0; i < oper->num_children; i++) {
-            replace_continue_with_break(A, slang_oper_child(oper, i));
-         }
-      }
-   }
-}
-
-
-/**
- * Transform a for-loop so that continue statements are converted to breaks.
- * Then do normal IR code generation.
- *
- * Before:
- * 
- * for (INIT; LOOPCOND; INCR) {
- *    A;
- *    if (IFCOND) {
- *       continue;
- *    }
- *    B;
- * }
- * 
- * After:
- * 
- * {
- *    bool _condFlag = 1;
- *    for (INIT; _condFlag; ) {
- *       for ( ; _condFlag = LOOPCOND; INCR) {
- *          A;
- *          if (IFCOND) {
- *             break;
- *          }
- *          B;
- *       }
- *       if (_condFlag)
- *          INCR;
- *    }
- * }
- */
-static slang_ir_node *
-_slang_gen_for_without_continue(slang_assemble_ctx *A, slang_operation *oper)
-{
-   slang_operation *top;
-   slang_operation *outerFor, *innerFor, *init, *cond, *incr;
-   slang_operation *lhs, *rhs;
-
-   assert(oper->type == SLANG_OPER_FOR);
-
-   top = slang_operation_new(1);
-   top->type = SLANG_OPER_BLOCK_NEW_SCOPE;
-   top->locals->outer_scope = oper->locals->outer_scope;
-   slang_operation_add_children(top, 2);
-
-   /* declare: bool _condFlag = true */
-   {
-      slang_operation *condDecl = slang_oper_child(top, 0);
-      slang_generate_declaration(A, top->locals, condDecl,
-                                 SLANG_SPEC_BOOL, "_condFlag", GL_TRUE);
-   }
-
-   /* build outer loop:  for (INIT; _condFlag; ) { */
-   outerFor = slang_oper_child(top, 1);
-   outerFor->type = SLANG_OPER_FOR;
-   slang_operation_add_children(outerFor, 4);
-
-   init = slang_oper_child(outerFor, 0);
-   slang_operation_copy(init, slang_oper_child(oper, 0));
-
-   cond = slang_oper_child(outerFor, 1);
-   cond->type = SLANG_OPER_IDENTIFIER;
-   cond->a_id = slang_atom_pool_atom(A->atoms, "_condFlag");
-
-   incr = slang_oper_child(outerFor, 2);
-   incr->type = SLANG_OPER_VOID;
-
-   /* body of the outer loop */
-   {
-      slang_operation *block = slang_oper_child(outerFor, 3);
-
-      slang_operation_add_children(block, 2);
-      block->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
-
-      /* build inner loop:  for ( ; _condFlag = LOOPCOND; INCR) { */
-      {
-         innerFor = slang_oper_child(block, 0);
-
-         /* make copy of orig loop */
-         slang_operation_copy(innerFor, oper);
-         assert(innerFor->type == SLANG_OPER_FOR);
-         innerFor->locals->outer_scope = block->locals;
-
-         init = slang_oper_child(innerFor, 0);
-         init->type = SLANG_OPER_VOID; /* leak? */
-
-         cond = slang_oper_child(innerFor, 1);
-         slang_operation_destruct(cond);
-         cond->type = SLANG_OPER_ASSIGN;
-         cond->locals = _slang_variable_scope_new(innerFor->locals);
-         slang_operation_add_children(cond, 2);
-
-         lhs = slang_oper_child(cond, 0);
-         lhs->type = SLANG_OPER_IDENTIFIER;
-         lhs->a_id = slang_atom_pool_atom(A->atoms, "_condFlag");
-
-         rhs = slang_oper_child(cond, 1);
-         slang_operation_copy(rhs, slang_oper_child(oper, 1));
-      }
-
-      /* if (_condFlag) INCR; */
-      {
-         slang_operation *ifop = slang_oper_child(block, 1);
-         ifop->type = SLANG_OPER_IF;
-         slang_operation_add_children(ifop, 2);
-
-         /* re-use cond node build above */
-         slang_operation_copy(slang_oper_child(ifop, 0), cond);
-
-         /* incr node from original for-loop operation */
-         slang_operation_copy(slang_oper_child(ifop, 1),
-                              slang_oper_child(oper, 2));
-      }
-
-      /* finally, replace "continue" with "break" in the inner for-loop */
-      replace_continue_with_break(A, slang_oper_child(innerFor, 3));
-   }
-
-   return _slang_gen_operation(A, top);
-}
-
-
-
-/**
- * Generate IR for a for-loop.  Unrolling will be done when possible.
- */
-static slang_ir_node *
-_slang_gen_for(slang_assemble_ctx * A, slang_operation *oper)
-{
-   GLboolean unroll;
-
-   if (!A->EmitContReturn) {
-      /* We don't want to emit CONT instructions.  If this for-loop has
-       * a continue, translate it away.
-       */
-      if (_slang_loop_contains_continue(slang_oper_child(oper, 3))) {
-         return _slang_gen_for_without_continue(A, oper);
-      }
-   }
-
-   unroll = _slang_can_unroll_for_loop(A, oper);
-   if (unroll) {
-      slang_ir_node *code = _slang_unroll_for_loop(A, oper);
-      if (code)
-         return code;
-   }
-
-   assert(oper->type == SLANG_OPER_FOR);
-
-   /* conventional for-loop code generation */
-   {
-      /*
-       * init code (child[0])
-       * LOOP:
-       *    BREAK if !expr (child[1])
-       *    body code (child[3])
-       *    tail code:
-       *       incr code (child[2])   // XXX continue here
-       */
-      slang_ir_node *loop, *cond, *breakIf, *body, *init, *incr;
-      init = _slang_gen_operation(A, &oper->children[0]);
-      loop = new_loop(NULL);
-
-      /* save loop state */
-      push_loop(A, oper, loop);
-
-      cond = new_cond(new_not(_slang_gen_operation(A, &oper->children[1])));
-      breakIf = new_break_if_true(A, cond);
-      body = _slang_gen_operation(A, &oper->children[3]);
-      incr = _slang_gen_operation(A, &oper->children[2]);
-
-      loop->Children[0] = new_seq(breakIf, body);
-      loop->Children[1] = incr;  /* tail code */
-
-      /* restore loop state */
-      pop_loop(A);
-
-      return new_seq(init, loop);
-   }
-}
-
-
-static slang_ir_node *
-_slang_gen_continue(slang_assemble_ctx * A, const slang_operation *oper)
-{
-   slang_ir_node *n, *cont, *incr = NULL, *loopNode;
-
-   assert(oper->type == SLANG_OPER_CONTINUE);
-   loopNode = current_loop_ir(A);
-   assert(loopNode);
-   assert(loopNode->Opcode == IR_LOOP);
-
-   cont = new_node0(IR_CONT);
-   if (cont) {
-      cont->Parent = loopNode;
-      /* insert this node at head of linked list of cont/break instructions */
-      cont->List = loopNode->List;
-      loopNode->List = cont;
-   }
-
-   n = new_seq(incr, cont);
-   return n;
-}
-
-
-/**
- * Determine if the given operation is of a specific type.
- */
-static GLboolean
-is_operation_type(const slang_operation *oper, slang_operation_type type)
-{
-   if (oper->type == type)
-      return GL_TRUE;
-   else if ((oper->type == SLANG_OPER_BLOCK_NEW_SCOPE ||
-             oper->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE) &&
-            oper->num_children == 1)
-      return is_operation_type(&oper->children[0], type);
-   else
-      return GL_FALSE;
-}
-
-
-/**
- * Generate IR tree for an if/then/else conditional using high-level
- * IR_IF instruction.
- */
-static slang_ir_node *
-_slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper)
-{
-   /*
-    * eval expr (child[0])
-    * IF expr THEN
-    *    if-body code
-    * ELSE
-    *    else-body code
-    * ENDIF
-    */
-   const GLboolean haveElseClause = !_slang_is_noop(&oper->children[2]);
-   slang_ir_node *ifNode, *cond, *ifBody, *elseBody;
-   GLboolean isConst, constTrue;
-
-   /* type-check expression */
-   if (!_slang_is_boolean(A, &oper->children[0])) {
-      slang_info_log_error(A->log, "boolean expression expected for 'if'");
-      return NULL;
-   }
-
-   if (!_slang_is_scalar_or_boolean(A, &oper->children[0])) {
-      slang_info_log_error(A->log, "scalar/boolean expression expected for 'if'");
-      return NULL;
-   }
-
-   isConst = _slang_is_constant_cond(&oper->children[0], &constTrue);
-   if (isConst) {
-      if (constTrue) {
-         /* if (true) ... */
-         return _slang_gen_operation(A, &oper->children[1]);
-      }
-      else {
-         /* if (false) ... */
-         return _slang_gen_operation(A, &oper->children[2]);
-      }
-   }
-
-   cond = _slang_gen_operation(A, &oper->children[0]);
-   cond = new_cond(cond);
-
-   if (is_operation_type(&oper->children[1], SLANG_OPER_BREAK)
-       && !haveElseClause) {
-      /* Special case: generate a conditional break */
-      ifBody = new_break_if_true(A, cond);
-      return ifBody;
-   }
-   else if (is_operation_type(&oper->children[1], SLANG_OPER_CONTINUE)
-            && !haveElseClause
-            && current_loop_oper(A)
-            && current_loop_oper(A)->type != SLANG_OPER_FOR) {
-      /* Special case: generate a conditional continue */
-      ifBody = new_cont_if_true(A, cond);
-      return ifBody;
-   }
-   else {
-      /* general case */
-      ifBody = _slang_gen_operation(A, &oper->children[1]);
-      if (haveElseClause)
-         elseBody = _slang_gen_operation(A, &oper->children[2]);
-      else
-         elseBody = NULL;
-      ifNode = new_if(cond, ifBody, elseBody);
-      return ifNode;
-   }
-}
-
-
-
-static slang_ir_node *
-_slang_gen_not(slang_assemble_ctx * A, const slang_operation *oper)
-{
-   slang_ir_node *n;
-
-   assert(oper->type == SLANG_OPER_NOT);
-
-   /* type-check expression */
-   if (!_slang_is_scalar_or_boolean(A, &oper->children[0])) {
-      slang_info_log_error(A->log,
-                           "scalar/boolean expression expected for '!'");
-      return NULL;
-   }
-
-   n = _slang_gen_operation(A, &oper->children[0]);
-   if (n)
-      return new_not(n);
-   else
-      return NULL;
-}
-
-
-static slang_ir_node *
-_slang_gen_xor(slang_assemble_ctx * A, const slang_operation *oper)
-{
-   slang_ir_node *n1, *n2;
-
-   assert(oper->type == SLANG_OPER_LOGICALXOR);
-
-   if (!_slang_is_scalar_or_boolean(A, &oper->children[0]) ||
-       !_slang_is_scalar_or_boolean(A, &oper->children[0])) {
-      slang_info_log_error(A->log,
-                           "scalar/boolean expressions expected for '^^'");
-      return NULL;
-   }
-
-   n1 = _slang_gen_operation(A, &oper->children[0]);
-   if (!n1)
-      return NULL;
-   n2 = _slang_gen_operation(A, &oper->children[1]);
-   if (!n2)
-      return NULL;
-   return new_node2(IR_NOTEQUAL, n1, n2);
-}
-
-
-/**
- * Generate IR node for storage of a temporary of given size.
- */
-static slang_ir_node *
-_slang_gen_temporary(GLint size)
-{
-   slang_ir_storage *store;
-   slang_ir_node *n = NULL;
-
-   store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -2, size);
-   if (store) {
-      n = new_node0(IR_VAR_DECL);
-      if (n) {
-         n->Store = store;
-      }
-      else {
-         _slang_free(store);
-      }
-   }
-   return n;
-}
-
-
-/**
- * Generate program constants for an array.
- * Ex: const vec2[3] v = vec2[3](vec2(1,1), vec2(2,2), vec2(3,3));
- * This will allocate and initialize three vector constants, storing
- * the array in constant memory, not temporaries like a non-const array.
- * This can also be used for uniform array initializers.
- * \return GL_TRUE for success, GL_FALSE if failure (semantic error, etc).
- */
-static GLboolean
-make_constant_array(slang_assemble_ctx *A,
-                    slang_variable *var,
-                    slang_operation *initializer)
-{
-   struct gl_program *prog = A->program;
-   const GLenum datatype = _slang_gltype_from_specifier(&var->type.specifier);
-   const char *varName = (char *) var->a_name;
-   const GLuint numElements = initializer->num_children;
-   GLint size;
-   GLuint i, j;
-   GLfloat *values;
-
-   if (!var->store) {
-      var->store = _slang_new_ir_storage(PROGRAM_UNDEFINED, -6, -6);
-   }
-   size = var->store->Size;
-
-   assert(var->type.qualifier == SLANG_QUAL_CONST ||
-          var->type.qualifier == SLANG_QUAL_UNIFORM);
-   assert(initializer->type == SLANG_OPER_CALL);
-   assert(initializer->array_constructor);
-
-   values = (GLfloat *) malloc(numElements * 4 * sizeof(GLfloat));
-
-   /* convert constructor params into ordinary floats */
-   for (i = 0; i < numElements; i++) {
-      const slang_operation *op = &initializer->children[i];
-      if (op->type != SLANG_OPER_LITERAL_FLOAT) {
-         /* unsupported type for this optimization */
-         free(values);
-         return GL_FALSE;
-      }
-      for (j = 0; j < op->literal_size; j++) {
-         values[i * 4 + j] = op->literal[j];
-      }
-      for ( ; j < 4; j++) {
-         values[i * 4 + j] = 0.0f;
-      }
-   }
-
-   /* slightly different paths for constants vs. uniforms */
-   if (var->type.qualifier == SLANG_QUAL_UNIFORM) {
-      var->store->File = PROGRAM_UNIFORM;
-      var->store->Index = _mesa_add_uniform(prog->Parameters, varName,
-                                            size, datatype, values);
-   }
-   else {
-      var->store->File = PROGRAM_CONSTANT;
-      var->store->Index = _mesa_add_named_constant(prog->Parameters, varName,
-                                                   values, size);
-   }
-   assert(var->store->Size == size);
-
-   free(values);
-
-   return GL_TRUE;
-}
-
-
-
-/**
- * Generate IR node for allocating/declaring a variable (either a local or
- * a global).
- * Generally, this involves allocating an slang_ir_storage instance for the
- * variable, choosing a register file (temporary, constant, etc).
- * For ordinary variables we do not yet allocate storage though.  We do that
- * when we find the first actual use of the variable to avoid allocating temp
- * regs that will never get used.
- * At this time, uniforms are always allocated space in this function.
- *
- * \param initializer  Optional initializer expression for the variable.
- */
-static slang_ir_node *
-_slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var,
-                    slang_operation *initializer)
-{
-   const char *varName = (const char *) var->a_name;
-   const GLenum datatype = _slang_gltype_from_specifier(&var->type.specifier);
-   slang_ir_node *varDecl, *n;
-   slang_ir_storage *store;
-   GLint arrayLen, size, totalSize;  /* if array then totalSize > size */
-   gl_register_file file;
-
-   /*assert(!var->declared);*/
-   var->declared = GL_TRUE;
-
-   /* determine GPU register file for simple cases */
-   if (is_sampler_type(&var->type)) {
-      file = PROGRAM_SAMPLER;
-   }
-   else if (var->type.qualifier == SLANG_QUAL_UNIFORM) {
-      file = PROGRAM_UNIFORM;
-   }
-   else {
-      file = PROGRAM_TEMPORARY;
-   }
-
-   size = _slang_sizeof_type_specifier(&var->type.specifier);
-   if (size <= 0) {
-      slang_info_log_error(A->log, "invalid declaration for '%s'", varName);
-      return NULL;
-   }
-
-   arrayLen = _slang_array_length(var);
-   totalSize = _slang_array_size(size, arrayLen);
-
-   /* Allocate IR node for the declaration */
-   varDecl = new_node0(IR_VAR_DECL);
-   if (!varDecl)
-      return NULL;
-
-   /* Allocate slang_ir_storage for this variable if needed.
-    * Note that we may not actually allocate a constant or temporary register
-    * until later.
-    */
-   if (!var->store) {
-      GLint index = -7;  /* TBD / unknown */
-      var->store = _slang_new_ir_storage(file, index, totalSize);
-      if (!var->store)
-         return NULL; /* out of memory */
-   }
-
-   /* set the IR node's Var and Store pointers */
-   varDecl->Var = var;
-   varDecl->Store = var->store;
-
-
-   store = var->store;
-
-   /* if there's an initializer, generate IR for the expression */
-   if (initializer) {
-      slang_ir_node *varRef, *init;
-
-      if (var->type.qualifier == SLANG_QUAL_CONST) {
-         /* if the variable is const, the initializer must be a const
-          * expression as well.
-          */
-#if 0
-         if (!_slang_is_constant_expr(initializer)) {
-            slang_info_log_error(A->log,
-                                 "initializer for %s not constant", varName);
-            return NULL;
-         }
-#endif
-      }
-
-      if (var->type.qualifier == SLANG_QUAL_UNIFORM &&
-          !A->allow_uniform_initializers) {
-         slang_info_log_error(A->log,
-                              "initializer for uniform %s not allowed",
-                              varName);
-         return NULL;
-      }
-
-      /* IR for the variable we're initializing */
-      varRef = new_var(A, var);
-      if (!varRef) {
-         slang_info_log_error(A->log, "out of memory");
-         return NULL;
-      }
-
-      /* constant-folding, etc here */
-      _slang_simplify(initializer, &A->space, A->atoms); 
-
-      /* look for simple constant-valued variables and uniforms */
-      if (var->type.qualifier == SLANG_QUAL_CONST ||
-          var->type.qualifier == SLANG_QUAL_UNIFORM) {
-
-         if (initializer->type == SLANG_OPER_CALL &&
-             initializer->array_constructor) {
-            /* array initializer */
-            if (make_constant_array(A, var, initializer))
-               return varRef;
-         }
-         else if (initializer->type == SLANG_OPER_LITERAL_FLOAT ||
-                  initializer->type == SLANG_OPER_LITERAL_INT) {
-            /* simple float/vector initializer */
-            if (store->File == PROGRAM_UNIFORM) {
-               store->Index = _mesa_add_uniform(A->program->Parameters,
-                                                varName,
-                                                totalSize, datatype,
-                                                initializer->literal);
-               store->Swizzle = _slang_var_swizzle(size, 0);
-               return varRef;
-            }
-#if 0
-            else {
-               store->File = PROGRAM_CONSTANT;
-               store->Index = _mesa_add_named_constant(A->program->Parameters,
-                                                       varName,
-                                                       initializer->literal,
-                                                       totalSize);
-               store->Swizzle = _slang_var_swizzle(size, 0);
-               return varRef;
-            }
-#endif
-         }
-      }
-
-      /* IR for initializer */
-      init = _slang_gen_operation(A, initializer);
-      if (!init)
-         return NULL;
-
-      /* XXX remove this when type checking is added above */
-      if (init->Store && init->Store->Size != totalSize) {
-         slang_info_log_error(A->log, "invalid assignment (wrong types)");
-         return NULL;
-      }
-
-      /* assign RHS to LHS */
-      n = new_node2(IR_COPY, varRef, init);
-      n = new_seq(varDecl, n);
-   }
-   else {
-      /* no initializer */
-      n = varDecl;
-   }
-
-   if (store->File == PROGRAM_UNIFORM && store->Index < 0) {
-      /* always need to allocate storage for uniforms at this point */
-      store->Index = _mesa_add_uniform(A->program->Parameters, varName,
-                                       totalSize, datatype, NULL);
-      store->Swizzle = _slang_var_swizzle(size, 0);
-   }
-
-#if 0
-   printf("%s var %p %s  store=%p index=%d size=%d\n",
-          __FUNCTION__, (void *) var, (char *) varName,
-          (void *) store, store->Index, store->Size);
-#endif
-
-   return n;
-}
-
-
-/**
- * Generate code for a selection expression:   b ? x : y
- * XXX In some cases we could implement a selection expression
- * with an LRP instruction (use the boolean as the interpolant).
- * Otherwise, we use an IF/ELSE/ENDIF construct.
- */
-static slang_ir_node *
-_slang_gen_select(slang_assemble_ctx *A, slang_operation *oper)
-{
-   slang_ir_node *cond, *ifNode, *trueExpr, *falseExpr, *trueNode, *falseNode;
-   slang_ir_node *tmpDecl, *tmpVar, *tree;
-   slang_typeinfo type0, type1, type2;
-   int size, isBool, isEqual;
-
-   assert(oper->type == SLANG_OPER_SELECT);
-   assert(oper->num_children == 3);
-
-   /* type of children[0] must be boolean */
-   slang_typeinfo_construct(&type0);
-   typeof_operation(A, &oper->children[0], &type0);
-   isBool = (type0.spec.type == SLANG_SPEC_BOOL);
-   slang_typeinfo_destruct(&type0);
-   if (!isBool) {
-      slang_info_log_error(A->log, "selector type is not boolean");
-      return NULL;
-   }
-
-   slang_typeinfo_construct(&type1);
-   slang_typeinfo_construct(&type2);
-   typeof_operation(A, &oper->children[1], &type1);
-   typeof_operation(A, &oper->children[2], &type2);
-   isEqual = slang_type_specifier_equal(&type1.spec, &type2.spec);
-   slang_typeinfo_destruct(&type1);
-   slang_typeinfo_destruct(&type2);
-   if (!isEqual) {
-      slang_info_log_error(A->log, "incompatible types for ?: operator");
-      return NULL;
-   }
-
-   /* size of x or y's type */
-   size = _slang_sizeof_type_specifier(&type1.spec);
-   assert(size > 0);
-
-   /* temporary var */
-   tmpDecl = _slang_gen_temporary(size);
-
-   /* the condition (child 0) */
-   cond = _slang_gen_operation(A, &oper->children[0]);
-   cond = new_cond(cond);
-
-   /* if-true body (child 1) */
-   tmpVar = new_node0(IR_VAR);
-   tmpVar->Store = tmpDecl->Store;
-   trueExpr = _slang_gen_operation(A, &oper->children[1]);
-   trueNode = new_node2(IR_COPY, tmpVar, trueExpr);
-
-   /* if-false body (child 2) */
-   tmpVar = new_node0(IR_VAR);
-   tmpVar->Store = tmpDecl->Store;
-   falseExpr = _slang_gen_operation(A, &oper->children[2]);
-   falseNode = new_node2(IR_COPY, tmpVar, falseExpr);
-
-   ifNode = new_if(cond, trueNode, falseNode);
-
-   /* tmp var value */
-   tmpVar = new_node0(IR_VAR);
-   tmpVar->Store = tmpDecl->Store;
-
-   tree = new_seq(ifNode, tmpVar);
-   tree = new_seq(tmpDecl, tree);
-
-   /*_slang_print_ir_tree(tree, 10);*/
-   return tree;
-}
-
-
-/**
- * Generate code for &&.
- */
-static slang_ir_node *
-_slang_gen_logical_and(slang_assemble_ctx *A, slang_operation *oper)
-{
-   /* rewrite "a && b" as  "a ? b : false" */
-   slang_operation *select;
-   slang_ir_node *n;
-
-   select = slang_operation_new(1);
-   select->type = SLANG_OPER_SELECT;
-   slang_operation_add_children(select, 3);
-
-   slang_operation_copy(slang_oper_child(select, 0), &oper->children[0]);
-   slang_operation_copy(slang_oper_child(select, 1), &oper->children[1]);
-   slang_operation_literal_bool(slang_oper_child(select, 2), GL_FALSE);
-
-   n = _slang_gen_select(A, select);
-   return n;
-}
-
-
-/**
- * Generate code for ||.
- */
-static slang_ir_node *
-_slang_gen_logical_or(slang_assemble_ctx *A, slang_operation *oper)
-{
-   /* rewrite "a || b" as  "a ? true : b" */
-   slang_operation *select;
-   slang_ir_node *n;
-
-   select = slang_operation_new(1);
-   select->type = SLANG_OPER_SELECT;
-   slang_operation_add_children(select, 3);
-
-   slang_operation_copy(slang_oper_child(select, 0), &oper->children[0]);
-   slang_operation_literal_bool(slang_oper_child(select, 1), GL_TRUE);
-   slang_operation_copy(slang_oper_child(select, 2), &oper->children[1]);
-
-   n = _slang_gen_select(A, select);
-   return n;
-}
-
-
-/**
- * Generate IR tree for a return statement.
- */
-static slang_ir_node *
-_slang_gen_return(slang_assemble_ctx * A, slang_operation *oper)
-{
-   assert(oper->type == SLANG_OPER_RETURN);
-   return new_return(A->curFuncEndLabel);
-}
-
-
-#if 0
-/**
- * Determine if the given operation/expression is const-valued.
- */
-static GLboolean
-_slang_is_constant_expr(const slang_operation *oper)
-{
-   slang_variable *var;
-   GLuint i;
-
-   switch (oper->type) {
-   case SLANG_OPER_IDENTIFIER:
-      var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE);
-      if (var && var->type.qualifier == SLANG_QUAL_CONST)
-         return GL_TRUE;
-      return GL_FALSE;
-   default:
-      for (i = 0; i < oper->num_children; i++) {
-         if (!_slang_is_constant_expr(&oper->children[i]))
-            return GL_FALSE;
-      }
-      return GL_TRUE;
-   }
-}
-#endif
-
-
-/**
- * Check if an assignment of type t1 to t0 is legal.
- * XXX more cases needed.
- */
-static GLboolean
-_slang_assignment_compatible(slang_assemble_ctx *A,
-                             slang_operation *op0,
-                             slang_operation *op1)
-{
-   slang_typeinfo t0, t1;
-   GLuint sz0, sz1;
-
-   if (op0->type == SLANG_OPER_POSTINCREMENT ||
-       op0->type == SLANG_OPER_POSTDECREMENT) {
-      return GL_FALSE;
-   }
-
-   slang_typeinfo_construct(&t0);
-   typeof_operation(A, op0, &t0);
-
-   slang_typeinfo_construct(&t1);
-   typeof_operation(A, op1, &t1);
-
-   sz0 = _slang_sizeof_type_specifier(&t0.spec);
-   sz1 = _slang_sizeof_type_specifier(&t1.spec);
-
-#if 1
-   if (sz0 != sz1) {
-      /*printf("assignment size mismatch %u vs %u\n", sz0, sz1);*/
-      return GL_FALSE;
-   }
-#endif
-
-   if (t0.spec.type == SLANG_SPEC_STRUCT &&
-       t1.spec.type == SLANG_SPEC_STRUCT &&
-       t0.spec._struct->a_name != t1.spec._struct->a_name)
-      return GL_FALSE;
-
-   if (t0.spec.type == SLANG_SPEC_FLOAT &&
-       t1.spec.type == SLANG_SPEC_BOOL)
-      return GL_FALSE;
-
-#if 0 /* not used just yet - causes problems elsewhere */
-   if (t0.spec.type == SLANG_SPEC_INT &&
-       t1.spec.type == SLANG_SPEC_FLOAT)
-      return GL_FALSE;
-#endif
-
-   if (t0.spec.type == SLANG_SPEC_BOOL &&
-       t1.spec.type == SLANG_SPEC_FLOAT)
-      return GL_FALSE;
-
-   if (t0.spec.type == SLANG_SPEC_BOOL &&
-       t1.spec.type == SLANG_SPEC_INT)
-      return GL_FALSE;
-
-   return GL_TRUE;
-}
-
-
-/**
- * Generate IR tree for a local variable declaration.
- * Basically do some error checking and call _slang_gen_var_decl().
- */
-static slang_ir_node *
-_slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper)
-{
-   const char *varName = (char *) oper->a_id;
-   slang_variable *var;
-   slang_ir_node *varDecl;
-   slang_operation *initializer;
-
-   assert(oper->type == SLANG_OPER_VARIABLE_DECL);
-   assert(oper->num_children <= 1);
-
-
-   /* lookup the variable by name */
-   var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE);
-   if (!var)
-      return NULL;  /* "shouldn't happen" */
-
-   if (var->type.qualifier == SLANG_QUAL_ATTRIBUTE ||
-       var->type.qualifier == SLANG_QUAL_VARYING ||
-       var->type.qualifier == SLANG_QUAL_UNIFORM) {
-      /* can't declare attribute/uniform vars inside functions */
-      slang_info_log_error(A->log,
-                "local variable '%s' cannot be an attribute/uniform/varying",
-                varName);
-      return NULL;
-   }
-
-#if 0
-   if (v->declared) {
-      slang_info_log_error(A->log, "variable '%s' redeclared", varName);
-      return NULL;
-   }
-#endif
-
-   /* check if the var has an initializer */
-   if (oper->num_children > 0) {
-      assert(oper->num_children == 1);
-      initializer = &oper->children[0];
-   }
-   else if (var->initializer) {
-      initializer = var->initializer;
-   }
-   else {
-      initializer = NULL;
-   }
-
-   if (initializer) {
-      /* check/compare var type and initializer type */
-      if (!_slang_assignment_compatible(A, oper, initializer)) {
-         slang_info_log_error(A->log, "incompatible types in assignment");
-         return NULL;
-      }         
-   }
-   else {
-      if (var->type.qualifier == SLANG_QUAL_CONST) {
-         slang_info_log_error(A->log,
-                       "const-qualified variable '%s' requires initializer",
-                       varName);
-         return NULL;
-      }
-   }
-
-   /* Generate IR node */
-   varDecl = _slang_gen_var_decl(A, var, initializer);
-   if (!varDecl)
-      return NULL;
-
-   return varDecl;
-}
-
-
-/**
- * Generate IR tree for a reference to a variable (such as in an expression).
- * This is different from a variable declaration.
- */
-static slang_ir_node *
-_slang_gen_variable(slang_assemble_ctx * A, slang_operation *oper)
-{
-   /* If there's a variable associated with this oper (from inlining)
-    * use it.  Otherwise, use the oper's var id.
-    */
-   slang_atom name = oper->var ? oper->var->a_name : oper->a_id;
-   slang_variable *var = _slang_variable_locate(oper->locals, name, GL_TRUE);
-   slang_ir_node *n;
-   if (!var || !var->declared) {
-      slang_info_log_error(A->log, "undefined variable '%s'", (char *) name);
-      return NULL;
-   }
-   n = new_var(A, var);
-   return n;
-}
-
-
-
-/**
- * Return the number of components actually named by the swizzle.
- * Recall that swizzles may have undefined/don't-care values.
- */
-static GLuint
-swizzle_size(GLuint swizzle)
-{
-   GLuint size = 0, i;
-   for (i = 0; i < 4; i++) {
-      GLuint swz = GET_SWZ(swizzle, i);
-      size += (swz <= 3);
-   }
-   return size;
-}
-
-
-static slang_ir_node *
-_slang_gen_swizzle(slang_ir_node *child, GLuint swizzle)
-{
-   slang_ir_node *n = new_node1(IR_SWIZZLE, child);
-   assert(child);
-   if (n) {
-      assert(!n->Store);
-      n->Store = _slang_new_ir_storage_relative(0,
-                                                swizzle_size(swizzle),
-                                                child->Store);
-      assert(n->Store);
-      n->Store->Swizzle = swizzle;
-   }
-   return n;
-}
-
-
-static GLboolean
-is_store_writable(const slang_assemble_ctx *A, const slang_ir_storage *store)
-{
-   while (store->Parent)
-      store = store->Parent;
-
-   if (!(store->File == PROGRAM_OUTPUT ||
-         store->File == PROGRAM_TEMPORARY ||
-         (store->File == PROGRAM_VARYING &&
-          A->program->Target == GL_VERTEX_PROGRAM_ARB))) {
-      return GL_FALSE;
-   }
-   else {
-      return GL_TRUE;
-   }
-}
-
-
-/**
- * Walk up an IR storage path to compute the final swizzle.
- * This is used when we find an expression such as "foo.xz.yx".
- */
-static GLuint
-root_swizzle(const slang_ir_storage *st)
-{
-   GLuint swizzle = st->Swizzle;
-   while (st->Parent) {
-      st = st->Parent;
-      swizzle = _slang_swizzle_swizzle(st->Swizzle, swizzle);
-   }
-   return swizzle;
-}
-
-
-/**
- * Generate IR tree for an assignment (=).
- */
-static slang_ir_node *
-_slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper)
-{
-   slang_operation *pred = NULL;
-   slang_ir_node *n = NULL;
-
-   if (oper->children[0].type == SLANG_OPER_IDENTIFIER) {
-      /* Check that var is writeable */
-      const char *varName = (char *) oper->children[0].a_id;
-      slang_variable *var
-         = _slang_variable_locate(oper->children[0].locals,
-                                  oper->children[0].a_id, GL_TRUE);
-      if (!var) {
-         slang_info_log_error(A->log, "undefined variable '%s'", varName);
-         return NULL;
-      }
-
-      if (var->type.qualifier == SLANG_QUAL_CONST ||
-          var->type.qualifier == SLANG_QUAL_ATTRIBUTE ||
-          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'",
-                              varName);
-         return NULL;
-      }
-
-      /* check if we need to predicate this assignment based on __notRetFlag */
-      if ((var->is_global ||
-           var->type.qualifier == SLANG_QUAL_OUT ||
-           var->type.qualifier == SLANG_QUAL_INOUT) && A->UseReturnFlag) {
-         /* create predicate, used below */
-         pred = slang_operation_new(1);
-         pred->type = SLANG_OPER_IDENTIFIER;
-         pred->a_id = slang_atom_pool_atom(A->atoms, "__notRetFlag");
-         pred->locals->outer_scope = oper->locals->outer_scope;
-      }
-   }
-
-   if (oper->children[0].type == SLANG_OPER_IDENTIFIER &&
-       oper->children[1].type == SLANG_OPER_CALL) {
-      /* Special case of:  x = f(a, b)
-       * Replace with f(a, b, x)  (where x == hidden __retVal out param)
-       *
-       * XXX this could be even more effective if we could accomodate
-       * cases such as "v.x = f();"  - would help with typical vertex
-       * transformation.
-       */
-      n = _slang_gen_function_call_name(A,
-                                      (const char *) oper->children[1].a_id,
-                                      &oper->children[1], &oper->children[0]);
-   }
-   else {
-      slang_ir_node *lhs, *rhs;
-
-      /* lhs and rhs type checking */
-      if (!_slang_assignment_compatible(A,
-                                        &oper->children[0],
-                                        &oper->children[1])) {
-         slang_info_log_error(A->log, "incompatible types in assignment");
-         return NULL;
-      }
-
-      lhs = _slang_gen_operation(A, &oper->children[0]);
-      if (!lhs) {
-         return NULL;
-      }
-
-      if (!lhs->Store) {
-         slang_info_log_error(A->log,
-                              "invalid left hand side for assignment");
-         return NULL;
-      }
-
-      /* check that lhs is writable */
-      if (!is_store_writable(A, lhs->Store)) {
-         slang_info_log_error(A->log,
-                              "illegal assignment to read-only l-value");
-         return NULL;
-      }
-
-      rhs = _slang_gen_operation(A, &oper->children[1]);
-      if (lhs && rhs) {
-         /* convert lhs swizzle into writemask */
-         const GLuint swizzle = root_swizzle(lhs->Store);
-         GLuint writemask, newSwizzle = 0x0;
-         if (!swizzle_to_writemask(A, swizzle, &writemask, &newSwizzle)) {
-            /* Non-simple writemask, need to swizzle right hand side in
-             * order to put components into the right place.
-             */
-            rhs = _slang_gen_swizzle(rhs, newSwizzle);
-         }
-         n = new_node2(IR_COPY, lhs, rhs);
-      }
-      else {
-         return NULL;
-      }
-   }
-
-   if (n && pred) {
-      /* predicate the assignment code on __notRetFlag */
-      slang_ir_node *top, *cond;
-
-      cond = _slang_gen_operation(A, pred);
-      top = new_if(cond, n, NULL);
-      return top;
-   }
-   return n;
-}
-
-
-/**
- * Generate IR tree for referencing a field in a struct (or basic vector type)
- */
-static slang_ir_node *
-_slang_gen_struct_field(slang_assemble_ctx * A, slang_operation *oper)
-{
-   slang_typeinfo ti;
-
-   /* type of struct */
-   slang_typeinfo_construct(&ti);
-   typeof_operation(A, &oper->children[0], &ti);
-
-   if (_slang_type_is_vector(ti.spec.type)) {
-      /* the field should be a swizzle */
-      const GLuint rows = _slang_type_dim(ti.spec.type);
-      slang_swizzle swz;
-      slang_ir_node *n;
-      GLuint swizzle;
-      if (!_slang_is_swizzle((char *) oper->a_id, rows, &swz)) {
-         slang_info_log_error(A->log, "Bad swizzle");
-         return NULL;
-      }
-      swizzle = MAKE_SWIZZLE4(swz.swizzle[0],
-                              swz.swizzle[1],
-                              swz.swizzle[2],
-                              swz.swizzle[3]);
-
-      n = _slang_gen_operation(A, &oper->children[0]);
-      /* create new parent node with swizzle */
-      if (n)
-         n = _slang_gen_swizzle(n, swizzle);
-      return n;
-   }
-   else if (   ti.spec.type == SLANG_SPEC_FLOAT
-            || ti.spec.type == SLANG_SPEC_INT
-            || ti.spec.type == SLANG_SPEC_BOOL) {
-      const GLuint rows = 1;
-      slang_swizzle swz;
-      slang_ir_node *n;
-      GLuint swizzle;
-      if (!_slang_is_swizzle((char *) oper->a_id, rows, &swz)) {
-         slang_info_log_error(A->log, "Bad swizzle");
-      }
-      swizzle = MAKE_SWIZZLE4(swz.swizzle[0],
-                              swz.swizzle[1],
-                              swz.swizzle[2],
-                              swz.swizzle[3]);
-      n = _slang_gen_operation(A, &oper->children[0]);
-      /* create new parent node with swizzle */
-      n = _slang_gen_swizzle(n, swizzle);
-      return n;
-   }
-   else {
-      /* the field is a structure member (base.field) */
-      /* oper->children[0] is the base */
-      /* oper->a_id is the field name */
-      slang_ir_node *base, *n;
-      slang_typeinfo field_ti;
-      GLint fieldSize, fieldOffset = -1;
-
-      /* type of field */
-      slang_typeinfo_construct(&field_ti);
-      typeof_operation(A, oper, &field_ti);
-
-      fieldSize = _slang_sizeof_type_specifier(&field_ti.spec);
-      if (fieldSize > 0)
-         fieldOffset = _slang_field_offset(&ti.spec, oper->a_id);
-
-      if (fieldSize == 0 || fieldOffset < 0) {
-         const char *structName;
-         if (ti.spec._struct)
-            structName = (char *) ti.spec._struct->a_name;
-         else
-            structName = "unknown";
-         slang_info_log_error(A->log,
-                              "\"%s\" is not a member of struct \"%s\"",
-                              (char *) oper->a_id, structName);
-         return NULL;
-      }
-      assert(fieldSize >= 0);
-
-      base = _slang_gen_operation(A, &oper->children[0]);
-      if (!base) {
-         /* error msg should have already been logged */
-         return NULL;
-      }
-
-      n = new_node1(IR_FIELD, base);
-      if (!n)
-         return NULL;
-
-      n->Field = (char *) oper->a_id;
-
-      /* Store the field's offset in storage->Index */
-      n->Store = _slang_new_ir_storage(base->Store->File,
-                                       fieldOffset,
-                                       fieldSize);
-
-      return n;
-   }
-}
-
-
-/**
- * Gen code for array indexing.
- */
-static slang_ir_node *
-_slang_gen_array_element(slang_assemble_ctx * A, slang_operation *oper)
-{
-   slang_typeinfo array_ti;
-
-   /* get array's type info */
-   slang_typeinfo_construct(&array_ti);
-   typeof_operation(A, &oper->children[0], &array_ti);
-
-   if (_slang_type_is_vector(array_ti.spec.type)) {
-      /* indexing a simple vector type: "vec4 v; v[0]=p;" */
-      /* translate the index into a swizzle/writemask: "v.x=p" */
-      const GLuint max = _slang_type_dim(array_ti.spec.type);
-      GLint index;
-      slang_ir_node *n;
-
-      index = (GLint) oper->children[1].literal[0];
-      if (oper->children[1].type != SLANG_OPER_LITERAL_INT ||
-          index >= (GLint) max) {
-#if 0
-         slang_info_log_error(A->log, "Invalid array index for vector type");
-         printf("type = %d\n", oper->children[1].type);
-         printf("index = %d, max = %d\n", index, max);
-         printf("array = %s\n", (char*)oper->children[0].a_id);
-         printf("index = %s\n", (char*)oper->children[1].a_id);
-         return NULL;
-#else
-         index = 0;
-#endif
-      }
-
-      n = _slang_gen_operation(A, &oper->children[0]);
-      if (n) {
-         /* use swizzle to access the element */
-         GLuint swizzle = MAKE_SWIZZLE4(SWIZZLE_X + index,
-                                        SWIZZLE_NIL,
-                                        SWIZZLE_NIL,
-                                        SWIZZLE_NIL);
-         n = _slang_gen_swizzle(n, swizzle);
-      }
-      return n;
-   }
-   else {
-      /* conventional array */
-      slang_typeinfo elem_ti;
-      slang_ir_node *elem, *array, *index;
-      GLint elemSize, arrayLen;
-
-      /* size of array element */
-      slang_typeinfo_construct(&elem_ti);
-      typeof_operation(A, oper, &elem_ti);
-      elemSize = _slang_sizeof_type_specifier(&elem_ti.spec);
-
-      if (_slang_type_is_matrix(array_ti.spec.type))
-         arrayLen = _slang_type_dim(array_ti.spec.type);
-      else
-         arrayLen = array_ti.array_len;
-
-      slang_typeinfo_destruct(&array_ti);
-      slang_typeinfo_destruct(&elem_ti);
-
-      if (elemSize <= 0) {
-         /* unknown var or type */
-         slang_info_log_error(A->log, "Undefined variable or type");
-         return NULL;
-      }
-
-      array = _slang_gen_operation(A, &oper->children[0]);
-      index = _slang_gen_operation(A, &oper->children[1]);
-      if (array && index) {
-         /* bounds check */
-         GLint constIndex = -1;
-         if (index->Opcode == IR_FLOAT) {
-            constIndex = (int) index->Value[0];
-            if (constIndex < 0 || constIndex >= arrayLen) {
-               slang_info_log_error(A->log,
-                                "Array index out of bounds (index=%d size=%d)",
-                                 constIndex, arrayLen);
-               _slang_free_ir_tree(array);
-               _slang_free_ir_tree(index);
-               return NULL;
-            }
-         }
-
-         if (!array->Store) {
-            slang_info_log_error(A->log, "Invalid array");
-            return NULL;
-         }
-
-         elem = new_node2(IR_ELEMENT, array, index);
-
-         /* The storage info here will be updated during code emit */
-         elem->Store = _slang_new_ir_storage(array->Store->File,
-                                             array->Store->Index,
-                                             elemSize);
-         elem->Store->Swizzle = _slang_var_swizzle(elemSize, 0);
-         return elem;
-      }
-      else {
-         _slang_free_ir_tree(array);
-         _slang_free_ir_tree(index);
-         return NULL;
-      }
-   }
-}
-
-
-static slang_ir_node *
-_slang_gen_compare(slang_assemble_ctx *A, slang_operation *oper,
-                   slang_ir_opcode opcode)
-{
-   slang_typeinfo t0, t1;
-   slang_ir_node *n;
-   
-   slang_typeinfo_construct(&t0);
-   typeof_operation(A, &oper->children[0], &t0);
-
-   slang_typeinfo_construct(&t1);
-   typeof_operation(A, &oper->children[0], &t1);
-
-   if (t0.spec.type == SLANG_SPEC_ARRAY ||
-       t1.spec.type == SLANG_SPEC_ARRAY) {
-      slang_info_log_error(A->log, "Illegal array comparison");
-      return NULL;
-   }
-
-   if (oper->type != SLANG_OPER_EQUAL &&
-       oper->type != SLANG_OPER_NOTEQUAL) {
-      /* <, <=, >, >= can only be used with scalars */
-      if ((t0.spec.type != SLANG_SPEC_INT &&
-           t0.spec.type != SLANG_SPEC_FLOAT) ||
-          (t1.spec.type != SLANG_SPEC_INT &&
-           t1.spec.type != SLANG_SPEC_FLOAT)) {
-         slang_info_log_error(A->log, "Incompatible type(s) for inequality operator");
-         return NULL;
-      }
-   }
-
-   n =  new_node2(opcode,
-                  _slang_gen_operation(A, &oper->children[0]),
-                  _slang_gen_operation(A, &oper->children[1]));
-
-   /* result is a bool (size 1) */
-   n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, 1);
-
-   return n;
-}
-
-
-#if 0
-static void
-print_vars(slang_variable_scope *s)
-{
-   int i;
-   printf("vars: ");
-   for (i = 0; i < s->num_variables; i++) {
-      printf("%s %d, \n",
-             (char*) s->variables[i]->a_name,
-             s->variables[i]->declared);
-   }
-
-   printf("\n");
-}
-#endif
-
-
-#if 0
-static void
-_slang_undeclare_vars(slang_variable_scope *locals)
-{
-   if (locals->num_variables > 0) {
-      int i;
-      for (i = 0; i < locals->num_variables; i++) {
-         slang_variable *v = locals->variables[i];
-         printf("undeclare %s at %p\n", (char*) v->a_name, v);
-         v->declared = GL_FALSE;
-      }
-   }
-}
-#endif
-
-
-/**
- * Generate IR tree for a slang_operation (AST node)
- */
-static slang_ir_node *
-_slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)
-{
-   switch (oper->type) {
-   case SLANG_OPER_BLOCK_NEW_SCOPE:
-      {
-         slang_ir_node *n;
-
-         _slang_push_var_table(A->vartable);
-
-         oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; /* temp change */
-         n = _slang_gen_operation(A, oper);
-         oper->type = SLANG_OPER_BLOCK_NEW_SCOPE; /* restore */
-
-         _slang_pop_var_table(A->vartable);
-
-         /*_slang_undeclare_vars(oper->locals);*/
-         /*print_vars(oper->locals);*/
-
-         if (n)
-            n = new_node1(IR_SCOPE, n);
-         return n;
-      }
-      break;
-
-   case SLANG_OPER_BLOCK_NO_NEW_SCOPE:
-      /* list of operations */
-      if (oper->num_children > 0)
-      {
-         slang_ir_node *n, *tree = NULL;
-         GLuint i;
-
-         for (i = 0; i < oper->num_children; i++) {
-            n = _slang_gen_operation(A, &oper->children[i]);
-            if (!n) {
-               _slang_free_ir_tree(tree);
-               return NULL; /* error must have occured */
-            }
-            tree = new_seq(tree, n);
-         }
-
-         return tree;
-      }
-      else {
-         return new_node0(IR_NOP);
-      }
-
-   case SLANG_OPER_EXPRESSION:
-      return _slang_gen_operation(A, &oper->children[0]);
-
-   case SLANG_OPER_FOR:
-      return _slang_gen_for(A, oper);
-   case SLANG_OPER_DO:
-      return _slang_gen_do(A, oper);
-   case SLANG_OPER_WHILE:
-      return _slang_gen_while(A, oper);
-   case SLANG_OPER_BREAK:
-      if (!current_loop_oper(A)) {
-         slang_info_log_error(A->log, "'break' not in loop");
-         return NULL;
-      }
-      return new_break(current_loop_ir(A));
-   case SLANG_OPER_CONTINUE:
-      if (!current_loop_oper(A)) {
-         slang_info_log_error(A->log, "'continue' not in loop");
-         return NULL;
-      }
-      return _slang_gen_continue(A, oper);
-   case SLANG_OPER_DISCARD:
-      return new_node0(IR_KILL);
-
-   case SLANG_OPER_EQUAL:
-      return _slang_gen_compare(A, oper, IR_EQUAL);
-   case SLANG_OPER_NOTEQUAL:
-      return _slang_gen_compare(A, oper, IR_NOTEQUAL);
-   case SLANG_OPER_GREATER:
-      return _slang_gen_compare(A, oper, IR_SGT);
-   case SLANG_OPER_LESS:
-      return _slang_gen_compare(A, oper, IR_SLT);
-   case SLANG_OPER_GREATEREQUAL:
-      return _slang_gen_compare(A, oper, IR_SGE);
-   case SLANG_OPER_LESSEQUAL:
-      return _slang_gen_compare(A, oper, IR_SLE);
-   case SLANG_OPER_ADD:
-      {
-        slang_ir_node *n;
-         assert(oper->num_children == 2);
-        n = _slang_gen_function_call_name(A, "+", oper, NULL);
-        return n;
-      }
-   case SLANG_OPER_SUBTRACT:
-      {
-        slang_ir_node *n;
-         assert(oper->num_children == 2);
-        n = _slang_gen_function_call_name(A, "-", oper, NULL);
-        return n;
-      }
-   case SLANG_OPER_MULTIPLY:
-      {
-        slang_ir_node *n;
-         assert(oper->num_children == 2);
-         n = _slang_gen_function_call_name(A, "*", oper, NULL);
-        return n;
-      }
-   case SLANG_OPER_DIVIDE:
-      {
-         slang_ir_node *n;
-         assert(oper->num_children == 2);
-        n = _slang_gen_function_call_name(A, "/", oper, NULL);
-        return n;
-      }
-   case SLANG_OPER_MINUS:
-      {
-         slang_ir_node *n;
-         assert(oper->num_children == 1);
-        n = _slang_gen_function_call_name(A, "-", oper, NULL);
-        return n;
-      }
-   case SLANG_OPER_PLUS:
-      /* +expr   --> do nothing */
-      return _slang_gen_operation(A, &oper->children[0]);
-   case SLANG_OPER_VARIABLE_DECL:
-      return _slang_gen_declaration(A, oper);
-   case SLANG_OPER_ASSIGN:
-      return _slang_gen_assignment(A, oper);
-   case SLANG_OPER_ADDASSIGN:
-      {
-        slang_ir_node *n;
-         assert(oper->num_children == 2);
-        n = _slang_gen_function_call_name(A, "+=", oper, NULL);
-        return n;
-      }
-   case SLANG_OPER_SUBASSIGN:
-      {
-        slang_ir_node *n;
-         assert(oper->num_children == 2);
-        n = _slang_gen_function_call_name(A, "-=", oper, NULL);
-        return n;
-      }
-      break;
-   case SLANG_OPER_MULASSIGN:
-      {
-        slang_ir_node *n;
-         assert(oper->num_children == 2);
-        n = _slang_gen_function_call_name(A, "*=", oper, NULL);
-        return n;
-      }
-   case SLANG_OPER_DIVASSIGN:
-      {
-        slang_ir_node *n;
-         assert(oper->num_children == 2);
-        n = _slang_gen_function_call_name(A, "/=", oper, NULL);
-        return n;
-      }
-   case SLANG_OPER_LOGICALAND:
-      {
-        slang_ir_node *n;
-         assert(oper->num_children == 2);
-        n = _slang_gen_logical_and(A, oper);
-        return n;
-      }
-   case SLANG_OPER_LOGICALOR:
-      {
-        slang_ir_node *n;
-         assert(oper->num_children == 2);
-        n = _slang_gen_logical_or(A, oper);
-        return n;
-      }
-   case SLANG_OPER_LOGICALXOR:
-      return _slang_gen_xor(A, oper);
-   case SLANG_OPER_NOT:
-      return _slang_gen_not(A, oper);
-   case SLANG_OPER_SELECT:  /* b ? x : y */
-      {
-        slang_ir_node *n;
-         assert(oper->num_children == 3);
-        n = _slang_gen_select(A, oper);
-        return n;
-      }
-
-   case SLANG_OPER_ASM:
-      return _slang_gen_asm(A, oper, NULL);
-   case SLANG_OPER_CALL:
-      return _slang_gen_function_call_name(A, (const char *) oper->a_id,
-                                           oper, NULL);
-   case SLANG_OPER_METHOD:
-      return _slang_gen_method_call(A, oper);
-   case SLANG_OPER_RETURN:
-      return _slang_gen_return(A, oper);
-   case SLANG_OPER_RETURN_INLINED:
-      return _slang_gen_return(A, oper);
-   case SLANG_OPER_LABEL:
-      return new_label(oper->label);
-   case SLANG_OPER_IDENTIFIER:
-      return _slang_gen_variable(A, oper);
-   case SLANG_OPER_IF:
-      return _slang_gen_if(A, oper);
-   case SLANG_OPER_FIELD:
-      return _slang_gen_struct_field(A, oper);
-   case SLANG_OPER_SUBSCRIPT:
-      return _slang_gen_array_element(A, oper);
-   case SLANG_OPER_LITERAL_FLOAT:
-      /* fall-through */
-   case SLANG_OPER_LITERAL_INT:
-      /* fall-through */
-   case SLANG_OPER_LITERAL_BOOL:
-      return new_float_literal(oper->literal, oper->literal_size);
-
-   case SLANG_OPER_POSTINCREMENT:   /* var++ */
-      {
-        slang_ir_node *n;
-         assert(oper->num_children == 1);
-        n = _slang_gen_function_call_name(A, "__postIncr", oper, NULL);
-        return n;
-      }
-   case SLANG_OPER_POSTDECREMENT:   /* var-- */
-      {
-        slang_ir_node *n;
-         assert(oper->num_children == 1);
-        n = _slang_gen_function_call_name(A, "__postDecr", oper, NULL);
-        return n;
-      }
-   case SLANG_OPER_PREINCREMENT:   /* ++var */
-      {
-        slang_ir_node *n;
-         assert(oper->num_children == 1);
-        n = _slang_gen_function_call_name(A, "++", oper, NULL);
-        return n;
-      }
-   case SLANG_OPER_PREDECREMENT:   /* --var */
-      {
-        slang_ir_node *n;
-         assert(oper->num_children == 1);
-        n = _slang_gen_function_call_name(A, "--", oper, NULL);
-        return n;
-      }
-
-   case SLANG_OPER_NON_INLINED_CALL:
-   case SLANG_OPER_SEQUENCE:
-      {
-         slang_ir_node *tree = NULL;
-         GLuint i;
-         for (i = 0; i < oper->num_children; i++) {
-            slang_ir_node *n = _slang_gen_operation(A, &oper->children[i]);
-            tree = new_seq(tree, n);
-            if (n)
-               tree->Store = n->Store;
-         }
-         if (oper->type == SLANG_OPER_NON_INLINED_CALL) {
-            tree = new_function_call(tree, oper->label);
-         }
-         return tree;
-      }
-
-   case SLANG_OPER_NONE:
-   case SLANG_OPER_VOID:
-      /* returning NULL here would generate an error */
-      return new_node0(IR_NOP);
-
-   default:
-      _mesa_problem(NULL, "bad node type %d in _slang_gen_operation",
-                    oper->type);
-      return new_node0(IR_NOP);
-   }
-
-   return NULL;
-}
-
-
-/**
- * Check if the given type specifier is a rectangular texture sampler.
- */
-static GLboolean
-is_rect_sampler_spec(const slang_type_specifier *spec)
-{
-   while (spec->_array) {
-      spec = spec->_array;
-   }
-   return spec->type == SLANG_SPEC_SAMPLER_RECT ||
-          spec->type == SLANG_SPEC_SAMPLER_RECT_SHADOW;
-}
-
-
-
-/**
- * Called by compiler when a global variable has been parsed/compiled.
- * Here we examine the variable's type to determine what kind of register
- * storage will be used.
- *
- * A uniform such as "gl_Position" will become the register specification
- * (PROGRAM_OUTPUT, VERT_RESULT_HPOS).  Or, uniform "gl_FogFragCoord"
- * will be (PROGRAM_INPUT, FRAG_ATTRIB_FOGC).
- *
- * Samplers are interesting.  For "uniform sampler2D tex;" we'll specify
- * (PROGRAM_SAMPLER, index) where index is resolved at link-time to an
- * actual texture unit (as specified by the user calling glUniform1i()).
- */
-GLboolean
-_slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
-                               slang_unit_type type)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   struct gl_program *prog = A->program;
-   const char *varName = (char *) var->a_name;
-   GLboolean success = GL_TRUE;
-   slang_ir_storage *store = NULL;
-   int dbg = 0;
-   const GLenum datatype = _slang_gltype_from_specifier(&var->type.specifier);
-   const GLint size = _slang_sizeof_type_specifier(&var->type.specifier);
-   const GLint arrayLen = _slang_array_length(var);
-   const GLint totalSize = _slang_array_size(size, arrayLen);
-   GLint texIndex = sampler_to_texture_index(var->type.specifier.type);
-
-   var->is_global = GL_TRUE;
-
-   /* check for sampler2D arrays */
-   if (texIndex == -1 && var->type.specifier._array)
-      texIndex = sampler_to_texture_index(var->type.specifier._array->type);
-
-   if (texIndex != -1) {
-      /* This is a texture sampler variable...
-       * store->File = PROGRAM_SAMPLER
-       * store->Index = sampler number (0..7, typically)
-       * store->Size = texture type index (1D, 2D, 3D, cube, etc)
-       */
-      if (var->initializer) {
-         slang_info_log_error(A->log, "illegal assignment to '%s'", varName);
-         return GL_FALSE;
-      }
-#if FEATURE_es2_glsl /* XXX should use FEATURE_texture_rect */
-      /* disallow rect samplers */
-      if (ctx->API == API_OPENGLES2 &&
-         is_rect_sampler_spec(&var->type.specifier)) {
-         slang_info_log_error(A->log, "invalid sampler type for '%s'", varName);
-         return GL_FALSE;
-      }
-#else
-      (void) is_rect_sampler_spec; /* silence warning */
-      (void) ctx;
-#endif
-      {
-         GLint sampNum = _mesa_add_sampler(prog->Parameters, varName, datatype);
-         store = _slang_new_ir_storage_sampler(sampNum, texIndex, totalSize);
-
-         /* If we have a sampler array, then we need to allocate the 
-         * additional samplers to ensure we don't allocate them elsewhere.
-         * We can't directly use _mesa_add_sampler() as that checks the
-         * varName and gets a match, so we call _mesa_add_parameter()
-         * directly and use the last sampler number from the call above.
-         */
-        if (arrayLen > 0) {
-           GLint a = arrayLen - 1;
-           GLint i;
-           for (i = 0; i < a; i++) {
-               GLfloat value = (GLfloat)(i + sampNum + 1);
-               (void) _mesa_add_parameter(prog->Parameters, PROGRAM_SAMPLER,
-                                 varName, 1, datatype, &value, NULL, 0x0);
-           }
-        }
-      }
-      if (dbg) printf("SAMPLER ");
-   }
-   else if (var->type.qualifier == SLANG_QUAL_UNIFORM) {
-      /* Uniform variable */
-      const GLuint swizzle = _slang_var_swizzle(totalSize, 0);
-
-      if (prog) {
-         /* user-defined uniform */
-         if (datatype == GL_NONE) {
-           if ((var->type.specifier.type == SLANG_SPEC_ARRAY &&
-                var->type.specifier._array->type == SLANG_SPEC_STRUCT) ||
-                (var->type.specifier.type == SLANG_SPEC_STRUCT)) {
-               /* temporary work-around */
-               GLenum datatype = GL_FLOAT;
-               GLint uniformLoc = _mesa_add_uniform(prog->Parameters, varName,
-                                                    totalSize, datatype, NULL);
-               store = _slang_new_ir_storage_swz(PROGRAM_UNIFORM, uniformLoc,
-                                                 totalSize, swizzle);
-        
-              if (arrayLen > 0) {
-                 GLint a = arrayLen - 1;
-                 GLint i;
-                 for (i = 0; i < a; i++) {
-                     GLfloat value = (GLfloat)(i + uniformLoc + 1);
-                     (void) _mesa_add_parameter(prog->Parameters, PROGRAM_UNIFORM,
-                                 varName, 1, datatype, &value, NULL, 0x0);
-                  }
-              }
-
-               /* XXX what we need to do is unroll the struct into its
-                * basic types, creating a uniform variable for each.
-                * For example:
-                * struct foo {
-                *   vec3 a;
-                *   vec4 b;
-                * };
-                * uniform foo f;
-                *
-                * Should produce uniforms:
-                * "f.a"  (GL_FLOAT_VEC3)
-                * "f.b"  (GL_FLOAT_VEC4)
-                */
-
-               if (var->initializer) {
-                  slang_info_log_error(A->log,
-                     "unsupported initializer for uniform '%s'", varName);
-                  return GL_FALSE;
-               }
-            }
-            else {
-               slang_info_log_error(A->log,
-                                    "invalid datatype for uniform variable %s",
-                                    varName);
-               return GL_FALSE;
-            }
-         }
-         else {
-            /* non-struct uniform */
-            if (!_slang_gen_var_decl(A, var, var->initializer))
-               return GL_FALSE;
-            store = var->store;
-         }
-      }
-      else {
-         /* pre-defined uniform, like gl_ModelviewMatrix */
-         /* We know it's a uniform, but don't allocate storage unless
-          * it's really used.
-          */
-         store = _slang_new_ir_storage_swz(PROGRAM_STATE_VAR, -1,
-                                           totalSize, swizzle);
-      }
-      if (dbg) printf("UNIFORM (sz %d) ", totalSize);
-   }
-   else if (var->type.qualifier == SLANG_QUAL_VARYING) {
-      /* varyings must be float, vec or mat */
-      if (!_slang_type_is_float_vec_mat(var->type.specifier.type) &&
-          var->type.specifier.type != SLANG_SPEC_ARRAY) {
-         slang_info_log_error(A->log,
-                              "varying '%s' must be float/vector/matrix",
-                              varName);
-         return GL_FALSE;
-      }
-
-      if (var->initializer) {
-         slang_info_log_error(A->log, "illegal initializer for varying '%s'",
-                              varName);
-         return GL_FALSE;
-      }
-
-      if (prog) {
-         /* user-defined varying */
-         GLbitfield flags;
-         GLint varyingLoc;
-         GLuint swizzle;
-
-         flags = 0x0;
-         if (var->type.centroid == SLANG_CENTROID)
-            flags |= PROG_PARAM_BIT_CENTROID;
-         if (var->type.variant == SLANG_INVARIANT)
-            flags |= PROG_PARAM_BIT_INVARIANT;
-
-         varyingLoc = _mesa_add_varying(prog->Varying, varName,
-                                        totalSize, GL_NONE, flags);
-         swizzle = _slang_var_swizzle(size, 0);
-         store = _slang_new_ir_storage_swz(PROGRAM_VARYING, varyingLoc,
-                                           totalSize, swizzle);
-      }
-      else {
-         /* pre-defined varying, like gl_Color or gl_TexCoord */
-         if (type == SLANG_UNIT_FRAGMENT_BUILTIN) {
-            /* fragment program input */
-            GLuint swizzle;
-            GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB,
-                                             &swizzle);
-            assert(index >= 0);
-            assert(index < FRAG_ATTRIB_MAX);
-            store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index,
-                                              size, swizzle);
-         }
-         else {
-            /* vertex program output */
-            GLint index = _slang_output_index(varName, GL_VERTEX_PROGRAM_ARB);
-            GLuint swizzle = _slang_var_swizzle(size, 0);
-            assert(index >= 0);
-            assert(index < VERT_RESULT_MAX);
-            assert(type == SLANG_UNIT_VERTEX_BUILTIN);
-            store = _slang_new_ir_storage_swz(PROGRAM_OUTPUT, index,
-                                              size, swizzle);
-         }
-         if (dbg) printf("V/F ");
-      }
-      if (dbg) printf("VARYING ");
-   }
-   else if (var->type.qualifier == SLANG_QUAL_ATTRIBUTE) {
-      GLuint swizzle;
-      GLint index;
-      /* attributes must be float, vec or mat */
-      if (!_slang_type_is_float_vec_mat(var->type.specifier.type)) {
-         slang_info_log_error(A->log,
-                              "attribute '%s' must be float/vector/matrix",
-                              varName);
-         return GL_FALSE;
-      }
-
-      if (prog) {
-         /* user-defined vertex attribute */
-         const GLint attr = -1; /* unknown */
-         swizzle = _slang_var_swizzle(size, 0);
-         index = _mesa_add_attribute(prog->Attributes, varName,
-                                     size, datatype, attr);
-         assert(index >= 0);
-         index = VERT_ATTRIB_GENERIC0 + index;
-      }
-      else {
-         /* pre-defined vertex attrib */
-         index = _slang_input_index(varName, GL_VERTEX_PROGRAM_ARB, &swizzle);
-         assert(index >= 0);
-      }
-      store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index, size, swizzle);
-      if (dbg) printf("ATTRIB ");
-   }
-   else if (var->type.qualifier == SLANG_QUAL_FIXEDINPUT) {
-      GLuint swizzle = SWIZZLE_XYZW; /* silence compiler warning */
-      GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB,
-                                       &swizzle);
-      store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index, size, swizzle);
-      if (dbg) printf("INPUT ");
-   }
-   else if (var->type.qualifier == SLANG_QUAL_FIXEDOUTPUT) {
-      if (type == SLANG_UNIT_VERTEX_BUILTIN) {
-         GLint index = _slang_output_index(varName, GL_VERTEX_PROGRAM_ARB);
-         store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, size);
-      }
-      else {
-         GLint index = _slang_output_index(varName, GL_FRAGMENT_PROGRAM_ARB);
-         GLint specialSize = 4; /* treat all fragment outputs as float[4] */
-         assert(type == SLANG_UNIT_FRAGMENT_BUILTIN);
-         store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, specialSize);
-      }
-      if (dbg) printf("OUTPUT ");
-   }
-   else if (var->type.qualifier == SLANG_QUAL_CONST && !prog) {
-      /* pre-defined global constant, like gl_MaxLights */
-      store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, size);
-      if (dbg) printf("CONST ");
-   }
-   else {
-      /* ordinary variable (may be const) */
-      slang_ir_node *n;
-
-      /* IR node to declare the variable */
-      n = _slang_gen_var_decl(A, var, var->initializer);
-
-      /* emit GPU instructions */
-      success = _slang_emit_code(n, A->vartable, A->program, A->pragmas, GL_FALSE, A->log);
-
-      _slang_free_ir_tree(n);
-   }
-
-   if (dbg) printf("GLOBAL VAR %s  idx %d\n", (char*) var->a_name,
-                   store ? store->Index : -2);
-
-   if (store)
-      var->store = store;  /* save var's storage info */
-
-   var->declared = GL_TRUE;
-
-   return success;
-}
-
-
-/**
- * Produce an IR tree from a function AST (fun->body).
- * Then call the code emitter to convert the IR tree into gl_program
- * instructions.
- */
-GLboolean
-_slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
-{
-   slang_ir_node *n;
-   GLboolean success = GL_TRUE;
-
-   if (strcmp((char *) fun->header.a_name, "main") != 0) {
-      /* we only really generate code for main, all other functions get
-       * inlined or codegen'd upon an actual call.
-       */
-#if 0
-      /* do some basic error checking though */
-      if (fun->header.type.specifier.type != SLANG_SPEC_VOID) {
-         /* check that non-void functions actually return something */
-         slang_operation *op
-            = _slang_find_node_type(fun->body, SLANG_OPER_RETURN);
-         if (!op) {
-            slang_info_log_error(A->log,
-                                 "function \"%s\" has no return statement",
-                                 (char *) fun->header.a_name);
-            printf(
-                   "function \"%s\" has no return statement\n",
-                   (char *) fun->header.a_name);
-            return GL_FALSE;
-         }
-      }
-#endif
-      return GL_TRUE;  /* not an error */
-   }
-
-#if 0
-   printf("\n*********** codegen_function %s\n", (char *) fun->header.a_name);
-   slang_print_function(fun, 1);
-#endif
-
-   /* should have been allocated earlier: */
-   assert(A->program->Parameters );
-   assert(A->program->Varying);
-   assert(A->vartable);
-
-   A->LoopDepth = 0;
-   A->UseReturnFlag = GL_FALSE;
-   A->CurFunction = fun;
-
-   /* fold constant expressions, etc. */
-   _slang_simplify(fun->body, &A->space, A->atoms);
-
-#if 0
-   printf("\n*********** simplified %s\n", (char *) fun->header.a_name);
-   slang_print_function(fun, 1);
-#endif
-
-   /* Create an end-of-function label */
-   A->curFuncEndLabel = _slang_label_new("__endOfFunc__main");
-
-   /* push new vartable scope */
-   _slang_push_var_table(A->vartable);
-
-   /* Generate IR tree for the function body code */
-   n = _slang_gen_operation(A, fun->body);
-   if (n)
-      n = new_node1(IR_SCOPE, n);
-
-   /* pop vartable, restore previous */
-   _slang_pop_var_table(A->vartable);
-
-   if (!n) {
-      /* XXX record error */
-      return GL_FALSE;
-   }
-
-   /* append an end-of-function-label to IR tree */
-   n = new_seq(n, new_label(A->curFuncEndLabel));
-
-   /*_slang_label_delete(A->curFuncEndLabel);*/
-   A->curFuncEndLabel = NULL;
-
-#if 0
-   printf("************* New AST for %s *****\n", (char*)fun->header.a_name);
-   slang_print_function(fun, 1);
-#endif
-#if 0
-   printf("************* IR for %s *******\n", (char*)fun->header.a_name);
-   _slang_print_ir_tree(n, 0);
-#endif
-#if 0
-   printf("************* End codegen function ************\n\n");
-#endif
-
-   if (A->UnresolvedRefs) {
-      /* Can't codegen at this time.
-       * At link time we'll concatenate all the vertex shaders and/or all
-       * the fragment shaders and try recompiling.
-       */
-      return GL_TRUE;
-   }
-
-   /* Emit program instructions */
-   success = _slang_emit_code(n, A->vartable, A->program, A->pragmas, GL_TRUE, A->log);
-   _slang_free_ir_tree(n);
-
-   /* free codegen context */
-   /*
-   free(A->codegen);
-   */
-
-   return success;
-}
-
diff --git a/src/mesa/shader/slang/slang_codegen.h b/src/mesa/shader/slang/slang_codegen.h
deleted file mode 100644 (file)
index 461633f..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.3
- *
- * Copyright (C) 2005-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.
- */
-
-
-#ifndef SLANG_CODEGEN_H
-#define SLANG_CODEGEN_H
-
-
-#include "main/imports.h"
-#include "slang_compile.h"
-
-
-#define MAX_LOOP_DEPTH 30
-
-
-typedef struct slang_assemble_ctx_
-{
-   slang_atom_pool *atoms;
-   slang_name_space space;
-   struct gl_program *program;
-   struct gl_sl_pragmas *pragmas;
-   slang_var_table *vartable;
-   slang_info_log *log;
-   GLboolean allow_uniform_initializers;
-
-   /* current loop stack */
-   const slang_operation *LoopOperStack[MAX_LOOP_DEPTH];
-   struct slang_ir_node_ *LoopIRStack[MAX_LOOP_DEPTH];
-   GLuint LoopDepth;
-
-   /* current function */
-   struct slang_function_ *CurFunction;
-   struct slang_label_ *curFuncEndLabel;
-   GLboolean UseReturnFlag;
-
-   GLboolean UnresolvedRefs;
-   GLboolean EmitContReturn;
-} slang_assemble_ctx;
-
-
-extern GLuint
-_slang_sizeof_type_specifier(const slang_type_specifier *spec);
-
-extern GLboolean
-_slang_codegen_function(slang_assemble_ctx *A , struct slang_function_ *fun);
-
-extern GLboolean
-_slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
-                               slang_unit_type type);
-
-
-#endif /* SLANG_CODEGEN_H */
diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c
deleted file mode 100644 (file)
index b6b1f3c..0000000
+++ /dev/null
@@ -1,3044 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
- * Copyright (C) 2008 VMware, 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
- * 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 slang_compile.c
- * slang front-end compiler
- * \author Michal Krol
- */
-
-#include "main/imports.h"
-#include "main/context.h"
-#include "shader/program.h"
-#include "shader/programopt.h"
-#include "shader/prog_optimize.h"
-#include "shader/prog_print.h"
-#include "shader/prog_parameter.h"
-#include "../../glsl/pp/sl_pp_public.h"
-#include "../../glsl/cl/sl_cl_parse.h"
-#include "slang_codegen.h"
-#include "slang_compile.h"
-#include "slang_storage.h"
-#include "slang_log.h"
-#include "slang_mem.h"
-#include "slang_vartable.h"
-#include "slang_simplify.h"
-
-/*
- * This is a straightforward implementation of the slang front-end
- * compiler.  Lots of error-checking functionality is missing but
- * every well-formed shader source should compile successfully and
- * execute as expected. However, some semantically ill-formed shaders
- * may be accepted resulting in undefined behaviour.
- */
-
-
-/** re-defined below, should be the same though */
-#define TYPE_SPECIFIER_COUNT 36
-
-
-/**
- * Check if the given identifier is legal.
- */
-static GLboolean
-legal_identifier(slang_atom name)
-{
-   /* "gl_" is a reserved prefix */
-   if (strncmp((char *) name, "gl_", 3) == 0) {
-      return GL_FALSE;
-   }
-   return GL_TRUE;
-}
-
-
-/*
- * slang_code_unit
- */
-
-GLvoid
-_slang_code_unit_ctr(slang_code_unit * self,
-                     struct slang_code_object_ * object)
-{
-   _slang_variable_scope_ctr(&self->vars);
-   _slang_function_scope_ctr(&self->funs);
-   _slang_struct_scope_ctr(&self->structs);
-   self->object = object;
-}
-
-GLvoid
-_slang_code_unit_dtr(slang_code_unit * self)
-{
-   slang_variable_scope_destruct(&self->vars);
-   slang_function_scope_destruct(&self->funs);
-   slang_struct_scope_destruct(&self->structs);
-}
-
-/*
- * slang_code_object
- */
-
-GLvoid
-_slang_code_object_ctr(slang_code_object * self)
-{
-   GLuint i;
-
-   for (i = 0; i < SLANG_BUILTIN_TOTAL; i++)
-      _slang_code_unit_ctr(&self->builtin[i], self);
-   _slang_code_unit_ctr(&self->unit, self);
-   slang_atom_pool_construct(&self->atompool);
-}
-
-GLvoid
-_slang_code_object_dtr(slang_code_object * self)
-{
-   GLuint i;
-
-   for (i = 0; i < SLANG_BUILTIN_TOTAL; i++)
-      _slang_code_unit_dtr(&self->builtin[i]);
-   _slang_code_unit_dtr(&self->unit);
-   slang_atom_pool_destruct(&self->atompool);
-}
-
-
-/* slang_parse_ctx */
-
-typedef struct slang_parse_ctx_
-{
-   const unsigned char *I;
-   slang_info_log *L;
-   int parsing_builtin;
-   GLboolean global_scope;   /**< Is object being declared a global? */
-   slang_atom_pool *atoms;
-   slang_unit_type type;     /**< Vertex vs. Fragment */
-   GLuint version;           /**< user-specified (or default) #version */
-} slang_parse_ctx;
-
-/* slang_output_ctx */
-
-typedef struct slang_output_ctx_
-{
-   slang_variable_scope *vars;
-   slang_function_scope *funs;
-   slang_struct_scope *structs;
-   struct gl_program *program;
-   struct gl_sl_pragmas *pragmas;
-   slang_var_table *vartable;
-   GLuint default_precision[TYPE_SPECIFIER_COUNT];
-   GLboolean allow_precision;
-   GLboolean allow_invariant;
-   GLboolean allow_centroid;
-   GLboolean allow_array_types;  /* float[] syntax */
-} slang_output_ctx;
-
-/* _slang_compile() */
-
-
-/* Debugging aid, print file/line where parsing error is detected */
-#define RETURN0 \
-   do { \
-      if (0) \
-         printf("slang error at %s:%d\n", __FILE__, __LINE__); \
-      return 0; \
-   } while (0)
-
-
-static void
-parse_identifier_str(slang_parse_ctx * C, char **id)
-{
-   *id = (char *) C->I;
-   C->I += strlen(*id) + 1;
-}
-
-static slang_atom
-parse_identifier(slang_parse_ctx * C)
-{
-   const char *id;
-
-   id = (const char *) C->I;
-   C->I += strlen(id) + 1;
-   return slang_atom_pool_atom(C->atoms, id);
-}
-
-static int
-is_hex_digit(char c)
-{
-   return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
-}
-
-static int
-parse_general_number(slang_parse_ctx *ctx, float *number)
-{
-   char *flt = NULL;
-
-   if (*ctx->I == '0') {
-      int value = 0;
-      const unsigned char *pi;
-
-      if (ctx->I[1] == 'x' || ctx->I[1] == 'X') {
-         ctx->I += 2;
-         if (!is_hex_digit(*ctx->I)) {
-            return 0;
-         }
-         do {
-            int digit;
-
-            if (*ctx->I >= '0' && *ctx->I <= '9') {
-               digit = (int)(*ctx->I - '0');
-            } else if (*ctx->I >= 'a' && *ctx->I <= 'f') {
-               digit = (int)(*ctx->I - 'a') + 10;
-            } else {
-               digit = (int)(*ctx->I - 'A') + 10;
-            }
-            value = value * 0x10 + digit;
-            ctx->I++;
-         } while (is_hex_digit(*ctx->I));
-         if (*ctx->I != '\0') {
-            return 0;
-         }
-         ctx->I++;
-         *number = (float)value;
-         return 1;
-      }
-
-      pi = ctx->I;
-      pi++;
-      while (*pi >= '0' && *pi <= '7') {
-         int digit;
-
-         digit = (int)(*pi - '0');
-         value = value * 010 + digit;
-         pi++;
-      }
-      if (*pi == '\0') {
-         pi++;
-         ctx->I = pi;
-         *number = (float)value;
-         return 1;
-      }
-   }
-
-   parse_identifier_str(ctx, &flt);
-   flt = _mesa_strdup(flt);
-   if (!flt) {
-      return 0;
-   }
-   if (flt[strlen(flt) - 1] == 'f' || flt[strlen(flt) - 1] == 'F') {
-      flt[strlen(flt) - 1] = '\0';
-   }
-   *number = _mesa_strtof(flt, (char **)NULL);
-   free(flt);
-
-   return 1;
-}
-
-static int
-parse_number(slang_parse_ctx * C, int *number)
-{
-   const int radix = (int) (*C->I++);
-
-   if (radix == 1) {
-      float f = 0.0f;
-
-      parse_general_number(C, &f);
-      *number = (int)f;
-   } else {
-      *number = 0;
-      while (*C->I != '\0') {
-         int digit;
-         if (*C->I >= '0' && *C->I <= '9')
-            digit = (int) (*C->I - '0');
-         else if (*C->I >= 'A' && *C->I <= 'Z')
-            digit = (int) (*C->I - 'A') + 10;
-         else
-            digit = (int) (*C->I - 'a') + 10;
-         *number = *number * radix + digit;
-         C->I++;
-      }
-      C->I++;
-   }
-   if (*number > 65535)
-      slang_info_log_warning(C->L, "%d: literal integer overflow.", *number);
-   return 1;
-}
-
-static int
-parse_float(slang_parse_ctx * C, float *number)
-{
-   if (*C->I == 1) {
-      C->I++;
-      parse_general_number(C, number);
-   } else {
-      char *integral = NULL;
-      char *fractional = NULL;
-      char *exponent = NULL;
-      char *whole = NULL;
-
-      parse_identifier_str(C, &integral);
-      parse_identifier_str(C, &fractional);
-      parse_identifier_str(C, &exponent);
-
-      whole = (char *) _slang_alloc((strlen(integral) +
-                                     strlen(fractional) +
-                                     strlen(exponent) + 3) * sizeof(char));
-      if (whole == NULL) {
-         slang_info_log_memory(C->L);
-         RETURN0;
-      }
-
-      slang_string_copy(whole, integral);
-      slang_string_concat(whole, ".");
-      slang_string_concat(whole, fractional);
-      slang_string_concat(whole, "E");
-      slang_string_concat(whole, exponent);
-
-      *number = _mesa_strtof(whole, (char **) NULL);
-
-      _slang_free(whole);
-   }
-
-   return 1;
-}
-
-/* revision number - increment after each change affecting emitted output */
-#define REVISION 5
-
-static int
-check_revision(slang_parse_ctx * C)
-{
-   if (*C->I != REVISION) {
-      slang_info_log_error(C->L, "Internal compiler error.");
-      RETURN0;
-   }
-   C->I++;
-   return 1;
-}
-
-static int parse_statement(slang_parse_ctx *, slang_output_ctx *,
-                           slang_operation *);
-static int parse_expression(slang_parse_ctx *, slang_output_ctx *,
-                            slang_operation *);
-static int parse_type_specifier(slang_parse_ctx *, slang_output_ctx *,
-                                slang_type_specifier *);
-static int
-parse_type_array_size(slang_parse_ctx *C,
-                      slang_output_ctx *O,
-                      GLint *array_len);
-
-static GLboolean
-parse_array_len(slang_parse_ctx * C, slang_output_ctx * O, GLuint * len)
-{
-   slang_operation array_size;
-   slang_name_space space;
-   GLboolean result;
-
-   if (!slang_operation_construct(&array_size))
-      return GL_FALSE;
-   if (!parse_expression(C, O, &array_size)) {
-      slang_operation_destruct(&array_size);
-      return GL_FALSE;
-   }
-
-   space.funcs = O->funs;
-   space.structs = O->structs;
-   space.vars = O->vars;
-
-   /* evaluate compile-time expression which is array size */
-   _slang_simplify(&array_size, &space, C->atoms);
-
-   if (array_size.type == SLANG_OPER_LITERAL_INT) {
-      result = GL_TRUE;
-      *len = (GLint) array_size.literal[0];
-   } else if (array_size.type == SLANG_OPER_IDENTIFIER) {
-      slang_variable *var = _slang_variable_locate(array_size.locals, array_size.a_id, GL_TRUE);
-      if (!var) {
-         slang_info_log_error(C->L, "undefined variable '%s'",
-                              (char *) array_size.a_id);
-         result = GL_FALSE;
-      } else if (var->type.qualifier == SLANG_QUAL_CONST &&
-                 var->type.specifier.type == SLANG_SPEC_INT) {
-         if (var->initializer &&
-             var->initializer->type == SLANG_OPER_LITERAL_INT) {
-            *len = (GLint) var->initializer->literal[0];
-            result = GL_TRUE;
-         } else {
-            slang_info_log_error(C->L, "unable to parse array size declaration");
-            result = GL_FALSE;
-         }
-      } else {
-         slang_info_log_error(C->L, "unable to parse array size declaration");
-         result = GL_FALSE;
-      }
-   } else {
-      result = GL_FALSE;
-   }
-
-   slang_operation_destruct(&array_size);
-   return result;
-}
-
-static GLboolean
-calculate_var_size(slang_parse_ctx * C, slang_output_ctx * O,
-                   slang_variable * var)
-{
-   slang_storage_aggregate agg;
-
-   if (!slang_storage_aggregate_construct(&agg))
-      return GL_FALSE;
-   if (!_slang_aggregate_variable(&agg, &var->type.specifier, var->array_len,
-                                  O->funs, O->structs, O->vars, C->atoms)) {
-      slang_storage_aggregate_destruct(&agg);
-      return GL_FALSE;
-   }
-   var->size = _slang_sizeof_aggregate(&agg);
-   slang_storage_aggregate_destruct(&agg);
-   return GL_TRUE;
-}
-
-static void
-promote_type_to_array(slang_parse_ctx *C,
-                      slang_fully_specified_type *type,
-                      GLint array_len)
-{
-   slang_type_specifier *baseType =
-      slang_type_specifier_new(type->specifier.type, NULL, NULL);
-
-   type->specifier.type = SLANG_SPEC_ARRAY;
-   type->specifier._array = baseType;
-   type->array_len = array_len;
-}
-
-
-static GLboolean
-convert_to_array(slang_parse_ctx * C, slang_variable * var,
-                 const slang_type_specifier * sp)
-{
-   /* sized array - mark it as array, copy the specifier to the array element
-    * and parse the expression */
-   var->type.specifier.type = SLANG_SPEC_ARRAY;
-   var->type.specifier._array = (slang_type_specifier *)
-      _slang_alloc(sizeof(slang_type_specifier));
-   if (var->type.specifier._array == NULL) {
-      slang_info_log_memory(C->L);
-      return GL_FALSE;
-   }
-   slang_type_specifier_ctr(var->type.specifier._array);
-   return slang_type_specifier_copy(var->type.specifier._array, sp);
-}
-
-/* structure field */
-#define FIELD_NONE 0
-#define FIELD_NEXT 1
-#define FIELD_ARRAY 2
-
-static GLboolean
-parse_struct_field_var(slang_parse_ctx * C, slang_output_ctx * O,
-                       slang_variable * var, slang_atom a_name,
-                       const slang_type_specifier * sp,
-                       GLuint array_len)
-{
-   var->a_name = a_name;
-   if (var->a_name == SLANG_ATOM_NULL)
-      return GL_FALSE;
-
-   switch (*C->I++) {
-   case FIELD_NONE:
-      if (array_len != -1) {
-         if (!convert_to_array(C, var, sp))
-            return GL_FALSE;
-         var->array_len = array_len;
-      }
-      else {
-         if (!slang_type_specifier_copy(&var->type.specifier, sp))
-            return GL_FALSE;
-      }
-      break;
-   case FIELD_ARRAY:
-      if (array_len != -1)
-         return GL_FALSE;
-      if (!convert_to_array(C, var, sp))
-         return GL_FALSE;
-      if (!parse_array_len(C, O, &var->array_len))
-         return GL_FALSE;
-      break;
-   default:
-      return GL_FALSE;
-   }
-
-   return calculate_var_size(C, O, var);
-}
-
-static int
-parse_struct_field(slang_parse_ctx * C, slang_output_ctx * O,
-                   slang_struct * st, slang_type_specifier * sp)
-{
-   slang_output_ctx o = *O;
-   GLint array_len;
-
-   o.structs = st->structs;
-   if (!parse_type_specifier(C, &o, sp))
-      RETURN0;
-   if (!parse_type_array_size(C, &o, &array_len))
-      RETURN0;
-
-   do {
-      slang_atom a_name;
-      slang_variable *var = slang_variable_scope_grow(st->fields);
-      if (!var) {
-         slang_info_log_memory(C->L);
-         RETURN0;
-      }
-      a_name = parse_identifier(C);
-      if (_slang_variable_locate(st->fields, a_name, GL_FALSE)) {
-         slang_info_log_error(C->L, "duplicate field '%s'", (char *) a_name);
-         RETURN0;
-      }
-
-      if (!parse_struct_field_var(C, &o, var, a_name, sp, array_len))
-         RETURN0;
-   }
-   while (*C->I++ != FIELD_NONE);
-
-   return 1;
-}
-
-static int
-parse_struct(slang_parse_ctx * C, slang_output_ctx * O, slang_struct ** st)
-{
-   slang_atom a_name;
-   const char *name;
-
-   /* parse struct name (if any) and make sure it is unique in current scope */
-   a_name = parse_identifier(C);
-   if (a_name == SLANG_ATOM_NULL)
-      RETURN0;
-
-   name = slang_atom_pool_id(C->atoms, a_name);
-   if (name[0] != '\0'
-       && slang_struct_scope_find(O->structs, a_name, 0) != NULL) {
-      slang_info_log_error(C->L, "%s: duplicate type name.", name);
-      RETURN0;
-   }
-
-   /* set-up a new struct */
-   *st = (slang_struct *) _slang_alloc(sizeof(slang_struct));
-   if (*st == NULL) {
-      slang_info_log_memory(C->L);
-      RETURN0;
-   }
-   if (!slang_struct_construct(*st)) {
-      _slang_free(*st);
-      *st = NULL;
-      slang_info_log_memory(C->L);
-      RETURN0;
-   }
-   (**st).a_name = a_name;
-   (**st).structs->outer_scope = O->structs;
-
-   /* parse individual struct fields */
-   do {
-      slang_type_specifier sp;
-
-      slang_type_specifier_ctr(&sp);
-      if (!parse_struct_field(C, O, *st, &sp)) {
-         slang_type_specifier_dtr(&sp);
-         RETURN0;
-      }
-      slang_type_specifier_dtr(&sp);
-   }
-   while (*C->I++ != FIELD_NONE);
-
-   /* if named struct, copy it to current scope */
-   if (name[0] != '\0') {
-      slang_struct *s;
-
-      O->structs->structs =
-         (slang_struct *) _slang_realloc(O->structs->structs,
-                                         O->structs->num_structs
-                                         * sizeof(slang_struct),
-                                         (O->structs->num_structs + 1)
-                                         * sizeof(slang_struct));
-      if (O->structs->structs == NULL) {
-         slang_info_log_memory(C->L);
-         RETURN0;
-      }
-      s = &O->structs->structs[O->structs->num_structs];
-      if (!slang_struct_construct(s))
-         RETURN0;
-      O->structs->num_structs++;
-      if (!slang_struct_copy(s, *st))
-         RETURN0;
-   }
-
-   return 1;
-}
-
-
-/* invariant qualifer */
-#define TYPE_VARIANT    90
-#define TYPE_INVARIANT  91
-
-static int
-parse_type_variant(slang_parse_ctx * C, slang_type_variant *variant)
-{
-   GLuint invariant = *C->I++;
-   switch (invariant) {
-   case TYPE_VARIANT:
-      *variant = SLANG_VARIANT;
-      return 1;
-   case TYPE_INVARIANT:
-      *variant = SLANG_INVARIANT;
-      return 1;
-   default:
-      RETURN0;
-   }
-}
-
-
-/* centroid qualifer */
-#define TYPE_CENTER    95
-#define TYPE_CENTROID  96
-
-static int
-parse_type_centroid(slang_parse_ctx * C, slang_type_centroid *centroid)
-{
-   GLuint c = *C->I++;
-   switch (c) {
-   case TYPE_CENTER:
-      *centroid = SLANG_CENTER;
-      return 1;
-   case TYPE_CENTROID:
-      *centroid = SLANG_CENTROID;
-      return 1;
-   default:
-      RETURN0;
-   }
-}
-
-
-/* Layout qualifiers */
-#define LAYOUT_QUALIFIER_NONE                      0
-#define LAYOUT_QUALIFIER_UPPER_LEFT                1
-#define LAYOUT_QUALIFIER_PIXEL_CENTER_INTEGER      2
-
-static int
-parse_layout_qualifiers(slang_parse_ctx * C, slang_layout_qualifier *layout)
-{
-   *layout = 0x0;
-
-   /* the layout qualifiers come as a list of LAYOUT_QUALIFER_x tokens,
-    * terminated by LAYOUT_QUALIFIER_NONE.
-    */
-   while (1) {
-      GLuint c = *C->I++;
-      switch (c) {
-      case LAYOUT_QUALIFIER_NONE:
-         /* end of list of qualifiers */
-         return 1;
-      case LAYOUT_QUALIFIER_UPPER_LEFT:
-         *layout |= SLANG_LAYOUT_UPPER_LEFT_BIT;
-         break;
-      case LAYOUT_QUALIFIER_PIXEL_CENTER_INTEGER:
-         *layout |= SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT;
-         break;
-      default:
-         assert(0 && "Bad layout qualifier");
-      }
-   }
-}
-
-
-/* type qualifier */
-#define TYPE_QUALIFIER_NONE 0
-#define TYPE_QUALIFIER_CONST 1
-#define TYPE_QUALIFIER_ATTRIBUTE 2
-#define TYPE_QUALIFIER_VARYING 3
-#define TYPE_QUALIFIER_UNIFORM 4
-#define TYPE_QUALIFIER_FIXEDOUTPUT 5
-#define TYPE_QUALIFIER_FIXEDINPUT 6
-
-static int
-parse_type_qualifier(slang_parse_ctx * C, slang_type_qualifier * qual)
-{
-   GLuint qualifier = *C->I++;
-   switch (qualifier) {
-   case TYPE_QUALIFIER_NONE:
-      *qual = SLANG_QUAL_NONE;
-      break;
-   case TYPE_QUALIFIER_CONST:
-      *qual = SLANG_QUAL_CONST;
-      break;
-   case TYPE_QUALIFIER_ATTRIBUTE:
-      *qual = SLANG_QUAL_ATTRIBUTE;
-      break;
-   case TYPE_QUALIFIER_VARYING:
-      *qual = SLANG_QUAL_VARYING;
-      break;
-   case TYPE_QUALIFIER_UNIFORM:
-      *qual = SLANG_QUAL_UNIFORM;
-      break;
-   case TYPE_QUALIFIER_FIXEDOUTPUT:
-      *qual = SLANG_QUAL_FIXEDOUTPUT;
-      break;
-   case TYPE_QUALIFIER_FIXEDINPUT:
-      *qual = SLANG_QUAL_FIXEDINPUT;
-      break;
-   default:
-      RETURN0;
-   }
-   return 1;
-}
-
-/* type specifier */
-#define TYPE_SPECIFIER_VOID 0
-#define TYPE_SPECIFIER_BOOL 1
-#define TYPE_SPECIFIER_BVEC2 2
-#define TYPE_SPECIFIER_BVEC3 3
-#define TYPE_SPECIFIER_BVEC4 4
-#define TYPE_SPECIFIER_INT 5
-#define TYPE_SPECIFIER_IVEC2 6
-#define TYPE_SPECIFIER_IVEC3 7
-#define TYPE_SPECIFIER_IVEC4 8
-#define TYPE_SPECIFIER_FLOAT 9
-#define TYPE_SPECIFIER_VEC2 10
-#define TYPE_SPECIFIER_VEC3 11
-#define TYPE_SPECIFIER_VEC4 12
-#define TYPE_SPECIFIER_MAT2 13
-#define TYPE_SPECIFIER_MAT3 14
-#define TYPE_SPECIFIER_MAT4 15
-#define TYPE_SPECIFIER_SAMPLER1D 16
-#define TYPE_SPECIFIER_SAMPLER2D 17
-#define TYPE_SPECIFIER_SAMPLER3D 18
-#define TYPE_SPECIFIER_SAMPLERCUBE 19
-#define TYPE_SPECIFIER_SAMPLER1DSHADOW 20
-#define TYPE_SPECIFIER_SAMPLER2DSHADOW 21
-#define TYPE_SPECIFIER_SAMPLER2DRECT 22
-#define TYPE_SPECIFIER_SAMPLER2DRECTSHADOW 23
-#define TYPE_SPECIFIER_STRUCT 24
-#define TYPE_SPECIFIER_TYPENAME 25
-#define TYPE_SPECIFIER_MAT23 26
-#define TYPE_SPECIFIER_MAT32 27
-#define TYPE_SPECIFIER_MAT24 28
-#define TYPE_SPECIFIER_MAT42 29
-#define TYPE_SPECIFIER_MAT34 30
-#define TYPE_SPECIFIER_MAT43 31
-#define TYPE_SPECIFIER_SAMPLER_1D_ARRAY 32
-#define TYPE_SPECIFIER_SAMPLER_2D_ARRAY 33
-#define TYPE_SPECIFIER_SAMPLER_1D_ARRAY_SHADOW 34
-#define TYPE_SPECIFIER_SAMPLER_2D_ARRAY_SHADOW 35
-#define TYPE_SPECIFIER_COUNT 36
-
-static int
-parse_type_specifier(slang_parse_ctx * C, slang_output_ctx * O,
-                     slang_type_specifier * spec)
-{
-   int type = *C->I++;
-   switch (type) {
-   case TYPE_SPECIFIER_VOID:
-      spec->type = SLANG_SPEC_VOID;
-      break;
-   case TYPE_SPECIFIER_BOOL:
-      spec->type = SLANG_SPEC_BOOL;
-      break;
-   case TYPE_SPECIFIER_BVEC2:
-      spec->type = SLANG_SPEC_BVEC2;
-      break;
-   case TYPE_SPECIFIER_BVEC3:
-      spec->type = SLANG_SPEC_BVEC3;
-      break;
-   case TYPE_SPECIFIER_BVEC4:
-      spec->type = SLANG_SPEC_BVEC4;
-      break;
-   case TYPE_SPECIFIER_INT:
-      spec->type = SLANG_SPEC_INT;
-      break;
-   case TYPE_SPECIFIER_IVEC2:
-      spec->type = SLANG_SPEC_IVEC2;
-      break;
-   case TYPE_SPECIFIER_IVEC3:
-      spec->type = SLANG_SPEC_IVEC3;
-      break;
-   case TYPE_SPECIFIER_IVEC4:
-      spec->type = SLANG_SPEC_IVEC4;
-      break;
-   case TYPE_SPECIFIER_FLOAT:
-      spec->type = SLANG_SPEC_FLOAT;
-      break;
-   case TYPE_SPECIFIER_VEC2:
-      spec->type = SLANG_SPEC_VEC2;
-      break;
-   case TYPE_SPECIFIER_VEC3:
-      spec->type = SLANG_SPEC_VEC3;
-      break;
-   case TYPE_SPECIFIER_VEC4:
-      spec->type = SLANG_SPEC_VEC4;
-      break;
-   case TYPE_SPECIFIER_MAT2:
-      spec->type = SLANG_SPEC_MAT2;
-      break;
-   case TYPE_SPECIFIER_MAT3:
-      spec->type = SLANG_SPEC_MAT3;
-      break;
-   case TYPE_SPECIFIER_MAT4:
-      spec->type = SLANG_SPEC_MAT4;
-      break;
-   case TYPE_SPECIFIER_MAT23:
-      spec->type = SLANG_SPEC_MAT23;
-      break;
-   case TYPE_SPECIFIER_MAT32:
-      spec->type = SLANG_SPEC_MAT32;
-      break;
-   case TYPE_SPECIFIER_MAT24:
-      spec->type = SLANG_SPEC_MAT24;
-      break;
-   case TYPE_SPECIFIER_MAT42:
-      spec->type = SLANG_SPEC_MAT42;
-      break;
-   case TYPE_SPECIFIER_MAT34:
-      spec->type = SLANG_SPEC_MAT34;
-      break;
-   case TYPE_SPECIFIER_MAT43:
-      spec->type = SLANG_SPEC_MAT43;
-      break;
-   case TYPE_SPECIFIER_SAMPLER1D:
-      spec->type = SLANG_SPEC_SAMPLER_1D;
-      break;
-   case TYPE_SPECIFIER_SAMPLER2D:
-      spec->type = SLANG_SPEC_SAMPLER_2D;
-      break;
-   case TYPE_SPECIFIER_SAMPLER3D:
-      spec->type = SLANG_SPEC_SAMPLER_3D;
-      break;
-   case TYPE_SPECIFIER_SAMPLERCUBE:
-      spec->type = SLANG_SPEC_SAMPLER_CUBE;
-      break;
-   case TYPE_SPECIFIER_SAMPLER2DRECT:
-      spec->type = SLANG_SPEC_SAMPLER_RECT;
-      break;
-   case TYPE_SPECIFIER_SAMPLER1DSHADOW:
-      spec->type = SLANG_SPEC_SAMPLER_1D_SHADOW;
-      break;
-   case TYPE_SPECIFIER_SAMPLER2DSHADOW:
-      spec->type = SLANG_SPEC_SAMPLER_2D_SHADOW;
-      break;
-   case TYPE_SPECIFIER_SAMPLER2DRECTSHADOW:
-      spec->type = SLANG_SPEC_SAMPLER_RECT_SHADOW;
-      break;
-   case TYPE_SPECIFIER_SAMPLER_1D_ARRAY:
-      spec->type = SLANG_SPEC_SAMPLER_1D_ARRAY;
-      break;
-   case TYPE_SPECIFIER_SAMPLER_2D_ARRAY:
-      spec->type = SLANG_SPEC_SAMPLER_2D_ARRAY;
-      break;
-   case TYPE_SPECIFIER_SAMPLER_1D_ARRAY_SHADOW:
-      spec->type = SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW;
-      break;
-   case TYPE_SPECIFIER_SAMPLER_2D_ARRAY_SHADOW:
-      spec->type = SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW;
-      break;
-   case TYPE_SPECIFIER_STRUCT:
-      spec->type = SLANG_SPEC_STRUCT;
-      if (!parse_struct(C, O, &spec->_struct))
-         RETURN0;
-      break;
-   case TYPE_SPECIFIER_TYPENAME:
-      spec->type = SLANG_SPEC_STRUCT;
-      {
-         slang_atom a_name;
-         slang_struct *stru;
-
-         a_name = parse_identifier(C);
-         if (a_name == NULL)
-            RETURN0;
-
-         stru = slang_struct_scope_find(O->structs, a_name, 1);
-         if (stru == NULL) {
-            slang_info_log_error(C->L, "undeclared type name '%s'",
-                                 slang_atom_pool_id(C->atoms, a_name));
-            RETURN0;
-         }
-
-         spec->_struct = (slang_struct *) _slang_alloc(sizeof(slang_struct));
-         if (spec->_struct == NULL) {
-            slang_info_log_memory(C->L);
-            RETURN0;
-         }
-         if (!slang_struct_construct(spec->_struct)) {
-            _slang_free(spec->_struct);
-            spec->_struct = NULL;
-            RETURN0;
-         }
-         if (!slang_struct_copy(spec->_struct, stru))
-            RETURN0;
-      }
-      break;
-   default:
-      RETURN0;
-   }
-   return 1;
-}
-
-#define TYPE_SPECIFIER_NONARRAY 0
-#define TYPE_SPECIFIER_ARRAY    1
-
-static int
-parse_type_array_size(slang_parse_ctx *C,
-                      slang_output_ctx *O,
-                      GLint *array_len)
-{
-   GLuint size;
-
-   switch (*C->I++) {
-   case TYPE_SPECIFIER_NONARRAY:
-      *array_len = -1; /* -1 = not an array */
-      break;
-   case TYPE_SPECIFIER_ARRAY:
-      if (!parse_array_len(C, O, &size))
-         RETURN0;
-      *array_len = (GLint) size;
-      break;
-   default:
-      assert(0);
-      RETURN0;
-   }
-   return 1;
-}
-
-#define PRECISION_DEFAULT 0
-#define PRECISION_LOW     1
-#define PRECISION_MEDIUM  2
-#define PRECISION_HIGH    3
-
-static int
-parse_type_precision(slang_parse_ctx *C,
-                     slang_type_precision *precision)
-{
-   GLint prec = *C->I++;
-   switch (prec) {
-   case PRECISION_DEFAULT:
-      *precision = SLANG_PREC_DEFAULT;
-      return 1;
-   case PRECISION_LOW:
-      *precision = SLANG_PREC_LOW;
-      return 1;
-   case PRECISION_MEDIUM:
-      *precision = SLANG_PREC_MEDIUM;
-      return 1;
-   case PRECISION_HIGH:
-      *precision = SLANG_PREC_HIGH;
-      return 1;
-   default:
-      RETURN0;
-   }
-}
-
-static int
-parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O,
-                           slang_fully_specified_type * type)
-{
-   if (!parse_layout_qualifiers(C, &type->layout))
-      RETURN0;
-
-   if (!parse_type_variant(C, &type->variant))
-      RETURN0;
-
-   if (!parse_type_centroid(C, &type->centroid))
-      RETURN0;
-
-   if (!parse_type_qualifier(C, &type->qualifier))
-      RETURN0;
-
-   if (!parse_type_precision(C, &type->precision))
-      RETURN0;
-
-   if (!parse_type_specifier(C, O, &type->specifier))
-      RETURN0;
-
-   if (!parse_type_array_size(C, O, &type->array_len))
-      RETURN0;
-
-   if (!O->allow_invariant && type->variant == SLANG_INVARIANT) {
-      slang_info_log_error(C->L,
-         "'invariant' keyword not allowed (perhaps set #version 120)");
-      RETURN0;
-   }
-
-   if (!O->allow_centroid && type->centroid == SLANG_CENTROID) {
-      slang_info_log_error(C->L,
-         "'centroid' keyword not allowed (perhaps set #version 120)");
-      RETURN0;
-   }
-   else if (type->centroid == SLANG_CENTROID &&
-            type->qualifier != SLANG_QUAL_VARYING) {
-      slang_info_log_error(C->L,
-         "'centroid' keyword only allowed for varying vars");
-      RETURN0;
-   }
-
-
-   /* need this?
-   if (type->qualifier != SLANG_QUAL_VARYING &&
-       type->variant == SLANG_INVARIANT) {
-      slang_info_log_error(C->L,
-                           "invariant qualifer only allowed for varying vars");
-      RETURN0;
-   }
-   */
-
-   if (O->allow_precision) {
-      if (type->precision == SLANG_PREC_DEFAULT) {
-         assert(type->specifier.type < TYPE_SPECIFIER_COUNT);
-         /* use the default precision for this datatype */
-         type->precision = O->default_precision[type->specifier.type];
-      }
-   }
-   else {
-      /* only default is allowed */
-      if (type->precision != SLANG_PREC_DEFAULT) {
-         slang_info_log_error(C->L, "precision qualifiers not allowed");
-         RETURN0;
-      }
-   }
-
-   if (!O->allow_array_types && type->array_len >= 0) {
-      slang_info_log_error(C->L, "first-class array types not allowed");
-      RETURN0;
-   }
-
-   if (type->array_len >= 0) {
-      /* convert type to array type (ex: convert "int" to "array of int" */
-      promote_type_to_array(C, type, type->array_len);
-   }
-
-   return 1;
-}
-
-/* operation */
-#define OP_END 0
-#define OP_BLOCK_BEGIN_NO_NEW_SCOPE 1
-#define OP_BLOCK_BEGIN_NEW_SCOPE 2
-#define OP_DECLARE 3
-#define OP_ASM 4
-#define OP_BREAK 5
-#define OP_CONTINUE 6
-#define OP_DISCARD 7
-#define OP_RETURN 8
-#define OP_EXPRESSION 9
-#define OP_IF 10
-#define OP_WHILE 11
-#define OP_DO 12
-#define OP_FOR 13
-#define OP_PUSH_VOID 14
-#define OP_PUSH_BOOL 15
-#define OP_PUSH_INT 16
-#define OP_PUSH_FLOAT 17
-#define OP_PUSH_IDENTIFIER 18
-#define OP_SEQUENCE 19
-#define OP_ASSIGN 20
-#define OP_ADDASSIGN 21
-#define OP_SUBASSIGN 22
-#define OP_MULASSIGN 23
-#define OP_DIVASSIGN 24
-/*#define OP_MODASSIGN 25*/
-/*#define OP_LSHASSIGN 26*/
-/*#define OP_RSHASSIGN 27*/
-/*#define OP_ORASSIGN 28*/
-/*#define OP_XORASSIGN 29*/
-/*#define OP_ANDASSIGN 30*/
-#define OP_SELECT 31
-#define OP_LOGICALOR 32
-#define OP_LOGICALXOR 33
-#define OP_LOGICALAND 34
-/*#define OP_BITOR 35*/
-/*#define OP_BITXOR 36*/
-/*#define OP_BITAND 37*/
-#define OP_EQUAL 38
-#define OP_NOTEQUAL 39
-#define OP_LESS 40
-#define OP_GREATER 41
-#define OP_LESSEQUAL 42
-#define OP_GREATEREQUAL 43
-/*#define OP_LSHIFT 44*/
-/*#define OP_RSHIFT 45*/
-#define OP_ADD 46
-#define OP_SUBTRACT 47
-#define OP_MULTIPLY 48
-#define OP_DIVIDE 49
-/*#define OP_MODULUS 50*/
-#define OP_PREINCREMENT 51
-#define OP_PREDECREMENT 52
-#define OP_PLUS 53
-#define OP_MINUS 54
-/*#define OP_COMPLEMENT 55*/
-#define OP_NOT 56
-#define OP_SUBSCRIPT 57
-#define OP_CALL 58
-#define OP_FIELD 59
-#define OP_POSTINCREMENT 60
-#define OP_POSTDECREMENT 61
-#define OP_PRECISION 62
-#define OP_METHOD 63
-
-
-/**
- * When parsing a compound production, this function is used to parse the
- * children.
- * For example, a while-loop compound will have two children, the
- * while condition expression and the loop body.  So, this function will
- * be called twice to parse those two sub-expressions.
- * \param C  the parsing context
- * \param O  the output context
- * \param oper  the operation we're parsing
- * \param statement  indicates whether parsing a statement, or expression
- * \return 1 if success, 0 if error
- */
-static int
-parse_child_operation(slang_parse_ctx * C, slang_output_ctx * O,
-                      slang_operation * oper, GLboolean statement)
-{
-   slang_operation *ch;
-
-   /* grow child array */
-   ch = slang_operation_grow(&oper->num_children, &oper->children);
-   if (statement)
-      return parse_statement(C, O, ch);
-   return parse_expression(C, O, ch);
-}
-
-static int parse_declaration(slang_parse_ctx * C, slang_output_ctx * O);
-
-static int
-parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
-                slang_operation * oper)
-{
-   int op;
-
-   oper->locals->outer_scope = O->vars;
-
-   op = *C->I++;
-   switch (op) {
-   case OP_BLOCK_BEGIN_NO_NEW_SCOPE:
-      /* parse child statements, do not create new variable scope */
-      oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
-      while (*C->I != OP_END)
-         if (!parse_child_operation(C, O, oper, GL_TRUE))
-            RETURN0;
-      C->I++;
-      break;
-   case OP_BLOCK_BEGIN_NEW_SCOPE:
-      /* parse child statements, create new variable scope */
-      {
-         slang_output_ctx o = *O;
-
-         oper->type = SLANG_OPER_BLOCK_NEW_SCOPE;
-         o.vars = oper->locals;
-         while (*C->I != OP_END)
-            if (!parse_child_operation(C, &o, oper, GL_TRUE))
-               RETURN0;
-         C->I++;
-      }
-      break;
-   case OP_DECLARE:
-      /* local variable declaration, individual declarators are stored as
-       * children identifiers
-       */
-      oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
-      {
-         const unsigned int first_var = O->vars->num_variables;
-
-         /* parse the declaration, note that there can be zero or more
-          * than one declarators
-          */
-         if (!parse_declaration(C, O))
-            RETURN0;
-         if (first_var < O->vars->num_variables) {
-            const unsigned int num_vars = O->vars->num_variables - first_var;
-            unsigned int i;
-            assert(oper->num_children == 0);
-            oper->num_children = num_vars;
-            oper->children = slang_operation_new(num_vars);
-            if (oper->children == NULL) {
-               slang_info_log_memory(C->L);
-               RETURN0;
-            }
-            for (i = first_var; i < O->vars->num_variables; i++) {
-               slang_operation *o = &oper->children[i - first_var];
-               slang_variable *var = O->vars->variables[i];
-               o->type = SLANG_OPER_VARIABLE_DECL;
-               o->locals->outer_scope = O->vars;
-               o->a_id = var->a_name;
-
-               /* new/someday...
-               calculate_var_size(C, O, var);
-               */
-
-               if (!legal_identifier(o->a_id)) {
-                  slang_info_log_error(C->L, "illegal variable name '%s'",
-                                       (char *) o->a_id);
-                  RETURN0;
-               }
-            }
-         }
-      }
-      break;
-   case OP_ASM:
-      /* the __asm statement, parse the mnemonic and all its arguments
-       * as expressions
-       */
-      oper->type = SLANG_OPER_ASM;
-      oper->a_id = parse_identifier(C);
-      if (oper->a_id == SLANG_ATOM_NULL)
-         RETURN0;
-      while (*C->I != OP_END) {
-         if (!parse_child_operation(C, O, oper, GL_FALSE))
-            RETURN0;
-      }
-      C->I++;
-      break;
-   case OP_BREAK:
-      oper->type = SLANG_OPER_BREAK;
-      break;
-   case OP_CONTINUE:
-      oper->type = SLANG_OPER_CONTINUE;
-      break;
-   case OP_DISCARD:
-      oper->type = SLANG_OPER_DISCARD;
-      break;
-   case OP_RETURN:
-      oper->type = SLANG_OPER_RETURN;
-      if (!parse_child_operation(C, O, oper, GL_FALSE))
-         RETURN0;
-      break;
-   case OP_EXPRESSION:
-      oper->type = SLANG_OPER_EXPRESSION;
-      if (!parse_child_operation(C, O, oper, GL_FALSE))
-         RETURN0;
-      break;
-   case OP_IF:
-      oper->type = SLANG_OPER_IF;
-      if (!parse_child_operation(C, O, oper, GL_FALSE))
-         RETURN0;
-      if (!parse_child_operation(C, O, oper, GL_TRUE))
-         RETURN0;
-      if (!parse_child_operation(C, O, oper, GL_TRUE))
-         RETURN0;
-      break;
-   case OP_WHILE:
-      {
-         slang_output_ctx o = *O;
-
-         oper->type = SLANG_OPER_WHILE;
-         o.vars = oper->locals;
-         if (!parse_child_operation(C, &o, oper, GL_TRUE))
-            RETURN0;
-         if (!parse_child_operation(C, &o, oper, GL_TRUE))
-            RETURN0;
-      }
-      break;
-   case OP_DO:
-      oper->type = SLANG_OPER_DO;
-      if (!parse_child_operation(C, O, oper, GL_TRUE))
-         RETURN0;
-      if (!parse_child_operation(C, O, oper, GL_FALSE))
-         RETURN0;
-      break;
-   case OP_FOR:
-      {
-         slang_output_ctx o = *O;
-
-         oper->type = SLANG_OPER_FOR;
-         o.vars = oper->locals;
-         if (!parse_child_operation(C, &o, oper, GL_TRUE))
-            RETURN0;
-         if (!parse_child_operation(C, &o, oper, GL_TRUE))
-            RETURN0;
-         if (!parse_child_operation(C, &o, oper, GL_FALSE))
-            RETURN0;
-         if (!parse_child_operation(C, &o, oper, GL_TRUE))
-            RETURN0;
-      }
-      break;
-   case OP_PRECISION:
-      {
-         /* set default precision for a type in this scope */
-         /* ignored at this time */
-         int prec_qual = *C->I++;
-         int datatype = *C->I++;
-         (void) prec_qual;
-         (void) datatype;
-      }
-      break;
-   default:
-      /*printf("Unexpected operation %d\n", op);*/
-      RETURN0;
-   }
-   return 1;
-}
-
-static int
-handle_nary_expression(slang_parse_ctx * C, slang_operation * op,
-                       slang_operation ** ops, unsigned int *total_ops,
-                       unsigned int n)
-{
-   unsigned int i;
-
-   op->children = slang_operation_new(n);
-   if (op->children == NULL) {
-      slang_info_log_memory(C->L);
-      RETURN0;
-   }
-   op->num_children = n;
-
-   for (i = 0; i < n; i++) {
-      slang_operation_destruct(&op->children[i]);
-      op->children[i] = (*ops)[*total_ops - (n + 1 - i)];
-   }
-
-   (*ops)[*total_ops - (n + 1)] = (*ops)[*total_ops - 1];
-   *total_ops -= n;
-
-   *ops = (slang_operation *)
-      _slang_realloc(*ops,
-                     (*total_ops + n) * sizeof(slang_operation),
-                     *total_ops * sizeof(slang_operation));
-   if (*ops == NULL) {
-      slang_info_log_memory(C->L);
-      RETURN0;
-   }
-   return 1;
-}
-
-static int
-is_constructor_name(const char *name, slang_atom a_name,
-                    slang_struct_scope * structs)
-{
-   if (slang_type_specifier_type_from_string(name) != SLANG_SPEC_VOID)
-      return 1;
-   return slang_struct_scope_find(structs, a_name, 1) != NULL;
-}
-
-#define FUNCTION_CALL_NONARRAY 0
-#define FUNCTION_CALL_ARRAY    1
-
-static int
-parse_expression(slang_parse_ctx * C, slang_output_ctx * O,
-                 slang_operation * oper)
-{
-   slang_operation *ops = NULL;
-   unsigned int num_ops = 0;
-   int number;
-
-   while (*C->I != OP_END) {
-      slang_operation *op;
-      const unsigned int op_code = *C->I++;
-
-      /* allocate default operation, becomes a no-op if not used  */
-      ops = (slang_operation *)
-         _slang_realloc(ops,
-                        num_ops * sizeof(slang_operation),
-                        (num_ops + 1) * sizeof(slang_operation));
-      if (ops == NULL) {
-         slang_info_log_memory(C->L);
-         RETURN0;
-      }
-      op = &ops[num_ops];
-      if (!slang_operation_construct(op)) {
-         slang_info_log_memory(C->L);
-         RETURN0;
-      }
-      num_ops++;
-      op->locals->outer_scope = O->vars;
-
-      switch (op_code) {
-      case OP_PUSH_VOID:
-         op->type = SLANG_OPER_VOID;
-         break;
-      case OP_PUSH_BOOL:
-         op->type = SLANG_OPER_LITERAL_BOOL;
-         if (!parse_number(C, &number))
-            RETURN0;
-         op->literal[0] =
-         op->literal[1] =
-         op->literal[2] =
-         op->literal[3] = (GLfloat) number;
-         op->literal_size = 1;
-         break;
-      case OP_PUSH_INT:
-         op->type = SLANG_OPER_LITERAL_INT;
-         if (!parse_number(C, &number))
-            RETURN0;
-         op->literal[0] =
-         op->literal[1] =
-         op->literal[2] =
-         op->literal[3] = (GLfloat) number;
-         op->literal_size = 1;
-         break;
-      case OP_PUSH_FLOAT:
-         op->type = SLANG_OPER_LITERAL_FLOAT;
-         if (!parse_float(C, &op->literal[0]))
-            RETURN0;
-         op->literal[1] =
-         op->literal[2] =
-         op->literal[3] = op->literal[0];
-         op->literal_size = 1;
-         break;
-      case OP_PUSH_IDENTIFIER:
-         op->type = SLANG_OPER_IDENTIFIER;
-         op->a_id = parse_identifier(C);
-         if (op->a_id == SLANG_ATOM_NULL)
-            RETURN0;
-         break;
-      case OP_SEQUENCE:
-         op->type = SLANG_OPER_SEQUENCE;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
-            RETURN0;
-         break;
-      case OP_ASSIGN:
-         op->type = SLANG_OPER_ASSIGN;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
-            RETURN0;
-         break;
-      case OP_ADDASSIGN:
-         op->type = SLANG_OPER_ADDASSIGN;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
-            RETURN0;
-         break;
-      case OP_SUBASSIGN:
-         op->type = SLANG_OPER_SUBASSIGN;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
-            RETURN0;
-         break;
-      case OP_MULASSIGN:
-         op->type = SLANG_OPER_MULASSIGN;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
-            RETURN0;
-         break;
-      case OP_DIVASSIGN:
-         op->type = SLANG_OPER_DIVASSIGN;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
-            RETURN0;
-         break;
-         /*case OP_MODASSIGN: */
-         /*case OP_LSHASSIGN: */
-         /*case OP_RSHASSIGN: */
-         /*case OP_ORASSIGN: */
-         /*case OP_XORASSIGN: */
-         /*case OP_ANDASSIGN: */
-      case OP_SELECT:
-         op->type = SLANG_OPER_SELECT;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 3))
-            RETURN0;
-         break;
-      case OP_LOGICALOR:
-         op->type = SLANG_OPER_LOGICALOR;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
-            RETURN0;
-         break;
-      case OP_LOGICALXOR:
-         op->type = SLANG_OPER_LOGICALXOR;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
-            RETURN0;
-         break;
-      case OP_LOGICALAND:
-         op->type = SLANG_OPER_LOGICALAND;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
-            RETURN0;
-         break;
-         /*case OP_BITOR: */
-         /*case OP_BITXOR: */
-         /*case OP_BITAND: */
-      case OP_EQUAL:
-         op->type = SLANG_OPER_EQUAL;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
-            RETURN0;
-         break;
-      case OP_NOTEQUAL:
-         op->type = SLANG_OPER_NOTEQUAL;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
-            RETURN0;
-         break;
-      case OP_LESS:
-         op->type = SLANG_OPER_LESS;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
-            RETURN0;
-         break;
-      case OP_GREATER:
-         op->type = SLANG_OPER_GREATER;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
-            RETURN0;
-         break;
-      case OP_LESSEQUAL:
-         op->type = SLANG_OPER_LESSEQUAL;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
-            RETURN0;
-         break;
-      case OP_GREATEREQUAL:
-         op->type = SLANG_OPER_GREATEREQUAL;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
-            RETURN0;
-         break;
-         /*case OP_LSHIFT: */
-         /*case OP_RSHIFT: */
-      case OP_ADD:
-         op->type = SLANG_OPER_ADD;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
-            RETURN0;
-         break;
-      case OP_SUBTRACT:
-         op->type = SLANG_OPER_SUBTRACT;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
-            RETURN0;
-         break;
-      case OP_MULTIPLY:
-         op->type = SLANG_OPER_MULTIPLY;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
-            RETURN0;
-         break;
-      case OP_DIVIDE:
-         op->type = SLANG_OPER_DIVIDE;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
-            RETURN0;
-         break;
-         /*case OP_MODULUS: */
-      case OP_PREINCREMENT:
-         op->type = SLANG_OPER_PREINCREMENT;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
-            RETURN0;
-         break;
-      case OP_PREDECREMENT:
-         op->type = SLANG_OPER_PREDECREMENT;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
-            RETURN0;
-         break;
-      case OP_PLUS:
-         op->type = SLANG_OPER_PLUS;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
-            RETURN0;
-         break;
-      case OP_MINUS:
-         op->type = SLANG_OPER_MINUS;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
-            RETURN0;
-         break;
-      case OP_NOT:
-         op->type = SLANG_OPER_NOT;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
-            RETURN0;
-         break;
-         /*case OP_COMPLEMENT: */
-      case OP_SUBSCRIPT:
-         op->type = SLANG_OPER_SUBSCRIPT;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
-            RETURN0;
-         break;
-      case OP_METHOD:
-         op->type = SLANG_OPER_METHOD;
-         op->a_obj = parse_identifier(C);
-         if (op->a_obj == SLANG_ATOM_NULL)
-            RETURN0;
-
-         op->a_id = parse_identifier(C);
-         if (op->a_id == SLANG_ATOM_NULL)
-            RETURN0;
-
-         assert(*C->I == OP_END);
-         C->I++;
-
-         while (*C->I != OP_END)
-            if (!parse_child_operation(C, O, op, GL_FALSE))
-               RETURN0;
-         C->I++;
-#if 0
-         /* don't lookup the method (not yet anyway) */
-         if (!C->parsing_builtin
-             && !slang_function_scope_find_by_name(O->funs, op->a_id, 1)) {
-            const char *id;
-
-            id = slang_atom_pool_id(C->atoms, op->a_id);
-            if (!is_constructor_name(id, op->a_id, O->structs)) {
-               slang_info_log_error(C->L, "%s: undeclared function name.", id);
-               RETURN0;
-            }
-         }
-#endif
-         break;
-      case OP_CALL:
-         {
-            GLboolean array_constructor = GL_FALSE;
-            GLint array_constructor_size = 0;
-
-            op->type = SLANG_OPER_CALL;
-            op->a_id = parse_identifier(C);
-            if (op->a_id == SLANG_ATOM_NULL)
-               RETURN0;
-            switch (*C->I++) {
-            case FUNCTION_CALL_NONARRAY:
-               /* Nothing to do. */
-               break;
-            case FUNCTION_CALL_ARRAY:
-               /* Calling an array constructor. For example:
-                *   float[3](1.1, 2.2, 3.3);
-                */
-               if (!O->allow_array_types) {
-                  slang_info_log_error(C->L,
-                                       "array constructors not allowed "
-                                       "in this GLSL version");
-                  RETURN0;
-               }
-               else {
-                  /* parse the array constructor size */
-                  slang_operation array_size;
-                  array_constructor = GL_TRUE;
-                  slang_operation_construct(&array_size);
-                  if (!parse_expression(C, O, &array_size)) {
-                     slang_operation_destruct(&array_size);
-                     return GL_FALSE;
-                  }
-                  if (array_size.type != SLANG_OPER_LITERAL_INT) {
-                     slang_info_log_error(C->L,
-                        "constructor array size is not an integer");
-                     slang_operation_destruct(&array_size);
-                     RETURN0;
-                  }
-                  array_constructor_size = (int) array_size.literal[0];
-                  op->array_constructor = GL_TRUE;
-                  slang_operation_destruct(&array_size);
-               }
-               break;
-            default:
-               assert(0);
-               RETURN0;
-            }
-            while (*C->I != OP_END)
-               if (!parse_child_operation(C, O, op, GL_FALSE))
-                  RETURN0;
-            C->I++;
-
-            if (array_constructor &&
-                array_constructor_size != op->num_children) {
-               slang_info_log_error(C->L, "number of parameters to array"
-                                    " constructor does not match array size");
-               RETURN0;
-            }
-
-            if (!C->parsing_builtin
-                && !slang_function_scope_find_by_name(O->funs, op->a_id, 1)) {
-               const char *id;
-
-               id = slang_atom_pool_id(C->atoms, op->a_id);
-               if (!is_constructor_name(id, op->a_id, O->structs)) {
-                  slang_info_log_error(C->L, "%s: undeclared function name.", id);
-                  RETURN0;
-               }
-            }
-         }
-         break;
-      case OP_FIELD:
-         op->type = SLANG_OPER_FIELD;
-         op->a_id = parse_identifier(C);
-         if (op->a_id == SLANG_ATOM_NULL)
-            RETURN0;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
-            RETURN0;
-         break;
-      case OP_POSTINCREMENT:
-         op->type = SLANG_OPER_POSTINCREMENT;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
-            RETURN0;
-         break;
-      case OP_POSTDECREMENT:
-         op->type = SLANG_OPER_POSTDECREMENT;
-         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
-            RETURN0;
-         break;
-      default:
-         RETURN0;
-      }
-   }
-   C->I++;
-
-   slang_operation_destruct(oper);
-   *oper = *ops; /* struct copy */
-   _slang_free(ops);
-
-   return 1;
-}
-
-/* parameter qualifier */
-#define PARAM_QUALIFIER_IN 0
-#define PARAM_QUALIFIER_OUT 1
-#define PARAM_QUALIFIER_INOUT 2
-
-/* function parameter array presence */
-#define PARAMETER_ARRAY_NOT_PRESENT 0
-#define PARAMETER_ARRAY_PRESENT 1
-
-static int
-parse_parameter_declaration(slang_parse_ctx * C, slang_output_ctx * O,
-                            slang_variable * param)
-{
-   int param_qual, precision_qual;
-
-   /* parse and validate the parameter's type qualifiers (there can be
-    * two at most) because not all combinations are valid
-    */
-   if (!parse_type_qualifier(C, &param->type.qualifier))
-      RETURN0;
-
-   param_qual = *C->I++;
-   switch (param_qual) {
-   case PARAM_QUALIFIER_IN:
-      if (param->type.qualifier != SLANG_QUAL_CONST
-          && param->type.qualifier != SLANG_QUAL_NONE) {
-         slang_info_log_error(C->L, "Invalid type qualifier.");
-         RETURN0;
-      }
-      break;
-   case PARAM_QUALIFIER_OUT:
-      if (param->type.qualifier == SLANG_QUAL_NONE)
-         param->type.qualifier = SLANG_QUAL_OUT;
-      else {
-         slang_info_log_error(C->L, "Invalid type qualifier.");
-         RETURN0;
-      }
-      break;
-   case PARAM_QUALIFIER_INOUT:
-      if (param->type.qualifier == SLANG_QUAL_NONE)
-         param->type.qualifier = SLANG_QUAL_INOUT;
-      else {
-         slang_info_log_error(C->L, "Invalid type qualifier.");
-         RETURN0;
-      }
-      break;
-   default:
-      RETURN0;
-   }
-
-   /* parse precision qualifier (lowp, mediump, highp */
-   precision_qual = *C->I++;
-   /* ignored at this time */
-   (void) precision_qual;
-
-   /* parse parameter's type specifier and name */
-   if (!parse_type_specifier(C, O, &param->type.specifier))
-      RETURN0;
-   if (!parse_type_array_size(C, O, &param->type.array_len))
-      RETURN0;
-   param->a_name = parse_identifier(C);
-   if (param->a_name == SLANG_ATOM_NULL)
-      RETURN0;
-
-   /* first-class array
-    */
-   if (param->type.array_len >= 0) {
-      slang_type_specifier p;
-
-      slang_type_specifier_ctr(&p);
-      if (!slang_type_specifier_copy(&p, &param->type.specifier)) {
-         slang_type_specifier_dtr(&p);
-         RETURN0;
-      }
-      if (!convert_to_array(C, param, &p)) {
-         slang_type_specifier_dtr(&p);
-         RETURN0;
-      }
-      slang_type_specifier_dtr(&p);
-      param->array_len = param->type.array_len;
-   }
-
-   /* if the parameter is an array, parse its size (the size must be
-    * explicitly defined
-    */
-   if (*C->I++ == PARAMETER_ARRAY_PRESENT) {
-      slang_type_specifier p;
-
-      if (param->type.array_len >= 0) {
-         slang_info_log_error(C->L, "multi-dimensional arrays not allowed");
-         RETURN0;
-      }
-      slang_type_specifier_ctr(&p);
-      if (!slang_type_specifier_copy(&p, &param->type.specifier)) {
-         slang_type_specifier_dtr(&p);
-         RETURN0;
-      }
-      if (!convert_to_array(C, param, &p)) {
-         slang_type_specifier_dtr(&p);
-         RETURN0;
-      }
-      slang_type_specifier_dtr(&p);
-      if (!parse_array_len(C, O, &param->array_len))
-         RETURN0;
-   }
-
-#if 0
-   /* calculate the parameter size */
-   if (!calculate_var_size(C, O, param))
-      RETURN0;
-#endif
-   /* TODO: allocate the local address here? */
-   return 1;
-}
-
-/* function type */
-#define FUNCTION_ORDINARY 0
-#define FUNCTION_CONSTRUCTOR 1
-#define FUNCTION_OPERATOR 2
-
-/* function parameter */
-#define PARAMETER_NONE 0
-#define PARAMETER_NEXT 1
-
-/* operator type */
-#define OPERATOR_ADDASSIGN 1
-#define OPERATOR_SUBASSIGN 2
-#define OPERATOR_MULASSIGN 3
-#define OPERATOR_DIVASSIGN 4
-/*#define OPERATOR_MODASSIGN 5*/
-/*#define OPERATOR_LSHASSIGN 6*/
-/*#define OPERATOR_RSHASSIGN 7*/
-/*#define OPERATOR_ANDASSIGN 8*/
-/*#define OPERATOR_XORASSIGN 9*/
-/*#define OPERATOR_ORASSIGN 10*/
-#define OPERATOR_LOGICALXOR 11
-/*#define OPERATOR_BITOR 12*/
-/*#define OPERATOR_BITXOR 13*/
-/*#define OPERATOR_BITAND 14*/
-#define OPERATOR_LESS 15
-#define OPERATOR_GREATER 16
-#define OPERATOR_LESSEQUAL 17
-#define OPERATOR_GREATEREQUAL 18
-/*#define OPERATOR_LSHIFT 19*/
-/*#define OPERATOR_RSHIFT 20*/
-#define OPERATOR_MULTIPLY 21
-#define OPERATOR_DIVIDE 22
-/*#define OPERATOR_MODULUS 23*/
-#define OPERATOR_INCREMENT 24
-#define OPERATOR_DECREMENT 25
-#define OPERATOR_PLUS 26
-#define OPERATOR_MINUS 27
-/*#define OPERATOR_COMPLEMENT 28*/
-#define OPERATOR_NOT 29
-
-static const struct
-{
-   unsigned int o_code;
-   const char *o_name;
-} operator_names[] = {
-   {OPERATOR_INCREMENT, "++"},
-   {OPERATOR_ADDASSIGN, "+="},
-   {OPERATOR_PLUS, "+"},
-   {OPERATOR_DECREMENT, "--"},
-   {OPERATOR_SUBASSIGN, "-="},
-   {OPERATOR_MINUS, "-"},
-   {OPERATOR_NOT, "!"},
-   {OPERATOR_MULASSIGN, "*="},
-   {OPERATOR_MULTIPLY, "*"},
-   {OPERATOR_DIVASSIGN, "/="},
-   {OPERATOR_DIVIDE, "/"},
-   {OPERATOR_LESSEQUAL, "<="},
-   /*{ OPERATOR_LSHASSIGN, "<<=" }, */
-   /*{ OPERATOR_LSHIFT, "<<" }, */
-   {OPERATOR_LESS, "<"},
-   {OPERATOR_GREATEREQUAL, ">="},
-   /*{ OPERATOR_RSHASSIGN, ">>=" }, */
-   /*{ OPERATOR_RSHIFT, ">>" }, */
-   {OPERATOR_GREATER, ">"},
-   /*{ OPERATOR_MODASSIGN, "%=" }, */
-   /*{ OPERATOR_MODULUS, "%" }, */
-   /*{ OPERATOR_ANDASSIGN, "&=" }, */
-   /*{ OPERATOR_BITAND, "&" }, */
-   /*{ OPERATOR_ORASSIGN, "|=" }, */
-   /*{ OPERATOR_BITOR, "|" }, */
-   /*{ OPERATOR_COMPLEMENT, "~" }, */
-   /*{ OPERATOR_XORASSIGN, "^=" }, */
-   {OPERATOR_LOGICALXOR, "^^"},
-   /*{ OPERATOR_BITXOR, "^" } */
-};
-
-static slang_atom
-parse_operator_name(slang_parse_ctx * C)
-{
-   unsigned int i;
-
-   for (i = 0; i < sizeof(operator_names) / sizeof(*operator_names); i++) {
-      if (operator_names[i].o_code == (unsigned int) (*C->I)) {
-         slang_atom atom =
-            slang_atom_pool_atom(C->atoms, operator_names[i].o_name);
-         if (atom == SLANG_ATOM_NULL) {
-            slang_info_log_memory(C->L);
-            RETURN0;
-         }
-         C->I++;
-         return atom;
-      }
-   }
-   RETURN0;
-}
-
-
-static int
-parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O,
-                         slang_function * func)
-{
-   GLuint functype;
-   /* parse function type and name */
-   if (!parse_fully_specified_type(C, O, &func->header.type))
-      RETURN0;
-
-   functype = *C->I++;
-   switch (functype) {
-   case FUNCTION_ORDINARY:
-      func->kind = SLANG_FUNC_ORDINARY;
-      func->header.a_name = parse_identifier(C);
-      if (func->header.a_name == SLANG_ATOM_NULL)
-         RETURN0;
-      break;
-   case FUNCTION_CONSTRUCTOR:
-      func->kind = SLANG_FUNC_CONSTRUCTOR;
-      if (func->header.type.specifier.type == SLANG_SPEC_STRUCT)
-         RETURN0;
-      func->header.a_name =
-         slang_atom_pool_atom(C->atoms,
-                              slang_type_specifier_type_to_string
-                              (func->header.type.specifier.type));
-      if (func->header.a_name == SLANG_ATOM_NULL) {
-         slang_info_log_memory(C->L);
-         RETURN0;
-      }
-      break;
-   case FUNCTION_OPERATOR:
-      func->kind = SLANG_FUNC_OPERATOR;
-      func->header.a_name = parse_operator_name(C);
-      if (func->header.a_name == SLANG_ATOM_NULL)
-         RETURN0;
-      break;
-   default:
-      RETURN0;
-   }
-
-   if (!legal_identifier(func->header.a_name)) {
-      slang_info_log_error(C->L, "illegal function name '%s'",
-                           (char *) func->header.a_name);
-      RETURN0;
-   }
-
-   /* parse function parameters */
-   while (*C->I++ == PARAMETER_NEXT) {
-      slang_variable *p = slang_variable_scope_grow(func->parameters);
-      if (!p) {
-         slang_info_log_memory(C->L);
-         RETURN0;
-      }
-      if (!parse_parameter_declaration(C, O, p))
-         RETURN0;
-   }
-
-   /* if the function returns a value, append a hidden __retVal 'out'
-    * parameter that corresponds to the return value.
-    */
-   if (_slang_function_has_return_value(func)) {
-      slang_variable *p = slang_variable_scope_grow(func->parameters);
-      slang_atom a_retVal = slang_atom_pool_atom(C->atoms, "__retVal");
-      assert(a_retVal);
-      p->a_name = a_retVal;
-      p->type = func->header.type;
-      p->type.qualifier = SLANG_QUAL_OUT;
-   }
-
-   /* function formal parameters and local variables share the same
-    * scope, so save the information about param count in a seperate
-    * place also link the scope to the global variable scope so when a
-    * given identifier is not found here, the search process continues
-    * in the global space
-    */
-   func->param_count = func->parameters->num_variables;
-   func->parameters->outer_scope = O->vars;
-
-   return 1;
-}
-
-static int
-parse_function_definition(slang_parse_ctx * C, slang_output_ctx * O,
-                          slang_function * func)
-{
-   slang_output_ctx o = *O;
-
-   if (!parse_function_prototype(C, O, func))
-      RETURN0;
-
-   /* create function's body operation */
-   func->body = (slang_operation *) _slang_alloc(sizeof(slang_operation));
-   if (func->body == NULL) {
-      slang_info_log_memory(C->L);
-      RETURN0;
-   }
-   if (!slang_operation_construct(func->body)) {
-      _slang_free(func->body);
-      func->body = NULL;
-      slang_info_log_memory(C->L);
-      RETURN0;
-   }
-
-   /* to parse the body the parse context is modified in order to
-    * capture parsed variables into function's local variable scope
-    */
-   C->global_scope = GL_FALSE;
-   o.vars = func->parameters;
-   if (!parse_statement(C, &o, func->body))
-      RETURN0;
-
-   C->global_scope = GL_TRUE;
-   return 1;
-}
-
-static GLboolean
-initialize_global(slang_assemble_ctx * A, slang_variable * var)
-{
-   slang_operation op_id, op_assign;
-   GLboolean result;
-
-   /* construct the left side of assignment */
-   if (!slang_operation_construct(&op_id))
-      return GL_FALSE;
-   op_id.type = SLANG_OPER_IDENTIFIER;
-   op_id.a_id = var->a_name;
-
-   /* put the variable into operation's scope */
-   op_id.locals->variables =
-      (slang_variable **) _slang_alloc(sizeof(slang_variable *));
-   if (op_id.locals->variables == NULL) {
-      slang_operation_destruct(&op_id);
-      return GL_FALSE;
-   }
-   op_id.locals->num_variables = 1;
-   op_id.locals->variables[0] = var;
-
-   /* construct the assignment expression */
-   if (!slang_operation_construct(&op_assign)) {
-      op_id.locals->num_variables = 0;
-      slang_operation_destruct(&op_id);
-      return GL_FALSE;
-   }
-   op_assign.type = SLANG_OPER_ASSIGN;
-   op_assign.children =
-      (slang_operation *) _slang_alloc(2 * sizeof(slang_operation));
-   if (op_assign.children == NULL) {
-      slang_operation_destruct(&op_assign);
-      op_id.locals->num_variables = 0;
-      slang_operation_destruct(&op_id);
-      return GL_FALSE;
-   }
-   op_assign.num_children = 2;
-   op_assign.children[0] = op_id;
-   op_assign.children[1] = *var->initializer;
-
-   result = 1;
-
-   /* carefully destroy the operations */
-   op_assign.num_children = 0;
-   _slang_free(op_assign.children);
-   op_assign.children = NULL;
-   slang_operation_destruct(&op_assign);
-   op_id.locals->num_variables = 0;
-   slang_operation_destruct(&op_id);
-
-   if (!result)
-      return GL_FALSE;
-
-   return GL_TRUE;
-}
-
-/* init declarator list */
-#define DECLARATOR_NONE 0
-#define DECLARATOR_NEXT 1
-
-/* variable declaration */
-#define VARIABLE_NONE 0
-#define VARIABLE_IDENTIFIER 1
-#define VARIABLE_INITIALIZER 2
-#define VARIABLE_ARRAY_EXPLICIT 3
-#define VARIABLE_ARRAY_UNKNOWN 4
-
-
-/**
- * Check if it's OK to re-declare a variable with the given new type.
- * This happens when applying layout qualifiers to gl_FragCoord or
- * (re)setting an array size.
- * If redeclaration is OK, return a pointer to the incoming variable
- * updated with new type info.  Else return NULL;
- */
-static slang_variable *
-redeclare_variable(slang_variable *var, 
-                   const slang_fully_specified_type *type)
-{
-   if (slang_fully_specified_types_compatible(&var->type, type)) {
-      /* replace orig var layout with new layout */
-      var->type.layout = type->layout;
-
-      /* XXX there may be other type updates in the future here */
-
-      return var;
-   }
-   else
-      return NULL;
-}
-
-
-/**
- * Parse the initializer for a variable declaration.
- */
-static int
-parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,
-                      const slang_fully_specified_type * type)
-{
-   GET_CURRENT_CONTEXT(ctx); /* a hack */
-   slang_variable *var = NULL, *prevDecl;
-   slang_atom a_name;
-
-   /* empty init declatator (without name, e.g. "float ;") */
-   if (*C->I++ == VARIABLE_NONE)
-      return 1;
-
-   a_name = parse_identifier(C);
-
-   /* check if name is already in this scope */
-   prevDecl = _slang_variable_locate(O->vars, a_name, C->global_scope);
-   if (prevDecl) {
-      /* A var with this name has already been declared.
-       * Check if redeclaring the var with a different type/layout is legal.
-       */
-      if (C->global_scope) {
-         var = redeclare_variable(prevDecl, type);
-      }
-      if (!var) {
-         slang_info_log_error(C->L,
-                   "declaration of '%s' conflicts with previous declaration",
-                   (char *) a_name);
-         RETURN0;
-      }
-   }
-
-   if (!var) {
-      /* make room for a new variable and initialize it */
-      var = slang_variable_scope_grow(O->vars);
-      if (!var) {
-         slang_info_log_memory(C->L);
-         RETURN0;
-      }
-
-      /* copy the declarator type qualifier/etc info, parse the identifier */
-      var->type.qualifier = type->qualifier;
-      var->type.centroid = type->centroid;
-      var->type.precision = type->precision;
-      var->type.specifier = type->specifier;/*new*/
-      var->type.variant = type->variant;
-      var->type.layout = type->layout;
-      var->type.array_len = type->array_len;
-      var->a_name = a_name;
-      if (var->a_name == SLANG_ATOM_NULL)
-         RETURN0;
-   }
-
-   switch (*C->I++) {
-   case VARIABLE_NONE:
-      /* simple variable declarator - just copy the specifier */
-      if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier))
-         RETURN0;
-      break;
-   case VARIABLE_INITIALIZER:
-      /* initialized variable - copy the specifier and parse the expression */
-      if (0 && type->array_len >= 0) {
-         /* The type was something like "float[4]" */
-         convert_to_array(C, var, &type->specifier);
-         var->array_len = type->array_len;
-      }
-      else {
-         if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier))
-            RETURN0;
-      }
-      var->initializer =
-         (slang_operation *) _slang_alloc(sizeof(slang_operation));
-      if (var->initializer == NULL) {
-         slang_info_log_memory(C->L);
-         RETURN0;
-      }
-      if (!slang_operation_construct(var->initializer)) {
-         _slang_free(var->initializer);
-         var->initializer = NULL;
-         slang_info_log_memory(C->L);
-         RETURN0;
-      }
-      if (!parse_expression(C, O, var->initializer))
-         RETURN0;
-      break;
-   case VARIABLE_ARRAY_UNKNOWN:
-      /* unsized array - mark it as array and copy the specifier to
-       * the array element
-       */
-      if (type->array_len >= 0) {
-         slang_info_log_error(C->L, "multi-dimensional arrays not allowed");
-         RETURN0;
-      }
-      if (!convert_to_array(C, var, &type->specifier))
-         return GL_FALSE;
-      break;
-   case VARIABLE_ARRAY_EXPLICIT:
-      if (type->array_len >= 0) {
-         /* the user is trying to do something like: float[2] x[3]; */
-         slang_info_log_error(C->L, "multi-dimensional arrays not allowed");
-         RETURN0;
-      }
-      if (!convert_to_array(C, var, &type->specifier))
-         return GL_FALSE;
-      if (!parse_array_len(C, O, &var->array_len))
-         return GL_FALSE;
-      break;
-   default:
-      RETURN0;
-   }
-
-   /* allocate global address space for a variable with a known size */
-   if (C->global_scope
-       && !(var->type.specifier.type == SLANG_SPEC_ARRAY
-            && var->array_len == 0)) {
-      if (!calculate_var_size(C, O, var))
-         return GL_FALSE;
-   }
-
-   /* emit code for global var decl */
-   if (C->global_scope) {
-      slang_assemble_ctx A;
-      memset(&A, 0, sizeof(slang_assemble_ctx));
-      A.allow_uniform_initializers = C->version > 110;
-      A.atoms = C->atoms;
-      A.space.funcs = O->funs;
-      A.space.structs = O->structs;
-      A.space.vars = O->vars;
-      A.program = O->program;
-      A.pragmas = O->pragmas;
-      A.vartable = O->vartable;
-      A.log = C->L;
-      A.curFuncEndLabel = NULL;
-      A.EmitContReturn = ctx->Shader.EmitContReturn;
-      if (!_slang_codegen_global_variable(&A, var, C->type))
-         RETURN0;
-   }
-
-   /* initialize global variable */
-   if (C->global_scope) {
-      if (var->initializer != NULL) {
-         slang_assemble_ctx A;
-         memset(&A, 0, sizeof(slang_assemble_ctx));
-         A.allow_uniform_initializers = C->version > 110;
-         A.atoms = C->atoms;
-         A.space.funcs = O->funs;
-         A.space.structs = O->structs;
-         A.space.vars = O->vars;
-         if (!initialize_global(&A, var))
-            RETURN0;
-      }
-   }
-
-   if (var->type.qualifier == SLANG_QUAL_FIXEDINPUT &&
-       var->a_name == slang_atom_pool_atom(C->atoms, "gl_FragCoord")) {
-      /* set the program's PixelCenterInteger, OriginUpperLeft fields */
-      struct gl_fragment_program *fragProg =
-         (struct gl_fragment_program *) O->program;
-
-      if (var->type.layout & SLANG_LAYOUT_UPPER_LEFT_BIT) {
-         fragProg->OriginUpperLeft = GL_TRUE;
-      }
-      if (var->type.layout & SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT) {
-         fragProg->PixelCenterInteger = GL_TRUE;
-      }
-   }
-
-   return 1;
-}
-
-/**
- * Parse a list of variable declarations.  Each variable may have an
- * initializer.
- */
-static int
-parse_init_declarator_list(slang_parse_ctx * C, slang_output_ctx * O)
-{
-   slang_fully_specified_type type;
-
-   /* parse the fully specified type, common to all declarators */
-   if (!slang_fully_specified_type_construct(&type))
-      RETURN0;
-   if (!parse_fully_specified_type(C, O, &type)) {
-      slang_fully_specified_type_destruct(&type);
-      RETURN0;
-   }
-
-   /* parse declarators, pass-in the parsed type */
-   do {
-      if (!parse_init_declarator(C, O, &type)) {
-         slang_fully_specified_type_destruct(&type);
-         RETURN0;
-      }
-   }
-   while (*C->I++ == DECLARATOR_NEXT);
-
-   slang_fully_specified_type_destruct(&type);
-   return 1;
-}
-
-
-/**
- * Parse a function definition or declaration.
- * \param C  parsing context
- * \param O  output context
- * \param definition if non-zero expect a definition, else a declaration
- * \param parsed_func_ret  returns the parsed function
- * \return GL_TRUE if success, GL_FALSE if failure
- */
-static GLboolean
-parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
-               slang_function ** parsed_func_ret)
-{
-   slang_function parsed_func, *found_func;
-
-   /* parse function definition/declaration */
-   if (!slang_function_construct(&parsed_func))
-      return GL_FALSE;
-   if (definition) {
-      if (!parse_function_definition(C, O, &parsed_func)) {
-         slang_function_destruct(&parsed_func);
-         return GL_FALSE;
-      }
-   }
-   else {
-      if (!parse_function_prototype(C, O, &parsed_func)) {
-         slang_function_destruct(&parsed_func);
-         return GL_FALSE;
-      }
-   }
-
-   /* find a function with a prototype matching the parsed one - only
-    * the current scope is being searched to allow built-in function
-    * overriding
-    */
-   found_func = slang_function_scope_find(O->funs, &parsed_func, 0);
-   if (found_func == NULL) {
-      /* New function, add it to the function list */
-      O->funs->functions =
-         (slang_function *) _slang_realloc(O->funs->functions,
-                                           O->funs->num_functions
-                                           * sizeof(slang_function),
-                                           (O->funs->num_functions + 1)
-                                           * sizeof(slang_function));
-      if (O->funs->functions == NULL) {
-         /* Make sure that there are no functions marked, as the
-          * allocation is currently NULL, in order to avoid
-          * a potental segfault as we clean up later.
-          */
-         O->funs->num_functions = 0;
-
-         slang_info_log_memory(C->L);
-         slang_function_destruct(&parsed_func);
-         return GL_FALSE;
-      }
-      O->funs->functions[O->funs->num_functions] = parsed_func;
-      O->funs->num_functions++;
-
-      /* return the newly parsed function */
-      *parsed_func_ret = &O->funs->functions[O->funs->num_functions - 1];
-   }
-   else {
-      /* previously defined or declared */
-      /* TODO: check function return type qualifiers and specifiers */
-      if (definition) {
-         if (found_func->body != NULL) {
-            slang_info_log_error(C->L, "%s: function already has a body.",
-                                 slang_atom_pool_id(C->atoms,
-                                                    parsed_func.header.
-                                                    a_name));
-            slang_function_destruct(&parsed_func);
-            return GL_FALSE;
-         }
-
-         /* destroy the existing function declaration and replace it
-          * with the new one
-          */
-         slang_function_destruct(found_func);
-         *found_func = parsed_func;
-      }
-      else {
-         /* another declaration of the same function prototype - ignore it */
-         slang_function_destruct(&parsed_func);
-      }
-
-      /* return the found function */
-      *parsed_func_ret = found_func;
-   }
-
-   return GL_TRUE;
-}
-
-/* declaration */
-#define DECLARATION_FUNCTION_PROTOTYPE 1
-#define DECLARATION_INIT_DECLARATOR_LIST 2
-
-static int
-parse_declaration(slang_parse_ctx * C, slang_output_ctx * O)
-{
-   switch (*C->I++) {
-   case DECLARATION_INIT_DECLARATOR_LIST:
-      if (!parse_init_declarator_list(C, O))
-         RETURN0;
-      break;
-   case DECLARATION_FUNCTION_PROTOTYPE:
-      {
-         slang_function *dummy_func;
-
-         if (!parse_function(C, O, 0, &dummy_func))
-            RETURN0;
-      }
-      break;
-   default:
-      RETURN0;
-   }
-   return 1;
-}
-
-static int
-parse_default_precision(slang_parse_ctx * C, slang_output_ctx * O)
-{
-   int precision, type;
-
-   if (!O->allow_precision) {
-      slang_info_log_error(C->L, "syntax error at \"precision\"");
-      RETURN0;
-   }
-
-   precision = *C->I++;
-   switch (precision) {
-   case PRECISION_LOW:
-   case PRECISION_MEDIUM:
-   case PRECISION_HIGH:
-      /* OK */
-      break;
-   default:
-      _mesa_problem(NULL, "unexpected precision %d at %s:%d\n",
-                    precision, __FILE__, __LINE__);
-      RETURN0;
-   }
-
-   type = *C->I++;
-   switch (type) {
-   case TYPE_SPECIFIER_FLOAT:
-   case TYPE_SPECIFIER_INT:
-   case TYPE_SPECIFIER_SAMPLER1D:
-   case TYPE_SPECIFIER_SAMPLER2D:
-   case TYPE_SPECIFIER_SAMPLER3D:
-   case TYPE_SPECIFIER_SAMPLERCUBE:
-   case TYPE_SPECIFIER_SAMPLER1DSHADOW:
-   case TYPE_SPECIFIER_SAMPLER2DSHADOW:
-   case TYPE_SPECIFIER_SAMPLER2DRECT:
-   case TYPE_SPECIFIER_SAMPLER2DRECTSHADOW:
-   case TYPE_SPECIFIER_SAMPLER_1D_ARRAY:
-   case TYPE_SPECIFIER_SAMPLER_2D_ARRAY:
-   case TYPE_SPECIFIER_SAMPLER_1D_ARRAY_SHADOW:
-   case TYPE_SPECIFIER_SAMPLER_2D_ARRAY_SHADOW:
-      /* OK */
-      break;
-   default:
-      _mesa_problem(NULL, "unexpected type %d at %s:%d\n",
-                    type, __FILE__, __LINE__);
-      RETURN0;
-   }
-
-   assert(type < TYPE_SPECIFIER_COUNT);
-   O->default_precision[type] = precision;
-
-   return 1;
-}
-
-
-/**
- * Initialize the default precision for all types.
- * XXX this info isn't used yet.
- */
-static void
-init_default_precision(slang_output_ctx *O, slang_unit_type type)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLuint i;
-   for (i = 0; i < TYPE_SPECIFIER_COUNT; i++) {
-#if FEATURE_es2_glsl
-      if (ctx->API == API_OPENGLES2)
-        O->default_precision[i] = PRECISION_LOW;
-      else
-        O->default_precision[i] = PRECISION_HIGH;
-#else
-      (void) ctx;
-      O->default_precision[i] = PRECISION_HIGH;
-#endif
-   }
-
-   if (type == SLANG_UNIT_VERTEX_SHADER) {
-      O->default_precision[TYPE_SPECIFIER_FLOAT] = PRECISION_HIGH;
-      O->default_precision[TYPE_SPECIFIER_INT] = PRECISION_HIGH;
-   }
-   else {
-      O->default_precision[TYPE_SPECIFIER_INT] = PRECISION_MEDIUM;
-   }
-}
-
-
-static int
-parse_invariant(slang_parse_ctx * C, slang_output_ctx * O)
-{
-   if (O->allow_invariant) {
-      slang_atom *a = parse_identifier(C);
-      /* XXX not doing anything with this var yet */
-      /*printf("ID: %s\n", (char*) a);*/
-      return a ? 1 : 0;
-   }
-   else {
-      slang_info_log_error(C->L, "syntax error at \"invariant\"");
-      RETURN0;
-   }
-}
-      
-
-/* external declaration or default precision specifier */
-#define EXTERNAL_NULL 0
-#define EXTERNAL_FUNCTION_DEFINITION 1
-#define EXTERNAL_DECLARATION 2
-#define DEFAULT_PRECISION 3
-#define INVARIANT_STMT 4
-
-
-static GLboolean
-parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit,
-                struct gl_shader *shader)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   slang_output_ctx o;
-   GLboolean success;
-   GLuint maxRegs;
-   slang_function *mainFunc = NULL;
-
-   if (unit->type == SLANG_UNIT_FRAGMENT_BUILTIN ||
-       unit->type == SLANG_UNIT_FRAGMENT_SHADER) {
-      maxRegs = ctx->Const.FragmentProgram.MaxTemps;
-   }
-   else {
-      assert(unit->type == SLANG_UNIT_VERTEX_BUILTIN ||
-             unit->type == SLANG_UNIT_VERTEX_SHADER);
-      maxRegs = ctx->Const.VertexProgram.MaxTemps;
-   }
-
-   /* setup output context */
-   o.funs = &unit->funs;
-   o.structs = &unit->structs;
-   o.vars = &unit->vars;
-   o.program = shader ? shader->Program : NULL;
-   o.pragmas = shader ? &shader->Pragmas : NULL;
-   o.vartable = _slang_new_var_table(maxRegs);
-   _slang_push_var_table(o.vartable);
-
-   /* allow 'invariant' keyword? */
-#if FEATURE_es2_glsl
-   o.allow_invariant =
-      (ctx->API == API_OPENGLES2 || C->version >= 120) ? GL_TRUE : GL_FALSE;
-#else
-   o.allow_invariant = (C->version >= 120) ? GL_TRUE : GL_FALSE;
-#endif
-
-   /* allow 'centroid' keyword? */
-   o.allow_centroid = (C->version >= 120) ? GL_TRUE : GL_FALSE;
-
-   /* allow 'lowp/mediump/highp' keywords? */
-#if FEATURE_es2_glsl
-   o.allow_precision =
-      (ctx->API == API_OPENGLES2 || C->version >= 120) ? GL_TRUE : GL_FALSE;
-#else
-   o.allow_precision = (C->version >= 120) ? GL_TRUE : GL_FALSE;
-#endif
-   init_default_precision(&o, unit->type);
-
-   /* allow 'float[]' keyword? */
-   o.allow_array_types = (C->version >= 120) ? GL_TRUE : GL_FALSE;
-
-   /* parse individual functions and declarations */
-   while (*C->I != EXTERNAL_NULL) {
-      switch (*C->I++) {
-      case EXTERNAL_FUNCTION_DEFINITION:
-         {
-            slang_function *func;
-            success = parse_function(C, &o, 1, &func);
-            if (success && strcmp((char *) func->header.a_name, "main") == 0) {
-               /* found main() */
-               mainFunc = func;
-            }
-         }
-         break;
-      case EXTERNAL_DECLARATION:
-         success = parse_declaration(C, &o);
-         break;
-      case DEFAULT_PRECISION:
-         success = parse_default_precision(C, &o);
-         break;
-      case INVARIANT_STMT:
-         success = parse_invariant(C, &o);
-         break;
-      default:
-         success = GL_FALSE;
-      }
-
-      if (!success) {
-         /* xxx free codegen */
-         _slang_pop_var_table(o.vartable);
-         return GL_FALSE;
-      }
-   }
-   C->I++;
-
-   if (mainFunc) {
-      /* assemble (generate code) for main() */
-      slang_assemble_ctx A;
-      memset(&A, 0, sizeof(slang_assemble_ctx));
-      A.atoms = C->atoms;
-      A.space.funcs = o.funs;
-      A.space.structs = o.structs;
-      A.space.vars = o.vars;
-      A.program = o.program;
-      A.pragmas = &shader->Pragmas;
-      A.vartable = o.vartable;
-      A.EmitContReturn = ctx->Shader.EmitContReturn;
-      A.log = C->L;
-      A.allow_uniform_initializers = C->version > 110;
-
-      /* main() takes no parameters */
-      if (mainFunc->param_count > 0) {
-         slang_info_log_error(A.log, "main() takes no arguments");
-         return GL_FALSE;
-      }
-
-      _slang_codegen_function(&A, mainFunc);
-
-      shader->Main = GL_TRUE; /* this shader defines main() */
-
-      shader->UnresolvedRefs = A.UnresolvedRefs;
-   }
-
-   _slang_pop_var_table(o.vartable);
-   _slang_delete_var_table(o.vartable);
-
-   return GL_TRUE;
-}
-
-static GLboolean
-compile_binary(const unsigned char * prod, slang_code_unit * unit,
-               GLuint version,
-               slang_unit_type type, slang_info_log * infolog,
-               slang_code_unit * builtin, slang_code_unit * downlink,
-               struct gl_shader *shader)
-{
-   slang_parse_ctx C;
-
-   unit->type = type;
-
-   /* setup parse context */
-   C.I = prod;
-   C.L = infolog;
-   C.parsing_builtin = (builtin == NULL);
-   C.global_scope = GL_TRUE;
-   C.atoms = &unit->object->atompool;
-   C.type = type;
-   C.version = version;
-
-   if (!check_revision(&C))
-      return GL_FALSE;
-
-   if (downlink != NULL) {
-      unit->vars.outer_scope = &downlink->vars;
-      unit->funs.outer_scope = &downlink->funs;
-      unit->structs.outer_scope = &downlink->structs;
-   }
-
-   /* parse translation unit */
-   return parse_code_unit(&C, unit, shader);
-}
-
-static GLboolean
-compile_with_grammar(const char *source,
-                     slang_code_unit *unit,
-                     slang_unit_type type,
-                     slang_info_log *infolog,
-                     slang_code_unit *builtin,
-                     struct gl_shader *shader,
-                     struct gl_sl_pragmas *pragmas,
-                     unsigned int shader_type,
-                     unsigned int parsing_builtin)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   struct sl_pp_purify_options options;
-   struct sl_pp_context *context;
-   unsigned char *prod;
-   GLuint size;
-   unsigned int version;
-   unsigned int maxVersion;
-   int result;
-   char errmsg[200] = "";
-
-   assert(shader_type == 1 || shader_type == 2);
-
-   memset(&options, 0, sizeof(options));
-
-   context = sl_pp_context_create(source, &options);
-   if (!context) {
-      slang_info_log_error(infolog, "out of memory");
-      return GL_FALSE;
-   }
-
-   if (sl_pp_version(context, &version)) {
-      slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context));
-      sl_pp_context_destroy(context);
-      return GL_FALSE;
-   }
-
-   if (sl_pp_context_add_extension(context, "GL_ARB_draw_buffers") ||
-       sl_pp_context_add_extension(context, "GL_ARB_texture_rectangle")) {
-      slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context));
-      sl_pp_context_destroy(context);
-      return GL_FALSE;
-   }
-
-   if (type == SLANG_UNIT_FRAGMENT_SHADER) {
-      sl_pp_context_add_extension(context, "GL_ARB_fragment_coord_conventions");
-   }
-
-
-#if FEATURE_es2_glsl
-   if (ctx->API == API_OPENGLES2) {
-      if (sl_pp_context_add_predefined(context, "GL_ES", "1") ||
-         sl_pp_context_add_predefined(context, "GL_FRAGMENT_PRECISION_HIGH", "1")) {
-        slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context));
-        sl_pp_context_destroy(context);
-        return GL_FALSE;
-      }
-   }
-#else
-   (void) ctx;
-#endif
-
-#if FEATURE_ARB_shading_language_120
-   maxVersion = 120;
-#elif FEATURE_es2_glsl
-   maxVersion = 100;
-#else
-   maxVersion = 110;
-#endif
-
-   if (version > maxVersion ||
-       (version != 100 && version != 110 && version != 120)) {
-      slang_info_log_error(infolog,
-                           "language version %.2f is not supported.",
-                           version * 0.01);
-      sl_pp_context_destroy(context);
-      return GL_FALSE;
-   }
-
-   /* Finally check the syntax and generate its binary representation. */
-   result = sl_cl_compile(context,
-                          shader_type,
-                          parsing_builtin,
-                          &prod,
-                          &size,
-                          errmsg,
-                          sizeof(errmsg));
-
-   sl_pp_context_destroy(context);
-
-   if (result) {
-      /*GLint pos;*/
-
-      slang_info_log_error(infolog, errmsg);
-      /* syntax error (possibly in library code) */
-#if 0
-      {
-         int line, col;
-         char *s;
-         s = (char *) _mesa_find_line_column((const GLubyte *) source,
-                                             (const GLubyte *) source + pos,
-                                             &line, &col);
-         printf("Error on line %d, col %d: %s\n", line, col, s);
-      }
-#endif
-      return GL_FALSE;
-   }
-
-   /* Syntax is okay - translate it to internal representation. */
-   if (!compile_binary(prod, unit, version, type, infolog, builtin,
-                       &builtin[SLANG_BUILTIN_TOTAL - 1],
-                       shader)) {
-      free(prod);
-      return GL_FALSE;
-   }
-   free(prod);
-   return GL_TRUE;
-}
-
-static const unsigned char slang_core_gc[] = {
-#include "library/slang_core_gc.h"
-};
-
-static const unsigned char slang_120_core_gc[] = {
-#include "library/slang_120_core_gc.h"
-};
-
-static const unsigned char slang_120_fragment_gc[] = {
-#include "library/slang_builtin_120_fragment_gc.h"
-};
-
-static const unsigned char slang_common_builtin_gc[] = {
-#include "library/slang_common_builtin_gc.h"
-};
-
-static const unsigned char slang_fragment_builtin_gc[] = {
-#include "library/slang_fragment_builtin_gc.h"
-};
-
-static const unsigned char slang_vertex_builtin_gc[] = {
-#include "library/slang_vertex_builtin_gc.h"
-};
-
-static GLboolean
-compile_object(const char *source,
-               slang_code_object *object,
-               slang_unit_type type,
-               slang_info_log *infolog,
-               struct gl_shader *shader,
-               struct gl_sl_pragmas *pragmas)
-{
-   slang_code_unit *builtins = NULL;
-   GLuint base_version = 110;
-   unsigned int shader_type;
-   unsigned int parsing_builtin;
-
-   /* set shader type - the syntax is slightly different for different shaders */
-   if (type == SLANG_UNIT_FRAGMENT_SHADER || type == SLANG_UNIT_FRAGMENT_BUILTIN) {
-      shader_type = 1;
-   } else {
-      shader_type = 2;
-   }
-
-   /* enable language extensions */
-   parsing_builtin = 1;
-
-   /* if parsing user-specified shader, load built-in library */
-   if (type == SLANG_UNIT_FRAGMENT_SHADER || type == SLANG_UNIT_VERTEX_SHADER) {
-      /* compile core functionality first */
-      if (!compile_binary(slang_core_gc,
-                          &object->builtin[SLANG_BUILTIN_CORE],
-                          base_version,
-                          SLANG_UNIT_FRAGMENT_BUILTIN, infolog,
-                          NULL, NULL, NULL))
-         return GL_FALSE;
-
-#if FEATURE_ARB_shading_language_120
-      if (!compile_binary(slang_120_core_gc,
-                          &object->builtin[SLANG_BUILTIN_120_CORE],
-                          120,
-                          SLANG_UNIT_FRAGMENT_BUILTIN, infolog,
-                          NULL, &object->builtin[SLANG_BUILTIN_CORE], NULL))
-         return GL_FALSE;
-#endif
-
-      /* compile common functions and variables, link to core */
-      if (!compile_binary(slang_common_builtin_gc,
-                          &object->builtin[SLANG_BUILTIN_COMMON],
-#if FEATURE_ARB_shading_language_120
-                          120,
-#else
-                          base_version,
-#endif
-                          SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL,
-#if FEATURE_ARB_shading_language_120
-                          &object->builtin[SLANG_BUILTIN_120_CORE],
-#else
-                          &object->builtin[SLANG_BUILTIN_CORE],
-#endif
-                          NULL))
-         return GL_FALSE;
-
-      /* compile target-specific functions and variables, link to common */
-      if (type == SLANG_UNIT_FRAGMENT_SHADER) {
-         if (!compile_binary(slang_fragment_builtin_gc,
-                             &object->builtin[SLANG_BUILTIN_TARGET],
-                             base_version,
-                             SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL,
-                             &object->builtin[SLANG_BUILTIN_COMMON], NULL))
-            return GL_FALSE;
-#if FEATURE_ARB_shading_language_120
-         if (!compile_binary(slang_120_fragment_gc,
-                             &object->builtin[SLANG_BUILTIN_TARGET],
-                             120,
-                             SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL,
-                             &object->builtin[SLANG_BUILTIN_COMMON], NULL))
-            return GL_FALSE;
-#endif
-      }
-      else if (type == SLANG_UNIT_VERTEX_SHADER) {
-         if (!compile_binary(slang_vertex_builtin_gc,
-                             &object->builtin[SLANG_BUILTIN_TARGET],
-                             base_version,
-                             SLANG_UNIT_VERTEX_BUILTIN, infolog, NULL,
-                             &object->builtin[SLANG_BUILTIN_COMMON], NULL))
-            return GL_FALSE;
-      }
-
-      /* disable language extensions */
-      parsing_builtin = 0;
-
-      builtins = object->builtin;
-   }
-
-   /* compile the actual shader - pass-in built-in library for external shader */
-   return compile_with_grammar(source,
-                               &object->unit,
-                               type,
-                               infolog,
-                               builtins,
-                               shader,
-                               pragmas,
-                               shader_type,
-                               parsing_builtin);
-}
-
-
-GLboolean
-_slang_compile(GLcontext *ctx, struct gl_shader *shader)
-{
-   GLboolean success;
-   slang_info_log info_log;
-   slang_code_object obj;
-   slang_unit_type type;
-   GLenum progTarget;
-
-   if (shader->Type == GL_VERTEX_SHADER) {
-      type = SLANG_UNIT_VERTEX_SHADER;
-   }
-   else {
-      assert(shader->Type == GL_FRAGMENT_SHADER);
-      type = SLANG_UNIT_FRAGMENT_SHADER;
-   }
-
-   if (!shader->Source)
-      return GL_FALSE;
-
-   ctx->Shader.MemPool = _slang_new_mempool(1024*1024);
-
-   shader->Main = GL_FALSE;
-
-   /* free the shader's old instructions, etc */
-   _mesa_reference_program(ctx, &shader->Program, NULL);
-
-   /* allocate new GPU program, parameter lists, etc. */
-   if (shader->Type == GL_VERTEX_SHADER)
-      progTarget = GL_VERTEX_PROGRAM_ARB;
-   else
-      progTarget = GL_FRAGMENT_PROGRAM_ARB;
-   shader->Program = ctx->Driver.NewProgram(ctx, progTarget, 1);
-   shader->Program->Parameters = _mesa_new_parameter_list();
-   shader->Program->Varying = _mesa_new_parameter_list();
-   shader->Program->Attributes = _mesa_new_parameter_list();
-
-   slang_info_log_construct(&info_log);
-   _slang_code_object_ctr(&obj);
-
-   success = compile_object(shader->Source,
-                            &obj,
-                            type,
-                            &info_log,
-                            shader,
-                            &shader->Pragmas);
-
-   /* free shader's prev info log */
-   if (shader->InfoLog) {
-      free(shader->InfoLog);
-      shader->InfoLog = NULL;
-   }
-
-   if (info_log.text) {
-      /* copy info-log string to shader object */
-      shader->InfoLog = _mesa_strdup(info_log.text);
-   }
-
-   if (info_log.error_flag) {
-      success = GL_FALSE;
-   }
-
-   slang_info_log_destruct(&info_log);
-   _slang_code_object_dtr(&obj);
-
-   _slang_delete_mempool((slang_mempool *) ctx->Shader.MemPool);
-   ctx->Shader.MemPool = NULL;
-
-   /* remove any reads of output registers */
-#if 0
-   printf("Pre-remove output reads:\n");
-   _mesa_print_program(shader->Program);
-#endif
-   _mesa_remove_output_reads(shader->Program, PROGRAM_OUTPUT);
-   if (shader->Type == GL_VERTEX_SHADER) {
-      /* and remove writes to varying vars in vertex programs */
-      _mesa_remove_output_reads(shader->Program, PROGRAM_VARYING);
-   }
-#if 0
-   printf("Post-remove output reads:\n");
-   _mesa_print_program(shader->Program);
-#endif
-
-   shader->CompileStatus = success;
-
-   if (success) {
-      if (shader->Pragmas.Optimize &&
-          (ctx->Shader.Flags & GLSL_NO_OPT) == 0) {
-         _mesa_optimize_program(ctx, shader->Program);
-      }
-      if ((ctx->Shader.Flags & GLSL_NOP_VERT) &&
-          shader->Program->Target == GL_VERTEX_PROGRAM_ARB) {
-         _mesa_nop_vertex_program(ctx,
-                                  (struct gl_vertex_program *) shader->Program);
-      }
-      if ((ctx->Shader.Flags & GLSL_NOP_FRAG) &&
-          shader->Program->Target == GL_FRAGMENT_PROGRAM_ARB) {
-         _mesa_nop_fragment_program(ctx,
-                                (struct gl_fragment_program *) shader->Program);
-      }
-   }
-
-   if (ctx->Shader.Flags & GLSL_LOG) {
-      _mesa_write_shader_to_file(shader);
-   }
-
-   return success;
-}
-
diff --git a/src/mesa/shader/slang/slang_compile.h b/src/mesa/shader/slang/slang_compile.h
deleted file mode 100644 (file)
index 7fb549d..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5
- *
- * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#if !defined SLANG_COMPILE_H
-#define SLANG_COMPILE_H
-
-#include "main/imports.h"
-#include "main/mtypes.h"
-#include "slang_typeinfo.h"
-#include "slang_compile_variable.h"
-#include "slang_compile_struct.h"
-#include "slang_compile_operation.h"
-#include "slang_compile_function.h"
-
-#if defined __cplusplus
-extern "C" {
-#endif
-
-typedef struct slang_name_space_
-{
-   struct slang_function_scope_ *funcs;
-   struct slang_struct_scope_ *structs;
-   struct slang_variable_scope_ *vars;
-} slang_name_space;
-
-typedef enum slang_unit_type_
-{
-   SLANG_UNIT_FRAGMENT_SHADER,
-   SLANG_UNIT_VERTEX_SHADER,
-   SLANG_UNIT_FRAGMENT_BUILTIN,
-   SLANG_UNIT_VERTEX_BUILTIN
-} slang_unit_type;
-
-
-typedef struct slang_code_unit_
-{
-   slang_variable_scope vars;
-   slang_function_scope funs;
-   slang_struct_scope structs;
-   slang_unit_type type;
-   struct slang_code_object_ *object;
-} slang_code_unit;
-
-
-extern GLvoid
-_slang_code_unit_ctr (slang_code_unit *, struct slang_code_object_ *);
-
-extern GLvoid
-_slang_code_unit_dtr (slang_code_unit *);
-
-#define SLANG_BUILTIN_CORE   0
-#define SLANG_BUILTIN_120_CORE   1
-#define SLANG_BUILTIN_COMMON 2
-#define SLANG_BUILTIN_TARGET 3
-
-#define SLANG_BUILTIN_TOTAL  4
-
-typedef struct slang_code_object_
-{
-   slang_code_unit builtin[SLANG_BUILTIN_TOTAL];
-   slang_code_unit unit;
-   slang_atom_pool atompool;
-} slang_code_object;
-
-extern GLvoid
-_slang_code_object_ctr (slang_code_object *);
-
-extern GLvoid
-_slang_code_object_dtr (slang_code_object *);
-
-extern GLboolean
-_slang_compile (GLcontext *ctx, struct gl_shader *shader);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/src/mesa/shader/slang/slang_compile_function.c b/src/mesa/shader/slang/slang_compile_function.c
deleted file mode 100644 (file)
index 4dd8851..0000000
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5
- *
- * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file slang_compile_function.c
- * slang front-end compiler
- * \author Michal Krol
- */
-
-#include "main/imports.h"
-#include "slang_compile.h"
-#include "slang_mem.h"
-
-
-int
-slang_function_construct(slang_function * func)
-{
-   func->kind = SLANG_FUNC_ORDINARY;
-   if (!slang_variable_construct(&func->header))
-      return 0;
-
-   func->parameters = (slang_variable_scope *)
-      _slang_alloc(sizeof(slang_variable_scope));
-   if (func->parameters == NULL) {
-      slang_variable_destruct(&func->header);
-      return 0;
-   }
-
-   _slang_variable_scope_ctr(func->parameters);
-   func->param_count = 0;
-   func->body = NULL;
-   return 1;
-}
-
-void
-slang_function_destruct(slang_function * func)
-{
-   slang_variable_destruct(&func->header);
-   slang_variable_scope_destruct(func->parameters);
-   _slang_free(func->parameters);
-   if (func->body != NULL) {
-      slang_operation_destruct(func->body);
-      _slang_free(func->body);
-   }
-}
-
-
-slang_function *
-slang_function_new(slang_function_kind kind)
-{
-   slang_function *fun = (slang_function *)
-      _slang_alloc(sizeof(slang_function));
-   if (fun) {
-      slang_function_construct(fun);
-      fun->kind = kind;
-   }
-   return fun;
-}
-
-
-/*
- * slang_function_scope
- */
-
-GLvoid
-_slang_function_scope_ctr(slang_function_scope * self)
-{
-   self->functions = NULL;
-   self->num_functions = 0;
-   self->outer_scope = NULL;
-}
-
-void
-slang_function_scope_destruct(slang_function_scope * scope)
-{
-   unsigned int i;
-
-   for (i = 0; i < scope->num_functions; i++)
-      slang_function_destruct(scope->functions + i);
-   _slang_free(scope->functions);
-}
-
-
-/**
- * Does this function have a non-void return value?
- */
-GLboolean
-_slang_function_has_return_value(const slang_function *fun)
-{
-   return fun->header.type.specifier.type != SLANG_SPEC_VOID;
-}
-
-
-/**
- * Search a list of functions for a particular function by name.
- * \param funcs  the list of functions to search
- * \param a_name  the name to search for
- * \param all_scopes  if non-zero, search containing scopes too.
- * \return pointer to found function, or NULL.
- */
-int
-slang_function_scope_find_by_name(slang_function_scope * funcs,
-                                  slang_atom a_name, int all_scopes)
-{
-   unsigned int i;
-
-   for (i = 0; i < funcs->num_functions; i++)
-      if (a_name == funcs->functions[i].header.a_name)
-         return 1;
-   if (all_scopes && funcs->outer_scope != NULL)
-      return slang_function_scope_find_by_name(funcs->outer_scope, a_name, 1);
-   return 0;
-}
-
-
-/**
- * Search a list of functions for a particular function (for implementing
- * function calls.  Matching is done by first comparing the function's name,
- * then the function's parameter list.
- *
- * \param funcs  the list of functions to search
- * \param fun  the function to search for
- * \param all_scopes  if non-zero, search containing scopes too.
- * \return pointer to found function, or NULL.
- */
-slang_function *
-slang_function_scope_find(slang_function_scope * funcs, slang_function * fun,
-                          int all_scopes)
-{
-   unsigned int i;
-
-   for (i = 0; i < funcs->num_functions; i++) {
-      slang_function *f = &funcs->functions[i];
-      const GLuint haveRetValue = 0;
-#if 0
-         = (f->header.type.specifier.type != SLANG_SPEC_VOID);
-#endif
-      unsigned int j;
-
-      /*
-      printf("Compare name %s to %s  (ret %u, %d, %d)\n",
-             (char *) fun->header.a_name, (char *) f->header.a_name,
-             haveRetValue,
-             fun->param_count, f->param_count);
-      */
-
-      if (fun->header.a_name != f->header.a_name)
-         continue;
-      if (fun->param_count != f->param_count)
-         continue;
-      for (j = haveRetValue; j < fun->param_count; j++) {
-         if (!slang_type_specifier_equal
-             (&fun->parameters->variables[j]->type.specifier,
-              &f->parameters->variables[j]->type.specifier))
-            break;
-      }
-      if (j == fun->param_count) {
-         /*
-         printf("Found match\n");
-         */
-         return f;
-      }
-   }
-   /*
-   printf("Not found\n");
-   */
-   if (all_scopes && funcs->outer_scope != NULL)
-      return slang_function_scope_find(funcs->outer_scope, fun, 1);
-   return NULL;
-}
-
-
-/**
- * Lookup a function according to name and parameter count/types.
- */
-slang_function *
-_slang_function_locate(const slang_function_scope * funcs, slang_atom a_name,
-                       slang_operation * args, GLuint num_args,
-                       const slang_name_space * space, slang_atom_pool * atoms,
-                       slang_info_log *log, GLboolean *error)
-{
-   slang_typeinfo arg_ti[100];
-   GLuint i;
-
-   *error = GL_FALSE;
-
-   /* determine type of each argument */
-   assert(num_args < 100);
-   for (i = 0; i < num_args; i++) {
-      if (!slang_typeinfo_construct(&arg_ti[i]))
-         return NULL;
-      if (!_slang_typeof_operation(&args[i], space, &arg_ti[i], atoms, log)) {
-         return NULL;
-      }
-   }
-
-   /* loop over function scopes */
-   while (funcs) {
-
-      /* look for function with matching name and argument/param types */
-      for (i = 0; i < funcs->num_functions; i++) {
-         slang_function *f = &funcs->functions[i];
-         const GLuint haveRetValue = _slang_function_has_return_value(f);
-         GLuint j;
-
-         if (a_name != f->header.a_name)
-            continue;
-         if (f->param_count - haveRetValue != num_args)
-            continue;
-
-         /* compare parameter / argument types */
-         for (j = 0; j < num_args; j++) {
-            if (!slang_type_specifier_compatible(&arg_ti[j].spec,
-                              &f->parameters->variables[j]->type.specifier)) {
-               /* param/arg types don't match */
-               break;
-            }
-
-            /* "out" and "inout" formal parameter requires the actual
-             * argument to be an l-value.
-             */
-            if (!arg_ti[j].can_be_referenced &&
-                (f->parameters->variables[j]->type.qualifier == SLANG_QUAL_OUT ||
-                 f->parameters->variables[j]->type.qualifier == SLANG_QUAL_INOUT)) {
-               /* param is not an lvalue! */
-               *error = GL_TRUE;
-               return NULL;
-            }
-         }
-
-         if (j == num_args) {
-            /* name and args match! */
-            return f;
-         }
-      }
-
-      funcs = funcs->outer_scope;
-   }
-
-   return NULL;
-}
diff --git a/src/mesa/shader/slang/slang_compile_function.h b/src/mesa/shader/slang/slang_compile_function.h
deleted file mode 100644 (file)
index a5445ec..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.2
- *
- * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef SLANG_COMPILE_FUNCTION_H
-#define SLANG_COMPILE_FUNCTION_H
-
-
-/**
- * Types of functions.
- */
-typedef enum slang_function_kind_
-{
-   SLANG_FUNC_ORDINARY,
-   SLANG_FUNC_CONSTRUCTOR,
-   SLANG_FUNC_OPERATOR
-} slang_function_kind;
-
-
-/**
- * Description of a compiled shader function.
- */
-typedef struct slang_function_
-{
-   slang_function_kind kind;
-   slang_variable header;      /**< The function's name and return type */
-   slang_variable_scope *parameters; /**< formal parameters AND local vars */
-   unsigned int param_count;   /**< number of formal params (no locals) */
-   slang_operation *body;      /**< The instruction tree */
-} slang_function;
-
-extern int slang_function_construct(slang_function *);
-extern void slang_function_destruct(slang_function *);
-extern slang_function *slang_function_new(slang_function_kind kind);
-
-extern GLboolean
-_slang_function_has_return_value(const slang_function *fun);
-
-
-/**
- * Basically, a list of compiled functions.
- */
-typedef struct slang_function_scope_
-{
-   slang_function *functions;
-   GLuint num_functions;
-   struct slang_function_scope_ *outer_scope;
-} slang_function_scope;
-
-
-extern GLvoid
-_slang_function_scope_ctr(slang_function_scope *);
-
-extern void
-slang_function_scope_destruct(slang_function_scope *);
-
-extern int
-slang_function_scope_find_by_name(slang_function_scope *, slang_atom, int);
-
-extern slang_function *
-slang_function_scope_find(slang_function_scope *, slang_function *, int);
-
-extern struct slang_function_ *
-_slang_function_locate(const struct slang_function_scope_ *funcs,
-                       slang_atom name, struct slang_operation_ *params,
-                       GLuint num_params,
-                       const struct slang_name_space_ *space,
-                       slang_atom_pool *atoms, slang_info_log *log,
-                       GLboolean *error);
-
-
-#endif /* SLANG_COMPILE_FUNCTION_H */
diff --git a/src/mesa/shader/slang/slang_compile_operation.c b/src/mesa/shader/slang/slang_compile_operation.c
deleted file mode 100644 (file)
index 5441d60..0000000
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.2
- *
- * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file slang_compile_operation.c
- * slang front-end compiler
- * \author Michal Krol
- */
-
-#include "main/imports.h"
-#include "slang_compile.h"
-#include "slang_mem.h"
-
-
-/**
- * Init a slang_operation object
- */
-GLboolean
-slang_operation_construct(slang_operation * oper)
-{
-   oper->type = SLANG_OPER_NONE;
-   oper->children = NULL;
-   oper->num_children = 0;
-   oper->literal[0] = 0.0;
-   oper->literal_size = 1;
-   oper->array_constructor = GL_FALSE;
-   oper->a_id = SLANG_ATOM_NULL;
-   oper->a_obj = SLANG_ATOM_NULL;
-   oper->locals = _slang_variable_scope_new(NULL);
-   if (oper->locals == NULL)
-      return GL_FALSE;
-   _slang_variable_scope_ctr(oper->locals);
-   oper->fun = NULL;
-   oper->var = NULL;
-   oper->label = NULL;
-   return GL_TRUE;
-}
-
-void
-slang_operation_destruct(slang_operation * oper)
-{
-   GLuint i;
-
-   for (i = 0; i < oper->num_children; i++)
-      slang_operation_destruct(oper->children + i);
-   _slang_free(oper->children);
-   slang_variable_scope_destruct(oper->locals);
-   _slang_free(oper->locals);
-   oper->children = NULL;
-   oper->num_children = 0;
-   oper->locals = NULL;
-}
-
-
-/**
- * Recursively traverse 'oper', replacing occurances of 'oldScope' with
- * 'newScope' in the oper->locals->outer_scope field.
- */
-void
-slang_replace_scope(slang_operation *oper,
-                    slang_variable_scope *oldScope,
-                    slang_variable_scope *newScope)
-{
-   GLuint i;
-
-   if (oper->locals != newScope &&
-       oper->locals->outer_scope == oldScope) {
-      /* found.  replace old w/ new */
-      oper->locals->outer_scope = newScope;
-   }
-
-   if (oper->type == SLANG_OPER_VARIABLE_DECL) {
-      /* search/replace in the initializer */
-      slang_variable *var;
-      var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE);
-      if (var && var->initializer) {
-         slang_replace_scope(var->initializer, oldScope, newScope);
-      }
-   }
-
-   /* search/replace in children */
-   for (i = 0; i < oper->num_children; i++) {
-      slang_replace_scope(&oper->children[i], oldScope, newScope);
-   }
-}
-
-
-/**
- * Recursively copy a slang_operation node.
- * \param x  copy target
- * \param y  copy source
- * \return GL_TRUE for success, GL_FALSE if failure
- */
-GLboolean
-slang_operation_copy(slang_operation * x, const slang_operation * y)
-{
-   slang_operation z;
-   GLuint i;
-
-   if (!slang_operation_construct(&z))
-      return GL_FALSE;
-   z.type = y->type;
-   if (y->num_children > 0) {
-      z.children = (slang_operation *)
-         _slang_alloc(y->num_children * sizeof(slang_operation));
-      if (z.children == NULL) {
-         slang_operation_destruct(&z);
-         return GL_FALSE;
-      }
-   }
-   for (z.num_children = 0; z.num_children < y->num_children;
-        z.num_children++) {
-      if (!slang_operation_construct(&z.children[z.num_children])) {
-         slang_operation_destruct(&z);
-         return GL_FALSE;
-      }
-   }
-   for (i = 0; i < z.num_children; i++) {
-      if (!slang_operation_copy(&z.children[i], &y->children[i])) {
-         slang_operation_destruct(&z);
-         return GL_FALSE;
-      }
-   }
-   z.literal[0] = y->literal[0];
-   z.literal[1] = y->literal[1];
-   z.literal[2] = y->literal[2];
-   z.literal[3] = y->literal[3];
-   z.literal_size = y->literal_size;
-   assert(y->literal_size >= 1);
-   assert(y->literal_size <= 4);
-   z.a_id = y->a_id;
-   if (y->locals) {
-      if (!slang_variable_scope_copy(z.locals, y->locals)) {
-         slang_operation_destruct(&z);
-         return GL_FALSE;
-      }
-   }
-
-   /* update scoping for children */
-   for (i = 0; i < y->num_children; i++) {
-      if (y->children[i].locals &&
-          y->children[i].locals->outer_scope == y->locals) {
-         z.children[i].locals->outer_scope = z.locals;
-      }
-   }
-
-#if 0
-   z.var = y->var;
-   z.fun = y->fun;
-#endif
-   slang_operation_destruct(x);
-   *x = z;
-
-   /* If this operation declares a new scope, we need to make sure
-    * all children point to it, not the original operation's scope!
-    */
-   if (x->type == SLANG_OPER_BLOCK_NEW_SCOPE ||
-       x->type == SLANG_OPER_WHILE ||
-       x->type == SLANG_OPER_FOR) {
-      slang_replace_scope(x, y->locals, x->locals);
-   }
-
-   return GL_TRUE;
-}
-
-
-slang_operation *
-slang_operation_new(GLuint count)
-{
-   slang_operation *ops
-       = (slang_operation *) _slang_alloc(count * sizeof(slang_operation));
-   assert(count > 0);
-   if (ops) {
-      GLuint i;
-      for (i = 0; i < count; i++)
-         slang_operation_construct(ops + i);
-   }
-   return ops;
-}
-
-
-/**
- * Delete operation and all children
- */
-void
-slang_operation_delete(slang_operation *oper)
-{
-   slang_operation_destruct(oper);
-   _slang_free(oper);
-}
-
-
-void
-slang_operation_free_children(slang_operation *oper)
-{
-   GLuint i;
-   for (i = 0; i < slang_oper_num_children(oper); i++) {
-      slang_operation *child = slang_oper_child(oper, i);
-      slang_operation_destruct(child);
-   }
-   _slang_free(oper->children);
-   oper->children = NULL;
-   oper->num_children = 0;
-}
-
-
-slang_operation *
-slang_operation_grow(GLuint *numChildren, slang_operation **children)
-{
-   slang_operation *ops;
-
-   ops = (slang_operation *)
-      _slang_realloc(*children,
-                     *numChildren * sizeof(slang_operation),
-                     (*numChildren + 1) * sizeof(slang_operation));
-   if (ops) {
-      slang_operation *newOp = ops + *numChildren;
-      if (!slang_operation_construct(newOp)) {
-         _slang_free(ops);
-         *children = NULL;
-         return NULL;
-      }
-      *children = ops;
-      (*numChildren)++;
-      return newOp;
-   }
-   return NULL;
-}
-
-/**
- * Insert a new slang_operation into an array.
- * \param numElements  pointer to current array size (in/out)
- * \param array  address of the array (in/out)
- * \param pos  position to insert new element
- * \return  pointer to the new operation/element
- */
-slang_operation *
-slang_operation_insert(GLuint *numElements, slang_operation **array,
-                       GLuint pos)
-{
-   slang_operation *ops;
-
-   assert(pos <= *numElements);
-
-   ops = (slang_operation *)
-      _slang_alloc((*numElements + 1) * sizeof(slang_operation));
-   if (ops) {
-      slang_operation *newOp;
-      newOp = ops + pos;
-      if (pos > 0)
-         memcpy(ops, *array, pos * sizeof(slang_operation));
-      if (pos < *numElements)
-         memcpy(newOp + 1, (*array) + pos,
-                (*numElements - pos) * sizeof(slang_operation));
-
-      if (!slang_operation_construct(newOp)) {
-         _slang_free(ops);
-         *numElements = 0;
-         *array = NULL;
-         return NULL;
-      }
-      if (*array)
-         _slang_free(*array);
-      *array = ops;
-      (*numElements)++;
-      return newOp;
-   }
-   return NULL;
-}
-
-
-/**
- * Add/insert new child into given node at given position.
- * \return pointer to the new child node
- */
-slang_operation *
-slang_operation_insert_child(slang_operation *oper, GLuint pos)
-{
-   slang_operation *newOp;
-
-   newOp = slang_operation_insert(&oper->num_children,
-                                  &oper->children,
-                                  pos);
-   if (newOp) {
-      newOp->locals->outer_scope = oper->locals;
-   }
-
-   return newOp;
-}
-
-
-void
-_slang_operation_swap(slang_operation *oper0, slang_operation *oper1)
-{
-   slang_operation tmp = *oper0;
-   *oper0 = *oper1;
-   *oper1 = tmp;
-}
-
-
-void
-slang_operation_add_children(slang_operation *oper, GLuint num_children)
-{
-   GLuint i;
-   assert(oper->num_children == 0);
-   assert(oper->children == NULL);
-   oper->num_children = num_children;
-   oper->children = slang_operation_new(num_children);
-   for (i = 0; i < num_children; i++) {
-      oper->children[i].locals = _slang_variable_scope_new(oper->locals);
-   }
-}
-
diff --git a/src/mesa/shader/slang/slang_compile_operation.h b/src/mesa/shader/slang/slang_compile_operation.h
deleted file mode 100644 (file)
index 1f15c19..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.2
- *
- * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef SLANG_COMPILE_OPERATION_H
-#define SLANG_COMPILE_OPERATION_H
-
-
-/**
- * Types of slang operations.
- * These are the types of the AST (abstract syntax tree) nodes.
- * [foo] indicates a sub-tree or reference to another type of node
- */
-typedef enum slang_operation_type_
-{
-   SLANG_OPER_NONE,
-   SLANG_OPER_BLOCK_NO_NEW_SCOPE,       /* "{" sequence "}" */
-   SLANG_OPER_BLOCK_NEW_SCOPE,  /* "{" sequence "}" */
-   SLANG_OPER_VARIABLE_DECL,    /* [type] [var] or [var] = [expr] */
-   SLANG_OPER_ASM,
-   SLANG_OPER_BREAK,            /* "break" statement */
-   SLANG_OPER_CONTINUE,         /* "continue" statement */
-   SLANG_OPER_DISCARD,          /* "discard" (kill fragment) statement */
-   SLANG_OPER_RETURN,           /* "return" [expr]  */
-   SLANG_OPER_RETURN_INLINED,   /* "return" [expr] from inlined function  */
-   SLANG_OPER_LABEL,            /* a jump target */
-   SLANG_OPER_EXPRESSION,       /* [expr] */
-   SLANG_OPER_IF,               /* "if" [0] then [1] else [2] */
-   SLANG_OPER_WHILE,            /* "while" [cond] [body] */
-   SLANG_OPER_DO,               /* "do" [body] "while" [cond] */
-   SLANG_OPER_FOR,              /* "for" [init] [while] [incr] [body] */
-   SLANG_OPER_VOID,             /* nop */
-   SLANG_OPER_LITERAL_BOOL,     /* "true" or "false" */
-   SLANG_OPER_LITERAL_INT,      /* integer literal */
-   SLANG_OPER_LITERAL_FLOAT,    /* float literal */
-   SLANG_OPER_IDENTIFIER,       /* var name, func name, etc */
-   SLANG_OPER_SEQUENCE,         /* [expr] "," [expr] "," etc */
-   SLANG_OPER_ASSIGN,           /* [var] "=" [expr] */
-   SLANG_OPER_ADDASSIGN,        /* [var] "+=" [expr] */
-   SLANG_OPER_SUBASSIGN,        /* [var] "-=" [expr] */
-   SLANG_OPER_MULASSIGN,        /* [var] "*=" [expr] */
-   SLANG_OPER_DIVASSIGN,        /* [var] "/=" [expr] */
-   /*SLANG_OPER_MODASSIGN, */
-   /*SLANG_OPER_LSHASSIGN, */
-   /*SLANG_OPER_RSHASSIGN, */
-   /*SLANG_OPER_ORASSIGN, */
-   /*SLANG_OPER_XORASSIGN, */
-   /*SLANG_OPER_ANDASSIGN, */
-   SLANG_OPER_SELECT,           /* [expr] "?" [expr] ":" [expr] */
-   SLANG_OPER_LOGICALOR,        /* [expr] "||" [expr] */
-   SLANG_OPER_LOGICALXOR,       /* [expr] "^^" [expr] */
-   SLANG_OPER_LOGICALAND,       /* [expr] "&&" [expr] */
-   /*SLANG_OPER_BITOR, */
-   /*SLANG_OPER_BITXOR, */
-   /*SLANG_OPER_BITAND, */
-   SLANG_OPER_EQUAL,            /* [expr] "==" [expr] */
-   SLANG_OPER_NOTEQUAL,         /* [expr] "!=" [expr] */
-   SLANG_OPER_LESS,             /* [expr] "<" [expr] */
-   SLANG_OPER_GREATER,          /* [expr] ">" [expr] */
-   SLANG_OPER_LESSEQUAL,        /* [expr] "<=" [expr] */
-   SLANG_OPER_GREATEREQUAL,     /* [expr] ">=" [expr] */
-   /*SLANG_OPER_LSHIFT, */
-   /*SLANG_OPER_RSHIFT, */
-   SLANG_OPER_ADD,              /* [expr] "+" [expr] */
-   SLANG_OPER_SUBTRACT,         /* [expr] "-" [expr] */
-   SLANG_OPER_MULTIPLY,         /* [expr] "*" [expr] */
-   SLANG_OPER_DIVIDE,           /* [expr] "/" [expr] */
-   /*SLANG_OPER_MODULUS, */
-   SLANG_OPER_PREINCREMENT,     /* "++" [var] */
-   SLANG_OPER_PREDECREMENT,     /* "--" [var] */
-   SLANG_OPER_PLUS,             /* "-" [expr] */
-   SLANG_OPER_MINUS,            /* "+" [expr] */
-   /*SLANG_OPER_COMPLEMENT, */
-   SLANG_OPER_NOT,              /* "!" [expr] */
-   SLANG_OPER_SUBSCRIPT,        /* [expr] "[" [expr] "]" */
-   SLANG_OPER_CALL,             /* [func name] [param] [param] [...] */
-   SLANG_OPER_NON_INLINED_CALL, /* a real function call */
-   SLANG_OPER_METHOD,           /* method call, such as  v.length() */
-   SLANG_OPER_FIELD,            /* i.e.: ".next" or ".xzy" or ".xxx" etc */
-   SLANG_OPER_POSTINCREMENT,    /* [var] "++" */
-   SLANG_OPER_POSTDECREMENT     /* [var] "--" */
-} slang_operation_type;
-
-
-/**
- * A slang_operation is basically a compiled instruction (such as assignment,
- * a while-loop, a conditional, a multiply, a function call, etc).
- * The AST (abstract syntax tree) is built from these nodes.
- * NOTE: This structure could have been implemented as a union of simpler
- * structs which would correspond to the operation types above.
- */
-typedef struct slang_operation_
-{
-   slang_operation_type type;
-   struct slang_operation_ *children;
-   GLuint num_children;
-   GLfloat literal[4];           /**< Used for float, int and bool values */
-   GLuint literal_size;          /**< 1, 2, 3, or 4 */
-   slang_atom a_id;              /**< type: asm, identifier, call, field */
-   slang_atom a_obj;             /**< object in a method call */
-   slang_variable_scope *locals; /**< local vars for scope */
-   struct slang_function_ *fun;  /**< If type == SLANG_OPER_CALL */
-   struct slang_variable_ *var;  /**< If type == slang_oper_identier */
-   struct slang_label_ *label;   /**< If type == SLANG_OPER_LABEL */
-   /** If type==SLANG_OPER_CALL and we're calling an array constructor,
-    * for which there's no real function, we need to have a flag to
-    * indicate such.  num_children indicates number of elements.
-    */
-   GLboolean array_constructor;
-} slang_operation;
-
-
-extern GLboolean
-slang_operation_construct(slang_operation *);
-
-extern void
-slang_operation_destruct(slang_operation *);
-
-extern void
-slang_replace_scope(slang_operation *oper,
-                    slang_variable_scope *oldScope,
-                    slang_variable_scope *newScope);
-
-extern GLboolean
-slang_operation_copy(slang_operation *, const slang_operation *);
-
-extern slang_operation *
-slang_operation_new(GLuint count);
-
-extern void
-slang_operation_delete(slang_operation *oper);
-
-extern void
-slang_operation_free_children(slang_operation *oper);
-
-extern slang_operation *
-slang_operation_grow(GLuint *numChildren, slang_operation **children);
-
-extern slang_operation *
-slang_operation_insert(GLuint *numChildren, slang_operation **children,
-                       GLuint pos);
-
-extern slang_operation *
-slang_operation_insert_child(slang_operation *oper, GLuint pos);
-
-extern void
-_slang_operation_swap(slang_operation *oper0, slang_operation *oper1);
-
-
-extern void
-slang_operation_add_children(slang_operation *oper, GLuint num_children);
-
-
-/** Return number of children of given node */
-static INLINE GLuint
-slang_oper_num_children(const slang_operation *oper)
-{
-   return oper->num_children;
-}
-
-/** Return child of given operation node */
-static INLINE slang_operation *
-slang_oper_child(slang_operation *oper, GLuint child)
-{
-   assert(child < oper->num_children);
-   return &oper->children[child];
-}
-
-
-/** Return child of given operation node, const version */
-static INLINE const slang_operation *
-slang_oper_child_const(const slang_operation *oper, GLuint child)
-{
-   assert(child < oper->num_children);
-   return &oper->children[child];
-}
-
-
-/** Init oper to a boolean literal. */
-static INLINE void
-slang_operation_literal_bool(slang_operation *oper, GLboolean value)
-{
-   oper->type = SLANG_OPER_LITERAL_BOOL;
-   oper->literal[0] =
-   oper->literal[1] =
-   oper->literal[2] =
-   oper->literal[3] = (float) value;
-   oper->literal_size = 1;
-}
-
-
-/** Init oper to an int literal. */
-static INLINE void
-slang_operation_literal_int(slang_operation *oper, GLint value)
-{
-   oper->type = SLANG_OPER_LITERAL_INT;
-   oper->literal[0] =
-   oper->literal[1] =
-   oper->literal[2] =
-   oper->literal[3] = (float) value;
-   oper->literal_size = 1;
-}
-
-
-#endif /* SLANG_COMPILE_OPERATION_H */
diff --git a/src/mesa/shader/slang/slang_compile_struct.c b/src/mesa/shader/slang/slang_compile_struct.c
deleted file mode 100644 (file)
index e6c3873..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.3
- *
- * Copyright (C) 2005-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 slang_compile_struct.c
- * slang front-end compiler
- * \author Michal Krol
- */
-
-#include "main/imports.h"
-#include "slang_mem.h"
-#include "slang_compile.h"
-
-
-GLvoid
-_slang_struct_scope_ctr(slang_struct_scope * self)
-{
-   self->structs = NULL;
-   self->num_structs = 0;
-   self->outer_scope = NULL;
-}
-
-void
-slang_struct_scope_destruct(slang_struct_scope * scope)
-{
-   GLuint i;
-
-   for (i = 0; i < scope->num_structs; i++)
-      slang_struct_destruct(scope->structs + i);
-   _slang_free(scope->structs);
-   /* do not free scope->outer_scope */
-}
-
-int
-slang_struct_scope_copy(slang_struct_scope * x, const slang_struct_scope * y)
-{
-   slang_struct_scope z;
-   GLuint i;
-
-   _slang_struct_scope_ctr(&z);
-   z.structs = (slang_struct *)
-      _slang_alloc(y->num_structs * sizeof(slang_struct));
-   if (z.structs == NULL) {
-      slang_struct_scope_destruct(&z);
-      return 0;
-   }
-   for (z.num_structs = 0; z.num_structs < y->num_structs; z.num_structs++)
-      if (!slang_struct_construct(&z.structs[z.num_structs])) {
-         slang_struct_scope_destruct(&z);
-         return 0;
-      }
-   for (i = 0; i < z.num_structs; i++)
-      if (!slang_struct_copy(&z.structs[i], &y->structs[i])) {
-         slang_struct_scope_destruct(&z);
-         return 0;
-      }
-   z.outer_scope = y->outer_scope;
-   slang_struct_scope_destruct(x);
-   *x = z;
-   return 1;
-}
-
-slang_struct *
-slang_struct_scope_find(slang_struct_scope * stru, slang_atom a_name,
-                        int all_scopes)
-{
-   GLuint i;
-
-   for (i = 0; i < stru->num_structs; i++)
-      if (a_name == stru->structs[i].a_name)
-         return &stru->structs[i];
-   if (all_scopes && stru->outer_scope != NULL)
-      return slang_struct_scope_find(stru->outer_scope, a_name, 1);
-   return NULL;
-}
-
-/* slang_struct */
-
-int
-slang_struct_construct(slang_struct * stru)
-{
-   stru->a_name = SLANG_ATOM_NULL;
-   stru->fields = (slang_variable_scope *)
-      _slang_alloc(sizeof(slang_variable_scope));
-   if (stru->fields == NULL)
-      return 0;
-   _slang_variable_scope_ctr(stru->fields);
-
-   stru->structs =
-      (slang_struct_scope *) _slang_alloc(sizeof(slang_struct_scope));
-   if (stru->structs == NULL) {
-      slang_variable_scope_destruct(stru->fields);
-      _slang_free(stru->fields);
-      return 0;
-   }
-   _slang_struct_scope_ctr(stru->structs);
-   stru->constructor = NULL;
-   return 1;
-}
-
-void
-slang_struct_destruct(slang_struct * stru)
-{
-   slang_variable_scope_destruct(stru->fields);
-   _slang_free(stru->fields);
-   slang_struct_scope_destruct(stru->structs);
-   _slang_free(stru->structs);
-}
-
-int
-slang_struct_copy(slang_struct * x, const slang_struct * y)
-{
-   slang_struct z;
-
-   if (!slang_struct_construct(&z))
-      return 0;
-   z.a_name = y->a_name;
-   if (!slang_variable_scope_copy(z.fields, y->fields)) {
-      slang_struct_destruct(&z);
-      return 0;
-   }
-   if (!slang_struct_scope_copy(z.structs, y->structs)) {
-      slang_struct_destruct(&z);
-      return 0;
-   }
-   slang_struct_destruct(x);
-   *x = z;
-   return 1;
-}
-
-int
-slang_struct_equal(const slang_struct * x, const slang_struct * y)
-{
-   GLuint i;
-
-   if (x->fields->num_variables != y->fields->num_variables)
-      return 0;
-
-   for (i = 0; i < x->fields->num_variables; i++) {
-      const slang_variable *varx = x->fields->variables[i];
-      const slang_variable *vary = y->fields->variables[i];
-
-      if (varx->a_name != vary->a_name)
-         return 0;
-      if (!slang_type_specifier_equal(&varx->type.specifier,
-                                      &vary->type.specifier))
-         return 0;
-      if (varx->type.specifier.type == SLANG_SPEC_ARRAY)
-         if (varx->array_len != vary->array_len)
-            return GL_FALSE;
-   }
-   return 1;
-}
diff --git a/src/mesa/shader/slang/slang_compile_struct.h b/src/mesa/shader/slang/slang_compile_struct.h
deleted file mode 100644 (file)
index 90c5512..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5
- *
- * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#if !defined SLANG_COMPILE_STRUCT_H
-#define SLANG_COMPILE_STRUCT_H
-
-#if defined __cplusplus
-extern "C" {
-#endif
-
-struct slang_function_;
-
-typedef struct slang_struct_scope_
-{
-   struct slang_struct_ *structs;
-   GLuint num_structs;
-   struct slang_struct_scope_ *outer_scope;
-} slang_struct_scope;
-
-extern GLvoid
-_slang_struct_scope_ctr (slang_struct_scope *);
-
-void slang_struct_scope_destruct (slang_struct_scope *);
-int slang_struct_scope_copy (slang_struct_scope *, const slang_struct_scope *);
-struct slang_struct_ *slang_struct_scope_find (slang_struct_scope *, slang_atom, int);
-
-typedef struct slang_struct_
-{
-   slang_atom a_name;
-   struct slang_variable_scope_ *fields;
-   slang_struct_scope *structs;
-   struct slang_function_ *constructor;
-} slang_struct;
-
-int slang_struct_construct (slang_struct *);
-void slang_struct_destruct (slang_struct *);
-int slang_struct_copy (slang_struct *, const slang_struct *);
-int slang_struct_equal (const slang_struct *, const slang_struct *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/src/mesa/shader/slang/slang_compile_variable.c b/src/mesa/shader/slang/slang_compile_variable.c
deleted file mode 100644 (file)
index 23c08a9..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.3
- *
- * Copyright (C) 2005-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 slang_compile_variable.c
- * slang front-end compiler
- * \author Michal Krol
- */
-
-#include "main/imports.h"
-#include "slang_compile.h"
-#include "slang_mem.h"
-
-
-static slang_variable *
-slang_variable_new(void)
-{
-   slang_variable *v = (slang_variable *) _slang_alloc(sizeof(slang_variable));
-   if (v) {
-      if (!slang_variable_construct(v)) {
-         _slang_free(v);
-         v = NULL;
-      }
-   }
-   return v;
-}
-
-
-static void
-slang_variable_delete(slang_variable * var)
-{
-   slang_variable_destruct(var);
-   _slang_free(var);
-}
-
-
-/*
- * slang_variable_scope
- */
-
-slang_variable_scope *
-_slang_variable_scope_new(slang_variable_scope *parent)
-{
-   slang_variable_scope *s;
-   s = (slang_variable_scope *) _slang_alloc(sizeof(slang_variable_scope));
-   if (s)
-      s->outer_scope = parent;
-   return s;
-}
-
-
-GLvoid
-_slang_variable_scope_ctr(slang_variable_scope * self)
-{
-   self->variables = NULL;
-   self->num_variables = 0;
-   self->outer_scope = NULL;
-}
-
-void
-slang_variable_scope_destruct(slang_variable_scope * scope)
-{
-   unsigned int i;
-
-   if (!scope)
-      return;
-   for (i = 0; i < scope->num_variables; i++) {
-      if (scope->variables[i])
-         slang_variable_delete(scope->variables[i]);
-   }
-   _slang_free(scope->variables);
-   /* do not free scope->outer_scope */
-}
-
-int
-slang_variable_scope_copy(slang_variable_scope * x,
-                          const slang_variable_scope * y)
-{
-   slang_variable_scope z;
-   unsigned int i;
-
-   _slang_variable_scope_ctr(&z);
-   z.variables = (slang_variable **)
-      _slang_alloc(y->num_variables * sizeof(slang_variable *));
-   if (z.variables == NULL) {
-      slang_variable_scope_destruct(&z);
-      return 0;
-   }
-   for (z.num_variables = 0; z.num_variables < y->num_variables;
-        z.num_variables++) {
-      z.variables[z.num_variables] = slang_variable_new();
-      if (!z.variables[z.num_variables]) {
-         slang_variable_scope_destruct(&z);
-         return 0;
-      }
-   }
-   for (i = 0; i < z.num_variables; i++) {
-      if (!slang_variable_copy(z.variables[i], y->variables[i])) {
-         slang_variable_scope_destruct(&z);
-         return 0;
-      }
-   }
-   z.outer_scope = y->outer_scope;
-   slang_variable_scope_destruct(x);
-   *x = z;
-   return 1;
-}
-
-
-/**
- * Grow the variable list by one.
- * \return  pointer to space for the new variable (will be initialized)
- */
-slang_variable *
-slang_variable_scope_grow(slang_variable_scope *scope)
-{
-   const int n = scope->num_variables;
-   scope->variables = (slang_variable **)
-         _slang_realloc(scope->variables,
-                        n * sizeof(slang_variable *),
-                        (n + 1) * sizeof(slang_variable *));
-   if (!scope->variables)
-      return NULL;
-
-   scope->num_variables++;
-
-   scope->variables[n] = slang_variable_new();
-   if (!scope->variables[n])
-      return NULL;
-
-   return scope->variables[n];
-}
-
-
-
-/* slang_variable */
-
-int
-slang_variable_construct(slang_variable * var)
-{
-   if (!slang_fully_specified_type_construct(&var->type))
-      return 0;
-   var->a_name = SLANG_ATOM_NULL;
-   var->array_len = 0;
-   var->initializer = NULL;
-   var->size = 0;
-   var->isTemp = GL_FALSE;
-   var->store = NULL;
-   var->declared = 0;
-   return 1;
-}
-
-
-void
-slang_variable_destruct(slang_variable * var)
-{
-   slang_fully_specified_type_destruct(&var->type);
-   if (var->initializer != NULL) {
-      slang_operation_destruct(var->initializer);
-      _slang_free(var->initializer);
-   }
-#if 0
-   if (var->aux) {
-      free(var->aux);
-   }
-#endif
-}
-
-
-int
-slang_variable_copy(slang_variable * x, const slang_variable * y)
-{
-   slang_variable z;
-
-   if (!slang_variable_construct(&z))
-      return 0;
-   if (!slang_fully_specified_type_copy(&z.type, &y->type)) {
-      slang_variable_destruct(&z);
-      return 0;
-   }
-   z.a_name = y->a_name;
-   z.array_len = y->array_len;
-   if (y->initializer != NULL) {
-      z.initializer
-         = (slang_operation *) _slang_alloc(sizeof(slang_operation));
-      if (z.initializer == NULL) {
-         slang_variable_destruct(&z);
-         return 0;
-      }
-      if (!slang_operation_construct(z.initializer)) {
-         _slang_free(z.initializer);
-         slang_variable_destruct(&z);
-         return 0;
-      }
-      if (!slang_operation_copy(z.initializer, y->initializer)) {
-         slang_variable_destruct(&z);
-         return 0;
-      }
-   }
-   z.size = y->size;
-   slang_variable_destruct(x);
-   *x = z;
-   return 1;
-}
-
-
-/**
- * Search for named variable in given scope.
- * \param all  if true, search parent scopes too.
- */
-slang_variable *
-_slang_variable_locate(const slang_variable_scope * scope,
-                       const slang_atom a_name, GLboolean all)
-{
-   while (scope) {
-      GLuint i;
-      for (i = 0; i < scope->num_variables; i++)
-         if (a_name == scope->variables[i]->a_name)
-            return scope->variables[i];
-      if (all)
-         scope = scope->outer_scope;
-      else
-         scope = NULL;
-   }
-   return NULL;
-}
diff --git a/src/mesa/shader/slang/slang_compile_variable.h b/src/mesa/shader/slang/slang_compile_variable.h
deleted file mode 100644 (file)
index 5c9d248..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.2
- *
- * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef SLANG_COMPILE_VARIABLE_H
-#define SLANG_COMPILE_VARIABLE_H
-
-
-struct slang_ir_storage_;
-
-
-/**
- * A shading language program variable.
- */
-typedef struct slang_variable_
-{
-   slang_fully_specified_type type; /**< Variable's data type */
-   slang_atom a_name;               /**< The variable's name (char *) */
-   GLuint array_len;                /**< only if type == SLANG_SPEC_ARRAy */
-   struct slang_operation_ *initializer; /**< Optional initializer code */
-   GLuint size;                     /**< Variable's size in bytes */
-   GLboolean is_global;
-   GLboolean isTemp;                /**< a named temporary (__resultTmp) */
-   GLboolean declared;              /**< has the var been declared? */
-   struct slang_ir_storage_ *store; /**< Storage for this var */
-} slang_variable;
-
-
-/**
- * Basically a list of variables, with a pointer to the parent scope.
- */
-typedef struct slang_variable_scope_
-{
-   slang_variable **variables;  /**< Array [num_variables] of ptrs to vars */
-   GLuint num_variables;
-   struct slang_variable_scope_ *outer_scope;
-} slang_variable_scope;
-
-
-extern slang_variable_scope *
-_slang_variable_scope_new(slang_variable_scope *parent);
-
-extern GLvoid
-_slang_variable_scope_ctr(slang_variable_scope *);
-
-extern void
-slang_variable_scope_destruct(slang_variable_scope *);
-
-extern int
-slang_variable_scope_copy(slang_variable_scope *,
-                          const slang_variable_scope *);
-
-extern slang_variable *
-slang_variable_scope_grow(slang_variable_scope *);
-
-extern int
-slang_variable_construct(slang_variable *);
-
-extern void
-slang_variable_destruct(slang_variable *);
-
-extern int
-slang_variable_copy(slang_variable *, const slang_variable *);
-
-extern slang_variable *
-_slang_variable_locate(const slang_variable_scope *, const slang_atom a_name,
-                       GLboolean all);
-
-
-#endif /* SLANG_COMPILE_VARIABLE_H */
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
deleted file mode 100644 (file)
index 4d4c611..0000000
+++ /dev/null
@@ -1,2666 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2005-2008  Brian Paul   All Rights Reserved.
- * Copyright (C) 2008 VMware, 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
- * 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 slang_emit.c
- * Emit program instructions (PI code) from IR trees.
- * \author Brian Paul
- */
-
-/***
- *** NOTES
- ***
- *** To emit GPU instructions, we basically just do an in-order traversal
- *** of the IR tree.
- ***/
-
-
-#include "main/imports.h"
-#include "main/context.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"
-
-
-#define PEEPHOLE_OPTIMIZATIONS 1
-#define ANNOTATE 0
-
-
-typedef struct
-{
-   slang_info_log *log;
-   slang_var_table *vt;
-   struct gl_program *prog;
-   struct gl_program **Subroutines;
-   GLuint NumSubroutines;
-
-   GLuint MaxInstructions;  /**< size of prog->Instructions[] buffer */
-
-   GLboolean UnresolvedFunctions;
-
-   /* code-gen options */
-   GLboolean EmitHighLevelInstructions;
-   GLboolean EmitCondCodes;
-   GLboolean EmitComments;
-   GLboolean EmitBeginEndSub; /* XXX TEMPORARY */
-} slang_emit_info;
-
-
-
-static struct gl_program *
-new_subroutine(slang_emit_info *emitInfo, GLuint *id)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   const GLuint n = emitInfo->NumSubroutines;
-
-   emitInfo->Subroutines = (struct gl_program **)
-      _mesa_realloc(emitInfo->Subroutines,
-                    n * sizeof(struct gl_program *),
-                    (n + 1) * sizeof(struct gl_program *));
-   emitInfo->Subroutines[n] = ctx->Driver.NewProgram(ctx, emitInfo->prog->Target, 0);
-   emitInfo->Subroutines[n]->Parameters = emitInfo->prog->Parameters;
-   emitInfo->NumSubroutines++;
-   *id = n;
-   return emitInfo->Subroutines[n];
-}
-
-
-/**
- * Convert a writemask to a swizzle.  Used for testing cond codes because
- * we only want to test the cond code component(s) that was set by the
- * previous instruction.
- */
-static GLuint
-writemask_to_swizzle(GLuint writemask)
-{
-   if (writemask == WRITEMASK_X)
-      return SWIZZLE_XXXX;
-   if (writemask == WRITEMASK_Y)
-      return SWIZZLE_YYYY;
-   if (writemask == WRITEMASK_Z)
-      return SWIZZLE_ZZZZ;
-   if (writemask == WRITEMASK_W)
-      return SWIZZLE_WWWW;
-   return SWIZZLE_XYZW;  /* shouldn't be hit */
-}
-
-
-/**
- * Convert a swizzle mask to a writemask.
- * Note that the slang_ir_storage->Swizzle field can represent either a
- * swizzle mask or a writemask, depending on how it's used.  For example,
- * when we parse "direction.yz" alone, we don't know whether .yz is a
- * writemask or a swizzle.  In this case, we encode ".yz" in store->Swizzle
- * as a swizzle mask (.yz?? actually).  Later, if direction.yz is used as
- * an R-value, we use store->Swizzle as-is.  Otherwise, if direction.yz is
- * used as an L-value, we convert it to a writemask.
- */
-static GLuint
-swizzle_to_writemask(GLuint swizzle)
-{
-   GLuint i, writemask = 0x0;
-   for (i = 0; i < 4; i++) {
-      GLuint swz = GET_SWZ(swizzle, i);
-      if (swz <= SWIZZLE_W) {
-         writemask |= (1 << swz);
-      }
-   }
-   return writemask;
-}
-
-
-/**
- * Swizzle a swizzle (function composition).
- * That is, return swz2(swz1), or said another way: swz1.szw2
- * Example: swizzle_swizzle(".zwxx", ".xxyw") yields ".zzwx"
- */
-GLuint
-_slang_swizzle_swizzle(GLuint swz1, GLuint swz2)
-{
-   GLuint i, swz, s[4];
-   for (i = 0; i < 4; i++) {
-      GLuint c = GET_SWZ(swz2, i);
-      if (c <= SWIZZLE_W)
-         s[i] = GET_SWZ(swz1, c);
-      else
-         s[i] = c;
-   }
-   swz = MAKE_SWIZZLE4(s[0], s[1], s[2], s[3]);
-   return swz;
-}
-
-
-/**
- * Return the default swizzle mask for accessing a variable of the
- * given size (in floats).  If size = 1, comp is used to identify
- * which component [0..3] of the register holds the variable.
- */
-GLuint
-_slang_var_swizzle(GLint size, GLint comp)
-{
-   switch (size) {
-   case 1:
-      return MAKE_SWIZZLE4(comp, SWIZZLE_NIL, SWIZZLE_NIL, SWIZZLE_NIL);
-   case 2:
-      return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_NIL, SWIZZLE_NIL);
-   case 3:
-      return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_NIL);
-   default:
-      return SWIZZLE_XYZW;
-   }
-}
-
-
-
-/**
- * Allocate storage for the given node (if it hasn't already been allocated).
- *
- * Typically this is temporary storage for an intermediate result (such as
- * for a multiply or add, etc).
- *
- * If n->Store does not exist it will be created and will be of the size
- * specified by defaultSize.
- */
-static GLboolean
-alloc_node_storage(slang_emit_info *emitInfo, slang_ir_node *n,
-                   GLint defaultSize)
-{
-   assert(!n->Var);
-   if (!n->Store) {
-      assert(defaultSize > 0);
-      n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, defaultSize);
-      if (!n->Store) {
-         return GL_FALSE;
-      }
-   }
-
-   /* now allocate actual register(s).  I.e. set n->Store->Index >= 0 */
-   if (n->Store->Index < 0) {
-      if (!_slang_alloc_temp(emitInfo->vt, n->Store)) {
-         slang_info_log_error(emitInfo->log,
-                              "Ran out of registers, too many temporaries");
-         _slang_free(n->Store);
-         n->Store = NULL;
-         return GL_FALSE;
-      }
-   }
-   return GL_TRUE;
-}
-
-
-/**
- * Free temporary storage, if n->Store is, in fact, temp storage.
- * Otherwise, no-op.
- */
-static void
-free_node_storage(slang_var_table *vt, slang_ir_node *n)
-{
-   if (n->Store->File == PROGRAM_TEMPORARY &&
-       n->Store->Index >= 0 &&
-       n->Opcode != IR_SWIZZLE) {
-      if (_slang_is_temp(vt, n->Store)) {
-         _slang_free_temp(vt, n->Store);
-         n->Store->Index = -1;
-         n->Store = NULL; /* XXX this may not be needed */
-      }
-   }
-}
-
-
-/**
- * Helper function to allocate a short-term temporary.
- * Free it with _slang_free_temp().
- */
-static GLboolean
-alloc_local_temp(slang_emit_info *emitInfo, slang_ir_storage *temp, GLint size)
-{
-   assert(size >= 1);
-   assert(size <= 4);
-   memset(temp, 0, sizeof(*temp));
-   temp->Size = size;
-   temp->File = PROGRAM_TEMPORARY;
-   temp->Index = -1;
-   return _slang_alloc_temp(emitInfo->vt, temp);
-}
-
-
-/**
- * Remove any SWIZZLE_NIL terms from given swizzle mask.
- * For a swizzle like .z??? generate .zzzz (replicate single component).
- * Else, for .wx?? generate .wxzw (insert default component for the position).
- */
-static GLuint
-fix_swizzle(GLuint swizzle)
-{
-   GLuint c0 = GET_SWZ(swizzle, 0),
-      c1 = GET_SWZ(swizzle, 1),
-      c2 = GET_SWZ(swizzle, 2),
-      c3 = GET_SWZ(swizzle, 3);
-   if (c1 == SWIZZLE_NIL && c2 == SWIZZLE_NIL && c3 == SWIZZLE_NIL) {
-      /* smear first component across all positions */
-      c1 = c2 = c3 = c0;
-   }
-   else {
-      /* insert default swizzle components */
-      if (c0 == SWIZZLE_NIL)
-         c0 = SWIZZLE_X;
-      if (c1 == SWIZZLE_NIL)
-         c1 = SWIZZLE_Y;
-      if (c2 == SWIZZLE_NIL)
-         c2 = SWIZZLE_Z;
-      if (c3 == SWIZZLE_NIL)
-         c3 = SWIZZLE_W;
-   }
-   return MAKE_SWIZZLE4(c0, c1, c2, c3);
-}
-
-
-
-/**
- * Convert IR storage to an instruction dst register.
- */
-static void
-storage_to_dst_reg(struct prog_dst_register *dst, const slang_ir_storage *st)
-{
-   const GLboolean relAddr = st->RelAddr;
-   const GLint size = st->Size;
-   GLint index = st->Index;
-   GLuint swizzle = st->Swizzle;
-
-   assert(index >= 0);
-   /* if this is storage relative to some parent storage, walk up the tree */
-   while (st->Parent) {
-      st = st->Parent;
-      assert(st->Index >= 0);
-      index += st->Index;
-      swizzle = _slang_swizzle_swizzle(st->Swizzle, swizzle);
-   }
-
-   assert(st->File != PROGRAM_UNDEFINED);
-   dst->File = st->File;
-
-   assert(index >= 0);
-   dst->Index = index;
-
-   assert(size >= 1);
-   assert(size <= 4);
-
-   if (swizzle != SWIZZLE_XYZW) {
-      dst->WriteMask = swizzle_to_writemask(swizzle);
-   }
-   else {
-      switch (size) {
-      case 1:
-         dst->WriteMask = WRITEMASK_X << GET_SWZ(st->Swizzle, 0);
-         break;
-      case 2:
-         dst->WriteMask = WRITEMASK_XY;
-         break;
-      case 3:
-         dst->WriteMask = WRITEMASK_XYZ;
-         break;
-      case 4:
-         dst->WriteMask = WRITEMASK_XYZW;
-         break;
-      default:
-         ; /* error would have been caught above */
-      }
-   }
-
-   dst->RelAddr = relAddr;
-}
-
-
-/**
- * Convert IR storage to an instruction src register.
- */
-static void
-storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st)
-{
-   const GLboolean relAddr = st->RelAddr;
-   GLint index = st->Index;
-   GLuint swizzle = st->Swizzle;
-
-   /* if this is storage relative to some parent storage, walk up the tree */
-   assert(index >= 0);
-   while (st->Parent) {
-      st = st->Parent;
-      if (st->Index < 0) {
-         /* an error should have been reported already */
-         return;
-      }
-      assert(st->Index >= 0);
-      index += st->Index;
-      swizzle = _slang_swizzle_swizzle(fix_swizzle(st->Swizzle), swizzle);
-   }
-
-   assert(st->File >= 0);
-#if 1 /* XXX temporary */
-   if (st->File == PROGRAM_UNDEFINED) {
-      slang_ir_storage *st0 = (slang_ir_storage *) st;
-      st0->File = PROGRAM_TEMPORARY;
-   }
-#endif
-   assert(st->File < PROGRAM_FILE_MAX);
-   src->File = st->File;
-
-   assert(index >= 0);
-   src->Index = index;
-
-   swizzle = fix_swizzle(swizzle);
-   assert(GET_SWZ(swizzle, 0) <= SWIZZLE_W);
-   assert(GET_SWZ(swizzle, 1) <= SWIZZLE_W);
-   assert(GET_SWZ(swizzle, 2) <= SWIZZLE_W);
-   assert(GET_SWZ(swizzle, 3) <= SWIZZLE_W);
-   src->Swizzle = swizzle;
-
-   src->RelAddr = relAddr;
-}
-
-
-/*
- * Setup storage pointing to a scalar constant/literal.
- */
-static void
-constant_to_storage(slang_emit_info *emitInfo,
-                    GLfloat val,
-                    slang_ir_storage *store)
-{
-   GLuint swizzle;
-   GLint reg;
-   GLfloat value[4];
-
-   value[0] = val;
-   reg = _mesa_add_unnamed_constant(emitInfo->prog->Parameters,
-                                        value, 1, &swizzle);
-
-   memset(store, 0, sizeof(*store));
-   store->File = PROGRAM_CONSTANT;
-   store->Index = reg;
-   store->Swizzle = swizzle;
-}
-
-
-/**
- * Add new instruction at end of given program.
- * \param prog  the program to append instruction onto
- * \param opcode  opcode for the new instruction
- * \return pointer to the new instruction
- */
-static struct prog_instruction *
-new_instruction(slang_emit_info *emitInfo, gl_inst_opcode opcode)
-{
-   struct gl_program *prog = emitInfo->prog;
-   struct prog_instruction *inst;
-
-#if 0
-   /* print prev inst */
-   if (prog->NumInstructions > 0) {
-      _mesa_print_instruction(prog->Instructions + prog->NumInstructions - 1);
-   }
-#endif
-   assert(prog->NumInstructions <= emitInfo->MaxInstructions);
-
-   if (prog->NumInstructions == emitInfo->MaxInstructions) {
-      /* grow the instruction buffer */
-      emitInfo->MaxInstructions += 20;
-      prog->Instructions =
-         _mesa_realloc_instructions(prog->Instructions,
-                                    prog->NumInstructions,
-                                    emitInfo->MaxInstructions);
-      if (!prog->Instructions) {
-         return NULL;
-      }
-   }
-
-   inst = prog->Instructions + prog->NumInstructions;
-   prog->NumInstructions++;
-   _mesa_init_instructions(inst, 1);
-   inst->Opcode = opcode;
-   inst->BranchTarget = -1; /* invalid */
-   /*
-   printf("New inst %d: %p %s\n", prog->NumInstructions-1,(void*)inst,
-          _mesa_opcode_string(inst->Opcode));
-   */
-   return inst;
-}
-
-
-static struct prog_instruction *
-emit_arl_load(slang_emit_info *emitInfo,
-              gl_register_file file, GLint index, GLuint swizzle)
-{
-   struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_ARL);
-   if (inst) {
-      inst->SrcReg[0].File = file;
-      inst->SrcReg[0].Index = index;
-      inst->SrcReg[0].Swizzle = fix_swizzle(swizzle);
-      inst->DstReg.File = PROGRAM_ADDRESS;
-      inst->DstReg.Index = 0;
-      inst->DstReg.WriteMask = WRITEMASK_X;
-   }
-   return inst;
-}
-
-
-/**
- * Emit a new instruction with given opcode, operands.
- * At this point the instruction may have multiple indirect register
- * loads/stores.  We convert those into ARL loads and address-relative
- * operands.  See comments inside.
- * At some point in the future we could directly emit indirectly addressed
- * registers in Mesa GPU instructions.
- */
-static struct prog_instruction *
-emit_instruction(slang_emit_info *emitInfo,
-                 gl_inst_opcode opcode,
-                 const slang_ir_storage *dst,
-                 const slang_ir_storage *src0,
-                 const slang_ir_storage *src1,
-                 const slang_ir_storage *src2)
-{
-   struct prog_instruction *inst;
-   GLuint numIndirect = 0;
-   const slang_ir_storage *src[3];
-   slang_ir_storage newSrc[3], newDst;
-   GLuint i;
-   GLboolean isTemp[3];
-
-   isTemp[0] = isTemp[1] = isTemp[2] = GL_FALSE;
-
-   src[0] = src0;
-   src[1] = src1;
-   src[2] = src2;
-
-   /* count up how many operands are indirect loads */
-   for (i = 0; i < 3; i++) {
-      if (src[i] && src[i]->IsIndirect)
-         numIndirect++;
-   }
-   if (dst && dst->IsIndirect)
-      numIndirect++;
-
-   /* Take special steps for indirect register loads.
-    * If we had multiple address registers this would be simpler.
-    * For example, this GLSL code:
-    *    x[i] = y[j] + z[k];
-    * would translate into something like:
-    *    ARL ADDR.x, i;
-    *    ARL ADDR.y, j;
-    *    ARL ADDR.z, k;
-    *    ADD TEMP[ADDR.x+5], TEMP[ADDR.y+9], TEMP[ADDR.z+4];
-    * But since we currently only have one address register we have to do this:
-    *    ARL ADDR.x, i;
-    *    MOV t1, TEMP[ADDR.x+9];
-    *    ARL ADDR.x, j;
-    *    MOV t2, TEMP[ADDR.x+4];
-    *    ARL ADDR.x, k;
-    *    ADD TEMP[ADDR.x+5], t1, t2;
-    * The code here figures this out...
-    */
-   if (numIndirect > 0) {
-      for (i = 0; i < 3; i++) {
-         if (src[i] && src[i]->IsIndirect) {
-            /* load the ARL register with the indirect register */
-            emit_arl_load(emitInfo,
-                          src[i]->IndirectFile,
-                          src[i]->IndirectIndex,
-                          src[i]->IndirectSwizzle);
-
-            if (numIndirect > 1) {
-               /* Need to load src[i] into a temporary register */
-               slang_ir_storage srcRelAddr;
-               alloc_local_temp(emitInfo, &newSrc[i], src[i]->Size);
-               isTemp[i] = GL_TRUE;
-
-               /* set RelAddr flag on src register */
-               srcRelAddr = *src[i];
-               srcRelAddr.RelAddr = GL_TRUE;
-               srcRelAddr.IsIndirect = GL_FALSE; /* not really needed */
-
-               /* MOV newSrc, srcRelAddr; */
-               inst = emit_instruction(emitInfo,
-                                       OPCODE_MOV,
-                                       &newSrc[i],
-                                       &srcRelAddr,
-                                       NULL,
-                                       NULL);
-               if (!inst) {
-                  return NULL;
-               }
-
-               src[i] = &newSrc[i];
-            }
-            else {
-               /* just rewrite the src[i] storage to be ARL-relative */
-               newSrc[i] = *src[i];
-               newSrc[i].RelAddr = GL_TRUE;
-               newSrc[i].IsIndirect = GL_FALSE; /* not really needed */
-               src[i] = &newSrc[i];
-            }
-         }
-      }
-   }
-
-   /* Take special steps for indirect dest register write */
-   if (dst && dst->IsIndirect) {
-      /* load the ARL register with the indirect register */
-      emit_arl_load(emitInfo,
-                    dst->IndirectFile,
-                    dst->IndirectIndex,
-                    dst->IndirectSwizzle);
-      newDst = *dst;
-      newDst.RelAddr = GL_TRUE;
-      newDst.IsIndirect = GL_FALSE;
-      dst = &newDst;
-   }
-
-   /* OK, emit the instruction and its dst, src regs */
-   inst = new_instruction(emitInfo, opcode);
-   if (!inst)
-      return NULL;
-
-   if (dst)
-      storage_to_dst_reg(&inst->DstReg, dst);
-
-   for (i = 0; i < 3; i++) {
-      if (src[i])
-         storage_to_src_reg(&inst->SrcReg[i], src[i]);
-   }
-
-   /* Free any temp registers that we allocated above */
-   for (i = 0; i < 3; i++) {
-      if (isTemp[i])
-         _slang_free_temp(emitInfo->vt, &newSrc[i]);
-   }
-
-   return inst;
-}
-
-
-
-/**
- * Put a comment on the given instruction.
- */
-static void
-inst_comment(struct prog_instruction *inst, const char *comment)
-{
-   if (inst)
-      inst->Comment = _mesa_strdup(comment);
-}
-
-
-
-/**
- * Return pointer to last instruction in program.
- */
-static struct prog_instruction *
-prev_instruction(slang_emit_info *emitInfo)
-{
-   struct gl_program *prog = emitInfo->prog;
-   if (prog->NumInstructions == 0)
-      return NULL;
-   else
-      return prog->Instructions + prog->NumInstructions - 1;
-}
-
-
-static struct prog_instruction *
-emit(slang_emit_info *emitInfo, slang_ir_node *n);
-
-
-/**
- * Return an annotation string for given node's storage.
- */
-static char *
-storage_annotation(const slang_ir_node *n, const struct gl_program *prog)
-{
-#if ANNOTATE
-   const slang_ir_storage *st = n->Store;
-   static char s[100] = "";
-
-   if (!st)
-      return _mesa_strdup("");
-
-   switch (st->File) {
-   case PROGRAM_CONSTANT:
-      if (st->Index >= 0) {
-         const GLfloat *val = prog->Parameters->ParameterValues[st->Index];
-         if (st->Swizzle == SWIZZLE_NOOP)
-            _mesa_snprintf(s, sizeof(s), "{%g, %g, %g, %g}", val[0], val[1], val[2], val[3]);
-         else {
-            _mesa_snprintf(s, sizeof(s), "%g", val[GET_SWZ(st->Swizzle, 0)]);
-         }
-      }
-      break;
-   case PROGRAM_TEMPORARY:
-      if (n->Var)
-         _mesa_snprintf(s, sizeof(s), "%s", (char *) n->Var->a_name);
-      else
-         _mesa_snprintf(s, sizeof(s), "t[%d]", st->Index);
-      break;
-   case PROGRAM_STATE_VAR:
-   case PROGRAM_UNIFORM:
-      _mesa_snprintf(s, sizeof(s), "%s", prog->Parameters->Parameters[st->Index].Name);
-      break;
-   case PROGRAM_VARYING:
-      _mesa_snprintf(s, sizeof(s), "%s", prog->Varying->Parameters[st->Index].Name);
-      break;
-   case PROGRAM_INPUT:
-      _mesa_snprintf(s, sizeof(s), "input[%d]", st->Index);
-      break;
-   case PROGRAM_OUTPUT:
-      _mesa_snprintf(s, sizeof(s), "output[%d]", st->Index);
-      break;
-   default:
-      s[0] = 0;
-   }
-   return _mesa_strdup(s);
-#else
-   return NULL;
-#endif
-}
-
-
-/**
- * Return an annotation string for an instruction.
- */
-static char *
-instruction_annotation(gl_inst_opcode opcode, char *dstAnnot,
-                       char *srcAnnot0, char *srcAnnot1, char *srcAnnot2)
-{
-#if ANNOTATE
-   const char *operator;
-   char *s;
-   int len = 50;
-
-   if (dstAnnot)
-      len += strlen(dstAnnot);
-   else
-      dstAnnot = _mesa_strdup("");
-
-   if (srcAnnot0)
-      len += strlen(srcAnnot0);
-   else
-      srcAnnot0 = _mesa_strdup("");
-
-   if (srcAnnot1)
-      len += strlen(srcAnnot1);
-   else
-      srcAnnot1 = _mesa_strdup("");
-
-   if (srcAnnot2)
-      len += strlen(srcAnnot2);
-   else
-      srcAnnot2 = _mesa_strdup("");
-
-   switch (opcode) {
-   case OPCODE_ADD:
-      operator = "+";
-      break;
-   case OPCODE_SUB:
-      operator = "-";
-      break;
-   case OPCODE_MUL:
-      operator = "*";
-      break;
-   case OPCODE_DP2:
-      operator = "DP2";
-      break;
-   case OPCODE_DP3:
-      operator = "DP3";
-      break;
-   case OPCODE_DP4:
-      operator = "DP4";
-      break;
-   case OPCODE_XPD:
-      operator = "XPD";
-      break;
-   case OPCODE_RSQ:
-      operator = "RSQ";
-      break;
-   case OPCODE_SGT:
-      operator = ">";
-      break;
-   default:
-      operator = ",";
-   }
-
-   s = (char *) malloc(len);
-   _mesa_snprintf(s, len, "%s = %s %s %s %s", dstAnnot,
-                  srcAnnot0, operator, srcAnnot1, srcAnnot2);
-
-   free(dstAnnot);
-   free(srcAnnot0);
-   free(srcAnnot1);
-   free(srcAnnot2);
-
-   return s;
-#else
-   return NULL;
-#endif
-}
-
-
-/**
- * Emit an instruction that's just a comment.
- */
-static struct prog_instruction *
-emit_comment(slang_emit_info *emitInfo, const char *comment)
-{
-   struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_NOP);
-   if (inst) {
-      inst_comment(inst, comment);
-   }
-   return inst;
-}
-
-
-/**
- * Generate code for a simple arithmetic instruction.
- * Either 1, 2 or 3 operands.
- */
-static struct prog_instruction *
-emit_arith(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   const slang_ir_info *info = _slang_ir_info(n->Opcode);
-   struct prog_instruction *inst;
-   GLuint i;
-
-   assert(info);
-   assert(info->InstOpcode != OPCODE_NOP);
-
-#if PEEPHOLE_OPTIMIZATIONS
-   /* Look for MAD opportunity */
-   if (info->NumParams == 2 &&
-       n->Opcode == IR_ADD && n->Children[0]->Opcode == IR_MUL) {
-      /* found pattern IR_ADD(IR_MUL(A, B), C) */
-      emit(emitInfo, n->Children[0]->Children[0]);  /* A */
-      emit(emitInfo, n->Children[0]->Children[1]);  /* B */
-      emit(emitInfo, n->Children[1]);  /* C */
-      if (!alloc_node_storage(emitInfo, n, -1)) {  /* dest */
-         return NULL;
-      }
-
-      inst = emit_instruction(emitInfo,
-                              OPCODE_MAD,
-                              n->Store,
-                              n->Children[0]->Children[0]->Store,
-                              n->Children[0]->Children[1]->Store,
-                              n->Children[1]->Store);
-
-      free_node_storage(emitInfo->vt, n->Children[0]->Children[0]);
-      free_node_storage(emitInfo->vt, n->Children[0]->Children[1]);
-      free_node_storage(emitInfo->vt, n->Children[1]);
-      return inst;
-   }
-
-   if (info->NumParams == 2 &&
-       n->Opcode == IR_ADD && n->Children[1]->Opcode == IR_MUL) {
-      /* found pattern IR_ADD(A, IR_MUL(B, C)) */
-      emit(emitInfo, n->Children[0]);  /* A */
-      emit(emitInfo, n->Children[1]->Children[0]);  /* B */
-      emit(emitInfo, n->Children[1]->Children[1]);  /* C */
-      if (!alloc_node_storage(emitInfo, n, -1)) {  /* dest */
-         return NULL;
-      }
-
-      inst = emit_instruction(emitInfo,
-                              OPCODE_MAD,
-                              n->Store,
-                              n->Children[1]->Children[0]->Store,
-                              n->Children[1]->Children[1]->Store,
-                              n->Children[0]->Store);
-
-      free_node_storage(emitInfo->vt, n->Children[1]->Children[0]);
-      free_node_storage(emitInfo->vt, n->Children[1]->Children[1]);
-      free_node_storage(emitInfo->vt, n->Children[0]);
-      return inst;
-   }
-#endif
-
-   /* gen code for children, may involve temp allocation */
-   for (i = 0; i < info->NumParams; i++) {
-      emit(emitInfo, n->Children[i]);
-      if (!n->Children[i] || !n->Children[i]->Store) {
-         /* error recovery */
-         return NULL;
-      }
-   }
-
-   /* result storage */
-   if (!alloc_node_storage(emitInfo, n, -1)) {
-      return NULL;
-   }
-
-   inst = emit_instruction(emitInfo,
-                           info->InstOpcode,
-                           n->Store,  /* dest */
-                           (info->NumParams > 0 ? n->Children[0]->Store : NULL),
-                           (info->NumParams > 1 ? n->Children[1]->Store : NULL),
-                           (info->NumParams > 2 ? n->Children[2]->Store : NULL)
-                           );
-
-   /* free temps */
-   for (i = 0; i < info->NumParams; i++)
-      free_node_storage(emitInfo->vt, n->Children[i]);
-
-   return inst;
-}
-
-
-/**
- * Emit code for == and != operators.  These could normally be handled
- * by emit_arith() except we need to be able to handle structure comparisons.
- */
-static struct prog_instruction *
-emit_compare(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   struct prog_instruction *inst = NULL;
-   GLint size;
-
-   assert(n->Opcode == IR_EQUAL || n->Opcode == IR_NOTEQUAL);
-
-   /* gen code for children */
-   emit(emitInfo, n->Children[0]);
-   emit(emitInfo, n->Children[1]);
-
-   if (n->Children[0]->Store->Size != n->Children[1]->Store->Size) {
-      /* XXX this error should have been caught in slang_codegen.c */
-      slang_info_log_error(emitInfo->log, "invalid operands to == or !=");
-      n->Store = NULL;
-      return NULL;
-   }
-
-   /* final result is 1 bool */
-   if (!alloc_node_storage(emitInfo, n, 1))
-      return NULL;
-
-   size = n->Children[0]->Store->Size;
-
-   if (size == 1) {
-      gl_inst_opcode opcode = n->Opcode == IR_EQUAL ? OPCODE_SEQ : OPCODE_SNE;
-      inst =  emit_instruction(emitInfo,
-                               opcode,
-                               n->Store, /* dest */
-                               n->Children[0]->Store,
-                               n->Children[1]->Store,
-                               NULL);
-   }
-   else if (size <= 4) {
-      /* compare two vectors.
-       * Unfortunately, there's no instruction to compare vectors and
-       * return a scalar result.  Do it with some compare and dot product
-       * instructions...
-       */
-      GLuint swizzle;
-      gl_inst_opcode dotOp;
-      slang_ir_storage tempStore;
-
-      if (!alloc_local_temp(emitInfo, &tempStore, 4)) {
-         n->Store = NULL;
-         return NULL;
-         /* out of temps */
-      }
-
-      if (size == 4) {
-         dotOp = OPCODE_DP4;
-         swizzle = SWIZZLE_XYZW;
-      }
-      else if (size == 3) {
-         dotOp = OPCODE_DP3;
-         swizzle = SWIZZLE_XYZW;
-      }
-      else {
-         assert(size == 2);
-         dotOp = OPCODE_DP3; /* XXX use OPCODE_DP2 eventually */
-         swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y);
-      }
-
-      /* Compute inequality (temp = (A != B)) */
-      inst = emit_instruction(emitInfo,
-                              OPCODE_SNE,
-                              &tempStore,
-                              n->Children[0]->Store,
-                              n->Children[1]->Store,
-                              NULL);
-      if (!inst) {
-         return NULL;
-      }
-      inst_comment(inst, "Compare values");
-
-      /* Compute val = DOT(temp, temp)  (reduction) */
-      inst = emit_instruction(emitInfo,
-                              dotOp,
-                              n->Store,
-                              &tempStore,
-                              &tempStore,
-                              NULL);
-      if (!inst) {
-         return NULL;
-      }
-      inst->SrcReg[0].Swizzle = inst->SrcReg[1].Swizzle = swizzle; /*override*/
-      inst_comment(inst, "Reduce vec to bool");
-
-      _slang_free_temp(emitInfo->vt, &tempStore); /* free temp */
-
-      if (n->Opcode == IR_EQUAL) {
-         /* compute val = !val.x  with SEQ val, val, 0; */
-         slang_ir_storage zero;
-         constant_to_storage(emitInfo, 0.0, &zero);
-         inst = emit_instruction(emitInfo,
-                                 OPCODE_SEQ,
-                                 n->Store, /* dest */
-                                 n->Store,
-                                 &zero,
-                                 NULL);
-         if (!inst) {
-            return NULL;
-         }
-         inst_comment(inst, "Invert true/false");
-      }
-   }
-   else {
-      /* size > 4, struct or array compare.
-       * XXX this won't work reliably for structs with padding!!
-       */
-      GLint i, num = (n->Children[0]->Store->Size + 3) / 4;
-      slang_ir_storage accTemp, sneTemp;
-
-      if (!alloc_local_temp(emitInfo, &accTemp, 4))
-         return NULL;
-
-      if (!alloc_local_temp(emitInfo, &sneTemp, 4))
-         return NULL;
-
-      for (i = 0; i < num; i++) {
-         slang_ir_storage srcStore0 = *n->Children[0]->Store;
-         slang_ir_storage srcStore1 = *n->Children[1]->Store;
-         srcStore0.Index += i;
-         srcStore1.Index += i;
-
-         if (i == 0) {
-            /* SNE accTemp, left[i], right[i] */
-            inst = emit_instruction(emitInfo, OPCODE_SNE,
-                                    &accTemp, /* dest */
-                                    &srcStore0,
-                                    &srcStore1,
-                                    NULL);
-            if (!inst) {
-               return NULL;
-            }
-            inst_comment(inst, "Begin struct/array comparison");
-         }
-         else {
-            /* SNE sneTemp, left[i], right[i] */
-            inst = emit_instruction(emitInfo, OPCODE_SNE,
-                                    &sneTemp, /* dest */
-                                    &srcStore0,
-                                    &srcStore1,
-                                    NULL);
-            if (!inst) {
-               return NULL;
-            }
-            /* ADD accTemp, accTemp, sneTemp; # like logical-OR */
-            inst = emit_instruction(emitInfo, OPCODE_ADD,
-                                    &accTemp, /* dest */
-                                    &accTemp,
-                                    &sneTemp,
-                                    NULL);
-            if (!inst) {
-               return NULL;
-            }
-         }
-      }
-
-      /* compute accTemp.x || accTemp.y || accTemp.z || accTemp.w with DOT4 */
-      inst = emit_instruction(emitInfo, OPCODE_DP4,
-                              n->Store,
-                              &accTemp,
-                              &accTemp,
-                              NULL);
-      if (!inst) {
-         return NULL;
-      }
-      inst_comment(inst, "End struct/array comparison");
-
-      if (n->Opcode == IR_EQUAL) {
-         /* compute tmp.x = !tmp.x  via tmp.x = (tmp.x == 0) */
-         slang_ir_storage zero;
-         constant_to_storage(emitInfo, 0.0, &zero);
-         inst = emit_instruction(emitInfo, OPCODE_SEQ,
-                                 n->Store, /* dest */
-                                 n->Store,
-                                 &zero,
-                                 NULL);
-         if (!inst) {
-            return NULL;
-         }
-         inst_comment(inst, "Invert true/false");
-      }
-
-      _slang_free_temp(emitInfo->vt, &accTemp);
-      _slang_free_temp(emitInfo->vt, &sneTemp);
-   }
-
-   /* free temps */
-   free_node_storage(emitInfo->vt, n->Children[0]);
-   free_node_storage(emitInfo->vt, n->Children[1]);
-
-   return inst;
-}
-
-
-
-/**
- * Generate code for an IR_CLAMP instruction.
- */
-static struct prog_instruction *
-emit_clamp(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   struct prog_instruction *inst;
-   slang_ir_node tmpNode;
-
-   assert(n->Opcode == IR_CLAMP);
-   /* ch[0] = value
-    * ch[1] = min limit
-    * ch[2] = max limit
-    */
-
-   inst = emit(emitInfo, n->Children[0]);
-
-   /* If lower limit == 0.0 and upper limit == 1.0,
-    *    set prev instruction's SaturateMode field to SATURATE_ZERO_ONE.
-    * Else,
-    *    emit OPCODE_MIN, OPCODE_MAX sequence.
-    */
-#if 0
-   /* XXX this isn't quite finished yet */
-   if (n->Children[1]->Opcode == IR_FLOAT &&
-       n->Children[1]->Value[0] == 0.0 &&
-       n->Children[1]->Value[1] == 0.0 &&
-       n->Children[1]->Value[2] == 0.0 &&
-       n->Children[1]->Value[3] == 0.0 &&
-       n->Children[2]->Opcode == IR_FLOAT &&
-       n->Children[2]->Value[0] == 1.0 &&
-       n->Children[2]->Value[1] == 1.0 &&
-       n->Children[2]->Value[2] == 1.0 &&
-       n->Children[2]->Value[3] == 1.0) {
-      if (!inst) {
-         inst = prev_instruction(prog);
-      }
-      if (inst && inst->Opcode != OPCODE_NOP) {
-         /* and prev instruction's DstReg matches n->Children[0]->Store */
-         inst->SaturateMode = SATURATE_ZERO_ONE;
-         n->Store = n->Children[0]->Store;
-         return inst;
-      }
-   }
-#else
-   (void) inst;
-#endif
-
-   if (!alloc_node_storage(emitInfo, n, n->Children[0]->Store->Size))
-      return NULL;
-
-   emit(emitInfo, n->Children[1]);
-   emit(emitInfo, n->Children[2]);
-
-   /* Some GPUs don't allow reading from output registers.  So if the
-    * dest for this clamp() is an output reg, we can't use that reg for
-    * the intermediate result.  Use a temp register instead.
-    */
-   memset(&tmpNode, 0, sizeof(tmpNode));
-   if (!alloc_node_storage(emitInfo, &tmpNode, n->Store->Size)) {
-      return NULL;
-   }
-
-   /* tmp = max(ch[0], ch[1]) */
-   inst = emit_instruction(emitInfo, OPCODE_MAX,
-                           tmpNode.Store, /* dest */
-                           n->Children[0]->Store,
-                           n->Children[1]->Store,
-                           NULL);
-   if (!inst) {
-      return NULL;
-   }
-
-   /* n->dest = min(tmp, ch[2]) */
-   inst = emit_instruction(emitInfo, OPCODE_MIN,
-                           n->Store, /* dest */
-                           tmpNode.Store,
-                           n->Children[2]->Store,
-                           NULL);
-
-   free_node_storage(emitInfo->vt, &tmpNode);
-
-   return inst;
-}
-
-
-static struct prog_instruction *
-emit_negation(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   /* Implement as MOV dst, -src; */
-   /* XXX we could look at the previous instruction and in some circumstances
-    * modify it to accomplish the negation.
-    */
-   struct prog_instruction *inst;
-
-   emit(emitInfo, n->Children[0]);
-
-   if (!alloc_node_storage(emitInfo, n, n->Children[0]->Store->Size))
-      return NULL;
-
-   inst = emit_instruction(emitInfo,
-                           OPCODE_MOV,
-                           n->Store, /* dest */
-                           n->Children[0]->Store,
-                           NULL,
-                           NULL);
-   if (inst) {
-      inst->SrcReg[0].Negate = NEGATE_XYZW;
-   }
-   return inst;
-}
-
-
-static struct prog_instruction *
-emit_label(slang_emit_info *emitInfo, const slang_ir_node *n)
-{
-   assert(n->Label);
-#if 0
-   /* XXX this fails in loop tail code - investigate someday */
-   assert(_slang_label_get_location(n->Label) < 0);
-   _slang_label_set_location(n->Label, emitInfo->prog->NumInstructions,
-                             emitInfo->prog);
-#else
-   if (_slang_label_get_location(n->Label) < 0)
-      _slang_label_set_location(n->Label, emitInfo->prog->NumInstructions,
-                                emitInfo->prog);
-#endif
-   return NULL;
-}
-
-
-/**
- * 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_fcall(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   struct gl_program *progSave;
-   struct prog_instruction *inst;
-   GLuint subroutineId;
-   GLuint maxInstSave;
-
-   assert(n->Opcode == IR_CALL);
-   assert(n->Label);
-
-   /* save/push cur program */
-   maxInstSave = emitInfo->MaxInstructions;
-   progSave = emitInfo->prog;
-
-   emitInfo->prog = new_subroutine(emitInfo, &subroutineId);
-   emitInfo->MaxInstructions = emitInfo->prog->NumInstructions;
-
-   _slang_label_set_location(n->Label, emitInfo->prog->NumInstructions,
-                             emitInfo->prog);
-
-   if (emitInfo->EmitBeginEndSub) {
-      /* BGNSUB isn't a real instruction.
-       * We require a label (i.e. "foobar:") though, if we're going to
-       * print the program in the NV format.  The BNGSUB instruction is
-       * really just a NOP to attach the label to.
-       */
-      inst = new_instruction(emitInfo, OPCODE_BGNSUB);
-      if (!inst) {
-         return NULL;
-      }
-      inst_comment(inst, n->Label->Name);
-   }
-
-   /* body of function: */
-   emit(emitInfo, n->Children[0]);
-   n->Store = n->Children[0]->Store;
-
-   /* add RET instruction now, if needed */
-   inst = prev_instruction(emitInfo);
-   if (inst && inst->Opcode != OPCODE_RET) {
-      inst = new_instruction(emitInfo, OPCODE_RET);
-      if (!inst) {
-         return NULL;
-      }
-   }
-
-   if (emitInfo->EmitBeginEndSub) {
-      inst = new_instruction(emitInfo, OPCODE_ENDSUB);
-      if (!inst) {
-         return NULL;
-      }
-      inst_comment(inst, n->Label->Name);
-   }
-
-   /* pop/restore cur program */
-   emitInfo->prog = progSave;
-   emitInfo->MaxInstructions = maxInstSave;
-
-   /* emit the function call */
-   inst = new_instruction(emitInfo, OPCODE_CAL);
-   if (!inst) {
-      return NULL;
-   }
-   /* The branch target is just the subroutine number (changed later) */
-   inst->BranchTarget = subroutineId;
-   inst_comment(inst, n->Label->Name);
-   assert(inst->BranchTarget >= 0);
-
-   return inst;
-}
-
-
-/**
- * Emit code for a 'return' statement.
- */
-static struct prog_instruction *
-emit_return(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   struct prog_instruction *inst;
-   assert(n);
-   assert(n->Opcode == IR_RETURN);
-   assert(n->Label);
-   inst = new_instruction(emitInfo, OPCODE_RET);
-   if (inst) {
-      inst->DstReg.CondMask = COND_TR;  /* always return */
-   }
-   return inst;
-}
-
-
-static struct prog_instruction *
-emit_kill(slang_emit_info *emitInfo)
-{
-   struct gl_fragment_program *fp;
-   struct prog_instruction *inst;
-   /* NV-KILL - discard fragment depending on condition code.
-    * Note that ARB-KILL depends on sign of vector operand.
-    */
-   inst = new_instruction(emitInfo, OPCODE_KIL_NV);
-   if (!inst) {
-      return NULL;
-   }
-   inst->DstReg.CondMask = COND_TR;  /* always kill */
-
-   assert(emitInfo->prog->Target == GL_FRAGMENT_PROGRAM_ARB);
-   fp = (struct gl_fragment_program *) emitInfo->prog;
-   fp->UsesKill = GL_TRUE;
-
-   return inst;
-}
-
-
-static struct prog_instruction *
-emit_tex(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   struct prog_instruction *inst;
-   gl_inst_opcode opcode;
-   GLboolean shadow = GL_FALSE;
-
-   switch (n->Opcode) {
-   case IR_TEX:
-      opcode = OPCODE_TEX;
-      break;
-   case IR_TEX_SH:
-      opcode = OPCODE_TEX;
-      shadow = GL_TRUE;
-      break;
-   case IR_TEXB:
-      opcode = OPCODE_TXB;
-      break;
-   case IR_TEXB_SH:
-      opcode = OPCODE_TXB;
-      shadow = GL_TRUE;
-      break;
-   case IR_TEXP:
-      opcode = OPCODE_TXP;
-      break;
-   case IR_TEXP_SH:
-      opcode = OPCODE_TXP;
-      shadow = GL_TRUE;
-      break;
-   default:
-      _mesa_problem(NULL, "Bad IR TEX code");
-      return NULL;
-   }
-
-   if (n->Children[0]->Opcode == IR_ELEMENT) {
-      /* array is the sampler (a uniform which'll indicate the texture unit) */
-      assert(n->Children[0]->Children[0]->Store);
-      assert(n->Children[0]->Children[0]->Store->File == PROGRAM_SAMPLER);
-
-      emit(emitInfo, n->Children[0]);
-
-      n->Children[0]->Var = n->Children[0]->Children[0]->Var;
-   } else {
-      /* this is the sampler (a uniform which'll indicate the texture unit) */
-      assert(n->Children[0]->Store);
-      assert(n->Children[0]->Store->File == PROGRAM_SAMPLER);
-   }
-
-   /* emit code for the texcoord operand */
-   (void) emit(emitInfo, n->Children[1]);
-
-   /* alloc storage for result of texture fetch */
-   if (!alloc_node_storage(emitInfo, n, 4))
-      return NULL;
-
-   /* emit TEX instruction;  Child[1] is the texcoord */
-   inst = emit_instruction(emitInfo,
-                           opcode,
-                           n->Store,
-                           n->Children[1]->Store,
-                           NULL,
-                           NULL);
-   if (!inst) {
-      return NULL;
-   }
-
-   inst->TexShadow = shadow;
-
-   /* Store->Index is the uniform/sampler index */
-   assert(n->Children[0]->Store->Index >= 0);
-   inst->TexSrcUnit = n->Children[0]->Store->Index;
-   inst->TexSrcTarget = n->Children[0]->Store->TexTarget;
-
-   /* mark the sampler as being used */
-   _mesa_use_uniform(emitInfo->prog->Parameters,
-                     (char *) n->Children[0]->Var->a_name);
-
-   return inst;
-}
-
-
-/**
- * Assignment/copy
- */
-static struct prog_instruction *
-emit_copy(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   struct prog_instruction *inst;
-
-   assert(n->Opcode == IR_COPY);
-
-   /* lhs */
-   emit(emitInfo, n->Children[0]);
-   if (!n->Children[0]->Store || n->Children[0]->Store->Index < 0) {
-      /* an error should have been already recorded */
-      return NULL;
-   }
-
-   /* rhs */
-   assert(n->Children[1]);
-   inst = emit(emitInfo, n->Children[1]);
-
-   if (!n->Children[1]->Store || n->Children[1]->Store->Index < 0) {
-      if (!emitInfo->log->text && !emitInfo->UnresolvedFunctions) {
-         /* XXX this error should have been caught in slang_codegen.c */
-         slang_info_log_error(emitInfo->log, "invalid assignment");
-      }
-      return NULL;
-   }
-
-   assert(n->Children[1]->Store->Index >= 0);
-
-   /*assert(n->Children[0]->Store->Size == n->Children[1]->Store->Size);*/
-
-   n->Store = n->Children[0]->Store;
-
-   if (n->Store->File == PROGRAM_SAMPLER) {
-      /* no code generated for sampler assignments,
-       * just copy the sampler index/target at compile time.
-       */
-      n->Store->Index = n->Children[1]->Store->Index;
-      n->Store->TexTarget = n->Children[1]->Store->TexTarget;
-      return NULL;
-   }
-
-#if PEEPHOLE_OPTIMIZATIONS
-   if (inst &&
-       (n->Children[1]->Opcode != IR_SWIZZLE) &&
-       _slang_is_temp(emitInfo->vt, n->Children[1]->Store) &&
-       (inst->DstReg.File == n->Children[1]->Store->File) &&
-       (inst->DstReg.Index == n->Children[1]->Store->Index) &&
-       !n->Children[0]->Store->IsIndirect &&
-       n->Children[0]->Store->Size <= 4) {
-      /* Peephole optimization:
-       * The Right-Hand-Side has its results in a temporary place.
-       * Modify the RHS (and the prev instruction) to store its results
-       * in the destination specified by n->Children[0].
-       * Then, this MOVE is a no-op.
-       * Ex:
-       *   MUL tmp, x, y;
-       *   MOV a, tmp;
-       * becomes:
-       *   MUL a, x, y;
-       */
-
-      /* fixup the previous instruction (which stored the RHS result) */
-      assert(n->Children[0]->Store->Index >= 0);
-      storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store);
-      return inst;
-   }
-   else
-#endif
-   {
-      if (n->Children[0]->Store->Size > 4) {
-         /* move matrix/struct etc (block of registers) */
-         slang_ir_storage dstStore = *n->Children[0]->Store;
-         slang_ir_storage srcStore = *n->Children[1]->Store;
-         GLint size = srcStore.Size;
-         ASSERT(n->Children[1]->Store->Swizzle == SWIZZLE_NOOP);
-         dstStore.Size = 4;
-         srcStore.Size = 4;
-         while (size >= 4) {
-            inst = emit_instruction(emitInfo, OPCODE_MOV,
-                                    &dstStore,
-                                    &srcStore,
-                                    NULL,
-                                    NULL);
-            if (!inst) {
-               return NULL;
-            }
-            inst_comment(inst, "IR_COPY block");
-            srcStore.Index++;
-            dstStore.Index++;
-            size -= 4;
-         }
-      }
-      else {
-         /* single register move */
-         char *srcAnnot, *dstAnnot;
-         assert(n->Children[0]->Store->Index >= 0);
-         inst = emit_instruction(emitInfo, OPCODE_MOV,
-                                 n->Children[0]->Store, /* dest */
-                                 n->Children[1]->Store,
-                                 NULL,
-                                 NULL);
-         if (!inst) {
-            return NULL;
-         }
-         dstAnnot = storage_annotation(n->Children[0], emitInfo->prog);
-         srcAnnot = storage_annotation(n->Children[1], emitInfo->prog);
-         inst->Comment = instruction_annotation(inst->Opcode, dstAnnot,
-                                                srcAnnot, NULL, NULL);
-      }
-      free_node_storage(emitInfo->vt, n->Children[1]);
-      return inst;
-   }
-}
-
-
-/**
- * An IR_COND node wraps a boolean expression which is used by an
- * IF or WHILE test.  This is where we'll set condition codes, if needed.
- */
-static struct prog_instruction *
-emit_cond(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   struct prog_instruction *inst;
-
-   assert(n->Opcode == IR_COND);
-
-   if (!n->Children[0])
-      return NULL;
-
-   /* emit code for the expression */
-   inst = emit(emitInfo, n->Children[0]);
-
-   if (!n->Children[0]->Store) {
-      /* error recovery */
-      return NULL;
-   }
-
-   assert(n->Children[0]->Store);
-   /*assert(n->Children[0]->Store->Size == 1);*/
-
-   if (emitInfo->EmitCondCodes) {
-      if (inst &&
-          n->Children[0]->Store &&
-          inst->DstReg.File == n->Children[0]->Store->File &&
-          inst->DstReg.Index == n->Children[0]->Store->Index) {
-         /* The previous instruction wrote to the register who's value
-          * we're testing.  Just fix that instruction so that the
-          * condition codes are computed.
-          */
-         inst->CondUpdate = GL_TRUE;
-         n->Store = n->Children[0]->Store;
-         return inst;
-      }
-      else {
-         /* This'll happen for things like "if (i) ..." where no code
-          * is normally generated for the expression "i".
-          * Generate a move instruction just to set condition codes.
-          */
-         if (!alloc_node_storage(emitInfo, n, 1))
-            return NULL;
-         inst = emit_instruction(emitInfo, OPCODE_MOV,
-                                 n->Store, /* dest */
-                                 n->Children[0]->Store,
-                                 NULL,
-                                 NULL);
-         if (!inst) {
-            return NULL;
-         }
-         inst->CondUpdate = GL_TRUE;
-         inst_comment(inst, "COND expr");
-         _slang_free_temp(emitInfo->vt, n->Store);
-         return inst;
-      }
-   }
-   else {
-      /* No-op: the boolean result of the expression is in a regular reg */
-      n->Store = n->Children[0]->Store;
-      return inst;
-   }
-}
-
-
-/**
- * Logical-NOT
- */
-static struct prog_instruction *
-emit_not(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   static const struct {
-      gl_inst_opcode op, opNot;
-   } operators[] = {
-      { OPCODE_SLT, OPCODE_SGE },
-      { OPCODE_SLE, OPCODE_SGT },
-      { OPCODE_SGT, OPCODE_SLE },
-      { OPCODE_SGE, OPCODE_SLT },
-      { OPCODE_SEQ, OPCODE_SNE },
-      { OPCODE_SNE, OPCODE_SEQ },
-      { 0, 0 }
-   };
-   struct prog_instruction *inst;
-   slang_ir_storage zero;
-   GLuint i;
-
-   /* child expr */
-   inst = emit(emitInfo, n->Children[0]);
-
-#if PEEPHOLE_OPTIMIZATIONS
-   if (inst) {
-      /* if the prev instruction was a comparison instruction, invert it */
-      for (i = 0; operators[i].op; i++) {
-         if (inst->Opcode == operators[i].op) {
-            inst->Opcode = operators[i].opNot;
-            n->Store = n->Children[0]->Store;
-            return inst;
-         }
-      }
-   }
-#endif
-
-   /* else, invert using SEQ (v = v == 0) */
-   if (!alloc_node_storage(emitInfo, n, n->Children[0]->Store->Size))
-      return NULL;
-
-   constant_to_storage(emitInfo, 0.0, &zero);
-   inst = emit_instruction(emitInfo,
-                           OPCODE_SEQ,
-                           n->Store,
-                           n->Children[0]->Store,
-                           &zero,
-                           NULL);
-   if (!inst) {
-      return NULL;
-   }
-   inst_comment(inst, "NOT");
-
-   free_node_storage(emitInfo->vt, n->Children[0]);
-
-   return inst;
-}
-
-
-static struct prog_instruction *
-emit_if(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   struct gl_program *prog = emitInfo->prog;
-   GLuint ifInstLoc, elseInstLoc = 0;
-   GLuint condWritemask = 0;
-
-   /* emit condition expression code */
-   {
-      struct prog_instruction *inst;
-      inst = emit(emitInfo, n->Children[0]);
-      if (emitInfo->EmitCondCodes) {
-         if (!inst) {
-            /* error recovery */
-            return NULL;
-         }
-         condWritemask = inst->DstReg.WriteMask;
-      }
-   }
-
-   if (!n->Children[0]->Store)
-      return NULL;
-
-#if 0
-   assert(n->Children[0]->Store->Size == 1); /* a bool! */
-#endif
-
-   ifInstLoc = prog->NumInstructions;
-   if (emitInfo->EmitHighLevelInstructions) {
-      if (emitInfo->EmitCondCodes) {
-         /* IF condcode THEN ... */
-         struct prog_instruction *ifInst = new_instruction(emitInfo, OPCODE_IF);
-         if (!ifInst) {
-            return NULL;
-         }
-         ifInst->DstReg.CondMask = COND_NE;  /* if cond is non-zero */
-         /* only test the cond code (1 of 4) that was updated by the
-          * previous instruction.
-          */
-         ifInst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
-      }
-      else {
-         struct prog_instruction *inst;
-
-         /* IF src[0] THEN ... */
-         inst = emit_instruction(emitInfo, OPCODE_IF,
-                                 NULL, /* dst */
-                                 n->Children[0]->Store, /* op0 */
-                                 NULL,
-                                 NULL);
-         if (!inst) {
-            return NULL;
-         }
-      }
-   }
-   else {
-      /* conditional jump to else, or endif */
-      struct prog_instruction *ifInst = new_instruction(emitInfo, OPCODE_BRA);
-      if (!ifInst) {
-         return NULL;
-      }
-      ifInst->DstReg.CondMask = COND_EQ;  /* BRA if cond is zero */
-      inst_comment(ifInst, "if zero");
-      ifInst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
-   }
-
-   /* if body */
-   emit(emitInfo, n->Children[1]);
-
-   if (n->Children[2]) {
-      /* have else body */
-      elseInstLoc = prog->NumInstructions;
-      if (emitInfo->EmitHighLevelInstructions) {
-         struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_ELSE);
-         if (!inst) {
-            return NULL;
-         }
-         prog->Instructions[ifInstLoc].BranchTarget = prog->NumInstructions - 1;
-      }
-      else {
-         /* jump to endif instruction */
-         struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_BRA);
-         if (!inst) {
-            return NULL;
-         }
-         inst_comment(inst, "else");
-         inst->DstReg.CondMask = COND_TR;  /* always branch */
-         prog->Instructions[ifInstLoc].BranchTarget = prog->NumInstructions;
-      }
-      emit(emitInfo, n->Children[2]);
-   }
-   else {
-      /* no else body */
-      prog->Instructions[ifInstLoc].BranchTarget = prog->NumInstructions;
-   }
-
-   if (emitInfo->EmitHighLevelInstructions) {
-      struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_ENDIF);
-      if (!inst) {
-         return NULL;
-      }
-   }
-
-   if (elseInstLoc) {
-      /* point ELSE instruction BranchTarget at ENDIF */
-      if (emitInfo->EmitHighLevelInstructions) {
-         prog->Instructions[elseInstLoc].BranchTarget = prog->NumInstructions - 1;
-      }
-      else {
-         prog->Instructions[elseInstLoc].BranchTarget = prog->NumInstructions;
-      }
-   }
-   return NULL;
-}
-
-
-static struct prog_instruction *
-emit_loop(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   struct gl_program *prog = emitInfo->prog;
-   struct prog_instruction *endInst;
-   GLuint beginInstLoc, tailInstLoc, endInstLoc;
-   slang_ir_node *ir;
-
-   /* emit OPCODE_BGNLOOP */
-   beginInstLoc = prog->NumInstructions;
-   if (emitInfo->EmitHighLevelInstructions) {
-      struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_BGNLOOP);
-      if (!inst) {
-         return NULL;
-      }
-   }
-
-   /* body */
-   emit(emitInfo, n->Children[0]);
-
-   /* tail */
-   tailInstLoc = prog->NumInstructions;
-   if (n->Children[1]) {
-      if (emitInfo->EmitComments)
-         emit_comment(emitInfo, "Loop tail code:");
-      emit(emitInfo, n->Children[1]);
-   }
-
-   endInstLoc = prog->NumInstructions;
-   if (emitInfo->EmitHighLevelInstructions) {
-      /* emit OPCODE_ENDLOOP */
-      endInst = new_instruction(emitInfo, OPCODE_ENDLOOP);
-      if (!endInst) {
-         return NULL;
-      }
-   }
-   else {
-      /* emit unconditional BRA-nch */
-      endInst = new_instruction(emitInfo, OPCODE_BRA);
-      if (!endInst) {
-         return NULL;
-      }
-      endInst->DstReg.CondMask = COND_TR;  /* always true */
-   }
-   /* ENDLOOP's BranchTarget points to the BGNLOOP inst */
-   endInst->BranchTarget = beginInstLoc;
-
-   if (emitInfo->EmitHighLevelInstructions) {
-      /* BGNLOOP's BranchTarget points to the ENDLOOP inst */
-      prog->Instructions[beginInstLoc].BranchTarget = prog->NumInstructions -1;
-   }
-
-   /* Done emitting loop code.  Now walk over the loop's linked list of
-    * BREAK and CONT nodes, filling in their BranchTarget fields (which
-    * will point to the corresponding ENDLOOP instruction.
-    */
-   for (ir = n->List; ir; ir = ir->List) {
-      struct prog_instruction *inst = prog->Instructions + ir->InstLocation;
-      assert(inst->BranchTarget < 0);
-      if (ir->Opcode == IR_BREAK ||
-          ir->Opcode == IR_BREAK_IF_TRUE) {
-         assert(inst->Opcode == OPCODE_BRK ||
-                inst->Opcode == OPCODE_BRA);
-         /* go to instruction at end of loop */
-         if (emitInfo->EmitHighLevelInstructions) {
-            inst->BranchTarget = endInstLoc;
-         }
-         else {
-            inst->BranchTarget = endInstLoc + 1;
-         }
-      }
-      else {
-         assert(ir->Opcode == IR_CONT ||
-                ir->Opcode == IR_CONT_IF_TRUE);
-         assert(inst->Opcode == OPCODE_CONT ||
-                inst->Opcode == OPCODE_BRA);
-         /* go to instruction at tail of loop */
-         inst->BranchTarget = endInstLoc;
-      }
-   }
-   return NULL;
-}
-
-
-/**
- * Unconditional "continue" or "break" statement.
- * Either OPCODE_CONT, OPCODE_BRK or OPCODE_BRA will be emitted.
- */
-static struct prog_instruction *
-emit_cont_break(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   gl_inst_opcode opcode;
-   struct prog_instruction *inst;
-
-   if (n->Opcode == IR_CONT) {
-      /* we need to execute the loop's tail code before doing CONT */
-      assert(n->Parent);
-      assert(n->Parent->Opcode == IR_LOOP);
-      if (n->Parent->Children[1]) {
-         /* emit tail code */
-         if (emitInfo->EmitComments) {
-            emit_comment(emitInfo, "continue - tail code:");
-         }
-         emit(emitInfo, n->Parent->Children[1]);
-      }
-   }
-
-   /* opcode selection */
-   if (emitInfo->EmitHighLevelInstructions) {
-      opcode = (n->Opcode == IR_CONT) ? OPCODE_CONT : OPCODE_BRK;
-   }
-   else {
-      opcode = OPCODE_BRA;
-   }
-   n->InstLocation = emitInfo->prog->NumInstructions;
-   inst = new_instruction(emitInfo, opcode);
-   if (inst) {
-      inst->DstReg.CondMask = COND_TR;  /* always true */
-   }
-   return inst;
-}
-
-
-/**
- * Conditional "continue" or "break" statement.
- * Either OPCODE_CONT, OPCODE_BRK or OPCODE_BRA will be emitted.
- */
-static struct prog_instruction *
-emit_cont_break_if_true(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   struct prog_instruction *inst;
-
-   assert(n->Opcode == IR_CONT_IF_TRUE ||
-          n->Opcode == IR_BREAK_IF_TRUE);
-
-   /* evaluate condition expr, setting cond codes */
-   inst = emit(emitInfo, n->Children[0]);
-   if (emitInfo->EmitCondCodes) {
-      assert(inst);
-      inst->CondUpdate = GL_TRUE;
-   }
-
-   n->InstLocation = emitInfo->prog->NumInstructions;
-
-   /* opcode selection */
-   if (emitInfo->EmitHighLevelInstructions) {
-      const gl_inst_opcode opcode
-         = (n->Opcode == IR_CONT_IF_TRUE) ? OPCODE_CONT : OPCODE_BRK;
-      if (emitInfo->EmitCondCodes) {
-         /* Get the writemask from the previous instruction which set
-          * the condcodes.  Use that writemask as the CondSwizzle.
-          */
-         const GLuint condWritemask = inst->DstReg.WriteMask;
-         inst = new_instruction(emitInfo, opcode);
-         if (inst) {
-            inst->DstReg.CondMask = COND_NE;
-            inst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
-         }
-         return inst;
-      }
-      else {
-         /* IF reg
-          *    BRK/CONT;
-          * ENDIF
-          */
-         GLint ifInstLoc;
-         ifInstLoc = emitInfo->prog->NumInstructions;
-         inst = emit_instruction(emitInfo, OPCODE_IF,
-                                 NULL, /* dest */
-                                 n->Children[0]->Store,
-                                 NULL,
-                                 NULL);
-         if (!inst) {
-            return NULL;
-         }
-         n->InstLocation = emitInfo->prog->NumInstructions;
-
-         inst = new_instruction(emitInfo, opcode);
-         if (!inst) {
-            return NULL;
-         }
-         inst = new_instruction(emitInfo, OPCODE_ENDIF);
-         if (!inst) {
-            return NULL;
-         }
-
-         emitInfo->prog->Instructions[ifInstLoc].BranchTarget
-            = emitInfo->prog->NumInstructions - 1;
-         return inst;
-      }
-   }
-   else {
-      const GLuint condWritemask = inst->DstReg.WriteMask;
-      assert(emitInfo->EmitCondCodes);
-      inst = new_instruction(emitInfo, OPCODE_BRA);
-      if (inst) {
-         inst->DstReg.CondMask = COND_NE;
-         inst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
-      }
-      return inst;
-   }
-}
-
-
-/**
- * Return the size of a swizzle mask given that some swizzle components
- * may be NIL/undefined.  For example:
- *  swizzle_size(".zzxx") = 4
- *  swizzle_size(".xy??") = 2
- *  swizzle_size(".w???") = 1
- */
-static GLuint
-swizzle_size(GLuint swizzle)
-{
-   GLuint i;
-   for (i = 0; i < 4; i++) {
-      if (GET_SWZ(swizzle, i) == SWIZZLE_NIL)
-         return i;
-   }
-   return 4;
-}
-
-
-static struct prog_instruction *
-emit_swizzle(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   struct prog_instruction *inst;
-
-   inst = emit(emitInfo, n->Children[0]);
-
-   if (!n->Store->Parent) {
-      /* this covers a case such as "(b ? p : q).x" */
-      n->Store->Parent = n->Children[0]->Store;
-      assert(n->Store->Parent);
-   }
-
-   {
-      const GLuint swizzle = n->Store->Swizzle;
-      /* new storage is parent storage with updated Swizzle + Size fields */
-      _slang_copy_ir_storage(n->Store, n->Store->Parent);
-      /* Apply this node's swizzle to parent's storage */
-      n->Store->Swizzle = _slang_swizzle_swizzle(n->Store->Swizzle, swizzle);
-      /* Update size */
-      n->Store->Size = swizzle_size(n->Store->Swizzle);
-   }
-
-   assert(!n->Store->Parent);
-   assert(n->Store->Index >= 0);
-
-   return inst;
-}
-
-
-/**
- * Dereference array element:  element == array[index]
- * This basically involves emitting code for computing the array index
- * and updating the node/element's storage info.
- */
-static struct prog_instruction *
-emit_array_element(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   slang_ir_storage *arrayStore, *indexStore;
-   const int elemSize = n->Store->Size;           /* number of floats */
-   const GLint elemSizeVec = (elemSize + 3) / 4;  /* number of vec4 */
-   struct prog_instruction *inst;
-
-   assert(n->Opcode == IR_ELEMENT);
-   assert(elemSize > 0);
-
-   /* special case for built-in state variables, like light state */
-   {
-      slang_ir_storage *root = n->Store;
-      assert(!root->Parent);
-      while (root->Parent)
-         root = root->Parent;
-
-      if (root->File == PROGRAM_STATE_VAR) {
-         GLboolean direct;
-         GLint index =
-            _slang_alloc_statevar(n, emitInfo->prog->Parameters, &direct);
-         if (index < 0) {
-            /* error */
-            return NULL;
-         }
-         if (direct) {
-            n->Store->Index = index;
-            return NULL; /* all done */
-         }
-      }
-   }
-
-   /* do codegen for array itself */
-   emit(emitInfo, n->Children[0]);
-   arrayStore = n->Children[0]->Store;
-
-   /* The initial array element storage is the array's storage,
-    * then modified below.
-    */
-   _slang_copy_ir_storage(n->Store, arrayStore);
-
-
-   if (n->Children[1]->Opcode == IR_FLOAT) {
-      /* Constant array index */
-      const GLint element = (GLint) n->Children[1]->Value[0];
-
-      /* this element's storage is the array's storage, plus constant offset */
-      n->Store->Index += elemSizeVec * element;
-   }
-   else {
-      /* Variable array index */
-
-      /* do codegen for array index expression */
-      emit(emitInfo, n->Children[1]);
-      indexStore = n->Children[1]->Store;
-
-      if (indexStore->IsIndirect) {
-         /* need to put the array index into a temporary since we can't
-          * directly support a[b[i]] constructs.
-          */
-
-
-         /*indexStore = tempstore();*/
-      }
-
-
-      if (elemSize > 4) {
-         /* need to multiply array index by array element size */
-         struct prog_instruction *inst;
-         slang_ir_storage *indexTemp;
-         slang_ir_storage elemSizeStore;
-
-         /* allocate 1 float indexTemp */
-         indexTemp = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, 1);
-         _slang_alloc_temp(emitInfo->vt, indexTemp);
-
-         /* allocate a constant containing the element size */
-         constant_to_storage(emitInfo, (float) elemSizeVec, &elemSizeStore);
-
-         /* multiply array index by element size */
-         inst = emit_instruction(emitInfo,
-                                 OPCODE_MUL,
-                                 indexTemp, /* dest */
-                                 indexStore, /* the index */
-                                 &elemSizeStore,
-                                 NULL);
-         if (!inst) {
-            return NULL;
-         }
-
-         indexStore = indexTemp;
-      }
-
-      if (arrayStore->IsIndirect) {
-         /* ex: in a[i][j], a[i] (the arrayStore) is indirect */
-         /* Need to add indexStore to arrayStore->Indirect store */
-         slang_ir_storage indirectArray;
-         slang_ir_storage *indexTemp;
-
-         _slang_init_ir_storage(&indirectArray,
-                                arrayStore->IndirectFile,
-                                arrayStore->IndirectIndex,
-                                1,
-                                arrayStore->IndirectSwizzle);
-
-         /* allocate 1 float indexTemp */
-         indexTemp = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, 1);
-         _slang_alloc_temp(emitInfo->vt, indexTemp);
-
-         inst = emit_instruction(emitInfo,
-                                 OPCODE_ADD,
-                                 indexTemp,      /* dest */
-                                 indexStore,     /* the index */
-                                 &indirectArray, /* indirect array base */
-                                 NULL);
-         if (!inst) {
-            return NULL;
-         }
-
-         indexStore = indexTemp;
-      }
-
-      /* update the array element storage info */
-      n->Store->IsIndirect = GL_TRUE;
-      n->Store->IndirectFile = indexStore->File;
-      n->Store->IndirectIndex = indexStore->Index;
-      n->Store->IndirectSwizzle = indexStore->Swizzle;
-   }
-
-   n->Store->Size = elemSize;
-   n->Store->Swizzle = _slang_var_swizzle(elemSize, 0);
-
-   return NULL; /* no instruction */
-}
-
-
-/**
- * Resolve storage for accessing a structure field.
- */
-static struct prog_instruction *
-emit_struct_field(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   slang_ir_storage *root = n->Store;
-   GLint fieldOffset, fieldSize;
-
-   assert(n->Opcode == IR_FIELD);
-
-   assert(!root->Parent);
-   while (root->Parent)
-      root = root->Parent;
-
-   /* If this is the field of a state var, allocate constant/uniform
-    * storage for it now if we haven't already.
-    * Note that we allocate storage (uniform/constant slots) for state
-    * variables here rather than at declaration time so we only allocate
-    * space for the ones that we actually use!
-    */
-   if (root->File == PROGRAM_STATE_VAR) {
-      GLboolean direct;
-      GLint index = _slang_alloc_statevar(n, emitInfo->prog->Parameters, &direct);
-      if (index < 0) {
-         slang_info_log_error(emitInfo->log, "Error parsing state variable");
-         return NULL;
-      }
-      if (direct) {
-         root->Index = index;
-         return NULL; /* all done */
-      }
-   }
-
-   /* do codegen for struct */
-   emit(emitInfo, n->Children[0]);
-   assert(n->Children[0]->Store->Index >= 0);
-
-
-   fieldOffset = n->Store->Index;
-   fieldSize = n->Store->Size;
-
-   _slang_copy_ir_storage(n->Store, n->Children[0]->Store);
-
-   n->Store->Index = n->Children[0]->Store->Index + fieldOffset / 4;
-   n->Store->Size = fieldSize;
-
-   switch (fieldSize) {
-   case 1:
-      {
-         GLint swz = fieldOffset % 4;
-         n->Store->Swizzle = MAKE_SWIZZLE4(swz, swz, swz, swz);
-      }
-      break;
-   case 2:
-      n->Store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
-                                        SWIZZLE_NIL, SWIZZLE_NIL);
-      break;
-   case 3:
-      n->Store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
-                                        SWIZZLE_Z, SWIZZLE_NIL);
-      break;
-   default:
-      n->Store->Swizzle = SWIZZLE_XYZW;
-   }
-
-   assert(n->Store->Index >= 0);
-
-   return NULL; /* no instruction */
-}
-
-
-/**
- * Emit code for a variable declaration.
- * This usually doesn't result in any code generation, but just
- * memory allocation.
- */
-static struct prog_instruction *
-emit_var_decl(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   assert(n->Store);
-   assert(n->Store->File != PROGRAM_UNDEFINED);
-   assert(n->Store->Size > 0);
-   /*assert(n->Store->Index < 0);*/
-
-   if (!n->Var || n->Var->isTemp) {
-      /* a nameless/temporary variable, will be freed after first use */
-      /*NEW*/
-      if (n->Store->Index < 0 && !_slang_alloc_temp(emitInfo->vt, n->Store)) {
-         slang_info_log_error(emitInfo->log,
-                              "Ran out of registers, too many temporaries");
-         return NULL;
-      }
-   }
-   else {
-      /* a regular variable */
-      _slang_add_variable(emitInfo->vt, n->Var);
-      if (!_slang_alloc_var(emitInfo->vt, n->Store)) {
-         slang_info_log_error(emitInfo->log,
-                              "Ran out of registers, too many variables");
-         return NULL;
-      }
-      /*
-        printf("IR_VAR_DECL %s %d store %p\n",
-        (char*) n->Var->a_name, n->Store->Index, (void*) n->Store);
-      */
-      assert(n->Var->store == n->Store);
-   }
-   if (emitInfo->EmitComments) {
-      /* emit NOP with comment describing the variable's storage location */
-      char s[1000];
-      _mesa_snprintf(s, sizeof(s), "TEMP[%d]%s = variable %s (size %d)",
-                     n->Store->Index,
-                     _mesa_swizzle_string(n->Store->Swizzle, 0, GL_FALSE), 
-                     (n->Var ? (char *) n->Var->a_name : "anonymous"),
-                     n->Store->Size);
-      emit_comment(emitInfo, s);
-   }
-   return NULL;
-}
-
-
-/**
- * Emit code for a reference to a variable.
- * Actually, no code is generated but we may do some memory allocation.
- * In particular, state vars (uniforms) are allocated on an as-needed basis.
- */
-static struct prog_instruction *
-emit_var_ref(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   assert(n->Store);
-   assert(n->Store->File != PROGRAM_UNDEFINED);
-
-   if (n->Store->File == PROGRAM_STATE_VAR && n->Store->Index < 0) {
-      GLboolean direct;
-      GLint index = _slang_alloc_statevar(n, emitInfo->prog->Parameters, &direct);
-      if (index < 0) {
-         /* error */
-         char s[100];
-         /* XXX isn't this really an out of memory/resources error? */
-         _mesa_snprintf(s, sizeof(s), "Undefined variable '%s'",
-                 (char *) n->Var->a_name);
-         slang_info_log_error(emitInfo->log, s);
-         return NULL;
-      }
-
-      n->Store->Index = index;
-   }
-   else if (n->Store->File == PROGRAM_UNIFORM ||
-            n->Store->File == PROGRAM_SAMPLER) {
-      /* mark var as used */
-      _mesa_use_uniform(emitInfo->prog->Parameters, (char *) n->Var->a_name);
-   }
-   else if (n->Store->File == PROGRAM_INPUT) {
-      assert(n->Store->Index >= 0);
-      emitInfo->prog->InputsRead |= (1 << n->Store->Index);
-   }
-
-   if (n->Store->Index < 0) {
-      /* probably ran out of registers */
-      return NULL;
-   }
-   assert(n->Store->Size > 0);
-
-   return NULL;
-}
-
-
-static struct prog_instruction *
-emit(slang_emit_info *emitInfo, slang_ir_node *n)
-{
-   struct prog_instruction *inst;
-   if (!n)
-      return NULL;
-
-   if (emitInfo->log->error_flag) {
-      return NULL;
-   }
-
-   if (n->Comment) {
-      inst = new_instruction(emitInfo, OPCODE_NOP);
-      if (inst) {
-         inst->Comment = _mesa_strdup(n->Comment);
-      }
-      inst = NULL;
-   }
-
-   switch (n->Opcode) {
-   case IR_SEQ:
-      /* sequence of two sub-trees */
-      assert(n->Children[0]);
-      assert(n->Children[1]);
-      emit(emitInfo, n->Children[0]);
-      if (emitInfo->log->error_flag)
-         return NULL;
-      inst = emit(emitInfo, n->Children[1]);
-#if 0
-      assert(!n->Store);
-#endif
-      n->Store = n->Children[1]->Store;
-      return inst;
-
-   case IR_SCOPE:
-      /* new variable scope */
-      _slang_push_var_table(emitInfo->vt);
-      inst = emit(emitInfo, n->Children[0]);
-      _slang_pop_var_table(emitInfo->vt);
-      return inst;
-
-   case IR_VAR_DECL:
-      /* Variable declaration - allocate a register for it */
-      inst = emit_var_decl(emitInfo, n);
-      return inst;
-
-   case IR_VAR:
-      /* Reference to a variable
-       * Storage should have already been resolved/allocated.
-       */
-      return emit_var_ref(emitInfo, n);
-
-   case IR_ELEMENT:
-      return emit_array_element(emitInfo, n);
-   case IR_FIELD:
-      return emit_struct_field(emitInfo, n);
-   case IR_SWIZZLE:
-      return emit_swizzle(emitInfo, n);
-
-   /* Simple arithmetic */
-   /* unary */
-   case IR_MOVE:
-   case IR_RSQ:
-   case IR_RCP:
-   case IR_FLOOR:
-   case IR_FRAC:
-   case IR_F_TO_I:
-   case IR_I_TO_F:
-   case IR_ABS:
-   case IR_SIN:
-   case IR_COS:
-   case IR_DDX:
-   case IR_DDY:
-   case IR_EXP:
-   case IR_EXP2:
-   case IR_LOG2:
-   case IR_NOISE1:
-   case IR_NOISE2:
-   case IR_NOISE3:
-   case IR_NOISE4:
-   case IR_NRM4:
-   case IR_NRM3:
-   /* binary */
-   case IR_ADD:
-   case IR_SUB:
-   case IR_MUL:
-   case IR_DOT4:
-   case IR_DOT3:
-   case IR_DOT2:
-   case IR_CROSS:
-   case IR_MIN:
-   case IR_MAX:
-   case IR_SEQUAL:
-   case IR_SNEQUAL:
-   case IR_SGE:
-   case IR_SGT:
-   case IR_SLE:
-   case IR_SLT:
-   case IR_POW:
-   /* trinary operators */
-   case IR_LRP:
-   case IR_CMP:
-      return emit_arith(emitInfo, n);
-
-   case IR_EQUAL:
-   case IR_NOTEQUAL:
-      return emit_compare(emitInfo, n);
-
-   case IR_CLAMP:
-      return emit_clamp(emitInfo, n);
-   case IR_TEX:
-   case IR_TEXB:
-   case IR_TEXP:
-   case IR_TEX_SH:
-   case IR_TEXB_SH:
-   case IR_TEXP_SH:
-      return emit_tex(emitInfo, n);
-   case IR_NEG:
-      return emit_negation(emitInfo, n);
-   case IR_FLOAT:
-      /* find storage location for this float constant */
-      n->Store->Index = _mesa_add_unnamed_constant(emitInfo->prog->Parameters,
-                                                   n->Value,
-                                                   n->Store->Size,
-                                                   &n->Store->Swizzle);
-      if (n->Store->Index < 0) {
-         slang_info_log_error(emitInfo->log, "Ran out of space for constants");
-         return NULL;
-      }
-      return NULL;
-
-   case IR_COPY:
-      return emit_copy(emitInfo, n);
-
-   case IR_COND:
-      return emit_cond(emitInfo, n);
-
-   case IR_NOT:
-      return emit_not(emitInfo, n);
-
-   case IR_LABEL:
-      return emit_label(emitInfo, n);
-
-   case IR_KILL:
-      return emit_kill(emitInfo);
-
-   case IR_CALL:
-      /* new variable scope for subroutines/function calls */
-      _slang_push_var_table(emitInfo->vt);
-      inst = emit_fcall(emitInfo, n);
-      _slang_pop_var_table(emitInfo->vt);
-      return inst;
-
-   case IR_IF:
-      return emit_if(emitInfo, n);
-
-   case IR_LOOP:
-      return emit_loop(emitInfo, n);
-   case IR_BREAK_IF_TRUE:
-   case IR_CONT_IF_TRUE:
-      return emit_cont_break_if_true(emitInfo, n);
-   case IR_BREAK:
-      /* fall-through */
-   case IR_CONT:
-      return emit_cont_break(emitInfo, n);
-
-   case IR_BEGIN_SUB:
-      return new_instruction(emitInfo, OPCODE_BGNSUB);
-   case IR_END_SUB:
-      return new_instruction(emitInfo, OPCODE_ENDSUB);
-   case IR_RETURN:
-      return emit_return(emitInfo, n);
-
-   case IR_NOP:
-      return NULL;
-
-   default:
-      _mesa_problem(NULL, "Unexpected IR opcode in emit()\n");
-   }
-   return NULL;
-}
-
-
-/**
- * After code generation, any subroutines will be in separate program
- * objects.  This function appends all the subroutines onto the main
- * program and resolves the linking of all the branch/call instructions.
- * XXX this logic should really be part of the linking process...
- */
-static void
-_slang_resolve_subroutines(slang_emit_info *emitInfo)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   struct gl_program *mainP = emitInfo->prog;
-   GLuint *subroutineLoc, i, total;
-
-   subroutineLoc
-      = (GLuint *) malloc(emitInfo->NumSubroutines * sizeof(GLuint));
-
-   /* total number of instructions */
-   total = mainP->NumInstructions;
-   for (i = 0; i < emitInfo->NumSubroutines; i++) {
-      subroutineLoc[i] = total;
-      total += emitInfo->Subroutines[i]->NumInstructions;
-   }
-
-   /* adjust BranchTargets within the functions */
-   for (i = 0; i < emitInfo->NumSubroutines; i++) {
-      struct gl_program *sub = emitInfo->Subroutines[i];
-      GLuint j;
-      for (j = 0; j < sub->NumInstructions; j++) {
-         struct prog_instruction *inst = sub->Instructions + j;
-         if (inst->Opcode != OPCODE_CAL && inst->BranchTarget >= 0) {
-            inst->BranchTarget += subroutineLoc[i];
-         }
-      }
-   }
-
-   /* append subroutines' instructions after main's instructions */
-   mainP->Instructions = _mesa_realloc_instructions(mainP->Instructions,
-                                                    mainP->NumInstructions,
-                                                    total);
-   mainP->NumInstructions = total;
-   for (i = 0; i < emitInfo->NumSubroutines; i++) {
-      struct gl_program *sub = emitInfo->Subroutines[i];
-      _mesa_copy_instructions(mainP->Instructions + subroutineLoc[i],
-                              sub->Instructions,
-                              sub->NumInstructions);
-      /* delete subroutine code */
-      sub->Parameters = NULL; /* prevent double-free */
-      _mesa_reference_program(ctx, &emitInfo->Subroutines[i], NULL);
-   }
-
-   /* free subroutine list */
-   if (emitInfo->Subroutines) {
-      free(emitInfo->Subroutines);
-      emitInfo->Subroutines = NULL;
-   }
-   emitInfo->NumSubroutines = 0;
-
-   /* Examine CAL instructions.
-    * 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.
-    */
-   for (i = 0; i < mainP->NumInstructions; i++) {
-      struct prog_instruction *inst = mainP->Instructions + i;
-      if (inst->Opcode == OPCODE_CAL) {
-         const GLuint f = inst->BranchTarget;
-         inst->BranchTarget = subroutineLoc[f];
-      }
-   }
-
-   free(subroutineLoc);
-}
-
-
-
-/**
- * Convert the IR tree into GPU instructions.
- * \param n  root of IR tree
- * \param vt  variable table
- * \param prog  program to put GPU instructions into
- * \param pragmas  controls codegen options
- * \param withEnd  if true, emit END opcode at end
- * \param log  log for emitting errors/warnings/info
- */
-GLboolean
-_slang_emit_code(slang_ir_node *n, slang_var_table *vt,
-                 struct gl_program *prog,
-                 const struct gl_sl_pragmas *pragmas,
-                 GLboolean withEnd,
-                 slang_info_log *log)
-{
-   GET_CURRENT_CONTEXT(ctx);
-   GLboolean success;
-   slang_emit_info emitInfo;
-   GLuint maxUniforms;
-
-   emitInfo.log = log;
-   emitInfo.vt = vt;
-   emitInfo.prog = prog;
-   emitInfo.Subroutines = NULL;
-   emitInfo.NumSubroutines = 0;
-   emitInfo.MaxInstructions = prog->NumInstructions;
-
-   emitInfo.EmitHighLevelInstructions = ctx->Shader.EmitHighLevelInstructions;
-   emitInfo.EmitCondCodes = ctx->Shader.EmitCondCodes;
-   emitInfo.EmitComments = ctx->Shader.EmitComments || pragmas->Debug;
-   emitInfo.EmitBeginEndSub = GL_TRUE;
-
-   if (!emitInfo.EmitCondCodes) {
-      emitInfo.EmitHighLevelInstructions = GL_TRUE;
-   }      
-
-   /* Check uniform/constant limits */
-   if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
-      maxUniforms = ctx->Const.FragmentProgram.MaxUniformComponents / 4;
-   }
-   else {
-      assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
-      maxUniforms = ctx->Const.VertexProgram.MaxUniformComponents / 4;
-   }
-   if (prog->Parameters->NumParameters > maxUniforms) {
-      slang_info_log_error(log, "Constant/uniform register limit exceeded "
-                           "(max=%u vec4)", maxUniforms);
-
-      return GL_FALSE;
-   }
-
-   (void) emit(&emitInfo, n);
-
-   /* finish up by adding the END opcode to program */
-   if (withEnd) {
-      struct prog_instruction *inst;
-      inst = new_instruction(&emitInfo, OPCODE_END);
-      if (!inst) {
-         return GL_FALSE;
-      }
-   }
-
-   _slang_resolve_subroutines(&emitInfo);
-
-   success = GL_TRUE;
-
-#if 0
-   printf("*********** End emit code (%u inst):\n", prog->NumInstructions);
-   _mesa_print_program(prog);
-   _mesa_print_program_parameters(ctx,prog);
-#endif
-
-   return success;
-}
diff --git a/src/mesa/shader/slang/slang_emit.h b/src/mesa/shader/slang/slang_emit.h
deleted file mode 100644 (file)
index ab4c202..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.1
- *
- * Copyright (C) 2005-2008  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 SLANG_EMIT_H
-#define SLANG_EMIT_H
-
-
-#include "main/imports.h"
-#include "slang_compile.h"
-#include "slang_ir.h"
-#include "main/mtypes.h"
-
-
-extern GLuint
-_slang_swizzle_swizzle(GLuint swz1, GLuint swz2);
-
-
-extern GLuint
-_slang_var_swizzle(GLint size, GLint comp);
-
-
-extern GLboolean
-_slang_emit_code(slang_ir_node *n, slang_var_table *vartable,
-                 struct gl_program *prog,
-                 const struct gl_sl_pragmas *pragmas,
-                 GLboolean withEnd,
-                 slang_info_log *log);
-
-
-#endif /* SLANG_EMIT_H */
diff --git a/src/mesa/shader/slang/slang_ir.c b/src/mesa/shader/slang/slang_ir.c
deleted file mode 100644 (file)
index c223004..0000000
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2005-2008  Brian Paul   All Rights Reserved.
- * Copyright (C) 2009  VMware, 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
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#include "main/imports.h"
-#include "main/context.h"
-#include "slang_ir.h"
-#include "slang_mem.h"
-#include "shader/prog_instruction.h"
-#include "shader/prog_print.h"
-
-
-static const slang_ir_info IrInfo[] = {
-   /* binary ops */
-   { IR_ADD, "IR_ADD", OPCODE_ADD, 4, 2 },
-   { IR_SUB, "IR_SUB", OPCODE_SUB, 4, 2 },
-   { IR_MUL, "IR_MUL", OPCODE_MUL, 4, 2 },
-   { IR_DIV, "IR_DIV", OPCODE_NOP, 0, 2 }, /* XXX broke */
-   { IR_DOT4, "IR_DOT4", OPCODE_DP4, 1, 2 },
-   { IR_DOT3, "IR_DOT3", OPCODE_DP3, 1, 2 },
-   { IR_DOT2, "IR_DOT2", OPCODE_DP2, 1, 2 },
-   { IR_NRM4, "IR_NRM4", OPCODE_NRM4, 1, 1 },
-   { IR_NRM3, "IR_NRM3", OPCODE_NRM3, 1, 1 },
-   { IR_CROSS, "IR_CROSS", OPCODE_XPD, 3, 2 },
-   { IR_LRP, "IR_LRP", OPCODE_LRP, 4, 3 },
-   { IR_MIN, "IR_MIN", OPCODE_MIN, 4, 2 },
-   { IR_MAX, "IR_MAX", OPCODE_MAX, 4, 2 },
-   { IR_CLAMP, "IR_CLAMP", OPCODE_NOP, 4, 3 }, /* special case: emit_clamp() */
-   { IR_SEQUAL, "IR_SEQUAL", OPCODE_SEQ, 4, 2 },
-   { IR_SNEQUAL, "IR_SNEQUAL", OPCODE_SNE, 4, 2 },
-   { IR_SGE, "IR_SGE", OPCODE_SGE, 4, 2 },
-   { IR_SGT, "IR_SGT", OPCODE_SGT, 4, 2 },
-   { IR_SLE, "IR_SLE", OPCODE_SLE, 4, 2 },
-   { IR_SLT, "IR_SLT", OPCODE_SLT, 4, 2 },
-   { IR_POW, "IR_POW", OPCODE_POW, 1, 2 },
-   { IR_EQUAL, "IR_EQUAL", OPCODE_NOP, 1, 2 },
-   { IR_NOTEQUAL, "IR_NOTEQUAL", OPCODE_NOP, 1, 2 },
-
-   /* unary ops */
-   { IR_MOVE, "IR_MOVE", OPCODE_MOV, 4, 1 },
-   { IR_I_TO_F, "IR_I_TO_F", OPCODE_MOV, 4, 1 },  /* int[4] to float[4] */
-   { IR_F_TO_I, "IR_F_TO_I", OPCODE_TRUNC, 4, 1 },
-   { IR_EXP, "IR_EXP", OPCODE_EXP, 1, 1 },
-   { IR_EXP2, "IR_EXP2", OPCODE_EX2, 1, 1 },
-   { IR_LOG2, "IR_LOG2", OPCODE_LG2, 1, 1 },
-   { IR_RSQ, "IR_RSQ", OPCODE_RSQ, 1, 1 },
-   { IR_RCP, "IR_RCP", OPCODE_RCP, 1, 1 },
-   { IR_FLOOR, "IR_FLOOR", OPCODE_FLR, 4, 1 },
-   { IR_FRAC, "IR_FRAC", OPCODE_FRC, 4, 1 },
-   { IR_ABS, "IR_ABS", OPCODE_ABS, 4, 1 },
-   { IR_NEG, "IR_NEG", OPCODE_NOP, 4, 1 }, /* special case: emit_negation() */
-   { IR_DDX, "IR_DDX", OPCODE_DDX, 4, 1 },
-   { IR_DDY, "IR_DDY", OPCODE_DDY, 4, 1 },
-   { IR_SIN, "IR_SIN", OPCODE_SIN, 1, 1 },
-   { IR_COS, "IR_COS", OPCODE_COS, 1, 1 },
-   { IR_NOISE1, "IR_NOISE1", OPCODE_NOISE1, 1, 1 },
-   { IR_NOISE2, "IR_NOISE2", OPCODE_NOISE2, 1, 1 },
-   { IR_NOISE3, "IR_NOISE3", OPCODE_NOISE3, 1, 1 },
-   { IR_NOISE4, "IR_NOISE4", OPCODE_NOISE4, 1, 1 },
-
-   /* other */
-   { IR_CMP, "IR_CMP", OPCODE_CMP, 4, 3 },  /* compare/select */
-   { IR_SEQ, "IR_SEQ", OPCODE_NOP, 0, 0 },
-   { IR_SCOPE, "IR_SCOPE", OPCODE_NOP, 0, 0 },
-   { IR_LABEL, "IR_LABEL", OPCODE_NOP, 0, 0 },
-   { IR_IF, "IR_IF", OPCODE_NOP, 0, 0 },
-   { IR_KILL, "IR_KILL", OPCODE_NOP, 0, 0 },
-   { IR_COND, "IR_COND", OPCODE_NOP, 0, 0 },
-   { IR_CALL, "IR_CALL", OPCODE_NOP, 0, 0 },
-   { IR_COPY, "IR_COPY", OPCODE_NOP, 0, 1 },
-   { IR_NOT, "IR_NOT", OPCODE_NOP, 1, 1 },
-   { IR_VAR, "IR_VAR", OPCODE_NOP, 0, 0 },
-   { IR_VAR_DECL, "IR_VAR_DECL", OPCODE_NOP, 0, 0 },
-   { IR_TEX, "IR_TEX", OPCODE_TEX, 4, 1 },
-   { IR_TEXB, "IR_TEXB", OPCODE_TXB, 4, 1 },
-   { IR_TEXP, "IR_TEXP", OPCODE_TXP, 4, 1 },
-   { IR_TEX_SH, "IR_TEX_SH", OPCODE_TEX, 4, 1 },
-   { IR_TEXB_SH, "IR_TEXB_SH", OPCODE_TXB, 4, 1 },
-   { IR_TEXP_SH, "IR_TEXP_SH", OPCODE_TXP, 4, 1 },
-   { IR_FLOAT, "IR_FLOAT", OPCODE_NOP, 0, 0 }, /* float literal */
-   { IR_FIELD, "IR_FIELD", OPCODE_NOP, 0, 0 },
-   { IR_ELEMENT, "IR_ELEMENT", OPCODE_NOP, 0, 0 },
-   { IR_SWIZZLE, "IR_SWIZZLE", OPCODE_NOP, 0, 0 },
-   { IR_NOP, "IR_NOP", OPCODE_NOP, 0, 0 },
-   { 0, NULL, 0, 0, 0 }
-};
-
-
-const slang_ir_info *
-_slang_ir_info(slang_ir_opcode opcode)
-{
-   GLuint i;
-   for (i = 0; IrInfo[i].IrName; i++) {
-      if (IrInfo[i].IrOpcode == opcode) {
-        return IrInfo + i;
-      }
-   }
-   return NULL;
-}
-
-
-void
-_slang_init_ir_storage(slang_ir_storage *st,
-                       gl_register_file file, GLint index, GLint size,
-                       GLuint swizzle)
-{
-   st->File = file;
-   st->Index = index;
-   st->Size = size;
-   st->Swizzle = swizzle;
-   st->Parent = NULL;
-   st->IsIndirect = GL_FALSE;
-}
-
-
-/**
- * Return a new slang_ir_storage object.
- */
-slang_ir_storage *
-_slang_new_ir_storage(gl_register_file file, GLint index, GLint size)
-{
-   slang_ir_storage *st;
-   st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage));
-   if (st) {
-      st->File = file;
-      st->Index = index;
-      st->Size = size;
-      st->Swizzle = SWIZZLE_NOOP;
-      st->Parent = NULL;
-      st->IsIndirect = GL_FALSE;
-   }
-   return st;
-}
-
-
-/**
- * Return a new slang_ir_storage object.
- */
-slang_ir_storage *
-_slang_new_ir_storage_swz(gl_register_file file, GLint index, GLint size,
-                          GLuint swizzle)
-{
-   slang_ir_storage *st;
-   st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage));
-   if (st) {
-      st->File = file;
-      st->Index = index;
-      st->Size = size;
-      st->Swizzle = swizzle;
-      st->Parent = NULL;
-      st->IsIndirect = GL_FALSE;
-   }
-   return st;
-}
-
-
-/**
- * Return a new slang_ir_storage object.
- */
-slang_ir_storage *
-_slang_new_ir_storage_relative(GLint index, GLint size,
-                               slang_ir_storage *parent)
-{
-   slang_ir_storage *st;
-   st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage));
-   if (st) {
-      st->File = PROGRAM_UNDEFINED;
-      st->Index = index;
-      st->Size = size;
-      st->Swizzle = SWIZZLE_NOOP;
-      st->Parent = parent;
-      st->IsIndirect = GL_FALSE;
-   }
-   return st;
-}
-
-
-slang_ir_storage *
-_slang_new_ir_storage_indirect(gl_register_file file,
-                               GLint index,
-                               GLint size,
-                               gl_register_file indirectFile,
-                               GLint indirectIndex,
-                               GLuint indirectSwizzle)
-{
-   slang_ir_storage *st;
-   st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage));
-   if (st) {
-      st->File = file;
-      st->Index = index;
-      st->Size = size;
-      st->Swizzle = SWIZZLE_NOOP;
-      st->IsIndirect = GL_TRUE;
-      st->IndirectFile = indirectFile;
-      st->IndirectIndex = indirectIndex;
-      st->IndirectSwizzle = indirectSwizzle;
-   }
-   return st;
-}
-
-
-/**
- * Allocate IR storage for a texture sampler.
- * \param sampNum  the sampler number/index
- * \param texTarget  one of TEXTURE_x_INDEX values
- * \param size  number of samplers (in case of sampler array)
- */
-slang_ir_storage *
-_slang_new_ir_storage_sampler(GLint sampNum, GLuint texTarget, GLint size)
-{
-   slang_ir_storage *st;
-   assert(texTarget < NUM_TEXTURE_TARGETS);
-   st = _slang_new_ir_storage(PROGRAM_SAMPLER, sampNum, size);
-   if (st) {
-      st->TexTarget = texTarget;
-   }
-   return st;
-}
-
-
-
-/* XXX temporary function */
-void
-_slang_copy_ir_storage(slang_ir_storage *dst, const slang_ir_storage *src)
-{
-   *dst = *src;
-   dst->Parent = NULL;
-}
-
-
-
-static const char *
-_slang_ir_name(slang_ir_opcode opcode)
-{
-   return _slang_ir_info(opcode)->IrName;
-}
-
-
-
-#if 0 /* no longer needed with mempool */
-/**
- * Since many IR nodes might point to the same IR storage info, we need
- * to be careful when deleting things.
- * Before deleting an IR tree, traverse it and do refcounting on the
- * IR storage nodes.  Use the refcount info during delete to free things
- * properly.
- */
-static void
-_slang_refcount_storage(slang_ir_node *n)
-{
-   GLuint i;
-   if (!n)
-      return;
-   if (n->Store)
-      n->Store->RefCount++;
-   for (i = 0; i < 3; i++)
-      _slang_refcount_storage(n->Children[i]);
-}
-#endif
-
-
-static void
-_slang_free_ir(slang_ir_node *n)
-{
-   GLuint i;
-   if (!n)
-      return;
-
-#if 0
-   if (n->Store) {
-      n->Store->RefCount--;
-      if (n->Store->RefCount == 0) {
-         _slang_free(n->Store);
-         n->Store = NULL;
-      }
-   }
-#endif
-
-   for (i = 0; i < 3; i++)
-      _slang_free_ir(n->Children[i]);
-   /* Do not free n->List since it's a child elsewhere */
-   _slang_free(n);
-}
-
-
-/**
- * Recursively free an IR tree.
- */
-void
-_slang_free_ir_tree(slang_ir_node *n)
-{
-#if 0
-   _slang_refcount_storage(n);
-#endif
-   _slang_free_ir(n);
-}
-
-
-static const char *
-storage_string(const slang_ir_storage *st)
-{
-   static const char *files[] = {
-      "TEMP",
-      "LOCAL_PARAM",
-      "ENV_PARAM",
-      "STATE",
-      "INPUT",
-      "OUTPUT",
-      "NAMED_PARAM",
-      "CONSTANT",
-      "UNIFORM",
-      "VARYING",
-      "WRITE_ONLY",
-      "ADDRESS",
-      "SAMPLER",
-      "UNDEFINED"
-   };
-   static char s[100];
-   assert(Elements(files) == PROGRAM_FILE_MAX);
-#if 0
-   if (st->Size == 1)
-      _mesa_snprintf(s, "%s[%d]", files[st->File], st->Index);
-   else
-      _mesa_snprintf(s, "%s[%d..%d]", files[st->File], st->Index,
-                     st->Index + st->Size - 1);
-#endif
-   assert(st->File < (GLint) (sizeof(files) / sizeof(files[0])));
-   _mesa_snprintf(s, sizeof(s), "%s[%d]", files[st->File], st->Index);
-   return s;
-}
-
-
-static void
-spaces(int n)
-{
-   while (n-- > 0) {
-      printf(" ");
-   }
-}
-
-
-void
-_slang_print_ir_tree(const slang_ir_node *n, int indent)
-{
-#define IND 0
-
-   if (!n)
-      return;
-#if !IND
-   if (n->Opcode != IR_SEQ)
-#else
-      printf("%3d:", indent);
-#endif
-      spaces(indent);
-
-   switch (n->Opcode) {
-   case IR_SEQ:
-#if IND
-      printf("SEQ  at %p\n", (void*) n);
-#endif
-      assert(n->Children[0]);
-      assert(n->Children[1]);
-      _slang_print_ir_tree(n->Children[0], indent + IND);
-      _slang_print_ir_tree(n->Children[1], indent + IND);
-      break;
-   case IR_SCOPE:
-      printf("NEW SCOPE\n");
-      assert(!n->Children[1]);
-      _slang_print_ir_tree(n->Children[0], indent + 3);
-      break;
-   case IR_COPY:
-      printf("COPY\n");
-      _slang_print_ir_tree(n->Children[0], indent+3);
-      _slang_print_ir_tree(n->Children[1], indent+3);
-      break;
-   case IR_LABEL:
-      printf("LABEL: %s\n", n->Label->Name);
-      break;
-   case IR_COND:
-      printf("COND\n");
-      _slang_print_ir_tree(n->Children[0], indent + 3);
-      break;
-
-   case IR_IF:
-      printf("IF \n");
-      _slang_print_ir_tree(n->Children[0], indent+3);
-      spaces(indent);
-      printf("THEN\n");
-      _slang_print_ir_tree(n->Children[1], indent+3);
-      if (n->Children[2]) {
-         spaces(indent);
-         printf("ELSE\n");
-         _slang_print_ir_tree(n->Children[2], indent+3);
-      }
-      spaces(indent);
-      printf("ENDIF\n");
-      break;
-
-   case IR_BEGIN_SUB:
-      printf("BEGIN_SUB\n");
-      break;
-   case IR_END_SUB:
-      printf("END_SUB\n");
-      break;
-   case IR_RETURN:
-      printf("RETURN\n");
-      break;
-   case IR_CALL:
-      printf("CALL %s\n", n->Label->Name);
-      break;
-
-   case IR_LOOP:
-      printf("LOOP\n");
-      _slang_print_ir_tree(n->Children[0], indent+3);
-      if (n->Children[1]) {
-         spaces(indent);
-         printf("TAIL:\n");
-         _slang_print_ir_tree(n->Children[1], indent+3);
-      }
-      spaces(indent);
-      printf("ENDLOOP\n");
-      break;
-   case IR_CONT:
-      printf("CONT\n");
-      break;
-   case IR_BREAK:
-      printf("BREAK\n");
-      break;
-   case IR_BREAK_IF_TRUE:
-      printf("BREAK_IF_TRUE\n");
-      _slang_print_ir_tree(n->Children[0], indent+3);
-      break;
-   case IR_CONT_IF_TRUE:
-      printf("CONT_IF_TRUE\n");
-      _slang_print_ir_tree(n->Children[0], indent+3);
-      break;
-
-   case IR_VAR:
-      printf("VAR %s%s at %s  store %p\n",
-             (n->Var ? (char *) n->Var->a_name : "TEMP"),
-             _mesa_swizzle_string(n->Store->Swizzle, 0, 0),
-             storage_string(n->Store), (void*) n->Store);
-      break;
-   case IR_VAR_DECL:
-      printf("VAR_DECL %s (%p) at %s  store %p\n",
-             (n->Var ? (char *) n->Var->a_name : "TEMP"),
-             (void*) n->Var, storage_string(n->Store),
-             (void*) n->Store);
-      break;
-   case IR_FIELD:
-      printf("FIELD %s of\n", n->Field);
-      _slang_print_ir_tree(n->Children[0], indent+3);
-      break;
-   case IR_FLOAT:
-      printf("FLOAT %g %g %g %g\n",
-             n->Value[0], n->Value[1], n->Value[2], n->Value[3]);
-      break;
-   case IR_I_TO_F:
-      printf("INT_TO_FLOAT\n");
-      _slang_print_ir_tree(n->Children[0], indent+3);
-      break;
-   case IR_F_TO_I:
-      printf("FLOAT_TO_INT\n");
-      _slang_print_ir_tree(n->Children[0], indent+3);
-      break;
-   case IR_SWIZZLE:
-      printf("SWIZZLE %s of  (store %p) \n",
-             _mesa_swizzle_string(n->Store->Swizzle, 0, 0), (void*) n->Store);
-      _slang_print_ir_tree(n->Children[0], indent + 3);
-      break;
-   default:
-      printf("%s (%p, %p)  (store %p)\n", _slang_ir_name(n->Opcode),
-             (void*) n->Children[0], (void*) n->Children[1], (void*) n->Store);
-      _slang_print_ir_tree(n->Children[0], indent+3);
-      _slang_print_ir_tree(n->Children[1], indent+3);
-   }
-}
diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h
deleted file mode 100644 (file)
index 166b4e8..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2005-2008  Brian Paul   All Rights Reserved.
- * Copyright (C) 2009  VMware, 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
- * 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 slang_ir.h
- * Mesa GLSL Intermediate Representation tree types and constants.
- * \author Brian Paul
- */
-
-
-#ifndef SLANG_IR_H
-#define SLANG_IR_H
-
-
-#include "main/imports.h"
-#include "slang_compile.h"
-#include "slang_label.h"
-#include "main/mtypes.h"
-
-
-/**
- * Intermediate Representation opcodes
- */
-typedef enum
-{
-   IR_NOP = 0,
-   IR_SEQ,     /* sequence (eval left, then right) */
-   IR_SCOPE,   /* new variable scope (one child) */
-
-   IR_LABEL,   /* target of a jump or cjump */
-
-   IR_COND,    /* conditional expression/predicate */
-
-   IR_IF,      /* high-level IF/then/else */
-               /* Children[0] = conditional expression */
-               /* Children[1] = if-true part */
-               /* Children[2] = if-else part, or NULL */
-
-   IR_BEGIN_SUB, /* begin subroutine */
-   IR_END_SUB,   /* end subroutine */
-   IR_RETURN,    /* return from subroutine */
-   IR_CALL,      /* call subroutine */
-
-   IR_LOOP,      /* high-level loop-begin / loop-end */
-                 /* Children[0] = loop body */
-                 /* Children[1] = loop tail code, or NULL */
-
-   IR_CONT,      /* continue loop */
-                 /* n->Parent = ptr to parent IR_LOOP Node */
-   IR_BREAK,     /* break loop */
-
-   IR_BREAK_IF_TRUE, /**< Children[0] = the condition expression */
-   IR_CONT_IF_TRUE,
-
-   IR_COPY,       /**< assignment/copy */
-   IR_MOVE,       /**< assembly MOV instruction */
-
-   /* vector ops: */
-   IR_ADD,        /**< assembly ADD instruction */
-   IR_SUB,
-   IR_MUL,
-   IR_DIV,
-   IR_DOT4,
-   IR_DOT3,
-   IR_DOT2,
-   IR_NRM4,
-   IR_NRM3,
-   IR_CROSS,   /* vec3 cross product */
-   IR_LRP,
-   IR_CLAMP,
-   IR_MIN,
-   IR_MAX,
-   IR_CMP,     /* = (op0 < 0) ? op1 : op2 */
-   IR_SEQUAL,  /* Set if args are equal (vector) */
-   IR_SNEQUAL, /* Set if args are not equal (vector) */
-   IR_SGE,     /* Set if greater or equal (vector) */
-   IR_SGT,     /* Set if greater than (vector) */
-   IR_SLE,     /* Set if less or equal (vector) */
-   IR_SLT,     /* Set if less than (vector) */
-   IR_POW,     /* x^y */
-   IR_EXP,     /* e^x */
-   IR_EXP2,    /* 2^x */
-   IR_LOG2,    /* log base 2 */
-   IR_RSQ,     /* 1/sqrt() */
-   IR_RCP,     /* reciprocol */
-   IR_FLOOR,
-   IR_FRAC,
-   IR_ABS,     /* absolute value */
-   IR_NEG,     /* negate */
-   IR_DDX,     /* derivative w.r.t. X */
-   IR_DDY,     /* derivative w.r.t. Y */
-   IR_SIN,     /* sine */
-   IR_COS,     /* cosine */
-   IR_NOISE1,  /* noise(x) */
-   IR_NOISE2,  /* noise(x, y) */
-   IR_NOISE3,  /* noise(x, y, z) */
-   IR_NOISE4,  /* noise(x, y, z, w) */
-
-   IR_EQUAL,   /* boolean equality */
-   IR_NOTEQUAL,/* boolean inequality */
-   IR_NOT,     /* boolean not */
-
-   IR_VAR,     /* variable reference */
-   IR_VAR_DECL,/* var declaration */
-
-   IR_ELEMENT, /* array element */
-   IR_FIELD,   /* struct field */
-   IR_SWIZZLE, /* swizzled storage access */
-
-   IR_TEX,     /* texture lookup */
-   IR_TEXB,    /* texture lookup with LOD bias */
-   IR_TEXP,    /* texture lookup with projection */
-
-   IR_TEX_SH,     /* texture lookup, shadow compare */
-   IR_TEXB_SH,    /* texture lookup with LOD bias, shadow compare */
-   IR_TEXP_SH,    /* texture lookup with projection, shadow compare */
-
-   IR_FLOAT,
-   IR_I_TO_F,  /* int[4] to float[4] conversion */
-   IR_F_TO_I,  /* float[4] to int[4] conversion */
-
-   IR_KILL     /* fragment kill/discard */
-} slang_ir_opcode;
-
-
-/**
- * Describes where data/variables are stored in the various register files.
- *
- * In the simple case, the File, Index and Size fields indicate where
- * a variable is stored.  For example, a vec3 variable may be stored
- * as (File=PROGRAM_TEMPORARY, Index=6, Size=3).  Or, File[Index].
- * Or, a program input like color may be stored as
- * (File=PROGRAM_INPUT,Index=3,Size=4);
- *
- * For single-float values, the Swizzle field indicates which component
- * of the vector contains the float.
- *
- * If IsIndirect is set, the storage is accessed through an indirect
- * register lookup.  The value in question will be located at:
- *   File[Index + IndirectFile[IndirectIndex]]
- *
- * This is primary used for indexing arrays.  For example, consider this
- * GLSL code:
- *   uniform int i;
- *   float a[10];
- *   float x = a[i];
- *
- * here, storage for a[i] would be described by (File=PROGRAM_TEMPORAY,
- * Index=aPos, IndirectFile=PROGRAM_UNIFORM, IndirectIndex=iPos), which
- * would mean TEMP[aPos + UNIFORM[iPos]]
- */
-struct slang_ir_storage_
-{
-   gl_register_file File;  /**< PROGRAM_TEMPORARY, PROGRAM_INPUT, etc */
-   GLint Index;    /**< -1 means unallocated */
-   GLint Size;     /**< number of floats or ints */
-   GLuint Swizzle; /**< Swizzle AND writemask info */
-   GLint RefCount; /**< Used during IR tree delete */
-
-   GLboolean RelAddr; /* we'll remove this eventually */
-
-   GLboolean IsIndirect;
-   gl_register_file IndirectFile;
-   GLint IndirectIndex;
-   GLuint IndirectSwizzle;
-   GLuint TexTarget;  /**< If File==PROGRAM_SAMPLER, one of TEXTURE_x_INDEX */
-
-   /** If Parent is non-null, Index is relative to parent.
-    * The other fields are ignored.
-    */
-   struct slang_ir_storage_ *Parent;
-};
-
-typedef struct slang_ir_storage_ slang_ir_storage;
-
-
-/**
- * Intermediate Representation (IR) tree node
- * Basically a binary tree, but IR_LRP and IR_CLAMP have three children.
- */
-typedef struct slang_ir_node_
-{
-   slang_ir_opcode Opcode;
-   struct slang_ir_node_ *Children[3];
-   slang_ir_storage *Store;  /**< location of result of this operation */
-   GLint InstLocation;  /**< Location of instruction emitted for this node */
-
-   /** special fields depending on Opcode: */
-   const char *Field;  /**< If Opcode == IR_FIELD */
-   GLfloat Value[4];    /**< If Opcode == IR_FLOAT */
-   slang_variable *Var;  /**< If Opcode == IR_VAR or IR_VAR_DECL */
-   struct slang_ir_node_ *List;  /**< For various linked lists */
-   struct slang_ir_node_ *Parent;  /**< Pointer to logical parent (ie. loop) */
-   slang_label *Label;  /**< Used for branches */
-   const char *Comment; /**< If Opcode == IR_COMMENT */
-} slang_ir_node;
-
-
-
-/**
- * Assembly and IR info
- */
-typedef struct
-{
-   slang_ir_opcode IrOpcode;
-   const char *IrName;
-   gl_inst_opcode InstOpcode;
-   GLuint ResultSize, NumParams;
-} slang_ir_info;
-
-
-
-extern const slang_ir_info *
-_slang_ir_info(slang_ir_opcode opcode);
-
-
-extern void
-_slang_init_ir_storage(slang_ir_storage *st,
-                       gl_register_file file, GLint index, GLint size,
-                       GLuint swizzle);
-
-extern slang_ir_storage *
-_slang_new_ir_storage(gl_register_file file, GLint index, GLint size);
-
-
-extern slang_ir_storage *
-_slang_new_ir_storage_swz(gl_register_file file, GLint index, GLint size,
-                          GLuint swizzle);
-
-extern slang_ir_storage *
-_slang_new_ir_storage_relative(GLint index, GLint size,
-                               slang_ir_storage *parent);
-
-
-extern slang_ir_storage *
-_slang_new_ir_storage_indirect(gl_register_file file,
-                               GLint index,
-                               GLint size,
-                               gl_register_file indirectFile,
-                               GLint indirectIndex,
-                               GLuint indirectSwizzle);
-
-extern slang_ir_storage *
-_slang_new_ir_storage_sampler(GLint sampNum, GLuint texTarget, GLint size);
-
-
-extern void
-_slang_copy_ir_storage(slang_ir_storage *dst, const slang_ir_storage *src);
-
-
-extern void
-_slang_free_ir_tree(slang_ir_node *n);
-
-
-extern void
-_slang_print_ir_tree(const slang_ir_node *n, int indent);
-
-
-#endif /* SLANG_IR_H */
diff --git a/src/mesa/shader/slang/slang_label.c b/src/mesa/shader/slang/slang_label.c
deleted file mode 100644 (file)
index 8e3a8eb..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-
-
-/**
- * Functions for managing instruction labels.
- * Basically, this is used to manage the problem of forward branches where
- * we have a branch instruciton but don't know the target address yet.
- */
-
-
-#include "slang_label.h"
-#include "slang_mem.h"
-
-
-
-slang_label *
-_slang_label_new(const char *name)
-{
-   slang_label *l = (slang_label *) _slang_alloc(sizeof(slang_label));
-   if (l) {
-      l->Name = _slang_strdup(name);
-      l->Location = -1;
-   }
-   return l;
-}
-
-/**
- * As above, but suffix the name with a unique number.
- */
-slang_label *
-_slang_label_new_unique(const char *name)
-{
-   static int id = 1;
-   slang_label *l = (slang_label *) _slang_alloc(sizeof(slang_label));
-   if (l) {
-      l->Name = (char *) _slang_alloc(strlen(name) + 10);
-      if (!l->Name) {
-         free(l);
-         return NULL;
-      }
-      _mesa_snprintf(l->Name, strlen(name) + 10, "%s_%d", name, id);
-      id++;
-      l->Location = -1;
-   }
-   return l;
-}
-
-void
-_slang_label_delete(slang_label *l)
-{
-   if (l->Name) {
-      _slang_free(l->Name);
-      l->Name = NULL;
-   }
-   if (l->References) {
-      _slang_free(l->References);
-      l->References = NULL;
-   }
-   _slang_free(l);
-}
-
-
-void
-_slang_label_add_reference(slang_label *l, GLuint inst)
-{
-   const GLuint oldSize = l->NumReferences * sizeof(GLuint);
-   assert(l->Location < 0);
-   l->References = _slang_realloc(l->References,
-                                  oldSize, oldSize + sizeof(GLuint));
-   if (l->References) {
-      l->References[l->NumReferences] = inst;
-      l->NumReferences++;
-   }
-}
-
-
-GLint
-_slang_label_get_location(const slang_label *l)
-{
-   return l->Location;
-}
-
-
-void
-_slang_label_set_location(slang_label *l, GLint location,
-                          struct gl_program *prog)
-{
-   GLuint i;
-
-   assert(l->Location < 0);
-   assert(location >= 0);
-
-   l->Location = location;
-
-   /* for the instructions that were waiting to learn the label's location: */
-   for (i = 0; i < l->NumReferences; i++) {
-      const GLuint j = l->References[i];
-      prog->Instructions[j].BranchTarget = location;
-   }
-
-   if (l->References) {
-      _slang_free(l->References);
-      l->References = NULL;
-   }
-}
diff --git a/src/mesa/shader/slang/slang_label.h b/src/mesa/shader/slang/slang_label.h
deleted file mode 100644 (file)
index 87068ae..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef SLANG_LABEL_H
-#define SLANG_LABEL_H 1
-
-#include "main/imports.h"
-#include "main/mtypes.h"
-#include "shader/prog_instruction.h"
-
-
-struct slang_label_
-{
-   char *Name;
-   GLint Location;
-   /**
-    * List of instruction references (numbered starting at zero) which need
-    * their BranchTarget field filled in with the location eventually
-    * assigned to the label.
-    */
-   GLuint NumReferences;
-   GLuint *References;   /** Array [NumReferences] */
-};
-
-typedef struct slang_label_ slang_label;
-
-
-extern slang_label *
-_slang_label_new(const char *name);
-
-extern slang_label *
-_slang_label_new_unique(const char *name);
-
-extern void
-_slang_label_delete(slang_label *l);
-
-extern void
-_slang_label_add_reference(slang_label *l, GLuint inst);
-
-extern GLint
-_slang_label_get_location(const slang_label *l);
-
-extern void
-_slang_label_set_location(slang_label *l, GLint location,
-                          struct gl_program *prog);
-
-
-#endif /* SLANG_LABEL_H */
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
deleted file mode 100644 (file)
index 2d003ef..0000000
+++ /dev/null
@@ -1,1122 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.3
- *
- * Copyright (C) 2008  Brian Paul   All Rights Reserved.
- * Copyright (C) 2009  VMware, 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
- * 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 slang_link.c
- * GLSL linker
- * \author Brian Paul
- */
-
-#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 "shader/prog_statevars.h"
-#include "shader/prog_uniform.h"
-#include "shader/shader_api.h"
-#include "slang_builtin.h"
-#include "slang_link.h"
-
-
-/** cast wrapper */
-static struct gl_vertex_program *
-vertex_program(struct gl_program *prog)
-{
-   assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
-   return (struct gl_vertex_program *) prog;
-}
-
-
-/** cast wrapper */
-static struct gl_fragment_program *
-fragment_program(struct gl_program *prog)
-{
-   assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB);
-   return (struct gl_fragment_program *) prog;
-}
-
-
-/**
- * Record a linking error.
- */
-static void
-link_error(struct gl_shader_program *shProg, const char *msg)
-{
-   if (shProg->InfoLog) {
-      free(shProg->InfoLog);
-   }
-   shProg->InfoLog = _mesa_strdup(msg);
-   shProg->LinkStatus = GL_FALSE;
-}
-
-
-
-/**
- * Check if the given bit is either set or clear in both bitfields.
- */
-static GLboolean
-bits_agree(GLbitfield flags1, GLbitfield flags2, GLbitfield bit)
-{
-   return (flags1 & bit) == (flags2 & bit);
-}
-
-
-/**
- * Examine the outputs/varyings written by the vertex shader and
- * append the names of those outputs onto the Varyings list.
- * This will only capture the pre-defined/built-in varyings like
- * gl_Position, not user-defined varyings.
- */
-static void
-update_varying_var_list(GLcontext *ctx, struct gl_shader_program *shProg)
-{
-   if (shProg->VertexProgram) {
-      GLbitfield64 written = shProg->VertexProgram->Base.OutputsWritten;
-      GLuint i;
-      for (i = 0; written && i < VERT_RESULT_MAX; i++) {
-         if (written & BITFIELD64_BIT(i)) {
-            const char *name = _slang_vertex_output_name(i);            
-            if (name)
-               _mesa_add_varying(shProg->Varying, name, 1, GL_FLOAT_VEC4, 0x0);
-            written &= ~BITFIELD64_BIT(i);
-         }
-      }
-   }
-}
-
-
-/**
- * Do link error checking related to transform feedback.
- */
-static GLboolean
-link_transform_feedback(GLcontext *ctx, struct gl_shader_program *shProg)
-{
-   GLbitfield varyingMask;
-   GLuint totalComps, maxComps, i;
-
-   if (shProg->TransformFeedback.NumVarying == 0) {
-      /* nothing to do */
-      return GL_TRUE;
-   }
-
-   /* Check that there's a vertex shader */
-   if (shProg->TransformFeedback.NumVarying > 0 &&
-       !shProg->VertexProgram) {
-      link_error(shProg, "Transform feedback without vertex shader");
-      return GL_FALSE;
-   }
-
-   /* Check that all named variables exist, and that none are duplicated.
-    * Also, build a count of the number of varying components to feedback.
-    */
-   totalComps = 0;
-   varyingMask = 0x0;
-   for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
-      const GLchar *name = shProg->TransformFeedback.VaryingNames[i];
-      GLint v = _mesa_lookup_parameter_index(shProg->Varying, -1, name);
-      struct gl_program_parameter *p;
-
-      if (v < 0) {
-         char msg[100];
-         _mesa_snprintf(msg, sizeof(msg),
-                        "vertex shader does not emit %s", name);
-         link_error(shProg, msg);
-         return GL_FALSE;
-      }
-
-      assert(v < MAX_VARYING);
-
-      /* already seen this varying name? */
-      if (varyingMask & (1 << v)) {
-         char msg[100];
-         _mesa_snprintf(msg, sizeof(msg),
-                        "duplicated transform feedback varying name: %s",
-                        name);
-         link_error(shProg, msg);
-         return GL_FALSE;
-      }
-
-      varyingMask |= (1 << v);
-
-      p = &shProg->Varying->Parameters[v];
-      
-      totalComps += _mesa_sizeof_glsl_type(p->DataType);
-   }
-
-   if (shProg->TransformFeedback.BufferMode == GL_INTERLEAVED_ATTRIBS)
-      maxComps = ctx->Const.MaxTransformFeedbackInterleavedComponents;
-   else
-      maxComps = ctx->Const.MaxTransformFeedbackSeparateComponents;
-
-   /* check max varying components against the limit */
-   if (totalComps > maxComps) {
-      char msg[100];
-      _mesa_snprintf(msg, sizeof(msg),
-                     "Too many feedback components: %u, max is %u",
-                     totalComps, maxComps);
-      link_error(shProg, msg);
-      return GL_FALSE;
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Linking varying vars involves rearranging varying vars so that the
- * vertex program's output varyings matches the order of the fragment
- * program's input varyings.
- * We'll then rewrite instructions to replace PROGRAM_VARYING with either
- * PROGRAM_INPUT or PROGRAM_OUTPUT depending on whether it's a vertex or
- * fragment shader.
- * This is also where we set program Input/OutputFlags to indicate
- * which inputs are centroid-sampled, invariant, etc.
- */
-static GLboolean
-link_varying_vars(GLcontext *ctx,
-                  struct gl_shader_program *shProg, struct gl_program *prog)
-{
-   GLuint *map, i, firstVarying, newFile;
-   GLbitfield *inOutFlags;
-
-   map = (GLuint *) malloc(prog->Varying->NumParameters * sizeof(GLuint));
-   if (!map)
-      return GL_FALSE;
-
-   /* Varying variables are treated like other vertex program outputs
-    * (and like other fragment program inputs).  The position of the
-    * first varying differs for vertex/fragment programs...
-    * Also, replace File=PROGRAM_VARYING with File=PROGRAM_INPUT/OUTPUT.
-    */
-   if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
-      firstVarying = VERT_RESULT_VAR0;
-      newFile = PROGRAM_OUTPUT;
-      inOutFlags = prog->OutputFlags;
-   }
-   else {
-      assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB);
-      firstVarying = FRAG_ATTRIB_VAR0;
-      newFile = PROGRAM_INPUT;
-      inOutFlags = prog->InputFlags;
-   }
-
-   for (i = 0; i < prog->Varying->NumParameters; i++) {
-      /* see if this varying is in the linked varying list */
-      const struct gl_program_parameter *var = prog->Varying->Parameters + i;
-      GLint j = _mesa_lookup_parameter_index(shProg->Varying, -1, var->Name);
-      if (j >= 0) {
-         /* varying is already in list, do some error checking */
-         const struct gl_program_parameter *v =
-            &shProg->Varying->Parameters[j];
-         if (var->Size != v->Size) {
-            link_error(shProg, "mismatched varying variable types");
-            free(map);
-            return GL_FALSE;
-         }
-         if (!bits_agree(var->Flags, v->Flags, PROG_PARAM_BIT_CENTROID)) {
-            char msg[100];
-            _mesa_snprintf(msg, sizeof(msg),
-                    "centroid modifier mismatch for '%s'", var->Name);
-            link_error(shProg, msg);
-            free(map);
-            return GL_FALSE;
-         }
-         if (!bits_agree(var->Flags, v->Flags, PROG_PARAM_BIT_INVARIANT)) {
-            char msg[100];
-            _mesa_snprintf(msg, sizeof(msg),
-                    "invariant modifier mismatch for '%s'", var->Name);
-            link_error(shProg, msg);
-            free(map);
-            return GL_FALSE;
-         }
-      }
-      else {
-         /* not already in linked list */
-         j = _mesa_add_varying(shProg->Varying, var->Name, var->Size,
-                               var->DataType, var->Flags);
-      }
-
-      if (shProg->Varying->NumParameters > ctx->Const.MaxVarying) {
-         link_error(shProg, "Too many varying variables");
-         free(map);
-         return GL_FALSE;
-      }
-
-      /* Map varying[i] to varying[j].
-       * Note: the loop here takes care of arrays or large (sz>4) vars.
-       */
-      {
-         GLint sz = var->Size;
-         while (sz > 0) {
-            inOutFlags[firstVarying + j] = var->Flags;
-            /*printf("Link varying from %d to %d\n", i, j);*/
-            map[i++] = j++;
-            sz -= 4;
-         }
-         i--; /* go back one */
-      }
-   }
-
-
-   /* OK, now scan the program/shader instructions looking for varying vars,
-    * replacing the old index with the new index.
-    */
-   for (i = 0; i < prog->NumInstructions; i++) {
-      struct prog_instruction *inst = prog->Instructions + i;
-      GLuint j;
-
-      if (inst->DstReg.File == PROGRAM_VARYING) {
-         inst->DstReg.File = newFile;
-         inst->DstReg.Index = map[ inst->DstReg.Index ] + firstVarying;
-      }
-
-      for (j = 0; j < 3; j++) {
-         if (inst->SrcReg[j].File == PROGRAM_VARYING) {
-            inst->SrcReg[j].File = newFile;
-            inst->SrcReg[j].Index = map[ inst->SrcReg[j].Index ] + firstVarying;
-         }
-      }
-   }
-
-   free(map);
-
-   /* these will get recomputed before linking is completed */
-   prog->InputsRead = 0x0;
-   prog->OutputsWritten = 0x0;
-
-   return GL_TRUE;
-}
-
-
-/**
- * Build the shProg->Uniforms list.
- * This is basically a list/index of all uniforms found in either/both of
- * the vertex and fragment shaders.
- *
- * About uniforms:
- * Each uniform has two indexes, one that points into the vertex
- * program's parameter array and another that points into the fragment
- * program's parameter array.  When the user changes a uniform's value
- * we have to change the value in the vertex and/or fragment program's
- * parameter array.
- *
- * This function will be called twice to set up the two uniform->parameter
- * mappings.
- *
- * If a uniform is only present in the vertex program OR fragment program
- * then the fragment/vertex parameter index, respectively, will be -1.
- */
-static GLboolean
-link_uniform_vars(GLcontext *ctx,
-                  struct gl_shader_program *shProg,
-                  struct gl_program *prog,
-                  GLuint *numSamplers)
-{
-   GLuint samplerMap[200]; /* max number of samplers declared, not used */
-   GLuint i;
-
-   for (i = 0; i < prog->Parameters->NumParameters; i++) {
-      const struct gl_program_parameter *p = prog->Parameters->Parameters + i;
-
-      /*
-       * XXX FIX NEEDED HERE
-       * We should also be adding a uniform if p->Type == PROGRAM_STATE_VAR.
-       * For example, modelview matrix, light pos, etc.
-       * Also, we need to update the state-var name-generator code to
-       * generate GLSL-style names, like "gl_LightSource[0].position".
-       * Furthermore, we'll need to fix the state-var's size/datatype info.
-       */
-
-      if ((p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER)
-          && p->Used) {
-         /* add this uniform, indexing into the target's Parameters list */
-         struct gl_uniform *uniform =
-            _mesa_append_uniform(shProg->Uniforms, p->Name, prog->Target, i);
-         if (uniform)
-            uniform->Initialized = p->Initialized;
-      }
-
-      /* The samplerMap[] table we build here is used to remap/re-index
-       * sampler references by TEX instructions.
-       */
-      if (p->Type == PROGRAM_SAMPLER && p->Used) {
-         /* Allocate a new sampler index */
-         GLuint oldSampNum = (GLuint) prog->Parameters->ParameterValues[i][0];
-         GLuint newSampNum = *numSamplers;
-         if (newSampNum >= ctx->Const.MaxTextureImageUnits) {
-            char s[100];
-            _mesa_snprintf(s, sizeof(s),
-                           "Too many texture samplers (%u, max is %u)",
-                           newSampNum, ctx->Const.MaxTextureImageUnits);
-            link_error(shProg, s);
-            return GL_FALSE;
-         }
-         /* save old->new mapping in the table */
-         if (oldSampNum < Elements(samplerMap))
-            samplerMap[oldSampNum] = newSampNum;
-         /* update parameter's sampler index */
-         prog->Parameters->ParameterValues[i][0] = (GLfloat) newSampNum;
-         (*numSamplers)++;
-      }
-   }
-
-   /* OK, now scan the program/shader instructions looking for texture
-    * instructions using sampler vars.  Replace old sampler indexes with
-    * new ones.
-    */
-   prog->SamplersUsed = 0x0;
-   for (i = 0; i < prog->NumInstructions; i++) {
-      struct prog_instruction *inst = prog->Instructions + i;
-      if (_mesa_is_tex_instruction(inst->Opcode)) {
-         /* here, inst->TexSrcUnit is really the sampler unit */
-         const GLint oldSampNum = inst->TexSrcUnit;
-
-#if 0
-         printf("====== remap sampler from %d to %d\n",
-                inst->TexSrcUnit, samplerMap[ inst->TexSrcUnit ]);
-#endif
-
-         if (oldSampNum < Elements(samplerMap)) {
-            const GLuint newSampNum = samplerMap[oldSampNum];
-            inst->TexSrcUnit = newSampNum;
-            prog->SamplerTargets[newSampNum] = inst->TexSrcTarget;
-            prog->SamplersUsed |= (1 << newSampNum);
-            if (inst->TexShadow) {
-               prog->ShadowSamplers |= (1 << newSampNum);
-            }
-         }
-      }
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Resolve binding of generic vertex attributes.
- * For example, if the vertex shader declared "attribute vec4 foobar" we'll
- * allocate a generic vertex attribute for "foobar" and plug that value into
- * the vertex program instructions.
- * But if the user called glBindAttributeLocation(), those bindings will
- * have priority.
- */
-static GLboolean
-_slang_resolve_attributes(struct gl_shader_program *shProg,
-                          const struct gl_program *origProg,
-                          struct gl_program *linkedProg)
-{
-   GLint attribMap[MAX_VERTEX_GENERIC_ATTRIBS];
-   GLuint i, j;
-   GLbitfield usedAttributes; /* generics only, not legacy attributes */
-   GLbitfield inputsRead = 0x0;
-
-   assert(origProg != linkedProg);
-   assert(origProg->Target == GL_VERTEX_PROGRAM_ARB);
-   assert(linkedProg->Target == GL_VERTEX_PROGRAM_ARB);
-
-   if (!shProg->Attributes)
-      shProg->Attributes = _mesa_new_parameter_list();
-
-   if (linkedProg->Attributes) {
-      _mesa_free_parameter_list(linkedProg->Attributes);
-   }
-   linkedProg->Attributes = _mesa_new_parameter_list();
-
-
-   /* Build a bitmask indicating which attribute indexes have been
-    * explicitly bound by the user with glBindAttributeLocation().
-    */
-   usedAttributes = 0x0;
-   for (i = 0; i < shProg->Attributes->NumParameters; i++) {
-      GLint attr = shProg->Attributes->Parameters[i].StateIndexes[0];
-      usedAttributes |= (1 << attr);
-   }
-
-   /* If gl_Vertex is used, that actually counts against the limit
-    * on generic vertex attributes.  This avoids the ambiguity of
-    * whether glVertexAttrib4fv(0, v) sets legacy attribute 0 (vert pos)
-    * or generic attribute[0].  If gl_Vertex is used, we want the former.
-    */
-   if (origProg->InputsRead & VERT_BIT_POS) {
-      usedAttributes |= 0x1;
-   }
-
-   /* initialize the generic attribute map entries to -1 */
-   for (i = 0; i < MAX_VERTEX_GENERIC_ATTRIBS; i++) {
-      attribMap[i] = -1;
-   }
-
-   /*
-    * Scan program for generic attribute references
-    */
-   for (i = 0; i < linkedProg->NumInstructions; i++) {
-      struct prog_instruction *inst = linkedProg->Instructions + i;
-      for (j = 0; j < 3; j++) {
-         if (inst->SrcReg[j].File == PROGRAM_INPUT) {
-            inputsRead |= (1 << inst->SrcReg[j].Index);
-         }
-
-         if (inst->SrcReg[j].File == PROGRAM_INPUT &&
-             inst->SrcReg[j].Index >= VERT_ATTRIB_GENERIC0) {
-            /*
-             * OK, we've found a generic vertex attribute reference.
-             */
-            const GLint k = inst->SrcReg[j].Index - VERT_ATTRIB_GENERIC0;
-
-            GLint attr = attribMap[k];
-
-            if (attr < 0) {
-               /* Need to figure out attribute mapping now.
-                */
-               const char *name = origProg->Attributes->Parameters[k].Name;
-               const GLint size = origProg->Attributes->Parameters[k].Size;
-               const GLenum type =origProg->Attributes->Parameters[k].DataType;
-               GLint index;
-
-               /* See if there's a user-defined attribute binding for
-                * this name.
-                */
-               index = _mesa_lookup_parameter_index(shProg->Attributes,
-                                                    -1, name);
-               if (index >= 0) {
-                  /* Found a user-defined binding */
-                  attr = shProg->Attributes->Parameters[index].StateIndexes[0];
-               }
-               else {
-                  /* No user-defined binding, choose our own attribute number.
-                   * Start at 1 since generic attribute 0 always aliases
-                   * glVertex/position.
-                   */
-                  for (attr = 0; attr < MAX_VERTEX_GENERIC_ATTRIBS; attr++) {
-                     if (((1 << attr) & usedAttributes) == 0)
-                        break;
-                  }
-                  if (attr == MAX_VERTEX_GENERIC_ATTRIBS) {
-                     link_error(shProg, "Too many vertex attributes");
-                     return GL_FALSE;
-                  }
-
-                  /* mark this attribute as used */
-                  usedAttributes |= (1 << attr);
-               }
-
-               attribMap[k] = attr;
-
-               /* Save the final name->attrib binding so it can be queried
-                * with glGetAttributeLocation().
-                */
-               _mesa_add_attribute(linkedProg->Attributes, name,
-                                   size, type, attr);
-            }
-
-            assert(attr >= 0);
-
-            /* update the instruction's src reg */
-            inst->SrcReg[j].Index = VERT_ATTRIB_GENERIC0 + attr;
-         }
-      }
-   }
-
-   /* Handle pre-defined attributes here (gl_Vertex, gl_Normal, etc).
-    * When the user queries the active attributes we need to include both
-    * the user-defined attributes and the built-in ones.
-    */
-   for (i = VERT_ATTRIB_POS; i < VERT_ATTRIB_GENERIC0; i++) {
-      if (inputsRead & (1 << i)) {
-         _mesa_add_attribute(linkedProg->Attributes,
-                             _slang_vert_attrib_name(i),
-                             4, /* size in floats */
-                             _slang_vert_attrib_type(i),
-                             -1 /* attrib/input */);
-      }
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Scan program instructions to update the program's NumTemporaries field.
- * Note: this implemenation relies on the code generator allocating
- * temps in increasing order (0, 1, 2, ... ).
- */
-static void
-_slang_count_temporaries(struct gl_program *prog)
-{
-   GLuint i, j;
-   GLint maxIndex = -1;
-
-   for (i = 0; i < prog->NumInstructions; i++) {
-      const struct prog_instruction *inst = prog->Instructions + i;
-      const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
-      for (j = 0; j < numSrc; j++) {
-         if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) {
-            if (maxIndex < inst->SrcReg[j].Index)
-               maxIndex = inst->SrcReg[j].Index;
-         }
-         if (inst->DstReg.File == PROGRAM_TEMPORARY) {
-            if (maxIndex < (GLint) inst->DstReg.Index)
-               maxIndex = inst->DstReg.Index;
-         }
-      }
-   }
-
-   prog->NumTemporaries = (GLuint) (maxIndex + 1);
-}
-
-
-/**
- * If an input attribute is indexed with relative addressing we have
- * to compute a gl_program::InputsRead bitmask which reflects the fact
- * that any input may be referenced by array element.  Ex: gl_TexCoord[i].
- * This function computes the bitmask of potentially read inputs.
- */
-static GLbitfield
-get_inputs_read_mask(GLenum target, GLuint index, GLboolean relAddr)
-{
-   GLbitfield mask;
-
-   mask = 1 << index;
-
-   if (relAddr) {
-      if (target == GL_VERTEX_PROGRAM_ARB) {
-         switch (index) {
-         case VERT_ATTRIB_TEX0:
-            mask = ((1U << (VERT_ATTRIB_TEX7 + 1)) - 1)
-                 - ((1U << VERT_ATTRIB_TEX0) - 1);
-            break;
-         case VERT_ATTRIB_GENERIC0:
-            /* different code to avoid uint overflow */
-            mask = ~0x0U - ((1U << VERT_ATTRIB_GENERIC0) - 1);
-            break;
-         default:
-            ; /* a non-array input attribute */
-         }
-      }
-      else if (target == GL_FRAGMENT_PROGRAM_ARB) {
-         switch (index) {
-         case FRAG_ATTRIB_TEX0:
-            mask = ((1U << (FRAG_ATTRIB_TEX7 + 1)) - 1)
-                 - ((1U << FRAG_ATTRIB_TEX0) - 1);
-            break;
-         case FRAG_ATTRIB_VAR0:
-            mask = ((1U << (FRAG_ATTRIB_VAR0 + MAX_VARYING)) - 1)
-                 - ((1U << FRAG_ATTRIB_VAR0) - 1);
-            break;
-         default:
-            ; /* a non-array input attribute */
-         }
-      }
-      else {
-         assert(0 && "bad program target");
-      }
-   }
-   else {
-   }
-
-   return mask;
-}
-
-
-/**
- * If an output attribute is indexed with relative addressing we have
- * to compute a gl_program::OutputsWritten bitmask which reflects the fact
- * that any output may be referenced by array element.  Ex: gl_TexCoord[i].
- * This function computes the bitmask of potentially written outputs.
- */
-static GLbitfield64
-get_outputs_written_mask(GLenum target, GLuint index, GLboolean relAddr)
-{
-   GLbitfield64 mask;
-
-   mask = BITFIELD64_BIT(index);
-
-   if (relAddr) {
-      if (target == GL_VERTEX_PROGRAM_ARB) {
-         switch (index) {
-         case VERT_RESULT_TEX0:
-            mask = BITFIELD64_RANGE(VERT_RESULT_TEX0,
-                                    (VERT_RESULT_TEX0
-                                     + MAX_TEXTURE_COORD_UNITS - 1));
-            break;
-         case VERT_RESULT_VAR0:
-            mask = BITFIELD64_RANGE(VERT_RESULT_VAR0,
-                                    (VERT_RESULT_VAR0 + MAX_VARYING - 1));
-            break;
-         default:
-            ; /* a non-array output attribute */
-         }
-      }
-      else if (target == GL_FRAGMENT_PROGRAM_ARB) {
-         switch (index) {
-         case FRAG_RESULT_DATA0:
-            mask = BITFIELD64_RANGE(FRAG_RESULT_DATA0,
-                                    (FRAG_RESULT_DATA0
-                                     + MAX_DRAW_BUFFERS - 1));
-            break;
-         default:
-            ; /* a non-array output attribute */
-         }
-      }
-      else {
-         assert(0 && "bad program target");
-      }
-   }
-
-   return mask;
-}
-
-
-/**
- * Scan program instructions to update the program's InputsRead and
- * OutputsWritten fields.
- */
-static void
-_slang_update_inputs_outputs(struct gl_program *prog)
-{
-   GLuint i, j;
-   GLuint maxAddrReg = 0;
-
-   prog->InputsRead = 0x0;
-   prog->OutputsWritten = 0x0;
-
-   for (i = 0; i < prog->NumInstructions; i++) {
-      const struct prog_instruction *inst = prog->Instructions + i;
-      const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
-      for (j = 0; j < numSrc; j++) {
-         if (inst->SrcReg[j].File == PROGRAM_INPUT) {
-            prog->InputsRead |= get_inputs_read_mask(prog->Target,
-                                                     inst->SrcReg[j].Index,
-                                                     inst->SrcReg[j].RelAddr);
-         }
-         else if (inst->SrcReg[j].File == PROGRAM_ADDRESS) {
-            maxAddrReg = MAX2(maxAddrReg, (GLuint) (inst->SrcReg[j].Index + 1));
-         }
-      }
-
-      if (inst->DstReg.File == PROGRAM_OUTPUT) {
-         prog->OutputsWritten |= get_outputs_written_mask(prog->Target,
-                                                          inst->DstReg.Index,
-                                                          inst->DstReg.RelAddr);
-      }
-      else if (inst->DstReg.File == PROGRAM_ADDRESS) {
-         maxAddrReg = MAX2(maxAddrReg, inst->DstReg.Index + 1);
-      }
-   }
-   prog->NumAddressRegs = maxAddrReg;
-}
-
-
-
-/**
- * Remove extra #version directives from the concatenated source string.
- * Disable the extra ones by converting first two chars to //, a comment.
- * This is a bit of hack to work around a preprocessor bug that only
- * allows one #version directive per source.
- */
-static void
-remove_extra_version_directives(GLchar *source)
-{
-   GLuint verCount = 0;
-   while (1) {
-      char *ver = strstr(source, "#version");
-      if (ver) {
-         verCount++;
-         if (verCount > 1) {
-            ver[0] = '/';
-            ver[1] = '/';
-         }
-         source += 8;
-      }
-      else {
-         break;
-      }
-   }
-}
-
-
-
-/**
- * Return a new shader whose source code is the concatenation of
- * all the shader sources of the given type.
- */
-static struct gl_shader *
-concat_shaders(struct gl_shader_program *shProg, GLenum shaderType)
-{
-   struct gl_shader *newShader;
-   const struct gl_shader *firstShader = NULL;
-   GLuint *shaderLengths;
-   GLchar *source;
-   GLuint totalLen = 0, len = 0;
-   GLuint i;
-
-   shaderLengths = (GLuint *)malloc(shProg->NumShaders * sizeof(GLuint));
-   if (!shaderLengths) {
-      return NULL;
-   }
-
-   /* compute total size of new shader source code */
-   for (i = 0; i < shProg->NumShaders; i++) {
-      const struct gl_shader *shader = shProg->Shaders[i];
-      if (shader->Type == shaderType) {
-         shaderLengths[i] = strlen(shader->Source);
-         totalLen += shaderLengths[i];
-         if (!firstShader)
-            firstShader = shader;
-      }
-   }
-
-   if (totalLen == 0) {
-      free(shaderLengths);
-      return NULL;
-   }
-
-   source = (GLchar *) malloc(totalLen + 1);
-   if (!source) {
-      free(shaderLengths);
-      return NULL;
-   }
-
-   /* concatenate shaders */
-   for (i = 0; i < shProg->NumShaders; i++) {
-      const struct gl_shader *shader = shProg->Shaders[i];
-      if (shader->Type == shaderType) {
-         memcpy(source + len, shader->Source, shaderLengths[i]);
-         len += shaderLengths[i];
-      }
-   }
-   source[len] = '\0';
-   /*
-   printf("---NEW CONCATENATED SHADER---:\n%s\n------------\n", source);
-   */
-
-   free(shaderLengths);
-
-   remove_extra_version_directives(source);
-
-   newShader = CALLOC_STRUCT(gl_shader);
-   if (!newShader) {
-      free(source);
-      return NULL;
-   }
-
-   newShader->Type = shaderType;
-   newShader->Source = source;
-   newShader->Pragmas = firstShader->Pragmas;
-
-   return newShader;
-}
-
-
-/**
- * Search the shader program's list of shaders to find the one that
- * defines main().
- * This will involve shader concatenation and recompilation if needed.
- */
-static struct gl_shader *
-get_main_shader(GLcontext *ctx,
-                struct gl_shader_program *shProg, GLenum type)
-{
-   struct gl_shader *shader = NULL;
-   GLuint i;
-
-   /*
-    * Look for a shader that defines main() and has no unresolved references.
-    */
-   for (i = 0; i < shProg->NumShaders; i++) {
-      shader = shProg->Shaders[i];
-      if (shader->Type == type &&
-          shader->Main &&
-          !shader->UnresolvedRefs) {
-         /* All set! */
-         return shader;
-      }
-   }
-
-   /*
-    * There must have been unresolved references during the original
-    * compilation.  Try concatenating all the shaders of the given type
-    * and recompile that.
-    */
-   shader = concat_shaders(shProg, type);
-
-   if (shader) {
-      _slang_compile(ctx, shader);
-
-      /* Finally, check if recompiling failed */
-      if (!shader->CompileStatus ||
-          !shader->Main ||
-          shader->UnresolvedRefs) {
-         link_error(shProg, "Unresolved symbols");
-         _mesa_free_shader(ctx, shader);
-         return NULL;
-      }
-   }
-
-   return shader;
-}
-
-
-/**
- * Shader linker.  Currently:
- *
- * 1. The last attached vertex shader and fragment shader are linked.
- * 2. Varying vars in the two shaders are combined so their locations
- *    agree between the vertex and fragment stages.  They're treated as
- *    vertex program output attribs and as fragment program input attribs.
- * 3. The vertex and fragment programs are cloned and modified to update
- *    src/dst register references so they use the new, linked varying
- *    storage locations.
- */
-void
-_slang_link(GLcontext *ctx,
-            GLhandleARB programObj,
-            struct gl_shader_program *shProg)
-{
-   const struct gl_vertex_program *vertProg = NULL;
-   const struct gl_fragment_program *fragProg = NULL;
-   GLboolean vertNotify = GL_TRUE, fragNotify = GL_TRUE;
-   GLuint numSamplers = 0;
-   GLuint i;
-
-   _mesa_clear_shader_program_data(ctx, shProg);
-
-   /* Initialize LinkStatus to "success".  Will be cleared if error. */
-   shProg->LinkStatus = GL_TRUE;
-
-   /* check that all programs compiled successfully */
-   for (i = 0; i < shProg->NumShaders; i++) {
-      if (!shProg->Shaders[i]->CompileStatus) {
-         link_error(shProg, "linking with uncompiled shader\n");
-         return;
-      }
-   }
-
-   shProg->Uniforms = _mesa_new_uniform_list();
-   shProg->Varying = _mesa_new_parameter_list();
-
-   /*
-    * Find the vertex and fragment shaders which define main()
-    */
-   {
-      struct gl_shader *vertShader, *fragShader;
-      vertShader = get_main_shader(ctx, shProg, GL_VERTEX_SHADER);
-      fragShader = get_main_shader(ctx, shProg, GL_FRAGMENT_SHADER);
-      if (vertShader)
-         vertProg = vertex_program(vertShader->Program);
-      if (fragShader)
-         fragProg = fragment_program(fragShader->Program);
-      if (!shProg->LinkStatus)
-         return;
-   }
-
-#if FEATURE_es2_glsl
-   /* must have both a vertex and fragment program for ES2 */
-   if (ctx->API == API_OPENGLES2) {
-      if (!vertProg) {
-        link_error(shProg, "missing vertex shader\n");
-        return;
-      }
-      if (!fragProg) {
-        link_error(shProg, "missing fragment shader\n");
-        return;
-      }
-   }
-#endif
-
-   /*
-    * Make copies of the vertex/fragment programs now since we'll be
-    * changing src/dst registers after merging the uniforms and varying vars.
-    */
-   _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
-   if (vertProg) {
-      struct gl_vertex_program *linked_vprog =
-         _mesa_clone_vertex_program(ctx, vertProg);
-      shProg->VertexProgram = linked_vprog; /* refcount OK */
-      /* vertex program ID not significant; just set Id for debugging purposes */
-      shProg->VertexProgram->Base.Id = shProg->Name;
-      ASSERT(shProg->VertexProgram->Base.RefCount == 1);
-   }
-
-   _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
-   if (fragProg) {
-      struct gl_fragment_program *linked_fprog = 
-         _mesa_clone_fragment_program(ctx, fragProg);
-      shProg->FragmentProgram = linked_fprog; /* refcount OK */
-      /* vertex program ID not significant; just set Id for debugging purposes */
-      shProg->FragmentProgram->Base.Id = shProg->Name;
-      ASSERT(shProg->FragmentProgram->Base.RefCount == 1);
-   }
-
-   /* link varying vars */
-   if (shProg->VertexProgram) {
-      if (!link_varying_vars(ctx, shProg, &shProg->VertexProgram->Base))
-         return;
-   }
-   if (shProg->FragmentProgram) {
-      if (!link_varying_vars(ctx, shProg, &shProg->FragmentProgram->Base))
-         return;
-   }
-
-   /* link uniform vars */
-   if (shProg->VertexProgram) {
-      if (!link_uniform_vars(ctx, shProg, &shProg->VertexProgram->Base,
-                             &numSamplers)) {
-         return;
-      }
-   }
-   if (shProg->FragmentProgram) {
-      if (!link_uniform_vars(ctx, shProg, &shProg->FragmentProgram->Base,
-                             &numSamplers)) {
-         return;
-      }
-   }
-
-   /*_mesa_print_uniforms(shProg->Uniforms);*/
-
-   if (shProg->VertexProgram) {
-      if (!_slang_resolve_attributes(shProg, &vertProg->Base,
-                                     &shProg->VertexProgram->Base)) {
-         return;
-      }
-   }
-
-   if (shProg->VertexProgram) {
-      _slang_update_inputs_outputs(&shProg->VertexProgram->Base);
-      _slang_count_temporaries(&shProg->VertexProgram->Base);
-      if (!(shProg->VertexProgram->Base.OutputsWritten
-           & BITFIELD64_BIT(VERT_RESULT_HPOS))) {
-         /* the vertex program did not compute a vertex position */
-         link_error(shProg,
-                    "gl_Position was not written by vertex shader\n");
-         return;
-      }
-   }
-   if (shProg->FragmentProgram) {
-      _slang_count_temporaries(&shProg->FragmentProgram->Base);
-      _slang_update_inputs_outputs(&shProg->FragmentProgram->Base);
-   }
-
-   /* Check that all the varying vars needed by the fragment shader are
-    * actually produced by the vertex shader.
-    */
-   if (shProg->FragmentProgram) {
-      const GLbitfield varyingRead
-         = shProg->FragmentProgram->Base.InputsRead >> FRAG_ATTRIB_VAR0;
-      const GLbitfield64 varyingWritten = shProg->VertexProgram ?
-         shProg->VertexProgram->Base.OutputsWritten >> VERT_RESULT_VAR0 : 0x0;
-      if ((varyingRead & varyingWritten) != varyingRead) {
-         link_error(shProg,
-          "Fragment program using varying vars not written by vertex shader\n");
-         return;
-      }         
-   }
-
-   /* check that gl_FragColor and gl_FragData are not both written to */
-   if (shProg->FragmentProgram) {
-      const GLbitfield64 outputsWritten =
-        shProg->FragmentProgram->Base.OutputsWritten;
-      if ((outputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) &&
-          (outputsWritten >= BITFIELD64_BIT(FRAG_RESULT_DATA0))) {
-         link_error(shProg, "Fragment program cannot write both gl_FragColor"
-                    " and gl_FragData[].\n");
-         return;
-      }         
-   }
-
-   update_varying_var_list(ctx, shProg);
-
-   /* checks related to transform feedback */
-   if (!link_transform_feedback(ctx, shProg)) {
-      return;
-   }
-
-   if (fragProg && shProg->FragmentProgram) {
-      /* Compute initial program's TexturesUsed info */
-      _mesa_update_shader_textures_used(&shProg->FragmentProgram->Base);
-
-      /* notify driver that a new fragment program has been compiled/linked */
-      vertNotify = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
-                                                 &shProg->FragmentProgram->Base);
-      if (ctx->Shader.Flags & GLSL_DUMP) {
-         printf("Mesa pre-link fragment program:\n");
-         _mesa_print_program(&fragProg->Base);
-         _mesa_print_program_parameters(ctx, &fragProg->Base);
-
-         printf("Mesa post-link fragment program:\n");
-         _mesa_print_program(&shProg->FragmentProgram->Base);
-         _mesa_print_program_parameters(ctx, &shProg->FragmentProgram->Base);
-      }
-   }
-
-   if (vertProg && shProg->VertexProgram) {
-      /* Compute initial program's TexturesUsed info */
-      _mesa_update_shader_textures_used(&shProg->VertexProgram->Base);
-
-      /* notify driver that a new vertex program has been compiled/linked */
-      fragNotify = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
-                                                   &shProg->VertexProgram->Base);
-      if (ctx->Shader.Flags & GLSL_DUMP) {
-         printf("Mesa pre-link vertex program:\n");
-         _mesa_print_program(&vertProg->Base);
-         _mesa_print_program_parameters(ctx, &vertProg->Base);
-
-         printf("Mesa post-link vertex program:\n");
-         _mesa_print_program(&shProg->VertexProgram->Base);
-         _mesa_print_program_parameters(ctx, &shProg->VertexProgram->Base);
-      }
-   }
-
-   /* Debug: */
-   if (0) {
-      if (shProg->VertexProgram)
-         _mesa_postprocess_program(ctx, &shProg->VertexProgram->Base);
-      if (shProg->FragmentProgram)
-         _mesa_postprocess_program(ctx, &shProg->FragmentProgram->Base);
-   }
-
-   if (ctx->Shader.Flags & GLSL_DUMP) {
-      printf("Varying vars:\n");
-      _mesa_print_parameter_list(shProg->Varying);
-      if (shProg->InfoLog) {
-         printf("Info Log: %s\n", shProg->InfoLog);
-      }
-   }
-
-   if (!vertNotify || !fragNotify) {
-      /* driver rejected one/both of the vertex/fragment programs */
-      if (!shProg->InfoLog) {
-        link_error(shProg,
-                   "Vertex and/or fragment program rejected by driver\n");
-      }
-   }
-   else {
-      shProg->LinkStatus = (shProg->VertexProgram || shProg->FragmentProgram);
-   }
-}
-
diff --git a/src/mesa/shader/slang/slang_link.h b/src/mesa/shader/slang/slang_link.h
deleted file mode 100644 (file)
index 2b44d20..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.2
- *
- * Copyright (C) 2008  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 SLANG_LINK_H
-#define SLANG_LINK_H 1
-
-#include "slang_compile.h"
-
-
-extern void
-_slang_link(GLcontext *ctx, GLhandleARB h,
-            struct gl_shader_program *shProg);
-
-
-#endif
-
diff --git a/src/mesa/shader/slang/slang_log.c b/src/mesa/shader/slang/slang_log.c
deleted file mode 100644 (file)
index 9ff2141..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.3
- *
- * Copyright (C) 2005-2007  Brian Paul   All Rights Reserved.
- * Copyright (C) 2009  VMware, 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
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "main/imports.h"
-#include "slang_log.h"
-#include "slang_utility.h"
-
-
-
-static char *out_of_memory = "Error: Out of memory.\n";
-
-void
-slang_info_log_construct(slang_info_log * log)
-{
-   log->text = NULL;
-   log->dont_free_text = GL_FALSE;
-   log->error_flag = GL_FALSE;
-}
-
-void
-slang_info_log_destruct(slang_info_log * log)
-{
-   if (!log->dont_free_text)
-      free(log->text);
-}
-
-static int
-slang_info_log_message(slang_info_log * log, const char *prefix,
-                       const char *msg)
-{
-   GLuint size;
-
-   if (log->dont_free_text)
-      return 0;
-   size = slang_string_length(msg) + 2;
-   if (prefix != NULL)
-      size += slang_string_length(prefix) + 2;
-   if (log->text != NULL) {
-      GLuint old_len = slang_string_length(log->text);
-      log->text = (char *)
-        _mesa_realloc(log->text, old_len + 1, old_len + size);
-   }
-   else {
-      log->text = (char *) (malloc(size));
-      if (log->text != NULL)
-         log->text[0] = '\0';
-   }
-   if (log->text == NULL)
-      return 0;
-   if (prefix != NULL) {
-      slang_string_concat(log->text, prefix);
-      slang_string_concat(log->text, ": ");
-   }
-   slang_string_concat(log->text, msg);
-   slang_string_concat(log->text, "\n");
-
-   return 1;
-}
-
-int
-slang_info_log_print(slang_info_log * log, const char *msg, ...)
-{
-   va_list va;
-   char buf[1024];
-
-   va_start(va, msg);
-   vsprintf(buf, msg, va);
-   va_end(va);
-   return slang_info_log_message(log, NULL, buf);
-}
-
-int
-slang_info_log_error(slang_info_log * log, const char *msg, ...)
-{
-   va_list va;
-   char buf[1024];
-
-   va_start(va, msg);
-   vsprintf(buf, msg, va);
-   va_end(va);
-   log->error_flag = GL_TRUE;
-   if (slang_info_log_message(log, "Error", buf))
-      return 1;
-   slang_info_log_memory(log);
-   return 0;
-}
-
-int
-slang_info_log_warning(slang_info_log * log, const char *msg, ...)
-{
-   va_list va;
-   char buf[1024];
-
-   va_start(va, msg);
-   vsprintf(buf, msg, va);
-   va_end(va);
-   if (slang_info_log_message(log, "Warning", buf))
-      return 1;
-   slang_info_log_memory(log);
-   return 0;
-}
-
-void
-slang_info_log_memory(slang_info_log * log)
-{
-   if (!slang_info_log_message(log, "Error", "Out of memory.")) {
-      log->dont_free_text = GL_TRUE;
-      log->error_flag = GL_TRUE;
-      log->text = out_of_memory;
-   }
-}
diff --git a/src/mesa/shader/slang/slang_log.h b/src/mesa/shader/slang/slang_log.h
deleted file mode 100644 (file)
index dcaba02..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.3
- *
- * Copyright (C) 2005-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.
- */
-
-
-#ifndef SLANG_LOG_H
-#define SLANG_LOG_H
-
-
-typedef struct slang_info_log_
-{
-   char *text;
-   GLboolean dont_free_text;
-   GLboolean error_flag;
-} slang_info_log;
-
-
-extern void
-slang_info_log_construct(slang_info_log *);
-
-extern void
-slang_info_log_destruct(slang_info_log *);
-
-extern int
-slang_info_log_print(slang_info_log *, const char *, ...);
-
-extern int
-slang_info_log_error(slang_info_log *, const char *, ...);
-
-extern int
-slang_info_log_warning(slang_info_log *, const char *, ...);
-
-extern void
-slang_info_log_memory(slang_info_log *);
-
-
-#endif /* SLANG_LOG_H */
diff --git a/src/mesa/shader/slang/slang_mem.c b/src/mesa/shader/slang/slang_mem.c
deleted file mode 100644 (file)
index 5eaa7c4..0000000
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.3
- *
- * Copyright (C) 2005-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 slang_mem.c
- *
- * Memory manager for GLSL compiler.  The general idea is to do all
- * allocations out of a large pool then just free the pool when done
- * compiling to avoid intricate malloc/free tracking and memory leaks.
- *
- * \author Brian Paul
- */
-
-#include "main/context.h"
-#include "main/macros.h"
-#include "slang_mem.h"
-
-
-#define GRANULARITY 8
-#define ROUND_UP(B)  ( ((B) + (GRANULARITY - 1)) & ~(GRANULARITY - 1) )
-
-
-/** If 1, use conventional malloc/free.  Helpful for debugging */
-#define USE_MALLOC_FREE 0
-
-
-struct slang_mempool_
-{
-   GLuint Size, Used, Count, Largest;
-   char *Data;
-   struct slang_mempool_ *Next;
-};
-
-
-slang_mempool *
-_slang_new_mempool(GLuint initialSize)
-{
-   slang_mempool *pool = (slang_mempool *) calloc(1, sizeof(slang_mempool));
-   if (pool) {
-      pool->Data = (char *) calloc(1, initialSize);
-      /*printf("ALLOC MEMPOOL %d at %p\n", initialSize, pool->Data);*/
-      if (!pool->Data) {
-         free(pool);
-         return NULL;
-      }
-      pool->Size = initialSize;
-      pool->Used = 0;
-   }
-   return pool;
-}
-
-
-void
-_slang_delete_mempool(slang_mempool *pool)
-{
-   GLuint total = 0;
-   while (pool) {
-      slang_mempool *next = pool->Next;
-      /*
-      printf("DELETE MEMPOOL %u / %u  count=%u largest=%u\n",
-             pool->Used, pool->Size, pool->Count, pool->Largest);
-      */
-      total += pool->Used;
-      free(pool->Data);
-      free(pool);
-      pool = next;
-   }
-   /*printf("TOTAL ALLOCATED: %u\n", total);*/
-}
-
-
-#ifdef DEBUG
-static void
-check_zero(const char *addr, GLuint n)
-{
-   GLuint i;
-   for (i = 0; i < n; i++) {
-      assert(addr[i]==0);
-   }
-}
-#endif
-
-
-#ifdef DEBUG
-static GLboolean
-is_valid_address(const slang_mempool *pool, void *addr)
-{
-   while (pool) {
-      if ((char *) addr >= pool->Data &&
-          (char *) addr < pool->Data + pool->Used)
-         return GL_TRUE;
-
-      pool = pool->Next;
-   }
-   return GL_FALSE;
-}
-#endif
-
-
-/**
- * Alloc 'bytes' from shader mempool.
- */
-void *
-_slang_alloc(GLuint bytes)
-{
-#if USE_MALLOC_FREE
-   return calloc(1, bytes);
-#else
-   slang_mempool *pool;
-   GET_CURRENT_CONTEXT(ctx);
-   pool = (slang_mempool *) ctx->Shader.MemPool;
-
-   if (bytes == 0)
-      bytes = 1;
-
-   while (pool) {
-      if (pool->Used + bytes <= pool->Size) {
-         /* found room */
-         void *addr = (void *) (pool->Data + pool->Used);
-#ifdef DEBUG
-         check_zero((char*) addr, bytes);
-#endif
-         pool->Used += ROUND_UP(bytes);
-         pool->Largest = MAX2(pool->Largest, bytes);
-         pool->Count++;
-         /*printf("alloc %u  Used %u\n", bytes, pool->Used);*/
-         return addr;
-      }
-      else if (pool->Next) {
-         /* try next block */
-         pool = pool->Next;
-      }
-      else {
-         /* alloc new pool */
-         const GLuint sz = MAX2(bytes, pool->Size);
-         pool->Next = _slang_new_mempool(sz);
-         if (!pool->Next) {
-            /* we're _really_ out of memory */
-            return NULL;
-         }
-         else {
-            pool = pool->Next;
-            pool->Largest = bytes;
-            pool->Count++;
-            pool->Used = ROUND_UP(bytes);
-#ifdef DEBUG
-            check_zero((char*) pool->Data, bytes);
-#endif
-            return (void *) pool->Data;
-         }
-      }
-   }
-   return NULL;
-#endif
-}
-
-
-void *
-_slang_realloc(void *oldBuffer, GLuint oldSize, GLuint newSize)
-{
-#if USE_MALLOC_FREE
-   return _mesa_realloc(oldBuffer, oldSize, newSize);
-#else
-   GET_CURRENT_CONTEXT(ctx);
-   slang_mempool *pool = (slang_mempool *) ctx->Shader.MemPool;
-   (void) pool;
-
-   if (newSize < oldSize) {
-      return oldBuffer;
-   }
-   else {
-      const GLuint copySize = (oldSize < newSize) ? oldSize : newSize;
-      void *newBuffer = _slang_alloc(newSize);
-
-      if (oldBuffer)
-         ASSERT(is_valid_address(pool, oldBuffer));
-
-      if (newBuffer && oldBuffer && copySize > 0)
-         memcpy(newBuffer, oldBuffer, copySize);
-
-      return newBuffer;
-   }
-#endif
-}
-
-
-/**
- * Clone string, storing in current mempool.
- */
-char *
-_slang_strdup(const char *s)
-{
-   if (s) {
-      size_t l = strlen(s);
-      char *s2 = (char *) _slang_alloc(l + 1);
-      if (s2)
-         strcpy(s2, s);
-      return s2;
-   }
-   else {
-      return NULL;
-   }
-}
-
-
-/**
- * Don't actually free memory, but mark it (for debugging).
- */
-void
-_slang_free(void *addr)
-{
-#if USE_MALLOC_FREE
-   free(addr);
-#else
-   if (addr) {
-      GET_CURRENT_CONTEXT(ctx);
-      slang_mempool *pool = (slang_mempool *) ctx->Shader.MemPool;
-      (void) pool;
-      ASSERT(is_valid_address(pool, addr));
-   }
-#endif
-}
diff --git a/src/mesa/shader/slang/slang_mem.h b/src/mesa/shader/slang/slang_mem.h
deleted file mode 100644 (file)
index b5bfae2..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.3
- *
- * Copyright (C) 2005-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.
- */
-
-
-#ifndef SLANG_MEM_H
-#define SLANG_MEM_H
-
-
-#include "main/imports.h"
-
-
-typedef struct slang_mempool_ slang_mempool;
-
-
-extern slang_mempool *
-_slang_new_mempool(GLuint initialSize);
-
-extern void
-_slang_delete_mempool(slang_mempool *pool);
-
-extern void *
-_slang_alloc(GLuint bytes);
-
-extern void *
-_slang_realloc(void *oldBuffer, GLuint oldSize, GLuint newSize);
-
-extern char *
-_slang_strdup(const char *s);
-
-extern void
-_slang_free(void *addr);
-
-
-#endif
diff --git a/src/mesa/shader/slang/slang_print.c b/src/mesa/shader/slang/slang_print.c
deleted file mode 100644 (file)
index 6b34f39..0000000
+++ /dev/null
@@ -1,883 +0,0 @@
-
-/**
- * Dump/print a slang_operation tree
- */
-
-
-#include "main/imports.h"
-#include "slang_compile.h"
-#include "slang_print.h"
-
-
-static void
-spaces(int n)
-{
-   while (n--)
-      printf(" ");
-}
-
-
-static void
-print_type(const slang_fully_specified_type *t)
-{
-   switch (t->qualifier) {
-   case SLANG_QUAL_NONE:
-      /*printf("");*/
-      break;
-   case SLANG_QUAL_CONST:
-      printf("const ");
-      break;
-   case SLANG_QUAL_ATTRIBUTE:
-      printf("attrib ");
-      break;
-   case SLANG_QUAL_VARYING:
-      printf("varying ");
-      break;
-   case SLANG_QUAL_UNIFORM:
-      printf("uniform ");
-      break;
-   case SLANG_QUAL_OUT:
-      printf("output ");
-      break;
-   case SLANG_QUAL_INOUT:
-      printf("inout ");
-      break;
-   case SLANG_QUAL_FIXEDOUTPUT:
-      printf("fixedoutput");
-      break;
-   case SLANG_QUAL_FIXEDINPUT:
-      printf("fixedinput");
-      break;
-   default:
-      printf("unknown qualifer!");
-   }
-
-   switch (t->specifier.type) {
-   case SLANG_SPEC_VOID:
-      printf("void");
-      break;
-   case SLANG_SPEC_BOOL:
-      printf("bool");
-      break;
-   case SLANG_SPEC_BVEC2:
-      printf("bvec2");
-      break;
-   case SLANG_SPEC_BVEC3:
-      printf("bvec3");
-      break;
-   case SLANG_SPEC_BVEC4:
-      printf("bvec4");
-      break;
-   case SLANG_SPEC_INT:
-      printf("int");
-      break;
-   case SLANG_SPEC_IVEC2:
-      printf("ivec2");
-      break;
-   case SLANG_SPEC_IVEC3:
-      printf("ivec3");
-      break;
-   case SLANG_SPEC_IVEC4:
-      printf("ivec4");
-      break;
-   case SLANG_SPEC_FLOAT:
-      printf("float");
-      break;
-   case SLANG_SPEC_VEC2:
-      printf("vec2");
-      break;
-   case SLANG_SPEC_VEC3:
-      printf("vec3");
-      break;
-   case SLANG_SPEC_VEC4:
-      printf("vec4");
-      break;
-   case SLANG_SPEC_MAT2:
-      printf("mat2");
-      break;
-   case SLANG_SPEC_MAT3:
-      printf("mat3");
-      break;
-   case SLANG_SPEC_MAT4:
-      printf("mat4");
-      break;
-   case SLANG_SPEC_MAT23:
-      printf("mat2x3");
-      break;
-   case SLANG_SPEC_MAT32:
-      printf("mat3x2");
-      break;
-   case SLANG_SPEC_MAT24:
-      printf("mat2x4");
-      break;
-   case SLANG_SPEC_MAT42:
-      printf("mat4x2");
-      break;
-   case SLANG_SPEC_MAT34:
-      printf("mat3x4");
-      break;
-   case SLANG_SPEC_MAT43:
-      printf("mat4x3");
-      break;
-   case SLANG_SPEC_SAMPLER_1D:
-      printf("sampler1D");
-      break;
-   case SLANG_SPEC_SAMPLER_2D:
-      printf("sampler2D");
-      break;
-   case SLANG_SPEC_SAMPLER_3D:
-      printf("sampler3D");
-      break;
-   case SLANG_SPEC_SAMPLER_CUBE:
-      printf("samplerCube");
-      break;
-   case SLANG_SPEC_SAMPLER_1D_SHADOW:
-      printf("sampler1DShadow");
-      break;
-   case SLANG_SPEC_SAMPLER_2D_SHADOW:
-      printf("sampler2DShadow");
-      break;
-   case SLANG_SPEC_STRUCT:
-      printf("struct");
-      break;
-   case SLANG_SPEC_ARRAY:
-      printf("array");
-      break;
-   default:
-      printf("unknown type");
-   }
-   /*printf("\n");*/
-}
-
-
-static void
-print_variable(const slang_variable *v, int indent)
-{
-   spaces(indent);
-   printf("VAR ");
-   print_type(&v->type);
-   printf(" %s (at %p)", (char *) v->a_name, (void *) v);
-   if (v->initializer) {
-      printf(" :=\n");
-      slang_print_tree(v->initializer, indent + 3);
-   }
-   else {
-      printf(";\n");
-   }
-}
-
-
-static void
-print_binary(const slang_operation *op, const char *oper, int indent)
-{
-   assert(op->num_children == 2);
-#if 0
-   printf("binary at %p locals=%p outer=%p\n",
-          (void *) op,
-          (void *) op->locals,
-          (void *) op->locals->outer_scope);
-#endif
-   slang_print_tree(&op->children[0], indent + 3);
-   spaces(indent);
-   printf("%s at %p locals=%p outer=%p\n",
-          oper, (void *) op, (void *) op->locals,
-          (void *) op->locals->outer_scope);
-   slang_print_tree(&op->children[1], indent + 3);
-}
-
-
-static void
-print_generic2(const slang_operation *op, const char *oper,
-               const char *s, int indent)
-{
-   GLuint i;
-   if (oper) {
-      spaces(indent);
-      printf("%s %s at %p locals=%p outer=%p\n",
-             oper, s, (void *) op, (void *) op->locals, 
-             (void *) op->locals->outer_scope);
-   }
-   for (i = 0; i < op->num_children; i++) {
-      spaces(indent);
-      printf("//child %u of %u:\n", i, op->num_children);
-      slang_print_tree(&op->children[i], indent);
-   }
-}
-
-static void
-print_generic(const slang_operation *op, const char *oper, int indent)
-{
-   print_generic2(op, oper, "", indent);
-}
-
-
-static const slang_variable_scope *
-find_scope(const slang_variable_scope *s, slang_atom name)
-{
-   GLuint i;
-   for (i = 0; i < s->num_variables; i++) {
-      if (s->variables[i]->a_name == name)
-         return s;
-   }
-   if (s->outer_scope)
-      return find_scope(s->outer_scope, name);
-   else
-      return NULL;
-}
-
-static const slang_variable *
-find_var(const slang_variable_scope *s, slang_atom name)
-{
-   GLuint i;
-   for (i = 0; i < s->num_variables; i++) {
-      if (s->variables[i]->a_name == name)
-         return s->variables[i];
-   }
-   if (s->outer_scope)
-      return find_var(s->outer_scope, name);
-   else
-      return NULL;
-}
-
-
-void
-slang_print_tree(const slang_operation *op, int indent)
-{
-   GLuint i;
-
-   switch (op->type) {
-
-   case SLANG_OPER_NONE:
-      spaces(indent);
-      printf("SLANG_OPER_NONE\n");
-      break;
-
-   case SLANG_OPER_BLOCK_NO_NEW_SCOPE:
-      spaces(indent);
-      printf("{ locals=%p  outer=%p\n", (void*)op->locals, (void*)op->locals->outer_scope);
-      print_generic(op, NULL, indent+3);
-      spaces(indent);
-      printf("}\n");
-      break;
-
-   case SLANG_OPER_BLOCK_NEW_SCOPE:
-   case SLANG_OPER_NON_INLINED_CALL:
-      spaces(indent);
-      printf("{{ // new scope  locals=%p outer=%p: ",
-             (void *) op->locals,
-             (void *) op->locals->outer_scope);
-      for (i = 0; i < op->locals->num_variables; i++) {
-         printf("%s ", (char *) op->locals->variables[i]->a_name);
-      }
-      printf("\n");
-      print_generic(op, NULL, indent+3);
-      spaces(indent);
-      printf("}}\n");
-      break;
-
-   case SLANG_OPER_VARIABLE_DECL:
-      assert(op->num_children == 0 || op->num_children == 1);
-      {
-         slang_variable *v;
-         v = _slang_variable_locate(op->locals, op->a_id, GL_TRUE);
-         if (v) {
-            const slang_variable_scope *scope;
-            spaces(indent);
-            printf("DECL (locals=%p outer=%p) ", (void*)op->locals, (void*) op->locals->outer_scope);
-            print_type(&v->type);
-            printf(" %s (%p)", (char *) op->a_id,
-                   (void *) find_var(op->locals, op->a_id));
-
-            scope = find_scope(op->locals, op->a_id);
-            printf(" (in scope %p) ", (void *) scope);
-            assert(scope);
-            if (op->num_children == 1) {
-               printf(" :=\n");
-               slang_print_tree(&op->children[0], indent + 3);
-            }
-            else if (v->initializer) {
-               printf(" := INITIALIZER\n");
-               slang_print_tree(v->initializer, indent + 3);
-            }
-            else {
-               printf(";\n");
-            }
-            /*
-            spaces(indent);
-            printf("TYPE: ");
-            print_type(&v->type);
-            spaces(indent);
-            printf("ADDR: %d  size: %d\n", v->address, v->size);
-            */
-         }
-         else {
-            spaces(indent);
-            printf("DECL %s (anonymous variable!!!!)\n", (char *) op->a_id);
-         }
-      }
-      break;
-
-   case SLANG_OPER_ASM:
-      spaces(indent);
-      printf("ASM: %s at %p locals=%p outer=%p\n",
-             (char *) op->a_id,
-             (void *) op,
-             (void *) op->locals,
-             (void *) op->locals->outer_scope);
-      print_generic(op, "ASM", indent+3);
-      break;
-
-   case SLANG_OPER_BREAK:
-      spaces(indent);
-      printf("BREAK\n");
-      break;
-
-   case SLANG_OPER_CONTINUE:
-      spaces(indent);
-      printf("CONTINUE\n");
-      break;
-
-   case SLANG_OPER_DISCARD:
-      spaces(indent);
-      printf("DISCARD\n");
-      break;
-
-   case SLANG_OPER_RETURN:
-      spaces(indent);
-      printf("RETURN\n");
-      if (op->num_children > 0)
-         slang_print_tree(&op->children[0], indent + 3);
-      break;
-
-   case SLANG_OPER_RETURN_INLINED:
-      spaces(indent);
-      printf("RETURN_INLINED\n");
-      if (op->num_children > 0)
-         slang_print_tree(&op->children[0], indent + 3);
-      break;
-
-   case SLANG_OPER_LABEL:
-      spaces(indent);
-      printf("LABEL %s\n", (char *) op->a_id);
-      break;
-
-   case SLANG_OPER_EXPRESSION:
-      spaces(indent);
-      printf("EXPR:  locals=%p outer=%p\n",
-             (void *) op->locals,
-             (void *) op->locals->outer_scope);
-      /*print_generic(op, "SLANG_OPER_EXPRESSION", indent);*/
-      slang_print_tree(&op->children[0], indent + 3);
-      break;
-
-   case SLANG_OPER_IF:
-      spaces(indent);
-      printf("IF\n");
-      slang_print_tree(&op->children[0], indent + 3);
-      spaces(indent);
-      printf("THEN\n");
-      slang_print_tree(&op->children[1], indent + 3);
-      spaces(indent);
-      printf("ELSE\n");
-      slang_print_tree(&op->children[2], indent + 3);
-      spaces(indent);
-      printf("ENDIF\n");
-      break;
-
-   case SLANG_OPER_WHILE:
-      assert(op->num_children == 2);
-      spaces(indent);
-      printf("WHILE LOOP: locals = %p\n", (void *) op->locals);
-      indent += 3;
-      spaces(indent);
-      printf("WHILE cond:\n");
-      slang_print_tree(&op->children[0], indent + 3);
-      spaces(indent);
-      printf("WHILE body:\n");
-      slang_print_tree(&op->children[1], indent + 3);
-      indent -= 3;
-      spaces(indent);
-      printf("END WHILE LOOP\n");
-      break;
-
-   case SLANG_OPER_DO:
-      spaces(indent);
-      printf("DO LOOP: locals = %p\n", (void *) op->locals);
-      indent += 3;
-      spaces(indent);
-      printf("DO body:\n");
-      slang_print_tree(&op->children[0], indent + 3);
-      spaces(indent);
-      printf("DO cond:\n");
-      slang_print_tree(&op->children[1], indent + 3);
-      indent -= 3;
-      spaces(indent);
-      printf("END DO LOOP\n");
-      break;
-
-   case SLANG_OPER_FOR:
-      spaces(indent);
-      printf("FOR LOOP: locals = %p\n", (void *) op->locals);
-      indent += 3;
-      spaces(indent);
-      printf("FOR init:\n");
-      slang_print_tree(&op->children[0], indent + 3);
-      spaces(indent);
-      printf("FOR condition:\n");
-      slang_print_tree(&op->children[1], indent + 3);
-      spaces(indent);
-      printf("FOR step:\n");
-      slang_print_tree(&op->children[2], indent + 3);
-      spaces(indent);
-      printf("FOR body:\n");
-      slang_print_tree(&op->children[3], indent + 3);
-      indent -= 3;
-      spaces(indent);
-      printf("ENDFOR\n");
-      /*
-      print_generic(op, "FOR", indent + 3);
-      */
-      break;
-
-   case SLANG_OPER_VOID:
-      spaces(indent);
-      printf("(oper-void)\n");
-      break;
-
-   case SLANG_OPER_LITERAL_BOOL:
-      spaces(indent);
-      printf("LITERAL (");
-      for (i = 0; i < op->literal_size; i++)
-         printf("%s ", op->literal[0] ? "TRUE" : "FALSE");
-      printf(")\n");
-
-      break;
-
-   case SLANG_OPER_LITERAL_INT:
-      spaces(indent);
-      printf("LITERAL (");
-      for (i = 0; i < op->literal_size; i++)
-         printf("%d ", (int) op->literal[i]);
-      printf(")\n");
-      break;
-
-   case SLANG_OPER_LITERAL_FLOAT:
-      spaces(indent);
-      printf("LITERAL (");
-      for (i = 0; i < op->literal_size; i++)
-         printf("%f ", op->literal[i]);
-      printf(")\n");
-      break;
-
-   case SLANG_OPER_IDENTIFIER:
-      {
-         const slang_variable_scope *scope;
-         spaces(indent);
-         if (op->var && op->var->a_name) {
-            scope = find_scope(op->locals, op->var->a_name);
-            printf("VAR %s  (in scope %p)\n", (char *) op->var->a_name,
-                   (void *) scope);
-            assert(scope);
-         }
-         else {
-            scope = find_scope(op->locals, op->a_id);
-            printf("VAR' %s  (in scope %p) locals=%p outer=%p\n",
-                   (char *) op->a_id,
-                   (void *) scope,
-                   (void *) op->locals,
-                   (void *) op->locals->outer_scope);
-            /*assert(scope);*/
-         }
-      }
-      break;
-
-   case SLANG_OPER_SEQUENCE:
-      print_generic(op, "COMMA-SEQ", indent+3);
-      break;
-
-   case SLANG_OPER_ASSIGN:
-      spaces(indent);
-      printf("ASSIGNMENT  locals=%p outer=%p\n",
-             (void *) op->locals,
-             (void *) op->locals->outer_scope);
-      print_binary(op, ":=", indent);
-      break;
-
-   case SLANG_OPER_ADDASSIGN:
-      spaces(indent);
-      printf("ASSIGN\n");
-      print_binary(op, "+=", indent);
-      break;
-
-   case SLANG_OPER_SUBASSIGN:
-      spaces(indent);
-      printf("ASSIGN\n");
-      print_binary(op, "-=", indent);
-      break;
-
-   case SLANG_OPER_MULASSIGN:
-      spaces(indent);
-      printf("ASSIGN\n");
-      print_binary(op, "*=", indent);
-      break;
-
-   case SLANG_OPER_DIVASSIGN:
-      spaces(indent);
-      printf("ASSIGN\n");
-      print_binary(op, "/=", indent);
-      break;
-
-       /*SLANG_OPER_MODASSIGN,*/
-       /*SLANG_OPER_LSHASSIGN,*/
-       /*SLANG_OPER_RSHASSIGN,*/
-       /*SLANG_OPER_ORASSIGN,*/
-       /*SLANG_OPER_XORASSIGN,*/
-       /*SLANG_OPER_ANDASSIGN,*/
-   case SLANG_OPER_SELECT:
-      spaces(indent);
-      printf("SLANG_OPER_SELECT n=%d\n", op->num_children);
-      assert(op->num_children == 3);
-      slang_print_tree(&op->children[0], indent+3);
-      spaces(indent);
-      printf("?\n");
-      slang_print_tree(&op->children[1], indent+3);
-      spaces(indent);
-      printf(":\n");
-      slang_print_tree(&op->children[2], indent+3);
-      break;
-
-   case SLANG_OPER_LOGICALOR:
-      print_binary(op, "||", indent);
-      break;
-
-   case SLANG_OPER_LOGICALXOR:
-      print_binary(op, "^^", indent);
-      break;
-
-   case SLANG_OPER_LOGICALAND:
-      print_binary(op, "&&", indent);
-      break;
-
-   /*SLANG_OPER_BITOR*/
-   /*SLANG_OPER_BITXOR*/
-   /*SLANG_OPER_BITAND*/
-   case SLANG_OPER_EQUAL:
-      print_binary(op, "==", indent);
-      break;
-
-   case SLANG_OPER_NOTEQUAL:
-      print_binary(op, "!=", indent);
-      break;
-
-   case SLANG_OPER_LESS:
-      print_binary(op, "<", indent);
-      break;
-
-   case SLANG_OPER_GREATER:
-      print_binary(op, ">", indent);
-      break;
-
-   case SLANG_OPER_LESSEQUAL:
-      print_binary(op, "<=", indent);
-      break;
-
-   case SLANG_OPER_GREATEREQUAL:
-      print_binary(op, ">=", indent);
-      break;
-
-   /*SLANG_OPER_LSHIFT*/
-   /*SLANG_OPER_RSHIFT*/
-   case SLANG_OPER_ADD:
-      print_binary(op, "+", indent);
-      break;
-
-   case SLANG_OPER_SUBTRACT:
-      print_binary(op, "-", indent);
-      break;
-
-   case SLANG_OPER_MULTIPLY:
-      print_binary(op, "*", indent);
-      break;
-
-   case SLANG_OPER_DIVIDE:
-      print_binary(op, "/", indent);
-      break;
-
-   /*SLANG_OPER_MODULUS*/
-   case SLANG_OPER_PREINCREMENT:
-      spaces(indent);
-      printf("PRE++\n");
-      slang_print_tree(&op->children[0], indent+3);
-      break;
-
-   case SLANG_OPER_PREDECREMENT:
-      spaces(indent);
-      printf("PRE--\n");
-      slang_print_tree(&op->children[0], indent+3);
-      break;
-
-   case SLANG_OPER_PLUS:
-      spaces(indent);
-      printf("SLANG_OPER_PLUS\n");
-      break;
-
-   case SLANG_OPER_MINUS:
-      spaces(indent);
-      printf("SLANG_OPER_MINUS\n");
-      break;
-
-   /*SLANG_OPER_COMPLEMENT*/
-   case SLANG_OPER_NOT:
-      spaces(indent);
-      printf("NOT\n");
-      slang_print_tree(&op->children[0], indent+3);
-      break;
-
-   case SLANG_OPER_SUBSCRIPT:
-      spaces(indent);
-      printf("SLANG_OPER_SUBSCRIPT locals=%p outer=%p\n",
-             (void *) op->locals,
-             (void *) op->locals->outer_scope);
-      print_generic(op, NULL, indent+3);
-      break;
-
-   case SLANG_OPER_CALL:
-#if 0
-         slang_function *fun
-            = _slang_function_locate(A->space.funcs, oper->a_id,
-                                     oper->children,
-                                     oper->num_children, &A->space, A->atoms);
-#endif
-      spaces(indent);
-      printf("CALL %s(\n", (char *) op->a_id);
-      for (i = 0; i < op->num_children; i++) {
-         slang_print_tree(&op->children[i], indent+3);
-         if (i + 1 < op->num_children) {
-            spaces(indent + 3);
-            printf(",\n");
-         }
-      }
-      spaces(indent);
-      printf(")\n");
-      break;
-
-   case SLANG_OPER_METHOD:
-      spaces(indent);
-      printf("METHOD CALL %s.%s\n", (char *) op->a_obj, (char *) op->a_id);
-      break;
-
-   case SLANG_OPER_FIELD:
-      spaces(indent);
-      printf("FIELD %s of\n", (char*) op->a_id);
-      slang_print_tree(&op->children[0], indent+3);
-      break;
-
-   case SLANG_OPER_POSTINCREMENT:
-      spaces(indent);
-      printf("POST++\n");
-      slang_print_tree(&op->children[0], indent+3);
-      break;
-
-   case SLANG_OPER_POSTDECREMENT:
-      spaces(indent);
-      printf("POST--\n");
-      slang_print_tree(&op->children[0], indent+3);
-      break;
-
-   default:
-      printf("unknown op->type %d\n", (int) op->type);
-   }
-
-}
-
-
-
-void
-slang_print_function(const slang_function *f, GLboolean body)
-{
-   GLuint i;
-
-#if 0
-   if (strcmp((char *) f->header.a_name, "main") != 0)
-     return;
-#endif
-
-   printf("FUNCTION %s ( scope=%p\n",
-          (char *) f->header.a_name, (void *) f->parameters);
-
-   for (i = 0; i < f->param_count; i++) {
-      print_variable(f->parameters->variables[i], 3);
-   }
-
-   printf(") param scope = %p\n", (void *) f->parameters);
-
-   if (body && f->body)
-      slang_print_tree(f->body, 0);
-}
-
-
-
-
-
-const char *
-slang_type_qual_string(slang_type_qualifier q)
-{
-   switch (q) {
-   case SLANG_QUAL_NONE:
-      return "none";
-   case SLANG_QUAL_CONST:
-      return "const";
-   case SLANG_QUAL_ATTRIBUTE:
-      return "attribute";
-   case SLANG_QUAL_VARYING:
-      return "varying";
-   case SLANG_QUAL_UNIFORM:
-      return "uniform";
-   case SLANG_QUAL_OUT:
-      return "out";
-   case SLANG_QUAL_INOUT:
-      return "inout";
-   case SLANG_QUAL_FIXEDOUTPUT:
-      return "fixedoutput";
-   case SLANG_QUAL_FIXEDINPUT:
-      return "fixedinputk";
-   default:
-      return "qual?";
-   }
-}
-
-
-static const char *
-slang_type_string(slang_type_specifier_type t)
-{
-   switch (t) {
-   case SLANG_SPEC_VOID:
-      return "void";
-   case SLANG_SPEC_BOOL:
-      return "bool";
-   case SLANG_SPEC_BVEC2:
-      return "bvec2";
-   case SLANG_SPEC_BVEC3:
-      return "bvec3";
-   case SLANG_SPEC_BVEC4:
-      return "bvec4";
-   case SLANG_SPEC_INT:
-      return "int";
-   case SLANG_SPEC_IVEC2:
-      return "ivec2";
-   case SLANG_SPEC_IVEC3:
-      return "ivec3";
-   case SLANG_SPEC_IVEC4:
-      return "ivec4";
-   case SLANG_SPEC_FLOAT:
-      return "float";
-   case SLANG_SPEC_VEC2:
-      return "vec2";
-   case SLANG_SPEC_VEC3:
-      return "vec3";
-   case SLANG_SPEC_VEC4:
-      return "vec4";
-   case SLANG_SPEC_MAT2:
-      return "mat2";
-   case SLANG_SPEC_MAT3:
-      return "mat3";
-   case SLANG_SPEC_MAT4:
-      return "mat4";
-   case SLANG_SPEC_SAMPLER_1D:
-      return "sampler1D";
-   case SLANG_SPEC_SAMPLER_2D:
-      return "sampler2D";
-   case SLANG_SPEC_SAMPLER_3D:
-      return "sampler3D";
-   case SLANG_SPEC_SAMPLER_CUBE:
-      return "samplerCube";
-   case SLANG_SPEC_SAMPLER_1D_SHADOW:
-      return "sampler1DShadow";
-   case SLANG_SPEC_SAMPLER_2D_SHADOW:
-      return "sampler2DShadow";
-   case SLANG_SPEC_SAMPLER_RECT:
-      return "sampler2DRect";
-   case SLANG_SPEC_SAMPLER_RECT_SHADOW:
-      return "sampler2DRectShadow";
-   case SLANG_SPEC_STRUCT:
-      return "struct";
-   case SLANG_SPEC_ARRAY:
-      return "array";
-   default:
-      return "type?";
-   }
-}
-
-
-static const char *
-slang_fq_type_string(const slang_fully_specified_type *t)
-{
-   static char str[1000];
-   _mesa_snprintf(str, sizeof(str), "%s %s", slang_type_qual_string(t->qualifier),
-      slang_type_string(t->specifier.type));
-   return str;
-}
-
-
-void
-slang_print_type(const slang_fully_specified_type *t)
-{
-   printf("%s %s", slang_type_qual_string(t->qualifier),
-      slang_type_string(t->specifier.type));
-}
-
-
-#if 0
-static char *
-slang_var_string(const slang_variable *v)
-{
-   static char str[1000];
-   _mesa_snprintf(str, sizeof(str), "%s : %s",
-                  (char *) v->a_name,
-                  slang_fq_type_string(&v->type));
-   return str;
-}
-#endif
-
-
-void
-slang_print_variable(const slang_variable *v)
-{
-   printf("Name: %s\n", (char *) v->a_name);
-   printf("Type: %s\n", slang_fq_type_string(&v->type));
-}
-
-
-void
-_slang_print_var_scope(const slang_variable_scope *vars, int indent)
-{
-   GLuint i;
-
-   spaces(indent);
-   printf("Var scope %p  %d vars:\n", (void *) vars, vars->num_variables);
-   for (i = 0; i < vars->num_variables; i++) {
-      spaces(indent + 3);
-      printf("%s (at %p)\n", (char *) vars->variables[i]->a_name, (void*) (vars->variables + i));
-   }
-   spaces(indent + 3);
-   printf("outer_scope = %p\n", (void*) vars->outer_scope);
-
-   if (vars->outer_scope) {
-      /*spaces(indent + 3);*/
-      _slang_print_var_scope(vars->outer_scope, indent + 3);
-   }
-}
-
-
-
-int
-slang_checksum_tree(const slang_operation *op)
-{
-   int s = op->num_children;
-   GLuint i;
-
-   for (i = 0; i < op->num_children; i++) {
-      s += slang_checksum_tree(&op->children[i]);
-   }
-   return s;
-}
diff --git a/src/mesa/shader/slang/slang_print.h b/src/mesa/shader/slang/slang_print.h
deleted file mode 100644 (file)
index 46605c8..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-#ifndef SLANG_PRINT
-#define SLANG_PRINT
-
-extern void
-slang_print_function(const slang_function *f, GLboolean body);
-
-extern void
-slang_print_tree(const slang_operation *op, int indent);
-
-extern const char *
-slang_type_qual_string(slang_type_qualifier q);
-
-extern void
-slang_print_type(const slang_fully_specified_type *t);
-
-extern void
-slang_print_variable(const slang_variable *v);
-
-extern void
-_slang_print_var_scope(const slang_variable_scope *s, int indent);
-
-
-extern int
-slang_checksum_tree(const slang_operation *op);
-
-#endif /* SLANG_PRINT */
-
diff --git a/src/mesa/shader/slang/slang_simplify.c b/src/mesa/shader/slang/slang_simplify.c
deleted file mode 100644 (file)
index 13b9ca3..0000000
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.1
- *
- * Copyright (C) 2005-2008  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.
- */
-
-/**
- * Functions for constant folding, built-in constant lookup, and function
- * call casting.
- */
-
-
-#include "main/imports.h"
-#include "main/macros.h"
-#include "main/get.h"
-#include "slang_compile.h"
-#include "slang_codegen.h"
-#include "slang_simplify.h"
-#include "slang_print.h"
-
-
-#ifndef GL_MAX_FRAGMENT_UNIFORM_VECTORS
-#define GL_MAX_FRAGMENT_UNIFORM_VECTORS     0x8DFD
-#endif
-#ifndef GL_MAX_VERTEX_UNIFORM_VECTORS
-#define GL_MAX_VERTEX_UNIFORM_VECTORS       0x8DFB
-#endif
-#ifndef GL_MAX_VARYING_VECTORS
-#define GL_MAX_VARYING_VECTORS              0x8DFC
-#endif
-
-
-/**
- * Lookup the value of named constant, such as gl_MaxLights.
- * \return value of constant, or -1 if unknown
- */
-GLint
-_slang_lookup_constant(const char *name)
-{
-   struct constant_info {
-      const char *Name;
-      const GLenum Token;
-   };
-   static const struct constant_info info[] = {
-      { "gl_MaxClipPlanes", GL_MAX_CLIP_PLANES },
-      { "gl_MaxCombinedTextureImageUnits", GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS },
-      { "gl_MaxDrawBuffers", GL_MAX_DRAW_BUFFERS },
-      { "gl_MaxFragmentUniformComponents", GL_MAX_FRAGMENT_UNIFORM_COMPONENTS },
-      { "gl_MaxLights", GL_MAX_LIGHTS },
-      { "gl_MaxTextureUnits", GL_MAX_TEXTURE_UNITS },
-      { "gl_MaxTextureCoords", GL_MAX_TEXTURE_COORDS },
-      { "gl_MaxVertexAttribs", GL_MAX_VERTEX_ATTRIBS },
-      { "gl_MaxVertexUniformComponents", GL_MAX_VERTEX_UNIFORM_COMPONENTS },
-      { "gl_MaxVaryingFloats", GL_MAX_VARYING_FLOATS },
-      { "gl_MaxVertexTextureImageUnits", GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS },
-      { "gl_MaxTextureImageUnits", GL_MAX_TEXTURE_IMAGE_UNITS },
-#if FEATURE_es2_glsl
-      { "gl_MaxVertexUniformVectors", GL_MAX_VERTEX_UNIFORM_VECTORS },
-      { "gl_MaxVaryingVectors", GL_MAX_VARYING_VECTORS },
-      { "gl_MaxFragmentUniformVectors", GL_MAX_FRAGMENT_UNIFORM_VECTORS },
-#endif
-      { NULL, 0 }
-   };
-   GLuint i;
-
-   for (i = 0; info[i].Name; i++) {
-      if (strcmp(info[i].Name, name) == 0) {
-         /* found */
-         GLint values[16];
-         values[0] = -1;
-         _mesa_GetIntegerv(info[i].Token, values);
-         ASSERT(values[0] >= 0);  /* sanity check that glGetFloatv worked */
-         return values[0];
-      }
-   }
-   return -1;
-}
-
-
-static slang_operation_type
-literal_type(slang_operation_type t1, slang_operation_type t2)
-{
-   if (t1 == SLANG_OPER_LITERAL_FLOAT || t2 == SLANG_OPER_LITERAL_FLOAT)
-      return SLANG_OPER_LITERAL_FLOAT;
-   else
-      return SLANG_OPER_LITERAL_INT;
-}
-
-
-/**
- * Recursively traverse an AST tree, applying simplifications wherever
- * possible.
- * At the least, we do constant folding.  We need to do that much so that
- * compile-time expressions can be evaluated for things like array
- * declarations.  I.e.:  float foo[3 + 5];
- */
-void
-_slang_simplify(slang_operation *oper,
-                const slang_name_space * space,
-                slang_atom_pool * atoms)
-{
-   GLboolean isFloat[4];
-   GLboolean isBool[4];
-   GLuint i, n;
-
-   if (oper->type == SLANG_OPER_IDENTIFIER) {
-      /* see if it's a named constant */
-      GLint value = _slang_lookup_constant((char *) oper->a_id);
-      /*printf("value[%s] = %d\n", (char*) oper->a_id, value);*/
-      if (value >= 0) {
-         oper->literal[0] =
-         oper->literal[1] =
-         oper->literal[2] =
-         oper->literal[3] = (GLfloat) value;
-         oper->type = SLANG_OPER_LITERAL_INT;
-         return;
-      }
-      /* look for user-defined constant */
-      {
-         slang_variable *var;
-         var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE);
-         if (var) {
-            if (var->type.qualifier == SLANG_QUAL_CONST &&
-                var->initializer &&
-                (var->initializer->type == SLANG_OPER_LITERAL_INT ||
-                 var->initializer->type == SLANG_OPER_LITERAL_FLOAT)) {
-               oper->literal[0] = var->initializer->literal[0];
-               oper->literal[1] = var->initializer->literal[1];
-               oper->literal[2] = var->initializer->literal[2];
-               oper->literal[3] = var->initializer->literal[3];
-               oper->literal_size = var->initializer->literal_size;
-               oper->type = var->initializer->type;
-               /*
-               printf("value[%s] = %f\n",
-                      (char*) oper->a_id, oper->literal[0]);
-               */
-               return;
-            }
-         }
-      }
-   }
-
-   /* first, simplify children */
-   for (i = 0; i < oper->num_children; i++) {
-      _slang_simplify(&oper->children[i], space, atoms);
-   }
-
-   /* examine children */
-   n = MIN2(oper->num_children, 4);
-   for (i = 0; i < n; i++) {
-      isFloat[i] = (oper->children[i].type == SLANG_OPER_LITERAL_FLOAT ||
-                   oper->children[i].type == SLANG_OPER_LITERAL_INT);
-      isBool[i] = (oper->children[i].type == SLANG_OPER_LITERAL_BOOL);
-   }
-                              
-   if (oper->num_children == 2 && isFloat[0] && isFloat[1]) {
-      /* probably simple arithmetic */
-      switch (oper->type) {
-      case SLANG_OPER_ADD:
-         for (i = 0; i < 4; i++) {
-            oper->literal[i]
-               = oper->children[0].literal[i] + oper->children[1].literal[i];
-         }
-         oper->literal_size = oper->children[0].literal_size;
-         oper->type = literal_type(oper->children[0].type, 
-                                   oper->children[1].type);
-         slang_operation_destruct(oper);  /* frees unused children */
-         return;
-      case SLANG_OPER_SUBTRACT:
-         for (i = 0; i < 4; i++) {
-            oper->literal[i]
-               = oper->children[0].literal[i] - oper->children[1].literal[i];
-         }
-         oper->literal_size = oper->children[0].literal_size;
-         oper->type = literal_type(oper->children[0].type, 
-                                   oper->children[1].type);
-         slang_operation_destruct(oper);
-         return;
-      case SLANG_OPER_MULTIPLY:
-         for (i = 0; i < 4; i++) {
-            oper->literal[i]
-               = oper->children[0].literal[i] * oper->children[1].literal[i];
-         }
-         oper->literal_size = oper->children[0].literal_size;
-         oper->type = literal_type(oper->children[0].type, 
-                                   oper->children[1].type);
-         slang_operation_destruct(oper);
-         return;
-      case SLANG_OPER_DIVIDE:
-         for (i = 0; i < 4; i++) {
-            oper->literal[i]
-               = oper->children[0].literal[i] / oper->children[1].literal[i];
-         }
-         oper->literal_size = oper->children[0].literal_size;
-         oper->type = literal_type(oper->children[0].type, 
-                                   oper->children[1].type);
-         slang_operation_destruct(oper);
-         return;
-      default:
-         ; /* nothing */
-      }
-   }
-
-   if (oper->num_children == 1 && isFloat[0]) {
-      switch (oper->type) {
-      case SLANG_OPER_MINUS:
-         for (i = 0; i < 4; i++) {
-            oper->literal[i] = -oper->children[0].literal[i];
-         }
-         oper->literal_size = oper->children[0].literal_size;
-         slang_operation_destruct(oper);
-         oper->type = SLANG_OPER_LITERAL_FLOAT;
-         return;
-      case SLANG_OPER_PLUS:
-         COPY_4V(oper->literal, oper->children[0].literal);
-         oper->literal_size = oper->children[0].literal_size;
-         slang_operation_destruct(oper);
-         oper->type = SLANG_OPER_LITERAL_FLOAT;
-         return;
-      default:
-         ; /* nothing */
-      }
-   }
-
-   if (oper->num_children == 2 && isBool[0] && isBool[1]) {
-      /* simple boolean expression */
-      switch (oper->type) {
-      case SLANG_OPER_LOGICALAND:
-         for (i = 0; i < 4; i++) {
-            const GLint a = oper->children[0].literal[i] ? 1 : 0;
-            const GLint b = oper->children[1].literal[i] ? 1 : 0;
-            oper->literal[i] = (GLfloat) (a && b);
-         }
-         oper->literal_size = oper->children[0].literal_size;
-         slang_operation_destruct(oper);
-         oper->type = SLANG_OPER_LITERAL_BOOL;
-         return;
-      case SLANG_OPER_LOGICALOR:
-         for (i = 0; i < 4; i++) {
-            const GLint a = oper->children[0].literal[i] ? 1 : 0;
-            const GLint b = oper->children[1].literal[i] ? 1 : 0;
-            oper->literal[i] = (GLfloat) (a || b);
-         }
-         oper->literal_size = oper->children[0].literal_size;
-         slang_operation_destruct(oper);
-         oper->type = SLANG_OPER_LITERAL_BOOL;
-         return;
-      case SLANG_OPER_LOGICALXOR:
-         for (i = 0; i < 4; i++) {
-            const GLint a = oper->children[0].literal[i] ? 1 : 0;
-            const GLint b = oper->children[1].literal[i] ? 1 : 0;
-            oper->literal[i] = (GLfloat) (a ^ b);
-         }
-         oper->literal_size = oper->children[0].literal_size;
-         slang_operation_destruct(oper);
-         oper->type = SLANG_OPER_LITERAL_BOOL;
-         return;
-      default:
-         ; /* nothing */
-      }
-   }
-
-   if (oper->num_children == 4
-       && isFloat[0] && isFloat[1] && isFloat[2] && isFloat[3]) {
-      /* vec4(flt, flt, flt, flt) constructor */
-      if (oper->type == SLANG_OPER_CALL) {
-         if (strcmp((char *) oper->a_id, "vec4") == 0) {
-            oper->literal[0] = oper->children[0].literal[0];
-            oper->literal[1] = oper->children[1].literal[0];
-            oper->literal[2] = oper->children[2].literal[0];
-            oper->literal[3] = oper->children[3].literal[0];
-            oper->literal_size = 4;
-            slang_operation_destruct(oper);
-            oper->type = SLANG_OPER_LITERAL_FLOAT;
-            return;
-         }
-      }
-   }
-
-   if (oper->num_children == 3 && isFloat[0] && isFloat[1] && isFloat[2]) {
-      /* vec3(flt, flt, flt) constructor */
-      if (oper->type == SLANG_OPER_CALL) {
-         if (strcmp((char *) oper->a_id, "vec3") == 0) {
-            oper->literal[0] = oper->children[0].literal[0];
-            oper->literal[1] = oper->children[1].literal[0];
-            oper->literal[2] = oper->children[2].literal[0];
-            oper->literal[3] = oper->literal[2];
-            oper->literal_size = 3;
-            slang_operation_destruct(oper);
-            oper->type = SLANG_OPER_LITERAL_FLOAT;
-            return;
-         }
-      }
-   }
-
-   if (oper->num_children == 2 && isFloat[0] && isFloat[1]) {
-      /* vec2(flt, flt) constructor */
-      if (oper->type == SLANG_OPER_CALL) {
-         if (strcmp((char *) oper->a_id, "vec2") == 0) {
-            oper->literal[0] = oper->children[0].literal[0];
-            oper->literal[1] = oper->children[1].literal[0];
-            oper->literal[2] = oper->literal[1];
-            oper->literal[3] = oper->literal[1];
-            oper->literal_size = 2;
-            slang_operation_destruct(oper); /* XXX oper->locals goes NULL! */
-            oper->type = SLANG_OPER_LITERAL_FLOAT;
-            assert(oper->num_children == 0);
-            return;
-         }
-      }
-   }
-
-   if (oper->num_children == 1 && isFloat[0]) {
-      /* vec2/3/4(flt, flt) constructor */
-      if (oper->type == SLANG_OPER_CALL) {
-         const char *func = (const char *) oper->a_id;
-         if (strncmp(func, "vec", 3) == 0 && func[3] >= '2' && func[3] <= '4') {
-            oper->literal[0] =
-            oper->literal[1] =
-            oper->literal[2] =
-            oper->literal[3] = oper->children[0].literal[0];
-            oper->literal_size = func[3] - '0';
-            assert(oper->literal_size >= 2);
-            assert(oper->literal_size <= 4);
-            slang_operation_destruct(oper); /* XXX oper->locals goes NULL! */
-            oper->type = SLANG_OPER_LITERAL_FLOAT;
-            assert(oper->num_children == 0);
-            return;
-         }
-      }
-   }
-}
-
-
-
-/**
- * Insert casts to try to adapt actual parameters to formal parameters for a
- * function call when an exact match for the parameter types is not found.
- * Example:
- *   void foo(int i, bool b) {}
- *   x = foo(3.15, 9);
- * Gets translated into:
- *   x = foo(int(3.15), bool(9))
- */
-GLboolean
-_slang_cast_func_params(slang_operation *callOper, const slang_function *fun,
-                        const slang_name_space * space,
-                        slang_atom_pool * atoms, slang_info_log *log)
-{
-   const GLboolean haveRetValue = _slang_function_has_return_value(fun);
-   const int numParams = fun->param_count - haveRetValue;
-   int i;
-   int dbg = 0;
-
-   if (dbg)
-      printf("Adapt call of %d args to func %s (%d params)\n",
-             callOper->num_children, (char*) fun->header.a_name, numParams);
-
-   for (i = 0; i < numParams; i++) {
-      slang_typeinfo argType;
-      slang_variable *paramVar = fun->parameters->variables[i];
-
-      /* Get type of arg[i] */
-      if (!slang_typeinfo_construct(&argType))
-         return GL_FALSE;
-      if (!_slang_typeof_operation(&callOper->children[i], space,
-                                    &argType, atoms, log)) {
-         slang_typeinfo_destruct(&argType);
-         return GL_FALSE;
-      }
-
-      /* see if arg type matches parameter type */
-      if (!slang_type_specifier_equal(&argType.spec,
-                                      &paramVar->type.specifier)) {
-         /* need to adapt arg type to match param type */
-         const char *constructorName =
-            slang_type_specifier_type_to_string(paramVar->type.specifier.type);
-         slang_operation *child = slang_operation_new(1);
-
-         if (dbg)
-            printf("Need to adapt types of arg %d\n", i);
-
-         slang_operation_copy(child, &callOper->children[i]);
-         child->locals->outer_scope = callOper->children[i].locals;
-
-#if 0
-         if (_slang_sizeof_type_specifier(&argType.spec) >
-             _slang_sizeof_type_specifier(&paramVar->type.specifier)) {
-         }
-#endif
-
-         callOper->children[i].type = SLANG_OPER_CALL;
-         callOper->children[i].a_id = slang_atom_pool_atom(atoms, constructorName);
-         callOper->children[i].num_children = 1;
-         callOper->children[i].children = child;
-      }
-
-      slang_typeinfo_destruct(&argType);
-   }
-
-   if (dbg) {
-      printf("===== New call to %s with cast arguments ===============\n",
-             (char*) fun->header.a_name);
-      slang_print_tree(callOper, 5);
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Adapt the arguments for a function call to match the parameters of
- * the given function.
- * This is for:
- * 1. converting/casting argument types to match parameters
- * 2. breaking up vector/matrix types into individual components to
- *    satisfy constructors.
- */
-GLboolean
-_slang_adapt_call(slang_operation *callOper, const slang_function *fun,
-                  const slang_name_space * space,
-                  slang_atom_pool * atoms, slang_info_log *log)
-{
-   const GLboolean haveRetValue = _slang_function_has_return_value(fun);
-   const int numParams = fun->param_count - haveRetValue;
-   int i;
-   int dbg = 0;
-
-   if (dbg)
-      printf("Adapt %d args to %d parameters for %s\n",
-             callOper->num_children, numParams, (char *) fun->header.a_name);
-
-   /* Only try adapting for constructors */
-   if (fun->kind != SLANG_FUNC_CONSTRUCTOR)
-      return GL_FALSE;
-
-   if (callOper->num_children != numParams) {
-      /* number of arguments doesn't match number of parameters */
-
-      /* For constructor calls, we can try to unroll vector/matrix args
-       * into individual floats/ints and try to match the function params.
-       */
-      for (i = 0; i < numParams; i++) {
-         slang_typeinfo argType;
-         GLint argSz, j;
-
-         /* Get type of arg[i] */
-         if (!slang_typeinfo_construct(&argType))
-            return GL_FALSE;
-         if (!_slang_typeof_operation(&callOper->children[i], space,
-                                       &argType, atoms, log)) {
-            slang_typeinfo_destruct(&argType);
-            return GL_FALSE;
-         }
-
-         /*
-           paramSz = _slang_sizeof_type_specifier(&paramVar->type.specifier);
-           assert(paramSz == 1);
-         */
-         argSz = _slang_sizeof_type_specifier(&argType.spec);
-         if (argSz > 1) {
-            slang_operation origArg;
-            /* break up arg[i] into components */
-            if (dbg)
-               printf("Break up arg %d from 1 to %d elements\n", i, argSz);
-
-            slang_operation_construct(&origArg);
-            slang_operation_copy(&origArg, &callOper->children[i]);
-
-            /* insert argSz-1 new children/args */
-            for (j = 0; j < argSz - 1; j++) {
-               (void) slang_operation_insert(&callOper->num_children,
-                                             &callOper->children, i);
-            }
-
-            /* replace arg[i+j] with subscript/index oper */
-            for (j = 0; j < argSz; j++) {
-               callOper->children[i + j].type = SLANG_OPER_SUBSCRIPT;
-               callOper->children[i + j].locals = _slang_variable_scope_new(callOper->locals);
-               callOper->children[i + j].num_children = 2;
-               callOper->children[i + j].children = slang_operation_new(2);
-               slang_operation_copy(&callOper->children[i + j].children[0],
-                                    &origArg);
-               callOper->children[i + j].children[1].type
-                  = SLANG_OPER_LITERAL_INT;
-               callOper->children[i + j].children[1].literal[0] = (GLfloat) j;
-            }
-         }
-      }
-   }
-
-   if (callOper->num_children < (GLuint) numParams) {
-      /* still not enough args for all params */
-      return GL_FALSE;
-   }
-   else if (callOper->num_children > (GLuint) numParams) {
-      /* now too many arguments */
-      /* just truncate */
-      callOper->num_children = (GLuint) numParams;
-   }
-
-   if (dbg) {
-      printf("===== New call to %s with adapted arguments ===============\n",
-             (char*) fun->header.a_name);
-      slang_print_tree(callOper, 5);
-   }
-
-   return GL_TRUE;
-}
diff --git a/src/mesa/shader/slang/slang_simplify.h b/src/mesa/shader/slang/slang_simplify.h
deleted file mode 100644 (file)
index 8689c23..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  7.1
- *
- * Copyright (C) 2005-2008  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 SLANG_SIMPLIFY_H
-#define SLANG_SIMPLIFY_H
-
-
-extern GLint
-_slang_lookup_constant(const char *name);
-
-
-extern void
-_slang_simplify(slang_operation *oper,
-                const slang_name_space * space,
-                slang_atom_pool * atoms);
-
-
-extern GLboolean
-_slang_cast_func_params(slang_operation *callOper, const slang_function *fun,
-                        const slang_name_space * space,
-                        slang_atom_pool * atoms, slang_info_log *log);
-
-extern GLboolean
-_slang_adapt_call(slang_operation *callOper, const slang_function *fun,
-                  const slang_name_space * space,
-                  slang_atom_pool * atoms, slang_info_log *log);
-
-
-#endif /* SLANG_SIMPLIFY_H */
diff --git a/src/mesa/shader/slang/slang_storage.c b/src/mesa/shader/slang/slang_storage.c
deleted file mode 100644 (file)
index 656e156..0000000
+++ /dev/null
@@ -1,321 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5
- *
- * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file slang_storage.c
- * slang variable storage
- * \author Michal Krol
- */
-
-#include "main/imports.h"
-#include "slang_storage.h"
-#include "slang_mem.h"
-
-/* slang_storage_array */
-
-GLboolean
-slang_storage_array_construct(slang_storage_array * arr)
-{
-   arr->type = SLANG_STORE_AGGREGATE;
-   arr->aggregate = NULL;
-   arr->length = 0;
-   return GL_TRUE;
-}
-
-GLvoid
-slang_storage_array_destruct(slang_storage_array * arr)
-{
-   if (arr->aggregate != NULL) {
-      slang_storage_aggregate_destruct(arr->aggregate);
-      _slang_free(arr->aggregate);
-   }
-}
-
-/* slang_storage_aggregate */
-
-GLboolean
-slang_storage_aggregate_construct(slang_storage_aggregate * agg)
-{
-   agg->arrays = NULL;
-   agg->count = 0;
-   return GL_TRUE;
-}
-
-GLvoid
-slang_storage_aggregate_destruct(slang_storage_aggregate * agg)
-{
-   GLuint i;
-
-   for (i = 0; i < agg->count; i++)
-      slang_storage_array_destruct(agg->arrays + i);
-   _slang_free(agg->arrays);
-}
-
-static slang_storage_array *
-slang_storage_aggregate_push_new(slang_storage_aggregate * agg)
-{
-   slang_storage_array *arr = NULL;
-
-   agg->arrays = (slang_storage_array *)
-      _slang_realloc(agg->arrays,
-                     agg->count * sizeof(slang_storage_array),
-                     (agg->count + 1) * sizeof(slang_storage_array));
-   if (agg->arrays != NULL) {
-      arr = agg->arrays + agg->count;
-      if (!slang_storage_array_construct(arr))
-         return NULL;
-      agg->count++;
-   }
-   return arr;
-}
-
-/* _slang_aggregate_variable() */
-
-static GLboolean
-aggregate_vector(slang_storage_aggregate * agg, slang_storage_type basic_type,
-                 GLuint row_count)
-{
-   slang_storage_array *arr = slang_storage_aggregate_push_new(agg);
-   if (arr == NULL)
-      return GL_FALSE;
-   arr->type = basic_type;
-   arr->length = row_count;
-   return GL_TRUE;
-}
-
-static GLboolean
-aggregate_matrix(slang_storage_aggregate * agg, slang_storage_type basic_type,
-                 GLuint columns, GLuint rows)
-{
-   slang_storage_array *arr = slang_storage_aggregate_push_new(agg);
-   if (arr == NULL)
-      return GL_FALSE;
-   arr->type = SLANG_STORE_AGGREGATE;
-   arr->length = columns;
-   arr->aggregate = (slang_storage_aggregate *)
-      _slang_alloc(sizeof(slang_storage_aggregate));
-   if (arr->aggregate == NULL)
-      return GL_FALSE;
-   if (!slang_storage_aggregate_construct(arr->aggregate)) {
-      _slang_free(arr->aggregate);
-      arr->aggregate = NULL;
-      return GL_FALSE;
-   }
-   if (!aggregate_vector(arr->aggregate, basic_type, rows))
-      return GL_FALSE;
-   return GL_TRUE;
-}
-
-
-static GLboolean
-aggregate_variables(slang_storage_aggregate * agg,
-                    slang_variable_scope * vars, slang_function_scope * funcs,
-                    slang_struct_scope * structs,
-                    slang_variable_scope * globals,
-                    slang_atom_pool * atoms)
-{
-   GLuint i;
-
-   for (i = 0; i < vars->num_variables; i++)
-      if (!_slang_aggregate_variable(agg, &vars->variables[i]->type.specifier,
-                                     vars->variables[i]->array_len, funcs,
-                                     structs, globals, atoms))
-         return GL_FALSE;
-   return GL_TRUE;
-}
-
-
-GLboolean
-_slang_aggregate_variable(slang_storage_aggregate * agg,
-                          slang_type_specifier * spec, GLuint array_len,
-                          slang_function_scope * funcs,
-                          slang_struct_scope * structs,
-                          slang_variable_scope * vars,
-                          slang_atom_pool * atoms)
-{
-   switch (spec->type) {
-   case SLANG_SPEC_BOOL:
-      return aggregate_vector(agg, SLANG_STORE_BOOL, 1);
-   case SLANG_SPEC_BVEC2:
-      return aggregate_vector(agg, SLANG_STORE_BOOL, 2);
-   case SLANG_SPEC_BVEC3:
-      return aggregate_vector(agg, SLANG_STORE_BOOL, 3);
-   case SLANG_SPEC_BVEC4:
-      return aggregate_vector(agg, SLANG_STORE_BOOL, 4);
-   case SLANG_SPEC_INT:
-      return aggregate_vector(agg, SLANG_STORE_INT, 1);
-   case SLANG_SPEC_IVEC2:
-      return aggregate_vector(agg, SLANG_STORE_INT, 2);
-   case SLANG_SPEC_IVEC3:
-      return aggregate_vector(agg, SLANG_STORE_INT, 3);
-   case SLANG_SPEC_IVEC4:
-      return aggregate_vector(agg, SLANG_STORE_INT, 4);
-   case SLANG_SPEC_FLOAT:
-      return aggregate_vector(agg, SLANG_STORE_FLOAT, 1);
-   case SLANG_SPEC_VEC2:
-      return aggregate_vector(agg, SLANG_STORE_FLOAT, 2);
-   case SLANG_SPEC_VEC3:
-      return aggregate_vector(agg, SLANG_STORE_FLOAT, 3);
-   case SLANG_SPEC_VEC4:
-      return aggregate_vector(agg, SLANG_STORE_FLOAT, 4);
-   case SLANG_SPEC_MAT2:
-      return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2, 2);
-   case SLANG_SPEC_MAT3:
-      return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 3);
-   case SLANG_SPEC_MAT4:
-      return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 4);
-
-   case SLANG_SPEC_MAT23:
-      return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2, 3);
-   case SLANG_SPEC_MAT32:
-      return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 2);
-   case SLANG_SPEC_MAT24:
-      return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2, 4);
-   case SLANG_SPEC_MAT42:
-      return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 2);
-   case SLANG_SPEC_MAT34:
-      return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 4);
-   case SLANG_SPEC_MAT43:
-      return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 3);
-
-   case SLANG_SPEC_SAMPLER_1D:
-   case SLANG_SPEC_SAMPLER_2D:
-   case SLANG_SPEC_SAMPLER_3D:
-   case SLANG_SPEC_SAMPLER_CUBE:
-   case SLANG_SPEC_SAMPLER_1D_SHADOW:
-   case SLANG_SPEC_SAMPLER_2D_SHADOW:
-   case SLANG_SPEC_SAMPLER_RECT:
-   case SLANG_SPEC_SAMPLER_RECT_SHADOW:
-   case SLANG_SPEC_SAMPLER_1D_ARRAY:
-   case SLANG_SPEC_SAMPLER_2D_ARRAY:
-   case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW:
-   case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW:
-
-      return aggregate_vector(agg, SLANG_STORE_INT, 1);
-   case SLANG_SPEC_STRUCT:
-      return aggregate_variables(agg, spec->_struct->fields, funcs, structs,
-                                 vars, atoms);
-   case SLANG_SPEC_ARRAY:
-      {
-         slang_storage_array *arr;
-
-         arr = slang_storage_aggregate_push_new(agg);
-         if (arr == NULL)
-            return GL_FALSE;
-         arr->type = SLANG_STORE_AGGREGATE;
-         arr->aggregate = (slang_storage_aggregate *)
-            _slang_alloc(sizeof(slang_storage_aggregate));
-         if (arr->aggregate == NULL)
-            return GL_FALSE;
-         if (!slang_storage_aggregate_construct(arr->aggregate)) {
-            _slang_free(arr->aggregate);
-            arr->aggregate = NULL;
-            return GL_FALSE;
-         }
-         if (!_slang_aggregate_variable(arr->aggregate, spec->_array, 0,
-                                        funcs, structs, vars, atoms))
-            return GL_FALSE;
-         arr->length = array_len;
-         /* TODO: check if 0 < arr->length <= 65535 */
-      }
-      return GL_TRUE;
-   default:
-      return GL_FALSE;
-   }
-}
-
-
-GLuint
-_slang_sizeof_type(slang_storage_type type)
-{
-   if (type == SLANG_STORE_AGGREGATE)
-      return 0;
-   if (type == SLANG_STORE_VEC4)
-      return 4 * sizeof(GLfloat);
-   return sizeof(GLfloat);
-}
-
-
-GLuint
-_slang_sizeof_aggregate(const slang_storage_aggregate * agg)
-{
-   GLuint i, size = 0;
-
-   for (i = 0; i < agg->count; i++) {
-      slang_storage_array *arr = &agg->arrays[i];
-      GLuint element_size;
-
-      if (arr->type == SLANG_STORE_AGGREGATE)
-         element_size = _slang_sizeof_aggregate(arr->aggregate);
-      else
-         element_size = _slang_sizeof_type(arr->type);
-      size += element_size * arr->length;
-   }
-   return size;
-}
-
-
-#if 0
-GLboolean
-_slang_flatten_aggregate(slang_storage_aggregate * flat,
-                         const slang_storage_aggregate * agg)
-{
-   GLuint i;
-
-   for (i = 0; i < agg->count; i++) {
-      GLuint j;
-
-      for (j = 0; j < agg->arrays[i].length; j++) {
-         if (agg->arrays[i].type == SLANG_STORE_AGGREGATE) {
-            if (!_slang_flatten_aggregate(flat, agg->arrays[i].aggregate))
-               return GL_FALSE;
-         }
-         else {
-            GLuint k, count;
-            slang_storage_type type;
-
-            if (agg->arrays[i].type == SLANG_STORE_VEC4) {
-               count = 4;
-               type = SLANG_STORE_FLOAT;
-            }
-            else {
-               count = 1;
-               type = agg->arrays[i].type;
-            }
-
-            for (k = 0; k < count; k++) {
-               slang_storage_array *arr;
-
-               arr = slang_storage_aggregate_push_new(flat);
-               if (arr == NULL)
-                  return GL_FALSE;
-               arr->type = type;
-               arr->length = 1;
-            }
-         }
-      }
-   }
-   return GL_TRUE;
-}
-#endif
diff --git a/src/mesa/shader/slang/slang_storage.h b/src/mesa/shader/slang/slang_storage.h
deleted file mode 100644 (file)
index 1876a36..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5
- *
- * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef SLANG_STORAGE_H
-#define SLANG_STORAGE_H
-
-#include "slang_compile.h"
-
-
-/*
- * Program variable data storage is kept completely transparent to the
- * front-end compiler. It is up to the back-end how the data is
- * actually allocated. The slang_storage_type enum provides the basic
- * information about how the memory is interpreted. This abstract
- * piece of memory is called a data slot. A data slot of a particular
- * type has a fixed size.
- *
- * For now, only the three basic types are supported, that is bool,
- * int and float. Other built-in types like vector or matrix can
- * easily be decomposed into a series of basic types.
- *
- * If the vec4 module is enabled, 4-component vectors of floats are
- * used when possible. 4x4 matrices are constructed of 4 vec4 slots.
- */
-typedef enum slang_storage_type_
-{
-   /* core */
-   SLANG_STORE_AGGREGATE,
-   SLANG_STORE_BOOL,
-   SLANG_STORE_INT,
-   SLANG_STORE_FLOAT,
-   /* vec4 */
-   SLANG_STORE_VEC4
-} slang_storage_type;
-
-
-/**
- * The slang_storage_array structure groups data slots of the same
- * type into an array. This array has a fixed length. Arrays are
- * required to have a size equal to the sum of sizes of its
- * elements. They are also required to support indirect
- * addressing. That is, if B references first data slot in the array,
- * S is the size of the data slot and I is the integral index that is
- * not known at compile time, B+I*S references I-th data slot.
- *
- * This structure is also used to break down built-in data types that
- * are not supported directly.  Vectors, like vec3, are constructed
- * from arrays of their basic types. Matrices are formed of an array
- * of column vectors, which are in turn processed as other vectors.
- */
-typedef struct slang_storage_array_
-{
-   slang_storage_type type;
-   struct slang_storage_aggregate_ *aggregate;
-   GLuint length;
-} slang_storage_array;
-
-GLboolean slang_storage_array_construct (slang_storage_array *);
-GLvoid slang_storage_array_destruct (slang_storage_array *);
-
-
-/**
- * The slang_storage_aggregate structure relaxes the indirect
- * addressing requirement for slang_storage_array
- * structure. Aggregates are always accessed statically - its member
- * addresses are well-known at compile time. For example, user-defined
- * types are implemented as aggregates. Aggregates can collect data of
- * a different type.
- */
-typedef struct slang_storage_aggregate_
-{
-   slang_storage_array *arrays;
-   GLuint count;
-} slang_storage_aggregate;
-
-GLboolean slang_storage_aggregate_construct (slang_storage_aggregate *);
-GLvoid slang_storage_aggregate_destruct (slang_storage_aggregate *);
-
-
-extern GLboolean
-_slang_aggregate_variable(slang_storage_aggregate *agg,
-                          slang_type_specifier *spec,
-                          GLuint array_len,
-                          slang_function_scope *funcs,
-                          slang_struct_scope *structs,
-                          slang_variable_scope *vars,
-                          slang_atom_pool *atoms);
-
-/*
- * Returns the size (in machine units) of the given storage type.
- * It is an error to pass-in SLANG_STORE_AGGREGATE.
- * Returns 0 on error.
- */
-extern GLuint
-_slang_sizeof_type (slang_storage_type);
-
-
-/**
- * Returns total size (in machine units) of the given aggregate.
- * Returns 0 on error.
- */
-extern GLuint
-_slang_sizeof_aggregate (const slang_storage_aggregate *);
-
-
-#if 0
-/**
- * Converts structured aggregate to a flat one, with arrays of generic
- * type being one-element long.  Returns GL_TRUE on success.  Returns
- * GL_FALSE otherwise.
- */
-extern GLboolean
-_slang_flatten_aggregate (slang_storage_aggregate *,
-                          const slang_storage_aggregate *);
-
-#endif
-
-#endif /* SLANG_STORAGE_H */
diff --git a/src/mesa/shader/slang/slang_typeinfo.c b/src/mesa/shader/slang/slang_typeinfo.c
deleted file mode 100644 (file)
index 0f96768..0000000
+++ /dev/null
@@ -1,1177 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5
- *
- * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file slang_typeinfo.c
- * slang type info
- * \author Michal Krol
- */
-
-#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"
-
-
-/**
- * Checks if a field selector is a general swizzle (an r-value swizzle
- * with replicated components or an l-value swizzle mask) for a
- * vector.  Returns GL_TRUE if this is the case, <swz> is filled with
- * swizzle information.  Returns GL_FALSE otherwise.
- */
-GLboolean
-_slang_is_swizzle(const char *field, GLuint rows, slang_swizzle * swz)
-{
-   GLuint i;
-   GLboolean xyzw = GL_FALSE, rgba = GL_FALSE, stpq = GL_FALSE;
-
-   /* init to undefined.
-    * We rely on undefined/nil values to distinguish between
-    * regular swizzles and writemasks.
-    * For example, the swizzle ".xNNN" is the writemask ".x".
-    * That's different than the swizzle ".xxxx".
-    */
-   for (i = 0; i < 4; i++)
-      swz->swizzle[i] = SWIZZLE_NIL;
-
-   /* the swizzle can be at most 4-component long */
-   swz->num_components = slang_string_length(field);
-   if (swz->num_components > 4)
-      return GL_FALSE;
-
-   for (i = 0; i < swz->num_components; i++) {
-      /* mark which swizzle group is used */
-      switch (field[i]) {
-      case 'x':
-      case 'y':
-      case 'z':
-      case 'w':
-         xyzw = GL_TRUE;
-         break;
-      case 'r':
-      case 'g':
-      case 'b':
-      case 'a':
-         rgba = GL_TRUE;
-         break;
-      case 's':
-      case 't':
-      case 'p':
-      case 'q':
-         stpq = GL_TRUE;
-         break;
-      default:
-         return GL_FALSE;
-      }
-
-      /* collect swizzle component */
-      switch (field[i]) {
-      case 'x':
-      case 'r':
-      case 's':
-         swz->swizzle[i] = 0;
-         break;
-      case 'y':
-      case 'g':
-      case 't':
-         swz->swizzle[i] = 1;
-         break;
-      case 'z':
-      case 'b':
-      case 'p':
-         swz->swizzle[i] = 2;
-         break;
-      case 'w':
-      case 'a':
-      case 'q':
-         swz->swizzle[i] = 3;
-         break;
-      }
-
-      /* check if the component is valid for given vector's row count */
-      if (rows <= swz->swizzle[i])
-         return GL_FALSE;
-   }
-
-   /* only one swizzle group can be used */
-   if ((xyzw && rgba) || (xyzw && stpq) || (rgba && stpq))
-      return GL_FALSE;
-
-   return GL_TRUE;
-}
-
-
-
-/**
- * Checks if a general swizzle is an l-value swizzle - these swizzles
- * do not have duplicated fields.  Returns GL_TRUE if this is a
- * swizzle mask.  Returns GL_FALSE otherwise
- */
-static GLboolean
-_slang_is_swizzle_mask(const slang_swizzle * swz, GLuint rows)
-{
-   GLuint i, c = 0;
-
-   /* the swizzle may not be longer than the vector dim */
-   if (swz->num_components > rows)
-      return GL_FALSE;
-
-   /* the swizzle components cannot be duplicated */
-   for (i = 0; i < swz->num_components; i++) {
-      if ((c & (1 << swz->swizzle[i])) != 0)
-         return GL_FALSE;
-      c |= 1 << swz->swizzle[i];
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Combines (multiplies) two swizzles to form single swizzle.
- * Example: "vec.wzyx.yx" --> "vec.zw".
- */
-static void
-_slang_multiply_swizzles(slang_swizzle * dst, const slang_swizzle * left,
-                         const slang_swizzle * right)
-{
-   GLuint i;
-
-   dst->num_components = right->num_components;
-   for (i = 0; i < right->num_components; i++)
-      dst->swizzle[i] = left->swizzle[right->swizzle[i]];
-}
-
-
-typedef struct
-{
-   const char *name;
-   slang_type_specifier_type type;
-} type_specifier_type_name;
-
-static const type_specifier_type_name type_specifier_type_names[] = {
-   {"void", SLANG_SPEC_VOID},
-   {"bool", SLANG_SPEC_BOOL},
-   {"bvec2", SLANG_SPEC_BVEC2},
-   {"bvec3", SLANG_SPEC_BVEC3},
-   {"bvec4", SLANG_SPEC_BVEC4},
-   {"int", SLANG_SPEC_INT},
-   {"ivec2", SLANG_SPEC_IVEC2},
-   {"ivec3", SLANG_SPEC_IVEC3},
-   {"ivec4", SLANG_SPEC_IVEC4},
-   {"float", SLANG_SPEC_FLOAT},
-   {"vec2", SLANG_SPEC_VEC2},
-   {"vec3", SLANG_SPEC_VEC3},
-   {"vec4", SLANG_SPEC_VEC4},
-   {"mat2", SLANG_SPEC_MAT2},
-   {"mat3", SLANG_SPEC_MAT3},
-   {"mat4", SLANG_SPEC_MAT4},
-   {"mat2x3", SLANG_SPEC_MAT23},
-   {"mat3x2", SLANG_SPEC_MAT32},
-   {"mat2x4", SLANG_SPEC_MAT24},
-   {"mat4x2", SLANG_SPEC_MAT42},
-   {"mat3x4", SLANG_SPEC_MAT34},
-   {"mat4x3", SLANG_SPEC_MAT43},
-   {"sampler1D", SLANG_SPEC_SAMPLER_1D},
-   {"sampler2D", SLANG_SPEC_SAMPLER_2D},
-   {"sampler3D", SLANG_SPEC_SAMPLER_3D},
-   {"samplerCube", SLANG_SPEC_SAMPLER_CUBE},
-   {"sampler1DShadow", SLANG_SPEC_SAMPLER_1D_SHADOW},
-   {"sampler2DShadow", SLANG_SPEC_SAMPLER_2D_SHADOW},
-   {"sampler2DRect", SLANG_SPEC_SAMPLER_RECT},
-   {"sampler2DRectShadow", SLANG_SPEC_SAMPLER_RECT_SHADOW},
-   {"sampler1DArray", SLANG_SPEC_SAMPLER_1D_ARRAY},
-   {"sampler2DArray", SLANG_SPEC_SAMPLER_2D_ARRAY},
-   {"sampler1DArrayShadow", SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW},
-   {"sampler2DArrayShadow", SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW},
-   {NULL, SLANG_SPEC_VOID}
-};
-
-slang_type_specifier_type
-slang_type_specifier_type_from_string(const char *name)
-{
-   const type_specifier_type_name *p = type_specifier_type_names;
-   while (p->name != NULL) {
-      if (slang_string_compare(p->name, name) == 0)
-         break;
-      p++;
-   }
-   return p->type;
-}
-
-const char *
-slang_type_specifier_type_to_string(slang_type_specifier_type type)
-{
-   const type_specifier_type_name *p = type_specifier_type_names;
-   while (p->name != NULL) {
-      if (p->type == type)
-         break;
-      p++;
-   }
-   return p->name;
-}
-
-/* slang_fully_specified_type */
-
-int
-slang_fully_specified_type_construct(slang_fully_specified_type * type)
-{
-   type->qualifier = SLANG_QUAL_NONE;
-   slang_type_specifier_ctr(&type->specifier);
-   return 1;
-}
-
-void
-slang_fully_specified_type_destruct(slang_fully_specified_type * type)
-{
-   slang_type_specifier_dtr(&type->specifier);
-}
-
-int
-slang_fully_specified_type_copy(slang_fully_specified_type * x,
-                                const slang_fully_specified_type * y)
-{
-   slang_fully_specified_type z;
-
-   if (!slang_fully_specified_type_construct(&z))
-      return 0;
-   z.qualifier = y->qualifier;
-   z.precision = y->precision;
-   z.variant = y->variant;
-   z.centroid = y->centroid;
-   z.layout = y->layout;
-   z.array_len = y->array_len;
-   if (!slang_type_specifier_copy(&z.specifier, &y->specifier)) {
-      slang_fully_specified_type_destruct(&z);
-      return 0;
-   }
-   slang_fully_specified_type_destruct(x);
-   *x = z;
-   return 1;
-}
-
-
-/**
- * Test if two fully specified types are compatible.  This is a bit
- * looser than testing for equality.  We don't check the precision,
- * variant, centroid, etc. information.
- * XXX this may need some tweaking.
- */
-GLboolean
-slang_fully_specified_types_compatible(const slang_fully_specified_type * x,
-                                       const slang_fully_specified_type * y)
-{
-   if (!slang_type_specifier_equal(&x->specifier, &y->specifier))
-      return GL_FALSE;
-
-   if (x->qualifier == SLANG_QUAL_FIXEDINPUT &&
-       y->qualifier == SLANG_QUAL_VARYING)
-      ; /* ok */
-   else if (x->qualifier != y->qualifier)
-      return GL_FALSE;
-
-   /* Note: don't compare precision, variant, centroid */
-
-   /* XXX array length? */
-
-   return GL_TRUE;
-}
-
-
-GLvoid
-slang_type_specifier_ctr(slang_type_specifier * self)
-{
-   self->type = SLANG_SPEC_VOID;
-   self->_struct = NULL;
-   self->_array = NULL;
-}
-
-GLvoid
-slang_type_specifier_dtr(slang_type_specifier * self)
-{
-   if (self->_struct != NULL) {
-      slang_struct_destruct(self->_struct);
-      _slang_free(self->_struct);
-   }
-   if (self->_array != NULL) {
-      slang_type_specifier_dtr(self->_array);
-      _slang_free(self->_array);
-   }
-}
-
-slang_type_specifier *
-slang_type_specifier_new(slang_type_specifier_type type,
-                         struct slang_struct_ *_struct,
-                         struct slang_type_specifier_ *_array)
-{
-   slang_type_specifier *spec =
-      (slang_type_specifier *) _slang_alloc(sizeof(slang_type_specifier));
-   if (spec) {
-      spec->type = type;
-      spec->_struct = _struct;
-      spec->_array = _array;
-   }
-   return spec;
-}
-
-GLboolean
-slang_type_specifier_copy(slang_type_specifier * x,
-                          const slang_type_specifier * y)
-{
-   slang_type_specifier z;
-
-   slang_type_specifier_ctr(&z);
-   z.type = y->type;
-   if (z.type == SLANG_SPEC_STRUCT) {
-      z._struct = (slang_struct *) _slang_alloc(sizeof(slang_struct));
-      if (z._struct == NULL) {
-         slang_type_specifier_dtr(&z);
-         return GL_FALSE;
-      }
-      if (!slang_struct_construct(z._struct)) {
-         _slang_free(z._struct);
-         slang_type_specifier_dtr(&z);
-         return GL_FALSE;
-      }
-      if (!slang_struct_copy(z._struct, y->_struct)) {
-         slang_type_specifier_dtr(&z);
-         return GL_FALSE;
-      }
-   }
-   else if (z.type == SLANG_SPEC_ARRAY) {
-      z._array = (slang_type_specifier *)
-         _slang_alloc(sizeof(slang_type_specifier));
-      if (z._array == NULL) {
-         slang_type_specifier_dtr(&z);
-         return GL_FALSE;
-      }
-      slang_type_specifier_ctr(z._array);
-      if (!slang_type_specifier_copy(z._array, y->_array)) {
-         slang_type_specifier_dtr(&z);
-         return GL_FALSE;
-      }
-   }
-   slang_type_specifier_dtr(x);
-   *x = z;
-   return GL_TRUE;
-}
-
-
-/**
- * Test if two types are equal.
- */
-GLboolean
-slang_type_specifier_equal(const slang_type_specifier * x,
-                           const slang_type_specifier * y)
-{
-   if (x->type != y->type)
-      return GL_FALSE;
-   if (x->type == SLANG_SPEC_STRUCT)
-      return slang_struct_equal(x->_struct, y->_struct);
-   if (x->type == SLANG_SPEC_ARRAY)
-      return slang_type_specifier_equal(x->_array, y->_array);
-   return GL_TRUE;
-}
-
-
-/**
- * As above, but allow float/int casting.
- */
-GLboolean
-slang_type_specifier_compatible(const slang_type_specifier * x,
-                                const slang_type_specifier * y)
-{
-   /* special case: float == int */
-   if (x->type == SLANG_SPEC_INT && y->type == SLANG_SPEC_FLOAT) {
-      return GL_TRUE;
-   }
-   /* XXX may need to add bool/int compatibility, etc */
-
-   if (x->type != y->type)
-      return GL_FALSE;
-   if (x->type == SLANG_SPEC_STRUCT)
-      return slang_struct_equal(x->_struct, y->_struct);
-   if (x->type == SLANG_SPEC_ARRAY)
-      return slang_type_specifier_compatible(x->_array, y->_array);
-   return GL_TRUE;
-}
-
-
-GLboolean
-slang_typeinfo_construct(slang_typeinfo * ti)
-{
-   memset(ti, 0, sizeof(*ti));
-   slang_type_specifier_ctr(&ti->spec);
-   ti->array_len = 0;
-   return GL_TRUE;
-}
-
-GLvoid
-slang_typeinfo_destruct(slang_typeinfo * ti)
-{
-   slang_type_specifier_dtr(&ti->spec);
-}
-
-
-
-/**
- * Determine the return type of a function.
- * \param a_name  the function name
- * \param param  function parameters (overloading)
- * \param num_params  number of parameters to function
- * \param space  namespace to search
- * \param spec  returns the type
- * \param funFound  returns pointer to the function, or NULL if not found.
- * \return GL_TRUE for success, GL_FALSE if failure (bad function name)
- */
-static GLboolean
-_slang_typeof_function(slang_atom a_name,
-                       slang_operation * params, GLuint num_params,
-                       const slang_name_space * space,
-                       slang_type_specifier * spec,
-                       slang_function **funFound,
-                       slang_atom_pool *atoms, slang_info_log *log)
-{
-   GLboolean error;
-
-   *funFound = _slang_function_locate(space->funcs, a_name, params,
-                                      num_params, space, atoms, log, &error);
-   if (error)
-      return GL_FALSE;
-
-   if (!*funFound)
-      return GL_TRUE;  /* yes, not false */
-
-   return slang_type_specifier_copy(spec, &(*funFound)->header.type.specifier);
-}
-
-
-/**
- * Determine the type of a math function.
- * \param name  name of the operator, one of +,-,*,/ or unary -
- * \param params  array of function parameters
- * \param num_params  number of parameters
- * \param space  namespace to use
- * \param spec  returns the function's type
- * \param atoms  atom pool
- * \return GL_TRUE for success, GL_FALSE if failure
- */
-static GLboolean
-typeof_math_call(const char *name, slang_operation *call,
-                 const slang_name_space * space,
-                 slang_type_specifier * spec,
-                 slang_atom_pool * atoms,
-                 slang_info_log *log)
-{
-   if (call->fun) {
-      /* we've previously resolved this function call */
-      slang_type_specifier_copy(spec, &call->fun->header.type.specifier);
-      return GL_TRUE;
-   }
-   else {
-      slang_atom atom;
-      slang_function *fun;
-
-      /* number of params: */
-      assert(call->num_children == 1 || call->num_children == 2);
-
-      atom = slang_atom_pool_atom(atoms, name);
-      if (!_slang_typeof_function(atom, call->children, call->num_children,
-                                  space, spec, &fun, atoms, log))
-         return GL_FALSE;
-
-      if (fun) {
-         /* Save pointer to save time in future */
-         call->fun = fun;
-         return GL_TRUE;
-      }
-      return GL_FALSE;
-   }
-}
-
-
-/**
- * Determine the return type of an operation.
- * \param op  the operation node
- * \param space  the namespace to use
- * \param ti  the returned type
- * \param atoms  atom pool
- * \return GL_TRUE for success, GL_FALSE if failure
- */
-GLboolean
-_slang_typeof_operation(slang_operation * op,
-                         const slang_name_space * space,
-                         slang_typeinfo * ti,
-                         slang_atom_pool * atoms,
-                         slang_info_log *log)
-{
-   ti->can_be_referenced = GL_FALSE;
-   ti->is_swizzled = GL_FALSE;
-
-   switch (op->type) {
-   case SLANG_OPER_BLOCK_NO_NEW_SCOPE:
-   case SLANG_OPER_BLOCK_NEW_SCOPE:
-   case SLANG_OPER_ASM:
-   case SLANG_OPER_BREAK:
-   case SLANG_OPER_CONTINUE:
-   case SLANG_OPER_DISCARD:
-   case SLANG_OPER_RETURN:
-   case SLANG_OPER_IF:
-   case SLANG_OPER_WHILE:
-   case SLANG_OPER_DO:
-   case SLANG_OPER_FOR:
-   case SLANG_OPER_VOID:
-      ti->spec.type = SLANG_SPEC_VOID;
-      break;
-   case SLANG_OPER_EXPRESSION:
-   case SLANG_OPER_ASSIGN:
-   case SLANG_OPER_ADDASSIGN:
-   case SLANG_OPER_SUBASSIGN:
-   case SLANG_OPER_MULASSIGN:
-   case SLANG_OPER_DIVASSIGN:
-   case SLANG_OPER_PREINCREMENT:
-   case SLANG_OPER_PREDECREMENT:
-      if (!_slang_typeof_operation(op->children, space, ti, atoms, log))
-         return GL_FALSE;
-      break;
-   case SLANG_OPER_LITERAL_BOOL:
-      if (op->literal_size == 1)
-         ti->spec.type = SLANG_SPEC_BOOL;
-      else if (op->literal_size == 2)
-         ti->spec.type = SLANG_SPEC_BVEC2;
-      else if (op->literal_size == 3)
-         ti->spec.type = SLANG_SPEC_BVEC3;
-      else if (op->literal_size == 4)
-         ti->spec.type = SLANG_SPEC_BVEC4;
-      else {
-         _mesa_problem(NULL,
-               "Unexpected bool literal_size %d in _slang_typeof_operation()",
-               op->literal_size);
-         ti->spec.type = SLANG_SPEC_BOOL;
-      }
-      break;
-   case SLANG_OPER_LOGICALOR:
-   case SLANG_OPER_LOGICALXOR:
-   case SLANG_OPER_LOGICALAND:
-   case SLANG_OPER_EQUAL:
-   case SLANG_OPER_NOTEQUAL:
-   case SLANG_OPER_LESS:
-   case SLANG_OPER_GREATER:
-   case SLANG_OPER_LESSEQUAL:
-   case SLANG_OPER_GREATEREQUAL:
-   case SLANG_OPER_NOT:
-      ti->spec.type = SLANG_SPEC_BOOL;
-      break;
-   case SLANG_OPER_LITERAL_INT:
-      if (op->literal_size == 1)
-         ti->spec.type = SLANG_SPEC_INT;
-      else if (op->literal_size == 2)
-         ti->spec.type = SLANG_SPEC_IVEC2;
-      else if (op->literal_size == 3)
-         ti->spec.type = SLANG_SPEC_IVEC3;
-      else if (op->literal_size == 4)
-         ti->spec.type = SLANG_SPEC_IVEC4;
-      else {
-         _mesa_problem(NULL,
-               "Unexpected int literal_size %d in _slang_typeof_operation()",
-               op->literal_size);
-         ti->spec.type = SLANG_SPEC_INT;
-      }
-      break;
-   case SLANG_OPER_LITERAL_FLOAT:
-      if (op->literal_size == 1)
-         ti->spec.type = SLANG_SPEC_FLOAT;
-      else if (op->literal_size == 2)
-         ti->spec.type = SLANG_SPEC_VEC2;
-      else if (op->literal_size == 3)
-         ti->spec.type = SLANG_SPEC_VEC3;
-      else if (op->literal_size == 4)
-         ti->spec.type = SLANG_SPEC_VEC4;
-      else {
-         _mesa_problem(NULL,
-               "Unexpected float literal_size %d in _slang_typeof_operation()",
-               op->literal_size);
-         ti->spec.type = SLANG_SPEC_FLOAT;
-      }
-      break;
-   case SLANG_OPER_IDENTIFIER:
-   case SLANG_OPER_VARIABLE_DECL:
-      {
-         slang_variable *var;
-         var = _slang_variable_locate(op->locals, op->a_id, GL_TRUE);
-         if (!var) {
-            slang_info_log_error(log, "undefined variable '%s'",
-                                 (char *) op->a_id);
-            return GL_FALSE;
-         }
-         if (!slang_type_specifier_copy(&ti->spec, &var->type.specifier)) {
-            slang_info_log_memory(log);
-            return GL_FALSE;
-         }
-         ti->can_be_referenced = GL_TRUE;
-         if (var->type.specifier.type == SLANG_SPEC_ARRAY &&
-             var->type.array_len >= 1) {
-            /* the datatype is an array, ex: float[3] x; */
-            ti->array_len = var->type.array_len;
-         }
-         else {
-            /* the variable is an array, ex: float x[3]; */
-            ti->array_len = var->array_len;
-         }
-      }
-      break;
-   case SLANG_OPER_SEQUENCE:
-      /* TODO: check [0] and [1] if they match */
-      if (!_slang_typeof_operation(&op->children[1], space, ti, atoms, log)) {
-         return GL_FALSE;
-      }
-      ti->can_be_referenced = GL_FALSE;
-      ti->is_swizzled = GL_FALSE;
-      break;
-      /*case SLANG_OPER_MODASSIGN: */
-      /*case SLANG_OPER_LSHASSIGN: */
-      /*case SLANG_OPER_RSHASSIGN: */
-      /*case SLANG_OPER_ORASSIGN: */
-      /*case SLANG_OPER_XORASSIGN: */
-      /*case SLANG_OPER_ANDASSIGN: */
-   case SLANG_OPER_SELECT:
-      /* TODO: check [1] and [2] if they match */
-      if (!_slang_typeof_operation(&op->children[1], space, ti, atoms, log)) {
-         return GL_FALSE;
-      }
-      ti->can_be_referenced = GL_FALSE;
-      ti->is_swizzled = GL_FALSE;
-      break;
-      /*case SLANG_OPER_BITOR: */
-      /*case SLANG_OPER_BITXOR: */
-      /*case SLANG_OPER_BITAND: */
-      /*case SLANG_OPER_LSHIFT: */
-      /*case SLANG_OPER_RSHIFT: */
-   case SLANG_OPER_ADD:
-      assert(op->num_children == 2);
-      if (!typeof_math_call("+", op, space, &ti->spec, atoms, log))
-         return GL_FALSE;
-      break;
-   case SLANG_OPER_SUBTRACT:
-      assert(op->num_children == 2);
-      if (!typeof_math_call("-", op, space, &ti->spec, atoms, log))
-         return GL_FALSE;
-      break;
-   case SLANG_OPER_MULTIPLY:
-      assert(op->num_children == 2);
-      if (!typeof_math_call("*", op, space, &ti->spec, atoms, log))
-         return GL_FALSE;
-      break;
-   case SLANG_OPER_DIVIDE:
-      assert(op->num_children == 2);
-      if (!typeof_math_call("/", op, space, &ti->spec, atoms, log))
-         return GL_FALSE;
-      break;
-   /*case SLANG_OPER_MODULUS: */
-   case SLANG_OPER_PLUS:
-      if (!_slang_typeof_operation(op->children, space, ti, atoms, log))
-         return GL_FALSE;
-      ti->can_be_referenced = GL_FALSE;
-      ti->is_swizzled = GL_FALSE;
-      break;
-   case SLANG_OPER_MINUS:
-      assert(op->num_children == 1);
-      if (!typeof_math_call("-", op, space, &ti->spec, atoms, log))
-         return GL_FALSE;
-      break;
-      /*case SLANG_OPER_COMPLEMENT: */
-   case SLANG_OPER_SUBSCRIPT:
-      {
-         slang_typeinfo _ti;
-
-         if (!slang_typeinfo_construct(&_ti))
-            return GL_FALSE;
-         if (!_slang_typeof_operation(op->children, space, &_ti, atoms, log)) {
-            slang_typeinfo_destruct(&_ti);
-            return GL_FALSE;
-         }
-         ti->can_be_referenced = _ti.can_be_referenced;
-         if (_ti.spec.type == SLANG_SPEC_ARRAY) {
-            if (!slang_type_specifier_copy(&ti->spec, _ti.spec._array)) {
-               slang_typeinfo_destruct(&_ti);
-               return GL_FALSE;
-            }
-         }
-         else {
-            if (!_slang_type_is_vector(_ti.spec.type)
-                && !_slang_type_is_matrix(_ti.spec.type)) {
-               slang_typeinfo_destruct(&_ti);
-               slang_info_log_error(log, "cannot index a non-array type");
-               return GL_FALSE;
-            }
-            ti->spec.type = _slang_type_base(_ti.spec.type);
-         }
-         slang_typeinfo_destruct(&_ti);
-      }
-      break;
-   case SLANG_OPER_CALL:
-      if (op->array_constructor) {
-         /* build array typeinfo */
-         ti->spec.type = SLANG_SPEC_ARRAY;
-         ti->spec._array = (slang_type_specifier *)
-            _slang_alloc(sizeof(slang_type_specifier));
-         slang_type_specifier_ctr(ti->spec._array);
-
-         ti->spec._array->type =
-            slang_type_specifier_type_from_string((char *) op->a_id);
-         ti->array_len = op->num_children;
-      }
-      else if (op->fun) {
-         /* we've resolved this call before */
-         slang_type_specifier_copy(&ti->spec, &op->fun->header.type.specifier);
-      }
-      else {
-         slang_function *fun;
-         if (!_slang_typeof_function(op->a_id, op->children, op->num_children,
-                                     space, &ti->spec, &fun, atoms, log))
-            return GL_FALSE;
-         if (fun) {
-            /* save result for future use */
-            op->fun = fun;
-         }
-         else {
-            slang_struct *s =
-               slang_struct_scope_find(space->structs, op->a_id, GL_TRUE);
-            if (s) {
-               /* struct initializer */
-               ti->spec.type = SLANG_SPEC_STRUCT;
-               ti->spec._struct =
-                  (slang_struct *) _slang_alloc(sizeof(slang_struct));
-               if (ti->spec._struct == NULL)
-                  return GL_FALSE;
-               if (!slang_struct_construct(ti->spec._struct)) {
-                  _slang_free(ti->spec._struct);
-                  ti->spec._struct = NULL;
-                  return GL_FALSE;
-               }
-               if (!slang_struct_copy(ti->spec._struct, s))
-                  return GL_FALSE;
-            }
-            else {
-               /* float, int, vec4, mat3, etc. constructor? */
-               const char *name;
-               slang_type_specifier_type type;
-
-               name = slang_atom_pool_id(atoms, op->a_id);
-               type = slang_type_specifier_type_from_string(name);
-               if (type == SLANG_SPEC_VOID) {
-                  slang_info_log_error(log, "undefined function '%s'", name);
-                  return GL_FALSE;
-               }
-               ti->spec.type = type;
-            }
-         }
-      }
-      break;
-   case SLANG_OPER_METHOD:
-      /* at this time, GLSL 1.20 only has one method: array.length()
-       * which returns an integer.
-       */
-      ti->spec.type = SLANG_SPEC_INT;
-      break;
-   case SLANG_OPER_FIELD:
-      {
-         slang_typeinfo _ti;
-
-         if (!slang_typeinfo_construct(&_ti))
-            return GL_FALSE;
-         if (!_slang_typeof_operation(op->children, space, &_ti, atoms, log)) {
-            slang_typeinfo_destruct(&_ti);
-            return GL_FALSE;
-         }
-         if (_ti.spec.type == SLANG_SPEC_STRUCT) {
-            slang_variable *field;
-
-            field = _slang_variable_locate(_ti.spec._struct->fields, op->a_id,
-                                           GL_FALSE);
-            if (field == NULL) {
-               slang_typeinfo_destruct(&_ti);
-               return GL_FALSE;
-            }
-            if (!slang_type_specifier_copy(&ti->spec, &field->type.specifier)) {
-               slang_typeinfo_destruct(&_ti);
-               return GL_FALSE;
-            }
-            ti->can_be_referenced = _ti.can_be_referenced;
-            ti->array_len = field->array_len;
-         }
-         else {
-            GLuint rows;
-            const char *swizzle;
-            slang_type_specifier_type base;
-
-            /* determine the swizzle of the field expression */
-            if (!_slang_type_is_vector(_ti.spec.type)) {
-               slang_typeinfo_destruct(&_ti);
-               slang_info_log_error(log, "Can't swizzle scalar expression");
-               return GL_FALSE;
-            }
-            rows = _slang_type_dim(_ti.spec.type);
-            swizzle = slang_atom_pool_id(atoms, op->a_id);
-            if (!_slang_is_swizzle(swizzle, rows, &ti->swz)) {
-               slang_typeinfo_destruct(&_ti);
-               slang_info_log_error(log, "bad swizzle '%s'", swizzle);
-               return GL_FALSE;
-            }
-            ti->is_swizzled = GL_TRUE;
-            ti->can_be_referenced = _ti.can_be_referenced
-               && _slang_is_swizzle_mask(&ti->swz, rows);
-            if (_ti.is_swizzled) {
-               slang_swizzle swz;
-
-               /* swizzle the swizzle */
-               _slang_multiply_swizzles(&swz, &_ti.swz, &ti->swz);
-               ti->swz = swz;
-            }
-            base = _slang_type_base(_ti.spec.type);
-            switch (ti->swz.num_components) {
-            case 1:
-               ti->spec.type = base;
-               break;
-            case 2:
-               switch (base) {
-               case SLANG_SPEC_FLOAT:
-                  ti->spec.type = SLANG_SPEC_VEC2;
-                  break;
-               case SLANG_SPEC_INT:
-                  ti->spec.type = SLANG_SPEC_IVEC2;
-                  break;
-               case SLANG_SPEC_BOOL:
-                  ti->spec.type = SLANG_SPEC_BVEC2;
-                  break;
-               default:
-                  break;
-               }
-               break;
-            case 3:
-               switch (base) {
-               case SLANG_SPEC_FLOAT:
-                  ti->spec.type = SLANG_SPEC_VEC3;
-                  break;
-               case SLANG_SPEC_INT:
-                  ti->spec.type = SLANG_SPEC_IVEC3;
-                  break;
-               case SLANG_SPEC_BOOL:
-                  ti->spec.type = SLANG_SPEC_BVEC3;
-                  break;
-               default:
-                  break;
-               }
-               break;
-            case 4:
-               switch (base) {
-               case SLANG_SPEC_FLOAT:
-                  ti->spec.type = SLANG_SPEC_VEC4;
-                  break;
-               case SLANG_SPEC_INT:
-                  ti->spec.type = SLANG_SPEC_IVEC4;
-                  break;
-               case SLANG_SPEC_BOOL:
-                  ti->spec.type = SLANG_SPEC_BVEC4;
-                  break;
-               default:
-                  break;
-               }
-               break;
-            default:
-               break;
-            }
-         }
-         slang_typeinfo_destruct(&_ti);
-      }
-      break;
-   case SLANG_OPER_POSTINCREMENT:
-   case SLANG_OPER_POSTDECREMENT:
-      if (!_slang_typeof_operation(op->children, space, ti, atoms, log))
-         return GL_FALSE;
-      ti->can_be_referenced = GL_FALSE;
-      ti->is_swizzled = GL_FALSE;
-      break;
-   default:
-      return GL_FALSE;
-   }
-
-   return GL_TRUE;
-}
-
-
-/**
- * Determine if a type is a matrix.
- * \return GL_TRUE if is a matrix, GL_FALSE otherwise.
- */
-GLboolean
-_slang_type_is_matrix(slang_type_specifier_type ty)
-{
-   switch (ty) {
-   case SLANG_SPEC_MAT2:
-   case SLANG_SPEC_MAT3:
-   case SLANG_SPEC_MAT4:
-   case SLANG_SPEC_MAT23:
-   case SLANG_SPEC_MAT32:
-   case SLANG_SPEC_MAT24:
-   case SLANG_SPEC_MAT42:
-   case SLANG_SPEC_MAT34:
-   case SLANG_SPEC_MAT43:
-      return GL_TRUE;
-   default:
-      return GL_FALSE;
-   }
-}
-
-
-/**
- * Determine if a type is a vector.
- * \return GL_TRUE if is a vector, GL_FALSE otherwise.
- */
-GLboolean
-_slang_type_is_vector(slang_type_specifier_type ty)
-{
-   switch (ty) {
-   case SLANG_SPEC_VEC2:
-   case SLANG_SPEC_VEC3:
-   case SLANG_SPEC_VEC4:
-   case SLANG_SPEC_IVEC2:
-   case SLANG_SPEC_IVEC3:
-   case SLANG_SPEC_IVEC4:
-   case SLANG_SPEC_BVEC2:
-   case SLANG_SPEC_BVEC3:
-   case SLANG_SPEC_BVEC4:
-      return GL_TRUE;
-   default:
-      return GL_FALSE;
-   }
-}
-
-
-/**
- * Determine if a type is a float, float vector or float matrix.
- * \return GL_TRUE if so, GL_FALSE otherwise
- */
-GLboolean
-_slang_type_is_float_vec_mat(slang_type_specifier_type ty)
-{
-   switch (ty) {
-   case SLANG_SPEC_FLOAT:
-   case SLANG_SPEC_VEC2:
-   case SLANG_SPEC_VEC3:
-   case SLANG_SPEC_VEC4:
-   case SLANG_SPEC_MAT2:
-   case SLANG_SPEC_MAT3:
-   case SLANG_SPEC_MAT4:
-   case SLANG_SPEC_MAT23:
-   case SLANG_SPEC_MAT32:
-   case SLANG_SPEC_MAT24:
-   case SLANG_SPEC_MAT42:
-   case SLANG_SPEC_MAT34:
-   case SLANG_SPEC_MAT43:
-      return GL_TRUE;
-   default:
-      return GL_FALSE;
-   }
-}
-
-
-/**
- * Given a vector type, return the type of the vector's elements.
- * For a matrix, return the type of the columns.
- */
-slang_type_specifier_type
-_slang_type_base(slang_type_specifier_type ty)
-{
-   switch (ty) {
-   case SLANG_SPEC_FLOAT:
-   case SLANG_SPEC_VEC2:
-   case SLANG_SPEC_VEC3:
-   case SLANG_SPEC_VEC4:
-      return SLANG_SPEC_FLOAT;
-   case SLANG_SPEC_INT:
-   case SLANG_SPEC_IVEC2:
-   case SLANG_SPEC_IVEC3:
-   case SLANG_SPEC_IVEC4:
-      return SLANG_SPEC_INT;
-   case SLANG_SPEC_BOOL:
-   case SLANG_SPEC_BVEC2:
-   case SLANG_SPEC_BVEC3:
-   case SLANG_SPEC_BVEC4:
-      return SLANG_SPEC_BOOL;
-   case SLANG_SPEC_MAT2:
-      return SLANG_SPEC_VEC2;
-   case SLANG_SPEC_MAT3:
-      return SLANG_SPEC_VEC3;
-   case SLANG_SPEC_MAT4:
-      return SLANG_SPEC_VEC4;
-   case SLANG_SPEC_MAT23:
-      return SLANG_SPEC_VEC3;
-   case SLANG_SPEC_MAT32:
-      return SLANG_SPEC_VEC2;
-   case SLANG_SPEC_MAT24:
-      return SLANG_SPEC_VEC4;
-   case SLANG_SPEC_MAT42:
-      return SLANG_SPEC_VEC2;
-   case SLANG_SPEC_MAT34:
-      return SLANG_SPEC_VEC4;
-   case SLANG_SPEC_MAT43:
-      return SLANG_SPEC_VEC3;
-   default:
-      return SLANG_SPEC_VOID;
-   }
-}
-
-
-/**
- * Return the dimensionality of a vector, or for a matrix, return number
- * of columns.
- */
-GLuint
-_slang_type_dim(slang_type_specifier_type ty)
-{
-   switch (ty) {
-   case SLANG_SPEC_FLOAT:
-   case SLANG_SPEC_INT:
-   case SLANG_SPEC_BOOL:
-      return 1;
-   case SLANG_SPEC_VEC2:
-   case SLANG_SPEC_IVEC2:
-   case SLANG_SPEC_BVEC2:
-   case SLANG_SPEC_MAT2:
-      return 2;
-   case SLANG_SPEC_VEC3:
-   case SLANG_SPEC_IVEC3:
-   case SLANG_SPEC_BVEC3:
-   case SLANG_SPEC_MAT3:
-      return 3;
-   case SLANG_SPEC_VEC4:
-   case SLANG_SPEC_IVEC4:
-   case SLANG_SPEC_BVEC4:
-   case SLANG_SPEC_MAT4:
-      return 4;
-
-   case SLANG_SPEC_MAT23:
-      return 2;
-   case SLANG_SPEC_MAT32:
-      return 3;
-   case SLANG_SPEC_MAT24:
-      return 2;
-   case SLANG_SPEC_MAT42:
-      return 4;
-   case SLANG_SPEC_MAT34:
-      return 3;
-   case SLANG_SPEC_MAT43:
-      return 4;
-
-   default:
-      return 0;
-   }
-}
-
-
-/**
- * Return the GL_* type that corresponds to a SLANG_SPEC_* type.
- */
-GLenum
-_slang_gltype_from_specifier(const slang_type_specifier *type)
-{
-   switch (type->type) {
-   case SLANG_SPEC_BOOL:
-      return GL_BOOL;
-   case SLANG_SPEC_BVEC2:
-      return GL_BOOL_VEC2;
-   case SLANG_SPEC_BVEC3:
-      return GL_BOOL_VEC3;
-   case SLANG_SPEC_BVEC4:
-      return GL_BOOL_VEC4;
-   case SLANG_SPEC_INT:
-      return GL_INT;
-   case SLANG_SPEC_IVEC2:
-      return GL_INT_VEC2;
-   case SLANG_SPEC_IVEC3:
-      return GL_INT_VEC3;
-   case SLANG_SPEC_IVEC4:
-      return GL_INT_VEC4;
-   case SLANG_SPEC_FLOAT:
-      return GL_FLOAT;
-   case SLANG_SPEC_VEC2:
-      return GL_FLOAT_VEC2;
-   case SLANG_SPEC_VEC3:
-      return GL_FLOAT_VEC3;
-   case SLANG_SPEC_VEC4:
-      return GL_FLOAT_VEC4;
-   case SLANG_SPEC_MAT2:
-      return GL_FLOAT_MAT2;
-   case SLANG_SPEC_MAT3:
-      return GL_FLOAT_MAT3;
-   case SLANG_SPEC_MAT4:
-      return GL_FLOAT_MAT4;
-   case SLANG_SPEC_MAT23:
-      return GL_FLOAT_MAT2x3;
-   case SLANG_SPEC_MAT32:
-      return GL_FLOAT_MAT3x2;
-   case SLANG_SPEC_MAT24:
-      return GL_FLOAT_MAT2x4;
-   case SLANG_SPEC_MAT42:
-      return GL_FLOAT_MAT4x2;
-   case SLANG_SPEC_MAT34:
-      return GL_FLOAT_MAT3x4;
-   case SLANG_SPEC_MAT43:
-      return GL_FLOAT_MAT4x3;
-   case SLANG_SPEC_SAMPLER_1D:
-      return GL_SAMPLER_1D;
-   case SLANG_SPEC_SAMPLER_2D:
-      return GL_SAMPLER_2D;
-   case SLANG_SPEC_SAMPLER_3D:
-      return GL_SAMPLER_3D;
-   case SLANG_SPEC_SAMPLER_CUBE:
-      return GL_SAMPLER_CUBE;
-   case SLANG_SPEC_SAMPLER_1D_SHADOW:
-      return GL_SAMPLER_1D_SHADOW;
-   case SLANG_SPEC_SAMPLER_2D_SHADOW:
-      return GL_SAMPLER_2D_SHADOW;
-   case SLANG_SPEC_SAMPLER_RECT:
-      return GL_SAMPLER_2D_RECT_ARB;
-   case SLANG_SPEC_SAMPLER_RECT_SHADOW:
-      return GL_SAMPLER_2D_RECT_SHADOW_ARB;
-   case SLANG_SPEC_SAMPLER_1D_ARRAY:
-      return GL_SAMPLER_1D_ARRAY_EXT;
-   case SLANG_SPEC_SAMPLER_2D_ARRAY:
-      return GL_SAMPLER_2D_ARRAY_EXT;
-   case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW:
-      return GL_SAMPLER_1D_ARRAY_SHADOW_EXT;
-   case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW:
-      return GL_SAMPLER_2D_ARRAY_SHADOW_EXT;
-   case SLANG_SPEC_ARRAY:
-      return _slang_gltype_from_specifier(type->_array);
-   case SLANG_SPEC_STRUCT:
-      /* fall-through */
-   default:
-      return GL_NONE;
-   }
-}
-
diff --git a/src/mesa/shader/slang/slang_typeinfo.h b/src/mesa/shader/slang/slang_typeinfo.h
deleted file mode 100644 (file)
index 9a6407a..0000000
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5
- *
- * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef SLANG_TYPEINFO_H
-#define SLANG_TYPEINFO_H 1
-
-#include "main/imports.h"
-#include "main/mtypes.h"
-#include "slang_log.h"
-#include "slang_utility.h"
-#include "slang_vartable.h"
-
-
-struct slang_operation_;
-
-struct slang_name_space_;
-
-
-
-/**
- * Holds complete information about vector swizzle - the <swizzle>
- * array contains vector component source indices, where 0 is "x", 1
- * is "y", 2 is "z" and 3 is "w".
- * Example: "xwz" --> { 3, { 0, 3, 2, not used } }.
- */
-typedef struct slang_swizzle_
-{
-   GLuint num_components;
-   GLuint swizzle[4];
-} slang_swizzle;
-
-extern GLboolean
-_slang_is_swizzle(const char *field, GLuint rows, slang_swizzle *swz);
-
-
-typedef enum slang_type_variant_
-{
-   SLANG_VARIANT,    /* the default */
-   SLANG_INVARIANT   /* indicates the "invariant" keyword */
-} slang_type_variant;
-
-
-typedef enum slang_type_centroid_
-{
-   SLANG_CENTER,    /* the default */
-   SLANG_CENTROID   /* indicates the "centroid" keyword */
-} slang_type_centroid;
-
-
-/**
- * These only apply to gl_FragCoord, but other layout qualifiers may
- * appear in the future.
- */
-typedef enum slang_layout_qualifier_
-{
-   SLANG_LAYOUT_NONE                      = 0x0,
-   SLANG_LAYOUT_UPPER_LEFT_BIT            = 0x1,
-   SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT  = 0x2
-} slang_layout_qualifier;
-
-
-typedef enum slang_type_qualifier_
-{
-   SLANG_QUAL_NONE,
-   SLANG_QUAL_CONST,
-   SLANG_QUAL_ATTRIBUTE,
-   SLANG_QUAL_VARYING,
-   SLANG_QUAL_UNIFORM,
-   SLANG_QUAL_OUT,
-   SLANG_QUAL_INOUT,
-   SLANG_QUAL_FIXEDOUTPUT,      /* internal */
-   SLANG_QUAL_FIXEDINPUT        /* internal */
-} slang_type_qualifier;
-
-
-typedef enum slang_type_precision_
-{
-   SLANG_PREC_DEFAULT,
-   SLANG_PREC_LOW,
-   SLANG_PREC_MEDIUM,
-   SLANG_PREC_HIGH
-} slang_type_precision;
-
-
-/**
- * The basic shading language types (float, vec4, mat3, etc)
- */
-typedef enum slang_type_specifier_type_
-{
-   SLANG_SPEC_VOID,
-   SLANG_SPEC_BOOL,
-   SLANG_SPEC_BVEC2,
-   SLANG_SPEC_BVEC3,
-   SLANG_SPEC_BVEC4,
-   SLANG_SPEC_INT,
-   SLANG_SPEC_IVEC2,
-   SLANG_SPEC_IVEC3,
-   SLANG_SPEC_IVEC4,
-   SLANG_SPEC_FLOAT,
-   SLANG_SPEC_VEC2,
-   SLANG_SPEC_VEC3,
-   SLANG_SPEC_VEC4,
-   SLANG_SPEC_MAT2,
-   SLANG_SPEC_MAT3,
-   SLANG_SPEC_MAT4,
-   SLANG_SPEC_MAT23,
-   SLANG_SPEC_MAT32,
-   SLANG_SPEC_MAT24,
-   SLANG_SPEC_MAT42,
-   SLANG_SPEC_MAT34,
-   SLANG_SPEC_MAT43,
-   SLANG_SPEC_SAMPLER_1D,
-   SLANG_SPEC_SAMPLER_2D,
-   SLANG_SPEC_SAMPLER_3D,
-   SLANG_SPEC_SAMPLER_CUBE,
-   SLANG_SPEC_SAMPLER_RECT,
-   SLANG_SPEC_SAMPLER_1D_SHADOW,
-   SLANG_SPEC_SAMPLER_2D_SHADOW,
-   SLANG_SPEC_SAMPLER_RECT_SHADOW,
-   SLANG_SPEC_SAMPLER_1D_ARRAY,
-   SLANG_SPEC_SAMPLER_2D_ARRAY,
-   SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW,
-   SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW,
-   SLANG_SPEC_STRUCT,
-   SLANG_SPEC_ARRAY
-} slang_type_specifier_type;
-
-
-extern slang_type_specifier_type
-slang_type_specifier_type_from_string(const char *);
-
-extern const char *
-slang_type_specifier_type_to_string(slang_type_specifier_type);
-
-
-/**
- * Describes more sophisticated types, like structs and arrays.
- */
-typedef struct slang_type_specifier_
-{
-   slang_type_specifier_type type;
-   struct slang_struct_ *_struct;         /**< if type == SLANG_SPEC_STRUCT */
-   struct slang_type_specifier_ *_array;  /**< if type == SLANG_SPEC_ARRAY */
-} slang_type_specifier;
-
-
-extern GLvoid
-slang_type_specifier_ctr(slang_type_specifier *);
-
-extern GLvoid
-slang_type_specifier_dtr(slang_type_specifier *);
-
-extern slang_type_specifier *
-slang_type_specifier_new(slang_type_specifier_type type,
-                         struct slang_struct_ *_struct,
-                         struct slang_type_specifier_ *_array);
-
-
-extern GLboolean
-slang_type_specifier_copy(slang_type_specifier *, const slang_type_specifier *);
-
-extern GLboolean
-slang_type_specifier_equal(const slang_type_specifier *,
-                           const slang_type_specifier *);
-
-
-extern GLboolean
-slang_type_specifier_compatible(const slang_type_specifier *x,
-                                const slang_type_specifier *y);
-
-
-typedef struct slang_fully_specified_type_
-{
-   slang_type_qualifier qualifier;
-   slang_type_specifier specifier;
-   slang_type_precision precision;
-   slang_type_variant variant;
-   slang_type_centroid centroid;
-   slang_layout_qualifier layout;
-   GLint array_len;           /**< -1 if not an array type */
-} slang_fully_specified_type;
-
-extern int
-slang_fully_specified_type_construct(slang_fully_specified_type *);
-
-extern void
-slang_fully_specified_type_destruct(slang_fully_specified_type *);
-
-extern int
-slang_fully_specified_type_copy(slang_fully_specified_type *,
-                               const slang_fully_specified_type *);
-
-GLboolean
-slang_fully_specified_types_compatible(const slang_fully_specified_type * x,
-                                       const slang_fully_specified_type * y);
-
-
-typedef struct slang_typeinfo_
-{
-   GLboolean can_be_referenced;
-   GLboolean is_swizzled;
-   slang_swizzle swz;
-   slang_type_specifier spec;
-   GLuint array_len;
-} slang_typeinfo;
-
-extern GLboolean
-slang_typeinfo_construct(slang_typeinfo *);
-
-extern GLvoid
-slang_typeinfo_destruct(slang_typeinfo *);
-
-
-extern GLboolean
-_slang_typeof_operation(struct slang_operation_ *,
-                         const struct slang_name_space_ *,
-                         slang_typeinfo *, slang_atom_pool *,
-                         slang_info_log *log);
-
-extern GLboolean
-_slang_type_is_matrix(slang_type_specifier_type);
-
-extern GLboolean
-_slang_type_is_vector(slang_type_specifier_type);
-
-extern GLboolean
-_slang_type_is_float_vec_mat(slang_type_specifier_type);
-
-extern slang_type_specifier_type
-_slang_type_base(slang_type_specifier_type);
-
-extern GLuint
-_slang_type_dim(slang_type_specifier_type);
-
-extern GLenum
-_slang_gltype_from_specifier(const slang_type_specifier *type);
-
-#endif
diff --git a/src/mesa/shader/slang/slang_utility.c b/src/mesa/shader/slang/slang_utility.c
deleted file mode 100644 (file)
index c1d5740..0000000
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.3
- *
- * Copyright (C) 2005-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 slang_utility.c
- * slang utilities
- * \author Michal Krol
- */
-
-#include "main/imports.h"
-#include "slang_utility.h"
-#include "slang_mem.h"
-
-char *
-slang_string_concat (char *dst, const char *src)
-{
-   return strcpy (dst + strlen (dst), src);
-}
-
-
-/* slang_string */
-
-GLvoid
-slang_string_init (slang_string *self)
-{
-   self->data = NULL;
-   self->capacity = 0;
-   self->length = 0;
-   self->fail = GL_FALSE;
-}
-
-GLvoid
-slang_string_free (slang_string *self)
-{
-   if (self->data != NULL)
-      free(self->data);
-}
-
-GLvoid
-slang_string_reset (slang_string *self)
-{
-   self->length = 0;
-   self->fail = GL_FALSE;
-}
-
-static GLboolean
-grow (slang_string *self, GLuint size)
-{
-   if (self->fail)
-      return GL_FALSE;
-   if (size > self->capacity) {
-      /* do not overflow 32-bit range */
-      assert (size < 0x80000000);
-
-      self->data = (char *) (_mesa_realloc (self->data, self->capacity, size * 2));
-      self->capacity = size * 2;
-      if (self->data == NULL) {
-         self->capacity = 0;
-         self->fail = GL_TRUE;
-         return GL_FALSE;
-      }
-   }
-   return GL_TRUE;
-}
-
-GLvoid
-slang_string_push (slang_string *self, const slang_string *str)
-{
-   if (str->fail) {
-      self->fail = GL_TRUE;
-      return;
-   }
-   if (grow (self, self->length + str->length)) {
-      memcpy (&self->data[self->length], str->data, str->length);
-      self->length += str->length;
-   }
-}
-
-GLvoid
-slang_string_pushc (slang_string *self, const char c)
-{
-   if (grow (self, self->length + 1)) {
-      self->data[self->length] = c;
-      self->length++;
-   }
-}
-
-GLvoid
-slang_string_pushs (slang_string *self, const char *cstr, GLuint len)
-{
-   if (grow (self, self->length + len)) {
-      memcpy (&self->data[self->length], cstr, len);
-      self->length += len;
-   }
-}
-
-GLvoid
-slang_string_pushi (slang_string *self, GLint i)
-{
-   char buffer[12];
-
-   _mesa_snprintf (buffer, sizeof(buffer), "%d", i);
-   slang_string_pushs (self, buffer, strlen (buffer));
-}
-
-const char *
-slang_string_cstr (slang_string *self)
-{
-   if (grow (self, self->length + 1))
-      self->data[self->length] = '\0';
-   return self->data;
-}
-
-/* slang_atom_pool */
-
-void
-slang_atom_pool_construct(slang_atom_pool * pool)
-{
-   GLuint i;
-
-   for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++)
-      pool->entries[i] = NULL;
-}
-
-void
-slang_atom_pool_destruct (slang_atom_pool * pool)
-{
-   GLuint i;
-
-   for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++) {
-      slang_atom_entry * entry;
-               
-      entry = pool->entries[i];
-      while (entry != NULL) {
-         slang_atom_entry *next = entry->next;
-         _slang_free(entry->id);
-         _slang_free(entry);
-         entry = next;
-      }
-   }
-}
-
-/*
- * Search the atom pool for an atom with a given name.
- * If atom is not found, create and add it to the pool.
- * Returns ATOM_NULL if the atom was not found and the function failed
- * to create a new atom.
- */
-slang_atom
-slang_atom_pool_atom(slang_atom_pool * pool, const char * id)
-{
-   GLuint hash;
-   const char * p = id;
-   slang_atom_entry ** entry;
-
-   /* Hash a given string to a number in the range [0, ATOM_POOL_SIZE). */
-   hash = 0;
-   while (*p != '\0') {
-      GLuint g;
-
-      hash = (hash << 4) + (GLuint) (*p++);
-      g = hash & 0xf0000000;
-      if (g != 0)
-         hash ^= g >> 24;
-      hash &= ~g;
-   }
-   hash %= SLANG_ATOM_POOL_SIZE;
-
-   /* Now the hash points to a linked list of atoms with names that
-    * have the same hash value.  Search the linked list for a given
-    * name.
-    */
-   entry = &pool->entries[hash];
-   while (*entry != NULL) {
-      /* If the same, return the associated atom. */
-      if (slang_string_compare((**entry).id, id) == 0)
-         return (slang_atom) (**entry).id;
-      /* Grab the next atom in the linked list. */
-      entry = &(**entry).next;
-   }
-
-   /* Okay, we have not found an atom. Create a new entry for it.
-    * Note that the <entry> points to the last entry's <next> field.
-    */
-   *entry = (slang_atom_entry *) _slang_alloc(sizeof(slang_atom_entry));
-   if (*entry == NULL)
-      return SLANG_ATOM_NULL;
-
-   /* Initialize a new entry. Because we'll need the actual name of
-    * the atom, we use the pointer to this string as an actual atom's
-    * value.
-    */
-   (**entry).next = NULL;
-   (**entry).id = _slang_strdup(id);
-   if ((**entry).id == NULL)
-      return SLANG_ATOM_NULL;
-   return (slang_atom) (**entry).id;
-}
-
-/**
- * Return the name of a given atom.
- */
-const char *
-slang_atom_pool_id(slang_atom_pool * pool, slang_atom atom)
-{
-   return (const char *) (atom);
-}
diff --git a/src/mesa/shader/slang/slang_utility.h b/src/mesa/shader/slang/slang_utility.h
deleted file mode 100644 (file)
index 2c0d0bc..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version:  6.5.3
- *
- * Copyright (C) 2005-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.
- */
-
-#ifndef SLANG_UTILITY_H
-#define SLANG_UTILITY_H
-
-
-/* Compile-time assertions.  If the expression is zero, try to declare an
- * array of size [-1] to cause compilation error.
- */
-#define static_assert(expr) do { int _array[(expr) ? 1 : -1]; (void) _array[0]; } while (0)
-
-
-#define slang_string_compare(str1, str2) strcmp (str1, str2)
-#define slang_string_copy(dst, src) strcpy (dst, src)
-#define slang_string_length(str) strlen (str)
-
-char *slang_string_concat (char *, const char *);
-
-/* slang_string */
-
-typedef struct
-{
-   char *data;
-   GLuint length;
-   GLuint capacity;
-   GLboolean fail;
-} slang_string;
-
-GLvoid
-slang_string_init (slang_string *);
-
-GLvoid
-slang_string_free (slang_string *);
-
-GLvoid
-slang_string_reset (slang_string *);
-
-GLvoid
-slang_string_push (slang_string *, const slang_string *);
-
-GLvoid
-slang_string_pushc (slang_string *, const char);
-
-GLvoid
-slang_string_pushs (slang_string *, const char *, GLuint);
-
-GLvoid
-slang_string_pushi (slang_string *, GLint);
-
-const char *
-slang_string_cstr (slang_string *);
-
-/* slang_atom */
-
-typedef GLvoid *slang_atom;
-
-#define SLANG_ATOM_NULL ((slang_atom) 0)
-
-typedef struct slang_atom_entry_
-{
-       char *id;
-       struct slang_atom_entry_ *next;
-} slang_atom_entry;
-
-#define SLANG_ATOM_POOL_SIZE 1023
-
-typedef struct slang_atom_pool_
-{
-       slang_atom_entry *entries[SLANG_ATOM_POOL_SIZE];
-} slang_atom_pool;
-
-GLvoid slang_atom_pool_construct (slang_atom_pool *);
-GLvoid slang_atom_pool_destruct (slang_atom_pool *);
-slang_atom slang_atom_pool_atom (slang_atom_pool *, const char *);
-const char *slang_atom_pool_id (slang_atom_pool *, slang_atom);
-
-
-#endif
diff --git a/src/mesa/shader/slang/slang_vartable.c b/src/mesa/shader/slang/slang_vartable.c
deleted file mode 100644 (file)
index e07e3a2..0000000
+++ /dev/null
@@ -1,362 +0,0 @@
-
-#include "main/imports.h"
-#include "shader/program.h"
-#include "shader/prog_print.h"
-#include "slang_compile.h"
-#include "slang_compile_variable.h"
-#include "slang_emit.h"
-#include "slang_mem.h"
-#include "slang_vartable.h"
-#include "slang_ir.h"
-
-
-static int dbg = 0;
-
-
-typedef enum {
-   FREE,
-   VAR,
-   TEMP
-} TempState;
-
-
-/**
- * Variable/register info for one variable scope.
- */
-struct table
-{
-   int Level;
-   int NumVars;
-   slang_variable **Vars;  /* array [NumVars] */
-
-   TempState Temps[MAX_PROGRAM_TEMPS * 4];  /* per-component state */
-   int ValSize[MAX_PROGRAM_TEMPS * 4];     /**< For debug only */
-
-   struct table *Parent;  /** Parent scope table */
-};
-
-
-/**
- * A variable table is a stack of tables, one per scope.
- */
-struct slang_var_table_
-{
-   GLint CurLevel;
-   GLuint MaxRegisters;
-   struct table *Top;  /**< Table at top of stack */
-};
-
-
-
-slang_var_table *
-_slang_new_var_table(GLuint maxRegisters)
-{
-   slang_var_table *vt
-      = (slang_var_table *) _slang_alloc(sizeof(slang_var_table));
-   if (vt) {
-      vt->MaxRegisters = maxRegisters;
-   }
-   return vt;
-}
-
-
-void
-_slang_delete_var_table(slang_var_table *vt)
-{
-   if (vt->Top) {
-      _mesa_problem(NULL, "non-empty var table in _slang_delete_var_table()");
-      return;
-   }
-   _slang_free(vt);
-}
-
-
-
-/**
- * Create new table on top of vartable stack.
- * Used when we enter a {} block.
- */
-void
-_slang_push_var_table(slang_var_table *vt)
-{
-   struct table *t = (struct table *) _slang_alloc(sizeof(struct table));
-   if (t) {
-      t->Level = vt->CurLevel++;
-      t->Parent = vt->Top;
-      if (t->Parent) {
-         /* copy the info indicating which temp regs are in use */
-         memcpy(t->Temps, t->Parent->Temps, sizeof(t->Temps));
-         memcpy(t->ValSize, t->Parent->ValSize, sizeof(t->ValSize));
-      }
-      vt->Top = t;
-      if (dbg) printf("Pushing level %d\n", t->Level);
-   }
-}
-
-
-/**
- * Pop top entry from variable table.
- * Used when we leave a {} block.
- */
-void
-_slang_pop_var_table(slang_var_table *vt)
-{
-   struct table *t = vt->Top;
-   int i;
-
-   if (dbg) printf("Popping level %d\n", t->Level);
-
-   /* free the storage allocated for each variable */
-   for (i = 0; i < t->NumVars; i++) {
-      slang_ir_storage *store = t->Vars[i]->store;
-      GLint j;
-      GLuint comp;
-      if (dbg) printf("  Free var %s, size %d at %d.%s\n",
-                      (char*) t->Vars[i]->a_name, store->Size,
-                      store->Index,
-                      _mesa_swizzle_string(store->Swizzle, 0, 0));
-
-      if (store->File == PROGRAM_SAMPLER) {
-         /* samplers have no storage */
-         continue;
-      }
-
-      if (store->Size == 1)
-         comp = GET_SWZ(store->Swizzle, 0);
-      else
-         comp = 0;
-
-      /* store->Index may be -1 if we run out of registers */
-      if (store->Index >= 0) {
-         for (j = 0; j < store->Size; j++) {
-            assert(t->Temps[store->Index * 4 + j + comp] == VAR);
-            t->Temps[store->Index * 4 + j + comp] = FREE;
-         }
-      }
-      store->Index = -1;
-   }
-   if (t->Parent) {
-      /* just verify that any remaining allocations in this scope 
-       * were for temps
-       */
-      for (i = 0; i < (int) vt->MaxRegisters * 4; i++) {
-         if (t->Temps[i] != FREE && t->Parent->Temps[i] == FREE) {
-            if (dbg) printf("  Free reg %d\n", i/4);
-            assert(t->Temps[i] == TEMP);
-         }
-      }
-   }
-
-   if (t->Vars) {
-      _slang_free(t->Vars);
-      t->Vars = NULL;
-   }
-
-   vt->Top = t->Parent;
-   _slang_free(t);
-   vt->CurLevel--;
-}
-
-
-/**
- * Add a new variable to the given var/symbol table.
- */
-void
-_slang_add_variable(slang_var_table *vt, slang_variable *v)
-{
-   struct table *t;
-   assert(vt);
-   t = vt->Top;
-   assert(t);
-   if (dbg) printf("Adding var %s, store %p\n", (char *) v->a_name, (void *) v->store);
-   t->Vars = (slang_variable **)
-      _slang_realloc(t->Vars,
-                     t->NumVars * sizeof(slang_variable *),
-                     (t->NumVars + 1) * sizeof(slang_variable *));
-   t->Vars[t->NumVars] = v;
-   t->NumVars++;
-}
-
-
-/**
- * Look for variable by name in given table.
- * If not found, Parent table will be searched.
- */
-slang_variable *
-_slang_find_variable(const slang_var_table *vt, slang_atom name)
-{
-   struct table *t = vt->Top;
-   while (1) {
-      int i;
-      for (i = 0; i < t->NumVars; i++) {
-         if (t->Vars[i]->a_name == name)
-            return t->Vars[i];
-      }
-      if (t->Parent)
-         t = t->Parent;
-      else
-         return NULL;
-   }
-}
-
-
-/**
- * Allocation helper.
- * \param size  var size in floats
- * \return  position for var, measured in floats
- */
-static GLint
-alloc_reg(slang_var_table *vt, GLint size, GLboolean isTemp)
-{
-   struct table *t = vt->Top;
-   /* if size == 1, allocate anywhere, else, pos must be multiple of 4 */
-   const GLuint step = (size == 1) ? 1 : 4;
-   GLuint i, j;
-   assert(size > 0); /* number of floats */
-
-   for (i = 0; i <= vt->MaxRegisters * 4 - size; i += step) {
-      GLuint found = 0;
-      for (j = 0; j < (GLuint) size; j++) {
-         assert(i + j < 4 * MAX_PROGRAM_TEMPS);
-         if (i + j < vt->MaxRegisters * 4 && t->Temps[i + j] == FREE) {
-            found++;
-         }
-         else {
-            break;
-         }
-      }
-      if (found == size) {
-         /* found block of size free regs */
-         if (size > 1)
-            assert(i % 4 == 0);
-         for (j = 0; j < (GLuint) size; j++) {
-            assert(i + j < 4 * MAX_PROGRAM_TEMPS);
-            t->Temps[i + j] = isTemp ? TEMP : VAR;
-         }
-         assert(i < MAX_PROGRAM_TEMPS * 4);
-         t->ValSize[i] = size;
-         return i;
-      }
-   }
-
-   /* if we get here, we ran out of registers */
-   return -1;
-}
-
-
-/**
- * Allocate temp register(s) for storing a variable.
- * \param size  size needed, in floats
- * \param swizzle  returns swizzle mask for accessing var in register
- * \return  register allocated, or -1
- */
-GLboolean
-_slang_alloc_var(slang_var_table *vt, slang_ir_storage *store)
-{
-   struct table *t = vt->Top;
-   int i;
-
-   if (store->File == PROGRAM_SAMPLER) {
-      /* don't really allocate storage */
-      store->Index = 0;
-      return GL_TRUE;
-   }
-
-   i = alloc_reg(vt, store->Size, GL_FALSE);
-   if (i < 0)
-      return GL_FALSE;
-
-   store->Index = i / 4;
-   store->Swizzle = _slang_var_swizzle(store->Size, i % 4);
-
-   if (dbg)
-      printf("Alloc var storage sz %d at %d.%s (level %d) store %p\n",
-             store->Size, store->Index,
-             _mesa_swizzle_string(store->Swizzle, 0, 0),
-             t->Level,
-             (void*) store);
-
-   return GL_TRUE;
-}
-
-
-
-/**
- * Allocate temp register(s) for storing an unnamed intermediate value.
- */
-GLboolean
-_slang_alloc_temp(slang_var_table *vt, slang_ir_storage *store)
-{
-   struct table *t = vt->Top;
-   const int i = alloc_reg(vt, store->Size, GL_TRUE);
-   if (i < 0)
-      return GL_FALSE;
-
-   assert(store->Index < 0);
-
-   store->Index = i / 4;
-   store->Swizzle = _slang_var_swizzle(store->Size, i % 4);
-
-   if (dbg) printf("Alloc temp sz %d at %d.%s (level %d) store %p\n",
-                   store->Size, store->Index,
-                   _mesa_swizzle_string(store->Swizzle, 0, 0), t->Level,
-                   (void *) store);
-
-   return GL_TRUE;
-}
-
-
-void
-_slang_free_temp(slang_var_table *vt, slang_ir_storage *store)
-{
-   struct table *t = vt->Top;
-   GLuint i;
-   GLint r = store->Index;
-   assert(store->Size > 0);
-   assert(r >= 0);
-   assert((GLuint)r + store->Size <= vt->MaxRegisters * 4);
-   if (dbg) printf("Free temp sz %d at %d.%s (level %d) store %p\n",
-                   store->Size, r,
-                   _mesa_swizzle_string(store->Swizzle, 0, 0),
-                   t->Level, (void *) store);
-   if (store->Size == 1) {
-      const GLuint comp = GET_SWZ(store->Swizzle, 0);
-      /* we can actually fail some of these assertions because of the
-       * troublesome IR_SWIZZLE handling.
-       */
-#if 0
-      assert(store->Swizzle == MAKE_SWIZZLE4(comp, comp, comp, comp));
-      assert(comp < 4);
-      assert(t->ValSize[r * 4 + comp] == 1);
-#endif
-      assert(t->Temps[r * 4 + comp] == TEMP);
-      t->Temps[r * 4 + comp] = FREE;
-   }
-   else {
-      /*assert(store->Swizzle == SWIZZLE_NOOP);*/
-      assert(t->ValSize[r*4] == store->Size);
-      for (i = 0; i < (GLuint) store->Size; i++) {
-         assert(t->Temps[r * 4 + i] == TEMP);
-         t->Temps[r * 4 + i] = FREE;
-      }
-   }
-}
-
-
-GLboolean
-_slang_is_temp(const slang_var_table *vt, const slang_ir_storage *store)
-{
-   struct table *t = vt->Top;
-   GLuint comp;
-   assert(store->Index >= 0);
-   assert(store->Index < (int) vt->MaxRegisters);
-   if (store->Swizzle == SWIZZLE_NOOP)
-      comp = 0;
-   else
-      comp = GET_SWZ(store->Swizzle, 0);
-
-   if (t->Temps[store->Index * 4 + comp] == TEMP)
-      return GL_TRUE;
-   else
-      return GL_FALSE;
-}
diff --git a/src/mesa/shader/slang/slang_vartable.h b/src/mesa/shader/slang/slang_vartable.h
deleted file mode 100644 (file)
index 94bcd63..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-
-#ifndef SLANG_VARTABLE_H
-#define SLANG_VARTABLE_H
-
-struct slang_ir_storage_;
-
-typedef struct slang_var_table_ slang_var_table;
-
-struct slang_variable_;
-
-extern slang_var_table *
-_slang_new_var_table(GLuint maxRegisters);
-
-extern void
-_slang_delete_var_table(slang_var_table *vt);
-
-extern void
-_slang_push_var_table(slang_var_table *parent);
-
-extern void
-_slang_pop_var_table(slang_var_table *t);
-
-extern void
-_slang_add_variable(slang_var_table *t, struct slang_variable_ *v);
-
-extern struct slang_variable_ *
-_slang_find_variable(const slang_var_table *t, slang_atom name);
-
-extern GLboolean
-_slang_alloc_var(slang_var_table *t, struct slang_ir_storage_ *store);
-
-extern GLboolean
-_slang_alloc_temp(slang_var_table *t, struct slang_ir_storage_ *store);
-
-extern void
-_slang_free_temp(slang_var_table *t, struct slang_ir_storage_ *store);
-
-extern GLboolean
-_slang_is_temp(const slang_var_table *t, const struct slang_ir_storage_ *store);
-
-
-#endif /* SLANG_VARTABLE_H */
diff --git a/src/mesa/shader/symbol_table.c b/src/mesa/shader/symbol_table.c
deleted file mode 100644 (file)
index 3fea5ee..0000000
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * Copyright Â© 2008 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION 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/imports.h"
-#include "symbol_table.h"
-#include "hash_table.h"
-
-struct symbol {
-    /**
-     * Link to the next symbol in the table with the same name
-     *
-     * The linked list of symbols with the same name is ordered by scope
-     * from inner-most to outer-most.
-     */
-    struct symbol *next_with_same_name;
-
-
-    /**
-     * Link to the next symbol in the table with the same scope
-     *
-     * The linked list of symbols with the same scope is unordered.  Symbols
-     * in this list my have unique names.
-     */
-    struct symbol *next_with_same_scope;
-
-
-    /**
-     * Header information for the list of symbols with the same name.
-     */
-    struct symbol_header *hdr;
-
-
-    /**
-     * Name space of the symbol
-     *
-     * Name space are arbitrary user assigned integers.  No two symbols can
-     * exist in the same name space at the same scope level.
-     */
-    int name_space;
-
-    /** Scope depth where this symbol was defined. */
-    unsigned depth;
-
-    /**
-     * Arbitrary user supplied data.
-     */
-    void *data;
-};
-
-
-/**
- */
-struct symbol_header {
-    /** Linkage in list of all headers in a given symbol table. */
-    struct symbol_header *next;
-
-    /** Symbol name. */
-    const char *name;
-
-    /** Linked list of symbols with the same name. */
-    struct symbol *symbols;
-};
-
-
-/**
- * Element of the scope stack.
- */
-struct scope_level {
-    /** Link to next (inner) scope level. */
-    struct scope_level *next;
-    
-    /** Linked list of symbols with the same scope. */
-    struct symbol *symbols;
-};
-
-
-/**
- *
- */
-struct _mesa_symbol_table {
-    /** Hash table containing all symbols in the symbol table. */
-    struct hash_table *ht;
-
-    /** Top of scope stack. */
-    struct scope_level *current_scope;
-
-    /** List of all symbol headers in the table. */
-    struct symbol_header *hdr;
-
-    /** Current scope depth. */
-    unsigned depth;
-};
-
-
-struct _mesa_symbol_table_iterator {
-    /**
-     * Name space of symbols returned by this iterator.
-     */
-    int name_space;
-
-
-    /**
-     * Currently iterated symbol
-     *
-     * The next call to \c _mesa_symbol_table_iterator_get will return this
-     * value.  It will also update this value to the value that should be
-     * returned by the next call.
-     */
-    struct symbol *curr;
-};
-
-
-static void
-check_symbol_table(struct _mesa_symbol_table *table)
-{
-#if 1
-    struct scope_level *scope;
-
-    for (scope = table->current_scope; scope != NULL; scope = scope->next) {
-        struct symbol *sym;
-
-        for (sym = scope->symbols
-             ; sym != NULL
-             ; sym = sym->next_with_same_name) {
-            const struct symbol_header *const hdr = sym->hdr;
-            struct symbol *sym2;
-
-            for (sym2 = hdr->symbols
-                 ; sym2 != NULL
-                 ; sym2 = sym2->next_with_same_name) {
-                assert(sym2->hdr == hdr);
-            }
-        }
-    }
-#endif
-}
-
-void
-_mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table)
-{
-    struct scope_level *const scope = table->current_scope;
-    struct symbol *sym = scope->symbols;
-
-    table->current_scope = scope->next;
-    table->depth--;
-
-    free(scope);
-
-    while (sym != NULL) {
-        struct symbol *const next = sym->next_with_same_scope;
-        struct symbol_header *const hdr = sym->hdr;
-
-        assert(hdr->symbols == sym);
-
-        hdr->symbols = sym->next_with_same_name;
-
-        free(sym);
-
-        sym = next;
-    }
-
-    check_symbol_table(table);
-}
-
-
-void
-_mesa_symbol_table_push_scope(struct _mesa_symbol_table *table)
-{
-    struct scope_level *const scope = calloc(1, sizeof(*scope));
-    
-    scope->next = table->current_scope;
-    table->current_scope = scope;
-    table->depth++;
-}
-
-
-static struct symbol_header *
-find_symbol(struct _mesa_symbol_table *table, const char *name)
-{
-    return (struct symbol_header *) hash_table_find(table->ht, name);
-}
-
-
-struct _mesa_symbol_table_iterator *
-_mesa_symbol_table_iterator_ctor(struct _mesa_symbol_table *table,
-                                 int name_space, const char *name)
-{
-    struct _mesa_symbol_table_iterator *iter = calloc(1, sizeof(*iter));
-    struct symbol_header *const hdr = find_symbol(table, name);
-    
-    iter->name_space = name_space;
-
-    if (hdr != NULL) {
-        struct symbol *sym;
-
-        for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
-            assert(sym->hdr == hdr);
-
-            if ((name_space == -1) || (sym->name_space == name_space)) {
-                iter->curr = sym;
-                break;
-            }
-        }
-    }
-
-    return iter;
-}
-
-
-void
-_mesa_symbol_table_iterator_dtor(struct _mesa_symbol_table_iterator *iter)
-{
-    free(iter);
-}
-
-
-void *
-_mesa_symbol_table_iterator_get(struct _mesa_symbol_table_iterator *iter)
-{
-    return (iter->curr == NULL) ? NULL : iter->curr->data;
-}
-
-
-int
-_mesa_symbol_table_iterator_next(struct _mesa_symbol_table_iterator *iter)
-{
-    struct symbol_header *hdr;
-
-    if (iter->curr == NULL) {
-        return 0;
-    }
-
-    hdr = iter->curr->hdr;
-    iter->curr = iter->curr->next_with_same_name;
-
-    while (iter->curr != NULL) {
-        assert(iter->curr->hdr == hdr);
-
-        if ((iter->name_space == -1)
-            || (iter->curr->name_space == iter->name_space)) {
-            return 1;
-        }
-
-        iter->curr = iter->curr->next_with_same_name;
-    }
-
-    return 0;
-}
-
-
-/**
- * Determine the scope "distance" of a symbol from the current scope
- *
- * \return
- * A non-negative number for the number of scopes between the current scope
- * and the scope where a symbol was defined.  A value of zero means the current
- * scope.  A negative number if the symbol does not exist.
- */
-int
-_mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table,
-                               int name_space, const char *name)
-{
-    struct symbol_header *const hdr = find_symbol(table, name);
-    struct symbol *sym;
-
-    if (hdr != NULL) {
-       for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
-         assert(sym->hdr == hdr);
-
-         if ((name_space == -1) || (sym->name_space == name_space)) {
-            assert(sym->depth <= table->depth);
-            return sym->depth - table->depth;
-         }
-       }
-    }
-
-    return -1;
-}
-
-
-void *
-_mesa_symbol_table_find_symbol(struct _mesa_symbol_table *table,
-                               int name_space, const char *name)
-{
-    struct symbol_header *const hdr = find_symbol(table, name);
-
-    if (hdr != NULL) {
-        struct symbol *sym;
-
-
-        for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
-            assert(sym->hdr == hdr);
-
-            if ((name_space == -1) || (sym->name_space == name_space)) {
-                return sym->data;
-            }
-        }
-    }
-
-    return NULL;
-}
-
-
-int
-_mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table,
-                              int name_space, const char *name,
-                              void *declaration)
-{
-    struct symbol_header *hdr;
-    struct symbol *sym;
-
-    check_symbol_table(table);
-
-    hdr = find_symbol(table, name);
-
-    check_symbol_table(table);
-
-    if (hdr == NULL) {
-        hdr = calloc(1, sizeof(*hdr));
-        hdr->name = name;
-
-        hash_table_insert(table->ht, hdr, name);
-       hdr->next = table->hdr;
-       table->hdr = hdr;
-    }
-
-    check_symbol_table(table);
-
-    /* If the symbol already exists in this namespace at this scope, it cannot
-     * be added to the table.
-     */
-    for (sym = hdr->symbols
-        ; (sym != NULL) && (sym->name_space != name_space)
-        ; sym = sym->next_with_same_name) {
-       /* empty */
-    }
-
-    if (sym && (sym->depth == table->depth))
-       return -1;
-
-    sym = calloc(1, sizeof(*sym));
-    sym->next_with_same_name = hdr->symbols;
-    sym->next_with_same_scope = table->current_scope->symbols;
-    sym->hdr = hdr;
-    sym->name_space = name_space;
-    sym->data = declaration;
-    sym->depth = table->depth;
-
-    assert(sym->hdr == hdr);
-
-    hdr->symbols = sym;
-    table->current_scope->symbols = sym;
-
-    check_symbol_table(table);
-    return 0;
-}
-
-
-struct _mesa_symbol_table *
-_mesa_symbol_table_ctor(void)
-{
-    struct _mesa_symbol_table *table = calloc(1, sizeof(*table));
-
-    if (table != NULL) {
-       table->ht = hash_table_ctor(32, hash_table_string_hash,
-                                  hash_table_string_compare);
-
-       _mesa_symbol_table_push_scope(table);
-    }
-
-    return table;
-}
-
-
-void
-_mesa_symbol_table_dtor(struct _mesa_symbol_table *table)
-{
-   struct symbol_header *hdr;
-   struct symbol_header *next;
-
-   while (table->current_scope != NULL) {
-      _mesa_symbol_table_pop_scope(table);
-   }
-
-   for (hdr = table->hdr; hdr != NULL; hdr = next) {
-       next = hdr->next;
-       free(hdr);
-   }
-
-   hash_table_dtor(table->ht);
-   free(table);
-}
diff --git a/src/mesa/shader/symbol_table.h b/src/mesa/shader/symbol_table.h
deleted file mode 100644 (file)
index 1d570fc..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright Â© 2008 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION 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 MESA_SYMBOL_TABLE_H
-#define MESA_SYMBOL_TABLE_H
-
-struct _mesa_symbol_table;
-struct _mesa_symbol_table_iterator;
-
-extern void _mesa_symbol_table_push_scope(struct _mesa_symbol_table *table);
-
-extern void _mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table);
-
-extern int _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *symtab,
-    int name_space, const char *name, void *declaration);
-
-extern int _mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table,
-    int name_space, const char *name);
-
-extern void *_mesa_symbol_table_find_symbol(
-    struct _mesa_symbol_table *symtab, int name_space, const char *name);
-
-extern struct _mesa_symbol_table *_mesa_symbol_table_ctor(void);
-
-extern void _mesa_symbol_table_dtor(struct _mesa_symbol_table *);
-
-extern struct _mesa_symbol_table_iterator *_mesa_symbol_table_iterator_ctor(
-    struct _mesa_symbol_table *table, int name_space, const char *name);
-
-extern void _mesa_symbol_table_iterator_dtor(
-    struct _mesa_symbol_table_iterator *);
-
-extern void *_mesa_symbol_table_iterator_get(
-    struct _mesa_symbol_table_iterator *iter);
-
-extern int _mesa_symbol_table_iterator_next(
-    struct _mesa_symbol_table_iterator *iter);
-
-#endif /* MESA_SYMBOL_TABLE_H */
diff --git a/src/mesa/shader/uniforms.c b/src/mesa/shader/uniforms.c
deleted file mode 100644 (file)
index b1fb90d..0000000
+++ /dev/null
@@ -1,937 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2004-2008  Brian Paul   All Rights Reserved.
- * Copyright (C) 2009-2010  VMware, 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
- * 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 uniforms.c
- * Functions related to GLSL uniform variables.
- * \author Brian Paul
- */
-
-/**
- * XXX things to do:
- * 1. Check that the right error code is generated for all _mesa_error() calls.
- * 2. Insert FLUSH_VERTICES calls in various places
- */
-
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_statevars.h"
-#include "shader/prog_uniform.h"
-#include "shader/shader_api.h"
-#include "uniforms.h"
-
-
-
-static GLenum
-base_uniform_type(GLenum type)
-{
-   switch (type) {
-#if 0 /* not needed, for now */
-   case GL_BOOL:
-   case GL_BOOL_VEC2:
-   case GL_BOOL_VEC3:
-   case GL_BOOL_VEC4:
-      return GL_BOOL;
-#endif
-   case GL_FLOAT:
-   case GL_FLOAT_VEC2:
-   case GL_FLOAT_VEC3:
-   case GL_FLOAT_VEC4:
-      return GL_FLOAT;
-   case GL_UNSIGNED_INT:
-   case GL_UNSIGNED_INT_VEC2:
-   case GL_UNSIGNED_INT_VEC3:
-   case GL_UNSIGNED_INT_VEC4:
-      return GL_UNSIGNED_INT;
-   case GL_INT:
-   case GL_INT_VEC2:
-   case GL_INT_VEC3:
-   case GL_INT_VEC4:
-      return GL_INT;
-   default:
-      _mesa_problem(NULL, "Invalid type in base_uniform_type()");
-      return GL_FLOAT;
-   }
-}
-
-
-static GLboolean
-is_boolean_type(GLenum type)
-{
-   switch (type) {
-   case GL_BOOL:
-   case GL_BOOL_VEC2:
-   case GL_BOOL_VEC3:
-   case GL_BOOL_VEC4:
-      return GL_TRUE;
-   default:
-      return GL_FALSE;
-   }
-}
-
-
-static GLboolean
-is_sampler_type(GLenum type)
-{
-   switch (type) {
-   case GL_SAMPLER_1D:
-   case GL_SAMPLER_2D:
-   case GL_SAMPLER_3D:
-   case GL_SAMPLER_CUBE:
-   case GL_SAMPLER_1D_SHADOW:
-   case GL_SAMPLER_2D_SHADOW:
-   case GL_SAMPLER_2D_RECT_ARB:
-   case GL_SAMPLER_2D_RECT_SHADOW_ARB:
-   case GL_SAMPLER_1D_ARRAY_EXT:
-   case GL_SAMPLER_2D_ARRAY_EXT:
-   case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
-   case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
-      return GL_TRUE;
-   default:
-      return GL_FALSE;
-   }
-}
-
-
-static struct gl_program_parameter *
-get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index)
-{
-   const struct gl_program *prog = NULL;
-   GLint progPos;
-
-   progPos = shProg->Uniforms->Uniforms[index].VertPos;
-   if (progPos >= 0) {
-      prog = &shProg->VertexProgram->Base;
-   }
-   else {
-      progPos = shProg->Uniforms->Uniforms[index].FragPos;
-      if (progPos >= 0) {
-         prog = &shProg->FragmentProgram->Base;
-      }
-   }
-
-   if (!prog || progPos < 0)
-      return NULL; /* should never happen */
-
-   return &prog->Parameters->Parameters[progPos];
-}
-
-
-/**
- * Called via ctx->Driver.GetActiveUniform().
- */
-static void
-_mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index,
-                         GLsizei maxLength, GLsizei *length, GLint *size,
-                         GLenum *type, GLchar *nameOut)
-{
-   const struct gl_shader_program *shProg;
-   const struct gl_program *prog = NULL;
-   const struct gl_program_parameter *param;
-   GLint progPos;
-
-   shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
-   if (!shProg)
-      return;
-
-   if (!shProg->Uniforms || index >= shProg->Uniforms->NumUniforms) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
-      return;
-   }
-
-   progPos = shProg->Uniforms->Uniforms[index].VertPos;
-   if (progPos >= 0) {
-      prog = &shProg->VertexProgram->Base;
-   }
-   else {
-      progPos = shProg->Uniforms->Uniforms[index].FragPos;
-      if (progPos >= 0) {
-         prog = &shProg->FragmentProgram->Base;
-      }
-   }
-
-   if (!prog || progPos < 0)
-      return; /* should never happen */
-
-   ASSERT(progPos < prog->Parameters->NumParameters);
-   param = &prog->Parameters->Parameters[progPos];
-
-   if (nameOut) {
-      _mesa_copy_string(nameOut, maxLength, length, param->Name);
-   }
-
-   if (size) {
-      GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
-      if ((GLint) param->Size > typeSize) {
-         /* This is an array.
-          * Array elements are placed on vector[4] boundaries so they're
-          * a multiple of four floats.  We round typeSize up to next multiple
-          * of four to get the right size below.
-          */
-         typeSize = (typeSize + 3) & ~3;
-      }
-      /* Note that the returned size is in units of the <type>, not bytes */
-      *size = param->Size / typeSize;
-   }
-
-   if (type) {
-      *type = param->DataType;
-   }
-}
-
-
-
-static void
-get_matrix_dims(GLenum type, GLint *rows, GLint *cols)
-{
-   switch (type) {
-   case GL_FLOAT_MAT2:
-      *rows = *cols = 2;
-      break;
-   case GL_FLOAT_MAT2x3:
-      *rows = 3;
-      *cols = 2;
-      break;
-   case GL_FLOAT_MAT2x4:
-      *rows = 4;
-      *cols = 2;
-      break;
-   case GL_FLOAT_MAT3:
-      *rows = 3;
-      *cols = 3;
-      break;
-   case GL_FLOAT_MAT3x2:
-      *rows = 2;
-      *cols = 3;
-      break;
-   case GL_FLOAT_MAT3x4:
-      *rows = 4;
-      *cols = 3;
-      break;
-   case GL_FLOAT_MAT4:
-      *rows = 4;
-      *cols = 4;
-      break;
-   case GL_FLOAT_MAT4x2:
-      *rows = 2;
-      *cols = 4;
-      break;
-   case GL_FLOAT_MAT4x3:
-      *rows = 3;
-      *cols = 4;
-      break;
-   default:
-      *rows = *cols = 0;
-   }
-}
-
-
-/**
- * Determine the number of rows and columns occupied by a uniform
- * according to its datatype.  For non-matrix types (such as GL_FLOAT_VEC4),
- * the number of rows = 1 and cols = number of elements in the vector.
- */
-static void
-get_uniform_rows_cols(const struct gl_program_parameter *p,
-                      GLint *rows, GLint *cols)
-{
-   get_matrix_dims(p->DataType, rows, cols);
-   if (*rows == 0 && *cols == 0) {
-      /* not a matrix type, probably a float or vector */
-      if (p->Size <= 4) {
-         *rows = 1;
-         *cols = p->Size;
-      }
-      else {
-         *rows = p->Size / 4 + 1;
-         if (p->Size % 4 == 0)
-            *cols = 4;
-         else
-            *cols = p->Size % 4;
-      }
-   }
-}
-
-
-/**
- * Helper for get_uniform[fi]v() functions.
- * Given a shader program name and uniform location, return a pointer
- * to the shader program and return the program parameter position.
- */
-static void
-lookup_uniform_parameter(GLcontext *ctx, GLuint program, GLint location,
-                         struct gl_program **progOut, GLint *paramPosOut)
-{
-   struct gl_shader_program *shProg
-      = _mesa_lookup_shader_program_err(ctx, program, "glGetUniform[if]v");
-   struct gl_program *prog = NULL;
-   GLint progPos = -1;
-
-   /* if shProg is NULL, we'll have already recorded an error */
-
-   if (shProg) {
-      if (!shProg->Uniforms ||
-          location < 0 ||
-          location >= (GLint) shProg->Uniforms->NumUniforms) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,  "glGetUniformfv(location)");
-      }
-      else {
-         /* OK, find the gl_program and program parameter location */
-         progPos = shProg->Uniforms->Uniforms[location].VertPos;
-         if (progPos >= 0) {
-            prog = &shProg->VertexProgram->Base;
-         }
-         else {
-            progPos = shProg->Uniforms->Uniforms[location].FragPos;
-            if (progPos >= 0) {
-               prog = &shProg->FragmentProgram->Base;
-            }
-         }
-      }
-   }
-
-   *progOut = prog;
-   *paramPosOut = progPos;
-}
-
-
-/**
- * GLGL uniform arrays and structs require special handling.
- *
- * The GL_ARB_shader_objects spec says that if you use
- * glGetUniformLocation to get the location of an array, you CANNOT
- * access other elements of the array by adding an offset to the
- * returned location.  For example, you must call
- * glGetUniformLocation("foo[16]") if you want to set the 16th element
- * of the array with glUniform().
- *
- * HOWEVER, some other OpenGL drivers allow accessing array elements
- * by adding an offset to the returned array location.  And some apps
- * seem to depend on that behaviour.
- *
- * Mesa's gl_uniform_list doesn't directly support this since each
- * entry in the list describes one uniform variable, not one uniform
- * element.  We could insert dummy entries in the list for each array
- * element after [0] but that causes complications elsewhere.
- *
- * We solve this problem by encoding two values in the location that's
- * returned by glGetUniformLocation():
- *  a) index into gl_uniform_list::Uniforms[] for the uniform
- *  b) an array/field offset (0 for simple types)
- *
- * These two values are encoded in the high and low halves of a GLint.
- * By putting the uniform number in the high part and the offset in the
- * low part, we can support the unofficial ability to index into arrays
- * by adding offsets to the location value.
- */
-static void
-merge_location_offset(GLint *location, GLint offset)
-{
-   *location = (*location << 16) | offset;
-}
-
-
-/**
- * Separate the uniform location and parameter offset.  See above.
- */
-static void
-split_location_offset(GLint *location, GLint *offset)
-{
-   *offset = *location & 0xffff;
-   *location = *location >> 16;
-}
-
-
-
-/**
- * Called via ctx->Driver.GetUniformfv().
- */
-static void
-_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
-                    GLfloat *params)
-{
-   struct gl_program *prog;
-   GLint paramPos;
-   GLint offset;
-
-   split_location_offset(&location, &offset);
-
-   lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
-
-   if (prog) {
-      const struct gl_program_parameter *p =
-         &prog->Parameters->Parameters[paramPos];
-      GLint rows, cols, i, j, k;
-
-      get_uniform_rows_cols(p, &rows, &cols);
-
-      k = 0;
-      for (i = 0; i < rows; i++) {
-         for (j = 0; j < cols; j++ ) {
-            params[k++] = prog->Parameters->ParameterValues[paramPos+i][j];
-         }
-      }
-   }
-}
-
-
-/**
- * Called via ctx->Driver.GetUniformiv().
- * \sa _mesa_get_uniformfv, only difference is a cast.
- */
-static void
-_mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location,
-                    GLint *params)
-{
-   struct gl_program *prog;
-   GLint paramPos;
-   GLint offset;
-
-   split_location_offset(&location, &offset);
-
-   lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
-
-   if (prog) {
-      const struct gl_program_parameter *p =
-         &prog->Parameters->Parameters[paramPos];
-      GLint rows, cols, i, j, k;
-
-      get_uniform_rows_cols(p, &rows, &cols);
-
-      k = 0;
-      for (i = 0; i < rows; i++) {
-         for (j = 0; j < cols; j++ ) {
-            params[k++] = (GLint) prog->Parameters->ParameterValues[paramPos+i][j];
-         }
-      }
-   }
-}
-
-
-/**
- * Called via ctx->Driver.GetUniformLocation().
- *
- * The return value will encode two values, the uniform location and an
- * offset (used for arrays, structs).
- */
-static GLint
-_mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name)
-{
-   GLint offset = 0, location = -1;
-
-   struct gl_shader_program *shProg =
-      _mesa_lookup_shader_program_err(ctx, program, "glGetUniformLocation");
-
-   if (!shProg)
-      return -1;
-
-   if (shProg->LinkStatus == GL_FALSE) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
-      return -1;
-   }
-
-   /* XXX we should return -1 if the uniform was declared, but not
-    * actually used.
-    */
-
-   /* XXX we need to be able to parse uniform names for structs and arrays
-    * such as:
-    *   mymatrix[1]
-    *   mystruct.field1
-    */
-
-   {
-      /* handle 1-dimension arrays here... */
-      char *c = strchr(name, '[');
-      if (c) {
-         /* truncate name at [ */
-         const GLint len = c - name;
-         GLchar *newName = malloc(len + 1);
-         if (!newName)
-            return -1; /* out of mem */
-         memcpy(newName, name, len);
-         newName[len] = 0;
-
-         location = _mesa_lookup_uniform(shProg->Uniforms, newName);
-         if (location >= 0) {
-            const GLint element = atoi(c + 1);
-            if (element > 0) {
-               /* get type of the uniform array element */
-               struct gl_program_parameter *p;
-               p = get_uniform_parameter(shProg, location);
-               if (p) {
-                  GLint rows, cols;
-                  get_matrix_dims(p->DataType, &rows, &cols);
-                  if (rows < 1)
-                     rows = 1;
-                  offset = element * rows;
-               }
-            }
-         }
-
-         free(newName);
-      }
-   }
-
-   if (location < 0) {
-      location = _mesa_lookup_uniform(shProg->Uniforms, name);
-   }
-
-   if (location >= 0) {
-      merge_location_offset(&location, offset);
-   }
-
-   return location;
-}
-
-
-/**
- * Check if the type given by userType is allowed to set a uniform of the
- * target type.  Generally, equivalence is required, but setting Boolean
- * uniforms can be done with glUniformiv or glUniformfv.
- */
-static GLboolean
-compatible_types(GLenum userType, GLenum targetType)
-{
-   if (userType == targetType)
-      return GL_TRUE;
-
-   if (targetType == GL_BOOL && (userType == GL_FLOAT ||
-                                 userType == GL_UNSIGNED_INT ||
-                                 userType == GL_INT))
-      return GL_TRUE;
-
-   if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 ||
-                                      userType == GL_UNSIGNED_INT_VEC2 ||
-                                      userType == GL_INT_VEC2))
-      return GL_TRUE;
-
-   if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 ||
-                                      userType == GL_UNSIGNED_INT_VEC3 ||
-                                      userType == GL_INT_VEC3))
-      return GL_TRUE;
-
-   if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 ||
-                                      userType == GL_UNSIGNED_INT_VEC4 ||
-                                      userType == GL_INT_VEC4))
-      return GL_TRUE;
-
-   if (is_sampler_type(targetType) && userType == GL_INT)
-      return GL_TRUE;
-
-   return GL_FALSE;
-}
-
-
-/**
- * Set the value of a program's uniform variable.
- * \param program  the program whose uniform to update
- * \param index  the index of the program parameter for the uniform
- * \param offset  additional parameter slot offset (for arrays)
- * \param type  the incoming datatype of 'values'
- * \param count  the number of uniforms to set
- * \param elems  number of elements per uniform (1, 2, 3 or 4)
- * \param values  the new values, of datatype 'type'
- */
-static void
-set_program_uniform(GLcontext *ctx, struct gl_program *program,
-                    GLint index, GLint offset,
-                    GLenum type, GLsizei count, GLint elems,
-                    const void *values)
-{
-   const struct gl_program_parameter *param =
-      &program->Parameters->Parameters[index];
-
-   assert(offset >= 0);
-   assert(elems >= 1);
-   assert(elems <= 4);
-
-   if (!compatible_types(type, param->DataType)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
-      return;
-   }
-
-   if (index + offset > (GLint) program->Parameters->Size) {
-      /* out of bounds! */
-      return;
-   }
-
-   if (param->Type == PROGRAM_SAMPLER) {
-      /* This controls which texture unit which is used by a sampler */
-      GLboolean changed = GL_FALSE;
-      GLint i;
-
-      /* this should have been caught by the compatible_types() check */
-      ASSERT(type == GL_INT);
-
-      /* loop over number of samplers to change */
-      for (i = 0; i < count; i++) {
-         GLuint sampler =
-            (GLuint) program->Parameters->ParameterValues[index + offset + i][0];
-         GLuint texUnit = ((GLuint *) values)[i];
-
-         /* check that the sampler (tex unit index) is legal */
-         if (texUnit >= ctx->Const.MaxTextureImageUnits) {
-            _mesa_error(ctx, GL_INVALID_VALUE,
-                        "glUniform1(invalid sampler/tex unit index for '%s')",
-                        param->Name);
-            return;
-         }
-
-         /* This maps a sampler to a texture unit: */
-         if (sampler < MAX_SAMPLERS) {
-#if 0
-            printf("Set program %p sampler %d '%s' to unit %u\n",
-                  program, sampler, param->Name, texUnit);
-#endif
-            if (program->SamplerUnits[sampler] != texUnit) {
-               program->SamplerUnits[sampler] = texUnit;
-               changed = GL_TRUE;
-            }
-         }
-      }
-
-      if (changed) {
-         /* When a sampler's value changes it usually requires rewriting
-          * a GPU program's TEX instructions since there may not be a
-          * sampler->texture lookup table.  We signal this with the
-          * ProgramStringNotify() callback.
-          */
-         FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
-         _mesa_update_shader_textures_used(program);
-         /* Do we need to care about the return value here?
-          * This should not be the first time the driver was notified of
-          * this program.
-          */
-         (void) ctx->Driver.ProgramStringNotify(ctx, program->Target, program);
-      }
-   }
-   else {
-      /* ordinary uniform variable */
-      const GLboolean isUniformBool = is_boolean_type(param->DataType);
-      const GLenum basicType = base_uniform_type(type);
-      const GLint slots = (param->Size + 3) / 4;
-      const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
-      GLsizei k, i;
-
-      if ((GLint) param->Size > typeSize) {
-         /* an array */
-         /* we'll ignore extra data below */
-      }
-      else {
-         /* non-array: count must be at most one; count == 0 is handled by the loop below */
-         if (count > 1) {
-            _mesa_error(ctx, GL_INVALID_OPERATION,
-                        "glUniform(uniform '%s' is not an array)",
-                        param->Name);
-            return;
-         }
-      }
-
-      /* loop over number of array elements */
-      for (k = 0; k < count; k++) {
-         GLfloat *uniformVal;
-
-         if (offset + k >= slots) {
-            /* Extra array data is ignored */
-            break;
-         }
-
-         /* uniformVal (the destination) is always float[4] */
-         uniformVal = program->Parameters->ParameterValues[index + offset + k];
-
-         if (basicType == GL_INT) {
-            /* convert user's ints to floats */
-            const GLint *iValues = ((const GLint *) values) + k * elems;
-            for (i = 0; i < elems; i++) {
-               uniformVal[i] = (GLfloat) iValues[i];
-            }
-         }
-         else if (basicType == GL_UNSIGNED_INT) {
-            /* convert user's uints to floats */
-            const GLuint *iValues = ((const GLuint *) values) + k * elems;
-            for (i = 0; i < elems; i++) {
-               uniformVal[i] = (GLfloat) iValues[i];
-            }
-         }
-         else {
-            const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
-            assert(basicType == GL_FLOAT);
-            for (i = 0; i < elems; i++) {
-               uniformVal[i] = fValues[i];
-            }
-         }
-
-         /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
-         if (isUniformBool) {
-            for (i = 0; i < elems; i++) {
-               uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f;
-            }
-         }
-      }
-   }
-}
-
-
-/**
- * Called via ctx->Driver.Uniform().
- */
-static void
-_mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
-              const GLvoid *values, GLenum type)
-{
-   struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
-   struct gl_uniform *uniform;
-   GLint elems, offset;
-
-   if (!shProg || !shProg->LinkStatus) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
-      return;
-   }
-
-   if (location == -1)
-      return;   /* The standard specifies this as a no-op */
-
-   if (location < -1) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(location=%d)",
-                  location);
-      return;
-   }
-
-   split_location_offset(&location, &offset);
-
-   if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location=%d)", location);
-      return;
-   }
-
-   if (count < 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)");
-      return;
-   }
-
-   elems = _mesa_sizeof_glsl_type(type);
-
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
-
-   uniform = &shProg->Uniforms->Uniforms[location];
-
-   if (ctx->Shader.Flags & GLSL_UNIFORMS) {
-      const GLenum basicType = base_uniform_type(type);
-      GLint i;
-      printf("Mesa: set program %u uniform %s (loc %d) to: ",
-            shProg->Name, uniform->Name, location);
-      if (basicType == GL_INT) {
-         const GLint *v = (const GLint *) values;
-         for (i = 0; i < count * elems; i++) {
-            printf("%d ", v[i]);
-         }
-      }
-      else if (basicType == GL_UNSIGNED_INT) {
-         const GLuint *v = (const GLuint *) values;
-         for (i = 0; i < count * elems; i++) {
-            printf("%u ", v[i]);
-         }
-      }
-      else {
-         const GLfloat *v = (const GLfloat *) values;
-         assert(basicType == GL_FLOAT);
-         for (i = 0; i < count * elems; i++) {
-            printf("%g ", v[i]);
-         }
-      }
-      printf("\n");
-   }
-
-   /* A uniform var may be used by both a vertex shader and a fragment
-    * shader.  We may need to update one or both shader's uniform here:
-    */
-   if (shProg->VertexProgram) {
-      /* convert uniform location to program parameter index */
-      GLint index = uniform->VertPos;
-      if (index >= 0) {
-         set_program_uniform(ctx, &shProg->VertexProgram->Base,
-                             index, offset, type, count, elems, values);
-      }
-   }
-
-   if (shProg->FragmentProgram) {
-      /* convert uniform location to program parameter index */
-      GLint index = uniform->FragPos;
-      if (index >= 0) {
-         set_program_uniform(ctx, &shProg->FragmentProgram->Base,
-                             index, offset, type, count, elems, values);
-      }
-   }
-
-   uniform->Initialized = GL_TRUE;
-}
-
-
-/**
- * Set a matrix-valued program parameter.
- */
-static void
-set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
-                           GLuint index, GLuint offset,
-                           GLuint count, GLuint rows, GLuint cols,
-                           GLboolean transpose, const GLfloat *values)
-{
-   GLuint mat, row, col;
-   GLuint src = 0;
-   const struct gl_program_parameter * param = &program->Parameters->Parameters[index];
-   const GLuint slots = (param->Size + 3) / 4;
-   const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
-   GLint nr, nc;
-
-   /* check that the number of rows, columns is correct */
-   get_matrix_dims(param->DataType, &nr, &nc);
-   if (rows != nr || cols != nc) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glUniformMatrix(matrix size mismatch)");
-      return;
-   }
-
-   if ((GLint) param->Size <= typeSize) {
-      /* non-array: count must be at most one; count == 0 is handled by the loop below */
-      if (count > 1) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glUniformMatrix(uniform is not an array)");
-         return;
-      }
-   }
-
-   /*
-    * Note: the _columns_ of a matrix are stored in program registers, not
-    * the rows.  So, the loops below look a little funny.
-    * XXX could optimize this a bit...
-    */
-
-   /* loop over matrices */
-   for (mat = 0; mat < count; mat++) {
-
-      /* each matrix: */
-      for (col = 0; col < cols; col++) {
-         GLfloat *v;
-         if (offset >= slots) {
-            /* Ignore writes beyond the end of (the used part of) an array */
-            return;
-         }
-         v = program->Parameters->ParameterValues[index + offset];
-         for (row = 0; row < rows; row++) {
-            if (transpose) {
-               v[row] = values[src + row * cols + col];
-            }
-            else {
-               v[row] = values[src + col * rows + row];
-            }
-         }
-
-         offset++;
-      }
-
-      src += rows * cols;  /* next matrix */
-   }
-}
-
-
-/**
- * Called by ctx->Driver.UniformMatrix().
- * Note: cols=2, rows=4  ==>  array[2] of vec4
- */
-static void
-_mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
-                     GLint location, GLsizei count,
-                     GLboolean transpose, const GLfloat *values)
-{
-   struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
-   struct gl_uniform *uniform;
-   GLint offset;
-
-   if (!shProg || !shProg->LinkStatus) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-         "glUniformMatrix(program not linked)");
-      return;
-   }
-
-   if (location == -1)
-      return;   /* The standard specifies this as a no-op */
-
-   if (location < -1) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(location)");
-      return;
-   }
-
-   split_location_offset(&location, &offset);
-
-   if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)");
-      return;
-   }
-   if (values == NULL) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix");
-      return;
-   }
-
-   FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
-
-   uniform = &shProg->Uniforms->Uniforms[location];
-
-   if (shProg->VertexProgram) {
-      /* convert uniform location to program parameter index */
-      GLint index = uniform->VertPos;
-      if (index >= 0) {
-         set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base,
-                                    index, offset,
-                                    count, rows, cols, transpose, values);
-      }
-   }
-
-   if (shProg->FragmentProgram) {
-      /* convert uniform location to program parameter index */
-      GLint index = uniform->FragPos;
-      if (index >= 0) {
-         set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base,
-                                    index, offset,
-                                    count, rows, cols, transpose, values);
-      }
-   }
-
-   uniform->Initialized = GL_TRUE;
-}
-
-
-
-void
-_mesa_init_uniform_functions(struct dd_function_table *driver)
-{
-   driver->GetActiveUniform = _mesa_get_active_uniform;
-   driver->GetUniformfv = _mesa_get_uniformfv;
-   driver->GetUniformiv = _mesa_get_uniformiv;
-   driver->GetUniformLocation = _mesa_get_uniform_location;
-   driver->Uniform = _mesa_uniform;
-   driver->UniformMatrix = _mesa_uniform_matrix;
-}
diff --git a/src/mesa/shader/uniforms.h b/src/mesa/shader/uniforms.h
deleted file mode 100644 (file)
index 52984de..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Mesa 3-D graphics library
- *
- * Copyright (C) 2010  VMware, 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
- * 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
- * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION 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 UNIFORMS_H
-#define UNIFORMS_H
-
-
-extern void
-_mesa_init_uniform_functions(struct dd_function_table *driver);
-
-
-#endif /* UNIFORMS_H */
diff --git a/src/mesa/slang/descrip.mms b/src/mesa/slang/descrip.mms
new file mode 100644 (file)
index 0000000..674b786
--- /dev/null
@@ -0,0 +1,67 @@
+# Makefile for core library for VMS
+# contributed by Jouk Jansen  joukj@hrem.nano.tudelft.nl
+# Last revision : 3 October 2007
+
+.first
+       define gl [----.include.gl]
+       define math [--.math]
+       define swrast [--.swrast]
+       define array_cache [--.array_cache]
+       define main [--.main]
+       define glapi [--.glapi]
+       define shader [--.shader]
+
+.include [----]mms-config.
+
+##### MACROS #####
+
+VPATH = RCS
+
+INCDIR = [----.include],[--.main],[--.glapi],[-.slang],[-]
+LIBDIR = [----.lib]
+CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short)/float=ieee/ieee=denorm
+
+SOURCES = \
+       slang_compile.c
+
+OBJECTS = slang_builtin.obj,slang_codegen.obj,slang_compile.obj,\
+       slang_compile_function.obj,slang_compile_operation.obj,\
+       slang_compile_struct.obj,slang_compile_variable.obj,slang_emit.obj,\
+       slang_ir.obj,slang_label.obj,slang_library_noise.obj,slang_link.obj,\
+       slang_log.obj,slang_mem.obj,slang_preprocess.obj,slang_print.obj,\
+       slang_simplify.obj,slang_storage.obj,slang_typeinfo.obj,\
+       slang_utility.obj,slang_vartable.obj
+
+##### RULES #####
+
+VERSION=Mesa V3.4
+
+##### TARGETS #####
+# Make the library
+$(LIBDIR)$(GL_LIB) : $(OBJECTS)
+  @ library $(LIBDIR)$(GL_LIB) $(OBJECTS)
+
+clean :
+       purge
+       delete *.obj;*
+
+slang_builtin.obj : slang_builtin.c
+slang_codegen.obj : slang_codegen.c
+slang_compile.obj : slang_compile.c
+slang_compile_function.obj : slang_compile_function.c
+slang_compile_operation.obj : slang_compile_operation.c
+slang_compile_struct.obj : slang_compile_struct.c
+slang_compile_variable.obj : slang_compile_variable.c
+slang_emit.obj : slang_emit.c
+slang_ir.obj : slang_ir.c
+slang_label.obj : slang_label.c
+slang_library_noise.obj : slang_library_noise.c
+slang_link.obj : slang_link.c
+slang_log.obj : slang_log.c
+slang_mem.obj : slang_mem.c
+slang_print.obj : slang_print.c
+slang_simplify.obj : slang_simplify.c
+slang_storage.obj : slang_storage.c
+slang_typeinfo.obj : slang_typeinfo.c
+slang_utility.obj : slang_utility.c
+slang_vartable.obj : slang_vartable.c
diff --git a/src/mesa/slang/library/.gitignore b/src/mesa/slang/library/.gitignore
new file mode 100644 (file)
index 0000000..02a89fc
--- /dev/null
@@ -0,0 +1 @@
+*_gc.h
diff --git a/src/mesa/slang/library/Makefile b/src/mesa/slang/library/Makefile
new file mode 100644 (file)
index 0000000..f546a03
--- /dev/null
@@ -0,0 +1,54 @@
+# src/mesa/slang/library/Makefile
+
+TOP = ../../../..
+
+include $(TOP)/configs/current
+
+GLSL_CL = $(TOP)/src/glsl/apps/compile
+
+#
+# targets
+#
+
+.PHONY: default clean
+
+default: builtin
+
+clean:
+       -rm -f *_gc.h
+
+builtin: builtin_110 builtin_120
+
+#
+# builtin library sources
+#
+
+builtin_110: slang_common_builtin_gc.h slang_core_gc.h slang_fragment_builtin_gc.h slang_vertex_builtin_gc.h slang_geometry_builtin_gc.h
+
+builtin_120: slang_120_core_gc.h slang_builtin_120_common_gc.h slang_builtin_120_fragment_gc.h
+
+
+slang_120_core_gc.h: slang_120_core.gc
+       $(GLSL_CL) fragment slang_120_core.gc slang_120_core_gc.h
+
+slang_builtin_120_common_gc.h: slang_builtin_120_common.gc
+       $(GLSL_CL) fragment slang_builtin_120_common.gc slang_builtin_120_common_gc.h
+
+slang_builtin_120_fragment_gc.h: slang_builtin_120_fragment.gc
+       $(GLSL_CL) fragment slang_builtin_120_fragment.gc slang_builtin_120_fragment_gc.h
+
+slang_common_builtin_gc.h: slang_common_builtin.gc
+       $(GLSL_CL) fragment slang_common_builtin.gc slang_common_builtin_gc.h
+
+slang_core_gc.h: slang_core.gc
+       $(GLSL_CL) fragment slang_core.gc slang_core_gc.h
+
+slang_fragment_builtin_gc.h: slang_fragment_builtin.gc
+       $(GLSL_CL) fragment slang_fragment_builtin.gc slang_fragment_builtin_gc.h
+
+slang_vertex_builtin_gc.h: slang_vertex_builtin.gc
+       $(GLSL_CL) vertex slang_vertex_builtin.gc slang_vertex_builtin_gc.h
+
+slang_geometry_builtin_gc.h: slang_geometry_builtin.gc
+       $(GLSL_CL) geometry slang_geometry_builtin.gc slang_geometry_builtin_gc.h
+
diff --git a/src/mesa/slang/library/SConscript b/src/mesa/slang/library/SConscript
new file mode 100644 (file)
index 0000000..5112cef
--- /dev/null
@@ -0,0 +1,62 @@
+#######################################################################
+# SConscript for GLSL builtin library
+
+Import('*')
+
+env = env.Clone()
+
+# See also http://www.scons.org/wiki/UsingCodeGenerators
+
+def glsl_compile_emitter(target, source, env):
+       env.Depends(target, glsl_compile)
+       return (target, source)
+
+bld_frag = Builder(
+       action = Action(glsl_compile[0].abspath + ' fragment $SOURCE $TARGET', '$CODEGENCODESTR'),
+       emitter = glsl_compile_emitter,
+       suffix = '.gc',
+       src_suffix = '_gc.h')
+
+bld_vert = Builder(
+       action = Action(glsl_compile[0].abspath + ' vertex $SOURCE $TARGET', '$CODEGENCODESTR'),
+       emitter = glsl_compile_emitter,
+       suffix = '.gc',
+       src_suffix = '_gc.h')
+
+bld_geom = Builder(
+       action = Action(glsl_compile[0].abspath + ' geometry $SOURCE $TARGET', '$CODEGENCODESTR'),
+       emitter = glsl_compile_emitter,
+       suffix = '.gc',
+       src_suffix = '_gc.h')
+
+env['BUILDERS']['bld_frag'] = bld_frag
+env['BUILDERS']['bld_vert'] = bld_vert
+env['BUILDERS']['bld_geom'] = bld_geom
+
+# Generate GLSL builtin library binaries
+env.bld_frag(
+       '#src/mesa/slang/library/slang_core_gc.h',
+       '#src/mesa/slang/library/slang_core.gc')
+env.bld_frag(
+       '#src/mesa/slang/library/slang_common_builtin_gc.h',
+       '#src/mesa/slang/library/slang_common_builtin.gc')
+env.bld_frag(
+       '#src/mesa/slang/library/slang_fragment_builtin_gc.h',
+       '#src/mesa/slang/library/slang_fragment_builtin.gc')
+env.bld_vert(
+       '#src/mesa/slang/library/slang_vertex_builtin_gc.h',
+       '#src/mesa/slang/library/slang_vertex_builtin.gc')
+env.bld_geom(
+       '#src/mesa/slang/library/slang_geometry_builtin_gc.h',
+       '#src/mesa/slang/library/slang_geometry_builtin.gc')
+
+# Generate GLSL 1.20 builtin library binaries
+env.bld_frag(
+       '#src/mesa/slang/library/slang_120_core_gc.h',
+       '#src/mesa/slang/library/slang_120_core.gc')
+env.bld_frag(
+       '#src/mesa/slang/library/slang_builtin_120_common_gc.h',
+       '#src/mesa/slang/library/slang_builtin_120_common.gc')
+env.bld_frag(
+       '#src/mesa/slang/library/slang_builtin_120_fragment_gc.h',
+       '#src/mesa/slang/library/slang_builtin_120_fragment.gc')
diff --git a/src/mesa/slang/library/slang_120_core.gc b/src/mesa/slang/library/slang_120_core.gc
new file mode 100644 (file)
index 0000000..04c5ec2
--- /dev/null
@@ -0,0 +1,1978 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+//
+// Constructors and operators introduced in GLSL 1.20 - mostly on new
+// (non-square) types of matrices.
+//
+// One important change in the language is that when a matrix is used
+// as an argument to a matrix constructor, it must be the only argument
+// for the constructor. The compiler takes care of it by itself and
+// here we only care to re-introduce constructors for old (square)
+// types of matrices.
+//
+
+//
+// From Shader Spec, ver. 1.20, rev. 6
+//
+
+//// mat2x3: 2 columns of vec3
+
+mat2x3 __constructor(const float f00, const float f10, const float f20,
+                     const float f01, const float f11, const float f21)
+{
+   __retVal[0].x = f00;
+   __retVal[0].y = f10;
+   __retVal[0].z = f20;
+   __retVal[1].x = f01;
+   __retVal[1].y = f11;
+   __retVal[1].z = f21;
+}
+
+mat2x3 __constructor(const float f)
+{
+   __retVal = mat2x3(  f, 0.0, 0.0,
+                     0.0,   f, 0.0);
+}
+
+mat2x3 __constructor(const int  i)
+{
+   const float f = float(i);
+   __retVal = mat2x3(f);
+}
+
+mat2x3 __constructor(const bool b)
+{
+   const float f = float(b);
+   __retVal = mat2x3(f);
+}
+
+mat2x3 __constructor(const vec3 c0, const vec3 c1)
+{
+   __retVal[0] = c0;
+   __retVal[1] = c1;
+}
+
+
+
+//// mat2x4: 2 columns of vec4
+
+mat2x4 __constructor(const float f00, const float f10, const float f20, const float f30,
+                     const float f01, const float f11, const float f21, const float f31)
+{
+   __retVal[0].x = f00;
+   __retVal[0].y = f10;
+   __retVal[0].z = f20;
+   __retVal[0].w = f30;
+   __retVal[1].x = f01;
+   __retVal[1].y = f11;
+   __retVal[1].z = f21;
+   __retVal[1].w = f31;
+}
+
+mat2x4 __constructor(const float f)
+{
+   __retVal = mat2x4(  f, 0.0, 0.0, 0.0,
+                     0.0,   f, 0.0, 0.0);
+}
+
+mat2x4 __constructor(const int i)
+{
+   const float f = float(i);
+   __retVal = mat2x4(f);
+}
+
+mat2x4 __constructor(const bool b)
+{
+   const float f = float(b);
+   __retVal = mat2x4(f);
+}
+
+mat2x4 __constructor(const vec4 c0, const vec4 c1)
+{
+   __retVal[0] = c0;
+   __retVal[1] = c1;
+}
+
+
+
+//// mat3x2: 3 columns of vec2
+
+mat3x2 __constructor(const float f00, const float f10,
+                     const float f01, const float f11,
+                     const float f02, const float f12)
+{
+   __retVal[0].x = f00;
+   __retVal[0].y = f10;
+   __retVal[1].x = f01;
+   __retVal[1].y = f11;
+   __retVal[2].x = f02;
+   __retVal[2].y = f12;
+}
+
+mat3x2 __constructor(const float f)
+{
+   __retVal = mat3x2(  f, 0.0,
+                     0.0,   f,
+                     0.0, 0.0);
+}
+
+mat3x2 __constructor(const int i)
+{
+   const float f = float(i);
+   __retVal = mat3x2(f);
+}
+
+mat3x2 __constructor(const bool b)
+{
+   const float f = float(b);
+   __retVal = mat3x2(f);
+}
+
+mat3x2 __constructor(const vec2 c0, const vec2 c1, const vec2 c2)
+{
+   __retVal[0] = c0;
+   __retVal[1] = c1;
+   __retVal[2] = c2;
+}
+
+
+
+//// mat3x4: 3 columns of vec4
+
+mat3x4 __constructor(const float f00, const float f10, const float f20, const float f30,
+                     const float f01, const float f11, const float f21, const float f31,
+                    const float f02, const float f12, const float f22, const float f32)
+{
+   __retVal[0].x = f00;
+   __retVal[0].y = f10;
+   __retVal[0].z = f20;
+   __retVal[0].w = f30;
+   __retVal[1].x = f01;
+   __retVal[1].y = f11;
+   __retVal[1].z = f21;
+   __retVal[1].w = f31;
+   __retVal[2].x = f02;
+   __retVal[2].y = f12;
+   __retVal[2].z = f22;
+   __retVal[2].w = f32;
+}
+
+mat3x4 __constructor(const float f)
+{
+   __retVal = mat3x4(  f, 0.0, 0.0, 0.0,
+                     0.0,   f, 0.0, 0.0,
+                     0.0, 0.0,   f, 0.0);
+}
+
+mat3x4 __constructor(const int i)
+{
+   const float f = float(i);
+   __retVal = mat3x4(f);
+}
+
+mat3x4 __constructor(const bool b)
+{
+   const float f = float(b);
+   __retVal = mat3x4(f);
+}
+
+mat3x4 __constructor(const vec4 c0, const vec4 c1, const vec4 c2)
+{
+   __retVal[0] = c0;
+   __retVal[1] = c1;
+   __retVal[2] = c2;
+}
+
+
+
+//// mat4x2: 4 columns of vec2
+
+mat4x2 __constructor(const float f00, const float f10,
+                     const float f01, const float f11,
+                    const float f02, const float f12,
+                    const float f03, const float f13)
+{
+   __retVal[0].x = f00;
+   __retVal[0].y = f10;
+   __retVal[1].x = f01;
+   __retVal[1].y = f11;
+   __retVal[2].x = f02;
+   __retVal[2].y = f12;
+   __retVal[3].x = f03;
+   __retVal[3].y = f13;
+}
+
+mat4x2 __constructor(const float f)
+{
+   __retVal = mat4x2(  f, 0.0,
+                     0.0,   4,
+                     0.0, 0.0,
+                     0.0, 0.0);
+}
+
+mat4x2 __constructor(const int i)
+{
+   const float f = float(i);
+   __retVal = mat4x2(f);
+}
+
+mat4x2 __constructor(const bool b)
+{
+   const float f = float(b);
+   __retVal = mat4x2(f);
+}
+
+mat4x2 __constructor(const vec2 c0, const vec2 c1, const vec2 c2, const vec2 c3)
+{
+   __retVal[0] = c0;
+   __retVal[1] = c1;
+   __retVal[2] = c2;
+   __retVal[3] = c3;
+}
+
+
+
+//// mat4x3: 4 columns of vec3
+
+mat4x3 __constructor(const float f00, const float f10, const float f20,
+                     const float f01, const float f11, const float f21,
+                    const float f02, const float f12, const float f22,
+                    const float f03, const float f13, const float f23)
+{
+   __retVal[0].x = f00;
+   __retVal[0].y = f10;
+   __retVal[0].z = f20;
+   __retVal[1].x = f01;
+   __retVal[1].y = f11;
+   __retVal[1].z = f21;
+   __retVal[2].x = f02;
+   __retVal[2].y = f12;
+   __retVal[2].z = f22;
+   __retVal[3].x = f03;
+   __retVal[3].y = f13;
+   __retVal[3].z = f23;
+}
+
+mat4x3 __constructor(const float f)
+{
+   __retVal = mat4x3(  f, 0.0, 0.0,
+                     0.0,   f, 0.0,
+                     0.0, 0.0,   f,
+                     0.0, 0.0, 0.0);
+}
+
+mat4x3 __constructor(const int i)
+{
+   const float f = float(i);
+   __retVal = mat4x3(f);
+}
+
+mat4x3 __constructor(const bool b)
+{
+   const float f = float(b);
+   __retVal = mat4x3(f);
+}
+
+mat4x3 __constructor(const vec3 c0, const vec3 c1, const vec3 c2, const vec3 c3)
+{
+   __retVal[0] = c0;
+   __retVal[1] = c1;
+   __retVal[2] = c2;
+   __retVal[3] = c3;
+}
+
+
+
+//// misc assorted matrix constructors
+
+mat2 __constructor(const mat2 m)
+{
+   __retVal = m;
+}
+
+mat2 __constructor(const mat3x2 m)
+{
+   __retVal = mat2(m[0], m[1]);
+}
+
+mat2 __constructor(const mat4x2 m)
+{
+   __retVal = mat2(m[0], m[1]);
+}
+
+mat2 __constructor(const mat2x3 m)
+{
+   __retVal = mat2(m[0].xy, m[1].xy);
+}
+
+mat2 __constructor(const mat2x4 m)
+{
+   __retVal = mat2(m[0].xy, m[1].xy);
+}
+
+mat2 __constructor(const mat3 m)
+{
+   __retVal = mat2(m[0].xy, m[1].xy);
+}
+
+mat2 __constructor(const mat3x4 m)
+{
+   __retVal = mat2(m[0].xy, m[1].xy);
+}
+
+mat2 __constructor(const mat4x3 m)
+{
+   __retVal = mat2(m[0].xy, m[1].xy);
+}
+
+mat2 __constructor(const mat4 m)
+{
+   __retVal = mat2(m[0].xy, m[1].xy);
+}
+
+
+
+mat2x3 __constructor(const mat2x3 m)
+{
+   __retVal = m;
+}
+
+mat2x3 __constructor(const mat3 m)
+{
+   __retVal = mat2x3(m[0], m[1]);
+}
+
+mat2x3 __constructor(const mat4x3 m)
+{
+   __retVal = mat2x3(m[0], m[1]);
+}
+
+mat2x3 __constructor(const mat2x4 m)
+{
+   __retVal = mat2x3(m[0].xyz, m[1].xyz);
+}
+
+mat2x3 __constructor(const mat3x4 m)
+{
+   __retVal = mat2x3(m[0].xyz, m[1].xyz);
+}
+
+mat2x3 __constructor(const mat4 m)
+{
+   __retVal = mat2x3(m[0].xyz, m[1].xyz);
+}
+
+mat2x3 __constructor(const mat2 m)
+{
+   __retVal = mat2x3(m[0].x, m[0].y, 0.0,
+                     m[1].x, m[1].y, 0.0);
+}
+
+mat2x3 __constructor(const mat3x2 m)
+{
+   __retVal = mat2x3(m[0].x, m[0].y, 0.0,
+                     m[1].x, m[1].y, 0.0);
+}
+
+mat2x3 __constructor(const mat4x2 m)
+{
+   __retVal = mat2x3(m[0].x, m[0].y, 0.0,
+                     m[1].x, m[1].y, 0.0);
+}
+
+
+
+mat2x4 __constructor(const mat2x4 m)
+{
+   __retVal = m;
+}
+
+mat2x4 __constructor(const mat3x4 m)
+{
+   __retVal = mat2x4(m[0], m[1]);
+}
+
+mat2x4 __constructor(const mat4 m)
+{
+   __retVal = mat2x4(m[0], m[1]);
+}
+
+mat2x4 __constructor(const mat2x3 m)
+{
+   __retVal = mat2x4(m[0].x, m[0].y, m[0].z, 0.0,
+                     m[1].x, m[1].y, m[1].z, 0.0);
+}
+
+mat2x4 __constructor(const mat3 m)
+{
+   __retVal = mat2x4(m[0].x, m[0].y, m[0].z, 0.0,
+                     m[1].x, m[1].y, m[1].z, 0.0);
+}
+
+mat2x4 __constructor(const mat4x3 m)
+{
+   __retVal = mat2x4(m[0].x, m[0].y, m[0].z, 0.0,
+                     m[1].x, m[1].y, m[1].z, 0.0);
+}
+
+mat2x4 __constructor(const mat2 m)
+{
+   __retVal = mat2x4(m[0].x, m[1].y, 0.0, 0.0,
+                     m[1].x, m[1].y, 0.0, 0.0);
+}
+
+mat2x4 __constructor(const mat3x2 m)
+{
+   __retVal = mat2x4(m[0].x, m[0].y, 0.0, 0.0,
+                     m[1].x, m[1].y, 0.0, 0.0);
+}
+
+mat2x4 __constructor(const mat4x2 m)
+{
+   __retVal = mat2x4(m[0].x, m[0].y, 0.0, 0.0,
+                     m[1].x, m[1].y, 0.0, 0.0);
+}
+
+
+
+mat3x2 __constructor(const mat3x2 m)
+{
+   __retVal = m;
+}
+
+mat3x2 __constructor(const mat4x2 m)
+{
+   __retVal = mat3x2(m[0], m[1], m[2]);
+}
+
+mat3x2 __constructor(const mat3 m)
+{
+   __retVal = mat3x2(m[0], m[1], m[2]);
+}
+
+mat3x2 __constructor(const mat3x4 m)
+{
+   __retVal = mat3x2(m[0].x, m[0].y,
+                     m[1].x, m[1].y,
+                     m[2].x, m[2].y);
+}
+
+mat3x2 __constructor(const mat4x3 m)
+{
+   __retVal = mat3x2(m[0].x, m[0].y,
+                     m[1].x, m[1].y,
+                     m[2].x, m[2].y);
+}
+
+mat3x2 __constructor(const mat4 m)
+{
+   __retVal = mat3x2(m[0].x, m[0].y,
+                     m[1].x, m[1].y,
+                        0.0,    0.0);
+}
+
+mat3x2 __constructor(const mat2 m)
+{
+   __retVal = mat3x2(m[0], m[1], vec2(0.0));
+}
+
+mat3x2 __constructor(const mat2x3 m)
+{
+   __retVal = mat3x2(m[0].x, m[0].y,
+                     m[1].x, m[1].y,
+                        0.0,    0.0);
+}
+
+mat3x2 __constructor(const mat2x4 m)
+{
+   __retVal = mat3x2(m[0].x, m[0].y,
+                     m[1].x, m[1].y,
+                        0.0,    0.0);
+}
+
+
+
+
+mat3 __constructor(const mat3 m)
+{
+   __retVal = m;
+}
+
+mat3 __constructor(const mat4x3 m)
+{
+   __retVal = mat3 (
+        m[0],
+        m[1],
+        m[2]
+    );
+}
+
+mat3 __constructor(const mat3x4 m)
+{
+   __retVal = mat3 (
+        m[0].xyz,
+        m[1].xyz,
+        m[2].xyz
+    );
+}
+
+mat3 __constructor(const mat4 m)
+{
+   __retVal = mat3 (
+        m[0].xyz,
+        m[1].xyz,
+        m[2].xyz
+    );
+}
+
+mat3 __constructor(const mat2x3 m)
+{
+   __retVal = mat3 (
+        m[0],
+        m[1],
+        0., 0., 1.
+    );
+}
+
+mat3 __constructor(const mat2x4 m)
+{
+   __retVal = mat3 (
+        m[0].xyz,
+        m[1].xyz,
+        0., 0., 1.
+    );
+}
+
+mat3 __constructor(const mat3x2 m)
+{
+   __retVal = mat3 (
+        m[0], 0.,
+        m[1], 0.,
+        m[2], 1.
+    );
+}
+
+mat3 __constructor(const mat4x2 m)
+{
+   __retVal = mat3 (
+        m[0], 0.,
+        m[1], 0.,
+        m[2], 1.
+    );
+}
+
+mat3 __constructor(const mat2 m)
+{
+   __retVal = mat3 (
+        m[0], 0.,
+        m[1], 0.,
+        0., 0., 1.
+    );
+}
+
+
+mat3x4 __constructor(const mat3x4 m)
+{
+   __retVal = m;
+}
+
+mat3x4 __constructor(const mat4 m)
+{
+   __retVal = mat3x4 (
+        m[0],
+        m[1],
+        m[2]
+    );
+}
+
+mat3x4 __constructor(const mat3 m)
+{
+   __retVal = mat3x4 (
+        m[0], 0.,
+        m[1], 0.,
+        m[2], 0.
+    );
+}
+
+mat3x4 __constructor(const mat4x3 m)
+{
+   __retVal = mat3x4 (
+        m[0], 0.,
+        m[1], 0.,
+        m[2], 0.
+    );
+}
+
+mat3x4 __constructor(const mat2x4 m)
+{
+   __retVal = mat3x4 (
+        m[0],
+        m[1],
+        0., 0., 1., 0.
+    );
+}
+
+mat3x4 __constructor(const mat2x3 m)
+{
+   __retVal = mat3x4 (
+        m[0], 0.,
+        m[1], 0.,
+        0., 0., 1., 0.
+    );
+}
+
+mat3x4 __constructor(const mat3x2 m)
+{
+   __retVal = mat3x4 (
+        m[0], 0., 0.,
+        m[1], 0., 0.,
+        m[2], 1., 0.
+    );
+}
+
+mat3x4 __constructor(const mat4x2 m)
+{
+   __retVal = mat3x4 (
+        m[0], 0., 0.,
+        m[1], 0., 0.,
+        m[2], 1., 0.
+    );
+}
+
+mat3x4 __constructor(const mat2 m)
+{
+   __retVal = mat3x4 (
+        m[0], 0., 0.,
+        m[1], 0., 0.,
+        0., 0., 1., 0.
+    );
+}
+
+
+mat4x2 __constructor(const mat4x2 m)
+{
+   __retVal = m;
+}
+
+mat4x2 __constructor(const mat4x3 m)
+{
+   __retVal = mat4x2 (
+        m[0].xy,
+        m[1].xy,
+        m[2].xy,
+        m[3].xy
+    );
+}
+
+mat4x2 __constructor(const mat4 m)
+{
+   __retVal = mat4x2 (
+        m[0].xy,
+        m[1].xy,
+        m[2].xy,
+        m[3].xy
+    );
+}
+
+mat4x2 __constructor(const mat3x2 m)
+{
+   __retVal = mat4x2 (
+        m[0],
+        m[1],
+        0., 0.
+    );
+}
+
+mat4x2 __constructor(const mat3 m)
+{
+   __retVal = mat4x2 (
+        m[0].xy,
+        m[1].xy,
+        m[2].xy,
+        0., 0.
+    );
+}
+
+mat4x2 __constructor(const mat3x4 m)
+{
+   __retVal = mat4x2 (
+        m[0].xy,
+        m[1].xy,
+        m[2].xy,
+        0., 0.
+    );
+}
+
+mat4x2 __constructor(const mat2 m)
+{
+   __retVal = mat4x2 (
+        m[0],
+        m[1],
+        0., 0.,
+        0., 0.
+    );
+}
+
+mat4x2 __constructor(const mat2x3 m)
+{
+   __retVal = mat4x2 (
+        m[0].xy,
+        m[1].xy,
+        0., 0.,
+        0., 0.
+    );
+}
+
+mat4x2 __constructor(const mat2x4 m)
+{
+   __retVal = mat4x2 (
+        m[0].xy,
+        m[1].xy,
+        0., 0.,
+        0., 0.
+    );
+}
+
+
+mat4x3 __constructor(const mat4x3 m)
+{
+   __retVal = m;
+}
+
+mat4x3 __constructor(const mat4 m)
+{
+   __retVal = mat4x3 (
+        m[0].xyz,
+        m[1].xyz,
+        m[2].xyz,
+        m[3].xyz
+    );
+}
+
+mat4x3 __constructor(const mat3 m)
+{
+   __retVal = mat4x3 (
+        m[0],
+        m[1],
+        m[2],
+        0., 0., 0.
+    );
+}
+
+mat4x3 __constructor(const mat3x4 m)
+{
+   __retVal = mat4x3 (
+        m[0].xyz,
+        m[1].xyz,
+        m[2].xyz,
+        0., 0., 0.
+    );
+}
+
+mat4x3 __constructor(const mat4x2 m)
+{
+   __retVal = mat4x3 (
+        m[0], 0.,
+        m[1], 0.,
+        m[2], 1.,
+        m[3], 0.
+    );
+}
+
+mat4x3 __constructor(const mat2x3 m)
+{
+   __retVal = mat4x3 (
+        m[0],
+        m[1],
+        0., 0., 1.,
+        0., 0., 0.
+    );
+}
+
+mat4x3 __constructor(const mat3x2 m)
+{
+   __retVal = mat4x3 (
+        m[0], 0.,
+        m[1], 0.,
+        m[2], 1.,
+        0., 0., 0.
+    );
+}
+
+mat4x3 __constructor(const mat2x4 m)
+{
+   __retVal = mat4x3 (
+        m[0].xyz,
+        m[1].xyz,
+        0., 0., 1.,
+        0., 0., 0.
+    );
+}
+
+mat4x3 __constructor(const mat2 m)
+{
+   __retVal = mat4x3 (
+        m[0], 0.,
+        m[1], 0.,
+        0., 0., 1.,
+        0., 0., 0.
+    );
+}
+
+
+mat4 __constructor(const mat4 m)
+{
+   __retVal = m;
+}
+
+mat4 __constructor(const mat3x4 m)
+{
+   __retVal = mat4 (
+        m[0],
+        m[1],
+        m[2],
+        0., 0., 0., 1.
+    );
+}
+
+mat4 __constructor(const mat4x3 m)
+{
+   __retVal = mat4 (
+        m[0], 0.,
+        m[1], 0.,
+        m[2], 0.,
+        m[3], 1.
+    );
+}
+
+mat4 __constructor(const mat2x4 m)
+{
+   __retVal = mat4 (
+        m[0],
+        m[1],
+        0., 0., 1., 0.,
+        0., 0., 0., 1.
+    );
+}
+
+mat4 __constructor(const mat4x2 m)
+{
+   __retVal = mat4 (
+        m[0], 0., 0.,
+        m[1], 0., 0.,
+        m[2], 1., 0.,
+        m[3], 0., 1.
+    );
+}
+
+mat4 __constructor(const mat3 m)
+{
+   __retVal = mat4 (
+        m[0], 0.,
+        m[1], 0.,
+        m[2], 0.,
+        0., 0., 0., 1.
+    );
+}
+
+mat4 __constructor(const mat2x3 m)
+{
+   __retVal = mat4 (
+        m[0], 0.,
+        m[1], 0.,
+        0., 0., 1., 0.,
+        0., 0., 0., 1.
+    );
+}
+
+mat4 __constructor(const mat3x2 m)
+{
+   __retVal = mat4 (
+        m[0], 0., 0.,
+        m[1], 0., 0.,
+        m[2], 1., 0.,
+        0., 0., 0., 1.
+    );
+}
+
+mat4 __constructor(const mat2 m)
+{
+   __retVal = mat4 (
+        m[0], 0., 0.,
+        m[1], 0., 0.,
+        0., 0., 1., 0.,
+        0., 0., 0., 1.
+    );
+}
+
+
+void __operator += (inout mat2x3 m, const mat2x3 n) {
+    m[0] += n[0];
+    m[1] += n[1];
+}
+
+void __operator += (inout mat2x4 m, const mat2x4 n) {
+    m[0] += n[0];
+    m[1] += n[1];
+}
+
+void __operator += (inout mat3x2 m, const mat3x2 n) {
+    m[0] += n[0];
+    m[1] += n[1];
+    m[2] += n[2];
+}
+
+void __operator += (inout mat3x4 m, const mat3x4 n) {
+    m[0] += n[0];
+    m[1] += n[1];
+    m[2] += n[2];
+}
+
+void __operator += (inout mat4x2 m, const mat4x2 n) {
+    m[0] += n[0];
+    m[1] += n[1];
+    m[2] += n[2];
+    m[3] += n[3];
+}
+
+void __operator += (inout mat4x3 m, const mat4x3 n) {
+    m[0] += n[0];
+    m[1] += n[1];
+    m[2] += n[2];
+    m[3] += n[3];
+}
+
+
+void __operator -= (inout mat2x3 m, const mat2x3 n) {
+    m[0] -= n[0];
+    m[1] -= n[1];
+}
+
+void __operator -= (inout mat2x4 m, const mat2x4 n) {
+    m[0] -= n[0];
+    m[1] -= n[1];
+}
+
+void __operator -= (inout mat3x2 m, const mat3x2 n) {
+    m[0] -= n[0];
+    m[1] -= n[1];
+    m[2] -= n[2];
+}
+
+void __operator -= (inout mat3x4 m, const mat3x4 n) {
+    m[0] -= n[0];
+    m[1] -= n[1];
+    m[2] -= n[2];
+}
+
+void __operator -= (inout mat4x2 m, const mat4x2 n) {
+    m[0] -= n[0];
+    m[1] -= n[1];
+    m[2] -= n[2];
+    m[3] -= n[3];
+}
+
+void __operator -= (inout mat4x3 m, const mat4x3 n) {
+    m[0] -= n[0];
+    m[1] -= n[1];
+    m[2] -= n[2];
+    m[3] -= n[3];
+}
+
+
+void __operator /= (inout mat2x3 m, const mat2x3 n) {
+    m[0] /= n[0];
+    m[1] /= n[1];
+}
+
+void __operator /= (inout mat2x4 m, const mat2x4 n) {
+    m[0] /= n[0];
+    m[1] /= n[1];
+}
+
+void __operator /= (inout mat3x2 m, const mat3x2 n) {
+    m[0] /= n[0];
+    m[1] /= n[1];
+    m[2] /= n[2];
+}
+
+void __operator /= (inout mat3x4 m, const mat3x4 n) {
+    m[0] /= n[0];
+    m[1] /= n[1];
+    m[2] /= n[2];
+}
+
+void __operator /= (inout mat4x2 m, const mat4x2 n) {
+    m[0] /= n[0];
+    m[1] /= n[1];
+    m[2] /= n[2];
+    m[3] /= n[3];
+}
+
+void __operator /= (inout mat4x3 m, const mat4x3 n) {
+    m[0] /= n[0];
+    m[1] /= n[1];
+    m[2] /= n[2];
+    m[3] /= n[3];
+}
+
+
+vec3 __operator * (const mat2x3 m, const vec2 v)
+{
+   __retVal.x = v.x * m[0].x + v.y * m[1].x;
+   __retVal.y = v.x * m[0].y + v.y * m[1].y;
+   __retVal.z = v.x * m[0].z + v.y * m[1].z;
+}
+
+vec4 __operator * (const mat2x4 m, const vec2 v)
+{
+   __retVal.x = v.x * m[0].x + v.y * m[1].x;
+   __retVal.y = v.x * m[0].y + v.y * m[1].y;
+   __retVal.z = v.x * m[0].z + v.y * m[1].z;
+   __retVal.w = v.x * m[0].w + v.y * m[1].w;
+}
+
+vec2 __operator * (const mat3x2 m, const vec3 v)
+{
+   __retVal.x = v.x * m[0].x + v.y * m[1].x + v.z * m[2].x;
+   __retVal.y = v.x * m[0].y + v.y * m[1].y + v.z * m[2].y;
+}
+
+vec4 __operator * (const mat3x4 m, const vec3 v)
+{
+   __retVal.x = v.x * m[0].x + v.y * m[1].x + v.z * m[2].x;
+   __retVal.y = v.x * m[0].y + v.y * m[1].y + v.z * m[2].y;
+   __retVal.z = v.x * m[0].z + v.y * m[1].z + v.z * m[2].z;
+   __retVal.w = v.x * m[0].w + v.y * m[1].w + v.z * m[2].w;
+}
+
+vec2 __operator * (const mat4x2 m, const vec4 v)
+{
+   __retVal.x = v.x * m[0].x + v.y * m[1].x + v.z * m[2].x + v.w * m[3].x;
+   __retVal.y = v.x * m[0].y + v.y * m[1].y + v.z * m[2].y + v.w * m[3].y;
+}
+
+vec3 __operator * (const mat4x3 m, const vec4 v)
+{
+   __retVal.x = v.x * m[0].x + v.y * m[1].x + v.z * m[2].x + v.w * m[3].x;
+   __retVal.y = v.x * m[0].y + v.y * m[1].y + v.z * m[2].y + v.w * m[3].y;
+   __retVal.z = v.x * m[0].z + v.y * m[1].z + v.z * m[2].z + v.w * m[3].z;
+}
+
+
+mat3x2 __operator * (const mat2 m, const mat3x2 n)
+{
+   //return mat3x2 (m * n[0], m * n[1], m * n[2]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+   __retVal[2] = m * n[2];
+}
+
+mat4x2 __operator * (const mat2 m, const mat4x2 n)
+{
+   //return mat4x2 (m * n[0], m * n[1], m * n[2], m * n[3]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+   __retVal[2] = m * n[2];
+   __retVal[3] = m * n[3];
+}
+
+
+mat2x3 __operator * (const mat2x3 m, const mat2 n)
+{
+   //return mat2x3 (m * n[0], m * n[1]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+}
+
+mat3 __operator * (const mat2x3 m, const mat3x2 n)
+{
+   //return mat3 (m * n[0], m * n[1], m * n[2]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+   __retVal[2] = m * n[2];
+}
+
+mat4x3 __operator * (const mat2x3 m, const mat4x2 n)
+{
+   //return mat4x3 (m * n[0], m * n[1], m * n[2], m * n[3]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+   __retVal[2] = m * n[2];
+   __retVal[3] = m * n[3];
+}
+
+
+mat2x4 __operator * (const mat2x4 m, const mat2 n)
+{
+   //return mat2x4 (m * n[0], m * n[1]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+}
+
+mat3x4 __operator * (const mat2x4 m, const mat3x2 n)
+{
+   //return mat3x4 (m * n[0], m * n[1], m * n[2]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+   __retVal[2] = m * n[2];
+}
+
+mat4 __operator * (const mat2x4 m, const mat4x2 n)
+{
+   //return mat4 (m * n[0], m * n[1], m * n[2], m * n[3]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+   __retVal[2] = m * n[2];
+   __retVal[3] = m * n[3];
+}
+
+
+mat2 __operator * (const mat3x2 m, const mat2x3 n)
+{
+   //return mat2 (m * n[0], m * n[1]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+}
+
+mat3x2 __operator * (const mat3x2 m, const mat3 n)
+{
+   //return mat3x2 (m * n[0], m * n[1], m * n[2]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+   __retVal[2] = m * n[2];
+}
+
+mat4x2 __operator * (const mat3x2 m, const mat4x3 n)
+{
+   //return mat4x2 (m * n[0], m * n[1], m * n[2], m * n[3]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+   __retVal[2] = m * n[2];
+   __retVal[3] = m * n[3];
+}
+
+
+mat2x3 __operator * (const mat3 m, const mat2x3 n)
+{
+   //return mat2x3 (m * n[0], m * n[1]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+}
+
+mat4x3 __operator * (const mat3 m, const mat4x3 n)
+{
+   //return mat4x3 (m * n[0], m * n[1], m * n[2], m * n[3]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+   __retVal[2] = m * n[2];
+   __retVal[3] = m * n[3];
+}
+
+
+mat2x4 __operator * (const mat3x4 m, const mat2x3 n)
+{
+   //return mat2x4 (m * n[0], m * n[1]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+}
+
+mat3x4 __operator * (const mat3x4 m, const mat3 n)
+{
+   //return mat3x4 (m * n[0], m * n[1], m * n[2]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+   __retVal[2] = m * n[2];
+}
+
+mat4 __operator * (const mat3x4 m, const mat4x3 n)
+{
+   //return mat4 (m * n[0], m * n[1], m * n[2], m * n[3]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+   __retVal[2] = m * n[2];
+   __retVal[3] = m * n[3];
+}
+
+
+mat2 __operator * (const mat4x2 m, const mat2x4 n)
+{
+   //return = mat2 (m * n[0], m * n[1]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+}
+
+mat3x2 __operator * (const mat4x2 m, const mat3x4 n)
+{
+   //return mat3x2 (m * n[0], m * n[1], m * n[2]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+   __retVal[2] = m * n[2];
+}
+
+mat4x2 __operator * (const mat4x2 m, const mat4 n)
+{
+   //return mat4x2 (m * n[0], m * n[1], m * n[2], m * n[3]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+   __retVal[2] = m * n[2];
+   __retVal[3] = m * n[3];
+}
+
+
+mat2x3 __operator * (const mat4x3 m, const mat2x4 n)
+{
+   //return mat2x3 (m * n[0], m * n[1]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+}
+
+mat3 __operator * (const mat4x3 m, const mat3x4 n)
+{
+   //return mat3 (m * n[0], m * n[1], m * n[2]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+   __retVal[2] = m * n[2];
+}
+
+mat4x3 __operator * (const mat4x3 m, const mat4 n)
+{
+   //return mat4x3 (m * n[0], m * n[1], m * n[2], m * n[3]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+   __retVal[2] = m * n[2];
+   __retVal[3] = m * n[3];
+}
+
+
+mat2x4 __operator * (const mat4 m, const mat2x4 n)
+{
+   //return mat2x4 (m * n[0], m * n[1]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+}
+
+mat3x4 __operator * (const mat4 m, const mat3x4 n)
+{
+   //return mat3x4 (m * n[0], m * n[1], m * n[2]);
+   __retVal[0] = m * n[0];
+   __retVal[1] = m * n[1];
+   __retVal[2] = m * n[2];
+}
+
+
+void __operator *= (inout mat2x3 m, const mat2 n) {
+    m = m * n;
+}
+
+void __operator *= (inout mat2x4 m, const mat2 n) {
+    m = m * n;
+}
+
+void __operator *= (inout mat3x2 m, const mat3 n) {
+    m = m * n;
+}
+
+void __operator *= (inout mat3x4 m, const mat3 n) {
+    m = m * n;
+}
+
+void __operator *= (inout mat4x2 m, const mat4 n) {
+    m = m * n;
+}
+
+void __operator *= (inout mat4x3 m, const mat4 n) {
+    m = m * n;
+}
+
+
+vec3 __operator * (const vec2 v, const mat3x2 m)
+{
+   __retVal.x = dot(v, m[0]);
+   __retVal.y = dot(v, m[1]);
+   __retVal.z = dot(v, m[2]);
+}
+
+vec4 __operator * (const vec2 v, const mat4x2 m)
+{
+   __retVal.x = dot(v, m[0]);
+   __retVal.y = dot(v, m[1]);
+   __retVal.z = dot(v, m[2]);
+   __retVal.w = dot(v, m[3]);
+}
+
+vec2 __operator * (const vec3 v, const mat2x3 m)
+{
+   __retVal.x = dot(v, m[0]);
+   __retVal.y = dot(v, m[1]);
+}
+
+vec4 __operator * (const vec3 v, const mat4x3 m)
+{
+   __retVal.x = dot(v, m[0]);
+   __retVal.y = dot(v, m[1]);
+   __retVal.z = dot(v, m[2]);
+   __retVal.w = dot(v, m[3]);
+}
+
+vec2 __operator * (const vec4 v, const mat2x4 m)
+{
+   __retVal.x = dot(v, m[0]);
+   __retVal.y = dot(v, m[1]);
+}
+
+vec3 __operator * (const vec4 v, const mat3x4 m)
+{
+   __retVal.x = dot(v, m[0]);
+   __retVal.y = dot(v, m[1]);
+   __retVal.z = dot(v, m[2]);
+}
+
+
+void __operator += (inout mat2x3 m, const float a) {
+    m[0] += a;
+    m[1] += a;
+}
+
+void __operator += (inout mat2x4 m, const float a) {
+    m[0] += a;
+    m[1] += a;
+}
+
+void __operator += (inout mat3x2 m, const float a) {
+    m[0] += a;
+    m[1] += a;
+    m[2] += a;
+}
+
+void __operator += (inout mat3x4 m, const float a) {
+    m[0] += a;
+    m[1] += a;
+    m[2] += a;
+}
+
+void __operator += (inout mat4x2 m, const float a) {
+    m[0] += a;
+    m[1] += a;
+    m[2] += a;
+    m[3] += a;
+}
+
+void __operator += (inout mat4x3 m, const float a) {
+    m[0] += a;
+    m[1] += a;
+    m[2] += a;
+    m[3] += a;
+}
+
+
+void __operator -= (inout mat2x3 m, const float a) {
+    m[0] -= a;
+    m[1] -= a;
+}
+
+void __operator -= (inout mat2x4 m, const float a) {
+    m[0] -= a;
+    m[1] -= a;
+}
+
+void __operator -= (inout mat3x2 m, const float a) {
+    m[0] -= a;
+    m[1] -= a;
+    m[2] -= a;
+}
+
+void __operator -= (inout mat3x4 m, const float a) {
+    m[0] -= a;
+    m[1] -= a;
+    m[2] -= a;
+}
+
+void __operator -= (inout mat4x2 m, const float a) {
+    m[0] -= a;
+    m[1] -= a;
+    m[2] -= a;
+    m[3] -= a;
+}
+
+void __operator -= (inout mat4x3 m, const float a) {
+    m[0] -= a;
+    m[1] -= a;
+    m[2] -= a;
+    m[3] -= a;
+}
+
+
+void __operator *= (inout mat2x3 m, const float a) {
+    m[0] *= a;
+    m[1] *= a;
+}
+
+void __operator *= (inout mat2x4 m, const float a) {
+    m[0] *= a;
+    m[1] *= a;
+}
+
+void __operator *= (inout mat3x2 m, const float a) {
+    m[0] *= a;
+    m[1] *= a;
+    m[2] *= a;
+}
+
+void __operator *= (inout mat3x4 m, const float a) {
+    m[0] *= a;
+    m[1] *= a;
+    m[2] *= a;
+}
+
+void __operator *= (inout mat4x2 m, const float a) {
+    m[0] *= a;
+    m[1] *= a;
+    m[2] *= a;
+    m[3] *= a;
+}
+
+void __operator *= (inout mat4x3 m, const float a) {
+    m[0] *= a;
+    m[1] *= a;
+    m[2] *= a;
+    m[3] *= a;
+}
+
+
+void __operator /= (inout mat2x3 m, const float a) {
+    m[0] /= a;
+    m[1] /= a;
+}
+
+void __operator /= (inout mat2x4 m, const float a) {
+    m[0] /= a;
+    m[1] /= a;
+}
+
+void __operator /= (inout mat3x2 m, const float a) {
+    m[0] /= a;
+    m[1] /= a;
+    m[2] /= a;
+}
+
+void __operator /= (inout mat3x4 m, const float a) {
+    m[0] /= a;
+    m[1] /= a;
+    m[2] /= a;
+}
+
+void __operator /= (inout mat4x2 m, const float a) {
+    m[0] /= a;
+    m[1] /= a;
+    m[2] /= a;
+    m[3] /= a;
+}
+
+void __operator /= (inout mat4x3 m, const float a) {
+    m[0] /= a;
+    m[1] /= a;
+    m[2] /= a;
+    m[3] /= a;
+}
+
+
+mat2x3 __operator + (const mat2x3 m, const mat2x3 n) {
+    return mat2x3 (m[0] + n[0], m[1] + n[1]);
+}
+
+mat2x4 __operator + (const mat2x4 m, const mat2x4 n) {
+    return mat2x4 (m[0] + n[0], m[1] + n[1]);
+}
+
+mat3x2 __operator + (const mat3x2 m, const mat3x2 n) {
+    return mat3x2 (m[0] + n[0], m[1] + n[1], m[2] + n[2]);
+}
+
+mat3x4 __operator + (const mat3x4 m, const mat3x4 n) {
+    return mat3x4 (m[0] + n[0], m[1] + n[1], m[2] + n[2]);
+}
+
+mat4x2 __operator + (const mat4x2 m, const mat4x2 n) {
+    return mat4x2 (m[0] + n[0], m[1] + n[1], m[2] + n[2], m[3] + n[3]);
+}
+
+mat4x3 __operator + (const mat4x3 m, const mat4x3 n) {
+    return mat4x3 (m[0] + n[0], m[1] + n[1], m[2] + n[2], m[3] + n[3]);
+}
+
+
+mat2x3 __operator - (const mat2x3 m, const mat2x3 n) {
+    return mat2x3 (m[0] - n[0], m[1] - n[1]);
+}
+
+mat2x4 __operator - (const mat2x4 m, const mat2x4 n) {
+    return mat2x4 (m[0] - n[0], m[1] - n[1]);
+}
+
+mat3x2 __operator - (const mat3x2 m, const mat3x2 n) {
+    return mat3x2 (m[0] - n[0], m[1] - n[1], m[2] - n[2]);
+}
+
+mat3x4 __operator - (const mat3x4 m, const mat3x4 n) {
+    return mat3x4 (m[0] - n[0], m[1] - n[1], m[2] - n[2]);
+}
+
+mat4x2 __operator - (const mat4x2 m, const mat4x2 n) {
+    return mat4x2 (m[0] - n[0], m[1] - n[1], m[2] - n[2], m[3] - n[3]);
+}
+
+mat4x3 __operator - (const mat4x3 m, const mat4x3 n) {
+    return mat4x3 (m[0] - n[0], m[1] - n[1], m[2] - n[2], m[3] - n[3]);
+}
+
+
+mat2x3 __operator / (const mat2x3 m, const mat2x3 n) {
+    return mat2x3 (m[0] / n[0], m[1] / n[1]);
+}
+
+mat2x4 __operator / (const mat2x4 m, const mat2x4 n) {
+    return mat2x4 (m[0] / n[0], m[1] / n[1]);
+}
+
+mat3x2 __operator / (const mat3x2 m, const mat3x2 n) {
+    return mat3x2 (m[0] / n[0], m[1] / n[1], m[2] / n[2]);
+}
+
+mat3x4 __operator / (const mat3x4 m, const mat3x4 n) {
+    return mat3x4 (m[0] / n[0], m[1] / n[1], m[2] / n[2]);
+}
+
+mat4x2 __operator / (const mat4x2 m, const mat4x2 n) {
+    return mat4x2 (m[0] / n[0], m[1] / n[1], m[2] / n[2], m[3] / n[3]);
+}
+
+mat4x3 __operator / (const mat4x3 m, const mat4x3 n) {
+    return mat4x3 (m[0] / n[0], m[1] / n[1], m[2] / n[2], m[3] / n[3]);
+}
+
+
+mat2x3 __operator + (const float a, const mat2x3 n) {
+    return mat2x3 (a + n[0], a + n[1]);
+}
+
+mat2x3 __operator + (const mat2x3 m, const float b) {
+    return mat2x3 (m[0] + b, m[1] + b);
+}
+
+mat2x4 __operator + (const float a, const mat2x4 n) {
+    return mat2x4 (a + n[0], a + n[1]);
+}
+
+mat2x4 __operator + (const mat2x4 m, const float b) {
+    return mat2x4 (m[0] + b, m[1] + b);
+}
+
+mat3x2 __operator + (const float a, const mat3x2 n) {
+    return mat3x2 (a + n[0], a + n[1], a + n[2]);
+}
+
+mat3x2 __operator + (const mat3x2 m, const float b) {
+    return mat3x2 (m[0] + b, m[1] + b, m[2] + b);
+}
+
+mat3x4 __operator + (const float a, const mat3x4 n) {
+    return mat3x4 (a + n[0], a + n[1], a + n[2]);
+}
+
+mat3x4 __operator + (const mat3x4 m, const float b) {
+    return mat3x4 (m[0] + b, m[1] + b, m[2] + b);
+}
+
+mat4x2 __operator + (const mat4x2 m, const float b) {
+    return mat4x2 (m[0] + b, m[1] + b, m[2] + b, m[3] + b);
+}
+
+mat4x2 __operator + (const float a, const mat4x2 n) {
+    return mat4x2 (a + n[0], a + n[1], a + n[2], a + n[3]);
+}
+
+mat4x3 __operator + (const mat4x3 m, const float b) {
+    return mat4x3 (m[0] + b, m[1] + b, m[2] + b, m[3] + b);
+}
+
+mat4x3 __operator + (const float a, const mat4x3 n) {
+    return mat4x3 (a + n[0], a + n[1], a + n[2], a + n[3]);
+}
+
+
+mat2x3 __operator - (const float a, const mat2x3 n) {
+    return mat2x3 (a - n[0], a - n[1]);
+}
+
+mat2x3 __operator - (const mat2x3 m, const float b) {
+    return mat2x3 (m[0] - b, m[1] - b);
+}
+
+mat2x4 __operator - (const float a, const mat2x4 n) {
+    return mat2x4 (a - n[0], a - n[1]);
+}
+
+mat2x4 __operator - (const mat2x4 m, const float b) {
+    return mat2x4 (m[0] - b, m[1] - b);
+}
+
+mat3x2 __operator - (const float a, const mat3x2 n) {
+    return mat3x2 (a - n[0], a - n[1], a - n[2]);
+}
+
+mat3x2 __operator - (const mat3x2 m, const float b) {
+    return mat3x2 (m[0] - b, m[1] - b, m[2] - b);
+}
+
+mat3x4 __operator - (const float a, const mat3x4 n) {
+    return mat3x4 (a - n[0], a - n[1], a - n[2]);
+}
+
+mat3x4 __operator - (const mat3x4 m, const float b) {
+    return mat3x4 (m[0] - b, m[1] - b, m[2] - b);
+}
+
+mat4x2 __operator - (const mat4x2 m, const float b) {
+    return mat4x2 (m[0] - b, m[1] - b, m[2] - b, m[3] - b);
+}
+
+mat4x2 __operator - (const float a, const mat4x2 n) {
+    return mat4x2 (a - n[0], a - n[1], a - n[2], a - n[3]);
+}
+
+mat4x3 __operator - (const mat4x3 m, const float b) {
+    return mat4x3 (m[0] - b, m[1] - b, m[2] - b, m[3] - b);
+}
+
+mat4x3 __operator - (const float a, const mat4x3 n) {
+    return mat4x3 (a - n[0], a - n[1], a - n[2], a - n[3]);
+}
+
+
+mat2x3 __operator * (const float a, const mat2x3 n)
+{
+   //return mat2x3 (a * n[0], a * n[1]);
+   __retVal[0] = a * n[0];
+   __retVal[1] = a * n[1];
+}
+
+mat2x3 __operator * (const mat2x3 m, const float b)
+{
+   //return mat2x3 (m[0] * b, m[1] * b);
+   __retVal[0] = m[0] * b;
+   __retVal[1] = m[1] * b;
+}
+
+mat2x4 __operator * (const float a, const mat2x4 n)
+{
+   //return mat2x4 (a * n[0], a * n[1]);
+   __retVal[0] = a * n[0];
+   __retVal[1] = a * n[1];
+}
+
+mat2x4 __operator * (const mat2x4 m, const float b)
+{
+   //return mat2x4 (m[0] * b, m[1] * b);
+   __retVal[0] = m[0] * b;
+   __retVal[1] = m[1] * b;
+}
+
+mat3x2 __operator * (const float a, const mat3x2 n)
+{
+   //return mat3x2 (a * n[0], a * n[1], a * n[2]);
+   __retVal[0] = a * n[0];
+   __retVal[1] = a * n[1];
+   __retVal[2] = a * n[2];
+}
+
+mat3x2 __operator * (const mat3x2 m, const float b)
+{
+   //return mat3x2 (m[0] * b, m[1] * b, m[2] * b);
+   __retVal[0] = m[0] * b;
+   __retVal[1] = m[1] * b;
+   __retVal[2] = m[2] * b;
+}
+
+mat3x4 __operator * (const float a, const mat3x4 n)
+{
+   //return mat3x4 (a * n[0], a * n[1], a * n[2]);
+   __retVal[0] = a * n[0];
+   __retVal[1] = a * n[1];
+   __retVal[2] = a * n[2];
+}
+
+mat3x4 __operator * (const mat3x4 m, const float b)
+{
+   //return mat3x4 (m[0] * b, m[1] * b, m[2] * b);
+   __retVal[0] = m[0] * b;
+   __retVal[1] = m[1] * b;
+   __retVal[2] = m[2] * b;
+}
+
+mat4x2 __operator * (const mat4x2 m, const float b)
+{
+   //return mat4x2 (m[0] * b, m[1] * b, m[2] * b, m[3] * b);
+   __retVal[0] = m[0] * b;
+   __retVal[1] = m[1] * b;
+   __retVal[2] = m[2] * b;
+   __retVal[3] = m[3] * b;
+}
+
+mat4x2 __operator * (const float a, const mat4x2 n)
+{
+   //return mat4x2 (a * n[0], a * n[1], a * n[2], a * n[3]);
+   __retVal[0] = a * n[0];
+   __retVal[1] = a * n[1];
+   __retVal[2] = a * n[2];
+   __retVal[3] = a * n[3];
+}
+
+mat4x3 __operator * (const mat4x3 m, const float b)
+{
+   //return mat4x3 (m[0] * b, m[1] * b, m[2] * b, m[3] * b);
+   __retVal[0] = m[0] * b;
+   __retVal[1] = m[1] * b;
+   __retVal[2] = m[2] * b;
+   __retVal[3] = m[3] * b;
+}
+
+mat4x3 __operator * (const float a, const mat4x3 n)
+{
+   //return mat4x3 (a * n[0], a * n[1], a * n[2], a * n[3]);
+   __retVal[0] = a * n[0];
+   __retVal[1] = a * n[1];
+   __retVal[2] = a * n[2];
+   __retVal[3] = a * n[3];
+}
+
+
+mat2x3 __operator / (const float a, const mat2x3 n)
+{
+   //return mat2x3 (a / n[0], a / n[1]);
+   const float inv = 1.0 / a;
+   __retVal[0] = inv * n[0];
+   __retVal[1] = inv * n[1];
+}
+
+mat2x3 __operator / (const mat2x3 m, const float b)
+{
+   //return mat2x3 (m[0] / b, m[1] / b);
+   const float inv = 1.0 / b;
+   __retVal[0] = m[0] * inv;
+   __retVal[1] = m[1] * inv;
+}
+
+mat2x4 __operator / (const float a, const mat2x4 n)
+{
+   //return mat2x4 (a / n[0], a / n[1]);
+   const float inv = 1.0 / a;
+   __retVal[0] = inv * n[0];
+   __retVal[1] = inv * n[1];
+}
+
+mat2x4 __operator / (const mat2x4 m, const float b)
+{
+   //return mat2x4 (m[0] / b, m[1] / b);
+   const float inv = 1.0 / b;
+   __retVal[0] = m[0] * inv;
+   __retVal[1] = m[1] * inv;
+}
+
+mat3x2 __operator / (const float a, const mat3x2 n)
+{
+   //return mat3x2 (a / n[0], a / n[1], a / n[2]);
+   const float inv = 1.0 / a;
+   __retVal[0] = inv * n[0];
+   __retVal[1] = inv * n[1];
+   __retVal[2] = inv * n[2];
+}
+
+mat3x2 __operator / (const mat3x2 m, const float b)
+{
+   //return mat3x2 (m[0] / b, m[1] / b, m[2] / b);
+   const float inv = 1.0 / b;
+   __retVal[0] = m[0] * inv;
+   __retVal[1] = m[1] * inv;
+   __retVal[2] = m[2] * inv;
+}
+
+mat3x4 __operator / (const float a, const mat3x4 n)
+{
+   //return mat3x4 (a / n[0], a / n[1], a / n[2]);
+   const float inv = 1.0 / a;
+   __retVal[0] = inv * n[0];
+   __retVal[1] = inv * n[1];
+   __retVal[2] = inv * n[2];
+}
+
+mat3x4 __operator / (const mat3x4 m, const float b)
+{
+   //return mat3x4 (m[0] / b, m[1] / b, m[2] / b);
+   const float inv = 1.0 / b;
+   __retVal[0] = m[0] * inv;
+   __retVal[1] = m[1] * inv;
+   __retVal[2] = m[2] * inv;
+}
+
+mat4x2 __operator / (const mat4x2 m, const float b)
+{
+   //return mat4x2 (m[0] / b, m[1] / b, m[2] / b, m[3] / b);
+   const float inv = 1.0 / b;
+   __retVal[0] = m[0] * inv;
+   __retVal[1] = m[1] * inv;
+   __retVal[2] = m[2] * inv;
+   __retVal[3] = m[3] * inv;
+}
+
+mat4x2 __operator / (const float a, const mat4x2 n)
+{
+   //return mat4x2 (a / n[0], a / n[1], a / n[2], a / n[3]);
+   const float inv = 1.0 / a;
+   __retVal[0] = inv * n[0];
+   __retVal[1] = inv * n[1];
+   __retVal[2] = inv * n[2];
+   __retVal[3] = inv * n[3];
+}
+
+mat4x3 __operator / (const mat4x3 m, const float b)
+{
+   //return mat4x3 (m[0] / b, m[1] / b, m[2] / b, m[3] / b);
+   const float inv = 1.0 / b;
+   __retVal[0] = m[0] * inv;
+   __retVal[1] = m[1] * inv;
+   __retVal[2] = m[2] * inv;
+   __retVal[3] = m[3] * inv;
+}
+
+mat4x3 __operator / (const float a, const mat4x3 n)
+{
+   //return mat4x3 (a / n[0], a / n[1], a / n[2], a / n[3]);
+   const float inv = 1.0 / a;
+   __retVal[0] = inv * n[0];
+   __retVal[1] = inv * n[1];
+   __retVal[2] = inv * n[2];
+   __retVal[3] = inv * n[3];
+}
+
+
+mat2x3 __operator - (const mat2x3 m) {
+    return mat2x3 (-m[0], -m[1]);
+}
+
+mat2x4 __operator - (const mat2x4 m) {
+    return mat2x4 (-m[0], -m[1]);
+}
+
+mat3x2 __operator - (const mat3x2 m) {
+    return mat3x2 (-m[0], -m[1], -m[2]);
+}
+
+mat3x4 __operator - (const mat3x4 m) {
+    return mat3x4 (-m[0], -m[1], -m[2]);
+}
+
+mat4x2 __operator - (const mat4x2 m) {
+    return mat4x2 (-m[0], -m[1], -m[2], -m[3]);
+}
+
+mat4x3 __operator - (const mat4x3 m) {
+    return mat4x3 (-m[0], -m[1], -m[2], -m[3]);
+}
+
+
+void __operator -- (inout mat2x3 m) {
+    --m[0];
+    --m[1];
+}
+
+void __operator -- (inout mat2x4 m) {
+    --m[0];
+    --m[1];
+}
+
+void __operator -- (inout mat3x2 m) {
+    --m[0];
+    --m[1];
+    --m[2];
+}
+
+void __operator -- (inout mat3x4 m) {
+    --m[0];
+    --m[1];
+    --m[2];
+}
+
+void __operator -- (inout mat4x2 m) {
+    --m[0];
+    --m[1];
+    --m[2];
+    --m[3];
+}
+
+void __operator -- (inout mat4x3 m) {
+    --m[0];
+    --m[1];
+    --m[2];
+    --m[3];
+}
+
+
+void __operator ++ (inout mat2x3 m) {
+    ++m[0];
+    ++m[1];
+}
+
+void __operator ++ (inout mat2x4 m) {
+    ++m[0];
+    ++m[1];
+}
+
+void __operator ++ (inout mat3x2 m) {
+    ++m[0];
+    ++m[1];
+    ++m[2];
+}
+
+void __operator ++ (inout mat3x4 m) {
+    ++m[0];
+    ++m[1];
+    ++m[2];
+}
+
+void __operator ++ (inout mat4x2 m) {
+    ++m[0];
+    ++m[1];
+    ++m[2];
+    ++m[3];
+}
+
+void __operator ++ (inout mat4x3 m) {
+    ++m[0];
+    ++m[1];
+    ++m[2];
+    ++m[3];
+}
+
diff --git a/src/mesa/slang/library/slang_builtin_120_common.gc b/src/mesa/slang/library/slang_builtin_120_common.gc
new file mode 100644 (file)
index 0000000..c6264c3
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.6
+ *
+ * Copyright (C) 2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+//
+// From Shader Spec, ver. 1.20, rev. 6
+//
+
+//
+// 8.5 Matrix Functions
+//
+
+mat2x3 matrixCompMult (mat2x3 m, mat2x3 n) {
+    return mat2x3 (m[0] * n[0], m[1] * n[1]);
+}
+
+mat2x4 matrixCompMult (mat2x4 m, mat2x4 n) {
+    return mat2x4 (m[0] * n[0], m[1] * n[1]);
+}
+
+mat3x2 matrixCompMult (mat3x2 m, mat3x2 n) {
+    return mat3x2 (m[0] * n[0], m[1] * n[1], m[2] * n[2]);
+}
+
+mat3x4 matrixCompMult (mat3x4 m, mat3x4 n) {
+    return mat3x4 (m[0] * n[0], m[1] * n[1], m[2] * n[2]);
+}
+
+mat4x2 matrixCompMult (mat4x2 m, mat4x2 n) {
+    return mat4x2 (m[0] * n[0], m[1] * n[1], m[2] * n[2], m[3] * n[3]);
+}
+
+mat4x3 matrixCompMult (mat4x3 m, mat4x3 n) {
+    return mat4x3 (m[0] * n[0], m[1] * n[1], m[2] * n[2], m[3] * n[3]);
+}
+
+mat2 outerProduct (vec2 c, vec2 r) {
+    return mat2 (
+        c.x * r.x, c.y * r.x,
+        c.x * r.y, c.y * r.y
+    );
+}
+
+mat3 outerProduct (vec3 c, vec3 r) {
+    return mat3 (
+        c.x * r.x, c.y * r.x, c.z * r.x,
+        c.x * r.y, c.y * r.y, c.z * r.y,
+        c.x * r.z, c.y * r.z, c.z * r.z
+    );
+}
+
+mat4 outerProduct (vec4 c, vec4 r) {
+    return mat4 (
+        c.x * r.x, c.y * r.x, c.z * r.x, c.w * r.x,
+        c.x * r.y, c.y * r.y, c.z * r.y, c.w * r.y,
+        c.x * r.z, c.y * r.z, c.z * r.z, c.w * r.z,
+        c.x * r.w, c.y * r.w, c.z * r.w, c.w * r.w
+    );
+}
+
+mat2x3 outerProduct (vec3 c, vec2 r) {
+    return mat2x3 (
+        c.x * r.x, c.y * r.x, c.z * r.x,
+        c.x * r.y, c.y * r.y, c.z * r.y
+    );
+}
+
+mat3x2 outerProduct (vec2 c, vec3 r) {
+    return mat3x2 (
+        c.x * r.x, c.y * r.x,
+        c.x * r.y, c.y * r.y,
+        c.x * r.z, c.y * r.z
+    );
+}
+
+mat2x4 outerProduct (vec4 c, vec2 r) {
+    return mat2x4 (
+        c.x * r.x, c.y * r.x, c.z * r.x, c.w * r.x,
+        c.x * r.y, c.y * r.y, c.z * r.y, c.w * r.y
+    );
+}
+
+mat4x2 outerProduct (vec2 c, vec4 r) {
+    return mat4x2 (
+        c.x * r.x, c.y * r.x,
+        c.x * r.y, c.y * r.y,
+        c.x * r.z, c.y * r.z,
+        c.x * r.w, c.y * r.w
+    );
+}
+
+mat3x4 outerProduct (vec4 c, vec3 r) {
+    return mat3x4 (
+        c.x * r.x, c.y * r.x, c.z * r.x, c.w * r.x,
+        c.x * r.y, c.y * r.y, c.z * r.y, c.w * r.y,
+        c.x * r.z, c.y * r.z, c.z * r.z, c.w * r.z
+    );
+}
+
+mat4x3 outerProduct (vec3 c, vec4 r) {
+    return mat4x3 (
+        c.x * r.x, c.y * r.x, c.z * r.x,
+        c.x * r.y, c.y * r.y, c.z * r.y,
+        c.x * r.z, c.y * r.z, c.z * r.z,
+        c.x * r.w, c.y * r.w, c.z * r.w
+    );
+}
+
+mat2 transpose (mat2 m) {
+    return mat2 (
+        m[0].x, m[1].x,
+        m[0].y, m[1].y
+    );
+}
+
+mat3 transpose (mat3 m) {
+    return mat3 (
+        m[0].x, m[1].x, m[2].x,
+        m[0].y, m[1].y, m[2].y,
+        m[0].z, m[1].z, m[2].z
+    );
+}
+
+mat4 transpose (mat4 m) {
+    return mat4 (
+        m[0].x, m[1].x, m[2].x, m[3].x,
+        m[0].y, m[1].y, m[2].y, m[3].y,
+        m[0].z, m[1].z, m[2].z, m[3].z,
+        m[0].w, m[1].w, m[2].w, m[3].w
+    );
+}
+
+mat2x3 transpose (mat3x2 m) {
+    return mat2x3 (
+        m[0].x, m[1].x, m[2].x,
+        m[0].y, m[1].y, m[2].y
+    );
+}
+
+mat3x2 transpose (mat2x3 m) {
+    return mat3x2 (
+        m[0].x, m[1].x,
+        m[0].y, m[1].y,
+        m[0].z, m[1].z
+    );
+}
+
+mat2x4 transpose (mat4x2 m) {
+    return mat2x4 (
+        m[0].x, m[1].x, m[2].x, m[3].x,
+        m[0].y, m[1].y, m[2].y, m[3].y
+    );
+}
+
+mat4x2 transpose (mat2x4 m) {
+    return mat4x2 (
+        m[0].x, m[1].x,
+        m[0].y, m[1].y,
+        m[0].z, m[1].z,
+        m[0].w, m[1].w
+    );
+}
+
+mat3x4 transpose (mat4x3 m) {
+    return mat3x4 (
+        m[0].x, m[1].x, m[2].x, m[3].x,
+        m[0].y, m[1].y, m[2].y, m[3].y,
+        m[0].z, m[1].z, m[2].z, m[3].z
+    );
+}
+
+mat4x3 transpose (mat3x4 m) {
+    return mat4x3 (
+        m[0].x, m[1].x, m[2].x,
+        m[0].y, m[1].y, m[2].y,
+        m[0].z, m[1].z, m[2].z,
+        m[0].w, m[1].w, m[2].w
+    );
+}
+
diff --git a/src/mesa/slang/library/slang_builtin_120_fragment.gc b/src/mesa/slang/library/slang_builtin_120_fragment.gc
new file mode 100644 (file)
index 0000000..7d51604
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+//
+// From Shader Spec, ver. 1.20, rev. 6
+//
+
+varying vec2 gl_PointCoord;
+
diff --git a/src/mesa/slang/library/slang_common_builtin.gc b/src/mesa/slang/library/slang_common_builtin.gc
new file mode 100644 (file)
index 0000000..d75354d
--- /dev/null
@@ -0,0 +1,1887 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.3
+ *
+ * Copyright (C) 2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2008  VMware, 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
+ * 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.
+ */
+
+//
+// From Shader Spec, ver. 1.10, rev. 59
+//
+
+// Note: the values assigned to these constants here aren't actually used.
+// They're set by the compiler according to the GL context limits.
+// See slang_simplify.c
+const int gl_MaxLights = 8;
+const int gl_MaxClipPlanes = 6;
+const int gl_MaxTextureUnits = 8;
+const int gl_MaxTextureCoords = 8;
+const int gl_MaxVertexAttribs = 16;
+const int gl_MaxVertexUniformComponents = 512;
+const int gl_MaxVaryingFloats = 32;
+const int gl_MaxVertexTextureImageUnits = 0;
+const int gl_MaxCombinedTextureImageUnits = 2;
+const int gl_MaxTextureImageUnits = 2;
+const int gl_MaxFragmentUniformComponents = 64;
+const int gl_MaxDrawBuffers = 1;
+
+uniform mat4 gl_ModelViewMatrix;
+uniform mat4 gl_ProjectionMatrix;
+uniform mat4 gl_ModelViewProjectionMatrix;
+uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords];
+
+uniform mat3 gl_NormalMatrix;
+
+uniform mat4 gl_ModelViewMatrixInverse;
+uniform mat4 gl_ProjectionMatrixInverse;
+uniform mat4 gl_ModelViewProjectionMatrixInverse;
+uniform mat4 gl_TextureMatrixInverse[gl_MaxTextureCoords];
+
+uniform mat4 gl_ModelViewMatrixTranspose;
+uniform mat4 gl_ProjectionMatrixTranspose;
+uniform mat4 gl_ModelViewProjectionMatrixTranspose;
+uniform mat4 gl_TextureMatrixTranspose[gl_MaxTextureCoords];
+
+uniform mat4 gl_ModelViewMatrixInverseTranspose;
+uniform mat4 gl_ProjectionMatrixInverseTranspose;
+uniform mat4 gl_ModelViewProjectionMatrixInverseTranspose;
+uniform mat4 gl_TextureMatrixInverseTranspose[gl_MaxTextureCoords];
+
+uniform float gl_NormalScale;
+
+struct gl_DepthRangeParameters {
+    float near;
+    float far;
+    float diff;
+};
+
+uniform gl_DepthRangeParameters gl_DepthRange;
+
+uniform vec4 gl_ClipPlane[gl_MaxClipPlanes];
+
+struct gl_PointParameters {
+    float size;
+    float sizeMin;
+    float sizeMax;
+    float fadeThresholdSize;
+    float distanceConstantAttenuation;
+    float distanceLinearAttenuation;
+    float distanceQuadraticAttenuation;
+};
+
+uniform gl_PointParameters gl_Point;
+
+struct gl_MaterialParameters {
+    vec4 emission;
+    vec4 ambient;
+    vec4 diffuse;
+    vec4 specular;
+    float shininess;
+};
+
+uniform gl_MaterialParameters gl_FrontMaterial;
+uniform gl_MaterialParameters gl_BackMaterial;
+
+/* NOTE: the order of these fields is significant!
+ * See the definition of the lighting state vars such as STATE_SPOT_DIRECTION.
+ */
+struct gl_LightSourceParameters {
+    vec4 ambient;
+    vec4 diffuse;
+    vec4 specular;
+    vec4 position;
+    vec4 halfVector;
+    vec3 spotDirection;
+    float spotCosCutoff;
+
+    float constantAttenuation;
+    float linearAttenuation;
+    float quadraticAttenuation;
+    float spotExponent;
+
+    float spotCutoff;
+};
+
+uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights];
+
+struct gl_LightModelParameters {
+    vec4 ambient;
+};
+
+uniform gl_LightModelParameters gl_LightModel;
+
+struct gl_LightModelProducts {
+    vec4 sceneColor;
+};
+
+uniform gl_LightModelProducts gl_FrontLightModelProduct;
+uniform gl_LightModelProducts gl_BackLightModelProduct;
+
+struct gl_LightProducts {
+    vec4 ambient;
+    vec4 diffuse;
+    vec4 specular;
+};
+
+uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights];
+uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights];
+
+uniform vec4 gl_TextureEnvColor[gl_MaxTextureImageUnits];
+uniform vec4 gl_EyePlaneS[gl_MaxTextureCoords];
+uniform vec4 gl_EyePlaneT[gl_MaxTextureCoords];
+uniform vec4 gl_EyePlaneR[gl_MaxTextureCoords];
+uniform vec4 gl_EyePlaneQ[gl_MaxTextureCoords];
+uniform vec4 gl_ObjectPlaneS[gl_MaxTextureCoords];
+uniform vec4 gl_ObjectPlaneT[gl_MaxTextureCoords];
+uniform vec4 gl_ObjectPlaneR[gl_MaxTextureCoords];
+uniform vec4 gl_ObjectPlaneQ[gl_MaxTextureCoords];
+
+struct gl_FogParameters {
+    vec4 color;
+    float density;
+    float start;
+    float end;
+    float scale;
+};
+
+uniform gl_FogParameters gl_Fog;
+
+
+
+
+
+//
+// 8.1 Angle and Trigonometry Functions
+//
+
+//// radians
+
+float radians(const float deg)
+{
+   const float c = 3.1415926 / 180.0;
+   __asm vec4_multiply __retVal, deg, c;
+}
+
+vec2 radians(const vec2 deg)
+{
+   const float c = 3.1415926 / 180.0;
+   __asm vec4_multiply __retVal.xy, deg.xy, c.xx;
+}
+
+vec3 radians(const vec3 deg)
+{
+   const float c = 3.1415926 / 180.0;
+   __asm vec4_multiply __retVal.xyz, deg.xyz, c.xxx;
+}
+
+vec4 radians(const vec4 deg)
+{
+   const float c = 3.1415926 / 180.0;
+   __asm vec4_multiply __retVal, deg, c.xxxx;
+}
+
+
+//// degrees
+
+float degrees(const float rad)
+{
+   const float c = 180.0 / 3.1415926;
+   __asm vec4_multiply __retVal, rad, c;
+}
+
+vec2 degrees(const vec2 rad)
+{
+   const float c = 180.0 / 3.1415926;
+   __asm vec4_multiply __retVal.xy, rad.xy, c.xx;
+}
+
+vec3 degrees(const vec3 rad)
+{
+   const float c = 180.0 / 3.1415926;
+   __asm vec4_multiply __retVal.xyz, rad.xyz, c.xxx;
+}
+
+vec4 degrees(const vec4 rad)
+{
+   const float c = 180.0 / 3.1415926;
+   __asm vec4_multiply __retVal, rad, c.xxxx;
+}
+
+
+//// sin
+
+float sin(const float radians)
+{
+   __asm float_sine __retVal, radians;
+}
+
+vec2 sin(const vec2 radians)
+{
+   __asm float_sine __retVal.x, radians.x;
+   __asm float_sine __retVal.y, radians.y;
+}
+
+vec3 sin(const vec3 radians)
+{
+   __asm float_sine __retVal.x, radians.x;
+   __asm float_sine __retVal.y, radians.y;
+   __asm float_sine __retVal.z, radians.z;
+}
+
+vec4 sin(const vec4 radians)
+{
+   __asm float_sine __retVal.x, radians.x;
+   __asm float_sine __retVal.y, radians.y;
+   __asm float_sine __retVal.z, radians.z;
+   __asm float_sine __retVal.w, radians.w;
+}
+
+
+//// cos
+
+float cos(const float radians)
+{
+   __asm float_cosine __retVal, radians;
+}
+
+vec2 cos(const vec2 radians)
+{
+   __asm float_cosine __retVal.x, radians.x;
+   __asm float_cosine __retVal.y, radians.y;
+}
+
+vec3 cos(const vec3 radians)
+{
+   __asm float_cosine __retVal.x, radians.x;
+   __asm float_cosine __retVal.y, radians.y;
+   __asm float_cosine __retVal.z, radians.z;
+}
+
+vec4 cos(const vec4 radians)
+{
+   __asm float_cosine __retVal.x, radians.x;
+   __asm float_cosine __retVal.y, radians.y;
+   __asm float_cosine __retVal.z, radians.z;
+   __asm float_cosine __retVal.w, radians.w;
+}
+
+
+
+//// tan
+
+float tan(const float angle)
+{
+   const float s = sin(angle);
+   const float c = cos(angle);
+   return s / c;
+}
+
+vec2 tan(const vec2 angle)
+{
+   const vec2 s = sin(angle);
+   const vec2 c = cos(angle);
+   return s / c;
+}
+
+vec3 tan(const vec3 angle)
+{
+   const vec3 s = sin(angle);
+   const vec3 c = cos(angle);
+   return s / c;
+}
+
+vec4 tan(const vec4 angle)
+{
+   const vec4 s = sin(angle);
+   const vec4 c = cos(angle);
+   return s / c;
+}
+
+
+
+float asin(const float x)
+{
+   const float a0 = 1.5707288;  // PI/2?
+   const float a1 = -0.2121144;
+   const float a2 = 0.0742610;
+   //const float a3 = -0.0187293;
+   const float halfPi = 3.1415926 * 0.5;
+   const float y = abs(x);
+   // three terms seem to be enough:
+   __retVal = (halfPi - sqrt(1.0 - y) * (a0 + y * (a1 + a2 * y))) * sign(x);
+   // otherwise, try four:
+   //__retVal = (halfPi - sqrt(1.0 - y) * (a0 + y * (a1 + y * (a2 + y * a3)))) * sign(x);
+}
+
+vec2 asin(const vec2 v)
+{
+   __retVal.x = asin(v.x);
+   __retVal.y = asin(v.y);
+}
+
+vec3 asin(const vec3 v)
+{
+   __retVal.x = asin(v.x);
+   __retVal.y = asin(v.y);
+   __retVal.z = asin(v.z);
+}
+
+vec4 asin(const vec4 v)
+{
+   __retVal.x = asin(v.x);
+   __retVal.y = asin(v.y);
+   __retVal.z = asin(v.z);
+   __retVal.w = asin(v.w);
+}
+
+float acos(const float x)
+{
+   const float halfPi = 3.1415926 * 0.5;
+   __retVal = halfPi - asin(x);
+}
+
+vec2 acos(const vec2 v)
+{
+   __retVal.x = acos(v.x);
+   __retVal.y = acos(v.y);
+}
+
+vec3 acos(const vec3 v)
+{
+   __retVal.x = acos(v.x);
+   __retVal.y = acos(v.y);
+   __retVal.z = acos(v.z);
+}
+
+vec4 acos(const vec4 v)
+{
+   __retVal.x = acos(v.x);
+   __retVal.y = acos(v.y);
+   __retVal.z = acos(v.z);
+   __retVal.w = acos(v.w);
+}
+
+float atan(const float x)
+{
+   __retVal = asin(x * inversesqrt(x * x + 1.0));
+}
+
+vec2 atan(const vec2 y_over_x)
+{
+   __retVal.x = atan(y_over_x.x);
+   __retVal.y = atan(y_over_x.y);
+}
+
+vec3 atan(const vec3 y_over_x)
+{
+   __retVal.x = atan(y_over_x.x);
+   __retVal.y = atan(y_over_x.y);
+   __retVal.z = atan(y_over_x.z);
+}
+
+vec4 atan(const vec4 y_over_x)
+{
+   __retVal.x = atan(y_over_x.x);
+   __retVal.y = atan(y_over_x.y);
+   __retVal.z = atan(y_over_x.z);
+   __retVal.w = atan(y_over_x.w);
+}
+
+float atan(const float y, const float x)
+{
+   float r;
+   if (abs(x) > 1.0e-4) {
+      r = atan(y / x);
+      if (x < 0.0) {
+         r = r + sign(y) * 3.141593;
+      }
+   }
+   else {
+      r = sign(y) * 1.5707965;  // pi/2
+   }
+   return r;
+}
+
+vec2 atan(const vec2 u, const vec2 v)
+{
+   __retVal.x = atan(u.x, v.x);
+   __retVal.y = atan(u.y, v.y);
+}
+
+vec3 atan(const vec3 u, const vec3 v)
+{
+   __retVal.x = atan(u.x, v.x);
+   __retVal.y = atan(u.y, v.y);
+   __retVal.z = atan(u.z, v.z);
+}
+
+vec4 atan(const vec4 u, const vec4 v)
+{
+   __retVal.x = atan(u.x, v.x);
+   __retVal.y = atan(u.y, v.y);
+   __retVal.z = atan(u.z, v.z);
+   __retVal.w = atan(u.w, v.w);
+}
+
+
+//
+// 8.2 Exponential Functions
+//
+
+//// pow
+
+float pow(const float a, const float b)
+{
+   __asm float_power __retVal, a, b;
+}
+
+vec2 pow(const vec2 a, const vec2 b)
+{
+   __asm float_power __retVal.x, a.x, b.x;
+   __asm float_power __retVal.y, a.y, b.y;
+}
+
+vec3 pow(const vec3 a, const vec3 b)
+{
+   __asm float_power __retVal.x, a.x, b.x;
+   __asm float_power __retVal.y, a.y, b.y;
+   __asm float_power __retVal.z, a.z, b.z;
+}
+
+vec4 pow(const vec4 a, const vec4 b)
+{
+   __asm float_power __retVal.x, a.x, b.x;
+   __asm float_power __retVal.y, a.y, b.y;
+   __asm float_power __retVal.z, a.z, b.z;
+   __asm float_power __retVal.w, a.w, b.w;
+}
+
+
+//// exp
+
+float exp(const float a)
+{
+   // NOTE: log2(e) = 1.44269502
+   float t = a * 1.44269502;
+   __asm float_exp2 __retVal, t;
+}
+
+vec2 exp(const vec2 a)
+{
+   vec2 t = a * 1.44269502;
+   __asm float_exp2 __retVal.x, t.x;
+   __asm float_exp2 __retVal.y, t.y;
+}
+
+vec3 exp(const vec3 a)
+{
+   vec3 t = a * 1.44269502;
+   __asm float_exp2 __retVal.x, t.x;
+   __asm float_exp2 __retVal.y, t.y;
+   __asm float_exp2 __retVal.z, t.z;
+}
+
+vec4 exp(const vec4 a)
+{
+   vec4 t = a * 1.44269502;
+   __asm float_exp2 __retVal.x, t.x;
+   __asm float_exp2 __retVal.y, t.y;
+   __asm float_exp2 __retVal.z, t.z;
+   __asm float_exp2 __retVal.w, t.w;
+}
+
+
+
+//// log2
+
+float log2(const float x)
+{
+   __asm float_log2 __retVal, x;
+}
+
+vec2 log2(const vec2 v)
+{
+   __asm float_log2 __retVal.x, v.x;
+   __asm float_log2 __retVal.y, v.y;
+}
+
+vec3 log2(const vec3 v)
+{
+   __asm float_log2 __retVal.x, v.x;
+   __asm float_log2 __retVal.y, v.y;
+   __asm float_log2 __retVal.z, v.z;
+}
+
+vec4 log2(const vec4 v)
+{
+   __asm float_log2 __retVal.x, v.x;
+   __asm float_log2 __retVal.y, v.y;
+   __asm float_log2 __retVal.z, v.z;
+   __asm float_log2 __retVal.w, v.w;
+}
+
+
+//// log  (natural log)
+
+float log(const float x)
+{
+   // note:  logBaseB(x) = logBaseN(x) / logBaseN(B)
+   // compute log(x) = log2(x) / log2(e)
+   // c = 1.0 / log2(e) = 0.693147181
+   const float c = 0.693147181;
+   return log2(x) * c;
+}
+
+vec2 log(const vec2 v)
+{
+   const float c = 0.693147181;
+   return log2(v) * c;
+}
+
+vec3 log(const vec3 v)
+{
+   const float c = 0.693147181;
+   return log2(v) * c;
+}
+
+vec4 log(const vec4 v)
+{
+   const float c = 0.693147181;
+   return log2(v) * c;
+}
+
+
+//// exp2
+
+float exp2(const float a)
+{
+   __asm float_exp2 __retVal, a;
+}
+
+vec2 exp2(const vec2 a)
+{
+   __asm float_exp2 __retVal.x, a.x;
+   __asm float_exp2 __retVal.y, a.y;
+}
+
+vec3 exp2(const vec3 a)
+{
+   __asm float_exp2 __retVal.x, a.x;
+   __asm float_exp2 __retVal.y, a.y;
+   __asm float_exp2 __retVal.z, a.z;
+}
+
+vec4 exp2(const vec4 a)
+{
+   __asm float_exp2 __retVal.x, a.x;
+   __asm float_exp2 __retVal.y, a.y;
+   __asm float_exp2 __retVal.z, a.z;
+   __asm float_exp2 __retVal.w, a.w;
+}
+
+
+//// sqrt
+
+float sqrt(const float x)
+{
+   const float nx = -x;
+   float r;
+   __asm float_rsq r, x;
+   r = r * x;
+   __asm vec4_cmp __retVal, nx, r, 0.0;
+}
+
+vec2 sqrt(const vec2 x)
+{
+   const vec2 nx = -x, zero = vec2(0.0);
+   vec2 r;
+   __asm float_rsq r.x, x.x;
+   __asm float_rsq r.y, x.y;
+   r = r * x;
+   __asm vec4_cmp __retVal, nx, r, zero;
+}
+
+vec3 sqrt(const vec3 x)
+{
+   const vec3 nx = -x, zero = vec3(0.0);
+   vec3 r;
+   __asm float_rsq r.x, x.x;
+   __asm float_rsq r.y, x.y;
+   __asm float_rsq r.z, x.z;
+   r = r * x;
+   __asm vec4_cmp __retVal, nx, r, zero;
+}
+
+vec4 sqrt(const vec4 x)
+{
+   const vec4 nx = -x, zero = vec4(0.0);
+   vec4 r;
+   __asm float_rsq r.x, x.x;
+   __asm float_rsq r.y, x.y;
+   __asm float_rsq r.z, x.z;
+   __asm float_rsq r.w, x.w;
+   r = r * x;
+   __asm vec4_cmp __retVal, nx, r, zero;
+}
+
+
+//// inversesqrt
+
+float inversesqrt(const float x)
+{
+   __asm float_rsq __retVal.x, x;
+}
+
+vec2 inversesqrt(const vec2 v)
+{
+   __asm float_rsq __retVal.x, v.x;
+   __asm float_rsq __retVal.y, v.y;
+}
+
+vec3 inversesqrt(const vec3 v)
+{
+   __asm float_rsq __retVal.x, v.x;
+   __asm float_rsq __retVal.y, v.y;
+   __asm float_rsq __retVal.z, v.z;
+}
+
+vec4 inversesqrt(const vec4 v)
+{
+   __asm float_rsq __retVal.x, v.x;
+   __asm float_rsq __retVal.y, v.y;
+   __asm float_rsq __retVal.z, v.z;
+   __asm float_rsq __retVal.w, v.w;
+}
+
+
+//// normalize
+
+float normalize(const float x)
+{
+   __retVal = 1.0;
+}
+
+vec2 normalize(const vec2 v)
+{
+   const float s = inversesqrt(dot(v, v));
+   __asm vec4_multiply __retVal.xy, v, s;
+}
+
+vec3 normalize(const vec3 v)
+{
+//   const float s = inversesqrt(dot(v, v));
+//   __retVal = v * s;
+// XXX note, we _could_ use __retVal.w instead of tmp and save a
+// register, but that's actually a compilation error because v is a vec3
+// and the .w suffix is illegal.  Oh well.
+   float tmp;
+   __asm vec3_dot tmp, v, v;
+   __asm float_rsq tmp, tmp;
+   __asm vec4_multiply __retVal.xyz, v, tmp;
+}
+
+vec4 normalize(const vec4 v)
+{
+   float tmp;
+   __asm vec4_dot tmp, v, v;
+   __asm float_rsq tmp, tmp;
+   __asm vec4_multiply __retVal.xyz, v, tmp;
+}
+
+
+
+//
+// 8.3 Common Functions
+//
+
+
+//// abs
+
+float abs(const float a)
+{
+   __asm vec4_abs __retVal, a;
+}
+
+vec2 abs(const vec2 a)
+{
+   __asm vec4_abs __retVal.xy, a;
+}
+
+vec3 abs(const vec3 a)
+{
+   __asm vec4_abs __retVal.xyz, a;
+}
+
+vec4 abs(const vec4 a)
+{
+   __asm vec4_abs __retVal, a;
+}
+
+
+//// sign
+
+float sign(const float x)
+{
+   float p, n;
+   __asm vec4_sgt p, x, 0.0;            // p = (x > 0)
+   __asm vec4_sgt n, 0.0, x;            // n = (x < 0)
+   __asm vec4_subtract __retVal, p, n;  // sign = p - n
+}
+
+vec2 sign(const vec2 v)
+{
+   vec2 p, n;
+   __asm vec4_sgt p.xy, v, 0.0;
+   __asm vec4_sgt n.xy, 0.0, v;
+   __asm vec4_subtract __retVal.xy, p, n;
+}
+
+vec3 sign(const vec3 v)
+{
+   vec3 p, n;
+   __asm vec4_sgt p.xyz, v, 0.0;
+   __asm vec4_sgt n.xyz, 0.0, v;
+   __asm vec4_subtract __retVal.xyz, p, n;
+}
+
+vec4 sign(const vec4 v)
+{
+   vec4 p, n;
+   __asm vec4_sgt p, v, 0.0;
+   __asm vec4_sgt n, 0.0, v;
+   __asm vec4_subtract __retVal, p, n;
+}
+
+
+//// floor
+
+float floor(const float a)
+{
+   __asm vec4_floor __retVal, a;
+}
+
+vec2 floor(const vec2 a)
+{
+   __asm vec4_floor __retVal.xy, a;
+}
+
+vec3 floor(const vec3 a)
+{
+   __asm vec4_floor __retVal.xyz, a;
+}
+
+vec4 floor(const vec4 a)
+{
+   __asm vec4_floor __retVal, a;
+}
+
+
+//// ceil
+
+float ceil(const float a)
+{
+   // XXX this could be improved
+   float b = -a;
+   __asm vec4_floor b, b;
+   __retVal = -b;
+}
+
+vec2 ceil(const vec2 a)
+{
+   vec2 b = -a;
+   __asm vec4_floor b, b;
+   __retVal.xy = -b;
+}
+
+vec3 ceil(const vec3 a)
+{
+   vec3 b = -a;
+   __asm vec4_floor b, b;
+   __retVal.xyz = -b;
+}
+
+vec4 ceil(const vec4 a)
+{
+   vec4 b = -a;
+   __asm vec4_floor b, b;
+   __retVal = -b;
+}
+
+
+//// fract
+
+float fract(const float a)
+{
+   __asm vec4_frac __retVal, a;
+}
+
+vec2 fract(const vec2 a)
+{
+   __asm vec4_frac __retVal.xy, a;
+}
+
+vec3 fract(const vec3 a)
+{
+   __asm vec4_frac __retVal.xyz, a;
+}
+
+vec4 fract(const vec4 a)
+{
+   __asm vec4_frac __retVal, a;
+}
+
+
+//// mod  (very untested!)
+
+float mod(const float a, const float b)
+{
+    float oneOverB;
+    __asm float_rcp oneOverB, b;
+    __retVal = a - b * floor(a * oneOverB);
+}
+
+vec2 mod(const vec2 a, const float b)
+{
+    float oneOverB;
+    __asm float_rcp oneOverB, b;
+    __retVal.xy = a - b * floor(a * oneOverB);
+}
+
+vec3 mod(const vec3 a, const float b)
+{
+    float oneOverB;
+    __asm float_rcp oneOverB, b;
+    __retVal.xyz = a - b * floor(a * oneOverB);
+}
+
+vec4 mod(const vec4 a, const float b)
+{
+    float oneOverB;
+    __asm float_rcp oneOverB, b;
+    __retVal = a - b * floor(a * oneOverB);
+}
+
+vec2 mod(const vec2 a, const vec2 b)
+{
+    vec2 oneOverB;
+    __asm float_rcp oneOverB.x, b.x;
+    __asm float_rcp oneOverB.y, b.y;
+    __retVal = a - b * floor(a * oneOverB);
+}
+
+vec3 mod(const vec3 a, const vec3 b)
+{
+    vec3 oneOverB;
+    __asm float_rcp oneOverB.x, b.x;
+    __asm float_rcp oneOverB.y, b.y;
+    __asm float_rcp oneOverB.z, b.z;
+    __retVal = a - b * floor(a * oneOverB);
+}
+
+vec4 mod(const vec4 a, const vec4 b)
+{
+    vec4 oneOverB;
+    __asm float_rcp oneOverB.x, b.x;
+    __asm float_rcp oneOverB.y, b.y;
+    __asm float_rcp oneOverB.z, b.z;
+    __asm float_rcp oneOverB.w, b.w;
+    __retVal = a - b * floor(a * oneOverB);
+}
+
+
+//// min
+
+float min(const float a, const float b)
+{
+   __asm vec4_min __retVal, a, b;
+}
+
+vec2 min(const vec2 a, const vec2 b)
+{
+   __asm vec4_min __retVal.xy, a.xy, b.xy;
+}
+
+vec3 min(const vec3 a, const vec3 b)
+{
+   __asm vec4_min __retVal.xyz, a.xyz, b.xyz;
+}
+
+vec4 min(const vec4 a, const vec4 b)
+{
+   __asm vec4_min __retVal, a, b;
+}
+
+vec2 min(const vec2 a, const float b)
+{
+   __asm vec4_min __retVal, a.xy, b;
+}
+
+vec3 min(const vec3 a, const float b)
+{
+   __asm vec4_min __retVal, a.xyz, b;
+}
+
+vec4 min(const vec4 a, const float b)
+{
+   __asm vec4_min __retVal, a, b;
+}
+
+
+//// max
+
+float max(const float a, const float b)
+{
+   __asm vec4_max __retVal, a, b;
+}
+
+vec2 max(const vec2 a, const vec2 b)
+{
+   __asm vec4_max __retVal.xy, a.xy, b.xy;
+}
+
+vec3 max(const vec3 a, const vec3 b)
+{
+   __asm vec4_max __retVal.xyz, a.xyz, b.xyz;
+}
+
+vec4 max(const vec4 a, const vec4 b)
+{
+   __asm vec4_max __retVal, a, b;
+}
+
+vec2 max(const vec2 a, const float b)
+{
+   __asm vec4_max __retVal, a.xy, b;
+}
+
+vec3 max(const vec3 a, const float b)
+{
+   __asm vec4_max __retVal, a.xyz, b;
+}
+
+vec4 max(const vec4 a, const float b)
+{
+   __asm vec4_max __retVal, a, b;
+}
+
+
+//// clamp
+
+float clamp(const float val, const float minVal, const float maxVal)
+{
+   __asm vec4_clamp __retVal, val, minVal, maxVal;
+}
+
+vec2 clamp(const vec2 val, const float minVal, const float maxVal)
+{
+   __asm vec4_clamp __retVal, val, minVal, maxVal;
+}
+
+vec3 clamp(const vec3 val, const float minVal, const float maxVal)
+{
+   __asm vec4_clamp __retVal, val, minVal, maxVal;
+}
+
+vec4 clamp(const vec4 val, const float minVal, const float maxVal)
+{
+   __asm vec4_clamp __retVal, val, minVal, maxVal;
+}
+
+vec2 clamp(const vec2 val, const vec2 minVal, const vec2 maxVal)
+{
+   __asm vec4_clamp __retVal, val, minVal, maxVal;
+}
+
+vec3 clamp(const vec3 val, const vec3 minVal, const vec3 maxVal)
+{
+   __asm vec4_clamp __retVal, val, minVal, maxVal;
+}
+
+vec4 clamp(const vec4 val, const vec4 minVal, const vec4 maxVal)
+{
+   __asm vec4_clamp __retVal, val, minVal, maxVal;
+}
+
+
+//// mix
+
+float mix(const float x, const float y, const float a)
+{
+   __asm vec4_lrp __retVal, a, y, x;
+}
+
+vec2 mix(const vec2 x, const vec2 y, const float a)
+{
+   __asm vec4_lrp __retVal, a, y, x;
+}
+
+vec3 mix(const vec3 x, const vec3 y, const float a)
+{
+   __asm vec4_lrp __retVal, a, y, x;
+}
+
+vec4 mix(const vec4 x, const vec4 y, const float a)
+{
+   __asm vec4_lrp __retVal, a, y, x;
+}
+
+vec2 mix(const vec2 x, const vec2 y, const vec2 a)
+{
+   __asm vec4_lrp __retVal, a, y, x;
+}
+
+vec3 mix(const vec3 x, const vec3 y, const vec3 a)
+{
+   __asm vec4_lrp __retVal, a, y, x;
+}
+
+vec4 mix(const vec4 x, const vec4 y, const vec4 a)
+{
+   __asm vec4_lrp __retVal, a, y, x;
+}
+
+
+//// step
+
+float step(const float edge, const float x)
+{
+   __asm vec4_sge __retVal, x, edge;
+}
+
+vec2 step(const vec2 edge, const vec2 x)
+{
+   __asm vec4_sge __retVal.xy, x, edge;
+}
+
+vec3 step(const vec3 edge, const vec3 x)
+{
+   __asm vec4_sge __retVal.xyz, x, edge;
+}
+
+vec4 step(const vec4 edge, const vec4 x)
+{
+   __asm vec4_sge __retVal, x, edge;
+}
+
+vec2 step(const float edge, const vec2 v)
+{
+   __asm vec4_sge __retVal.xy, v, edge;
+}
+
+vec3 step(const float edge, const vec3 v)
+{
+   __asm vec4_sge __retVal.xyz, v, edge;
+}
+
+vec4 step(const float edge, const vec4 v)
+{
+   __asm vec4_sge __retVal, v, edge;
+}
+
+
+//// smoothstep
+
+float smoothstep(const float edge0, const float edge1, const float x)
+{
+    float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
+    return t * t * (3.0 - 2.0 * t);
+}
+
+vec2 smoothstep(const vec2 edge0, const vec2 edge1, const vec2 v)
+{
+   vec2 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0);
+   return t * t * (3.0 - 2.0 * t);
+}
+
+vec3 smoothstep(const vec3 edge0, const vec3 edge1, const vec3 v)
+{
+   vec3 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0);
+   return t * t * (3.0 - 2.0 * t);
+}
+
+vec4 smoothstep(const vec4 edge0, const vec4 edge1, const vec4 v)
+{
+   vec4 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0);
+   return t * t * (3.0 - 2.0 * t);
+}
+
+vec2 smoothstep(const float edge0, const float edge1, const vec2 v)
+{
+   vec2 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0);
+   return t * t * (3.0 - 2.0 * t);
+}
+
+vec3 smoothstep(const float edge0, const float edge1, const vec3 v)
+{
+   vec3 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0);
+   return t * t * (3.0 - 2.0 * t);
+}
+
+vec4 smoothstep(const float edge0, const float edge1, const vec4 v)
+{
+   vec4 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0);
+   return t * t * (3.0 - 2.0 * t);
+}
+
+
+
+//
+// 8.4 Geometric Functions
+//
+
+
+//// length
+
+float length(const float x)
+{
+   return abs(x);
+}
+
+float length(const vec2 v)
+{
+   float r;
+   const float p = dot(v, v);      // p = v.x * v.x + v.y * v.y
+   __asm float_rsq r, p;           // r = 1 / sqrt(p)
+   __retVal = p * r;               // p * r = sqrt(p);
+}
+
+float length(const vec3 v)
+{
+   float r;
+   const float p = dot(v, v);      // p = v.x * v.x + v.y * v.y + v.z * v.z
+   __asm float_rsq r, p;           // r = 1 / sqrt(p)
+   __retVal = p * r;               // p * r = sqrt(p);
+}
+
+float length(const vec4 v)
+{
+   float r;
+   const float p = dot(v, v);      // p = v.x * v.x + v.y * v.y + ...
+   __asm float_rsq r, p;           // r = 1 / sqrt(p)
+   __retVal = p * r;               // p * r = sqrt(p);
+}
+
+
+//// distance
+
+float distance(const float x, const float y)
+{
+   const float d = x - y;
+   __retVal = length(d);
+}
+
+float distance(const vec2 v, const vec2 u)
+{
+   const vec2 d2 = v - u;
+   __retVal = length(d2);
+}
+
+float distance(const vec3 v, const vec3 u)
+{
+   const vec3 d3 = v - u;
+   __retVal = length(d3);
+}
+
+float distance(const vec4 v, const vec4 u)
+{
+   const vec4 d4 = v - u;
+   __retVal = length(d4);
+}
+
+
+//// cross
+
+vec3 cross(const vec3 v, const vec3 u)
+{
+   __asm vec3_cross __retVal.xyz, v, u;
+}
+
+
+//// faceforward
+
+float faceforward(const float N, const float I, const float Nref)
+{
+    // this could probably be done better
+    const float d = dot(Nref, I);
+    float s;
+    __asm vec4_sgt s, 0.0, d;  // s = (0.0 > d) ? 1 : 0
+    return mix(-N, N, s);
+}
+
+vec2 faceforward(const vec2 N, const vec2 I, const vec2 Nref)
+{
+    // this could probably be done better
+    const float d = dot(Nref, I);
+    float s;
+    __asm vec4_sgt s, 0.0, d;  // s = (0.0 > d) ? 1 : 0
+    return mix(-N, N, s);
+}
+
+vec3 faceforward(const vec3 N, const vec3 I, const vec3 Nref)
+{
+    // this could probably be done better
+    const float d = dot(Nref, I);
+    float s;
+    __asm vec4_sgt s, 0.0, d;  // s = (0.0 > d) ? 1 : 0
+    return mix(-N, N, s);
+}
+
+vec4 faceforward(const vec4 N, const vec4 I, const vec4 Nref)
+{
+    // this could probably be done better
+    const float d = dot(Nref, I);
+    float s;
+    __asm vec4_sgt s, 0.0, d;  // s = (0.0 > d) ? 1 : 0
+    return mix(-N, N, s);
+}
+
+
+//// reflect
+
+float reflect(const float I, const float N)
+{
+   return I - 2.0 * dot(N, I) * N;
+}
+
+vec2 reflect(const vec2 I, const vec2 N)
+{
+   return I - 2.0 * dot(N, I) * N;
+}
+
+vec3 reflect(const vec3 I, const vec3 N)
+{
+   return I - 2.0 * dot(N, I) * N;
+}
+
+vec4 reflect(const vec4 I, const vec4 N)
+{
+   return I - 2.0 * dot(N, I) * N;
+}
+
+//// refract
+
+float refract(const float I, const float N, const float eta)
+{
+   float n_dot_i = dot(N, I);
+   float k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i);
+   float retval;
+   if (k < 0.0)
+      retval = 0.0;
+   else
+      retval = eta * I - (eta * n_dot_i + sqrt(k)) * N;
+   return retval;
+}
+
+vec2 refract(const vec2 I, const vec2 N, const float eta)
+{
+   float n_dot_i = dot(N, I);
+   float k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i);
+   vec2 retval;
+   if (k < 0.0)
+      retval = vec2(0.0);
+   else
+      retval = eta * I - (eta * n_dot_i + sqrt(k)) * N;
+   return retval;
+}
+
+vec3 refract(const vec3 I, const vec3 N, const float eta)
+{
+   float n_dot_i = dot(N, I);
+   float k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i);
+   vec3 retval;
+   if (k < 0.0)
+      retval = vec3(0.0);
+   else
+      retval = eta * I - (eta * n_dot_i + sqrt(k)) * N;
+   return retval;
+}
+
+vec4 refract(const vec4 I, const vec4 N, const float eta)
+{
+   float n_dot_i = dot(N, I);
+   float k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i);
+   vec4 retval;
+   if (k < 0.0)
+      retval = vec4(0.0);
+   else
+      retval = eta * I - (eta * n_dot_i + sqrt(k)) * N;
+   return retval;
+}
+
+
+
+
+//
+// 8.5 Matrix Functions
+//
+
+mat2 matrixCompMult (mat2 m, mat2 n) {
+    return mat2 (m[0] * n[0], m[1] * n[1]);
+}
+
+mat3 matrixCompMult (mat3 m, mat3 n) {
+    return mat3 (m[0] * n[0], m[1] * n[1], m[2] * n[2]);
+}
+
+mat4 matrixCompMult (mat4 m, mat4 n) {
+    return mat4 (m[0] * n[0], m[1] * n[1], m[2] * n[2], m[3] * n[3]);
+}
+
+
+
+
+//
+// 8.6 Vector Relational Functions
+//
+
+//// lessThan
+
+bvec2 lessThan(const vec2 u, const vec2 v)
+{
+   __asm vec4_slt __retVal.xy, u, v;
+}
+
+bvec3 lessThan(const vec3 u, const vec3 v)
+{
+   __asm vec4_slt __retVal.xyz, u, v;
+}
+
+bvec4 lessThan(const vec4 u, const vec4 v)
+{
+   __asm vec4_slt __retVal, u, v;
+}
+
+bvec2 lessThan(const ivec2 u, const ivec2 v)
+{
+   __asm vec4_slt __retVal.xy, u, v;
+}
+
+bvec3 lessThan(const ivec3 u, const ivec3 v)
+{
+   __asm vec4_slt __retVal.xyz, u, v;
+}
+
+bvec4 lessThan(const ivec4 u, const ivec4 v)
+{
+   __asm vec4_slt __retVal, u, v;
+}
+
+
+//// lessThanEqual
+
+bvec2 lessThanEqual(const vec2 u, const vec2 v)
+{
+   __asm vec4_sle __retVal.xy, u, v;
+}
+
+bvec3 lessThanEqual(const vec3 u, const vec3 v)
+{
+   __asm vec4_sle __retVal.xyz, u, v;
+}
+
+bvec4 lessThanEqual(const vec4 u, const vec4 v)
+{
+   __asm vec4_sle __retVal, u, v;
+}
+
+bvec2 lessThanEqual(const ivec2 u, const ivec2 v)
+{
+   __asm vec4_sle __retVal.xy, u, v;
+}
+
+bvec3 lessThanEqual(const ivec3 u, const ivec3 v)
+{
+   __asm vec4_sle __retVal.xyz, u, v;
+}
+
+bvec4 lessThanEqual(const ivec4 u, const ivec4 v)
+{
+   __asm vec4_sle __retVal, u, v;
+}
+
+
+//// greaterThan
+
+bvec2 greaterThan(const vec2 u, const vec2 v)
+{
+   __asm vec4_sgt __retVal.xy, u, v;
+}
+
+bvec3 greaterThan(const vec3 u, const vec3 v)
+{
+   __asm vec4_sgt __retVal.xyz, u, v;
+}
+
+bvec4 greaterThan(const vec4 u, const vec4 v)
+{
+   __asm vec4_sgt __retVal, u, v;
+}
+
+bvec2 greaterThan(const ivec2 u, const ivec2 v)
+{
+   __asm vec4_sgt __retVal.xy, u.xy, v.xy;
+}
+
+bvec3 greaterThan(const ivec3 u, const ivec3 v)
+{
+   __asm vec4_sgt __retVal.xyz, u, v;
+}
+
+bvec4 greaterThan(const ivec4 u, const ivec4 v)
+{
+   __asm vec4_sgt __retVal, u, v;
+}
+
+
+//// greaterThanEqual
+
+bvec2 greaterThanEqual(const vec2 u, const vec2 v)
+{
+   __asm vec4_sge __retVal.xy, u, v;
+}
+
+bvec3 greaterThanEqual(const vec3 u, const vec3 v)
+{
+   __asm vec4_sge __retVal.xyz, u, v;
+}
+
+bvec4 greaterThanEqual(const vec4 u, const vec4 v)
+{
+   __asm vec4_sge __retVal, u, v;
+}
+
+bvec2 greaterThanEqual(const ivec2 u, const ivec2 v)
+{
+   __asm vec4_sge __retVal.xy, u, v;
+}
+
+bvec3 greaterThanEqual(const ivec3 u, const ivec3 v)
+{
+   __asm vec4_sge __retVal.xyz, u, v;
+}
+
+bvec4 greaterThanEqual(const ivec4 u, const ivec4 v)
+{
+   __asm vec4_sge __retVal, u, v;
+}
+
+
+//// equal
+
+bvec2 equal(const vec2 u, const vec2 v)
+{
+   __asm vec4_seq __retVal.xy, u, v;
+}
+
+bvec3 equal(const vec3 u, const vec3 v)
+{
+   __asm vec4_seq __retVal.xyz, u, v;
+}
+
+bvec4 equal(const vec4 u, const vec4 v)
+{
+   __asm vec4_seq __retVal, u, v;
+}
+
+bvec2 equal(const ivec2 u, const ivec2 v)
+{
+   __asm vec4_seq __retVal.xy, u, v;
+}
+
+bvec3 equal(const ivec3 u, const ivec3 v)
+{
+   __asm vec4_seq __retVal.xyz, u, v;
+}
+
+bvec4 equal(const ivec4 u, const ivec4 v)
+{
+   __asm vec4_seq __retVal, u, v;
+}
+
+bvec2 equal(const bvec2 u, const bvec2 v)
+{
+   __asm vec4_seq __retVal.xy, u, v;
+}
+
+bvec3 equal(const bvec3 u, const bvec3 v)
+{
+   __asm vec4_seq __retVal.xyz, u, v;
+}
+
+bvec4 equal(const bvec4 u, const bvec4 v)
+{
+   __asm vec4_seq __retVal, u, v;
+}
+
+
+
+
+//// notEqual
+
+bvec2 notEqual(const vec2 u, const vec2 v)
+{
+   __asm vec4_sne __retVal.xy, u, v;
+}
+
+bvec3 notEqual(const vec3 u, const vec3 v)
+{
+   __asm vec4_sne __retVal.xyz, u, v;
+}
+
+bvec4 notEqual(const vec4 u, const vec4 v)
+{
+   __asm vec4_sne __retVal, u, v;
+}
+
+bvec2 notEqual(const ivec2 u, const ivec2 v)
+{
+   __asm vec4_sne __retVal.xy, u, v;
+}
+
+bvec3 notEqual(const ivec3 u, const ivec3 v)
+{
+   __asm vec4_sne __retVal.xyz, u, v;
+}
+
+bvec4 notEqual(const ivec4 u, const ivec4 v)
+{
+   __asm vec4_sne __retVal, u, v;
+}
+
+bvec2 notEqual(const bvec2 u, const bvec2 v)
+{
+   __asm vec4_sne __retVal.xy, u, v;
+}
+
+bvec3 notEqual(const bvec3 u, const bvec3 v)
+{
+   __asm vec4_sne __retVal.xyz, u, v;
+}
+
+bvec4 notEqual(const bvec4 u, const bvec4 v)
+{
+   __asm vec4_sne __retVal, u, v;
+}
+
+
+
+//// any
+
+bool any(const bvec2 v)
+{
+   float sum;
+   __asm vec4_add sum.x, v.x, v.y;
+   __asm vec4_sne __retVal.x, sum.x, 0.0;
+}
+
+bool any(const bvec3 v)
+{
+   float sum;
+   __asm vec4_add sum.x, v.x, v.y;
+   __asm vec4_add sum.x, sum.x, v.z;
+   __asm vec4_sne __retVal.x, sum.x, 0.0;
+}
+
+bool any(const bvec4 v)
+{
+   float sum;
+   __asm vec4_add sum.x, v.x, v.y;
+   __asm vec4_add sum.x, sum.x, v.z;
+   __asm vec4_add sum.x, sum.x, v.w;
+   __asm vec4_sne __retVal.x, sum.x, 0.0;
+}
+
+
+//// all
+
+bool all (const bvec2 v)
+{
+   float prod;
+   __asm vec4_multiply prod, v.x, v.y;
+   __asm vec4_sne __retVal, prod, 0.0;
+}
+
+bool all (const bvec3 v)
+{
+   float prod;
+   __asm vec4_multiply prod, v.x, v.y;
+   __asm vec4_multiply prod, prod, v.z;
+   __asm vec4_sne __retVal, prod, 0.0;
+}
+
+bool all (const bvec4 v)
+{
+   float prod;
+   __asm vec4_multiply prod, v.x, v.y;
+   __asm vec4_multiply prod, prod, v.z;
+   __asm vec4_multiply prod, prod, v.w;
+   __asm vec4_sne __retVal, prod, 0.0;
+}
+
+
+
+//// not
+
+bvec2 not (const bvec2 v)
+{
+   __asm vec4_seq __retVal.xy, v, 0.0;
+}
+
+bvec3 not (const bvec3 v)
+{
+   __asm vec4_seq __retVal.xyz, v, 0.0;
+}
+
+bvec4 not (const bvec4 v)
+{
+   __asm vec4_seq __retVal, v, 0.0;
+}
+
+
+
+//// Texture Lookup Functions  (for both fragment and vertex shaders)
+
+vec4 texture1D(const sampler1D sampler, const float coord)
+{
+   __asm vec4_tex_1d __retVal, sampler, coord;
+}
+
+vec4 texture1DProj(const sampler1D sampler, const vec2 coord)
+{
+   // need to swizzle .y into .w
+   __asm vec4_tex_1d_proj __retVal, sampler, coord.xyyy;
+}
+
+vec4 texture1DProj(const sampler1D sampler, const vec4 coord)
+{
+   __asm vec4_tex_1d_proj __retVal, sampler, coord;
+}
+
+
+vec4 texture2D(const sampler2D sampler, const vec2 coord)
+{
+   __asm vec4_tex_2d __retVal, sampler, coord;
+}
+
+vec4 texture2DProj(const sampler2D sampler, const vec3 coord)
+{
+   // need to swizzle 'z' into 'w'.
+   __asm vec4_tex_2d_proj __retVal, sampler, coord.xyzz;
+}
+
+vec4 texture2DProj(const sampler2D sampler, const vec4 coord)
+{
+   __asm vec4_tex_2d_proj __retVal, sampler, coord;
+}
+
+
+vec4 texture3D(const sampler3D sampler, const vec3 coord)
+{
+   __asm vec4_tex_3d __retVal, sampler, coord;
+}
+
+vec4 texture3DProj(const sampler3D sampler, const vec4 coord)
+{
+   __asm vec4_tex_3d_proj __retVal, sampler, coord;
+}
+
+
+vec4 textureCube(const samplerCube sampler, const vec3 coord)
+{
+   __asm vec4_tex_cube __retVal, sampler, coord;
+}
+
+
+
+vec4 shadow1D(const sampler1DShadow sampler, const vec3 coord)
+{
+   __asm vec4_tex_1d_shadow __retVal, sampler, coord;
+}
+
+vec4 shadow1DProj(const sampler1DShadow sampler, const vec4 coord)
+{
+   // .s and .p will be divided by .q
+   __asm vec4_tex_1d_proj_shadow __retVal, sampler, coord;
+}
+
+vec4 shadow2D(const sampler2DShadow sampler, const vec3 coord)
+{
+   __asm vec4_tex_2d_shadow __retVal, sampler, coord;
+}
+
+vec4 shadow2DProj(const sampler2DShadow sampler, const vec4 coord)
+{
+   // .s, .t and .p will be divided by .q
+   __asm vec4_tex_2d_proj_shadow __retVal, sampler, coord;
+}
+
+
+//// GL_ARB_texture_rectangle:
+vec4 texture2DRect(const sampler2DRect sampler, const vec2 coord)
+{
+   __asm vec4_tex_rect __retVal, sampler, coord;
+}
+
+vec4 texture2DRectProj(const sampler2DRect sampler, const vec3 coord)
+{
+   // need to swizzle .y into .w
+   __asm vec4_tex_rect_proj __retVal, sampler, coord.xyzz;
+}
+
+vec4 texture2DRectProj(const sampler2DRect sampler, const vec4 coord)
+{
+   __asm vec4_tex_rect_proj __retVal, sampler, ccoord;
+}
+
+vec4 shadow2DRect(const sampler2DRectShadow sampler, const vec3 coord)
+{
+   __asm vec4_tex_rect_shadow __retVal, sampler, coord;
+}
+
+vec4 shadow2DRectProj(const sampler2DRectShadow sampler, const vec4 coord)
+{
+   __asm vec4_tex_rect_proj_shadow __retVal, sampler, coord;
+}
+
+
+
+//// GL_EXT_texture_array
+vec4 texture1DArray(const sampler1DArray sampler, const vec2 coord)
+{
+   __asm vec4_tex_1d_array __retVal, sampler, coord;
+}
+
+vec4 texture2DArray(const sampler2DArray sampler, const vec3 coord)
+{
+   __asm vec4_tex_2d_array __retVal, sampler, coord;
+}
+
+
+//
+// 8.9 Noise Functions
+//
+// AUTHOR: Stefan Gustavson (stegu@itn.liu.se), Nov 26, 2005
+//
+
+float noise1(const float x)
+{
+   __asm float_noise1 __retVal, x;
+}
+
+
+float noise1(const vec2 x)
+{
+    __asm float_noise2 __retVal, x;
+}
+
+float noise1(const vec3 x)
+{
+    __asm float_noise3 __retVal, x;
+}
+
+float noise1(const vec4 x)
+{
+    __asm float_noise4 __retVal, x;
+}
+
+vec2 noise2(const float x)
+{
+   __retVal.x = noise1(x);
+   __retVal.y = noise1(x + 19.34);
+}
+
+vec2 noise2(const vec2 x)
+{
+   __retVal.x = noise1(x);
+   __retVal.y = noise1(x + vec2(19.34, 7.66));
+}
+
+vec2 noise2(const vec3 x)
+{
+   __retVal.x = noise1(x);
+   __retVal.y = noise1(x + vec3(19.34, 7.66, 3.23));
+}
+
+vec2 noise2(const vec4 x)
+{
+   __retVal.x = noise1(x);
+   __retVal.y = noise1(x + vec4(19.34, 7.66, 3.23, 2.77));
+}
+
+vec3 noise3(const float x)
+{
+   __retVal.x = noise1(x);
+   __retVal.y = noise1(x + 19.34);
+   __retVal.z = noise1(x + 5.47);
+}
+
+vec3 noise3(const vec2 x)
+{
+   __retVal.x = noise1(x);
+   __retVal.y = noise1(x + vec2(19.34, 7.66));
+   __retVal.z = noise1(x + vec2(5.47, 17.85));
+}
+
+vec3 noise3(const vec3 x)
+{
+   __retVal.x = noise1(x);
+   __retVal.y = noise1(x + vec3(19.34, 7.66, 3.23));
+   __retVal.z = noise1(x + vec3(5.47, 17.85, 11.04));
+}
+
+vec3 noise3(const vec4 x)
+{
+   __retVal.x = noise1(x);
+   __retVal.y = noise1(x + vec4(19.34, 7.66, 3.23, 2.77));
+   __retVal.z = noise1(x + vec4(5.47, 17.85, 11.04, 13.19));
+}
+
+vec4 noise4(const float x)
+{
+   __retVal.x = noise1(x);
+   __retVal.y = noise1(x + 19.34);
+   __retVal.z = noise1(x + 5.47);
+   __retVal.w = noise1(x + 23.54);
+}
+
+vec4 noise4(const vec2 x)
+{
+   __retVal.x = noise1(x);
+   __retVal.y = noise1(x + vec2 (19.34, 7.66));
+   __retVal.z = noise1(x + vec2 (5.47, 17.85));
+   __retVal.w = noise1(x + vec2 (23.54, 29.11));
+}
+
+vec4 noise4(const vec3 x)
+{
+   __retVal.x = noise1(x);
+   __retVal.y = noise1(x + vec3(19.34, 7.66, 3.23));
+   __retVal.z = noise1(x + vec3(5.47, 17.85, 11.04));
+   __retVal.w = noise1(x + vec3(23.54, 29.11, 31.91));
+}
+
+vec4 noise4(const vec4 x)
+{
+   __retVal.x = noise1(x);
+   __retVal.y = noise1(x + vec4(19.34, 7.66, 3.23, 2.77));
+   __retVal.z = noise1(x + vec4(5.47, 17.85, 11.04, 13.19));
+   __retVal.w = noise1(x + vec4(23.54, 29.11, 31.91, 37.48));
+}
diff --git a/src/mesa/slang/library/slang_core.gc b/src/mesa/slang/library/slang_core.gc
new file mode 100644 (file)
index 0000000..0a0d159
--- /dev/null
@@ -0,0 +1,2619 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+//
+// This file defines nearly all constructors and operators for built-in data
+// types, using extended language syntax. In general, compiler treats
+// constructors and operators as ordinary functions with some exceptions.
+// For example, the language does not allow functions to be called in
+// constant expressions - here the exception is made to allow it.
+//
+// Each implementation provides its own version of this file. Each
+// implementation can define the required set of operators and constructors
+// in its own fashion.
+//
+// The extended language syntax is only present when compiling this file.
+// It is implicitly included at the very beginning of the compiled shader,
+// so no built-in functions can be used.
+//
+// To communicate with the implementation, a special extended "__asm" keyword
+// is used, followed by an instruction name (any valid identifier), a
+// destination variable identifier and a list of zero or more source
+// variable identifiers.
+//
+// A variable identifier is a variable name declared earlier in the code
+// (as a function parameter, local or global variable).
+//
+// An instruction name designates an instruction that must be exported
+// by the implementation.  Each instruction receives data from source
+// variable identifiers and returns data in the destination variable
+// identifier.
+//
+// It is up to the implementation how to define a particular operator
+// or constructor. If it is expected to being used rarely, it can be
+// defined in terms of other operators and constructors,
+// for example:
+//
+// ivec2 __operator + (const ivec2 x, const ivec2 y) {
+//    return ivec2 (x[0] + y[0], x[1] + y[1]);
+// }
+//
+// If a particular operator or constructor is expected to be used very
+// often or is an atomic operation (that is, an operation that cannot be
+// expressed in terms of other operations or would create a dependency
+// cycle) it must be defined using one or more __asm constructs.
+//
+// Each implementation must define constructors for all scalar types
+// (bool, float, int).  There are 9 scalar-to-scalar constructors
+// (including identity constructors). However, since the language
+// introduces special constructors (like matrix constructor with a single
+// scalar value), implementations must also implement these cases.
+// The compiler provides the following algorithm when resolving a constructor:
+// - try to find a constructor with a prototype matching ours,
+// - if no constructor is found and this is a scalar-to-scalar constructor,
+//   raise an error,
+// - if a constructor is found, execute it and return,
+// - count the size of the constructor parameter list - if it is less than
+//   the size of our constructor's type, raise an error,
+// - for each parameter in the list do a recursive constructor matching for
+//   appropriate scalar fields in the constructed variable,
+//
+// Each implementation must also define a set of operators that deal with
+// built-in data types.
+// There are four kinds of operators:
+// 1) Operators that are implemented only by the compiler: "()" (function
+//    call), "," (sequence) and "?:" (selection).
+// 2) Operators that are implemented by the compiler by expressing it in
+//    terms of other operators:
+//    - "." (field selection) - translated to subscript access,
+//    - "&&" (logical and) - translated to "<left_expr> ? <right_expr> :
+//      false",
+//    - "||" (logical or) - translated to "<left_expr> ? true : <right_expr>",
+// 3) Operators that can be defined by the implementation and if the required
+//    prototype is not found, standard behaviour is used:
+//    - "==", "!=", "=" (equality, assignment) - compare or assign
+//      matching fields one-by-one;
+//      note that at least operators for scalar data types must be defined
+//      by the implementation to get it work,
+// 4) All other operators not mentioned above. If no required prototype is
+//    found, an error is raised. An implementation must follow the language
+//    specification to provide all valid operator prototypes.
+//
+
+
+
+//// Basic, scalar constructors/casts
+
+int __constructor(const float f)
+{
+   __asm vec4_to_ivec4 __retVal, f;
+}
+
+int __constructor(const bool b)
+{
+   __retVal = b;
+}
+
+int __constructor(const int i)
+{
+   __retVal = i;
+}
+
+bool __constructor(const int i)
+{
+   __asm vec4_sne __retVal, i, 0.0;
+}
+
+bool __constructor(const float f)
+{
+   __asm vec4_sne __retVal, f, 0.0;
+}
+
+bool __constructor(const bool b)
+{
+   __retVal = b;
+}
+
+float __constructor(const int i)
+{
+    __asm ivec4_to_vec4 __retVal, i;
+}
+
+float __constructor(const bool b)
+{
+    __asm ivec4_to_vec4 __retVal, b;
+}
+
+float __constructor(const float f)
+{
+   __retVal = f;
+}
+
+
+//// vec2 constructors
+
+vec2 __constructor(const float x, const float y)
+{
+   __retVal.x = x;
+   __retVal.y = y;
+}
+
+vec2 __constructor(const float f)
+{
+   __asm vec4_move __retVal.xy, f;
+}
+
+vec2 __constructor(const int i)
+{
+   __asm ivec4_to_vec4 __retVal.xy, i;
+}
+
+vec2 __constructor(const bool b)
+{
+   __asm ivec4_to_vec4 __retVal.xy, b;
+}
+
+vec2 __constructor(const bvec2 b)
+{
+//   __retVal = b;
+   __asm ivec4_to_vec4 __retVal.xy, b;
+}
+
+vec2 __constructor(const vec3 v)
+{
+   __asm vec4_move __retVal.xy, v.xy;
+}
+
+vec2 __constructor(const vec4 v)
+{
+   __asm vec4_move __retVal.xy, v.xy;
+}
+
+
+//// vec3 constructors
+
+vec3 __constructor(const float x, const float y, const float z)
+{
+   __retVal.x = x;
+   __retVal.y = y;
+   __retVal.z = z;
+}
+
+vec3 __constructor(const float f)
+{
+   // Note: this could be "__retVal.xyz = f" but that's an illegal assignment
+   __asm vec4_move __retVal.xyz, f;
+}
+
+vec3 __constructor(const int i)
+{
+   __asm ivec4_to_vec4 __retVal.xyz, i;
+}
+
+vec3 __constructor(const bool b)
+{
+   __asm ivec4_to_vec4 __retVal.xyz, b;
+}
+
+vec3 __constructor(const bvec3 b)
+{
+   __asm ivec4_to_vec4 __retVal.xyz, b;
+}
+
+vec3 __constructor(const vec4 v)
+{
+   __asm vec4_move __retVal.xyz, v;
+}
+
+
+//// vec4 constructors
+
+vec4 __constructor(const float x, const float y, const float z, const float w)
+{
+   __retVal.x = x;
+   __retVal.y = y;
+   __retVal.z = z;
+   __retVal.w = w;
+}
+
+vec4 __constructor(const float f)
+{
+   // Note: this could be "__retVal = f" but that's an illegal assignment
+   __asm vec4_move __retVal, f;
+}
+
+vec4 __constructor(const int i)
+{
+   __asm ivec4_to_vec4 __retVal, i;
+}
+
+vec4 __constructor(const bool b)
+{
+   __asm ivec4_to_vec4 __retVal, b;
+}
+
+vec4 __constructor(const bvec4 b)
+{
+   __asm ivec4_to_vec4 __retVal, b;
+}
+
+vec4 __constructor(const ivec4 i)
+{
+   __asm ivec4_to_vec4 __retVal, i;
+}
+
+vec4 __constructor(const vec3 v3, const float f)
+{
+   // XXX this constructor shouldn't be needed anymore
+   __retVal.xyz = v3;
+   __retVal.w = f;
+}
+
+vec4 __constructor(const vec2 v2, const float f1, const float f2)
+{
+   // XXX this constructor shouldn't be needed anymore
+   __retVal.xy = v2;
+   __retVal.z = f1;
+   __retVal.w = f2;
+}
+
+
+//// ivec2 constructors
+
+ivec2 __constructor(const int i, const int j)
+{
+   __retVal.x = i;
+   __retVal.y = j;
+}
+
+ivec2 __constructor(const int i)
+{
+   __asm vec4_move __retVal.xy, i;
+}
+
+ivec2 __constructor(const float f)
+{
+   __asm vec4_to_ivec4 __retVal.xy, f;
+}
+
+ivec2 __constructor(const bool b)
+{
+   __asm vec4_to_ivec4 __retVal.xy, b;
+}
+
+
+//// ivec3 constructors
+
+ivec3 __constructor(const int i, const int j, const int k)
+{
+   __retVal.x = i;
+   __retVal.y = j;
+   __retVal.z = k;
+}
+
+ivec3 __constructor(const int i)
+{
+   __asm vec4_move __retVal.xyz, i;
+}
+
+ivec3 __constructor(const float f)
+{
+   __asm vec4_to_ivec4 __retVal.xyz, f;
+}
+
+ivec3 __constructor(const bool b)
+{
+   __asm vec4_move __retVal.xyz, b;
+}
+
+
+//// ivec4 constructors
+
+ivec4 __constructor(const int x, const int y, const int z, const int w)
+{
+   __retVal.x = x;
+   __retVal.y = y;
+   __retVal.z = z;
+   __retVal.w = w;
+}
+
+ivec4 __constructor(const int i)
+{
+   __asm vec4_move __retVal, i;
+}
+
+ivec4 __constructor(const float f)
+{
+   __asm vec4_to_ivec4 __retVal, f;
+}
+
+ivec4 __constructor(const bool b)
+{
+   __asm vec4_to_ivec4 __retVal, b;
+}
+
+
+//// bvec2 constructors
+
+bvec2 __constructor(const bool b1, const bool b2)
+{
+   __retVal.x = b1;
+   __retVal.y = b2;
+}
+
+bvec2 __constructor(const int i1, const int i2)
+{
+   __asm vec4_sne __retVal.x, i1, 0.0;
+   __asm vec4_sne __retVal.y, i2, 0.0;
+}
+
+
+bvec2 __constructor(const bool b)
+{
+   __asm vec4_move __retVal.xy, b;
+}
+
+bvec2 __constructor(const float f)
+{
+   __asm vec4_sne __retVal.xy, f, 0.0;
+}
+
+bvec2 __constructor(const int i)
+{
+   __asm vec4_sne __retVal.xy, i, 0.0;
+}
+
+bvec2 __constructor(const vec2 v)
+{
+   __asm vec4_sne __retVal.xy, v, 0.0;
+}
+
+bvec2 __constructor(const ivec2 v)
+{
+   __asm vec4_sne __retVal.xy, v, 0.0;
+}
+
+
+
+//// bvec3 constructors
+
+bvec3 __constructor(const bool b1, const bool b2, const bool b3)
+{
+   __retVal.x = b1;
+   __retVal.y = b2;
+   __retVal.z = b3;
+}
+
+bvec3 __constructor(const float f1, const float f2, const float f3)
+{
+   __asm vec4_sne __retVal.x, f1, 0.0;
+   __asm vec4_sne __retVal.y, f2, 0.0;
+   __asm vec4_sne __retVal.z, f3, 0.0;
+}
+
+bvec3 __constructor(const bool b)
+{
+   __asm vec4_move __retVal.xyz, b;
+}
+
+bvec3 __constructor(const float f)
+{
+   __asm vec4_sne __retVal.xyz, f, 0.0;
+}
+
+bvec3 __constructor(const int i)
+{
+   __asm vec4_sne __retVal.xyz, i, 0.0;
+}
+
+bvec3 __constructor(const vec3 v)
+{
+   __asm vec4_sne __retVal.xyz, v, 0.0;
+}
+
+bvec3 __constructor(const ivec3 v)
+{
+   __asm vec4_sne __retVal.xyz, v, 0.0;
+}
+
+
+
+//// bvec4 constructors
+
+bvec4 __constructor(const bool b1, const bool b2, const bool b3, const bool b4)
+{
+   __retVal.x = b1;
+   __retVal.y = b2;
+   __retVal.z = b3;
+   __retVal.w = b4;
+}
+
+bvec4 __constructor(const float f1, const float f2, const float f3, const float f4)
+{
+   const float zero = 0.0;
+   __asm vec4_sne __retVal.x, f1, zero;   
+   __asm vec4_sne __retVal.y, f2, zero;   
+   __asm vec4_sne __retVal.z, f3, zero;   
+   __asm vec4_sne __retVal.w, f4, zero;   
+}
+
+bvec4 __constructor(const bool b)
+{
+   __asm vec4_move __retVal.xyzw, b;
+}
+
+bvec4 __constructor(const float f)
+{
+   __asm vec4_sne __retVal.xyzw, f, 0.0;
+}
+
+bvec4 __constructor(const int i)
+{
+   __asm vec4_sne __retVal.xyzw, i, 0.0;
+}
+
+bvec4 __constructor(const vec4 v)
+{
+   __asm vec4_sne __retVal.xyzw, v, 0.0;
+}
+
+bvec4 __constructor(const ivec4 v)
+{
+   __asm vec4_sne __retVal.xyzw, v, 0.0;
+}
+
+
+
+//// mat2 constructors
+
+mat2 __constructor(const float m00, const float m10,
+                   const float m01, const float m11)
+{
+   __retVal[0].x = m00;
+   __retVal[0].y = m10;
+   __retVal[1].x = m01;
+   __retVal[1].y = m11;
+}
+
+mat2 __constructor(const float f)
+{
+   __retVal[0].x = f;
+   __retVal[0].y = 0.0;
+   __retVal[1].x = 0.0;
+   __retVal[1].y = f;
+}
+
+mat2 __constructor(const int i)
+{
+   return mat2(float(i));
+}
+
+mat2 __constructor(const bool b)
+{
+   return mat2(float(b));
+}
+
+mat2 __constructor(const vec2 c0, const vec2 c1)
+{
+   __retVal[0] = c0;
+   __retVal[1] = c1;
+}
+
+
+//// mat3 constructors
+
+mat3 __constructor(const float m00, const float m10, const float m20,
+                   const float m01, const float m11, const float m21,
+                   const float m02, const float m12, const float m22)
+{
+   __retVal[0].x = m00;
+   __retVal[0].y = m10;
+   __retVal[0].z = m20;
+   __retVal[1].x = m01;
+   __retVal[1].y = m11;
+   __retVal[1].z = m21;
+   __retVal[2].x = m02;
+   __retVal[2].y = m12;
+   __retVal[2].z = m22;
+}
+
+mat3 __constructor(const float f)
+{
+   vec2 v = vec2(f, 0.0);
+   __retVal[0] = v.xyy;
+   __retVal[1] = v.yxy;
+   __retVal[2] = v.yyx;
+}
+
+mat3 __constructor(const int i)
+{
+   return mat3(float(i));
+}
+
+mat3 __constructor(const bool b)
+{
+   return mat3(float(b));
+}
+
+mat3 __constructor(const vec3 c0, const vec3 c1, const vec3 c2)
+{
+   __retVal[0] = c0;
+   __retVal[1] = c1;
+   __retVal[2] = c2;
+}
+
+
+//// mat4 constructors
+
+mat4 __constructor(const float m00, const float m10, const float m20, const float m30,
+                   const float m01, const float m11, const float m21, const float m31,
+                   const float m02, const float m12, const float m22, const float m32,
+                   const float m03, const float m13, const float m23, const float m33)
+{
+   __retVal[0].x = m00;
+   __retVal[0].y = m10;
+   __retVal[0].z = m20;
+   __retVal[0].w = m30;
+   __retVal[1].x = m01;
+   __retVal[1].y = m11;
+   __retVal[1].z = m21;
+   __retVal[1].w = m31;
+   __retVal[2].x = m02;
+   __retVal[2].y = m12;
+   __retVal[2].z = m22;
+   __retVal[2].w = m32;
+   __retVal[3].x = m03;
+   __retVal[3].y = m13;
+   __retVal[3].z = m23;
+   __retVal[3].w = m33;
+}
+
+
+mat4 __constructor(const float f)
+{
+   vec2 v = vec2(f, 0.0);
+   __retVal[0] = v.xyyy;
+   __retVal[1] = v.yxyy;
+   __retVal[2] = v.yyxy;
+   __retVal[3] = v.yyyx;
+}
+
+mat4 __constructor(const int i)
+{
+   return mat4(float(i));
+}
+
+mat4 __constructor(const bool b)
+{
+   return mat4(float(b));
+}
+
+mat4 __constructor(const vec4 c0, const vec4 c1, const vec4 c2, const vec4 c3)
+{
+   __retVal[0] = c0;
+   __retVal[1] = c1;
+   __retVal[2] = c2;
+   __retVal[3] = c3;
+}
+
+
+
+//// Basic int operators
+
+int __operator + (const int a, const int b)
+{
+   __asm vec4_add __retVal, a, b;
+}
+
+int __operator - (const int a, const int b)
+{
+   __asm vec4_subtract __retVal, a, b;
+}
+
+int __operator * (const int a, const int b)
+{
+   __asm vec4_multiply __retVal, a, b;
+}
+
+int __operator / (const int a, const int b)
+{
+   float bInv, x;
+   __asm float_rcp bInv, b;
+   __asm vec4_multiply x, a, bInv;
+   __asm vec4_to_ivec4 __retVal, x;
+}
+
+
+//// Basic ivec2 operators
+
+ivec2 __operator + (const ivec2 a, const ivec2 b)
+{
+   __asm vec4_add __retVal, a, b;
+}
+
+ivec2 __operator - (const ivec2 a, const ivec2 b)
+{
+   __asm vec4_subtract __retVal, a, b;
+}
+
+ivec2 __operator * (const ivec2 a, const ivec2 b)
+{
+   __asm vec4_multiply __retVal, a, b;
+}
+
+ivec2 __operator / (const ivec2 a, const ivec2 b)
+{
+   vec2 bInv, x;
+   __asm float_rcp bInv.x, b.x;
+   __asm float_rcp bInv.y, b.y;
+   __asm vec4_multiply x, a, bInv;
+   __asm vec4_to_ivec4 __retVal, x;
+}
+
+
+//// Basic ivec3 operators
+
+ivec3 __operator + (const ivec3 a, const ivec3 b)
+{
+   __asm vec4_add __retVal, a, b;
+}
+
+ivec3 __operator - (const ivec3 a, const ivec3 b)
+{
+   __asm vec4_subtract __retVal, a, b;
+}
+
+ivec3 __operator * (const ivec3 a, const ivec3 b)
+{
+   __asm vec4_multiply __retVal, a, b;
+}
+
+ivec3 __operator / (const ivec3 a, const ivec3 b)
+{
+   vec3 bInv, x;
+   __asm float_rcp bInv.x, b.x;
+   __asm float_rcp bInv.y, b.y;
+   __asm float_rcp bInv.z, b.z;
+   __asm vec4_multiply x, a, bInv;
+   __asm vec4_to_ivec4 __retVal, x;
+}
+
+
+//// Basic ivec4 operators
+
+ivec4 __operator + (const ivec4 a, const ivec4 b)
+{
+   __asm vec4_add __retVal, a, b;
+}
+
+ivec4 __operator - (const ivec4 a, const ivec4 b)
+{
+   __asm vec4_subtract __retVal, a, b;
+}
+
+ivec4 __operator * (const ivec4 a, const ivec4 b)
+{
+   __asm vec4_multiply __retVal, a, b;
+}
+
+ivec4 __operator / (const ivec4 a, const ivec4 b)
+{
+   vec4 bInv, x;
+   __asm float_rcp bInv.x, b.x;
+   __asm float_rcp bInv.y, b.y;
+   __asm float_rcp bInv.z, b.z;
+   __asm float_rcp bInv.w, b.w;
+   __asm vec4_multiply x, a, bInv;
+   __asm vec4_to_ivec4 __retVal, x;
+}
+
+
+//// Basic float operators
+
+float __operator + (const float a, const float b)
+{
+   __asm vec4_add __retVal, a, b;
+}
+
+float __operator - (const float a, const float b)
+{
+   __asm vec4_subtract __retVal, a, b;
+}
+
+float __operator * (const float a, const float b)
+{
+    __asm vec4_multiply __retVal, a, b;
+}
+
+float __operator / (const float a, const float b)
+{
+   float bInv;
+   __asm float_rcp bInv.x, b;
+   __asm vec4_multiply __retVal, a, bInv;
+}
+
+
+//// Basic vec2 operators
+
+vec2 __operator + (const vec2 v, const vec2 u)
+{
+   __asm vec4_add __retVal.xy, v, u;
+}
+
+vec2 __operator - (const vec2 v, const vec2 u)
+{
+    __asm vec4_subtract __retVal.xy, v, u;
+}
+
+vec2 __operator * (const vec2 v, const vec2 u)
+{
+    __asm vec4_multiply __retVal.xy, v, u;
+}
+
+vec2 __operator / (const vec2 v, const vec2 u)
+{
+   vec2 w; // = 1 / u
+   __asm float_rcp w.x, u.x;
+   __asm float_rcp w.y, u.y;
+   __asm vec4_multiply __retVal.xy, v, w;
+}
+
+
+//// Basic vec3 operators
+
+vec3 __operator + (const vec3 v, const vec3 u)
+{
+   __asm vec4_add __retVal.xyz, v, u;
+}
+
+vec3 __operator - (const vec3 v, const vec3 u)
+{
+    __asm vec4_subtract __retVal.xyz, v, u;
+}
+
+vec3 __operator * (const vec3 v, const vec3 u)
+{
+    __asm vec4_multiply __retVal.xyz, v, u;
+}
+
+vec3 __operator / (const vec3 v, const vec3 u)
+{
+   vec3 w; // = 1 / u
+   __asm float_rcp w.x, u.x;
+   __asm float_rcp w.y, u.y;
+   __asm float_rcp w.z, u.z;
+   __asm vec4_multiply __retVal.xyz, v, w;
+}
+
+
+//// Basic vec4 operators
+
+vec4 __operator + (const vec4 v, const vec4 u)
+{
+   __asm vec4_add __retVal, v, u;
+}
+
+vec4 __operator - (const vec4 v, const vec4 u)
+{
+    __asm vec4_subtract __retVal, v, u;
+}
+
+vec4 __operator * (const vec4 v, const vec4 u)
+{
+    __asm vec4_multiply __retVal, v, u;
+}
+
+vec4 __operator / (const vec4 v, const vec4 u)
+{
+   vec4 w; // = 1 / u
+   __asm float_rcp w.x, u.x;
+   __asm float_rcp w.y, u.y;
+   __asm float_rcp w.z, u.z;
+   __asm float_rcp w.w, u.w;
+   __asm vec4_multiply __retVal, v, w;
+}
+
+
+
+
+//// Basic vec2/float operators
+
+vec2 __operator + (const float a, const vec2 u)
+{
+   __asm vec4_add __retVal.xy, a, u.xy;
+}
+
+vec2 __operator + (const vec2 v, const float b)
+{
+   __asm vec4_add __retVal.xy, v.xy, b;
+}
+
+vec2 __operator - (const float a, const vec2 u)
+{
+   __asm vec4_subtract __retVal.xy, a, u.xy;
+}
+
+vec2 __operator - (const vec2 v, const float b)
+{
+   __asm vec4_subtract __retVal.xy, v.xy, b;
+}
+
+vec2 __operator * (const float a, const vec2 u)
+{
+   __asm vec4_multiply __retVal.xy, a, u.xy;
+}
+
+vec2 __operator * (const vec2 v, const float b)
+{
+   __asm vec4_multiply __retVal.xy, v.xy, b;
+}
+
+vec2 __operator / (const float a, const vec2 u)
+{
+   vec2 invU;
+   __asm float_rcp invU.x, u.x;
+   __asm float_rcp invU.y, u.y;
+   __asm vec4_multiply __retVal.xy, a, invU.xy;
+}
+
+vec2 __operator / (const vec2 v, const float b)
+{
+   float invB;
+   __asm float_rcp invB, b;
+   __asm vec4_multiply __retVal.xy, v.xy, invB;
+}
+
+
+//// Basic vec3/float operators
+
+vec3 __operator + (const float a, const vec3 u)
+{
+   __asm vec4_add __retVal.xyz, a, u.xyz;
+}
+
+vec3 __operator + (const vec3 v, const float b)
+{
+   __asm vec4_add __retVal.xyz, v.xyz, b;
+}
+
+vec3 __operator - (const float a, const vec3 u)
+{
+   __asm vec4_subtract __retVal.xyz, a, u.xyz;
+}
+
+vec3 __operator - (const vec3 v, const float b)
+{
+   __asm vec4_subtract __retVal.xyz, v.xyz, b;
+}
+
+vec3 __operator * (const float a, const vec3 u)
+{
+   __asm vec4_multiply __retVal.xyz, a, u.xyz;
+}
+
+vec3 __operator * (const vec3 v, const float b)
+{
+   __asm vec4_multiply __retVal.xyz, v.xyz, b;
+}
+
+vec3 __operator / (const float a, const vec3 u)
+{
+   vec3 invU;
+   __asm float_rcp invU.x, u.x;
+   __asm float_rcp invU.y, u.y;
+   __asm float_rcp invU.z, u.z;
+   __asm vec4_multiply __retVal.xyz, a, invU.xyz;
+}
+
+vec3 __operator / (const vec3 v, const float b)
+{
+   float invB;
+   __asm float_rcp invB, b;
+   __asm vec4_multiply __retVal.xyz, v.xyz, invB;
+}
+
+
+//// Basic vec4/float operators
+
+vec4 __operator + (const float a, const vec4 u)
+{
+   __asm vec4_add __retVal, a, u;
+}
+
+vec4 __operator + (const vec4 v, const float b)
+{
+   __asm vec4_add __retVal, v, b;
+}
+
+vec4 __operator - (const float a, const vec4 u)
+{
+   __asm vec4_subtract __retVal, a, u;
+}
+
+vec4 __operator - (const vec4 v, const float b)
+{
+   __asm vec4_subtract __retVal, v, b;
+}
+
+vec4 __operator * (const float a, const vec4 u)
+{
+   __asm vec4_multiply __retVal, a, u;
+}
+
+vec4 __operator * (const vec4 v, const float b)
+{
+   __asm vec4_multiply __retVal, v, b;
+}
+
+vec4 __operator / (const float a, const vec4 u)
+{
+   vec4 invU;
+   __asm float_rcp invU.x, u.x;
+   __asm float_rcp invU.y, u.y;
+   __asm float_rcp invU.z, u.z;
+   __asm float_rcp invU.w, u.w;
+   __asm vec4_multiply __retVal, a, invU;
+}
+
+vec4 __operator / (const vec4 v, const float b)
+{
+   float invB;
+   __asm float_rcp invB, b;
+   __asm vec4_multiply __retVal, v, invB;
+}
+
+
+
+//// Basic ivec2/int operators
+
+ivec2 __operator + (const int a, const ivec2 u)
+{
+   __retVal = ivec2(a) + u;
+}
+
+ivec2 __operator + (const ivec2 v, const int b)
+{
+   __retVal = v + ivec2(b);
+}
+
+ivec2 __operator - (const int a, const ivec2 u)
+{
+   __retVal = ivec2(a) - u;
+}
+
+ivec2 __operator - (const ivec2 v, const int b)
+{
+   __retVal = v - ivec2(b);
+}
+
+ivec2 __operator * (const int a, const ivec2 u)
+{
+   __retVal = ivec2(a) * u;
+}
+
+ivec2 __operator * (const ivec2 v, const int b)
+{
+   __retVal = v * ivec2(b);
+}
+
+ivec2 __operator / (const int a, const ivec2 u)
+{
+   __retVal = ivec2(a) / u;
+}
+
+ivec2 __operator / (const ivec2 v, const int b)
+{
+   __retVal = v / ivec2(b);
+}
+
+
+//// Basic ivec3/int operators
+
+ivec3 __operator + (const int a, const ivec3 u)
+{
+   __retVal = ivec3(a) + u;
+}
+
+ivec3 __operator + (const ivec3 v, const int b)
+{
+   __retVal = v + ivec3(b);
+}
+
+ivec3 __operator - (const int a, const ivec3 u)
+{
+   __retVal = ivec3(a) - u;
+}
+
+ivec3 __operator - (const ivec3 v, const int b)
+{
+   __retVal = v - ivec3(b);
+}
+
+ivec3 __operator * (const int a, const ivec3 u)
+{
+   __retVal = ivec3(a) * u;
+}
+
+ivec3 __operator * (const ivec3 v, const int b)
+{
+   __retVal = v * ivec3(b);
+}
+
+ivec3 __operator / (const int a, const ivec3 u)
+{
+   __retVal = ivec3(a) / u;
+}
+
+ivec3 __operator / (const ivec3 v, const int b)
+{
+   __retVal = v / ivec3(b);
+}
+
+
+//// Basic ivec4/int operators
+
+ivec4 __operator + (const int a, const ivec4 u)
+{
+   __retVal = ivec4(a) + u;
+}
+
+ivec4 __operator + (const ivec4 v, const int b)
+{
+   __retVal = v + ivec4(b);
+}
+
+ivec4 __operator - (const int a, const ivec4 u)
+{
+   __retVal = ivec4(a) - u;
+}
+
+ivec4 __operator - (const ivec4 v, const int b)
+{
+   __retVal = v - ivec4(b);
+}
+
+ivec4 __operator * (const int a, const ivec4 u)
+{
+   __retVal = ivec4(a) * u;
+}
+
+ivec4 __operator * (const ivec4 v, const int b)
+{
+   __retVal = v * ivec4(b);
+}
+
+ivec4 __operator / (const int a, const ivec4 u)
+{
+   __retVal = ivec4(a) / u;
+}
+
+ivec4 __operator / (const ivec4 v, const int b)
+{
+   __retVal = v / ivec4(b);
+}
+
+
+
+
+//// Unary negation operator
+
+int __operator - (const int a)
+{
+   __asm vec4_negate __retVal.x, a;
+}
+
+ivec2 __operator - (const ivec2 v)
+{
+   __asm vec4_negate __retVal, v;
+}
+
+ivec3 __operator - (const ivec3 v)
+{
+   __asm vec4_negate __retVal, v;
+}
+
+ivec4 __operator - (const ivec4 v)
+{
+   __asm vec4_negate __retVal, v;
+}
+
+float __operator - (const float a)
+{
+   __asm vec4_negate __retVal.x, a;
+}
+
+vec2 __operator - (const vec2 v)
+{
+   __asm vec4_negate __retVal.xy, v.xy;
+}
+
+vec3 __operator - (const vec3 v)
+{
+   __asm vec4_negate __retVal.xyz, v.xyz;
+}
+
+vec4 __operator - (const vec4 v)
+{
+   __asm vec4_negate __retVal, v;
+}
+
+mat2 __operator - (const mat2 m)
+{
+   __retVal[0] = -m[0];
+   __retVal[1] = -m[1];
+}
+
+mat3 __operator - (const mat3 m)
+{
+   __retVal[0] = -m[0];
+   __retVal[1] = -m[1];
+   __retVal[2] = -m[2];
+}
+
+mat4 __operator - (const mat4 m)
+{
+   __retVal[0] = -m[0];
+   __retVal[1] = -m[1];
+   __retVal[2] = -m[2];
+   __retVal[3] = -m[3];
+}
+
+
+
+//// dot product
+
+float dot(const float a, const float b)
+{
+   __retVal = a * b;
+}
+
+float dot(const vec2 a, const vec2 b)
+{
+   __retVal = a.x * b.x + a.y * b.y;
+}
+
+float dot(const vec3 a, const vec3 b)
+{
+    __asm vec3_dot __retVal, a, b;
+}
+
+float dot(const vec4 a, const vec4 b)
+{
+    __asm vec4_dot __retVal, a, b;
+}
+
+
+
+//// int assignment operators
+
+int __operator += (inout int a, const int b)
+{
+   a = a + b;
+   return a;
+}
+
+int __operator -= (inout int a, const int b)
+{
+   a = a - b;
+   return a;
+}
+
+int __operator *= (inout int a, const int b)
+{
+   a = a * b;
+   return a;
+}
+
+int __operator /= (inout int a, const int b)
+{
+   a = a / b;
+   return a;
+}
+
+
+//// ivec2 assignment operators
+
+ivec2 __operator += (inout ivec2 v, const ivec2 u)
+{
+   v = v + u;
+   return v;
+}
+
+ivec2 __operator -= (inout ivec2 v, const ivec2 u)
+{
+   v = v - u;
+   return v;
+}
+
+ivec2 __operator *= (inout ivec2 v, const ivec2 u)
+{
+   v = v * u;
+   return v;
+}
+
+ivec2 __operator /= (inout ivec2 v, const ivec2 u)
+{
+   v = v / u;
+   return v;
+}
+
+
+//// ivec3 assignment operators
+
+ivec3 __operator += (inout ivec3 v, const ivec3 u)
+{
+   v = v + u;
+   return v;
+}
+
+ivec3 __operator -= (inout ivec3 v, const ivec3 u)
+{
+   v = v - u;
+   return v;
+}
+
+ivec3 __operator *= (inout ivec3 v, const ivec3 u)
+{
+   v = v * u;
+   return v;
+}
+
+ivec3 __operator /= (inout ivec3 v, const ivec3 u)
+{
+   v = v / u;
+   return v;
+}
+
+
+//// ivec4 assignment operators
+
+ivec4 __operator += (inout ivec4 v, const ivec4 u)
+{
+   v = v + u;
+   return v;
+}
+
+ivec4 __operator -= (inout ivec4 v, const ivec4 u)
+{
+   v = v - u;
+   return v;
+}
+
+ivec4 __operator *= (inout ivec4 v, const ivec4 u)
+{
+   v = v * u;
+   return v;
+}
+
+ivec4 __operator /= (inout ivec4 v, const ivec4 u)
+{
+   v = v / u;
+   return v;
+}
+
+
+//// float assignment operators
+
+float __operator += (inout float a, const float b)
+{
+   a = a + b;
+   return a;
+}
+
+float __operator -= (inout float a, const float b)
+{
+   a = a - b;
+   return a;
+}
+
+float __operator *= (inout float a, const float b)
+{
+   a = a * b;
+   return a;
+}
+
+float __operator /= (inout float a, const float b)
+{
+   a = a / b;
+   return a;
+}
+
+
+//// vec2 assignment operators
+
+vec2 __operator += (inout vec2 v, const vec2 u)
+{
+   v = v + u;
+   return v;
+}
+
+vec2 __operator -= (inout vec2 v, const vec2 u)
+{
+   v = v - u;
+   return v;
+}
+
+vec2 __operator *= (inout vec2 v, const vec2 u)
+{
+   v = v * u;
+   return v;
+}
+
+vec2 __operator /= (inout vec2 v, const vec2 u)
+{
+   v = v / u;
+   return v;
+}
+
+
+//// vec3 assignment operators
+
+vec3 __operator += (inout vec3 v, const vec3 u)
+{
+   v = v + u;
+   return v;
+}
+
+vec3 __operator -= (inout vec3 v, const vec3 u)
+{
+   v = v - u;
+   return v;
+}
+
+vec3 __operator *= (inout vec3 v, const vec3 u)
+{
+   v = v * u;
+   return v;
+}
+
+vec3 __operator /= (inout vec3 v, const vec3 u)
+{
+   v = v / u;
+   return v;
+}
+
+
+//// vec4 assignment operators
+
+vec4 __operator += (inout vec4 v, const vec4 u)
+{
+   v = v + u;
+   return v;
+}
+
+vec4 __operator -= (inout vec4 v, const vec4 u)
+{
+   v = v - u;
+   return v;
+}
+
+vec4 __operator *= (inout vec4 v, const vec4 u)
+{
+   v = v * u;
+   return v;
+}
+
+vec4 __operator /= (inout vec4 v, const vec4 u)
+{
+   v = v / u;
+   return v;
+}
+
+
+
+//// ivec2/int assignment operators
+
+ivec2 __operator += (inout ivec2 v, const int a)
+{
+   v = v + ivec2(a);
+   return v;
+}
+
+ivec2 __operator -= (inout ivec2 v, const int a)
+{
+   v = v - ivec2(a);
+   return v;
+}
+
+ivec2 __operator *= (inout ivec2 v, const int a)
+{
+   v = v * ivec2(a);
+   return v;
+}
+
+ivec2 __operator /= (inout ivec2 v, const int a)
+{
+   v = v / ivec2(a);
+   return v;
+}
+
+
+//// ivec3/int assignment operators
+
+ivec3 __operator += (inout ivec3 v, const int a)
+{
+   v = v + ivec3(a);
+   return v;
+}
+
+ivec3 __operator -= (inout ivec3 v, const int a)
+{
+   v = v - ivec3(a);
+   return v;
+}
+
+ivec3 __operator *= (inout ivec3 v, const int a)
+{
+   v = v * ivec3(a);
+   return v;
+}
+
+ivec4 __operator /= (inout ivec3 v, const int a)
+{
+   v = v / ivec3(a);
+   return v;
+}
+
+
+//// ivec4/int assignment operators
+
+ivec4 __operator += (inout ivec4 v, const int a)
+{
+   v = v + ivec4(a);
+   return v;
+}
+
+ivec4 __operator -= (inout ivec4 v, const int a)
+{
+   v = v - ivec4(a);
+   return v;
+}
+
+ivec4 __operator *= (inout ivec4 v, const int a)
+{
+   v = v * ivec4(a);
+   return v;
+}
+
+ivec4 __operator /= (inout ivec4 v, const int a)
+{
+   v = v / ivec4(a);
+   return v;
+}
+
+
+
+//// vec2/float assignment operators
+
+vec2 __operator += (inout vec2 v, const float a)
+{
+   v = v + vec2(a);
+   return v;
+}
+
+vec2 __operator -= (inout vec2 v, const float a)
+{
+   v = v - vec2(a);
+   return v;
+}
+
+vec2 __operator *= (inout vec2 v, const float a)
+{
+   v = v * vec2(a);
+   return v;
+}
+
+vec2 __operator /= (inout vec2 v, const float a)
+{
+   v = v / vec2(a);
+   return v;
+}
+
+
+//// vec3/float assignment operators
+
+vec3 __operator += (inout vec3 v, const float a)
+{
+   v = v + vec3(a);
+   return v;
+}
+
+vec3 __operator -= (inout vec3 v, const float a)
+{
+   v = v - vec3(a);
+   return v;
+}
+
+vec3 __operator *= (inout vec3 v, const float a)
+{
+   v = v * vec3(a);
+   return v;
+}
+
+vec3 __operator /= (inout vec3 v, const float a)
+{
+   v = v / vec3(a);
+   return v;
+}
+
+
+//// vec4/float assignment operators
+
+vec4 __operator += (inout vec4 v, const float a)
+{
+   v = v + vec4(a);
+   return v;
+}
+
+vec4 __operator -= (inout vec4 v, const float a)
+{
+   v = v - vec4(a);
+   return v;
+}
+
+vec4 __operator *= (inout vec4 v, const float a)
+{
+   v = v * vec4(a);
+   return v;
+}
+
+vec4 __operator /= (inout vec4 v, const float a)
+{
+   v = v / vec4(a);
+   return v;
+}
+
+
+
+
+
+//// Basic mat2 operations
+
+mat2 __operator + (const mat2 m, const mat2 n)
+{
+   __retVal[0] = m[0] + n[0];
+   __retVal[1] = m[1] + n[1];
+}
+
+mat2 __operator - (const mat2 m, const mat2 n)
+{
+   __retVal[0] = m[0] - n[0];
+   __retVal[1] = m[1] - n[1];
+}
+
+mat2 __operator * (const mat2 m, const mat2 n)
+{
+   __retVal[0] = m[0] * n[0].xx + m[1] * n[0].yy;
+   __retVal[1] = m[0] * n[1].xx + m[1] * n[1].yy;
+}
+
+mat2 __operator / (const mat2 m, const mat2 n)
+{
+   __retVal[0] = m[0] / n[0];
+   __retVal[1] = m[1] / n[1];
+}
+
+
+//// Basic mat3 operations
+
+mat3 __operator + (const mat3 m, const mat3 n)
+{
+   __retVal[0] = m[0] + n[0];
+   __retVal[1] = m[1] + n[1];
+   __retVal[2] = m[2] + n[2];
+}
+
+mat3 __operator - (const mat3 m, const mat3 n)
+{
+   __retVal[0] = m[0] - n[0];
+   __retVal[1] = m[1] - n[1];
+   __retVal[2] = m[2] - n[2];
+}
+
+mat3 __operator * (const mat3 m, const mat3 n)
+{
+   __retVal[0] = m[0] * n[0].xxx + m[1] * n[0].yyy + m[2] * n[0].zzz;
+   __retVal[1] = m[0] * n[1].xxx + m[1] * n[1].yyy + m[2] * n[1].zzz;
+   __retVal[2] = m[0] * n[2].xxx + m[1] * n[2].yyy + m[2] * n[2].zzz;
+}
+
+mat3 __operator / (const mat3 m, const mat3 n)
+{
+    __retVal[0] = m[0] / n[0];
+    __retVal[1] = m[1] / n[1];
+    __retVal[2] = m[2] / n[2];
+}
+
+
+//// Basic mat4 operations
+
+mat4 __operator + (const mat4 m, const mat4 n)
+{
+   __retVal[0] = m[0] + n[0];
+   __retVal[1] = m[1] + n[1];
+   __retVal[2] = m[2] + n[2];
+   __retVal[3] = m[3] + n[3];
+}
+
+mat4 __operator - (const mat4 m, const mat4 n)
+{
+   __retVal[0] = m[0] - n[0];
+   __retVal[1] = m[1] - n[1];
+   __retVal[2] = m[2] - n[2];
+   __retVal[3] = m[3] - n[3];
+}
+
+mat4 __operator * (const mat4 m, const mat4 n)
+{
+   __retVal[0] = m[0] * n[0].xxxx + m[1] * n[0].yyyy + m[2] * n[0].zzzz + m[3] * n[0].wwww;
+   __retVal[1] = m[0] * n[1].xxxx + m[1] * n[1].yyyy + m[2] * n[1].zzzz + m[3] * n[1].wwww;
+   __retVal[2] = m[0] * n[2].xxxx + m[1] * n[2].yyyy + m[2] * n[2].zzzz + m[3] * n[2].wwww;
+   __retVal[3] = m[0] * n[3].xxxx + m[1] * n[3].yyyy + m[2] * n[3].zzzz + m[3] * n[3].wwww;
+}
+
+mat4 __operator / (const mat4 m, const mat4 n)
+{
+    __retVal[0] = m[0] / n[0];
+    __retVal[1] = m[1] / n[1];
+    __retVal[2] = m[2] / n[2];
+    __retVal[3] = m[3] / n[3];
+}
+
+
+//// mat2/float operations
+
+mat2 __operator + (const float a, const mat2 n)
+{
+   __retVal[0] = a + n[0];
+   __retVal[1] = a + n[1];
+}
+
+mat2 __operator + (const mat2 m, const float b)
+{
+   __retVal[0] = m[0] + b;
+   __retVal[1] = m[1] + b;
+}
+
+mat2 __operator - (const float a, const mat2 n)
+{
+   __retVal[0] = a - n[0];
+   __retVal[1] = a - n[1];
+}
+
+mat2 __operator - (const mat2 m, const float b)
+{
+   __retVal[0] = m[0] - b;
+   __retVal[1] = m[1] - b;
+}
+
+mat2 __operator * (const float a, const mat2 n)
+{
+   __retVal[0] = a * n[0];
+   __retVal[1] = a * n[1];
+}
+
+mat2 __operator * (const mat2 m, const float b)
+{
+   __retVal[0] = m[0] * b;
+   __retVal[1] = m[1] * b;
+}
+
+mat2 __operator / (const float a, const mat2 n)
+{
+   __retVal[0] = a / n[0];
+   __retVal[1] = a / n[1];
+}
+
+mat2 __operator / (const mat2 m, const float b)
+{
+   __retVal[0] = m[0] / b;
+   __retVal[1] = m[1] / b;
+}
+
+
+//// mat3/float operations
+
+mat3 __operator + (const float a, const mat3 n)
+{
+   __retVal[0] = a + n[0];
+   __retVal[1] = a + n[1];
+   __retVal[2] = a + n[2];
+}
+
+mat3 __operator + (const mat3 m, const float b)
+{
+   __retVal[0] = m[0] + b;
+   __retVal[1] = m[1] + b;
+   __retVal[2] = m[2] + b;
+}
+
+mat3 __operator - (const float a, const mat3 n)
+{
+   __retVal[0] = a - n[0];
+   __retVal[1] = a - n[1];
+   __retVal[2] = a - n[2];
+}
+
+mat3 __operator - (const mat3 m, const float b)
+{
+   __retVal[0] = m[0] - b;
+   __retVal[1] = m[1] - b;
+   __retVal[2] = m[2] - b;
+}
+
+mat3 __operator * (const float a, const mat3 n)
+{
+   __retVal[0] = a * n[0];
+   __retVal[1] = a * n[1];
+   __retVal[2] = a * n[2];
+}
+
+mat3 __operator * (const mat3 m, const float b)
+{
+   __retVal[0] = m[0] * b;
+   __retVal[1] = m[1] * b;
+   __retVal[2] = m[2] * b;
+}
+
+mat3 __operator / (const float a, const mat3 n)
+{
+   __retVal[0] = a / n[0];
+   __retVal[1] = a / n[1];
+   __retVal[2] = a / n[2];
+}
+
+mat3 __operator / (const mat3 m, const float b)
+{
+   __retVal[0] = m[0] / b;
+   __retVal[1] = m[1] / b;
+   __retVal[2] = m[2] / b;
+}
+
+
+//// mat4/float operations
+
+mat4 __operator + (const float a, const mat4 n)
+{
+   __retVal[0] = a + n[0];
+   __retVal[1] = a + n[1];
+   __retVal[2] = a + n[2];
+   __retVal[3] = a + n[3];
+}
+
+mat4 __operator + (const mat4 m, const float b)
+{
+   __retVal[0] = m[0] + b;
+   __retVal[1] = m[1] + b;
+   __retVal[2] = m[2] + b;
+   __retVal[3] = m[3] + b;
+}
+
+mat4 __operator - (const float a, const mat4 n)
+{
+   __retVal[0] = a - n[0];
+   __retVal[1] = a - n[1];
+   __retVal[2] = a - n[2];
+   __retVal[3] = a - n[3];
+}
+
+mat4 __operator - (const mat4 m, const float b)
+{
+   __retVal[0] = m[0] - b;
+   __retVal[1] = m[1] - b;
+   __retVal[2] = m[2] - b;
+   __retVal[3] = m[3] - b;
+}
+
+mat4 __operator * (const float a, const mat4 n)
+{
+   __retVal[0] = a * n[0];
+   __retVal[1] = a * n[1];
+   __retVal[2] = a * n[2];
+   __retVal[3] = a * n[3];
+}
+
+mat4 __operator * (const mat4 m, const float b)
+{
+   __retVal[0] = m[0] * b;
+   __retVal[1] = m[1] * b;
+   __retVal[2] = m[2] * b;
+   __retVal[3] = m[3] * b;
+}
+
+mat4 __operator / (const float a, const mat4 n)
+{
+   __retVal[0] = a / n[0];
+   __retVal[1] = a / n[1];
+   __retVal[2] = a / n[2];
+   __retVal[3] = a / n[3];
+}
+
+mat4 __operator / (const mat4 m, const float b)
+{
+   __retVal[0] = m[0] / b;
+   __retVal[1] = m[1] / b;
+   __retVal[2] = m[2] / b;
+   __retVal[3] = m[3] / b;
+}
+
+
+
+//// matrix / vector products
+
+vec2 __operator * (const mat2 m, const vec2 v)
+{
+   __retVal = m[0] * v.xx
+            + m[1] * v.yy;
+}
+
+vec2 __operator * (const vec2 v, const mat2 m)
+{
+   __retVal.x = dot(v, m[0]);
+   __retVal.y = dot(v, m[1]);
+}
+
+vec3 __operator * (const mat3 m, const vec3 v)
+{
+   __retVal = m[0] * v.xxx
+            + m[1] * v.yyy
+            + m[2] * v.zzz;
+}
+
+vec3 __operator * (const vec3 v, const mat3 m)
+{
+   __retVal.x = dot(v, m[0]);
+   __retVal.y = dot(v, m[1]);
+   __retVal.z = dot(v, m[2]);
+}
+
+vec4 __operator * (const mat4 m, const vec4 v)
+{
+   __retVal = m[0] * v.xxxx
+            + m[1] * v.yyyy
+            + m[2] * v.zzzz
+            + m[3] * v.wwww;
+}
+
+vec4 __operator * (const vec4 v, const mat4 m)
+{
+   __retVal.x = dot(v, m[0]);
+   __retVal.y = dot(v, m[1]);
+   __retVal.z = dot(v, m[2]);
+   __retVal.w = dot(v, m[3]);
+}
+
+
+
+//// mat2 assignment operators
+
+mat2 __operator += (inout mat2 m, const mat2 n)
+{
+   m[0] = m[0] + n[0];
+   m[1] = m[1] + n[1];
+   return m;
+}
+
+mat2 __operator -= (inout mat2 m, const mat2 n)
+{
+   m[0] = m[0] - n[0];
+   m[1] = m[1] - n[1];
+   return m;
+}
+
+mat2 __operator *= (inout mat2 m, const mat2 n)
+{
+   m = m * n;
+   return m;
+}
+
+mat2 __operator /= (inout mat2 m, const mat2 n)
+{
+   m[0] = m[0] / n[0];
+   m[1] = m[1] / n[1];
+   return m;
+}
+
+
+//// mat3 assignment operators
+
+mat3 __operator += (inout mat3 m, const mat3 n)
+{
+   m[0] = m[0] + n[0];
+   m[1] = m[1] + n[1];
+   m[2] = m[2] + n[2];
+   return m;
+}
+
+mat3 __operator -= (inout mat3 m, const mat3 n)
+{
+   m[0] = m[0] - n[0];
+   m[1] = m[1] - n[1];
+   m[2] = m[2] - n[2];
+   return m;
+}
+
+mat3 __operator *= (inout mat3 m, const mat3 n)
+{
+   m = m * n;
+   return m;
+}
+
+mat3 __operator /= (inout mat3 m, const mat3 n)
+{
+   m[0] = m[0] / n[0];
+   m[1] = m[1] / n[1];
+   m[2] = m[2] / n[2];
+   return m;
+}
+
+
+// mat4 assignment operators
+
+mat4 __operator += (inout mat4 m, const mat4 n)
+{
+   m[0] = m[0] + n[0];
+   m[1] = m[1] + n[1];
+   m[2] = m[2] + n[2];
+   m[3] = m[3] + n[3];
+   return m;
+}
+
+mat4 __operator -= (inout mat4 m, const mat4 n)
+{
+   m[0] = m[0] - n[0];
+   m[1] = m[1] - n[1];
+   m[2] = m[2] - n[2];
+   m[3] = m[3] - n[3];
+   return m;
+}
+
+mat4 __operator *= (inout mat4 m, const mat4 n)
+{
+   m = m * n;
+   return m;
+}
+
+mat4 __operator /= (inout mat4 m, const mat4 n)
+{
+   m[0] = m[0] / n[0];
+   m[1] = m[1] / n[1];
+   m[2] = m[2] / n[2];
+   m[3] = m[3] / n[3];
+   return m;
+}
+
+
+//// mat2/float assignment operators
+
+mat2 __operator += (inout mat2 m, const float a)
+{
+   vec2 v = vec2(a);
+   m[0] = m[0] + v;
+   m[1] = m[1] + v;
+   return m;
+}
+
+mat2 __operator -= (inout mat2 m, const float a)
+{
+   vec2 v = vec2(a);
+   m[0] = m[0] - v;
+   m[1] = m[1] - v;
+   return m;
+}
+
+mat2 __operator *= (inout mat2 m, const float a)
+{
+   vec2 v = vec2(a);
+   m[0] = m[0] * v;
+   m[1] = m[1] * v;
+   return m;
+}
+
+mat2 __operator /= (inout mat2 m, const float a)
+{
+   vec2 v = vec2(1.0 / a);
+   m[0] = m[0] * v;
+   m[1] = m[1] * v;
+   return m;
+}
+
+
+//// mat3/float assignment operators
+
+mat3 __operator += (inout mat3 m, const float a)
+{
+   vec3 v = vec3(a);
+   m[0] = m[0] + v;
+   m[1] = m[1] + v;
+   m[2] = m[2] + v;
+   return m;
+}
+
+mat3 __operator -= (inout mat3 m, const float a)
+{
+   vec3 v = vec3(a);
+   m[0] = m[0] - v;
+   m[1] = m[1] - v;
+   m[2] = m[2] - v;
+   return m;
+}
+
+mat3 __operator *= (inout mat3 m, const float a)
+{
+   vec3 v = vec3(a);
+   m[0] = m[0] * v;
+   m[1] = m[1] * v;
+   m[2] = m[2] * v;
+   return m;
+}
+
+mat3 __operator /= (inout mat3 m, const float a)
+{
+   vec3 v = vec3(1.0 / a);
+   m[0] = m[0] * v;
+   m[1] = m[1] * v;
+   m[2] = m[2] * v;
+   return m;
+}
+
+
+//// mat4/float assignment operators
+
+mat4 __operator += (inout mat4 m, const float a)
+{
+   vec4 v = vec4(a);
+   m[0] = m[0] + v;
+   m[1] = m[1] + v;
+   m[2] = m[2] + v;
+   m[3] = m[3] + v;
+   return m;
+}
+
+mat4 __operator -= (inout mat4 m, const float a)
+{
+   vec4 v = vec4(a);
+   m[0] = m[0] - v;
+   m[1] = m[1] - v;
+   m[2] = m[2] - v;
+   m[3] = m[3] - v;
+   return m;
+}
+
+mat4 __operator *= (inout mat4 m, const float a)
+{
+   vec4 v = vec4(a);
+   m[0] = m[0] * v;
+   m[1] = m[1] * v;
+   m[2] = m[2] * v;
+   m[3] = m[3] * v;
+   return m;
+}
+
+mat4 __operator /= (inout mat4 m, const float a)
+{
+   vec4 v = vec4(1.0 / a);
+   m[0] = m[0] * v;
+   m[1] = m[1] * v;
+   m[2] = m[2] * v;
+   m[3] = m[3] * v;
+   return m;
+}
+
+
+
+//// vec/mat assignment operators
+
+vec2 __operator *= (inout vec2 v, const mat2 m)
+{
+   v = v * m;
+   return v;
+}
+
+vec3 __operator *= (inout vec3 v, const mat3 m)
+{
+   v = v * m;
+   return v;
+}
+
+vec4 __operator *= (inout vec4 v, const mat4 m)
+{
+   v = v * m;
+   return v;
+}
+
+
+
+//// pre-decrement operators
+
+int __operator --(inout int a)
+{
+    a = a - 1;
+   __retVal = a;
+}
+
+ivec2 __operator --(inout ivec2 v)
+{
+   v = v - ivec2(1);
+   __retVal = v;
+}
+
+ivec3 __operator --(inout ivec3 v)
+{
+   v = v - ivec3(1);
+   __retVal = v;
+}
+
+ivec4 __operator --(inout ivec4 v)
+{
+   v = v - ivec4(1);
+   __retVal = v;
+}
+
+
+float __operator --(inout float a)
+{
+   a = a - 1.0;
+   __retVal = a;
+}
+
+vec2 __operator --(inout vec2 v)
+{
+   v = v - vec2(1.0);
+   __retVal = v;
+}
+
+vec3 __operator --(inout vec3 v)
+{
+   v = v - vec3(1.0);
+   __retVal = v;
+}
+
+vec4 __operator --(inout vec4 v)
+{
+   v = v - vec4(1.0);
+   __retVal = v;
+}
+
+
+mat2 __operator --(inout mat2 m)
+{
+   m[0] = m[0] - vec2(1.0);
+   m[1] = m[1] - vec2(1.0);
+   __retVal = m;
+}
+
+mat3 __operator --(inout mat3 m)
+{
+   m[0] = m[0] - vec3(1.0);
+   m[1] = m[1] - vec3(1.0);
+   m[2] = m[2] - vec3(1.0);
+   __retVal = m;
+}
+
+mat4 __operator --(inout mat4 m)
+{
+   m[0] = m[0] - vec4(1.0);
+   m[1] = m[1] - vec4(1.0);
+   m[2] = m[2] - vec4(1.0);
+   m[3] = m[3] - vec4(1.0);
+   __retVal = m;
+}
+
+
+//// pre-increment operators
+
+int __operator ++(inout int a)
+{
+    a = a + 1;
+    __retVal = a;
+}
+
+ivec2 __operator ++(inout ivec2 v)
+{
+   v = v + ivec2(1);
+   __retVal = v;
+}
+
+ivec3 __operator ++(inout ivec3 v)
+{
+   v = v + ivec3(1);
+   __retVal = v;
+}
+
+ivec4 __operator ++(inout ivec4 v)
+{
+   v = v + ivec4(1);
+   __retVal = v;
+}
+
+
+float __operator ++(inout float a)
+{
+    a = a + 1.0;
+    __retVal = a;
+}
+
+vec2 __operator ++(inout vec2 v)
+{
+   v = v + vec2(1.0);
+   __retVal = v;
+}
+
+vec3 __operator ++(inout vec3 v)
+{
+   v = v + vec3(1.0);
+   __retVal = v;
+}
+
+vec4 __operator ++(inout vec4 v)
+{
+   v = v + vec4(1.0);
+   __retVal = v;
+}
+
+
+mat2 __operator ++(inout mat2 m)
+{
+   m[0] = m[0] + vec2(1.0);
+   m[1] = m[1] + vec2(1.0);
+   __retVal = m;
+}
+
+mat3 __operator ++(inout mat3 m)
+{
+   m[0] = m[0] + vec3(1.0);
+   m[1] = m[1] + vec3(1.0);
+   m[2] = m[2] + vec3(1.0);
+   __retVal = m;
+}
+
+mat4 __operator ++(inout mat4 m)
+{
+   m[0] = m[0] + vec4(1.0);
+   m[1] = m[1] + vec4(1.0);
+   m[2] = m[2] + vec4(1.0);
+   m[3] = m[3] + vec4(1.0);
+   __retVal = m;
+}
+
+
+
+//// post-decrement
+
+int __postDecr(inout int a)
+{
+   __retVal = a;
+   a = a - 1;
+}
+
+ivec2 __postDecr(inout ivec2 v)
+{
+   __retVal = v;
+   v = v - ivec2(1);
+}
+
+ivec3 __postDecr(inout ivec3 v)
+{
+   __retVal = v;
+   v = v - ivec3(1);
+}
+
+ivec4 __postDecr(inout ivec4 v)
+{
+   __retVal = v;
+   v = v - ivec4(1);
+}
+
+
+float __postDecr(inout float a)
+{
+   __retVal = a;
+   a = a - 1.0;
+}
+
+vec2 __postDecr(inout vec2 v)
+{
+   __retVal = v;
+   v = v - vec2(1.0);
+}
+
+vec3 __postDecr(inout vec3 v)
+{
+   __retVal = v;
+   v = v - vec3(1.0);
+}
+
+vec4 __postDecr(inout vec4 v)
+{
+   __retVal = v;
+   v = v - vec4(1.0);
+}
+
+
+mat2 __postDecr(inout mat2 m)
+{
+   __retVal = m;
+   m[0] = m[0] - vec2(1.0);
+   m[1] = m[1] - vec2(1.0);
+}
+
+mat3 __postDecr(inout mat3 m)
+{
+   __retVal = m;
+   m[0] = m[0] - vec3(1.0);
+   m[1] = m[1] - vec3(1.0);
+   m[2] = m[2] - vec3(1.0);
+}
+
+mat4 __postDecr(inout mat4 m)
+{
+   __retVal = m;
+   m[0] = m[0] - vec4(1.0);
+   m[1] = m[1] - vec4(1.0);
+   m[2] = m[2] - vec4(1.0);
+   m[3] = m[3] - vec4(1.0);
+}
+
+
+//// post-increment
+
+float __postIncr(inout float a)
+{
+   __retVal = a;
+   a = a + 1;
+}
+
+vec2 __postIncr(inout vec2 v)
+{
+   __retVal = v;
+   v = v + vec2(1.0);
+}
+
+vec3 __postIncr(inout vec3 v)
+{
+   __retVal = v;
+   v = v + vec3(1.0);
+}
+
+vec4 __postIncr(inout vec4 v)
+{
+   __retVal = v;
+   v = v + vec4(1.0);
+}
+
+
+int __postIncr(inout int a)
+{
+   __retVal = a;
+   a = a + 1;
+}
+
+ivec2 __postIncr(inout ivec2 v)
+{
+   __retVal = v;
+   v = v + ivec2(1);
+}
+
+ivec3 __postIncr(inout ivec3 v)
+{
+   __retVal = v;
+   v = v + ivec3(1);
+}
+
+ivec4 __postIncr(inout ivec4 v)
+{
+   __retVal = v;
+   v = v + ivec3(1);
+}
+
+
+mat2 __postIncr(inout mat2 m)
+{
+   mat2 n = m;
+   m[0] = m[0] + vec2(1.0);
+   m[1] = m[1] + vec2(1.0);
+   return n;
+}
+
+mat3 __postIncr(inout mat3 m)
+{
+   mat3 n = m;
+   m[0] = m[0] + vec3(1.0);
+   m[1] = m[1] + vec3(1.0);
+   m[2] = m[2] + vec3(1.0);
+   return n;
+}
+
+mat4 __postIncr(inout mat4 m)
+{
+   mat4 n = m;
+   m[0] = m[0] + vec4(1.0);
+   m[1] = m[1] + vec4(1.0);
+   m[2] = m[2] + vec4(1.0);
+   m[3] = m[3] + vec4(1.0);
+   return n;
+}
+
+
+
+//// inequality operators
+
+
+// XXX are the inequality operators for floats/ints really needed????
+bool __operator < (const float a, const float b)
+{
+   __asm vec4_sgt __retVal.x, b, a;
+}
+
+
+bool __operator < (const int a, const int b) {
+    return float (a) < float (b);
+}
+
+bool __operator > (const float a, const float b) {
+    bool c;
+    __asm float_less c, b, a;
+    return c;
+}
+
+bool __operator > (const int a, const int b) {
+    return float (a) > float (b);
+}
+
+bool __operator >= (const float a, const float b) {
+    bool g, e;
+    __asm float_less  g, b, a;
+    __asm float_equal e, a, b;
+    return g || e;
+}
+
+bool __operator >= (const int a, const int b) {
+    return float (a) >= float (b);
+}
+
+bool __operator <= (const float a, const float b) {
+    bool g, e;
+    __asm float_less  g, a, b;
+    __asm float_equal e, a, b;
+    return g || e;
+}
+
+bool __operator <= (const int a, const int b) {
+    return float (a) <= float (b);
+}
+
+
+
+//
+// MESA-specific extension functions.
+//
+
+void printMESA (const float f) {
+    __asm float_print f;
+}
+
+void printMESA (const int i) {
+    __asm int_print i;
+}
+
+void printMESA (const bool b) {
+    __asm bool_print b;
+}
+
+void printMESA (const vec2 v) {
+    printMESA (v.x);
+    printMESA (v.y);
+}
+
+void printMESA (const vec3 v) {
+    printMESA (v.x);
+    printMESA (v.y);
+    printMESA (v.z);
+}
+
+void printMESA (const vec4 v) {
+    printMESA (v.x);
+    printMESA (v.y);
+    printMESA (v.z);
+    printMESA (v.w);
+}
+
+void printMESA (const ivec2 v) {
+    printMESA (v.x);
+    printMESA (v.y);
+}
+
+void printMESA (const ivec3 v) {
+    printMESA (v.x);
+    printMESA (v.y);
+    printMESA (v.z);
+}
+
+void printMESA (const ivec4 v) {
+    printMESA (v.x);
+    printMESA (v.y);
+    printMESA (v.z);
+    printMESA (v.w);
+}
+
+void printMESA (const bvec2 v) {
+    printMESA (v.x);
+    printMESA (v.y);
+}
+
+void printMESA (const bvec3 v) {
+    printMESA (v.x);
+    printMESA (v.y);
+    printMESA (v.z);
+}
+
+void printMESA (const bvec4 v) {
+    printMESA (v.x);
+    printMESA (v.y);
+    printMESA (v.z);
+    printMESA (v.w);
+}
+
+void printMESA (const mat2 m) {
+    printMESA (m[0]);
+    printMESA (m[1]);
+}
+
+void printMESA (const mat3 m) {
+    printMESA (m[0]);
+    printMESA (m[1]);
+    printMESA (m[2]);
+}
+
+void printMESA (const mat4 m) {
+    printMESA (m[0]);
+    printMESA (m[1]);
+    printMESA (m[2]);
+    printMESA (m[3]);
+}
+
+void printMESA (const sampler1D e) {
+    __asm int_print e;
+}
+
+void printMESA (const sampler2D e) {
+    __asm int_print e;
+}
+
+void printMESA (const sampler3D e) {
+    __asm int_print e;
+}
+
+void printMESA (const samplerCube e) {
+    __asm int_print e;
+}
+
+void printMESA (const sampler1DShadow e) {
+    __asm int_print e;
+}
+
+void printMESA (const sampler2DShadow e) {
+    __asm int_print e;
+}
+
diff --git a/src/mesa/slang/library/slang_fragment_builtin.gc b/src/mesa/slang/library/slang_fragment_builtin.gc
new file mode 100644 (file)
index 0000000..54a80ea
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+//
+// From Shader Spec, ver. 1.10, rev. 59
+//
+
+__fixed_input vec4 gl_FragCoord;
+__fixed_input bool gl_FrontFacing;
+__fixed_output vec4 gl_FragColor;
+__fixed_output vec4 gl_FragData[gl_MaxDrawBuffers];
+__fixed_output float gl_FragDepth;
+
+varying vec4 gl_Color;
+varying vec4 gl_SecondaryColor;
+varying vec4 gl_TexCoord[gl_MaxTextureCoords];
+varying float gl_FogFragCoord;
+
+
+
+//// 8.7 Texture Lookup Functions (with bias)
+
+vec4 texture1D(const sampler1D sampler, const float coord, const float bias)
+{
+   vec4 coord4;
+   coord4.x = coord;
+   coord4.w = bias;
+   __asm vec4_tex_1d_bias __retVal, sampler, coord4;
+}
+
+vec4 texture1DProj(const sampler1D sampler, const vec2 coord, const float bias)
+{
+   // do projection here (there's no vec4_texbp1d instruction)
+   vec4 pcoord;
+   pcoord.x = coord.x / coord.y;
+   pcoord.w = bias;
+   __asm vec4_tex_1d_bias __retVal, sampler, pcoord;
+}
+
+vec4 texture1DProj(const sampler1D sampler, const vec4 coord, const float bias)
+{
+   // do projection here (there's no vec4_texbp1d instruction)
+   vec4 pcoord;
+   pcoord.x = coord.x / coord.z;
+   pcoord.w = bias;
+   __asm vec4_tex_1d_bias __retVal, sampler, pcoord;
+}
+
+
+
+
+vec4 texture2D(const sampler2D sampler, const vec2 coord, const float bias)
+{
+   vec4 coord4;
+   coord4.xy = coord.xy;
+   coord4.w = bias;
+   __asm vec4_tex_2d_bias __retVal, sampler, coord4;
+}
+
+vec4 texture2DProj(const sampler2D sampler, const vec3 coord, const float bias)
+{
+   // do projection here (there's no vec4_texbp2d instruction)
+   vec4 pcoord;
+   pcoord.xy = coord.xy / coord.z;
+   pcoord.w = bias;
+   __asm vec4_tex_2d_bias __retVal, sampler, pcoord;
+}
+
+vec4 texture2DProj(const sampler2D sampler, const vec4 coord, const float bias)
+{
+   // do projection here (there's no vec4_texbp2d instruction)
+   vec4 pcoord;
+   pcoord.xy = coord.xy / coord.w;
+   pcoord.w = bias;
+   __asm vec4_tex_2d_bias __retVal, sampler, pcoord;
+}
+
+
+
+
+vec4 texture3D(const sampler3D sampler, const vec3 coord, const float bias)
+{
+   vec4 coord4;
+   coord4.xyz = coord.xyz;
+   coord4.w = bias;
+   __asm vec4_tex_3d_bias __retVal, sampler, coord4;
+}
+
+vec4 texture3DProj(const sampler3D sampler, const vec4 coord, const float bias)
+{
+   // do projection here (there's no vec4_texbp3d instruction)
+   vec4 pcoord;
+   pcoord.xyz = coord.xyz / coord.w;
+   pcoord.w = bias;
+   __asm vec4_tex_3d_bias __retVal, sampler, pcoord;
+}
+
+
+
+
+vec4 textureCube(const samplerCube sampler, const vec3 coord, const float bias)
+{
+   vec4 coord4;
+   coord4.xyz = coord;
+   coord4.w = bias;
+   __asm vec4_tex_cube __retVal, sampler, coord4;
+}
+
+
+
+vec4 shadow1D(const sampler1DShadow sampler, const vec3 coord, const float bias)
+{
+   vec4 coord4;
+   coord4.xyz = coord;
+   coord4.w = bias;
+   __asm vec4_tex_1d_bias_shadow __retVal, sampler, coord4;
+}
+
+vec4 shadow1DProj(const sampler1DShadow sampler, const vec4 coord, const float bias)
+{
+   vec4 pcoord;
+   pcoord.x = coord.x / coord.w;
+   pcoord.z = coord.z;
+   pcoord.w = bias;
+   __asm vec4_tex_1d_bias_shadow __retVal, sampler, pcoord;
+}
+
+vec4 shadow2D(const sampler2DShadow sampler, const vec3 coord, const float bias)
+{
+   vec4 coord4;
+   coord4.xyz = coord;
+   coord4.w = bias;
+   __asm vec4_tex_2d_bias_shadow __retVal, sampler, coord4;
+}
+
+vec4 shadow2DProj(const sampler2DShadow sampler, const vec4 coord, const float bias)
+{
+   vec4 pcoord;
+   pcoord.xy = coord.xy / coord.w;
+   pcoord.z = coord.z;
+   pcoord.w = bias;
+   __asm vec4_tex_2d_bias_shadow __retVal, sampler, pcoord;
+}
+
+
+
+//// GL_EXT_texture_array
+
+vec4 texture1DArray(const sampler1DArray sampler, const vec2 coord)
+{
+   vec4 coord4;
+   coord4.xy = coord;
+   __asm vec4_tex_1d_array __retVal, sampler, coord4;
+}
+
+vec4 texture1DArray(const sampler1DArray sampler, const vec2 coord, const float bias)
+{
+   vec4 coord4;
+   coord4.xy = coord;
+   coord4.w = bias;
+   __asm vec4_tex_1d_array_bias __retVal, sampler, coord4;
+}
+
+vec4 texure2DArray(const sampler2DArray sampler, const vec3 coord)
+{
+   vec4 coord4;
+   coord4.xyz = coord;
+   __asm vec4_tex_2d_array __retVal, sampler, coord4;
+}
+
+vec4 texture2DArray(const sampler2DArray sampler, const vec3 coord, const float bias)
+{
+   vec4 coord4;
+   coord4.xyz = coord;
+   coord4.w = bias;
+   __asm vec4_tex_2d_array_bias __retVal, sampler, coord4;
+}
+
+vec4 shadow1DArray(const sampler1DArrayShadow sampler, const vec2 coord)
+{
+   vec4 coord4;
+   coord4.xy = coord;
+   __asm vec4_tex_1d_array_shadow __retVal, sampler, coord4;
+}
+
+vec4 shadow1DArray(const sampler1DArrayShadow sampler, const vec2 coord, const float bias)
+{
+   vec4 coord4;
+   coord4.xy = coord;
+   coord4.w = bias;
+   __asm vec4_tex_1d_array_bias_shadow __retVal, sampler, coord4;
+}
+
+vec4 shadow2DArray(const sampler2DArrayShadow sampler, const vec3 coord)
+{
+   vec4 coord4;
+   coord4.xyz = coord;
+   __asm vec4_tex_2d_array_shadow __retVal, sampler, coord4;
+}
+
+vec4 shadow2DArray(const sampler2DArrayShadow sampler, const vec3 coord, const float bias)
+{
+   vec4 coord4;
+   coord4.xyz = coord;
+   coord4.w = bias;
+   __asm vec4_tex_2d_array_bias_shadow __retVal, sampler, coord4;
+}
+
+
+
+//
+// 8.8 Fragment Processing Functions
+//
+
+float dFdx(const float p)
+{
+   __asm vec4_ddx __retVal.x, p.xxxx;
+}
+
+vec2 dFdx(const vec2 p)
+{
+   __asm vec4_ddx __retVal.xy, p.xyyy;
+}
+
+vec3 dFdx(const vec3 p)
+{
+   __asm vec4_ddx __retVal.xyz, p.xyzz;
+}
+
+vec4 dFdx(const vec4 p)
+{
+   __asm vec4_ddx __retVal, p;
+}
+
+float dFdy(const float p)
+{
+   __asm vec4_ddy __retVal.x, p.xxxx;
+}
+
+vec2 dFdy(const vec2 p)
+{
+   __asm vec4_ddy __retVal.xy, p.xyyy;
+}
+
+vec3 dFdy(const vec3 p)
+{
+   __asm vec4_ddy __retVal.xyz, p.xyzz;
+}
+
+vec4 dFdy(const vec4 p)
+{
+   __asm vec4_ddy __retVal, p;
+}
+
+float fwidth (const float p)
+{
+   // XXX hand-write with __asm
+   return abs(dFdx(p)) + abs(dFdy(p));
+}
+
+vec2 fwidth(const vec2 p)
+{
+   // XXX hand-write with __asm
+   return abs(dFdx(p)) + abs(dFdy(p));
+}
+
+vec3 fwidth(const vec3 p)
+{
+   // XXX hand-write with __asm
+   return abs(dFdx(p)) + abs(dFdy(p));
+}
+
+vec4 fwidth(const vec4 p)
+{
+   // XXX hand-write with __asm
+   return abs(dFdx(p)) + abs(dFdy(p));
+}
+
diff --git a/src/mesa/slang/library/slang_geometry_builtin.gc b/src/mesa/slang/library/slang_geometry_builtin.gc
new file mode 100644 (file)
index 0000000..0752491
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and 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.
+ */
+
+const int _mesa_VerticesInMax = 6;
+
+__fixed_input int gl_PrimitiveIDIn;
+__fixed_output int gl_PrimitiveID;
+__fixed_output int gl_Layer;
+
+
+varying in vec4 gl_FrontColorIn[_mesa_VerticesInMax];
+varying in vec4 gl_BackColorIn[_mesa_VerticesInMax];
+varying in vec4 gl_FrontSecondaryColorIn[_mesa_VerticesInMax];
+varying in vec4 gl_BackSecondaryColorIn[_mesa_VerticesInMax];
+/*varying in vec4 gl_TexCoordIn[_mesa_VerticesInMax][gl_MaxTextureCoords];*/
+varying in float gl_FogFragCoordIn[_mesa_VerticesInMax];
+varying in vec4 gl_PositionIn[_mesa_VerticesInMax];
+varying in float gl_PointSizeIn[_mesa_VerticesInMax];
+varying in vec4 gl_ClipVertexIn[_mesa_VerticesInMax];
+
+varying out vec4 gl_Position;
+varying out vec4 gl_FrontColor;
+varying out vec4 gl_BackColor;
+varying out vec4 gl_FrontSecondaryColor;
+varying out vec4 gl_BackSecondaryColor;
+varying out vec4 gl_TexCoord[gl_MaxTextureCoords];
+varying out float gl_FogFragCoord;
+
+void EmitVertex()
+{
+    __asm emit_vertex;
+}
+
+void EndPrimitive()
+{
+    __asm end_primitive;
+}
diff --git a/src/mesa/slang/library/slang_vertex_builtin.gc b/src/mesa/slang/library/slang_vertex_builtin.gc
new file mode 100644 (file)
index 0000000..0c67c2e
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+//
+// From Shader Spec, ver. 1.10, rev. 59
+//
+
+__fixed_output vec4 gl_Position;
+__fixed_output float gl_PointSize;
+__fixed_output vec4 gl_ClipVertex;
+
+attribute vec4 gl_Color;
+attribute vec4 gl_SecondaryColor;
+attribute vec3 gl_Normal;
+attribute vec4 gl_Vertex;
+attribute vec4 gl_MultiTexCoord0;
+attribute vec4 gl_MultiTexCoord1;
+attribute vec4 gl_MultiTexCoord2;
+attribute vec4 gl_MultiTexCoord3;
+attribute vec4 gl_MultiTexCoord4;
+attribute vec4 gl_MultiTexCoord5;
+attribute vec4 gl_MultiTexCoord6;
+attribute vec4 gl_MultiTexCoord7;
+attribute float gl_FogCoord;
+
+varying vec4 gl_FrontColor;
+varying vec4 gl_BackColor;
+varying vec4 gl_FrontSecondaryColor;
+varying vec4 gl_BackSecondaryColor;
+varying vec4 gl_TexCoord[gl_MaxTextureCoords];
+varying float gl_FogFragCoord;
+
+//
+// Geometric Functions
+//
+
+vec4 ftransform()
+{
+   __retVal = gl_ModelViewProjectionMatrix[0] * gl_Vertex.xxxx
+            + gl_ModelViewProjectionMatrix[1] * gl_Vertex.yyyy
+            + gl_ModelViewProjectionMatrix[2] * gl_Vertex.zzzz
+            + gl_ModelViewProjectionMatrix[3] * gl_Vertex.wwww;
+}
+
+
+
+//
+// 8.7 Texture Lookup Functions
+// These are pretty much identical to the ones in slang_fragment_builtin.gc
+// When used in a vertex program, the texture sample instructions should not
+// be using a LOD term so it's effectively zero.  Adding 'lod' to that does
+// what we want.
+//
+
+vec4 texture1DLod(const sampler1D sampler, const float coord, const float lod)
+{
+   vec4 coord4;
+   coord4.x = coord;
+   coord4.w = lod;
+   __asm vec4_tex_1d_bias __retVal, sampler, coord4;
+}
+
+vec4 texture1DProjLod(const sampler1D sampler, const vec2 coord, const float lod)
+{
+   vec4 pcoord;
+   pcoord.x = coord.x / coord.y;
+   pcoord.w = lod;
+   __asm vec4_tex_1d_bias __retVal, sampler, pcoord;
+}
+
+vec4 texture1DProjLod(const sampler1D sampler, const vec4 coord, const float lod)
+{
+   vec4 pcoord;
+   pcoord.x = coord.x / coord.z;
+   pcoord.w = lod;
+   __asm vec4_tex_1d_bias __retVal, sampler, pcoord;
+}
+
+
+
+vec4 texture2DLod(const sampler2D sampler, const vec2 coord, const float lod)
+{
+   vec4 coord4;
+   coord4.xy = coord.xy;
+   coord4.w = lod;
+   __asm vec4_tex_2d_bias __retVal, sampler, coord4;
+}
+
+vec4 texture2DProjLod(const sampler2D sampler, const vec3 coord, const float lod)
+{
+   vec4 pcoord;
+   pcoord.xy = coord.xy / coord.z;
+   pcoord.w = lod;
+   __asm vec4_tex_2d_bias __retVal, sampler, pcoord;
+}
+
+vec4 texture2DProjLod(const sampler2D sampler, const vec4 coord, const float lod)
+{
+   vec4 pcoord;
+   pcoord.xy = coord.xy / coord.z;
+   pcoord.w = lod;
+   __asm vec4_tex_2d_bias __retVal, sampler, pcoord;
+}
+
+
+vec4 texture3DLod(const sampler3D sampler, const vec3 coord, const float lod)
+{
+   vec4 coord4;
+   coord4.xyz = coord.xyz;
+   coord4.w = lod;
+   __asm vec4_tex_3d_bias __retVal, sampler, coord4;
+}
+
+vec4 texture3DProjLod(const sampler3D sampler, const vec4 coord, const float lod)
+{
+   // do projection here (there's no vec4_tex_3d_bias_proj instruction)
+   vec4 pcoord;
+   pcoord.xyz = coord.xyz / coord.w;
+   pcoord.w = lod;
+   __asm vec4_tex_3d_bias __retVal, sampler, pcoord;
+}
+
+
+vec4 textureCubeLod(const samplerCube sampler, const vec3 coord, const float lod)
+{
+   vec4 coord4;
+   coord4.xyz = coord;
+   coord4.w = lod;
+   __asm vec4_tex_cube __retVal, sampler, coord4;
+}
+
+
+vec4 shadow1DLod(const sampler1DShadow sampler, const vec3 coord, const float lod)
+{
+   vec4 coord4;
+   coord4.xyz = coord;
+   coord4.w = lod;
+   __asm vec4_tex_1d_bias_shadow __retVal, sampler, coord4;
+}
+
+vec4 shadow1DProjLod(const sampler1DShadow sampler, const vec4 coord,
+                     const float lod)
+{
+   vec4 pcoord;
+   pcoord.x = coord.x / coord.w;
+   pcoord.z = coord.z;
+   pcoord.w = lod;
+   __asm vec4_tex_1d_bias_shadow __retVal, sampler, pcoord;
+}
+
+
+vec4 shadow2DLod(const sampler2DShadow sampler, const vec3 coord, const float lod)
+{
+   vec4 coord4;
+   coord4.xyz = coord;
+   coord4.w = lod;
+   __asm vec4_tex_2d_bias_shadow __retVal, sampler, coord4;
+}
+
+vec4 shadow2DProjLod(const sampler2DShadow sampler, const vec4 coord,
+                     const float lod)
+{
+   vec4 pcoord;
+   pcoord.xy = coord.xy / coord.w;
+   pcoord.z = coord.z;
+   pcoord.w = lod;
+   __asm vec4_tex_2d_bias_shadow __retVal, sampler, pcoord;
+}
+
+
+//// GL_EXT_texture_array
+
+vec4 texture1DArrayLod(const sampler1DArray sampler, const vec2 coord, const float lod)
+{
+   vec4 coord4;
+   coord4.xy = coord;
+   coord4.w = lod;
+   __asm vec4_tex_1d_array_bias __retVal, sampler, coord4;
+}
+
+
+vec4 texture2DArrayLod(const sampler2DArray sampler, const vec3 coord, const float lod)
+{
+   vec4 coord4;
+   coord4.xyz = coord;
+   coord4.w = lod;
+   __asm vec4_tex_2d_array_bias __retVal, sampler, coord4;
+}
+
diff --git a/src/mesa/slang/slang_builtin.c b/src/mesa/slang/slang_builtin.c
new file mode 100644 (file)
index 0000000..a7e0efc
--- /dev/null
@@ -0,0 +1,1018 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.3
+ *
+ * Copyright (C) 2005-2007  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2008  VMware, 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
+ * 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 slang_builtin.c
+ * Resolve built-in uniform vars.
+ * \author Brian Paul
+ */
+
+#include "main/imports.h"
+#include "main/mtypes.h"
+#include "program/program.h"
+#include "program/prog_instruction.h"
+#include "program/prog_parameter.h"
+#include "program/prog_statevars.h"
+#include "slang/slang_ir.h"
+#include "slang/slang_builtin.h"
+
+
+/** special state token (see below) */
+#define STATE_ARRAY ((gl_state_index) 0xfffff)
+
+
+/**
+ * Lookup GL state given a variable name, 0, 1 or 2 indexes and a field.
+ * Allocate room for the state in the given param list and return position
+ * in the list.
+ * Yes, this is kind of ugly, but it works.
+ */
+static GLint
+lookup_statevar(const char *var, GLint index1, GLint index2, const char *field,
+                GLuint *swizzleOut,
+                struct gl_program_parameter_list *paramList)
+{
+   /*
+    * NOTE: The ARB_vertex_program extension specified that matrices get
+    * loaded in registers in row-major order.  With GLSL, we want column-
+    * major order.  So, we need to transpose all matrices here...
+    */
+   static const struct {
+      const char *name;
+      gl_state_index matrix;
+      gl_state_index modifier;
+   } matrices[] = {
+      { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE },
+      { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS },
+      { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 },
+      { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
+
+      { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE },
+      { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS },
+      { "gl_ProjectionMatrixTranspose", STATE_PROJECTION_MATRIX, 0 },
+      { "gl_ProjectionMatrixInverseTranspose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE },
+
+      { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE },
+      { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS },
+      { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 },
+      { "gl_ModelViewProjectionMatrixInverseTranspose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE },
+
+      { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE },
+      { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS },
+      { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 },
+      { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE },
+
+      { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
+
+      { NULL, 0, 0 }
+   };
+   gl_state_index tokens[STATE_LENGTH];
+   GLuint i;
+   GLboolean isMatrix = GL_FALSE;
+
+   for (i = 0; i < STATE_LENGTH; i++) {
+      tokens[i] = 0;
+   }
+   *swizzleOut = SWIZZLE_NOOP;
+
+   /* first, look if var is a pre-defined matrix */
+   for (i = 0; matrices[i].name; i++) {
+      if (strcmp(var, matrices[i].name) == 0) {
+         tokens[0] = matrices[i].matrix;
+         /* tokens[1], [2] and [3] filled below */
+         tokens[4] = matrices[i].modifier;
+         isMatrix = GL_TRUE;
+         break;
+      }
+   }
+
+   if (isMatrix) {
+      if (tokens[0] == STATE_TEXTURE_MATRIX) {
+         /* texture_matrix[index1][index2] */
+         tokens[1] = index1 >= 0 ? index1 : 0; /* which texture matrix */
+         index1 = index2; /* move matrix row value to index1 */
+      }
+      if (index1 < 0) {
+         /* index1 is unused: prevent extra addition at end of function */
+         index1 = 0;
+      }
+   }
+   else if (strcmp(var, "gl_DepthRange") == 0) {
+      tokens[0] = STATE_DEPTH_RANGE;
+      assert(field);
+      if (strcmp(field, "near") == 0) {
+         *swizzleOut = SWIZZLE_XXXX;
+      }
+      else if (strcmp(field, "far") == 0) {
+         *swizzleOut = SWIZZLE_YYYY;
+      }
+      else if (strcmp(field, "diff") == 0) {
+         *swizzleOut = SWIZZLE_ZZZZ;
+      }
+      else {
+         return -1;
+      }
+   }
+   else if (strcmp(var, "gl_ClipPlane") == 0) {
+      if (index1 < 0)
+         return -1;
+      tokens[0] = STATE_CLIPPLANE;
+      tokens[1] = index1;
+   }
+   else if (strcmp(var, "gl_Point") == 0) {
+      assert(field);
+      if (strcmp(field, "size") == 0) {
+         tokens[0] = STATE_POINT_SIZE;
+         *swizzleOut = SWIZZLE_XXXX;
+      }
+      else if (strcmp(field, "sizeMin") == 0) {
+         tokens[0] = STATE_POINT_SIZE;
+         *swizzleOut = SWIZZLE_YYYY;
+      }
+      else if (strcmp(field, "sizeMax") == 0) {
+         tokens[0] = STATE_POINT_SIZE;
+         *swizzleOut = SWIZZLE_ZZZZ;
+      }
+      else if (strcmp(field, "fadeThresholdSize") == 0) {
+         tokens[0] = STATE_POINT_SIZE;
+         *swizzleOut = SWIZZLE_WWWW;
+      }
+      else if (strcmp(field, "distanceConstantAttenuation") == 0) {
+         tokens[0] = STATE_POINT_ATTENUATION;
+         *swizzleOut = SWIZZLE_XXXX;
+      }
+      else if (strcmp(field, "distanceLinearAttenuation") == 0) {
+         tokens[0] = STATE_POINT_ATTENUATION;
+         *swizzleOut = SWIZZLE_YYYY;
+      }
+      else if (strcmp(field, "distanceQuadraticAttenuation") == 0) {
+         tokens[0] = STATE_POINT_ATTENUATION;
+         *swizzleOut = SWIZZLE_ZZZZ;
+      }
+      else {
+         return -1;
+      }
+   }
+   else if (strcmp(var, "gl_FrontMaterial") == 0 ||
+            strcmp(var, "gl_BackMaterial") == 0) {
+      tokens[0] = STATE_MATERIAL;
+      if (strcmp(var, "gl_FrontMaterial") == 0)
+         tokens[1] = 0;
+      else
+         tokens[1] = 1;
+      assert(field);
+      if (strcmp(field, "emission") == 0) {
+         tokens[2] = STATE_EMISSION;
+      }
+      else if (strcmp(field, "ambient") == 0) {
+         tokens[2] = STATE_AMBIENT;
+      }
+      else if (strcmp(field, "diffuse") == 0) {
+         tokens[2] = STATE_DIFFUSE;
+      }
+      else if (strcmp(field, "specular") == 0) {
+         tokens[2] = STATE_SPECULAR;
+      }
+      else if (strcmp(field, "shininess") == 0) {
+         tokens[2] = STATE_SHININESS;
+         *swizzleOut = SWIZZLE_XXXX;
+      }
+      else {
+         return -1;
+      }
+   }
+   else if (strcmp(var, "gl_LightSource") == 0) {
+      if (!field || index1 < 0)
+         return -1;
+
+      tokens[0] = STATE_LIGHT;
+      tokens[1] = index1;
+
+      if (strcmp(field, "ambient") == 0) {
+         tokens[2] = STATE_AMBIENT;
+      }
+      else if (strcmp(field, "diffuse") == 0) {
+         tokens[2] = STATE_DIFFUSE;
+      }
+      else if (strcmp(field, "specular") == 0) {
+         tokens[2] = STATE_SPECULAR;
+      }
+      else if (strcmp(field, "position") == 0) {
+         tokens[2] = STATE_POSITION;
+      }
+      else if (strcmp(field, "halfVector") == 0) {
+         tokens[2] = STATE_HALF_VECTOR;
+      }
+      else if (strcmp(field, "spotDirection") == 0) {
+         tokens[2] = STATE_SPOT_DIRECTION;
+      }
+      else if (strcmp(field, "spotCosCutoff") == 0) {
+         tokens[2] = STATE_SPOT_DIRECTION;
+         *swizzleOut = SWIZZLE_WWWW;
+      }
+      else if (strcmp(field, "spotCutoff") == 0) {
+         tokens[2] = STATE_SPOT_CUTOFF;
+         *swizzleOut = SWIZZLE_XXXX;
+      }
+      else if (strcmp(field, "spotExponent") == 0) {
+         tokens[2] = STATE_ATTENUATION;
+         *swizzleOut = SWIZZLE_WWWW;
+      }
+      else if (strcmp(field, "constantAttenuation") == 0) {
+         tokens[2] = STATE_ATTENUATION;
+         *swizzleOut = SWIZZLE_XXXX;
+      }
+      else if (strcmp(field, "linearAttenuation") == 0) {
+         tokens[2] = STATE_ATTENUATION;
+         *swizzleOut = SWIZZLE_YYYY;
+      }
+      else if (strcmp(field, "quadraticAttenuation") == 0) {
+         tokens[2] = STATE_ATTENUATION;
+         *swizzleOut = SWIZZLE_ZZZZ;
+      }
+      else {
+         return -1;
+      }
+   }
+   else if (strcmp(var, "gl_LightModel") == 0) {
+      if (strcmp(field, "ambient") == 0) {
+         tokens[0] = STATE_LIGHTMODEL_AMBIENT;
+      }
+      else {
+         return -1;
+      }
+   }
+   else if (strcmp(var, "gl_FrontLightModelProduct") == 0) {
+      if (strcmp(field, "sceneColor") == 0) {
+         tokens[0] = STATE_LIGHTMODEL_SCENECOLOR;
+         tokens[1] = 0;
+      }
+      else {
+         return -1;
+      }
+   }
+   else if (strcmp(var, "gl_BackLightModelProduct") == 0) {
+      if (strcmp(field, "sceneColor") == 0) {
+         tokens[0] = STATE_LIGHTMODEL_SCENECOLOR;
+         tokens[1] = 1;
+      }
+      else {
+         return -1;
+      }
+   }
+   else if (strcmp(var, "gl_FrontLightProduct") == 0 ||
+            strcmp(var, "gl_BackLightProduct") == 0) {
+      if (index1 < 0 || !field)
+         return -1;
+
+      tokens[0] = STATE_LIGHTPROD;
+      tokens[1] = index1; /* light number */
+      if (strcmp(var, "gl_FrontLightProduct") == 0) {
+         tokens[2] = 0; /* front */
+      }
+      else {
+         tokens[2] = 1; /* back */
+      }
+      if (strcmp(field, "ambient") == 0) {
+         tokens[3] = STATE_AMBIENT;
+      }
+      else if (strcmp(field, "diffuse") == 0) {
+         tokens[3] = STATE_DIFFUSE;
+      }
+      else if (strcmp(field, "specular") == 0) {
+         tokens[3] = STATE_SPECULAR;
+      }
+      else {
+         return -1;
+      }
+   }
+   else if (strcmp(var, "gl_TextureEnvColor") == 0) {
+      if (index1 < 0)
+         return -1;
+      tokens[0] = STATE_TEXENV_COLOR;
+      tokens[1] = index1;
+   }
+   else if (strcmp(var, "gl_EyePlaneS") == 0) {
+      if (index1 < 0)
+         return -1;
+      tokens[0] = STATE_TEXGEN;
+      tokens[1] = index1; /* tex unit */
+      tokens[2] = STATE_TEXGEN_EYE_S;
+   }
+   else if (strcmp(var, "gl_EyePlaneT") == 0) {
+      if (index1 < 0)
+         return -1;
+      tokens[0] = STATE_TEXGEN;
+      tokens[1] = index1; /* tex unit */
+      tokens[2] = STATE_TEXGEN_EYE_T;
+   }
+   else if (strcmp(var, "gl_EyePlaneR") == 0) {
+      if (index1 < 0)
+         return -1;
+      tokens[0] = STATE_TEXGEN;
+      tokens[1] = index1; /* tex unit */
+      tokens[2] = STATE_TEXGEN_EYE_R;
+   }
+   else if (strcmp(var, "gl_EyePlaneQ") == 0) {
+      if (index1 < 0)
+         return -1;
+      tokens[0] = STATE_TEXGEN;
+      tokens[1] = index1; /* tex unit */
+      tokens[2] = STATE_TEXGEN_EYE_Q;
+   }
+   else if (strcmp(var, "gl_ObjectPlaneS") == 0) {
+      if (index1 < 0)
+         return -1;
+      tokens[0] = STATE_TEXGEN;
+      tokens[1] = index1; /* tex unit */
+      tokens[2] = STATE_TEXGEN_OBJECT_S;
+   }
+   else if (strcmp(var, "gl_ObjectPlaneT") == 0) {
+      if (index1 < 0)
+         return -1;
+      tokens[0] = STATE_TEXGEN;
+      tokens[1] = index1; /* tex unit */
+      tokens[2] = STATE_TEXGEN_OBJECT_T;
+   }
+   else if (strcmp(var, "gl_ObjectPlaneR") == 0) {
+      if (index1 < 0)
+         return -1;
+      tokens[0] = STATE_TEXGEN;
+      tokens[1] = index1; /* tex unit */
+      tokens[2] = STATE_TEXGEN_OBJECT_R;
+   }
+   else if (strcmp(var, "gl_ObjectPlaneQ") == 0) {
+      if (index1 < 0)
+         return -1;
+      tokens[0] = STATE_TEXGEN;
+      tokens[1] = index1; /* tex unit */
+      tokens[2] = STATE_TEXGEN_OBJECT_Q;
+   }
+   else if (strcmp(var, "gl_Fog") == 0) {
+      if (strcmp(field, "color") == 0) {
+         tokens[0] = STATE_FOG_COLOR;
+      }
+      else if (strcmp(field, "density") == 0) {
+         tokens[0] = STATE_FOG_PARAMS;
+         *swizzleOut = SWIZZLE_XXXX;
+      }
+      else if (strcmp(field, "start") == 0) {
+         tokens[0] = STATE_FOG_PARAMS;
+         *swizzleOut = SWIZZLE_YYYY;
+      }
+      else if (strcmp(field, "end") == 0) {
+         tokens[0] = STATE_FOG_PARAMS;
+         *swizzleOut = SWIZZLE_ZZZZ;
+      }
+      else if (strcmp(field, "scale") == 0) {
+         tokens[0] = STATE_FOG_PARAMS;
+         *swizzleOut = SWIZZLE_WWWW;
+      }
+      else {
+         return -1;
+      }
+   }
+   else {
+      return -1;
+   }
+
+   if (isMatrix) {
+      /* load all four rows (or columns) of matrix */
+      GLint pos[4];
+      GLuint j;
+      for (j = 0; j < 4; j++) {
+         tokens[2] = tokens[3] = j; /* jth row of matrix */
+         pos[j] = _mesa_add_state_reference(paramList, tokens);
+         assert(pos[j] >= 0);
+         ASSERT(pos[j] >= 0);
+      }
+      return pos[0] + index1;
+   }
+   else {
+      /* allocate a single register */
+      GLint pos = _mesa_add_state_reference(paramList, tokens);
+      ASSERT(pos >= 0);
+      return pos;
+   }
+}
+
+
+
+/**
+ * Given a variable name and datatype, emit uniform/constant buffer
+ * entries which will store that state variable.
+ * For example, if name="gl_LightSource" we'll emit 64 state variable
+ * vectors/references and return position where that data starts.  This will
+ * allow run-time array indexing into the light source array.
+ *
+ * Note that this is a recursive function.
+ *
+ * \return -1 if error, else index of start of data in the program parameter list
+ */
+static GLint
+emit_statevars(const char *name, int array_len,
+               const slang_type_specifier *type,
+               gl_state_index tokens[STATE_LENGTH],
+               struct gl_program_parameter_list *paramList)
+{
+   if (type->type == SLANG_SPEC_ARRAY) {
+      GLint i, pos = -1;
+      assert(array_len > 0);
+      if (strcmp(name, "gl_ClipPlane") == 0) {
+         tokens[0] = STATE_CLIPPLANE;
+      }
+      else if (strcmp(name, "gl_LightSource") == 0) {
+         tokens[0] = STATE_LIGHT;
+      }
+      else if (strcmp(name, "gl_FrontLightProduct") == 0) {
+         tokens[0] = STATE_LIGHTPROD;
+         tokens[2] = 0; /* front */
+      }
+      else if (strcmp(name, "gl_BackLightProduct") == 0) {
+         tokens[0] = STATE_LIGHTPROD;
+         tokens[2] = 1; /* back */
+      }
+      else if (strcmp(name, "gl_TextureEnvColor") == 0) {
+         tokens[0] = STATE_TEXENV_COLOR;
+      }
+      else if (strcmp(name, "gl_EyePlaneS") == 0) {
+         tokens[0] = STATE_TEXGEN;
+         tokens[2] = STATE_TEXGEN_EYE_S;
+      }
+      else if (strcmp(name, "gl_EyePlaneT") == 0) {
+         tokens[0] = STATE_TEXGEN;
+         tokens[2] = STATE_TEXGEN_EYE_T;
+      }
+      else if (strcmp(name, "gl_EyePlaneR") == 0) {
+         tokens[0] = STATE_TEXGEN;
+         tokens[2] = STATE_TEXGEN_EYE_R;
+      }
+      else if (strcmp(name, "gl_EyePlaneQ") == 0) {
+         tokens[0] = STATE_TEXGEN;
+         tokens[2] = STATE_TEXGEN_EYE_Q;
+      }
+      else if (strcmp(name, "gl_ObjectPlaneS") == 0) {
+         tokens[0] = STATE_TEXGEN;
+         tokens[2] = STATE_TEXGEN_OBJECT_S;
+      }
+      else if (strcmp(name, "gl_ObjectPlaneT") == 0) {
+         tokens[0] = STATE_TEXGEN;
+         tokens[2] = STATE_TEXGEN_OBJECT_T;
+      }
+      else if (strcmp(name, "gl_ObjectPlaneR") == 0) {
+         tokens[0] = STATE_TEXGEN;
+         tokens[2] = STATE_TEXGEN_OBJECT_R;
+      }
+      else if (strcmp(name, "gl_ObjectPlaneQ") == 0) {
+         tokens[0] = STATE_TEXGEN;
+         tokens[2] = STATE_TEXGEN_OBJECT_Q;
+      }
+      else if (strcmp(name, "gl_TextureMatrix") == 0) {
+         tokens[0] = STATE_TEXTURE_MATRIX;
+         tokens[4] = STATE_MATRIX_TRANSPOSE;
+      }
+      else if (strcmp(name, "gl_TextureMatrixInverse") == 0) {
+         tokens[0] = STATE_TEXTURE_MATRIX;
+         tokens[4] = STATE_MATRIX_INVTRANS;
+      }
+      else if (strcmp(name, "gl_TextureMatrixTranspose") == 0) {
+         tokens[0] = STATE_TEXTURE_MATRIX;
+         tokens[4] = 0;
+      }
+      else if (strcmp(name, "gl_TextureMatrixInverseTranspose") == 0) {
+         tokens[0] = STATE_TEXTURE_MATRIX;
+         tokens[4] = STATE_MATRIX_INVERSE;
+      }
+      else {
+         return -1; /* invalid array name */
+      }
+      /* emit state vars for each array element */
+      for (i = 0; i < array_len; i++) {
+         GLint p;
+         tokens[1] = i;
+         p = emit_statevars(NULL, 0, type->_array, tokens, paramList);
+         if (i == 0)
+            pos = p;
+      }
+      return pos;
+   }
+   else if (type->type == SLANG_SPEC_STRUCT) {
+      const slang_variable_scope *fields = type->_struct->fields;
+      GLuint i, pos = 0;
+      for (i = 0; i < fields->num_variables; i++) {
+         const slang_variable *var = fields->variables[i];
+         GLint p = emit_statevars(var->a_name, 0, &var->type.specifier,
+                                  tokens, paramList);
+         if (i == 0)
+            pos = p;
+      }
+      return pos;
+   }
+   else if (type->type == SLANG_SPEC_MAT4) {
+      /* unroll/emit 4 array rows (or columns) */
+      slang_type_specifier vec4;
+      GLint i, p, pos = -1;
+      vec4.type = SLANG_SPEC_VEC4;
+      for (i = 0; i < 4; i++) {
+         tokens[2] = tokens[3] = i; /* row[i] (or column[i]) of matrix */
+         p = emit_statevars(NULL, 0, &vec4, tokens, paramList);
+         if (pos == -1)
+            pos = p;
+      }
+      return pos;
+   }
+   else {
+      GLint pos;
+      assert(type->type == SLANG_SPEC_VEC4 ||
+             type->type == SLANG_SPEC_VEC3 ||
+             type->type == SLANG_SPEC_VEC2 ||
+             type->type == SLANG_SPEC_FLOAT ||
+             type->type == SLANG_SPEC_IVEC4 ||
+             type->type == SLANG_SPEC_IVEC3 ||
+             type->type == SLANG_SPEC_IVEC2 ||
+             type->type == SLANG_SPEC_INT);
+      if (name) {
+         GLint t;
+
+         if (tokens[0] == STATE_LIGHT)
+            t = 2;
+         else if (tokens[0] == STATE_LIGHTPROD)
+            t = 3;
+         else
+            return -1; /* invalid array name */
+
+         if (strcmp(name, "ambient") == 0) {
+            tokens[t] = STATE_AMBIENT;
+         }
+         else if (strcmp(name, "diffuse") == 0) {
+            tokens[t] = STATE_DIFFUSE;
+         }
+         else if (strcmp(name, "specular") == 0) {
+            tokens[t] = STATE_SPECULAR;
+         }
+         else if (strcmp(name, "position") == 0) {
+            tokens[t] = STATE_POSITION;
+         }
+         else if (strcmp(name, "halfVector") == 0) {
+            tokens[t] = STATE_HALF_VECTOR;
+         }
+         else if (strcmp(name, "spotDirection") == 0) {
+            tokens[t] = STATE_SPOT_DIRECTION; /* xyz components */
+         }
+         else if (strcmp(name, "spotCosCutoff") == 0) {
+            tokens[t] = STATE_SPOT_DIRECTION; /* w component */
+         }
+
+         else if (strcmp(name, "constantAttenuation") == 0) {
+            tokens[t] = STATE_ATTENUATION; /* x component */
+         }
+         else if (strcmp(name, "linearAttenuation") == 0) {
+            tokens[t] = STATE_ATTENUATION; /* y component */
+         }
+         else if (strcmp(name, "quadraticAttenuation") == 0) {
+            tokens[t] = STATE_ATTENUATION; /* z component */
+         }
+         else if (strcmp(name, "spotExponent") == 0) {
+            tokens[t] = STATE_ATTENUATION; /* w = spot exponent */
+         }
+
+         else if (strcmp(name, "spotCutoff") == 0) {
+            tokens[t] = STATE_SPOT_CUTOFF; /* x component */
+         }
+
+         else {
+            return -1; /* invalid field name */
+         }
+      }
+
+      pos = _mesa_add_state_reference(paramList, tokens);
+      return pos;
+   }
+
+   return 1;
+}
+
+
+/**
+ * Unroll the named built-in uniform variable into a sequence of state
+ * vars in the given parameter list.
+ */
+static GLint
+alloc_state_var_array(const slang_variable *var,
+                      struct gl_program_parameter_list *paramList)
+{
+   gl_state_index tokens[STATE_LENGTH];
+   GLuint i;
+   GLint pos;
+
+   /* Initialize the state tokens array.  This is very important.
+    * When we call _mesa_add_state_reference() it'll searches the parameter
+    * list to see if the given statevar token sequence is already present.
+    * This is normally a good thing since it prevents redundant values in the
+    * constant buffer.
+    *
+    * But when we're building arrays of state this can be bad.  For example,
+    * consider this fragment of GLSL code:
+    *   foo = gl_LightSource[3].diffuse;
+    *   ...
+    *   bar = gl_LightSource[i].diffuse;
+    *
+    * When we unroll the gl_LightSource array (for "bar") we want to re-emit
+    * gl_LightSource[3].diffuse and not re-use the first instance (from "foo")
+    * since that would upset the array layout.  We handle this situation by
+    * setting the last token in the state var token array to the special
+    * value STATE_ARRAY.
+    * This token will only be set for array state.  We can hijack the last
+    * element in the array for this since it's never used for light, clipplane
+    * or texture env array state.
+    */
+   for (i = 0; i < STATE_LENGTH; i++)
+      tokens[i] = 0;
+   tokens[STATE_LENGTH - 1] = STATE_ARRAY;
+
+   pos = emit_statevars(var->a_name, var->array_len, &var->type.specifier,
+                        tokens, paramList);
+
+   return pos;
+}
+
+
+
+/**
+ * Allocate storage for a pre-defined uniform (a GL state variable).
+ * As a memory-saving optimization, we try to only allocate storage for
+ * state vars that are actually used.
+ *
+ * Arrays such as gl_LightSource are handled specially.  For an expression
+ * like "gl_LightSource[2].diffuse", we can allocate a single uniform/constant
+ * slot and return the index.  In this case, we return direct=TRUE.
+ *
+ * Buf for something like "gl_LightSource[i].diffuse" we don't know the value
+ * of 'i' at compile time so we need to "unroll" the gl_LightSource array
+ * into a consecutive sequence of uniform/constant slots so it can be indexed
+ * at runtime.  In this case, we return direct=FALSE.
+ *
+ * Currently, all pre-defined uniforms are in one of these forms:
+ *   var
+ *   var[i]
+ *   var.field
+ *   var[i].field
+ *   var[i][j]
+ *
+ * \return -1 upon error, else position in paramList of the state variable/data
+ */
+GLint
+_slang_alloc_statevar(slang_ir_node *n,
+                      struct gl_program_parameter_list *paramList,
+                      GLboolean *direct)
+{
+   slang_ir_node *n0 = n;
+   const char *field = NULL;
+   GLint index1 = -1, index2 = -1;
+   GLuint swizzle;
+
+   *direct = GL_TRUE;
+
+   if (n->Opcode == IR_FIELD) {
+      field = n->Field;
+      n = n->Children[0];
+   }
+
+   if (n->Opcode == IR_ELEMENT) {
+      if (n->Children[1]->Opcode == IR_FLOAT) {
+         index1 = (GLint) n->Children[1]->Value[0];
+      }
+      else {
+         *direct = GL_FALSE;
+      }
+      n = n->Children[0];
+   }
+
+   if (n->Opcode == IR_ELEMENT) {
+      /* XXX can only handle constant indexes for now */
+      if (n->Children[1]->Opcode == IR_FLOAT) {
+         /* two-dimensional array index: mat[i][j] */
+         index2 = index1;
+         index1 = (GLint) n->Children[1]->Value[0];
+      }
+      else {
+         *direct = GL_FALSE;
+      }
+      n = n->Children[0];
+   }
+
+   assert(n->Opcode == IR_VAR);
+
+   if (*direct) {
+      const char *var = (const char *) n->Var->a_name;
+      GLint pos =
+         lookup_statevar(var, index1, index2, field, &swizzle, paramList);
+      if (pos >= 0) {
+         /* newly resolved storage for the statevar/constant/uniform */
+         n0->Store->File = PROGRAM_STATE_VAR;
+         n0->Store->Index = pos;
+         n0->Store->Swizzle = swizzle;
+         n0->Store->Parent = NULL;
+         return pos;
+      }
+   }
+
+   *direct = GL_FALSE;
+   return alloc_state_var_array(n->Var, paramList);
+}
+
+
+
+
+#define SWIZZLE_ZWWW MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W)
+
+
+/** Predefined shader inputs */
+struct input_info
+{
+   const char *Name;
+   GLuint Attrib;
+   GLenum Type;
+   GLuint Swizzle;
+   GLboolean Array;
+};
+
+/** Predefined vertex shader inputs/attributes */
+static const struct input_info vertInputs[] = {
+   { "gl_Vertex", VERT_ATTRIB_POS, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
+   { "gl_Normal", VERT_ATTRIB_NORMAL, GL_FLOAT_VEC3, SWIZZLE_NOOP, GL_FALSE },
+   { "gl_Color", VERT_ATTRIB_COLOR0, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
+   { "gl_SecondaryColor", VERT_ATTRIB_COLOR1, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
+   { "gl_FogCoord", VERT_ATTRIB_FOG, GL_FLOAT, SWIZZLE_XXXX, GL_FALSE },
+   { "gl_MultiTexCoord0", VERT_ATTRIB_TEX0, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
+   { "gl_MultiTexCoord1", VERT_ATTRIB_TEX1, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
+   { "gl_MultiTexCoord2", VERT_ATTRIB_TEX2, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
+   { "gl_MultiTexCoord3", VERT_ATTRIB_TEX3, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
+   { "gl_MultiTexCoord4", VERT_ATTRIB_TEX4, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
+   { "gl_MultiTexCoord5", VERT_ATTRIB_TEX5, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
+   { "gl_MultiTexCoord6", VERT_ATTRIB_TEX6, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
+   { "gl_MultiTexCoord7", VERT_ATTRIB_TEX7, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE }
+};
+
+static const struct input_info geomInputs[] = {
+   { "gl_PrimitiveIDIn", GEOM_ATTRIB_PRIMITIVE_ID, GL_FLOAT, SWIZZLE_NOOP, GL_FALSE },
+   { "gl_FrontColorIn", GEOM_ATTRIB_COLOR0, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_TRUE },
+   { "gl_BackColorIn", GEOM_ATTRIB_COLOR1, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_TRUE },
+   { "gl_FrontSecondaryColorIn", GEOM_ATTRIB_SECONDARY_COLOR0, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_TRUE },
+   { "gl_BackSecondaryColorIn", GEOM_ATTRIB_SECONDARY_COLOR1, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_TRUE },
+   { "gl_TexCoordIn", GEOM_ATTRIB_TEX_COORD, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_TRUE },
+   { "gl_FogFragCoordIn", GEOM_ATTRIB_FOG_FRAG_COORD, GL_FLOAT, SWIZZLE_NOOP, GL_TRUE },
+   { "gl_PositionIn", GEOM_ATTRIB_POSITION, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_TRUE },
+   { "gl_ClipVertexIn", GEOM_ATTRIB_CLIP_VERTEX, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_TRUE },
+   { "gl_PointSizeIn", GEOM_ATTRIB_POINT_SIZE, GL_FLOAT, SWIZZLE_NOOP, GL_TRUE }
+};
+
+/** Predefined fragment shader inputs */
+static const struct input_info fragInputs[] = {
+   { "gl_FragCoord", FRAG_ATTRIB_WPOS, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
+   { "gl_Color", FRAG_ATTRIB_COL0, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
+   { "gl_SecondaryColor", FRAG_ATTRIB_COL1, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
+   { "gl_TexCoord", FRAG_ATTRIB_TEX0, GL_FLOAT_VEC4, SWIZZLE_NOOP, GL_FALSE },
+   { "gl_FogFragCoord", FRAG_ATTRIB_FOGC, GL_FLOAT, SWIZZLE_XXXX, GL_FALSE },
+   { "gl_FrontFacing", FRAG_ATTRIB_FACE, GL_FLOAT, SWIZZLE_XXXX, GL_FALSE },
+   { "gl_PointCoord", FRAG_ATTRIB_PNTC, GL_FLOAT_VEC2, SWIZZLE_XYZW, GL_FALSE }
+};
+
+
+/**
+ * Return the VERT_ATTRIB_* or FRAG_ATTRIB_* value that corresponds to
+ * a vertex or fragment program input variable.  Return -1 if the input
+ * name is invalid.
+ * XXX return size too
+ */
+GLint
+_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut,
+                   GLboolean *is_array)
+{
+   const struct input_info *inputs;
+   GLuint i, n;
+
+   switch (target) {
+   case GL_VERTEX_PROGRAM_ARB:
+      inputs = vertInputs;
+      n = Elements(vertInputs);
+      break;
+   case GL_FRAGMENT_PROGRAM_ARB:
+      inputs = fragInputs;
+      n = Elements(fragInputs);
+      break;
+   case MESA_GEOMETRY_PROGRAM:
+      inputs = geomInputs;
+      n = Elements(geomInputs);
+      break;
+   default:
+      _mesa_problem(NULL, "bad target in _slang_input_index");
+      return -1;
+   }
+
+   ASSERT(MAX_TEXTURE_COORD_UNITS == 8); /* if this fails, fix vertInputs above */
+
+   for (i = 0; i < n; i++) {
+      if (strcmp(inputs[i].Name, name) == 0) {
+         /* found */
+         *swizzleOut = inputs[i].Swizzle;
+         if (is_array)
+            *is_array = inputs[i].Array;
+         return inputs[i].Attrib;
+      }
+   }
+   return -1;
+}
+
+
+/**
+ * Return name of the given vertex attribute (VERT_ATTRIB_x).
+ */
+const char *
+_slang_vert_attrib_name(GLuint attrib)
+{
+   GLuint i;
+   assert(attrib < VERT_ATTRIB_GENERIC0);
+   for (i = 0; Elements(vertInputs); i++) {
+      if (vertInputs[i].Attrib == attrib)
+         return vertInputs[i].Name;
+   }
+   return NULL;
+}
+
+
+/**
+ * Return type (GL_FLOAT, GL_FLOAT_VEC2, etc) of the given vertex
+ * attribute (VERT_ATTRIB_x).
+ */
+GLenum
+_slang_vert_attrib_type(GLuint attrib)
+{
+   GLuint i;
+   assert(attrib < VERT_ATTRIB_GENERIC0);
+   for (i = 0; Elements(vertInputs); i++) {
+      if (vertInputs[i].Attrib == attrib)
+         return vertInputs[i].Type;
+   }
+   return GL_NONE;
+}
+
+
+
+
+
+/** Predefined shader output info */
+struct output_info
+{
+   const char *Name;
+   GLuint Attrib;
+   GLenum Type;
+};
+
+/** Predefined vertex shader outputs */
+static const struct output_info vertOutputs[] = {
+   { "gl_Position", VERT_RESULT_HPOS, GL_FLOAT_VEC4 },
+   { "gl_FrontColor", VERT_RESULT_COL0, GL_FLOAT_VEC4 },
+   { "gl_BackColor", VERT_RESULT_BFC0, GL_FLOAT_VEC4 },
+   { "gl_FrontSecondaryColor", VERT_RESULT_COL1, GL_FLOAT_VEC4 },
+   { "gl_BackSecondaryColor", VERT_RESULT_BFC1, GL_FLOAT_VEC4 },
+   { "gl_TexCoord", VERT_RESULT_TEX0, GL_FLOAT_VEC4 },
+   { "gl_FogFragCoord", VERT_RESULT_FOGC, GL_FLOAT },
+   { "gl_PointSize", VERT_RESULT_PSIZ, GL_FLOAT }
+};
+
+/** Predefined geometry shader outputs */
+static const struct output_info geomOutputs[] = {
+   { "gl_Position", GEOM_RESULT_POS, GL_FLOAT_VEC4 },
+   { "gl_FrontColor", GEOM_RESULT_COL0, GL_FLOAT_VEC4  },
+   { "gl_BackColor", GEOM_RESULT_COL1, GL_FLOAT_VEC4  },
+   { "gl_FrontSecondaryColor", GEOM_RESULT_SCOL0, GL_FLOAT_VEC4  },
+   { "gl_BackSecondaryColor", GEOM_RESULT_SCOL1, GL_FLOAT_VEC4  },
+   { "gl_TexCoord", GEOM_RESULT_TEX0, GL_FLOAT_VEC4  },
+   { "gl_FogFragCoord", GEOM_RESULT_FOGC, GL_FLOAT  },
+   { "gl_ClipVertex", GEOM_RESULT_CLPV, GL_FLOAT_VEC4  },
+   { "gl_PointSize", GEOM_RESULT_PSIZ, GL_FLOAT  },
+   { "gl_PrimitiveID", GEOM_RESULT_PRID, GL_FLOAT  },
+   { "gl_Layer", GEOM_RESULT_LAYR, GL_FLOAT  }
+};
+
+/** Predefined fragment shader outputs */
+static const struct output_info fragOutputs[] = {
+   { "gl_FragColor", FRAG_RESULT_COLOR, GL_FLOAT_VEC4 },
+   { "gl_FragDepth", FRAG_RESULT_DEPTH, GL_FLOAT },
+   { "gl_FragData", FRAG_RESULT_DATA0, GL_FLOAT_VEC4 }
+};
+
+
+/**
+ * Return the VERT_RESULT_*, GEOM_RESULT_* or FRAG_RESULT_* value that corresponds
+ * to a vertex or fragment program output variable.  Return -1 for an invalid
+ * output name.
+ */
+GLint
+_slang_output_index(const char *name, GLenum target)
+{
+   const struct output_info *outputs;
+   GLuint i, n;
+
+   switch (target) {
+   case GL_VERTEX_PROGRAM_ARB:
+      outputs = vertOutputs;
+      n = Elements(vertOutputs);
+      break;
+   case GL_FRAGMENT_PROGRAM_ARB:
+      outputs = fragOutputs;
+      n = Elements(fragOutputs);
+      break;
+   case MESA_GEOMETRY_PROGRAM:
+      outputs = geomOutputs;
+      n = Elements(geomOutputs);
+      break;
+   default:
+      _mesa_problem(NULL, "bad target in _slang_output_index");
+      return -1;
+   }
+
+   for (i = 0; i < n; i++) {
+      if (strcmp(outputs[i].Name, name) == 0) {
+         /* found */
+         return outputs[i].Attrib;
+      }
+   }
+   return -1;
+}
+
+
+/**
+ * Given a VERT_RESULT_x index, return the corresponding string name.
+ */
+const char *
+_slang_vertex_output_name(gl_vert_result index)
+{
+   if (index < Elements(vertOutputs))
+      return vertOutputs[index].Name;
+   else
+      return NULL;
+}
+
+
+/**
+ * Given a GEOM_RESULT_x index, return the corresponding string name.
+ */
+const char *
+_slang_geometry_output_name(gl_geom_result index)
+{
+   if (index < Elements(geomOutputs))
+      return geomOutputs[index].Name;
+   else
+      return NULL;
+}
+
+
+/**
+ * Given a FRAG_RESULT_x index, return the corresponding string name.
+ */
+const char *
+_slang_fragment_output_name(gl_frag_result index)
+{
+   if (index < Elements(fragOutputs))
+      return fragOutputs[index].Name;
+   else
+      return NULL;
+}
+
+
+/**
+ * Given a VERT_RESULT_x index, return the corresponding varying
+ * var's datatype.
+ */
+GLenum
+_slang_vertex_output_type(gl_vert_result index)
+{
+   if (index < Elements(vertOutputs))
+      return vertOutputs[index].Type;
+   else
+      return GL_NONE;
+}
diff --git a/src/mesa/slang/slang_builtin.h b/src/mesa/slang/slang_builtin.h
new file mode 100644 (file)
index 0000000..ed9ae80
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.3
+ *
+ * Copyright (C) 2005-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.
+ */
+
+
+#ifndef SLANG_BUILTIN_H
+#define SLANG_BUILTIN_H
+
+#include "program/prog_parameter.h"
+#include "slang_utility.h"
+#include "slang_ir.h"
+
+
+extern GLint
+_slang_alloc_statevar(slang_ir_node *n,
+                      struct gl_program_parameter_list *paramList,
+                      GLboolean *direct);
+
+
+extern GLint
+_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut,
+                   GLboolean *is_array);
+
+extern GLint
+_slang_output_index(const char *name, GLenum target);
+
+
+extern const char *
+_slang_vert_attrib_name(GLuint attrib);
+
+extern GLenum
+_slang_vert_attrib_type(GLuint attrib);
+
+
+const char *
+_slang_vertex_output_name(gl_vert_result index);
+
+const char *
+_slang_fragment_output_name(gl_frag_result index);
+
+const char *
+_slang_geometry_output_name(gl_geom_result index);
+
+GLenum
+_slang_vertex_output_type(gl_vert_result index);
+
+
+#endif /* SLANG_BUILTIN_H */
diff --git a/src/mesa/slang/slang_codegen.c b/src/mesa/slang/slang_codegen.c
new file mode 100644 (file)
index 0000000..95787e4
--- /dev/null
@@ -0,0 +1,5410 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2005-2007  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2008 VMware, 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
+ * 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 slang_codegen.c
+ * Generate IR tree from AST.
+ * \author Brian Paul
+ */
+
+
+/***
+ *** NOTES:
+ *** The new_() functions return a new instance of a simple IR node.
+ *** The gen_() functions generate larger IR trees from the simple nodes.
+ ***/
+
+
+
+#include "main/imports.h"
+#include "main/macros.h"
+#include "main/mtypes.h"
+#include "program/program.h"
+#include "program/prog_instruction.h"
+#include "program/prog_parameter.h"
+#include "program/prog_print.h"
+#include "program/prog_statevars.h"
+#include "slang_typeinfo.h"
+#include "slang_builtin.h"
+#include "slang_codegen.h"
+#include "slang_compile.h"
+#include "slang_label.h"
+#include "slang_mem.h"
+#include "slang_simplify.h"
+#include "slang_emit.h"
+#include "slang_vartable.h"
+#include "slang_ir.h"
+#include "slang_print.h"
+
+
+/** Max iterations to unroll */
+const GLuint MAX_FOR_LOOP_UNROLL_ITERATIONS = 32;
+
+/** Max for-loop body size (in slang operations) to unroll */
+const GLuint MAX_FOR_LOOP_UNROLL_BODY_SIZE = 50;
+
+/** Max for-loop body complexity to unroll.
+ * We'll compute complexity as the product of the number of iterations
+ * and the size of the body.  So long-ish loops with very simple bodies
+ * can be unrolled, as well as short loops with larger bodies.
+ */
+const GLuint MAX_FOR_LOOP_UNROLL_COMPLEXITY = 256;
+
+
+
+static slang_ir_node *
+_slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper);
+
+static void
+slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
+                 GLuint substCount, slang_variable **substOld,
+                slang_operation **substNew, GLboolean isLHS);
+
+
+/**
+ * Retrieves type information about an operation.
+ * Returns GL_TRUE on success.
+ * Returns GL_FALSE otherwise.
+ */
+static GLboolean
+typeof_operation(const struct slang_assemble_ctx_ *A,
+                 slang_operation *op,
+                 slang_typeinfo *ti)
+{
+   return _slang_typeof_operation(op, &A->space, ti, A->atoms, A->log);
+}
+
+
+static GLboolean
+is_sampler_type(const slang_fully_specified_type *t)
+{
+   switch (t->specifier.type) {
+   case SLANG_SPEC_SAMPLER_1D:
+   case SLANG_SPEC_SAMPLER_2D:
+   case SLANG_SPEC_SAMPLER_3D:
+   case SLANG_SPEC_SAMPLER_CUBE:
+   case SLANG_SPEC_SAMPLER_1D_SHADOW:
+   case SLANG_SPEC_SAMPLER_2D_SHADOW:
+   case SLANG_SPEC_SAMPLER_RECT:
+   case SLANG_SPEC_SAMPLER_RECT_SHADOW:
+   case SLANG_SPEC_SAMPLER_1D_ARRAY:
+   case SLANG_SPEC_SAMPLER_2D_ARRAY:
+   case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW:
+   case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW:
+      return GL_TRUE;
+   default:
+      return GL_FALSE;
+   }
+}
+
+
+/**
+ * Return the offset (in floats or ints) of the named field within
+ * the given struct.  Return -1 if field not found.
+ * If field is NULL, return the size of the struct instead.
+ */
+static GLint
+_slang_field_offset(const slang_type_specifier *spec, slang_atom field)
+{
+   GLint offset = 0;
+   GLuint i;
+   for (i = 0; i < spec->_struct->fields->num_variables; i++) {
+      const slang_variable *v = spec->_struct->fields->variables[i];
+      const GLuint sz = _slang_sizeof_type_specifier(&v->type.specifier);
+      if (sz > 1) {
+         /* types larger than 1 float are register (4-float) aligned */
+         offset = (offset + 3) & ~3;
+      }
+      if (field && v->a_name == field) {
+         return offset;
+      }
+      offset += sz;
+   }
+   if (field)
+      return -1; /* field not found */
+   else
+      return offset;  /* struct size */
+}
+
+
+/**
+ * Return the size (in floats) of the given type specifier.
+ * If the size is greater than 4, the size should be a multiple of 4
+ * so that the correct number of 4-float registers are allocated.
+ * For example, a mat3x2 is size 12 because we want to store the
+ * 3 columns in 3 float[4] registers.
+ */
+GLuint
+_slang_sizeof_type_specifier(const slang_type_specifier *spec)
+{
+   GLuint sz;
+   switch (spec->type) {
+   case SLANG_SPEC_VOID:
+      sz = 0;
+      break;
+   case SLANG_SPEC_BOOL:
+      sz = 1;
+      break;
+   case SLANG_SPEC_BVEC2:
+      sz = 2;
+      break;
+   case SLANG_SPEC_BVEC3:
+      sz = 3;
+      break;
+   case SLANG_SPEC_BVEC4:
+      sz = 4;
+      break;
+   case SLANG_SPEC_INT:
+      sz = 1;
+      break;
+   case SLANG_SPEC_IVEC2:
+      sz = 2;
+      break;
+   case SLANG_SPEC_IVEC3:
+      sz = 3;
+      break;
+   case SLANG_SPEC_IVEC4:
+      sz = 4;
+      break;
+   case SLANG_SPEC_FLOAT:
+      sz = 1;
+      break;
+   case SLANG_SPEC_VEC2:
+      sz = 2;
+      break;
+   case SLANG_SPEC_VEC3:
+      sz = 3;
+      break;
+   case SLANG_SPEC_VEC4:
+      sz = 4;
+      break;
+   case SLANG_SPEC_MAT2:
+      sz = 2 * 4; /* 2 columns (regs) */
+      break;
+   case SLANG_SPEC_MAT3:
+      sz = 3 * 4;
+      break;
+   case SLANG_SPEC_MAT4:
+      sz = 4 * 4;
+      break;
+   case SLANG_SPEC_MAT23:
+      sz = 2 * 4; /* 2 columns (regs) */
+      break;
+   case SLANG_SPEC_MAT32:
+      sz = 3 * 4; /* 3 columns (regs) */
+      break;
+   case SLANG_SPEC_MAT24:
+      sz = 2 * 4;
+      break;
+   case SLANG_SPEC_MAT42:
+      sz = 4 * 4; /* 4 columns (regs) */
+      break;
+   case SLANG_SPEC_MAT34:
+      sz = 3 * 4;
+      break;
+   case SLANG_SPEC_MAT43:
+      sz = 4 * 4; /* 4 columns (regs) */
+      break;
+   case SLANG_SPEC_SAMPLER_1D:
+   case SLANG_SPEC_SAMPLER_2D:
+   case SLANG_SPEC_SAMPLER_3D:
+   case SLANG_SPEC_SAMPLER_CUBE:
+   case SLANG_SPEC_SAMPLER_1D_SHADOW:
+   case SLANG_SPEC_SAMPLER_2D_SHADOW:
+   case SLANG_SPEC_SAMPLER_RECT:
+   case SLANG_SPEC_SAMPLER_RECT_SHADOW:
+   case SLANG_SPEC_SAMPLER_1D_ARRAY:
+   case SLANG_SPEC_SAMPLER_2D_ARRAY:
+   case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW:
+   case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW:
+      sz = 1; /* a sampler is basically just an integer index */
+      break;
+   case SLANG_SPEC_STRUCT:
+      sz = _slang_field_offset(spec, 0); /* special use */
+      if (sz == 1) {
+         /* 1-float structs are actually troublesome to deal with since they
+          * might get placed at R.x, R.y, R.z or R.z.  Return size=2 to
+          * ensure the object is placed at R.x
+          */
+         sz = 2;
+      }
+      else if (sz > 4) {
+         sz = (sz + 3) & ~0x3; /* round up to multiple of four */
+      }
+      break;
+   case SLANG_SPEC_ARRAY:
+      sz = _slang_sizeof_type_specifier(spec->_array);
+      break;
+   default:
+      _mesa_problem(NULL, "Unexpected type in _slang_sizeof_type_specifier()");
+      sz = 0;
+   }
+
+   if (sz > 4) {
+      /* if size is > 4, it should be a multiple of four */
+      assert((sz & 0x3) == 0);
+   }
+   return sz;
+}
+
+
+/**
+ * Query variable/array length (number of elements).
+ * This is slightly non-trivial because there are two ways to express
+ * arrays: "float x[3]" vs. "float[3] x".
+ * \return the length of the array for the given variable, or 0 if not an array
+ */
+static GLint
+_slang_array_length(const slang_variable *var)
+{
+   if (var->type.array_len > 0) {
+      /* Ex: float[4] x; */
+      return var->type.array_len;
+   }
+   if (var->array_len > 0) {
+      /* Ex: float x[4]; */
+      return var->array_len;
+   }
+   return 0;
+}
+
+
+/**
+ * Compute total size of array give size of element, number of elements.
+ * \return size in floats
+ */
+static GLint
+_slang_array_size(GLint elemSize, GLint arrayLen)
+{
+   GLint total;
+   assert(elemSize > 0);
+   if (arrayLen > 1) {
+      /* round up base type to multiple of 4 */
+      total = ((elemSize + 3) & ~0x3) * MAX2(arrayLen, 1);
+   }
+   else {
+      total = elemSize;
+   }
+   return total;
+}
+
+
+/**
+ * Return the TEXTURE_*_INDEX value that corresponds to a sampler type,
+ * or -1 if the type is not a sampler.
+ */
+static GLint
+sampler_to_texture_index(const slang_type_specifier_type type)
+{
+   switch (type) {
+   case SLANG_SPEC_SAMPLER_1D:
+      return TEXTURE_1D_INDEX;
+   case SLANG_SPEC_SAMPLER_2D:
+      return TEXTURE_2D_INDEX;
+   case SLANG_SPEC_SAMPLER_3D:
+      return TEXTURE_3D_INDEX;
+   case SLANG_SPEC_SAMPLER_CUBE:
+      return TEXTURE_CUBE_INDEX;
+   case SLANG_SPEC_SAMPLER_1D_SHADOW:
+      return TEXTURE_1D_INDEX; /* XXX fix */
+   case SLANG_SPEC_SAMPLER_2D_SHADOW:
+      return TEXTURE_2D_INDEX; /* XXX fix */
+   case SLANG_SPEC_SAMPLER_RECT:
+      return TEXTURE_RECT_INDEX;
+   case SLANG_SPEC_SAMPLER_RECT_SHADOW:
+      return TEXTURE_RECT_INDEX; /* XXX fix */
+   case SLANG_SPEC_SAMPLER_1D_ARRAY:
+      return TEXTURE_1D_ARRAY_INDEX;
+   case SLANG_SPEC_SAMPLER_2D_ARRAY:
+      return TEXTURE_2D_ARRAY_INDEX;
+   case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW:
+      return TEXTURE_1D_ARRAY_INDEX;
+   case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW:
+      return TEXTURE_2D_ARRAY_INDEX;
+   default:
+      return -1;
+   }
+}
+
+
+/** helper to build a SLANG_OPER_IDENTIFIER node */
+static void
+slang_operation_identifier(slang_operation *oper,
+                           slang_assemble_ctx *A,
+                           const char *name)
+{
+   oper->type = SLANG_OPER_IDENTIFIER;
+   oper->a_id = slang_atom_pool_atom(A->atoms, name);
+}
+
+
+/**
+ * Called when we begin code/IR generation for a new while/do/for loop.
+ */
+static void
+push_loop(slang_assemble_ctx *A, slang_operation *loopOper, slang_ir_node *loopIR)
+{
+   A->LoopOperStack[A->LoopDepth] = loopOper;
+   A->LoopIRStack[A->LoopDepth] = loopIR;
+   A->LoopDepth++;
+}
+
+
+/**
+ * Called when we end code/IR generation for a new while/do/for loop.
+ */
+static void
+pop_loop(slang_assemble_ctx *A)
+{
+   assert(A->LoopDepth > 0);
+   A->LoopDepth--;
+}
+
+
+/**
+ * Return pointer to slang_operation for the loop we're currently inside,
+ * or NULL if not in a loop.
+ */
+static const slang_operation *
+current_loop_oper(const slang_assemble_ctx *A)
+{
+   if (A->LoopDepth > 0)
+      return A->LoopOperStack[A->LoopDepth - 1];
+   else
+      return NULL;
+}
+
+
+/**
+ * Return pointer to slang_ir_node for the loop we're currently inside,
+ * or NULL if not in a loop.
+ */
+static slang_ir_node *
+current_loop_ir(const slang_assemble_ctx *A)
+{
+   if (A->LoopDepth > 0)
+      return A->LoopIRStack[A->LoopDepth - 1];
+   else
+      return NULL;
+}
+
+
+/**********************************************************************/
+
+
+/**
+ * Map "_asm foo" to IR_FOO, etc.
+ */
+typedef struct
+{
+   const char *Name;
+   slang_ir_opcode Opcode;
+   GLuint HaveRetValue, NumParams;
+} slang_asm_info;
+
+
+static slang_asm_info AsmInfo[] = {
+   /* vec4 binary op */
+   { "vec4_add", IR_ADD, 1, 2 },
+   { "vec4_subtract", IR_SUB, 1, 2 },
+   { "vec4_multiply", IR_MUL, 1, 2 },
+   { "vec4_dot", IR_DOT4, 1, 2 },
+   { "vec3_dot", IR_DOT3, 1, 2 },
+   { "vec2_dot", IR_DOT2, 1, 2 },
+   { "vec3_nrm", IR_NRM3, 1, 1 },
+   { "vec4_nrm", IR_NRM4, 1, 1 },
+   { "vec3_cross", IR_CROSS, 1, 2 },
+   { "vec4_lrp", IR_LRP, 1, 3 },
+   { "vec4_min", IR_MIN, 1, 2 },
+   { "vec4_max", IR_MAX, 1, 2 },
+   { "vec4_cmp", IR_CMP, 1, 3 },
+   { "vec4_clamp", IR_CLAMP, 1, 3 },
+   { "vec4_seq", IR_SEQUAL, 1, 2 },
+   { "vec4_sne", IR_SNEQUAL, 1, 2 },
+   { "vec4_sge", IR_SGE, 1, 2 },
+   { "vec4_sgt", IR_SGT, 1, 2 },
+   { "vec4_sle", IR_SLE, 1, 2 },
+   { "vec4_slt", IR_SLT, 1, 2 },
+   /* vec4 unary */
+   { "vec4_move", IR_MOVE, 1, 1 },
+   { "vec4_floor", IR_FLOOR, 1, 1 },
+   { "vec4_frac", IR_FRAC, 1, 1 },
+   { "vec4_abs", IR_ABS, 1, 1 },
+   { "vec4_negate", IR_NEG, 1, 1 },
+   { "vec4_ddx", IR_DDX, 1, 1 },
+   { "vec4_ddy", IR_DDY, 1, 1 },
+   /* float binary op */
+   { "float_power", IR_POW, 1, 2 },
+   /* texture / sampler */
+   { "vec4_tex_1d", IR_TEX, 1, 2 },
+   { "vec4_tex_1d_bias", IR_TEXB, 1, 2 },  /* 1d w/ bias */
+   { "vec4_tex_1d_proj", IR_TEXP, 1, 2 },  /* 1d w/ projection */
+   { "vec4_tex_2d", IR_TEX, 1, 2 },
+   { "vec4_tex_2d_bias", IR_TEXB, 1, 2 },  /* 2d w/ bias */
+   { "vec4_tex_2d_proj", IR_TEXP, 1, 2 },  /* 2d w/ projection */
+   { "vec4_tex_3d", IR_TEX, 1, 2 },
+   { "vec4_tex_3d_bias", IR_TEXB, 1, 2 },  /* 3d w/ bias */
+   { "vec4_tex_3d_proj", IR_TEXP, 1, 2 },  /* 3d w/ projection */
+   { "vec4_tex_cube", IR_TEX, 1, 2 },      /* cubemap */
+   { "vec4_tex_rect", IR_TEX, 1, 2 },      /* rectangle */
+   { "vec4_tex_rect_bias", IR_TEX, 1, 2 }, /* rectangle w/ projection */
+   { "vec4_tex_1d_array", IR_TEX, 1, 2 },
+   { "vec4_tex_1d_array_bias", IR_TEXB, 1, 2 },
+   { "vec4_tex_1d_array_shadow", IR_TEX, 1, 2 },
+   { "vec4_tex_1d_array_bias_shadow", IR_TEXB, 1, 2 },
+   { "vec4_tex_2d_array", IR_TEX, 1, 2 },
+   { "vec4_tex_2d_array_bias", IR_TEXB, 1, 2 },
+   { "vec4_tex_2d_array_shadow", IR_TEX, 1, 2 },
+   { "vec4_tex_2d_array_bias_shadow", IR_TEXB, 1, 2 },
+
+   /* texture / sampler but with shadow comparison */
+   { "vec4_tex_1d_shadow", IR_TEX_SH, 1, 2 },
+   { "vec4_tex_1d_bias_shadow", IR_TEXB_SH, 1, 2 },
+   { "vec4_tex_1d_proj_shadow", IR_TEXP_SH, 1, 2 },
+   { "vec4_tex_2d_shadow", IR_TEX_SH, 1, 2 },
+   { "vec4_tex_2d_bias_shadow", IR_TEXB_SH, 1, 2 },
+   { "vec4_tex_2d_proj_shadow", IR_TEXP_SH, 1, 2 },
+   { "vec4_tex_rect_shadow", IR_TEX_SH, 1, 2 },
+   { "vec4_tex_rect_proj_shadow", IR_TEXP_SH, 1, 2 },
+
+   /* unary op */
+   { "ivec4_to_vec4", IR_I_TO_F, 1, 1 }, /* int[4] to float[4] */
+   { "vec4_to_ivec4", IR_F_TO_I, 1, 1 },  /* float[4] to int[4] */
+   { "float_exp", IR_EXP, 1, 1 },
+   { "float_exp2", IR_EXP2, 1, 1 },
+   { "float_log2", IR_LOG2, 1, 1 },
+   { "float_rsq", IR_RSQ, 1, 1 },
+   { "float_rcp", IR_RCP, 1, 1 },
+   { "float_sine", IR_SIN, 1, 1 },
+   { "float_cosine", IR_COS, 1, 1 },
+   { "float_noise1", IR_NOISE1, 1, 1},
+   { "float_noise2", IR_NOISE2, 1, 1},
+   { "float_noise3", IR_NOISE3, 1, 1},
+   { "float_noise4", IR_NOISE4, 1, 1},
+
+   { "emit_vertex", IR_EMIT_VERTEX, 0, 0},
+   { "end_primitive", IR_END_PRIMITIVE, 0, 0},
+
+   { NULL, IR_NOP, 0, 0 }
+};
+
+
+static slang_ir_node *
+new_node3(slang_ir_opcode op,
+          slang_ir_node *c0, slang_ir_node *c1, slang_ir_node *c2)
+{
+   slang_ir_node *n = (slang_ir_node *) _slang_alloc(sizeof(slang_ir_node));
+   if (n) {
+      n->Opcode = op;
+      n->Children[0] = c0;
+      n->Children[1] = c1;
+      n->Children[2] = c2;
+      n->InstLocation = -1;
+   }
+   return n;
+}
+
+static slang_ir_node *
+new_node2(slang_ir_opcode op, slang_ir_node *c0, slang_ir_node *c1)
+{
+   return new_node3(op, c0, c1, NULL);
+}
+
+static slang_ir_node *
+new_node1(slang_ir_opcode op, slang_ir_node *c0)
+{
+   return new_node3(op, c0, NULL, NULL);
+}
+
+static slang_ir_node *
+new_node0(slang_ir_opcode op)
+{
+   return new_node3(op, NULL, NULL, NULL);
+}
+
+
+/**
+ * Create sequence of two nodes.
+ */
+static slang_ir_node *
+new_seq(slang_ir_node *left, slang_ir_node *right)
+{
+   if (!left)
+      return right;
+   if (!right)
+      return left;
+   return new_node2(IR_SEQ, left, right);
+}
+
+static slang_ir_node *
+new_label(slang_label *label)
+{
+   slang_ir_node *n = new_node0(IR_LABEL);
+   assert(label);
+   if (n)
+      n->Label = label;
+   return n;
+}
+
+static slang_ir_node *
+new_float_literal(const float v[4], GLuint size)
+{
+   slang_ir_node *n = new_node0(IR_FLOAT);
+   assert(size <= 4);
+   COPY_4V(n->Value, v);
+   /* allocate a storage object, but compute actual location (Index) later */
+   n->Store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, size);
+   return n;
+}
+
+
+static slang_ir_node *
+new_not(slang_ir_node *n)
+{
+   return new_node1(IR_NOT, n);
+}
+
+
+/**
+ * Non-inlined function call.
+ */
+static slang_ir_node *
+new_function_call(slang_ir_node *code, slang_label *name)
+{
+   slang_ir_node *n = new_node1(IR_CALL, code);
+   assert(name);
+   if (n)
+      n->Label = name;
+   return n;
+}
+
+
+/**
+ * Unconditional jump.
+ */
+static slang_ir_node *
+new_return(slang_label *dest)
+{
+   slang_ir_node *n = new_node0(IR_RETURN);
+   assert(dest);
+   if (n)
+      n->Label = dest;
+   return n;
+}
+
+
+static slang_ir_node *
+new_loop(slang_ir_node *body)
+{
+   return new_node1(IR_LOOP, body);
+}
+
+
+static slang_ir_node *
+new_break(slang_ir_node *loopNode)
+{
+   slang_ir_node *n = new_node0(IR_BREAK);
+   assert(loopNode);
+   assert(loopNode->Opcode == IR_LOOP);
+   if (n) {
+      /* insert this node at head of linked list of cont/break instructions */
+      n->List = loopNode->List;
+      loopNode->List = n;
+   }
+   return n;
+}
+
+
+/**
+ * Make new IR_BREAK_IF_TRUE.
+ */
+static slang_ir_node *
+new_break_if_true(slang_assemble_ctx *A, slang_ir_node *cond)
+{
+   slang_ir_node *loopNode = current_loop_ir(A);
+   slang_ir_node *n;
+   assert(loopNode);
+   assert(loopNode->Opcode == IR_LOOP);
+   n = new_node1(IR_BREAK_IF_TRUE, cond);
+   if (n) {
+      /* insert this node at head of linked list of cont/break instructions */
+      n->List = loopNode->List;
+      loopNode->List = n;
+   }
+   return n;
+}
+
+
+/**
+ * Make new IR_CONT_IF_TRUE node.
+ */
+static slang_ir_node *
+new_cont_if_true(slang_assemble_ctx *A, slang_ir_node *cond)
+{
+   slang_ir_node *loopNode = current_loop_ir(A);
+   slang_ir_node *n;
+   assert(loopNode);
+   assert(loopNode->Opcode == IR_LOOP);
+   n = new_node1(IR_CONT_IF_TRUE, cond);
+   if (n) {
+      n->Parent = loopNode; /* pointer to containing loop */
+      /* insert this node at head of linked list of cont/break instructions */
+      n->List = loopNode->List;
+      loopNode->List = n;
+   }
+   return n;
+}
+
+
+static slang_ir_node *
+new_cond(slang_ir_node *n)
+{
+   slang_ir_node *c = new_node1(IR_COND, n);
+   return c;
+}
+
+
+static slang_ir_node *
+new_if(slang_ir_node *cond, slang_ir_node *ifPart, slang_ir_node *elsePart)
+{
+   return new_node3(IR_IF, cond, ifPart, elsePart);
+}
+
+
+/**
+ * New IR_VAR node - a reference to a previously declared variable.
+ */
+static slang_ir_node *
+new_var(slang_assemble_ctx *A, slang_variable *var)
+{
+   slang_ir_node *n = new_node0(IR_VAR);
+   if (n) {
+      ASSERT(var);
+      ASSERT(var->store);
+      ASSERT(!n->Store);
+      ASSERT(!n->Var);
+
+      /* Set IR node's Var and Store pointers */
+      n->Var = var;
+      n->Store = var->store;
+   }
+   return n;
+}
+
+
+/**
+ * Check if the given function is really just a wrapper for a
+ * basic assembly instruction.
+ */
+static GLboolean
+slang_is_asm_function(const slang_function *fun)
+{
+   if (fun->body->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE &&
+       fun->body->num_children == 1 &&
+       fun->body->children[0].type == SLANG_OPER_ASM) {
+      return GL_TRUE;
+   }
+   return GL_FALSE;
+}
+
+
+static GLboolean
+_slang_is_noop(const slang_operation *oper)
+{
+   if (!oper ||
+       oper->type == SLANG_OPER_VOID ||
+       (oper->num_children == 1 && oper->children[0].type == SLANG_OPER_VOID))
+      return GL_TRUE;
+   else
+      return GL_FALSE;
+}
+
+
+/**
+ * Recursively search tree for a node of the given type.
+ */
+#if 0
+static slang_operation *
+_slang_find_node_type(slang_operation *oper, slang_operation_type type)
+{
+   GLuint i;
+   if (oper->type == type)
+      return oper;
+   for (i = 0; i < oper->num_children; i++) {
+      slang_operation *p = _slang_find_node_type(&oper->children[i], type);
+      if (p)
+         return p;
+   }
+   return NULL;
+}
+#endif
+
+
+/**
+ * Count the number of operations of the given time rooted at 'oper'.
+ */
+static GLuint
+_slang_count_node_type(const slang_operation *oper, slang_operation_type type)
+{
+   GLuint i, count = 0;
+   if (oper->type == type) {
+      return 1;
+   }
+   for (i = 0; i < oper->num_children; i++) {
+      count += _slang_count_node_type(&oper->children[i], type);
+   }
+   return count;
+}
+
+
+/**
+ * Check if the 'return' statement found under 'oper' is a "tail return"
+ * that can be no-op'd.  For example:
+ *
+ * void func(void)
+ * {
+ *    .. do something ..
+ *    return;   // this is a no-op
+ * }
+ *
+ * This is used when determining if a function can be inlined.  If the
+ * 'return' is not the last statement, we can't inline the function since
+ * we still need the semantic behaviour of the 'return' but we don't want
+ * to accidentally return from the _calling_ function.  We'd need to use an
+ * unconditional branch, but we don't have such a GPU instruction (not
+ * always, at least).
+ */
+static GLboolean
+_slang_is_tail_return(const slang_operation *oper)
+{
+   GLuint k = oper->num_children;
+
+   while (k > 0) {
+      const slang_operation *last = &oper->children[k - 1];
+      if (last->type == SLANG_OPER_RETURN)
+         return GL_TRUE;
+      else if (last->type == SLANG_OPER_IDENTIFIER ||
+               last->type == SLANG_OPER_LABEL)
+         k--; /* try prev child */
+      else if (last->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE ||
+               last->type == SLANG_OPER_BLOCK_NEW_SCOPE)
+         /* try sub-children */
+         return _slang_is_tail_return(last);
+      else
+         break;
+   }
+
+   return GL_FALSE;
+}
+
+
+/**
+ * Generate a variable declaration opeartion.
+ * I.e.: generate AST code for "bool flag = false;"
+ */
+static void
+slang_generate_declaration(slang_assemble_ctx *A,
+                           slang_variable_scope *scope,
+                           slang_operation *decl,
+                           slang_type_specifier_type type,
+                           const char *name,
+                           GLint initValue)
+{
+   slang_variable *var;
+
+   assert(type == SLANG_SPEC_BOOL ||
+          type == SLANG_SPEC_INT);
+
+   decl->type = SLANG_OPER_VARIABLE_DECL;
+
+   var = slang_variable_scope_grow(scope);
+
+   slang_fully_specified_type_construct(&var->type);
+
+   var->type.specifier.type = type;
+   var->a_name = slang_atom_pool_atom(A->atoms, name);
+   decl->a_id = var->a_name;
+   var->initializer = slang_operation_new(1);
+   slang_operation_literal_bool(var->initializer, initValue);
+}
+
+
+static void
+slang_resolve_variable(slang_operation *oper)
+{
+   if (oper->type == SLANG_OPER_IDENTIFIER && !oper->var) {
+      oper->var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE);
+   }
+}
+
+
+/**
+ * Rewrite AST code for "return expression;".
+ *
+ * We return values from functions by assinging the returned value to
+ * the hidden __retVal variable which is an extra 'out' parameter we add
+ * to the function signature.
+ * This code basically converts "return expr;" into "__retVal = expr; return;"
+ *
+ * \return the new AST code.
+ */
+static slang_operation *
+gen_return_with_expression(slang_assemble_ctx *A, slang_operation *oper)
+{
+   slang_operation *blockOper, *assignOper;
+
+   assert(oper->type == SLANG_OPER_RETURN);
+
+   if (A->CurFunction->header.type.specifier.type == SLANG_SPEC_VOID) {
+      slang_info_log_error(A->log, "illegal return expression");
+      return NULL;
+   }
+
+   blockOper = slang_operation_new(1);
+   blockOper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
+   blockOper->locals->outer_scope = oper->locals->outer_scope;
+   slang_operation_add_children(blockOper, 2);
+
+   if (A->UseReturnFlag) {
+      /* Emit:
+       *    {
+       *       if (__notRetFlag)
+       *          __retVal = expr;
+       *       __notRetFlag = 0;
+       *    }
+       */
+      {
+         slang_operation *ifOper = slang_oper_child(blockOper, 0);
+         ifOper->type = SLANG_OPER_IF;
+         slang_operation_add_children(ifOper, 3);
+         {
+            slang_operation *cond = slang_oper_child(ifOper, 0);
+            cond->type = SLANG_OPER_IDENTIFIER;
+            cond->a_id = slang_atom_pool_atom(A->atoms, "__notRetFlag");
+         }
+         {
+            slang_operation *elseOper = slang_oper_child(ifOper, 2);
+            elseOper->type = SLANG_OPER_VOID;
+         }
+         assignOper = slang_oper_child(ifOper, 1);
+      }
+      {
+         slang_operation *setOper = slang_oper_child(blockOper, 1);
+         setOper->type = SLANG_OPER_ASSIGN;
+         slang_operation_add_children(setOper, 2);
+         {
+            slang_operation *lhs = slang_oper_child(setOper, 0);
+            lhs->type = SLANG_OPER_IDENTIFIER;
+            lhs->a_id = slang_atom_pool_atom(A->atoms, "__notRetFlag");
+         }
+         {
+            slang_operation *rhs = slang_oper_child(setOper, 1);
+            slang_operation_literal_bool(rhs, GL_FALSE);
+         }
+      }
+   }
+   else {
+      /* Emit:
+       *    {
+       *       __retVal = expr;
+       *       return_inlined;
+       *    }
+       */
+      assignOper = slang_oper_child(blockOper, 0);
+      {
+         slang_operation *returnOper = slang_oper_child(blockOper, 1);
+         returnOper->type = SLANG_OPER_RETURN_INLINED;
+         assert(returnOper->num_children == 0);
+      }
+   }
+
+   /* __retVal = expression; */
+   assignOper->type = SLANG_OPER_ASSIGN;
+   slang_operation_add_children(assignOper, 2);
+   {
+      slang_operation *lhs = slang_oper_child(assignOper, 0);
+      lhs->type = SLANG_OPER_IDENTIFIER;
+      lhs->a_id = slang_atom_pool_atom(A->atoms, "__retVal");
+   }
+   {
+      slang_operation *rhs = slang_oper_child(assignOper, 1);
+      slang_operation_copy(rhs, &oper->children[0]);
+   }
+
+   /*blockOper->locals->outer_scope = oper->locals->outer_scope;*/
+
+   /*slang_print_tree(blockOper, 0);*/
+
+   return blockOper;
+}
+
+
+/**
+ * Rewrite AST code for "return;" (no expression).
+ */
+static slang_operation *
+gen_return_without_expression(slang_assemble_ctx *A, slang_operation *oper)
+{
+   slang_operation *newRet;
+
+   assert(oper->type == SLANG_OPER_RETURN);
+
+   if (A->CurFunction->header.type.specifier.type != SLANG_SPEC_VOID) {
+      slang_info_log_error(A->log, "return statement requires an expression");
+      return NULL;
+   }
+
+   if (A->UseReturnFlag) {
+      /* Emit:
+       *    __notRetFlag = 0;
+       */
+      {
+         newRet = slang_operation_new(1);
+         newRet->locals->outer_scope = oper->locals->outer_scope;
+         newRet->type = SLANG_OPER_ASSIGN;
+         slang_operation_add_children(newRet, 2);
+         {
+            slang_operation *lhs = slang_oper_child(newRet, 0);
+            lhs->type = SLANG_OPER_IDENTIFIER;
+            lhs->a_id = slang_atom_pool_atom(A->atoms, "__notRetFlag");
+         }
+         {
+            slang_operation *rhs = slang_oper_child(newRet, 1);
+            slang_operation_literal_bool(rhs, GL_FALSE);
+         }
+      }
+   }
+   else {
+      /* Emit:
+       *    return_inlined;
+       */
+      newRet = slang_operation_new(1);
+      newRet->locals->outer_scope = oper->locals->outer_scope;
+      newRet->type = SLANG_OPER_RETURN_INLINED;
+   }
+
+   /*slang_print_tree(newRet, 0);*/
+
+   return newRet;
+}
+
+
+
+
+/**
+ * Replace particular variables (SLANG_OPER_IDENTIFIER) with new expressions.
+ */
+static void
+slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
+                 GLuint substCount, slang_variable **substOld,
+                slang_operation **substNew, GLboolean isLHS)
+{
+   switch (oper->type) {
+   case SLANG_OPER_VARIABLE_DECL:
+      {
+         slang_variable *v = _slang_variable_locate(oper->locals,
+                                                    oper->a_id, GL_TRUE);
+         assert(v);
+         if (v->initializer && oper->num_children == 0) {
+            /* set child of oper to copy of initializer */
+            oper->num_children = 1;
+            oper->children = slang_operation_new(1);
+            slang_operation_copy(&oper->children[0], v->initializer);
+         }
+         if (oper->num_children == 1) {
+            /* the initializer */
+            slang_substitute(A, &oper->children[0], substCount,
+                             substOld, substNew, GL_FALSE);
+         }
+      }
+      break;
+   case SLANG_OPER_IDENTIFIER:
+      assert(oper->num_children == 0);
+      if (1/**!isLHS XXX FIX */) {
+         slang_atom id = oper->a_id;
+         slang_variable *v;
+        GLuint i;
+         v = _slang_variable_locate(oper->locals, id, GL_TRUE);
+        if (!v) {
+#if 0
+            if (strcmp((char *) oper->a_id, "__notRetFlag"))
+               _mesa_problem(NULL, "var %s not found!\n", (char *) oper->a_id);
+#endif
+            return;
+        }
+
+        /* look for a substitution */
+        for (i = 0; i < substCount; i++) {
+           if (v == substOld[i]) {
+               /* OK, replace this SLANG_OPER_IDENTIFIER with a new expr */
+#if 0 /* DEBUG only */
+              if (substNew[i]->type == SLANG_OPER_IDENTIFIER) {
+                  assert(substNew[i]->var);
+                  assert(substNew[i]->var->a_name);
+                 printf("Substitute %s with %s in id node %p\n",
+                        (char*)v->a_name, (char*) substNew[i]->var->a_name,
+                        (void*) oper);
+               }
+              else {
+                 printf("Substitute %s with %f in id node %p\n",
+                        (char*)v->a_name, substNew[i]->literal[0],
+                        (void*) oper);
+               }
+#endif
+              slang_operation_copy(oper, substNew[i]);
+              break;
+           }
+        }
+      }
+      break;
+
+   case SLANG_OPER_RETURN:
+      {
+         slang_operation *newReturn;
+         /* generate new 'return' code' */
+         if (slang_oper_child(oper, 0)->type == SLANG_OPER_VOID)
+            newReturn = gen_return_without_expression(A, oper);
+         else
+            newReturn = gen_return_with_expression(A, oper);
+
+         if (!newReturn)
+            return;
+
+         /* do substitutions on the new 'return' code */
+         slang_substitute(A, newReturn,
+                          substCount, substOld, substNew, GL_FALSE);
+
+         /* install new 'return' code */
+         slang_operation_copy(oper, newReturn);
+         slang_operation_destruct(newReturn);
+      }
+      break;
+
+   case SLANG_OPER_ASSIGN:
+   case SLANG_OPER_SUBSCRIPT:
+      /* special case:
+       * child[0] can't have substitutions but child[1] can.
+       */
+      slang_substitute(A, &oper->children[0],
+                       substCount, substOld, substNew, GL_TRUE);
+      slang_substitute(A, &oper->children[1],
+                       substCount, substOld, substNew, GL_FALSE);
+      break;
+   case SLANG_OPER_FIELD:
+      /* XXX NEW - test */
+      slang_substitute(A, &oper->children[0],
+                       substCount, substOld, substNew, GL_TRUE);
+      break;
+   default:
+      {
+         GLuint i;
+         for (i = 0; i < oper->num_children; i++) 
+            slang_substitute(A, &oper->children[i],
+                             substCount, substOld, substNew, GL_FALSE);
+      }
+   }
+}
+
+
+/**
+ * Produce inline code for a call to an assembly instruction.
+ * This is typically used to compile a call to a built-in function like this:
+ *
+ * vec4 mix(const vec4 x, const vec4 y, const vec4 a)
+ * {
+ *    __asm vec4_lrp __retVal, a, y, x;
+ * }
+ *
+ *
+ * A call to
+ *     r = mix(p1, p2, p3);
+ *
+ * Becomes:
+ *
+ *              mov
+ *             /   \
+ *            r   vec4_lrp
+ *                 /  |  \
+ *                p3  p2  p1
+ *
+ * We basically translate a SLANG_OPER_CALL into a SLANG_OPER_ASM.
+ */
+static slang_operation *
+slang_inline_asm_function(slang_assemble_ctx *A,
+                          slang_function *fun, slang_operation *oper)
+{
+   const GLuint numArgs = oper->num_children;
+   GLuint i;
+   slang_operation *inlined;
+   const GLboolean haveRetValue = _slang_function_has_return_value(fun);
+   slang_variable **substOld;
+   slang_operation **substNew;
+
+   ASSERT(slang_is_asm_function(fun));
+   ASSERT(fun->param_count == numArgs + haveRetValue);
+
+   /*
+   printf("Inline %s as %s\n",
+          (char*) fun->header.a_name,
+          (char*) fun->body->children[0].a_id);
+   */
+
+   /*
+    * We'll substitute formal params with actual args in the asm call.
+    */
+   substOld = (slang_variable **)
+      _slang_alloc(numArgs * sizeof(slang_variable *));
+   substNew = (slang_operation **)
+      _slang_alloc(numArgs * sizeof(slang_operation *));
+   for (i = 0; i < numArgs; i++) {
+      substOld[i] = fun->parameters->variables[i];
+      substNew[i] = oper->children + i;
+   }
+
+   /* make a copy of the code to inline */
+   inlined = slang_operation_new(1);
+   slang_operation_copy(inlined, &fun->body->children[0]);
+   if (haveRetValue) {
+      /* get rid of the __retVal child */
+      inlined->num_children--;
+      for (i = 0; i < inlined->num_children; i++) {
+         inlined->children[i] = inlined->children[i + 1];
+      }
+   }
+
+   /* now do formal->actual substitutions */
+   slang_substitute(A, inlined, numArgs, substOld, substNew, GL_FALSE);
+
+   _slang_free(substOld);
+   _slang_free(substNew);
+
+#if 0
+   printf("+++++++++++++ inlined asm function %s +++++++++++++\n",
+          (char *) fun->header.a_name);
+   slang_print_tree(inlined, 3);
+   printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+#endif
+
+   return inlined;
+}
+
+
+/**
+ * Inline the given function call operation.
+ * Return a new slang_operation that corresponds to the inlined code.
+ */
+static slang_operation *
+slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
+                          slang_operation *oper, slang_operation *returnOper)
+{
+   typedef enum {
+      SUBST = 1,
+      COPY_IN,
+      COPY_OUT
+   } ParamMode;
+   ParamMode *paramMode;
+   const GLboolean haveRetValue = _slang_function_has_return_value(fun);
+   const GLuint numArgs = oper->num_children;
+   const GLuint totalArgs = numArgs + haveRetValue;
+   slang_operation *args = oper->children;
+   slang_operation *inlined, *top;
+   slang_variable **substOld;
+   slang_operation **substNew;
+   GLuint substCount, numCopyIn, i;
+   slang_function *prevFunction;
+   slang_variable_scope *newScope = NULL;
+
+   /* save / push */
+   prevFunction = A->CurFunction;
+   A->CurFunction = fun;
+
+   /*assert(oper->type == SLANG_OPER_CALL); (or (matrix) multiply, etc) */
+   assert(fun->param_count == totalArgs);
+
+   /* allocate temporary arrays */
+   paramMode = (ParamMode *)
+      _slang_alloc(totalArgs * sizeof(ParamMode));
+   substOld = (slang_variable **)
+      _slang_alloc(totalArgs * sizeof(slang_variable *));
+   substNew = (slang_operation **)
+      _slang_alloc(totalArgs * sizeof(slang_operation *));
+
+#if 0
+   printf("\nInline call to %s  (total vars=%d  nparams=%d)\n",
+         (char *) fun->header.a_name,
+         fun->parameters->num_variables, numArgs);
+#endif
+
+   if (haveRetValue && !returnOper) {
+      /* Create 3-child comma sequence for inlined code:
+       * child[0]:  declare __resultTmp
+       * child[1]:  inlined function body
+       * child[2]:  __resultTmp
+       */
+      slang_operation *commaSeq;
+      slang_operation *declOper = NULL;
+      slang_variable *resultVar;
+
+      commaSeq = slang_operation_new(1);
+      commaSeq->type = SLANG_OPER_SEQUENCE;
+      assert(commaSeq->locals);
+      commaSeq->locals->outer_scope = oper->locals->outer_scope;
+      commaSeq->num_children = 3;
+      commaSeq->children = slang_operation_new(3);
+      /* allocate the return var */
+      resultVar = slang_variable_scope_grow(commaSeq->locals);
+      /*
+      printf("Alloc __resultTmp in scope %p for retval of calling %s\n",
+             (void*)commaSeq->locals, (char *) fun->header.a_name);
+      */
+
+      resultVar->a_name = slang_atom_pool_atom(A->atoms, "__resultTmp");
+      resultVar->type = fun->header.type; /* XXX copy? */
+      resultVar->isTemp = GL_TRUE;
+
+      /* child[0] = __resultTmp declaration */
+      declOper = &commaSeq->children[0];
+      declOper->type = SLANG_OPER_VARIABLE_DECL;
+      declOper->a_id = resultVar->a_name;
+      declOper->locals->outer_scope = commaSeq->locals;
+
+      /* child[1] = function body */
+      inlined = &commaSeq->children[1];
+      inlined->locals->outer_scope = commaSeq->locals;
+
+      /* child[2] = __resultTmp reference */
+      returnOper = &commaSeq->children[2];
+      returnOper->type = SLANG_OPER_IDENTIFIER;
+      returnOper->a_id = resultVar->a_name;
+      returnOper->locals->outer_scope = commaSeq->locals;
+
+      top = commaSeq;
+   }
+   else {
+      top = inlined = slang_operation_new(1);
+      /* XXXX this may be inappropriate!!!! */
+      inlined->locals->outer_scope = oper->locals->outer_scope;
+   }
+
+
+   assert(inlined->locals);
+
+   /* Examine the parameters, look for inout/out params, look for possible
+    * substitutions, etc:
+    *    param type      behaviour
+    *     in             copy actual to local
+    *     const in       substitute param with actual
+    *     out            copy out
+    */
+   substCount = 0;
+   for (i = 0; i < totalArgs; i++) {
+      slang_variable *p = fun->parameters->variables[i];
+      /*
+      printf("Param %d: %s %s \n", i,
+             slang_type_qual_string(p->type.qualifier),
+            (char *) p->a_name);
+      */
+      if (p->type.qualifier == SLANG_QUAL_INOUT ||
+         p->type.qualifier == SLANG_QUAL_OUT) {
+        /* an output param */
+         slang_operation *arg;
+         if (i < numArgs)
+            arg = &args[i];
+         else
+            arg = returnOper;
+        paramMode[i] = SUBST;
+
+        if (arg->type == SLANG_OPER_IDENTIFIER)
+            slang_resolve_variable(arg);
+
+         /* replace parameter 'p' with argument 'arg' */
+        substOld[substCount] = p;
+        substNew[substCount] = arg; /* will get copied */
+        substCount++;
+      }
+      else if (p->type.qualifier == SLANG_QUAL_CONST) {
+        /* a constant input param */
+         if (args[i].type == SLANG_OPER_IDENTIFIER ||
+             args[i].type == SLANG_OPER_LITERAL_FLOAT ||
+             args[i].type == SLANG_OPER_SUBSCRIPT) {
+           /* replace all occurances of this parameter variable with the
+            * actual argument variable or a literal.
+            */
+           paramMode[i] = SUBST;
+            slang_resolve_variable(&args[i]);
+           substOld[substCount] = p;
+           substNew[substCount] = &args[i]; /* will get copied */
+           substCount++;
+        }
+        else {
+           paramMode[i] = COPY_IN;
+        }
+      }
+      else {
+        paramMode[i] = COPY_IN;
+      }
+      assert(paramMode[i]);
+   }
+
+   /* actual code inlining: */
+   slang_operation_copy(inlined, fun->body);
+
+   /*** XXX review this */
+   assert(inlined->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE ||
+          inlined->type == SLANG_OPER_BLOCK_NEW_SCOPE);
+   inlined->type = SLANG_OPER_BLOCK_NEW_SCOPE;
+
+#if 0
+   printf("======================= orig body code ======================\n");
+   printf("=== params scope = %p\n", (void*) fun->parameters);
+   slang_print_tree(fun->body, 8);
+   printf("======================= copied code =========================\n");
+   slang_print_tree(inlined, 8);
+#endif
+
+   /* do parameter substitution in inlined code: */
+   slang_substitute(A, inlined, substCount, substOld, substNew, GL_FALSE);
+
+#if 0
+   printf("======================= subst code ==========================\n");
+   slang_print_tree(inlined, 8);
+   printf("=============================================================\n");
+#endif
+
+   /* New prolog statements: (inserted before the inlined code)
+    * Copy the 'in' arguments.
+    */
+   numCopyIn = 0;
+   for (i = 0; i < numArgs; i++) {
+      if (paramMode[i] == COPY_IN) {
+        slang_variable *p = fun->parameters->variables[i];
+        /* declare parameter 'p' */
+        slang_operation *decl = slang_operation_insert(&inlined->num_children,
+                                                       &inlined->children,
+                                                       numCopyIn);
+
+        decl->type = SLANG_OPER_VARIABLE_DECL;
+         assert(decl->locals);
+         decl->locals->outer_scope = inlined->locals;
+        decl->a_id = p->a_name;
+        decl->num_children = 1;
+        decl->children = slang_operation_new(1);
+
+         /* child[0] is the var's initializer */
+         slang_operation_copy(&decl->children[0], args + i);
+
+         /* add parameter 'p' to the local variable scope here */
+         {
+            slang_variable *pCopy = slang_variable_scope_grow(inlined->locals);
+            pCopy->type = p->type;
+            pCopy->a_name = p->a_name;
+            pCopy->array_len = p->array_len;
+         }
+
+         newScope = inlined->locals;
+        numCopyIn++;
+      }
+   }
+
+   /* Now add copies of the function's local vars to the new variable scope */
+   for (i = totalArgs; i < fun->parameters->num_variables; i++) {
+      slang_variable *p = fun->parameters->variables[i];
+      slang_variable *pCopy = slang_variable_scope_grow(inlined->locals);
+      pCopy->type = p->type;
+      pCopy->a_name = p->a_name;
+      pCopy->array_len = p->array_len;
+   }
+
+
+   /* New epilog statements:
+    * 1. Create end of function label to jump to from return statements.
+    * 2. Copy the 'out' parameter vars
+    */
+   {
+      slang_operation *lab = slang_operation_insert(&inlined->num_children,
+                                                    &inlined->children,
+                                                    inlined->num_children);
+      lab->type = SLANG_OPER_LABEL;
+      lab->label = A->curFuncEndLabel;
+   }
+
+   for (i = 0; i < totalArgs; i++) {
+      if (paramMode[i] == COPY_OUT) {
+        const slang_variable *p = fun->parameters->variables[i];
+        /* actualCallVar = outParam */
+        /*if (i > 0 || !haveRetValue)*/
+        slang_operation *ass = slang_operation_insert(&inlined->num_children,
+                                                      &inlined->children,
+                                                      inlined->num_children);
+        ass->type = SLANG_OPER_ASSIGN;
+        ass->num_children = 2;
+         ass->locals->outer_scope = inlined->locals;
+        ass->children = slang_operation_new(2);
+        ass->children[0] = args[i]; /*XXX copy */
+        ass->children[1].type = SLANG_OPER_IDENTIFIER;
+        ass->children[1].a_id = p->a_name;
+         ass->children[1].locals->outer_scope = ass->locals;
+      }
+   }
+
+   _slang_free(paramMode);
+   _slang_free(substOld);
+   _slang_free(substNew);
+
+   /* Update scoping to use the new local vars instead of the
+    * original function's vars.  This is especially important
+    * for nested inlining.
+    */
+   if (newScope)
+      slang_replace_scope(inlined, fun->parameters, newScope);
+
+#if 0
+   printf("Done Inline call to %s  (total vars=%d  nparams=%d)\n\n",
+         (char *) fun->header.a_name,
+         fun->parameters->num_variables, numArgs);
+   slang_print_tree(top, 0);
+#endif
+
+   /* pop */
+   A->CurFunction = prevFunction;
+
+   return top;
+}
+
+
+/**
+ * Insert declaration for "bool __notRetFlag" in given block operation.
+ * This is used when we can't emit "early" return statements in subroutines.
+ */
+static void
+declare_return_flag(slang_assemble_ctx *A, slang_operation *oper)
+{
+   slang_operation *decl;
+
+   assert(oper->type == SLANG_OPER_BLOCK_NEW_SCOPE ||
+          oper->type == SLANG_OPER_SEQUENCE);
+
+   decl = slang_operation_insert_child(oper, 1);
+
+   slang_generate_declaration(A, oper->locals, decl,
+                              SLANG_SPEC_BOOL, "__notRetFlag", GL_TRUE);
+
+   /*slang_print_tree(oper, 0);*/
+}
+
+
+/**
+ * Recursively replace instances of the old node type with the new type.
+ */
+static void
+replace_node_type(slang_operation *oper, slang_operation_type oldType,
+                  slang_operation_type newType)
+{
+   GLuint i;
+
+   if (oper->type == oldType)
+      oper->type = newType;
+
+   for (i = 0; i < slang_oper_num_children(oper); i++) {
+      replace_node_type(slang_oper_child(oper, i), oldType, newType);
+   }
+}
+
+
+
+/**
+ * Test if the given function body has an "early return".  That is, there's
+ * a 'return' statement that's not the very last instruction in the body.
+ */
+static GLboolean
+has_early_return(const slang_operation *funcBody)
+{
+   GLuint retCount = _slang_count_node_type(funcBody, SLANG_OPER_RETURN);
+   if (retCount == 0)
+      return GL_FALSE;
+   else if (retCount == 1 && _slang_is_tail_return(funcBody))
+      return GL_FALSE;
+   else
+      return GL_TRUE;
+}
+
+
+/**
+ * Emit IR code for a function call.  This does one of two things:
+ * 1. Inline the function's code
+ * 2. Create an IR for the function's body and create a real call to it.
+ */
+static slang_ir_node *
+_slang_gen_function_call(slang_assemble_ctx *A, slang_function *fun,
+                         slang_operation *oper, slang_operation *dest)
+{
+   slang_ir_node *n;
+   slang_operation *instance;
+   slang_label *prevFuncEndLabel;
+   char name[200];
+
+   prevFuncEndLabel = A->curFuncEndLabel;
+   _mesa_snprintf(name, sizeof(name), "__endOfFunc_%s_", (char *) fun->header.a_name);
+   A->curFuncEndLabel = _slang_label_new(name);
+   assert(A->curFuncEndLabel);
+
+   /*
+    * 'instance' is basically a copy of the function's body with various
+    * transformations.
+    */
+
+   if (slang_is_asm_function(fun) && !dest) {
+      /* assemble assembly function - tree style */
+      instance = slang_inline_asm_function(A, fun, oper);
+   }
+   else {
+      /* non-assembly function */
+      /* We always generate an "inline-able" block of code here.
+       * We may either:
+       *  1. insert the inline code
+       *  2. Generate a call to the "inline" code as a subroutine
+       */
+      const GLboolean earlyReturn = has_early_return(fun->body);
+
+      if (earlyReturn && !A->EmitContReturn) {
+         A->UseReturnFlag = GL_TRUE;
+      }
+
+      instance = slang_inline_function_call(A, fun, oper, dest);
+      if (!instance)
+         return NULL;
+
+      if (earlyReturn) {
+         /* The function we're calling has one or more 'return' statements
+          * that prevent us from inlining the function's code.
+          *
+          * In this case, change the function's body type from
+          * SLANG_OPER_BLOCK_NEW_SCOPE to SLANG_OPER_NON_INLINED_CALL.
+          * During code emit this will result in a true subroutine call.
+          *
+          * Also, convert SLANG_OPER_RETURN_INLINED nodes to SLANG_OPER_RETURN.
+          */
+         slang_operation *callOper;
+
+         assert(instance->type == SLANG_OPER_BLOCK_NEW_SCOPE ||
+                instance->type == SLANG_OPER_SEQUENCE);
+
+         if (_slang_function_has_return_value(fun) && !dest) {
+            assert(instance->children[0].type == SLANG_OPER_VARIABLE_DECL);
+            assert(instance->children[2].type == SLANG_OPER_IDENTIFIER);
+            callOper = &instance->children[1];
+         }
+         else {
+            callOper = instance;
+         }
+
+         if (A->UseReturnFlag) {
+            /* Early returns not supported.  Create a _returnFlag variable
+             * that's set upon 'return' and tested elsewhere to no-op any
+             * remaining instructions in the subroutine.
+             */
+            assert(callOper->type == SLANG_OPER_BLOCK_NEW_SCOPE ||
+                   callOper->type == SLANG_OPER_SEQUENCE);
+            declare_return_flag(A, callOper);
+         }
+         else {
+            /* We can emit real 'return' statements.  If we generated any
+             * 'inline return' statements during function instantiation,
+             * change them back to regular 'return' statements.
+             */
+            replace_node_type(instance, SLANG_OPER_RETURN_INLINED,
+                              SLANG_OPER_RETURN);
+         }
+
+         callOper->type = SLANG_OPER_NON_INLINED_CALL;
+         callOper->fun = fun;
+         callOper->label = _slang_label_new_unique((char*) fun->header.a_name);
+      }
+      else {
+         /* If there are any 'return' statements remaining, they're at the
+          * very end of the function and can effectively become no-ops.
+          */
+         replace_node_type(instance, SLANG_OPER_RETURN_INLINED,
+                           SLANG_OPER_VOID);
+      }
+   }
+
+   if (!instance)
+      return NULL;
+
+   /* Replace the function call with the instance block (or new CALL stmt) */
+   slang_operation_destruct(oper);
+   *oper = *instance;
+   _slang_free(instance);
+
+#if 0
+   assert(instance->locals);
+   printf("*** Inlined code for call to %s:\n", (char*) fun->header.a_name);
+   slang_print_tree(oper, 10);
+   printf("\n");
+#endif
+
+   n = _slang_gen_operation(A, oper);
+
+   /*_slang_label_delete(A->curFuncEndLabel);*/
+   A->curFuncEndLabel = prevFuncEndLabel;
+
+   if (A->pragmas->Debug) {
+      char s[1000];
+      _mesa_snprintf(s, sizeof(s), "Call/inline %s()", (char *) fun->header.a_name);
+      n->Comment = _slang_strdup(s);
+   }
+
+   A->UseReturnFlag = GL_FALSE;
+
+   return n;
+}
+
+
+static slang_asm_info *
+slang_find_asm_info(const char *name)
+{
+   GLuint i;
+   for (i = 0; AsmInfo[i].Name; i++) {
+      if (strcmp(AsmInfo[i].Name, name) == 0) {
+         return AsmInfo + i;
+      }
+   }
+   return NULL;
+}
+
+
+/**
+ * Some write-masked assignments are simple, but others are hard.
+ * Simple example:
+ *    vec3 v;
+ *    v.xy = vec2(a, b);
+ * Hard example:
+ *    vec3 v;
+ *    v.zy = vec2(a, b);
+ * this gets transformed/swizzled into:
+ *    v.zy = vec2(a, b).*yx*         (* = don't care)
+ * This function helps to determine simple vs. non-simple.
+ */
+static GLboolean
+_slang_simple_writemask(GLuint writemask, GLuint swizzle)
+{
+   switch (writemask) {
+   case WRITEMASK_X:
+      return GET_SWZ(swizzle, 0) == SWIZZLE_X;
+   case WRITEMASK_Y:
+      return GET_SWZ(swizzle, 1) == SWIZZLE_Y;
+   case WRITEMASK_Z:
+      return GET_SWZ(swizzle, 2) == SWIZZLE_Z;
+   case WRITEMASK_W:
+      return GET_SWZ(swizzle, 3) == SWIZZLE_W;
+   case WRITEMASK_XY:
+      return (GET_SWZ(swizzle, 0) == SWIZZLE_X)
+         && (GET_SWZ(swizzle, 1) == SWIZZLE_Y);
+   case WRITEMASK_XYZ:
+      return (GET_SWZ(swizzle, 0) == SWIZZLE_X)
+         && (GET_SWZ(swizzle, 1) == SWIZZLE_Y)
+         && (GET_SWZ(swizzle, 2) == SWIZZLE_Z);
+   case WRITEMASK_XYZW:
+      return swizzle == SWIZZLE_NOOP;
+   default:
+      return GL_FALSE;
+   }
+}
+
+
+/**
+ * Convert the given swizzle into a writemask.  In some cases this
+ * is trivial, in other cases, we'll need to also swizzle the right
+ * hand side to put components in the right places.
+ * See comment above for more info.
+ * XXX this function could be simplified and should probably be renamed.
+ * \param swizzle  the incoming swizzle
+ * \param writemaskOut  returns the writemask
+ * \param swizzleOut  swizzle to apply to the right-hand-side
+ * \return GL_FALSE for simple writemasks, GL_TRUE for non-simple
+ */
+static GLboolean
+swizzle_to_writemask(slang_assemble_ctx *A, GLuint swizzle,
+                     GLuint *writemaskOut, GLuint *swizzleOut)
+{
+   GLuint mask = 0x0, newSwizzle[4];
+   GLint i, size;
+
+   /* make new dst writemask, compute size */
+   for (i = 0; i < 4; i++) {
+      const GLuint swz = GET_SWZ(swizzle, i);
+      if (swz == SWIZZLE_NIL) {
+         /* end */
+         break;
+      }
+      assert(swz <= 3);
+
+      if (swizzle != SWIZZLE_XXXX &&
+          swizzle != SWIZZLE_YYYY &&
+          swizzle != SWIZZLE_ZZZZ &&
+          swizzle != SWIZZLE_WWWW &&
+          (mask & (1 << swz))) {
+         /* a channel can't be specified twice (ex: ".xyyz") */
+         slang_info_log_error(A->log, "Invalid writemask '%s'",
+                              _mesa_swizzle_string(swizzle, 0, 0));
+         return GL_FALSE;
+      }
+
+      mask |= (1 << swz);
+   }
+   assert(mask <= 0xf);
+   size = i;  /* number of components in mask/swizzle */
+
+   *writemaskOut = mask;
+
+   /* make new src swizzle, by inversion */
+   for (i = 0; i < 4; i++) {
+      newSwizzle[i] = i; /*identity*/
+   }
+   for (i = 0; i < size; i++) {
+      const GLuint swz = GET_SWZ(swizzle, i);
+      newSwizzle[swz] = i;
+   }
+   *swizzleOut = MAKE_SWIZZLE4(newSwizzle[0],
+                               newSwizzle[1],
+                               newSwizzle[2],
+                               newSwizzle[3]);
+
+   if (_slang_simple_writemask(mask, *swizzleOut)) {
+      if (size >= 1)
+         assert(GET_SWZ(*swizzleOut, 0) == SWIZZLE_X);
+      if (size >= 2)
+         assert(GET_SWZ(*swizzleOut, 1) == SWIZZLE_Y);
+      if (size >= 3)
+         assert(GET_SWZ(*swizzleOut, 2) == SWIZZLE_Z);
+      if (size >= 4)
+         assert(GET_SWZ(*swizzleOut, 3) == SWIZZLE_W);
+      return GL_TRUE;
+   }
+   else
+      return GL_FALSE;
+}
+
+
+#if 0 /* not used, but don't remove just yet */
+/**
+ * Recursively traverse 'oper' to produce a swizzle mask in the event
+ * of any vector subscripts and swizzle suffixes.
+ * Ex:  for "vec4 v",  "v[2].x" resolves to v.z
+ */
+static GLuint
+resolve_swizzle(const slang_operation *oper)
+{
+   if (oper->type == SLANG_OPER_FIELD) {
+      /* writemask from .xyzw suffix */
+      slang_swizzle swz;
+      if (_slang_is_swizzle((char*) oper->a_id, 4, &swz)) {
+         GLuint swizzle = MAKE_SWIZZLE4(swz.swizzle[0],
+                                        swz.swizzle[1],
+                                        swz.swizzle[2],
+                                        swz.swizzle[3]);
+         GLuint child_swizzle = resolve_swizzle(&oper->children[0]);
+         GLuint s = _slang_swizzle_swizzle(child_swizzle, swizzle);
+         return s;
+      }
+      else
+         return SWIZZLE_XYZW;
+   }
+   else if (oper->type == SLANG_OPER_SUBSCRIPT &&
+            oper->children[1].type == SLANG_OPER_LITERAL_INT) {
+      /* writemask from [index] */
+      GLuint child_swizzle = resolve_swizzle(&oper->children[0]);
+      GLuint i = (GLuint) oper->children[1].literal[0];
+      GLuint swizzle;
+      GLuint s;
+      switch (i) {
+      case 0:
+         swizzle = SWIZZLE_XXXX;
+         break;
+      case 1:
+         swizzle = SWIZZLE_YYYY;
+         break;
+      case 2:
+         swizzle = SWIZZLE_ZZZZ;
+         break;
+      case 3:
+         swizzle = SWIZZLE_WWWW;
+         break;
+      default:
+         swizzle = SWIZZLE_XYZW;
+      }
+      s = _slang_swizzle_swizzle(child_swizzle, swizzle);
+      return s;
+   }
+   else {
+      return SWIZZLE_XYZW;
+   }
+}
+#endif
+
+
+#if 0
+/**
+ * Recursively descend through swizzle nodes to find the node's storage info.
+ */
+static slang_ir_storage *
+get_store(const slang_ir_node *n)
+{
+   if (n->Opcode == IR_SWIZZLE) {
+      return get_store(n->Children[0]);
+   }
+   return n->Store;
+}
+#endif
+
+
+/**
+ * Generate IR tree for an asm instruction/operation such as:
+ *    __asm vec4_dot __retVal.x, v1, v2;
+ */
+static slang_ir_node *
+_slang_gen_asm(slang_assemble_ctx *A, slang_operation *oper,
+               slang_operation *dest)
+{
+   const slang_asm_info *info;
+   slang_ir_node *kids[3], *n;
+   GLuint j, firstOperand;
+
+   assert(oper->type == SLANG_OPER_ASM);
+
+   info = slang_find_asm_info((char *) oper->a_id);
+   if (!info) {
+      _mesa_problem(NULL, "undefined __asm function %s\n",
+                    (char *) oper->a_id);
+      assert(info);
+      return NULL;
+   }
+   assert(info->NumParams <= 3);
+
+   if (info->NumParams == oper->num_children) {
+      /* Storage for result is not specified.
+       * Children[0], [1], [2] are the operands.
+       */
+      firstOperand = 0;
+   }
+   else {
+      /* Storage for result (child[0]) is specified.
+       * Children[1], [2], [3] are the operands.
+       */
+      firstOperand = 1;
+   }
+
+   /* assemble child(ren) */
+   kids[0] = kids[1] = kids[2] = NULL;
+   for (j = 0; j < info->NumParams; j++) {
+      kids[j] = _slang_gen_operation(A, &oper->children[firstOperand + j]);
+      if (!kids[j])
+         return NULL;
+   }
+
+   n = new_node3(info->Opcode, kids[0], kids[1], kids[2]);
+
+   if (firstOperand) {
+      /* Setup n->Store to be a particular location.  Otherwise, storage
+       * for the result (a temporary) will be allocated later.
+       */
+      slang_operation *dest_oper;
+      slang_ir_node *n0;
+
+      dest_oper = &oper->children[0];
+
+      n0 = _slang_gen_operation(A, dest_oper);
+      if (!n0)
+         return NULL;
+
+      assert(!n->Store);
+      n->Store = n0->Store;
+
+      assert(n->Store->File != PROGRAM_UNDEFINED || n->Store->Parent);
+
+      _slang_free(n0);
+   }
+
+   return n;
+}
+
+
+#if 0
+static void
+print_funcs(struct slang_function_scope_ *scope, const char *name)
+{
+   GLuint i;
+   for (i = 0; i < scope->num_functions; i++) {
+      slang_function *f = &scope->functions[i];
+      if (!name || strcmp(name, (char*) f->header.a_name) == 0)
+          printf("  %s (%d args)\n", name, f->param_count);
+
+   }
+   if (scope->outer_scope)
+      print_funcs(scope->outer_scope, name);
+}
+#endif
+
+
+/**
+ * Find a function of the given name, taking 'numArgs' arguments.
+ * This is the function we'll try to call when there is no exact match
+ * between function parameters and call arguments.
+ *
+ * XXX we should really create a list of candidate functions and try
+ * all of them...
+ */
+static slang_function *
+_slang_find_function_by_argc(slang_function_scope *scope,
+                             const char *name, int numArgs)
+{
+   while (scope) {
+      GLuint i;
+      for (i = 0; i < scope->num_functions; i++) {
+         slang_function *f = &scope->functions[i];
+         if (strcmp(name, (char*) f->header.a_name) == 0) {
+            int haveRetValue = _slang_function_has_return_value(f);
+            if (numArgs == f->param_count - haveRetValue)
+               return f;
+         }
+      }
+      scope = scope->outer_scope;
+   }
+
+   return NULL;
+}
+
+
+static slang_function *
+_slang_find_function_by_max_argc(slang_function_scope *scope,
+                                 const char *name)
+{
+   slang_function *maxFunc = NULL;
+   GLuint maxArgs = 0;
+
+   while (scope) {
+      GLuint i;
+      for (i = 0; i < scope->num_functions; i++) {
+         slang_function *f = &scope->functions[i];
+         if (strcmp(name, (char*) f->header.a_name) == 0) {
+            if (f->param_count > maxArgs) {
+               maxArgs = f->param_count;
+               maxFunc = f;
+            }
+         }
+      }
+      scope = scope->outer_scope;
+   }
+
+   return maxFunc;
+}
+
+
+/**
+ * Generate a new slang_function which is a constructor for a user-defined
+ * struct type.
+ */
+static slang_function *
+_slang_make_struct_constructor(slang_assemble_ctx *A, slang_struct *str)
+{
+   const GLint numFields = str->fields->num_variables;
+   slang_function *fun = slang_function_new(SLANG_FUNC_CONSTRUCTOR);
+
+   /* function header (name, return type) */
+   fun->header.a_name = str->a_name;
+   fun->header.type.qualifier = SLANG_QUAL_NONE;
+   fun->header.type.specifier.type = SLANG_SPEC_STRUCT;
+   fun->header.type.specifier._struct = str;
+
+   /* function parameters (= struct's fields) */
+   {
+      GLint i;
+      for (i = 0; i < numFields; i++) {
+         /*
+         printf("Field %d: %s\n", i, (char*) str->fields->variables[i]->a_name);
+         */
+         slang_variable *p = slang_variable_scope_grow(fun->parameters);
+         *p = *str->fields->variables[i]; /* copy the variable and type */
+         p->type.qualifier = SLANG_QUAL_CONST;
+      }
+      fun->param_count = fun->parameters->num_variables;
+   }
+
+   /* Add __retVal to params */
+   {
+      slang_variable *p = slang_variable_scope_grow(fun->parameters);
+      slang_atom a_retVal = slang_atom_pool_atom(A->atoms, "__retVal");
+      assert(a_retVal);
+      p->a_name = a_retVal;
+      p->type = fun->header.type;
+      p->type.qualifier = SLANG_QUAL_OUT;
+      fun->param_count++;
+   }
+
+   /* function body is:
+    *    block:
+    *       declare T;
+    *       T.f1 = p1;
+    *       T.f2 = p2;
+    *       ...
+    *       T.fn = pn;
+    *       return T;
+    */
+   {
+      slang_variable_scope *scope;
+      slang_variable *var;
+      GLint i;
+
+      fun->body = slang_operation_new(1);
+      fun->body->type = SLANG_OPER_BLOCK_NEW_SCOPE;
+      fun->body->num_children = numFields + 2;
+      fun->body->children = slang_operation_new(numFields + 2);
+
+      scope = fun->body->locals;
+      scope->outer_scope = fun->parameters;
+
+      /* create local var 't' */
+      var = slang_variable_scope_grow(scope);
+      var->a_name = slang_atom_pool_atom(A->atoms, "t");
+      var->type = fun->header.type;
+
+      /* declare t */
+      {
+         slang_operation *decl;
+
+         decl = &fun->body->children[0];
+         decl->type = SLANG_OPER_VARIABLE_DECL;
+         decl->locals = _slang_variable_scope_new(scope);
+         decl->a_id = var->a_name;
+      }
+
+      /* assign params to fields of t */
+      for (i = 0; i < numFields; i++) {
+         slang_operation *assign = &fun->body->children[1 + i];
+
+         assign->type = SLANG_OPER_ASSIGN;
+         assign->locals = _slang_variable_scope_new(scope);
+         assign->num_children = 2;
+         assign->children = slang_operation_new(2);
+         
+         {
+            slang_operation *lhs = &assign->children[0];
+
+            lhs->type = SLANG_OPER_FIELD;
+            lhs->locals = _slang_variable_scope_new(scope);
+            lhs->num_children = 1;
+            lhs->children = slang_operation_new(1);
+            lhs->a_id = str->fields->variables[i]->a_name;
+
+            lhs->children[0].type = SLANG_OPER_IDENTIFIER;
+            lhs->children[0].a_id = var->a_name;
+            lhs->children[0].locals = _slang_variable_scope_new(scope);
+
+#if 0
+            lhs->children[1].num_children = 1;
+            lhs->children[1].children = slang_operation_new(1);
+            lhs->children[1].children[0].type = SLANG_OPER_IDENTIFIER;
+            lhs->children[1].children[0].a_id = str->fields->variables[i]->a_name;
+            lhs->children[1].children->locals = _slang_variable_scope_new(scope);
+#endif
+         }
+
+         {
+            slang_operation *rhs = &assign->children[1];
+
+            rhs->type = SLANG_OPER_IDENTIFIER;
+            rhs->locals = _slang_variable_scope_new(scope);
+            rhs->a_id = str->fields->variables[i]->a_name;
+         }         
+      }
+
+      /* return t; */
+      {
+         slang_operation *ret = &fun->body->children[numFields + 1];
+
+         ret->type = SLANG_OPER_RETURN;
+         ret->locals = _slang_variable_scope_new(scope);
+         ret->num_children = 1;
+         ret->children = slang_operation_new(1);
+         ret->children[0].type = SLANG_OPER_IDENTIFIER;
+         ret->children[0].a_id = var->a_name;
+         ret->children[0].locals = _slang_variable_scope_new(scope);
+      }
+   }
+   /*
+   slang_print_function(fun, 1);
+   */
+   return fun;
+}
+
+
+/**
+ * Find/create a function (constructor) for the given structure name.
+ */
+static slang_function *
+_slang_locate_struct_constructor(slang_assemble_ctx *A, const char *name)
+{
+   unsigned int i;
+   for (i = 0; i < A->space.structs->num_structs; i++) {
+      slang_struct *str = &A->space.structs->structs[i];
+      if (strcmp(name, (const char *) str->a_name) == 0) {
+         /* found a structure type that matches the function name */
+         if (!str->constructor) {
+            /* create the constructor function now */
+            str->constructor = _slang_make_struct_constructor(A, str);
+         }
+         return str->constructor;
+      }
+   }
+   return NULL;
+}
+
+
+/**
+ * Generate a new slang_function to satisfy a call to an array constructor.
+ * Ex:  float[3](1., 2., 3.)
+ */
+static slang_function *
+_slang_make_array_constructor(slang_assemble_ctx *A, slang_operation *oper)
+{
+   slang_type_specifier_type baseType;
+   slang_function *fun;
+   int num_elements;
+
+   fun = slang_function_new(SLANG_FUNC_CONSTRUCTOR);
+   if (!fun)
+      return NULL;
+
+   baseType = slang_type_specifier_type_from_string((char *) oper->a_id);
+
+   num_elements = oper->num_children;
+
+   /* function header, return type */
+   {
+      fun->header.a_name = oper->a_id;
+      fun->header.type.qualifier = SLANG_QUAL_NONE;
+      fun->header.type.specifier.type = SLANG_SPEC_ARRAY;
+      fun->header.type.specifier._array =
+         slang_type_specifier_new(baseType, NULL, NULL);
+      fun->header.type.array_len = num_elements;
+   }
+
+   /* function parameters (= number of elements) */
+   {
+      GLint i;
+      for (i = 0; i < num_elements; i++) {
+         /*
+         printf("Field %d: %s\n", i, (char*) str->fields->variables[i]->a_name);
+         */
+         slang_variable *p = slang_variable_scope_grow(fun->parameters);
+         char name[10];
+         _mesa_snprintf(name, sizeof(name), "p%d", i);
+         p->a_name = slang_atom_pool_atom(A->atoms, name);
+         p->type.qualifier = SLANG_QUAL_CONST;
+         p->type.specifier.type = baseType;
+      }
+      fun->param_count = fun->parameters->num_variables;
+   }
+
+   /* Add __retVal to params */
+   {
+      slang_variable *p = slang_variable_scope_grow(fun->parameters);
+      slang_atom a_retVal = slang_atom_pool_atom(A->atoms, "__retVal");
+      assert(a_retVal);
+      p->a_name = a_retVal;
+      p->type = fun->header.type;
+      p->type.qualifier = SLANG_QUAL_OUT;
+      p->type.specifier.type = baseType;
+      fun->param_count++;
+   }
+
+   /* function body is:
+    *    block:
+    *       declare T;
+    *       T[0] = p0;
+    *       T[1] = p1;
+    *       ...
+    *       T[n] = pn;
+    *       return T;
+    */
+   {
+      slang_variable_scope *scope;
+      slang_variable *var;
+      GLint i;
+
+      fun->body = slang_operation_new(1);
+      fun->body->type = SLANG_OPER_BLOCK_NEW_SCOPE;
+      fun->body->num_children = num_elements + 2;
+      fun->body->children = slang_operation_new(num_elements + 2);
+
+      scope = fun->body->locals;
+      scope->outer_scope = fun->parameters;
+
+      /* create local var 't' */
+      var = slang_variable_scope_grow(scope);
+      var->a_name = slang_atom_pool_atom(A->atoms, "ttt");
+      var->type = fun->header.type;/*XXX copy*/
+
+      /* declare t */
+      {
+         slang_operation *decl;
+
+         decl = &fun->body->children[0];
+         decl->type = SLANG_OPER_VARIABLE_DECL;
+         decl->locals = _slang_variable_scope_new(scope);
+         decl->a_id = var->a_name;
+      }
+
+      /* assign params to elements of t */
+      for (i = 0; i < num_elements; i++) {
+         slang_operation *assign = &fun->body->children[1 + i];
+
+         assign->type = SLANG_OPER_ASSIGN;
+         assign->locals = _slang_variable_scope_new(scope);
+         assign->num_children = 2;
+         assign->children = slang_operation_new(2);
+         
+         {
+            slang_operation *lhs = &assign->children[0];
+
+            lhs->type = SLANG_OPER_SUBSCRIPT;
+            lhs->locals = _slang_variable_scope_new(scope);
+            lhs->num_children = 2;
+            lhs->children = slang_operation_new(2);
+            lhs->children[0].type = SLANG_OPER_IDENTIFIER;
+            lhs->children[0].a_id = var->a_name;
+            lhs->children[0].locals = _slang_variable_scope_new(scope);
+
+            lhs->children[1].type = SLANG_OPER_LITERAL_INT;
+            lhs->children[1].literal[0] = (GLfloat) i;
+         }
+
+         {
+            slang_operation *rhs = &assign->children[1];
+
+            rhs->type = SLANG_OPER_IDENTIFIER;
+            rhs->locals = _slang_variable_scope_new(scope);
+            rhs->a_id = fun->parameters->variables[i]->a_name;
+         }         
+      }
+
+      /* return t; */
+      {
+         slang_operation *ret = &fun->body->children[num_elements + 1];
+
+         ret->type = SLANG_OPER_RETURN;
+         ret->locals = _slang_variable_scope_new(scope);
+         ret->num_children = 1;
+         ret->children = slang_operation_new(1);
+         ret->children[0].type = SLANG_OPER_IDENTIFIER;
+         ret->children[0].a_id = var->a_name;
+         ret->children[0].locals = _slang_variable_scope_new(scope);
+      }
+   }
+
+   /*
+   slang_print_function(fun, 1);
+   */
+
+   return fun;
+}
+
+
+static GLboolean
+_slang_is_vec_mat_type(const char *name)
+{
+   static const char *vecmat_types[] = {
+      "float", "int", "bool",
+      "vec2", "vec3", "vec4",
+      "ivec2", "ivec3", "ivec4",
+      "bvec2", "bvec3", "bvec4",
+      "mat2", "mat3", "mat4",
+      "mat2x3", "mat2x4", "mat3x2", "mat3x4", "mat4x2", "mat4x3",
+      NULL
+   };
+   int i;
+   for (i = 0; vecmat_types[i]; i++)
+      if (strcmp(name, vecmat_types[i]) == 0)
+         return GL_TRUE;
+   return GL_FALSE;
+}
+
+
+/**
+ * Assemble a function call, given a particular function name.
+ * \param name  the function's name (operators like '*' are possible).
+ */
+static slang_ir_node *
+_slang_gen_function_call_name(slang_assemble_ctx *A, const char *name,
+                              slang_operation *oper, slang_operation *dest)
+{
+   slang_operation *params = oper->children;
+   const GLuint param_count = oper->num_children;
+   slang_atom atom;
+   slang_function *fun;
+   slang_ir_node *n;
+
+   atom = slang_atom_pool_atom(A->atoms, name);
+   if (atom == SLANG_ATOM_NULL)
+      return NULL;
+
+   if (oper->array_constructor) {
+      /* this needs special handling */
+      fun = _slang_make_array_constructor(A, oper);
+   }
+   else {
+      /* Try to find function by name and exact argument type matching */
+      GLboolean error = GL_FALSE;
+      fun = _slang_function_locate(A->space.funcs, atom, params, param_count,
+                                   &A->space, A->atoms, A->log, &error);
+      if (error) {
+         slang_info_log_error(A->log,
+                              "Function '%s' not found (check argument types)",
+                              name);
+         return NULL;
+      }
+   }
+
+   if (!fun) {
+      /* Next, try locating a constructor function for a user-defined type */
+      fun = _slang_locate_struct_constructor(A, name);
+   }
+
+   /*
+    * At this point, some heuristics are used to try to find a function
+    * that matches the calling signature by means of casting or "unrolling"
+    * of constructors.
+    */
+
+   if (!fun && _slang_is_vec_mat_type(name)) {
+      /* Next, if this call looks like a vec() or mat() constructor call,
+       * try "unwinding" the args to satisfy a constructor.
+       */
+      fun = _slang_find_function_by_max_argc(A->space.funcs, name);
+      if (fun) {
+         if (!_slang_adapt_call(oper, fun, &A->space, A->atoms, A->log)) {
+            slang_info_log_error(A->log,
+                                 "Function '%s' not found (check argument types)",
+                                 name);
+            return NULL;
+         }
+      }
+   }
+
+   if (!fun && _slang_is_vec_mat_type(name)) {
+      /* Next, try casting args to the types of the formal parameters */
+      int numArgs = oper->num_children;
+      fun = _slang_find_function_by_argc(A->space.funcs, name, numArgs);
+      if (!fun || !_slang_cast_func_params(oper, fun, &A->space, A->atoms, A->log)) {
+         slang_info_log_error(A->log,
+                              "Function '%s' not found (check argument types)",
+                              name);
+         return NULL;
+      }
+      assert(fun);
+   }
+
+   if (!fun) {
+      slang_info_log_error(A->log,
+                           "Function '%s' not found (check argument types)",
+                           name);
+      return NULL;
+   }
+
+   if (!fun->body) {
+      /* The function body may be in another compilation unit.
+       * We'll try concatenating the shaders and recompile at link time.
+       */
+      A->UnresolvedRefs = GL_TRUE;
+      return new_node1(IR_NOP, NULL);
+   }
+
+   /* type checking to be sure function's return type matches 'dest' type */
+   if (dest) {
+      slang_typeinfo t0;
+
+      slang_typeinfo_construct(&t0);
+      typeof_operation(A, dest, &t0);
+
+      if (!slang_type_specifier_equal(&t0.spec, &fun->header.type.specifier)) {
+         slang_info_log_error(A->log,
+                              "Incompatible type returned by call to '%s'",
+                              name);
+         return NULL;
+      }
+   }
+
+   n = _slang_gen_function_call(A, fun, oper, dest);
+
+   if (n && !n->Store && !dest
+       && fun->header.type.specifier.type != SLANG_SPEC_VOID) {
+      /* setup n->Store for the result of the function call */
+      GLint size = _slang_sizeof_type_specifier(&fun->header.type.specifier);
+      n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, size);
+      /*printf("Alloc storage for function result, size %d \n", size);*/
+   }
+
+   if (oper->array_constructor) {
+      /* free the temporary array constructor function now */
+      slang_function_destruct(fun);
+   }
+
+   return n;
+}
+
+
+static slang_ir_node *
+_slang_gen_method_call(slang_assemble_ctx *A, slang_operation *oper)
+{
+   slang_atom *a_length = slang_atom_pool_atom(A->atoms, "length");
+   slang_ir_node *n;
+   slang_variable *var;
+
+   /* NOTE: In GLSL 1.20, there's only one kind of method
+    * call: array.length().  Anything else is an error.
+    */
+   if (oper->a_id != a_length) {
+      slang_info_log_error(A->log,
+                           "Undefined method call '%s'", (char *) oper->a_id);
+      return NULL;
+   }
+
+   /* length() takes no arguments */
+   if (oper->num_children > 0) {
+      slang_info_log_error(A->log, "Invalid arguments to length() method");
+      return NULL;
+   }
+
+   /* lookup the object/variable */
+   var = _slang_variable_locate(oper->locals, oper->a_obj, GL_TRUE);
+   if (!var || var->type.specifier.type != SLANG_SPEC_ARRAY) {
+      slang_info_log_error(A->log,
+                           "Undefined object '%s'", (char *) oper->a_obj);
+      return NULL;
+   }
+
+   /* Create a float/literal IR node encoding the array length */
+   n = new_node0(IR_FLOAT);
+   if (n) {
+      n->Value[0] = (float) _slang_array_length(var);
+      n->Store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, 1);
+   }
+   return n;
+}
+
+
+static GLboolean
+_slang_is_constant_cond(const slang_operation *oper, GLboolean *value)
+{
+   if (oper->type == SLANG_OPER_LITERAL_FLOAT ||
+       oper->type == SLANG_OPER_LITERAL_INT ||
+       oper->type == SLANG_OPER_LITERAL_BOOL) {
+      if (oper->literal[0])
+         *value = GL_TRUE;
+      else
+         *value = GL_FALSE;
+      return GL_TRUE;
+   }
+   else if (oper->type == SLANG_OPER_EXPRESSION &&
+            oper->num_children == 1) {
+      return _slang_is_constant_cond(&oper->children[0], value);
+   }
+   return GL_FALSE;
+}
+
+
+/**
+ * Test if an operation is a scalar or boolean.
+ */
+static GLboolean
+_slang_is_scalar_or_boolean(slang_assemble_ctx *A, slang_operation *oper)
+{
+   slang_typeinfo type;
+   GLint size;
+
+   slang_typeinfo_construct(&type);
+   typeof_operation(A, oper, &type);
+   size = _slang_sizeof_type_specifier(&type.spec);
+   slang_typeinfo_destruct(&type);
+   return size == 1;
+}
+
+
+/**
+ * Test if an operation is boolean.
+ */
+static GLboolean
+_slang_is_boolean(slang_assemble_ctx *A, slang_operation *oper)
+{
+   slang_typeinfo type;
+   GLboolean isBool;
+
+   slang_typeinfo_construct(&type);
+   typeof_operation(A, oper, &type);
+   isBool = (type.spec.type == SLANG_SPEC_BOOL);
+   slang_typeinfo_destruct(&type);
+   return isBool;
+}
+
+
+/**
+ * Check if a loop contains a 'continue' statement.
+ * Stop looking if we find a nested loop.
+ */
+static GLboolean
+_slang_loop_contains_continue(const slang_operation *oper)
+{
+   switch (oper->type) {
+   case SLANG_OPER_CONTINUE:
+      return GL_TRUE;
+   case SLANG_OPER_FOR:
+   case SLANG_OPER_DO:
+   case SLANG_OPER_WHILE:
+      /* stop upon finding a nested loop */
+      return GL_FALSE;
+   default:
+       /* recurse */
+      {
+         GLuint i;
+         for (i = 0; i < oper->num_children; i++) {
+            const slang_operation *child = slang_oper_child_const(oper, i);
+            if (_slang_loop_contains_continue(child))
+               return GL_TRUE;
+         }
+      }
+      return GL_FALSE;
+   }
+}
+
+
+/**
+ * Check if a loop contains a 'continue' or 'break' statement.
+ * Stop looking if we find a nested loop.
+ */
+static GLboolean
+_slang_loop_contains_continue_or_break(const slang_operation *oper)
+{
+   switch (oper->type) {
+   case SLANG_OPER_CONTINUE:
+   case SLANG_OPER_BREAK:
+      return GL_TRUE;
+   case SLANG_OPER_FOR:
+   case SLANG_OPER_DO:
+   case SLANG_OPER_WHILE:
+      /* stop upon finding a nested loop */
+      return GL_FALSE;
+   default:
+       /* recurse */
+      {
+         GLuint i;
+         for (i = 0; i < oper->num_children; i++) {
+            const slang_operation *child = slang_oper_child_const(oper, i);
+            if (_slang_loop_contains_continue_or_break(child))
+               return GL_TRUE;
+         }
+      }
+      return GL_FALSE;
+   }
+}
+
+
+/**
+ * Replace 'break' and 'continue' statements inside a do and while loops.
+ * This is a recursive helper function used by
+ * _slang_gen_do/while_without_continue().
+ */
+static void
+replace_break_and_cont(slang_assemble_ctx *A, slang_operation *oper)
+{
+   switch (oper->type) {
+   case SLANG_OPER_BREAK:
+      /* replace 'break' with "_notBreakFlag = false; break" */
+      {
+         slang_operation *block = oper;
+         block->type = SLANG_OPER_BLOCK_NEW_SCOPE;
+         slang_operation_add_children(block, 2);
+         {
+            slang_operation *assign = slang_oper_child(block, 0);
+            assign->type = SLANG_OPER_ASSIGN;
+            slang_operation_add_children(assign, 2);
+            {
+               slang_operation *lhs = slang_oper_child(assign, 0);
+               slang_operation_identifier(lhs, A, "_notBreakFlag");
+            }
+            {
+               slang_operation *rhs = slang_oper_child(assign, 1);
+               slang_operation_literal_bool(rhs, GL_FALSE);
+            }
+         }
+         {
+            slang_operation *brk = slang_oper_child(block, 1);
+            brk->type = SLANG_OPER_BREAK;
+            assert(!brk->children);
+         }
+      }
+      break;
+   case SLANG_OPER_CONTINUE:
+      /* convert continue into a break */
+      oper->type = SLANG_OPER_BREAK;
+      break;
+   case SLANG_OPER_FOR:
+   case SLANG_OPER_DO:
+   case SLANG_OPER_WHILE:
+      /* stop upon finding a nested loop */
+      break;
+   default:
+      /* recurse */
+      {
+         GLuint i;
+         for (i = 0; i < oper->num_children; i++) {
+            replace_break_and_cont(A, slang_oper_child(oper, i));
+         }
+      }
+   }
+}
+
+
+/**
+ * Transform a while-loop so that continue statements are converted to breaks.
+ * Then do normal IR code generation.
+ *
+ * Before:
+ * 
+ * while (LOOPCOND) {
+ *    A;
+ *    if (IFCOND)
+ *       continue;
+ *    B;
+ *    break;
+ *    C;
+ * }
+ * 
+ * After:
+ * 
+ * {
+ *    bool _notBreakFlag = 1;
+ *    while (_notBreakFlag && LOOPCOND) {
+ *       do {
+ *          A;
+ *          if (IFCOND) {
+ *             break;  // was continue
+ *          }
+ *          B;
+ *          _notBreakFlag = 0; // was
+ *          break;             // break
+ *          C;
+ *       } while (0)
+ *    }
+ * }
+ */
+static slang_ir_node *
+_slang_gen_while_without_continue(slang_assemble_ctx *A, slang_operation *oper)
+{
+   slang_operation *top;
+   slang_operation *innerBody;
+
+   assert(oper->type == SLANG_OPER_WHILE);
+
+   top = slang_operation_new(1);
+   top->type = SLANG_OPER_BLOCK_NEW_SCOPE;
+   top->locals->outer_scope = oper->locals->outer_scope;
+   slang_operation_add_children(top, 2);
+
+   /* declare: bool _notBreakFlag = true */
+   {
+      slang_operation *condDecl = slang_oper_child(top, 0);
+      slang_generate_declaration(A, top->locals, condDecl,
+                                 SLANG_SPEC_BOOL, "_notBreakFlag", GL_TRUE);
+   }
+
+   /* build outer while-loop:  while (_notBreakFlag && LOOPCOND) { ... } */
+   {
+      slang_operation *outerWhile = slang_oper_child(top, 1);
+      outerWhile->type = SLANG_OPER_WHILE;
+      slang_operation_add_children(outerWhile, 2);
+
+      /* _notBreakFlag && LOOPCOND */
+      {
+         slang_operation *cond = slang_oper_child(outerWhile, 0);
+         cond->type = SLANG_OPER_LOGICALAND;
+         slang_operation_add_children(cond, 2);
+         {
+            slang_operation *notBreak = slang_oper_child(cond, 0);
+            slang_operation_identifier(notBreak, A, "_notBreakFlag");
+         }
+         {
+            slang_operation *origCond = slang_oper_child(cond, 1);
+            slang_operation_copy(origCond, slang_oper_child(oper, 0));
+         }
+      }
+
+      /* inner loop */
+      {
+         slang_operation *innerDo = slang_oper_child(outerWhile, 1);
+         innerDo->type = SLANG_OPER_DO;
+         slang_operation_add_children(innerDo, 2);
+
+         /* copy original do-loop body into inner do-loop's body */
+         innerBody = slang_oper_child(innerDo, 0);
+         slang_operation_copy(innerBody, slang_oper_child(oper, 1));
+         innerBody->locals->outer_scope = innerDo->locals;
+
+         /* inner do-loop's condition is constant/false */
+         {
+            slang_operation *constFalse = slang_oper_child(innerDo, 1);
+            slang_operation_literal_bool(constFalse, GL_FALSE);
+         }
+      }
+   }
+
+   /* Finally, in innerBody,
+    *   replace "break" with "_notBreakFlag = 0; break"
+    *   replace "continue" with "break"
+    */
+   replace_break_and_cont(A, innerBody);
+
+   /*slang_print_tree(top, 0);*/
+
+   return _slang_gen_operation(A, top);
+
+   return NULL;
+}
+
+
+/**
+ * Generate loop code using high-level IR_LOOP instruction
+ */
+static slang_ir_node *
+_slang_gen_while(slang_assemble_ctx * A, slang_operation *oper)
+{
+   /*
+    * LOOP:
+    *    BREAK if !expr (child[0])
+    *    body code (child[1])
+    */
+   slang_ir_node *loop, *breakIf, *body;
+   GLboolean isConst, constTrue = GL_FALSE;
+
+   if (!A->EmitContReturn) {
+      /* We don't want to emit CONT instructions.  If this while-loop has
+       * a continue, translate it away.
+       */
+      if (_slang_loop_contains_continue(slang_oper_child(oper, 1))) {
+         return _slang_gen_while_without_continue(A, oper);
+      }
+   }
+
+   /* type-check expression */
+   if (!_slang_is_boolean(A, &oper->children[0])) {
+      slang_info_log_error(A->log, "scalar/boolean expression expected for 'while'");
+      return NULL;
+   }
+
+   /* Check if loop condition is a constant */
+   isConst = _slang_is_constant_cond(&oper->children[0], &constTrue);
+
+   if (isConst && !constTrue) {
+      /* loop is never executed! */
+      return new_node0(IR_NOP);
+   }
+
+   /* Begin new loop */
+   loop = new_loop(NULL);
+
+   /* save loop state */
+   push_loop(A, oper, loop);
+
+   if (isConst && constTrue) {
+      /* while(nonzero constant), no conditional break */
+      breakIf = NULL;
+   }
+   else {
+      slang_ir_node *cond
+         = new_cond(new_not(_slang_gen_operation(A, &oper->children[0])));
+      breakIf = new_break_if_true(A, cond);
+   }
+   body = _slang_gen_operation(A, &oper->children[1]);
+   loop->Children[0] = new_seq(breakIf, body);
+
+   /* Do infinite loop detection */
+   /* loop->List is head of linked list of break/continue nodes */
+   if (!loop->List && isConst && constTrue) {
+      /* infinite loop detected */
+      pop_loop(A);
+      slang_info_log_error(A->log, "Infinite loop detected!");
+      return NULL;
+   }
+
+   /* restore loop state */
+   pop_loop(A);
+
+   return loop;
+}
+
+
+/**
+ * Transform a do-while-loop so that continue statements are converted to breaks.
+ * Then do normal IR code generation.
+ *
+ * Before:
+ * 
+ * do {
+ *    A;
+ *    if (IFCOND)
+ *       continue;
+ *    B;
+ *    break;
+ *    C;
+ * } while (LOOPCOND);
+ * 
+ * After:
+ * 
+ * {
+ *    bool _notBreakFlag = 1;
+ *    do {
+ *       do {
+ *          A;
+ *          if (IFCOND) {
+ *             break;  // was continue
+ *          }
+ *          B;
+ *          _notBreakFlag = 0; // was
+ *          break;             // break
+ *          C;
+ *       } while (0)
+ *    } while (_notBreakFlag && LOOPCOND);
+ * }
+ */
+static slang_ir_node *
+_slang_gen_do_without_continue(slang_assemble_ctx *A, slang_operation *oper)
+{
+   slang_operation *top;
+   slang_operation *innerBody;
+
+   assert(oper->type == SLANG_OPER_DO);
+
+   top = slang_operation_new(1);
+   top->type = SLANG_OPER_BLOCK_NEW_SCOPE;
+   top->locals->outer_scope = oper->locals->outer_scope;
+   slang_operation_add_children(top, 2);
+
+   /* declare: bool _notBreakFlag = true */
+   {
+      slang_operation *condDecl = slang_oper_child(top, 0);
+      slang_generate_declaration(A, top->locals, condDecl,
+                                 SLANG_SPEC_BOOL, "_notBreakFlag", GL_TRUE);
+   }
+
+   /* build outer do-loop:  do { ... } while (_notBreakFlag && LOOPCOND) */
+   {
+      slang_operation *outerDo = slang_oper_child(top, 1);
+      outerDo->type = SLANG_OPER_DO;
+      slang_operation_add_children(outerDo, 2);
+
+      /* inner do-loop */
+      {
+         slang_operation *innerDo = slang_oper_child(outerDo, 0);
+         innerDo->type = SLANG_OPER_DO;
+         slang_operation_add_children(innerDo, 2);
+
+         /* copy original do-loop body into inner do-loop's body */
+         innerBody = slang_oper_child(innerDo, 0);
+         slang_operation_copy(innerBody, slang_oper_child(oper, 0));
+         innerBody->locals->outer_scope = innerDo->locals;
+
+         /* inner do-loop's condition is constant/false */
+         {
+            slang_operation *constFalse = slang_oper_child(innerDo, 1);
+            slang_operation_literal_bool(constFalse, GL_FALSE);
+         }
+      }
+
+      /* _notBreakFlag && LOOPCOND */
+      {
+         slang_operation *cond = slang_oper_child(outerDo, 1);
+         cond->type = SLANG_OPER_LOGICALAND;
+         slang_operation_add_children(cond, 2);
+         {
+            slang_operation *notBreak = slang_oper_child(cond, 0);
+            slang_operation_identifier(notBreak, A, "_notBreakFlag");
+         }
+         {
+            slang_operation *origCond = slang_oper_child(cond, 1);
+            slang_operation_copy(origCond, slang_oper_child(oper, 1));
+         }
+      }
+   }
+
+   /* Finally, in innerBody,
+    *   replace "break" with "_notBreakFlag = 0; break"
+    *   replace "continue" with "break"
+    */
+   replace_break_and_cont(A, innerBody);
+
+   /*slang_print_tree(top, 0);*/
+
+   return _slang_gen_operation(A, top);
+}
+
+
+/**
+ * Generate IR tree for a do-while loop using high-level LOOP, IF instructions.
+ */
+static slang_ir_node *
+_slang_gen_do(slang_assemble_ctx * A, slang_operation *oper)
+{
+   /*
+    * LOOP:
+    *    body code (child[0])
+    *    tail code:
+    *       BREAK if !expr (child[1])
+    */
+   slang_ir_node *loop;
+   GLboolean isConst, constTrue;
+
+   if (!A->EmitContReturn) {
+      /* We don't want to emit CONT instructions.  If this do-loop has
+       * a continue, translate it away.
+       */
+      if (_slang_loop_contains_continue(slang_oper_child(oper, 0))) {
+         return _slang_gen_do_without_continue(A, oper);
+      }
+   }
+
+   /* type-check expression */
+   if (!_slang_is_boolean(A, &oper->children[1])) {
+      slang_info_log_error(A->log, "scalar/boolean expression expected for 'do/while'");
+      return NULL;
+   }
+
+   loop = new_loop(NULL);
+
+   /* save loop state */
+   push_loop(A, oper, loop);
+
+   /* loop body: */
+   loop->Children[0] = _slang_gen_operation(A, &oper->children[0]);
+
+   /* Check if loop condition is a constant */
+   isConst = _slang_is_constant_cond(&oper->children[1], &constTrue);
+   if (isConst && constTrue) {
+      /* do { } while(1)   ==> no conditional break */
+      loop->Children[1] = NULL; /* no tail code */
+   }
+   else {
+      slang_ir_node *cond
+         = new_cond(new_not(_slang_gen_operation(A, &oper->children[1])));
+      loop->Children[1] = new_break_if_true(A, cond);
+   }
+
+   /* XXX we should do infinite loop detection, as above */
+
+   /* restore loop state */
+   pop_loop(A);
+
+   return loop;
+}
+
+
+/**
+ * Recursively count the number of operations rooted at 'oper'.
+ * This gives some kind of indication of the size/complexity of an operation.
+ */
+static GLuint
+sizeof_operation(const slang_operation *oper)
+{
+   if (oper) {
+      GLuint count = 1; /* me */
+      GLuint i;
+      for (i = 0; i < oper->num_children; i++) {
+         count += sizeof_operation(&oper->children[i]);
+      }
+      return count;
+   }
+   else {
+      return 0;
+   }
+}
+
+
+/**
+ * Determine if a for-loop can be unrolled.
+ * At this time, only a rather narrow class of for loops can be unrolled.
+ * See code for details.
+ * When a loop can't be unrolled because it's too large we'll emit a
+ * message to the log.
+ */
+static GLboolean
+_slang_can_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper)
+{
+   GLuint bodySize;
+   GLint start, end;
+   const char *varName;
+   slang_atom varId;
+
+   if (oper->type != SLANG_OPER_FOR)
+      return GL_FALSE;
+
+   assert(oper->num_children == 4);
+
+   if (_slang_loop_contains_continue_or_break(slang_oper_child_const(oper, 3)))
+      return GL_FALSE;
+
+   /* children[0] must be either "int i=constant" or "i=constant" */
+   if (oper->children[0].type == SLANG_OPER_BLOCK_NO_NEW_SCOPE) {
+      slang_variable *var;
+
+      if (oper->children[0].children[0].type != SLANG_OPER_VARIABLE_DECL)
+         return GL_FALSE;
+
+      varId = oper->children[0].children[0].a_id;
+
+      var = _slang_variable_locate(oper->children[0].children[0].locals,
+                                   varId, GL_TRUE);
+      if (!var)
+         return GL_FALSE;
+      if (!var->initializer)
+         return GL_FALSE;
+      if (var->initializer->type != SLANG_OPER_LITERAL_INT)
+         return GL_FALSE;
+      start = (GLint) var->initializer->literal[0];
+   }
+   else if (oper->children[0].type == SLANG_OPER_EXPRESSION) {
+      if (oper->children[0].children[0].type != SLANG_OPER_ASSIGN)
+         return GL_FALSE;
+      if (oper->children[0].children[0].children[0].type != SLANG_OPER_IDENTIFIER)
+         return GL_FALSE;
+      if (oper->children[0].children[0].children[1].type != SLANG_OPER_LITERAL_INT)
+         return GL_FALSE;
+
+      varId = oper->children[0].children[0].children[0].a_id;
+
+      start = (GLint) oper->children[0].children[0].children[1].literal[0];
+   }
+   else {
+      return GL_FALSE;
+   }
+
+   /* children[1] must be "i<constant" */
+   if (oper->children[1].type != SLANG_OPER_EXPRESSION)
+      return GL_FALSE;
+   if (oper->children[1].children[0].type != SLANG_OPER_LESS)
+      return GL_FALSE;
+   if (oper->children[1].children[0].children[0].type != SLANG_OPER_IDENTIFIER)
+      return GL_FALSE;
+   if (oper->children[1].children[0].children[1].type != SLANG_OPER_LITERAL_INT)
+      return GL_FALSE;
+
+   end = (GLint) oper->children[1].children[0].children[1].literal[0];
+
+   /* children[2] must be "i++" or "++i" */
+   if (oper->children[2].type != SLANG_OPER_POSTINCREMENT &&
+       oper->children[2].type != SLANG_OPER_PREINCREMENT)
+      return GL_FALSE;
+   if (oper->children[2].children[0].type != SLANG_OPER_IDENTIFIER)
+      return GL_FALSE;
+
+   /* make sure the same variable name is used in all places */
+   if ((oper->children[1].children[0].children[0].a_id != varId) ||
+       (oper->children[2].children[0].a_id != varId))
+      return GL_FALSE;
+
+   varName = (const char *) varId;
+
+   /* children[3], the loop body, can't be too large */
+   bodySize = sizeof_operation(&oper->children[3]);
+   if (bodySize > MAX_FOR_LOOP_UNROLL_BODY_SIZE) {
+      slang_info_log_print(A->log,
+                           "Note: 'for (%s ... )' body is too large/complex"
+                           " to unroll",
+                           varName);
+      return GL_FALSE;
+   }
+
+   if (start >= end)
+      return GL_FALSE; /* degenerate case */
+
+   if ((GLuint)(end - start) > MAX_FOR_LOOP_UNROLL_ITERATIONS) {
+      slang_info_log_print(A->log,
+                           "Note: 'for (%s=%d; %s<%d; ++%s)' is too"
+                           " many iterations to unroll",
+                           varName, start, varName, end, varName);
+      return GL_FALSE;
+   }
+
+   if ((end - start) * bodySize > MAX_FOR_LOOP_UNROLL_COMPLEXITY) {
+      slang_info_log_print(A->log,
+                           "Note: 'for (%s=%d; %s<%d; ++%s)' will generate"
+                           " too much code to unroll",
+                           varName, start, varName, end, varName);
+      return GL_FALSE;
+   }
+
+   return GL_TRUE; /* we can unroll the loop */
+}
+
+
+/**
+ * Unroll a for-loop.
+ * First we determine the number of iterations to unroll.
+ * Then for each iteration:
+ *   make a copy of the loop body
+ *   replace instances of the loop variable with the current iteration value
+ *   generate IR code for the body
+ * \return pointer to generated IR code or NULL if error, out of memory, etc.
+ */
+static slang_ir_node *
+_slang_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper)
+{
+   GLint start, end, iter;
+   slang_ir_node *n, *root = NULL;
+   slang_atom varId;
+
+   if (oper->children[0].type == SLANG_OPER_BLOCK_NO_NEW_SCOPE) {
+      /* for (int i=0; ... */
+      slang_variable *var;
+
+      varId = oper->children[0].children[0].a_id;
+      var = _slang_variable_locate(oper->children[0].children[0].locals,
+                                   varId, GL_TRUE);
+      assert(var);
+      start = (GLint) var->initializer->literal[0];
+   }
+   else {
+      /* for (i=0; ... */
+      varId = oper->children[0].children[0].children[0].a_id;
+      start = (GLint) oper->children[0].children[0].children[1].literal[0];
+   }
+
+   end = (GLint) oper->children[1].children[0].children[1].literal[0];
+
+   for (iter = start; iter < end; iter++) {
+      slang_operation *body;
+
+      /* make a copy of the loop body */
+      body = slang_operation_new(1);
+      if (!body)
+         return NULL;
+
+      if (!slang_operation_copy(body, &oper->children[3]))
+         return NULL;
+
+      /* in body, replace instances of 'varId' with literal 'iter' */
+      {
+         slang_variable *oldVar;
+         slang_operation *newOper;
+
+         oldVar = _slang_variable_locate(oper->locals, varId, GL_TRUE);
+         if (!oldVar) {
+            /* undeclared loop variable */
+            slang_operation_delete(body);
+            return NULL;
+         }
+
+         newOper = slang_operation_new(1);
+         newOper->type = SLANG_OPER_LITERAL_INT;
+         newOper->literal_size = 1;
+         newOper->literal[0] = (GLfloat) iter;
+
+         /* replace instances of the loop variable with newOper */
+         slang_substitute(A, body, 1, &oldVar, &newOper, GL_FALSE);
+      }
+
+      /* do IR codegen for body */
+      n = _slang_gen_operation(A, body);
+      if (!n)
+         return NULL;
+
+      root = new_seq(root, n);
+
+      slang_operation_delete(body);
+   }
+
+   return root;
+}
+
+
+/**
+ * Replace 'continue' statement with 'break' inside a for-loop.
+ * This is a recursive helper function used by _slang_gen_for_without_continue().
+ */
+static void
+replace_continue_with_break(slang_assemble_ctx *A, slang_operation *oper)
+{
+   switch (oper->type) {
+   case SLANG_OPER_CONTINUE:
+      oper->type = SLANG_OPER_BREAK;
+      break;
+   case SLANG_OPER_FOR:
+   case SLANG_OPER_DO:
+   case SLANG_OPER_WHILE:
+      /* stop upon finding a nested loop */
+      break;
+   default:
+      /* recurse */
+      {
+         GLuint i;
+         for (i = 0; i < oper->num_children; i++) {
+            replace_continue_with_break(A, slang_oper_child(oper, i));
+         }
+      }
+   }
+}
+
+
+/**
+ * Transform a for-loop so that continue statements are converted to breaks.
+ * Then do normal IR code generation.
+ *
+ * Before:
+ * 
+ * for (INIT; LOOPCOND; INCR) {
+ *    A;
+ *    if (IFCOND) {
+ *       continue;
+ *    }
+ *    B;
+ * }
+ * 
+ * After:
+ * 
+ * {
+ *    bool _condFlag = 1;
+ *    for (INIT; _condFlag; ) {
+ *       for ( ; _condFlag = LOOPCOND; INCR) {
+ *          A;
+ *          if (IFCOND) {
+ *             break;
+ *          }
+ *          B;
+ *       }
+ *       if (_condFlag)
+ *          INCR;
+ *    }
+ * }
+ */
+static slang_ir_node *
+_slang_gen_for_without_continue(slang_assemble_ctx *A, slang_operation *oper)
+{
+   slang_operation *top;
+   slang_operation *outerFor, *innerFor, *init, *cond, *incr;
+   slang_operation *lhs, *rhs;
+
+   assert(oper->type == SLANG_OPER_FOR);
+
+   top = slang_operation_new(1);
+   top->type = SLANG_OPER_BLOCK_NEW_SCOPE;
+   top->locals->outer_scope = oper->locals->outer_scope;
+   slang_operation_add_children(top, 2);
+
+   /* declare: bool _condFlag = true */
+   {
+      slang_operation *condDecl = slang_oper_child(top, 0);
+      slang_generate_declaration(A, top->locals, condDecl,
+                                 SLANG_SPEC_BOOL, "_condFlag", GL_TRUE);
+   }
+
+   /* build outer loop:  for (INIT; _condFlag; ) { */
+   outerFor = slang_oper_child(top, 1);
+   outerFor->type = SLANG_OPER_FOR;
+   slang_operation_add_children(outerFor, 4);
+
+   init = slang_oper_child(outerFor, 0);
+   slang_operation_copy(init, slang_oper_child(oper, 0));
+
+   cond = slang_oper_child(outerFor, 1);
+   cond->type = SLANG_OPER_IDENTIFIER;
+   cond->a_id = slang_atom_pool_atom(A->atoms, "_condFlag");
+
+   incr = slang_oper_child(outerFor, 2);
+   incr->type = SLANG_OPER_VOID;
+
+   /* body of the outer loop */
+   {
+      slang_operation *block = slang_oper_child(outerFor, 3);
+
+      slang_operation_add_children(block, 2);
+      block->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
+
+      /* build inner loop:  for ( ; _condFlag = LOOPCOND; INCR) { */
+      {
+         innerFor = slang_oper_child(block, 0);
+
+         /* make copy of orig loop */
+         slang_operation_copy(innerFor, oper);
+         assert(innerFor->type == SLANG_OPER_FOR);
+         innerFor->locals->outer_scope = block->locals;
+
+         init = slang_oper_child(innerFor, 0);
+         init->type = SLANG_OPER_VOID; /* leak? */
+
+         cond = slang_oper_child(innerFor, 1);
+         slang_operation_destruct(cond);
+         cond->type = SLANG_OPER_ASSIGN;
+         cond->locals = _slang_variable_scope_new(innerFor->locals);
+         slang_operation_add_children(cond, 2);
+
+         lhs = slang_oper_child(cond, 0);
+         lhs->type = SLANG_OPER_IDENTIFIER;
+         lhs->a_id = slang_atom_pool_atom(A->atoms, "_condFlag");
+
+         rhs = slang_oper_child(cond, 1);
+         slang_operation_copy(rhs, slang_oper_child(oper, 1));
+      }
+
+      /* if (_condFlag) INCR; */
+      {
+         slang_operation *ifop = slang_oper_child(block, 1);
+         ifop->type = SLANG_OPER_IF;
+         slang_operation_add_children(ifop, 2);
+
+         /* re-use cond node build above */
+         slang_operation_copy(slang_oper_child(ifop, 0), cond);
+
+         /* incr node from original for-loop operation */
+         slang_operation_copy(slang_oper_child(ifop, 1),
+                              slang_oper_child(oper, 2));
+      }
+
+      /* finally, replace "continue" with "break" in the inner for-loop */
+      replace_continue_with_break(A, slang_oper_child(innerFor, 3));
+   }
+
+   return _slang_gen_operation(A, top);
+}
+
+
+
+/**
+ * Generate IR for a for-loop.  Unrolling will be done when possible.
+ */
+static slang_ir_node *
+_slang_gen_for(slang_assemble_ctx * A, slang_operation *oper)
+{
+   GLboolean unroll;
+
+   if (!A->EmitContReturn) {
+      /* We don't want to emit CONT instructions.  If this for-loop has
+       * a continue, translate it away.
+       */
+      if (_slang_loop_contains_continue(slang_oper_child(oper, 3))) {
+         return _slang_gen_for_without_continue(A, oper);
+      }
+   }
+
+   unroll = _slang_can_unroll_for_loop(A, oper);
+   if (unroll) {
+      slang_ir_node *code = _slang_unroll_for_loop(A, oper);
+      if (code)
+         return code;
+   }
+
+   assert(oper->type == SLANG_OPER_FOR);
+
+   /* conventional for-loop code generation */
+   {
+      /*
+       * init code (child[0])
+       * LOOP:
+       *    BREAK if !expr (child[1])
+       *    body code (child[3])
+       *    tail code:
+       *       incr code (child[2])   // XXX continue here
+       */
+      slang_ir_node *loop, *cond, *breakIf, *body, *init, *incr;
+      init = _slang_gen_operation(A, &oper->children[0]);
+      loop = new_loop(NULL);
+
+      /* save loop state */
+      push_loop(A, oper, loop);
+
+      cond = new_cond(new_not(_slang_gen_operation(A, &oper->children[1])));
+      breakIf = new_break_if_true(A, cond);
+      body = _slang_gen_operation(A, &oper->children[3]);
+      incr = _slang_gen_operation(A, &oper->children[2]);
+
+      loop->Children[0] = new_seq(breakIf, body);
+      loop->Children[1] = incr;  /* tail code */
+
+      /* restore loop state */
+      pop_loop(A);
+
+      return new_seq(init, loop);
+   }
+}
+
+
+static slang_ir_node *
+_slang_gen_continue(slang_assemble_ctx * A, const slang_operation *oper)
+{
+   slang_ir_node *n, *cont, *incr = NULL, *loopNode;
+
+   assert(oper->type == SLANG_OPER_CONTINUE);
+   loopNode = current_loop_ir(A);
+   assert(loopNode);
+   assert(loopNode->Opcode == IR_LOOP);
+
+   cont = new_node0(IR_CONT);
+   if (cont) {
+      cont->Parent = loopNode;
+      /* insert this node at head of linked list of cont/break instructions */
+      cont->List = loopNode->List;
+      loopNode->List = cont;
+   }
+
+   n = new_seq(incr, cont);
+   return n;
+}
+
+
+/**
+ * Determine if the given operation is of a specific type.
+ */
+static GLboolean
+is_operation_type(const slang_operation *oper, slang_operation_type type)
+{
+   if (oper->type == type)
+      return GL_TRUE;
+   else if ((oper->type == SLANG_OPER_BLOCK_NEW_SCOPE ||
+             oper->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE) &&
+            oper->num_children == 1)
+      return is_operation_type(&oper->children[0], type);
+   else
+      return GL_FALSE;
+}
+
+
+/**
+ * Generate IR tree for an if/then/else conditional using high-level
+ * IR_IF instruction.
+ */
+static slang_ir_node *
+_slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper)
+{
+   /*
+    * eval expr (child[0])
+    * IF expr THEN
+    *    if-body code
+    * ELSE
+    *    else-body code
+    * ENDIF
+    */
+   const GLboolean haveElseClause = !_slang_is_noop(&oper->children[2]);
+   slang_ir_node *ifNode, *cond, *ifBody, *elseBody;
+   GLboolean isConst, constTrue;
+
+   /* type-check expression */
+   if (!_slang_is_boolean(A, &oper->children[0])) {
+      slang_info_log_error(A->log, "boolean expression expected for 'if'");
+      return NULL;
+   }
+
+   if (!_slang_is_scalar_or_boolean(A, &oper->children[0])) {
+      slang_info_log_error(A->log, "scalar/boolean expression expected for 'if'");
+      return NULL;
+   }
+
+   isConst = _slang_is_constant_cond(&oper->children[0], &constTrue);
+   if (isConst) {
+      if (constTrue) {
+         /* if (true) ... */
+         return _slang_gen_operation(A, &oper->children[1]);
+      }
+      else {
+         /* if (false) ... */
+         return _slang_gen_operation(A, &oper->children[2]);
+      }
+   }
+
+   cond = _slang_gen_operation(A, &oper->children[0]);
+   cond = new_cond(cond);
+
+   if (is_operation_type(&oper->children[1], SLANG_OPER_BREAK)
+       && !haveElseClause) {
+      /* Special case: generate a conditional break */
+      ifBody = new_break_if_true(A, cond);
+      return ifBody;
+   }
+   else if (is_operation_type(&oper->children[1], SLANG_OPER_CONTINUE)
+            && !haveElseClause
+            && current_loop_oper(A)
+            && current_loop_oper(A)->type != SLANG_OPER_FOR) {
+      /* Special case: generate a conditional continue */
+      ifBody = new_cont_if_true(A, cond);
+      return ifBody;
+   }
+   else {
+      /* general case */
+      ifBody = _slang_gen_operation(A, &oper->children[1]);
+      if (haveElseClause)
+         elseBody = _slang_gen_operation(A, &oper->children[2]);
+      else
+         elseBody = NULL;
+      ifNode = new_if(cond, ifBody, elseBody);
+      return ifNode;
+   }
+}
+
+
+
+static slang_ir_node *
+_slang_gen_not(slang_assemble_ctx * A, const slang_operation *oper)
+{
+   slang_ir_node *n;
+
+   assert(oper->type == SLANG_OPER_NOT);
+
+   /* type-check expression */
+   if (!_slang_is_scalar_or_boolean(A, &oper->children[0])) {
+      slang_info_log_error(A->log,
+                           "scalar/boolean expression expected for '!'");
+      return NULL;
+   }
+
+   n = _slang_gen_operation(A, &oper->children[0]);
+   if (n)
+      return new_not(n);
+   else
+      return NULL;
+}
+
+
+static slang_ir_node *
+_slang_gen_xor(slang_assemble_ctx * A, const slang_operation *oper)
+{
+   slang_ir_node *n1, *n2;
+
+   assert(oper->type == SLANG_OPER_LOGICALXOR);
+
+   if (!_slang_is_scalar_or_boolean(A, &oper->children[0]) ||
+       !_slang_is_scalar_or_boolean(A, &oper->children[0])) {
+      slang_info_log_error(A->log,
+                           "scalar/boolean expressions expected for '^^'");
+      return NULL;
+   }
+
+   n1 = _slang_gen_operation(A, &oper->children[0]);
+   if (!n1)
+      return NULL;
+   n2 = _slang_gen_operation(A, &oper->children[1]);
+   if (!n2)
+      return NULL;
+   return new_node2(IR_NOTEQUAL, n1, n2);
+}
+
+
+/**
+ * Generate IR node for storage of a temporary of given size.
+ */
+static slang_ir_node *
+_slang_gen_temporary(GLint size)
+{
+   slang_ir_storage *store;
+   slang_ir_node *n = NULL;
+
+   store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -2, size);
+   if (store) {
+      n = new_node0(IR_VAR_DECL);
+      if (n) {
+         n->Store = store;
+      }
+      else {
+         _slang_free(store);
+      }
+   }
+   return n;
+}
+
+
+/**
+ * Generate program constants for an array.
+ * Ex: const vec2[3] v = vec2[3](vec2(1,1), vec2(2,2), vec2(3,3));
+ * This will allocate and initialize three vector constants, storing
+ * the array in constant memory, not temporaries like a non-const array.
+ * This can also be used for uniform array initializers.
+ * \return GL_TRUE for success, GL_FALSE if failure (semantic error, etc).
+ */
+static GLboolean
+make_constant_array(slang_assemble_ctx *A,
+                    slang_variable *var,
+                    slang_operation *initializer)
+{
+   struct gl_program *prog = A->program;
+   const GLenum datatype = _slang_gltype_from_specifier(&var->type.specifier);
+   const char *varName = (char *) var->a_name;
+   const GLuint numElements = initializer->num_children;
+   GLint size;
+   GLuint i, j;
+   GLfloat *values;
+
+   if (!var->store) {
+      var->store = _slang_new_ir_storage(PROGRAM_UNDEFINED, -6, -6);
+   }
+   size = var->store->Size;
+
+   assert(var->type.qualifier == SLANG_QUAL_CONST ||
+          var->type.qualifier == SLANG_QUAL_UNIFORM);
+   assert(initializer->type == SLANG_OPER_CALL);
+   assert(initializer->array_constructor);
+
+   values = (GLfloat *) malloc(numElements * 4 * sizeof(GLfloat));
+
+   /* convert constructor params into ordinary floats */
+   for (i = 0; i < numElements; i++) {
+      const slang_operation *op = &initializer->children[i];
+      if (op->type != SLANG_OPER_LITERAL_FLOAT) {
+         /* unsupported type for this optimization */
+         free(values);
+         return GL_FALSE;
+      }
+      for (j = 0; j < op->literal_size; j++) {
+         values[i * 4 + j] = op->literal[j];
+      }
+      for ( ; j < 4; j++) {
+         values[i * 4 + j] = 0.0f;
+      }
+   }
+
+   /* slightly different paths for constants vs. uniforms */
+   if (var->type.qualifier == SLANG_QUAL_UNIFORM) {
+      var->store->File = PROGRAM_UNIFORM;
+      var->store->Index = _mesa_add_uniform(prog->Parameters, varName,
+                                            size, datatype, values);
+   }
+   else {
+      var->store->File = PROGRAM_CONSTANT;
+      var->store->Index = _mesa_add_named_constant(prog->Parameters, varName,
+                                                   values, size);
+   }
+   assert(var->store->Size == size);
+
+   free(values);
+
+   return GL_TRUE;
+}
+
+
+
+/**
+ * Generate IR node for allocating/declaring a variable (either a local or
+ * a global).
+ * Generally, this involves allocating an slang_ir_storage instance for the
+ * variable, choosing a register file (temporary, constant, etc).
+ * For ordinary variables we do not yet allocate storage though.  We do that
+ * when we find the first actual use of the variable to avoid allocating temp
+ * regs that will never get used.
+ * At this time, uniforms are always allocated space in this function.
+ *
+ * \param initializer  Optional initializer expression for the variable.
+ */
+static slang_ir_node *
+_slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var,
+                    slang_operation *initializer)
+{
+   const char *varName = (const char *) var->a_name;
+   const GLenum datatype = _slang_gltype_from_specifier(&var->type.specifier);
+   slang_ir_node *varDecl, *n;
+   slang_ir_storage *store;
+   GLint arrayLen, size, totalSize;  /* if array then totalSize > size */
+   gl_register_file file;
+
+   /*assert(!var->declared);*/
+   var->declared = GL_TRUE;
+
+   /* determine GPU register file for simple cases */
+   if (is_sampler_type(&var->type)) {
+      file = PROGRAM_SAMPLER;
+   }
+   else if (var->type.qualifier == SLANG_QUAL_UNIFORM) {
+      file = PROGRAM_UNIFORM;
+   }
+   else {
+      file = PROGRAM_TEMPORARY;
+   }
+
+   size = _slang_sizeof_type_specifier(&var->type.specifier);
+   if (size <= 0) {
+      slang_info_log_error(A->log, "invalid declaration for '%s'", varName);
+      return NULL;
+   }
+
+   arrayLen = _slang_array_length(var);
+   totalSize = _slang_array_size(size, arrayLen);
+
+   /* Allocate IR node for the declaration */
+   varDecl = new_node0(IR_VAR_DECL);
+   if (!varDecl)
+      return NULL;
+
+   /* Allocate slang_ir_storage for this variable if needed.
+    * Note that we may not actually allocate a constant or temporary register
+    * until later.
+    */
+   if (!var->store) {
+      GLint index = -7;  /* TBD / unknown */
+      var->store = _slang_new_ir_storage(file, index, totalSize);
+      if (!var->store)
+         return NULL; /* out of memory */
+   }
+
+   /* set the IR node's Var and Store pointers */
+   varDecl->Var = var;
+   varDecl->Store = var->store;
+
+
+   store = var->store;
+
+   /* if there's an initializer, generate IR for the expression */
+   if (initializer) {
+      slang_ir_node *varRef, *init;
+
+      if (var->type.qualifier == SLANG_QUAL_CONST) {
+         /* if the variable is const, the initializer must be a const
+          * expression as well.
+          */
+#if 0
+         if (!_slang_is_constant_expr(initializer)) {
+            slang_info_log_error(A->log,
+                                 "initializer for %s not constant", varName);
+            return NULL;
+         }
+#endif
+      }
+
+      if (var->type.qualifier == SLANG_QUAL_UNIFORM &&
+          !A->allow_uniform_initializers) {
+         slang_info_log_error(A->log,
+                              "initializer for uniform %s not allowed",
+                              varName);
+         return NULL;
+      }
+
+      /* IR for the variable we're initializing */
+      varRef = new_var(A, var);
+      if (!varRef) {
+         slang_info_log_error(A->log, "out of memory");
+         return NULL;
+      }
+
+      /* constant-folding, etc here */
+      _slang_simplify(initializer, &A->space, A->atoms); 
+
+      /* look for simple constant-valued variables and uniforms */
+      if (var->type.qualifier == SLANG_QUAL_CONST ||
+          var->type.qualifier == SLANG_QUAL_UNIFORM) {
+
+         if (initializer->type == SLANG_OPER_CALL &&
+             initializer->array_constructor) {
+            /* array initializer */
+            if (make_constant_array(A, var, initializer))
+               return varRef;
+         }
+         else if (initializer->type == SLANG_OPER_LITERAL_FLOAT ||
+                  initializer->type == SLANG_OPER_LITERAL_INT) {
+            /* simple float/vector initializer */
+            if (store->File == PROGRAM_UNIFORM) {
+               store->Index = _mesa_add_uniform(A->program->Parameters,
+                                                varName,
+                                                totalSize, datatype,
+                                                initializer->literal);
+               store->Swizzle = _slang_var_swizzle(size, 0);
+               return varRef;
+            }
+#if 0
+            else {
+               store->File = PROGRAM_CONSTANT;
+               store->Index = _mesa_add_named_constant(A->program->Parameters,
+                                                       varName,
+                                                       initializer->literal,
+                                                       totalSize);
+               store->Swizzle = _slang_var_swizzle(size, 0);
+               return varRef;
+            }
+#endif
+         }
+      }
+
+      /* IR for initializer */
+      init = _slang_gen_operation(A, initializer);
+      if (!init)
+         return NULL;
+
+      /* XXX remove this when type checking is added above */
+      if (init->Store && init->Store->Size != totalSize) {
+         slang_info_log_error(A->log, "invalid assignment (wrong types)");
+         return NULL;
+      }
+
+      /* assign RHS to LHS */
+      n = new_node2(IR_COPY, varRef, init);
+      n = new_seq(varDecl, n);
+   }
+   else {
+      /* no initializer */
+      n = varDecl;
+   }
+
+   if (store->File == PROGRAM_UNIFORM && store->Index < 0) {
+      /* always need to allocate storage for uniforms at this point */
+      store->Index = _mesa_add_uniform(A->program->Parameters, varName,
+                                       totalSize, datatype, NULL);
+      store->Swizzle = _slang_var_swizzle(size, 0);
+   }
+
+#if 0
+   printf("%s var %p %s  store=%p index=%d size=%d\n",
+          __FUNCTION__, (void *) var, (char *) varName,
+          (void *) store, store->Index, store->Size);
+#endif
+
+   return n;
+}
+
+
+/**
+ * Generate code for a selection expression:   b ? x : y
+ * XXX In some cases we could implement a selection expression
+ * with an LRP instruction (use the boolean as the interpolant).
+ * Otherwise, we use an IF/ELSE/ENDIF construct.
+ */
+static slang_ir_node *
+_slang_gen_select(slang_assemble_ctx *A, slang_operation *oper)
+{
+   slang_ir_node *cond, *ifNode, *trueExpr, *falseExpr, *trueNode, *falseNode;
+   slang_ir_node *tmpDecl, *tmpVar, *tree;
+   slang_typeinfo type0, type1, type2;
+   int size, isBool, isEqual;
+
+   assert(oper->type == SLANG_OPER_SELECT);
+   assert(oper->num_children == 3);
+
+   /* type of children[0] must be boolean */
+   slang_typeinfo_construct(&type0);
+   typeof_operation(A, &oper->children[0], &type0);
+   isBool = (type0.spec.type == SLANG_SPEC_BOOL);
+   slang_typeinfo_destruct(&type0);
+   if (!isBool) {
+      slang_info_log_error(A->log, "selector type is not boolean");
+      return NULL;
+   }
+
+   slang_typeinfo_construct(&type1);
+   slang_typeinfo_construct(&type2);
+   typeof_operation(A, &oper->children[1], &type1);
+   typeof_operation(A, &oper->children[2], &type2);
+   isEqual = slang_type_specifier_equal(&type1.spec, &type2.spec);
+   slang_typeinfo_destruct(&type1);
+   slang_typeinfo_destruct(&type2);
+   if (!isEqual) {
+      slang_info_log_error(A->log, "incompatible types for ?: operator");
+      return NULL;
+   }
+
+   /* size of x or y's type */
+   size = _slang_sizeof_type_specifier(&type1.spec);
+   assert(size > 0);
+
+   /* temporary var */
+   tmpDecl = _slang_gen_temporary(size);
+
+   /* the condition (child 0) */
+   cond = _slang_gen_operation(A, &oper->children[0]);
+   cond = new_cond(cond);
+
+   /* if-true body (child 1) */
+   tmpVar = new_node0(IR_VAR);
+   tmpVar->Store = tmpDecl->Store;
+   trueExpr = _slang_gen_operation(A, &oper->children[1]);
+   trueNode = new_node2(IR_COPY, tmpVar, trueExpr);
+
+   /* if-false body (child 2) */
+   tmpVar = new_node0(IR_VAR);
+   tmpVar->Store = tmpDecl->Store;
+   falseExpr = _slang_gen_operation(A, &oper->children[2]);
+   falseNode = new_node2(IR_COPY, tmpVar, falseExpr);
+
+   ifNode = new_if(cond, trueNode, falseNode);
+
+   /* tmp var value */
+   tmpVar = new_node0(IR_VAR);
+   tmpVar->Store = tmpDecl->Store;
+
+   tree = new_seq(ifNode, tmpVar);
+   tree = new_seq(tmpDecl, tree);
+
+   /*_slang_print_ir_tree(tree, 10);*/
+   return tree;
+}
+
+
+/**
+ * Generate code for &&.
+ */
+static slang_ir_node *
+_slang_gen_logical_and(slang_assemble_ctx *A, slang_operation *oper)
+{
+   /* rewrite "a && b" as  "a ? b : false" */
+   slang_operation *select;
+   slang_ir_node *n;
+
+   select = slang_operation_new(1);
+   select->type = SLANG_OPER_SELECT;
+   slang_operation_add_children(select, 3);
+
+   slang_operation_copy(slang_oper_child(select, 0), &oper->children[0]);
+   slang_operation_copy(slang_oper_child(select, 1), &oper->children[1]);
+   slang_operation_literal_bool(slang_oper_child(select, 2), GL_FALSE);
+
+   n = _slang_gen_select(A, select);
+   return n;
+}
+
+
+/**
+ * Generate code for ||.
+ */
+static slang_ir_node *
+_slang_gen_logical_or(slang_assemble_ctx *A, slang_operation *oper)
+{
+   /* rewrite "a || b" as  "a ? true : b" */
+   slang_operation *select;
+   slang_ir_node *n;
+
+   select = slang_operation_new(1);
+   select->type = SLANG_OPER_SELECT;
+   slang_operation_add_children(select, 3);
+
+   slang_operation_copy(slang_oper_child(select, 0), &oper->children[0]);
+   slang_operation_literal_bool(slang_oper_child(select, 1), GL_TRUE);
+   slang_operation_copy(slang_oper_child(select, 2), &oper->children[1]);
+
+   n = _slang_gen_select(A, select);
+   return n;
+}
+
+
+/**
+ * Generate IR tree for a return statement.
+ */
+static slang_ir_node *
+_slang_gen_return(slang_assemble_ctx * A, slang_operation *oper)
+{
+   assert(oper->type == SLANG_OPER_RETURN);
+   return new_return(A->curFuncEndLabel);
+}
+
+
+#if 0
+/**
+ * Determine if the given operation/expression is const-valued.
+ */
+static GLboolean
+_slang_is_constant_expr(const slang_operation *oper)
+{
+   slang_variable *var;
+   GLuint i;
+
+   switch (oper->type) {
+   case SLANG_OPER_IDENTIFIER:
+      var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE);
+      if (var && var->type.qualifier == SLANG_QUAL_CONST)
+         return GL_TRUE;
+      return GL_FALSE;
+   default:
+      for (i = 0; i < oper->num_children; i++) {
+         if (!_slang_is_constant_expr(&oper->children[i]))
+            return GL_FALSE;
+      }
+      return GL_TRUE;
+   }
+}
+#endif
+
+
+/**
+ * Check if an assignment of type t1 to t0 is legal.
+ * XXX more cases needed.
+ */
+static GLboolean
+_slang_assignment_compatible(slang_assemble_ctx *A,
+                             slang_operation *op0,
+                             slang_operation *op1)
+{
+   slang_typeinfo t0, t1;
+   GLuint sz0, sz1;
+
+   if (op0->type == SLANG_OPER_POSTINCREMENT ||
+       op0->type == SLANG_OPER_POSTDECREMENT) {
+      return GL_FALSE;
+   }
+
+   slang_typeinfo_construct(&t0);
+   typeof_operation(A, op0, &t0);
+
+   slang_typeinfo_construct(&t1);
+   typeof_operation(A, op1, &t1);
+
+   sz0 = _slang_sizeof_type_specifier(&t0.spec);
+   sz1 = _slang_sizeof_type_specifier(&t1.spec);
+
+#if 1
+   if (sz0 != sz1) {
+      /*printf("assignment size mismatch %u vs %u\n", sz0, sz1);*/
+      return GL_FALSE;
+   }
+#endif
+
+   if (t0.spec.type == SLANG_SPEC_STRUCT &&
+       t1.spec.type == SLANG_SPEC_STRUCT &&
+       t0.spec._struct->a_name != t1.spec._struct->a_name)
+      return GL_FALSE;
+
+   if (t0.spec.type == SLANG_SPEC_FLOAT &&
+       t1.spec.type == SLANG_SPEC_BOOL)
+      return GL_FALSE;
+
+#if 0 /* not used just yet - causes problems elsewhere */
+   if (t0.spec.type == SLANG_SPEC_INT &&
+       t1.spec.type == SLANG_SPEC_FLOAT)
+      return GL_FALSE;
+#endif
+
+   if (t0.spec.type == SLANG_SPEC_BOOL &&
+       t1.spec.type == SLANG_SPEC_FLOAT)
+      return GL_FALSE;
+
+   if (t0.spec.type == SLANG_SPEC_BOOL &&
+       t1.spec.type == SLANG_SPEC_INT)
+      return GL_FALSE;
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Generate IR tree for a local variable declaration.
+ * Basically do some error checking and call _slang_gen_var_decl().
+ */
+static slang_ir_node *
+_slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper)
+{
+   const char *varName = (char *) oper->a_id;
+   slang_variable *var;
+   slang_ir_node *varDecl;
+   slang_operation *initializer;
+
+   assert(oper->type == SLANG_OPER_VARIABLE_DECL);
+   assert(oper->num_children <= 1);
+
+
+   /* lookup the variable by name */
+   var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE);
+   if (!var)
+      return NULL;  /* "shouldn't happen" */
+
+   if (var->type.qualifier == SLANG_QUAL_ATTRIBUTE ||
+       var->type.qualifier == SLANG_QUAL_VARYING ||
+       var->type.qualifier == SLANG_QUAL_UNIFORM) {
+      /* can't declare attribute/uniform vars inside functions */
+      slang_info_log_error(A->log,
+                "local variable '%s' cannot be an attribute/uniform/varying",
+                varName);
+      return NULL;
+   }
+
+#if 0
+   if (v->declared) {
+      slang_info_log_error(A->log, "variable '%s' redeclared", varName);
+      return NULL;
+   }
+#endif
+
+   /* check if the var has an initializer */
+   if (oper->num_children > 0) {
+      assert(oper->num_children == 1);
+      initializer = &oper->children[0];
+   }
+   else if (var->initializer) {
+      initializer = var->initializer;
+   }
+   else {
+      initializer = NULL;
+   }
+
+   if (initializer) {
+      /* check/compare var type and initializer type */
+      if (!_slang_assignment_compatible(A, oper, initializer)) {
+         slang_info_log_error(A->log, "incompatible types in assignment");
+         return NULL;
+      }         
+   }
+   else {
+      if (var->type.qualifier == SLANG_QUAL_CONST) {
+         slang_info_log_error(A->log,
+                       "const-qualified variable '%s' requires initializer",
+                       varName);
+         return NULL;
+      }
+   }
+
+   /* Generate IR node */
+   varDecl = _slang_gen_var_decl(A, var, initializer);
+   if (!varDecl)
+      return NULL;
+
+   return varDecl;
+}
+
+
+/**
+ * Generate IR tree for a reference to a variable (such as in an expression).
+ * This is different from a variable declaration.
+ */
+static slang_ir_node *
+_slang_gen_variable(slang_assemble_ctx * A, slang_operation *oper)
+{
+   /* If there's a variable associated with this oper (from inlining)
+    * use it.  Otherwise, use the oper's var id.
+    */
+   slang_atom name = oper->var ? oper->var->a_name : oper->a_id;
+   slang_variable *var = _slang_variable_locate(oper->locals, name, GL_TRUE);
+   slang_ir_node *n;
+   if (!var || !var->declared) {
+      /* Geometry shaders set gl_VerticesIn at link time
+       * so we need to wait with resolving this variable
+       * until then */
+      if (A->program->Target == MESA_GEOMETRY_PROGRAM &&
+          !strcmp((char*)name, "gl_VerticesIn") ){
+         A->UnresolvedRefs = GL_TRUE;
+         return NULL;
+      }
+      slang_info_log_error(A->log, "undefined variable '%s'", (char *) name);
+      return NULL;
+   }
+   n = new_var(A, var);
+   return n;
+}
+
+
+
+/**
+ * Return the number of components actually named by the swizzle.
+ * Recall that swizzles may have undefined/don't-care values.
+ */
+static GLuint
+swizzle_size(GLuint swizzle)
+{
+   GLuint size = 0, i;
+   for (i = 0; i < 4; i++) {
+      GLuint swz = GET_SWZ(swizzle, i);
+      size += (swz <= 3);
+   }
+   return size;
+}
+
+
+static slang_ir_node *
+_slang_gen_swizzle(slang_ir_node *child, GLuint swizzle)
+{
+   slang_ir_node *n = new_node1(IR_SWIZZLE, child);
+   assert(child);
+   if (n) {
+      assert(!n->Store);
+      n->Store = _slang_new_ir_storage_relative(0,
+                                                swizzle_size(swizzle),
+                                                child->Store);
+      assert(n->Store);
+      n->Store->Swizzle = swizzle;
+   }
+   return n;
+}
+
+
+static GLboolean
+is_store_writable(const slang_assemble_ctx *A, const slang_ir_storage *store)
+{
+   while (store->Parent)
+      store = store->Parent;
+
+   if (!(store->File == PROGRAM_OUTPUT ||
+         store->File == PROGRAM_TEMPORARY ||
+         (store->File == PROGRAM_VARYING &&
+          (A->program->Target == GL_VERTEX_PROGRAM_ARB ||
+           A->program->Target == MESA_GEOMETRY_PROGRAM)))) {
+      return GL_FALSE;
+   }
+   else {
+      return GL_TRUE;
+   }
+}
+
+
+/**
+ * Walk up an IR storage path to compute the final swizzle.
+ * This is used when we find an expression such as "foo.xz.yx".
+ */
+static GLuint
+root_swizzle(const slang_ir_storage *st)
+{
+   GLuint swizzle = st->Swizzle;
+   while (st->Parent) {
+      st = st->Parent;
+      swizzle = _slang_swizzle_swizzle(st->Swizzle, swizzle);
+   }
+   return swizzle;
+}
+
+
+/**
+ * Generate IR tree for an assignment (=).
+ */
+static slang_ir_node *
+_slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper)
+{
+   slang_operation *pred = NULL;
+   slang_ir_node *n = NULL;
+
+   if (oper->children[0].type == SLANG_OPER_IDENTIFIER) {
+      /* Check that var is writeable */
+      const char *varName = (char *) oper->children[0].a_id;
+      slang_variable *var
+         = _slang_variable_locate(oper->children[0].locals,
+                                  oper->children[0].a_id, GL_TRUE);
+      if (!var) {
+         slang_info_log_error(A->log, "undefined variable '%s'", varName);
+         return NULL;
+      }
+
+      if (var->type.qualifier == SLANG_QUAL_CONST ||
+          var->type.qualifier == SLANG_QUAL_ATTRIBUTE ||
+          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'",
+                              varName);
+         return NULL;
+      }
+
+      /* check if we need to predicate this assignment based on __notRetFlag */
+      if ((var->is_global ||
+           var->type.qualifier == SLANG_QUAL_OUT ||
+           var->type.qualifier == SLANG_QUAL_INOUT) && A->UseReturnFlag) {
+         /* create predicate, used below */
+         pred = slang_operation_new(1);
+         pred->type = SLANG_OPER_IDENTIFIER;
+         pred->a_id = slang_atom_pool_atom(A->atoms, "__notRetFlag");
+         pred->locals->outer_scope = oper->locals->outer_scope;
+      }
+   }
+
+   if (oper->children[0].type == SLANG_OPER_IDENTIFIER &&
+       oper->children[1].type == SLANG_OPER_CALL) {
+      /* Special case of:  x = f(a, b)
+       * Replace with f(a, b, x)  (where x == hidden __retVal out param)
+       *
+       * XXX this could be even more effective if we could accomodate
+       * cases such as "v.x = f();"  - would help with typical vertex
+       * transformation.
+       */
+      n = _slang_gen_function_call_name(A,
+                                      (const char *) oper->children[1].a_id,
+                                      &oper->children[1], &oper->children[0]);
+   }
+   else {
+      slang_ir_node *lhs, *rhs;
+
+      /* lhs and rhs type checking */
+      if (!_slang_assignment_compatible(A,
+                                        &oper->children[0],
+                                        &oper->children[1])) {
+         slang_info_log_error(A->log, "incompatible types in assignment");
+         return NULL;
+      }
+
+      lhs = _slang_gen_operation(A, &oper->children[0]);
+      if (!lhs) {
+         return NULL;
+      }
+
+      if (!lhs->Store) {
+         slang_info_log_error(A->log,
+                              "invalid left hand side for assignment");
+         return NULL;
+      }
+
+      /* check that lhs is writable */
+      if (!is_store_writable(A, lhs->Store)) {
+         slang_info_log_error(A->log,
+                              "illegal assignment to read-only l-value");
+         return NULL;
+      }
+
+      rhs = _slang_gen_operation(A, &oper->children[1]);
+      if (lhs && rhs) {
+         /* convert lhs swizzle into writemask */
+         const GLuint swizzle = root_swizzle(lhs->Store);
+         GLuint writemask, newSwizzle = 0x0;
+         if (!swizzle_to_writemask(A, swizzle, &writemask, &newSwizzle)) {
+            /* Non-simple writemask, need to swizzle right hand side in
+             * order to put components into the right place.
+             */
+            rhs = _slang_gen_swizzle(rhs, newSwizzle);
+         }
+         n = new_node2(IR_COPY, lhs, rhs);
+      }
+      else {
+         return NULL;
+      }
+   }
+
+   if (n && pred) {
+      /* predicate the assignment code on __notRetFlag */
+      slang_ir_node *top, *cond;
+
+      cond = _slang_gen_operation(A, pred);
+      top = new_if(cond, n, NULL);
+      return top;
+   }
+   return n;
+}
+
+
+/**
+ * Generate IR tree for referencing a field in a struct (or basic vector type)
+ */
+static slang_ir_node *
+_slang_gen_struct_field(slang_assemble_ctx * A, slang_operation *oper)
+{
+   slang_typeinfo ti;
+
+   /* type of struct */
+   slang_typeinfo_construct(&ti);
+   typeof_operation(A, &oper->children[0], &ti);
+
+   if (_slang_type_is_vector(ti.spec.type)) {
+      /* the field should be a swizzle */
+      const GLuint rows = _slang_type_dim(ti.spec.type);
+      slang_swizzle swz;
+      slang_ir_node *n;
+      GLuint swizzle;
+      if (!_slang_is_swizzle((char *) oper->a_id, rows, &swz)) {
+         slang_info_log_error(A->log, "Bad swizzle");
+         return NULL;
+      }
+      swizzle = MAKE_SWIZZLE4(swz.swizzle[0],
+                              swz.swizzle[1],
+                              swz.swizzle[2],
+                              swz.swizzle[3]);
+
+      n = _slang_gen_operation(A, &oper->children[0]);
+      /* create new parent node with swizzle */
+      if (n)
+         n = _slang_gen_swizzle(n, swizzle);
+      return n;
+   }
+   else if (   ti.spec.type == SLANG_SPEC_FLOAT
+            || ti.spec.type == SLANG_SPEC_INT
+            || ti.spec.type == SLANG_SPEC_BOOL) {
+      const GLuint rows = 1;
+      slang_swizzle swz;
+      slang_ir_node *n;
+      GLuint swizzle;
+      if (!_slang_is_swizzle((char *) oper->a_id, rows, &swz)) {
+         slang_info_log_error(A->log, "Bad swizzle");
+      }
+      swizzle = MAKE_SWIZZLE4(swz.swizzle[0],
+                              swz.swizzle[1],
+                              swz.swizzle[2],
+                              swz.swizzle[3]);
+      n = _slang_gen_operation(A, &oper->children[0]);
+      /* create new parent node with swizzle */
+      n = _slang_gen_swizzle(n, swizzle);
+      return n;
+   }
+   else {
+      /* the field is a structure member (base.field) */
+      /* oper->children[0] is the base */
+      /* oper->a_id is the field name */
+      slang_ir_node *base, *n;
+      slang_typeinfo field_ti;
+      GLint fieldSize, fieldOffset = -1;
+
+      /* type of field */
+      slang_typeinfo_construct(&field_ti);
+      typeof_operation(A, oper, &field_ti);
+
+      fieldSize = _slang_sizeof_type_specifier(&field_ti.spec);
+      if (fieldSize > 0)
+         fieldOffset = _slang_field_offset(&ti.spec, oper->a_id);
+
+      if (fieldSize == 0 || fieldOffset < 0) {
+         const char *structName;
+         if (ti.spec._struct)
+            structName = (char *) ti.spec._struct->a_name;
+         else
+            structName = "unknown";
+         slang_info_log_error(A->log,
+                              "\"%s\" is not a member of struct \"%s\"",
+                              (char *) oper->a_id, structName);
+         return NULL;
+      }
+      assert(fieldSize >= 0);
+
+      base = _slang_gen_operation(A, &oper->children[0]);
+      if (!base) {
+         /* error msg should have already been logged */
+         return NULL;
+      }
+
+      n = new_node1(IR_FIELD, base);
+      if (!n)
+         return NULL;
+
+      n->Field = (char *) oper->a_id;
+
+      /* Store the field's offset in storage->Index */
+      n->Store = _slang_new_ir_storage(base->Store->File,
+                                       fieldOffset,
+                                       fieldSize);
+
+      return n;
+   }
+}
+
+
+/**
+ * Gen code for array indexing.
+ */
+static slang_ir_node *
+_slang_gen_array_element(slang_assemble_ctx * A, slang_operation *oper)
+{
+   slang_typeinfo array_ti;
+
+   /* get array's type info */
+   slang_typeinfo_construct(&array_ti);
+   typeof_operation(A, &oper->children[0], &array_ti);
+
+   if (_slang_type_is_vector(array_ti.spec.type)) {
+      /* indexing a simple vector type: "vec4 v; v[0]=p;" */
+      /* translate the index into a swizzle/writemask: "v.x=p" */
+      const GLuint max = _slang_type_dim(array_ti.spec.type);
+      GLint index;
+      slang_ir_node *n;
+
+      index = (GLint) oper->children[1].literal[0];
+      if (oper->children[1].type != SLANG_OPER_LITERAL_INT ||
+          index >= (GLint) max) {
+#if 0
+         slang_info_log_error(A->log, "Invalid array index for vector type");
+         printf("type = %d\n", oper->children[1].type);
+         printf("index = %d, max = %d\n", index, max);
+         printf("array = %s\n", (char*)oper->children[0].a_id);
+         printf("index = %s\n", (char*)oper->children[1].a_id);
+         return NULL;
+#else
+         index = 0;
+#endif
+      }
+
+      n = _slang_gen_operation(A, &oper->children[0]);
+      if (n) {
+         /* use swizzle to access the element */
+         GLuint swizzle = MAKE_SWIZZLE4(SWIZZLE_X + index,
+                                        SWIZZLE_NIL,
+                                        SWIZZLE_NIL,
+                                        SWIZZLE_NIL);
+         n = _slang_gen_swizzle(n, swizzle);
+      }
+      return n;
+   }
+   else {
+      /* conventional array */
+      slang_typeinfo elem_ti;
+      slang_ir_node *elem, *array, *index;
+      GLint elemSize, arrayLen;
+
+      /* size of array element */
+      slang_typeinfo_construct(&elem_ti);
+      typeof_operation(A, oper, &elem_ti);
+      elemSize = _slang_sizeof_type_specifier(&elem_ti.spec);
+
+      if (_slang_type_is_matrix(array_ti.spec.type))
+         arrayLen = _slang_type_dim(array_ti.spec.type);
+      else
+         arrayLen = array_ti.array_len;
+
+      slang_typeinfo_destruct(&array_ti);
+      slang_typeinfo_destruct(&elem_ti);
+
+      if (elemSize <= 0) {
+         /* unknown var or type */
+         slang_info_log_error(A->log, "Undefined variable or type");
+         return NULL;
+      }
+
+      array = _slang_gen_operation(A, &oper->children[0]);
+      index = _slang_gen_operation(A, &oper->children[1]);
+      if (array && index) {
+         /* bounds check */
+         GLint constIndex = -1;
+         if (index->Opcode == IR_FLOAT) {
+            constIndex = (int) index->Value[0];
+            if (constIndex < 0 || constIndex >= arrayLen) {
+               slang_info_log_error(A->log,
+                                "Array index out of bounds (index=%d size=%d)",
+                                 constIndex, arrayLen);
+               _slang_free_ir_tree(array);
+               _slang_free_ir_tree(index);
+               return NULL;
+            }
+         }
+
+         if (!array->Store) {
+            slang_info_log_error(A->log, "Invalid array");
+            return NULL;
+         }
+
+         elem = new_node2(IR_ELEMENT, array, index);
+
+         /* The storage info here will be updated during code emit */
+         elem->Store = _slang_new_ir_storage(array->Store->File,
+                                             array->Store->Index,
+                                             elemSize);
+         elem->Store->Swizzle = _slang_var_swizzle(elemSize, 0);
+         return elem;
+      }
+      else {
+         _slang_free_ir_tree(array);
+         _slang_free_ir_tree(index);
+         return NULL;
+      }
+   }
+}
+
+
+static slang_ir_node *
+_slang_gen_compare(slang_assemble_ctx *A, slang_operation *oper,
+                   slang_ir_opcode opcode)
+{
+   slang_typeinfo t0, t1;
+   slang_ir_node *n;
+   
+   slang_typeinfo_construct(&t0);
+   typeof_operation(A, &oper->children[0], &t0);
+
+   slang_typeinfo_construct(&t1);
+   typeof_operation(A, &oper->children[0], &t1);
+
+   if (t0.spec.type == SLANG_SPEC_ARRAY ||
+       t1.spec.type == SLANG_SPEC_ARRAY) {
+      slang_info_log_error(A->log, "Illegal array comparison");
+      return NULL;
+   }
+
+   if (oper->type != SLANG_OPER_EQUAL &&
+       oper->type != SLANG_OPER_NOTEQUAL) {
+      /* <, <=, >, >= can only be used with scalars */
+      if ((t0.spec.type != SLANG_SPEC_INT &&
+           t0.spec.type != SLANG_SPEC_FLOAT) ||
+          (t1.spec.type != SLANG_SPEC_INT &&
+           t1.spec.type != SLANG_SPEC_FLOAT)) {
+         slang_info_log_error(A->log, "Incompatible type(s) for inequality operator");
+         return NULL;
+      }
+   }
+
+   n =  new_node2(opcode,
+                  _slang_gen_operation(A, &oper->children[0]),
+                  _slang_gen_operation(A, &oper->children[1]));
+
+   /* result is a bool (size 1) */
+   n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, 1);
+
+   return n;
+}
+
+
+#if 0
+static void
+print_vars(slang_variable_scope *s)
+{
+   int i;
+   printf("vars: ");
+   for (i = 0; i < s->num_variables; i++) {
+      printf("%s %d, \n",
+             (char*) s->variables[i]->a_name,
+             s->variables[i]->declared);
+   }
+
+   printf("\n");
+}
+#endif
+
+
+#if 0
+static void
+_slang_undeclare_vars(slang_variable_scope *locals)
+{
+   if (locals->num_variables > 0) {
+      int i;
+      for (i = 0; i < locals->num_variables; i++) {
+         slang_variable *v = locals->variables[i];
+         printf("undeclare %s at %p\n", (char*) v->a_name, v);
+         v->declared = GL_FALSE;
+      }
+   }
+}
+#endif
+
+
+/**
+ * Generate IR tree for a slang_operation (AST node)
+ */
+static slang_ir_node *
+_slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper)
+{
+   switch (oper->type) {
+   case SLANG_OPER_BLOCK_NEW_SCOPE:
+      {
+         slang_ir_node *n;
+
+         _slang_push_var_table(A->vartable);
+
+         oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; /* temp change */
+         n = _slang_gen_operation(A, oper);
+         oper->type = SLANG_OPER_BLOCK_NEW_SCOPE; /* restore */
+
+         _slang_pop_var_table(A->vartable);
+
+         /*_slang_undeclare_vars(oper->locals);*/
+         /*print_vars(oper->locals);*/
+
+         if (n)
+            n = new_node1(IR_SCOPE, n);
+         return n;
+      }
+      break;
+
+   case SLANG_OPER_BLOCK_NO_NEW_SCOPE:
+      /* list of operations */
+      if (oper->num_children > 0)
+      {
+         slang_ir_node *n, *tree = NULL;
+         GLuint i;
+
+         for (i = 0; i < oper->num_children; i++) {
+            n = _slang_gen_operation(A, &oper->children[i]);
+            if (!n) {
+               _slang_free_ir_tree(tree);
+               return NULL; /* error must have occured */
+            }
+            tree = new_seq(tree, n);
+         }
+
+         return tree;
+      }
+      else {
+         return new_node0(IR_NOP);
+      }
+
+   case SLANG_OPER_EXPRESSION:
+      return _slang_gen_operation(A, &oper->children[0]);
+
+   case SLANG_OPER_FOR:
+      return _slang_gen_for(A, oper);
+   case SLANG_OPER_DO:
+      return _slang_gen_do(A, oper);
+   case SLANG_OPER_WHILE:
+      return _slang_gen_while(A, oper);
+   case SLANG_OPER_BREAK:
+      if (!current_loop_oper(A)) {
+         slang_info_log_error(A->log, "'break' not in loop");
+         return NULL;
+      }
+      return new_break(current_loop_ir(A));
+   case SLANG_OPER_CONTINUE:
+      if (!current_loop_oper(A)) {
+         slang_info_log_error(A->log, "'continue' not in loop");
+         return NULL;
+      }
+      return _slang_gen_continue(A, oper);
+   case SLANG_OPER_DISCARD:
+      return new_node0(IR_KILL);
+
+   case SLANG_OPER_EQUAL:
+      return _slang_gen_compare(A, oper, IR_EQUAL);
+   case SLANG_OPER_NOTEQUAL:
+      return _slang_gen_compare(A, oper, IR_NOTEQUAL);
+   case SLANG_OPER_GREATER:
+      return _slang_gen_compare(A, oper, IR_SGT);
+   case SLANG_OPER_LESS:
+      return _slang_gen_compare(A, oper, IR_SLT);
+   case SLANG_OPER_GREATEREQUAL:
+      return _slang_gen_compare(A, oper, IR_SGE);
+   case SLANG_OPER_LESSEQUAL:
+      return _slang_gen_compare(A, oper, IR_SLE);
+   case SLANG_OPER_ADD:
+      {
+        slang_ir_node *n;
+         assert(oper->num_children == 2);
+        n = _slang_gen_function_call_name(A, "+", oper, NULL);
+        return n;
+      }
+   case SLANG_OPER_SUBTRACT:
+      {
+        slang_ir_node *n;
+         assert(oper->num_children == 2);
+        n = _slang_gen_function_call_name(A, "-", oper, NULL);
+        return n;
+      }
+   case SLANG_OPER_MULTIPLY:
+      {
+        slang_ir_node *n;
+         assert(oper->num_children == 2);
+         n = _slang_gen_function_call_name(A, "*", oper, NULL);
+        return n;
+      }
+   case SLANG_OPER_DIVIDE:
+      {
+         slang_ir_node *n;
+         assert(oper->num_children == 2);
+        n = _slang_gen_function_call_name(A, "/", oper, NULL);
+        return n;
+      }
+   case SLANG_OPER_MINUS:
+      {
+         slang_ir_node *n;
+         assert(oper->num_children == 1);
+        n = _slang_gen_function_call_name(A, "-", oper, NULL);
+        return n;
+      }
+   case SLANG_OPER_PLUS:
+      /* +expr   --> do nothing */
+      return _slang_gen_operation(A, &oper->children[0]);
+   case SLANG_OPER_VARIABLE_DECL:
+      return _slang_gen_declaration(A, oper);
+   case SLANG_OPER_ASSIGN:
+      return _slang_gen_assignment(A, oper);
+   case SLANG_OPER_ADDASSIGN:
+      {
+        slang_ir_node *n;
+         assert(oper->num_children == 2);
+        n = _slang_gen_function_call_name(A, "+=", oper, NULL);
+        return n;
+      }
+   case SLANG_OPER_SUBASSIGN:
+      {
+        slang_ir_node *n;
+         assert(oper->num_children == 2);
+        n = _slang_gen_function_call_name(A, "-=", oper, NULL);
+        return n;
+      }
+      break;
+   case SLANG_OPER_MULASSIGN:
+      {
+        slang_ir_node *n;
+         assert(oper->num_children == 2);
+        n = _slang_gen_function_call_name(A, "*=", oper, NULL);
+        return n;
+      }
+   case SLANG_OPER_DIVASSIGN:
+      {
+        slang_ir_node *n;
+         assert(oper->num_children == 2);
+        n = _slang_gen_function_call_name(A, "/=", oper, NULL);
+        return n;
+      }
+   case SLANG_OPER_LOGICALAND:
+      {
+        slang_ir_node *n;
+         assert(oper->num_children == 2);
+        n = _slang_gen_logical_and(A, oper);
+        return n;
+      }
+   case SLANG_OPER_LOGICALOR:
+      {
+        slang_ir_node *n;
+         assert(oper->num_children == 2);
+        n = _slang_gen_logical_or(A, oper);
+        return n;
+      }
+   case SLANG_OPER_LOGICALXOR:
+      return _slang_gen_xor(A, oper);
+   case SLANG_OPER_NOT:
+      return _slang_gen_not(A, oper);
+   case SLANG_OPER_SELECT:  /* b ? x : y */
+      {
+        slang_ir_node *n;
+         assert(oper->num_children == 3);
+        n = _slang_gen_select(A, oper);
+        return n;
+      }
+
+   case SLANG_OPER_ASM:
+      return _slang_gen_asm(A, oper, NULL);
+   case SLANG_OPER_CALL:
+      return _slang_gen_function_call_name(A, (const char *) oper->a_id,
+                                           oper, NULL);
+   case SLANG_OPER_METHOD:
+      return _slang_gen_method_call(A, oper);
+   case SLANG_OPER_RETURN:
+      return _slang_gen_return(A, oper);
+   case SLANG_OPER_RETURN_INLINED:
+      return _slang_gen_return(A, oper);
+   case SLANG_OPER_LABEL:
+      return new_label(oper->label);
+   case SLANG_OPER_IDENTIFIER:
+      return _slang_gen_variable(A, oper);
+   case SLANG_OPER_IF:
+      return _slang_gen_if(A, oper);
+   case SLANG_OPER_FIELD:
+      return _slang_gen_struct_field(A, oper);
+   case SLANG_OPER_SUBSCRIPT:
+      return _slang_gen_array_element(A, oper);
+   case SLANG_OPER_LITERAL_FLOAT:
+      /* fall-through */
+   case SLANG_OPER_LITERAL_INT:
+      /* fall-through */
+   case SLANG_OPER_LITERAL_BOOL:
+      return new_float_literal(oper->literal, oper->literal_size);
+
+   case SLANG_OPER_POSTINCREMENT:   /* var++ */
+      {
+        slang_ir_node *n;
+         assert(oper->num_children == 1);
+        n = _slang_gen_function_call_name(A, "__postIncr", oper, NULL);
+        return n;
+      }
+   case SLANG_OPER_POSTDECREMENT:   /* var-- */
+      {
+        slang_ir_node *n;
+         assert(oper->num_children == 1);
+        n = _slang_gen_function_call_name(A, "__postDecr", oper, NULL);
+        return n;
+      }
+   case SLANG_OPER_PREINCREMENT:   /* ++var */
+      {
+        slang_ir_node *n;
+         assert(oper->num_children == 1);
+        n = _slang_gen_function_call_name(A, "++", oper, NULL);
+        return n;
+      }
+   case SLANG_OPER_PREDECREMENT:   /* --var */
+      {
+        slang_ir_node *n;
+         assert(oper->num_children == 1);
+        n = _slang_gen_function_call_name(A, "--", oper, NULL);
+        return n;
+      }
+
+   case SLANG_OPER_NON_INLINED_CALL:
+   case SLANG_OPER_SEQUENCE:
+      {
+         slang_ir_node *tree = NULL;
+         GLuint i;
+         for (i = 0; i < oper->num_children; i++) {
+            slang_ir_node *n = _slang_gen_operation(A, &oper->children[i]);
+            tree = new_seq(tree, n);
+            if (n)
+               tree->Store = n->Store;
+         }
+         if (oper->type == SLANG_OPER_NON_INLINED_CALL) {
+            tree = new_function_call(tree, oper->label);
+         }
+         return tree;
+      }
+
+   case SLANG_OPER_NONE:
+   case SLANG_OPER_VOID:
+      /* returning NULL here would generate an error */
+      return new_node0(IR_NOP);
+
+   default:
+      _mesa_problem(NULL, "bad node type %d in _slang_gen_operation",
+                    oper->type);
+      return new_node0(IR_NOP);
+   }
+
+   return NULL;
+}
+
+
+/**
+ * Check if the given type specifier is a rectangular texture sampler.
+ */
+static GLboolean
+is_rect_sampler_spec(const slang_type_specifier *spec)
+{
+   while (spec->_array) {
+      spec = spec->_array;
+   }
+   return spec->type == SLANG_SPEC_SAMPLER_RECT ||
+          spec->type == SLANG_SPEC_SAMPLER_RECT_SHADOW;
+}
+
+
+
+/**
+ * Called by compiler when a global variable has been parsed/compiled.
+ * Here we examine the variable's type to determine what kind of register
+ * storage will be used.
+ *
+ * A uniform such as "gl_Position" will become the register specification
+ * (PROGRAM_OUTPUT, VERT_RESULT_HPOS).  Or, uniform "gl_FogFragCoord"
+ * will be (PROGRAM_INPUT, FRAG_ATTRIB_FOGC).
+ *
+ * Samplers are interesting.  For "uniform sampler2D tex;" we'll specify
+ * (PROGRAM_SAMPLER, index) where index is resolved at link-time to an
+ * actual texture unit (as specified by the user calling glUniform1i()).
+ */
+GLboolean
+_slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
+                               slang_unit_type type)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_program *prog = A->program;
+   const char *varName = (char *) var->a_name;
+   GLboolean success = GL_TRUE;
+   slang_ir_storage *store = NULL;
+   int dbg = 0;
+   const GLenum datatype = _slang_gltype_from_specifier(&var->type.specifier);
+   const GLint size = _slang_sizeof_type_specifier(&var->type.specifier);
+   const GLint arrayLen = _slang_array_length(var);
+   const GLint totalSize = _slang_array_size(size, arrayLen);
+   GLint texIndex = sampler_to_texture_index(var->type.specifier.type);
+
+   var->is_global = GL_TRUE;
+
+   /* check for sampler2D arrays */
+   if (texIndex == -1 && var->type.specifier._array)
+      texIndex = sampler_to_texture_index(var->type.specifier._array->type);
+
+   if (texIndex != -1) {
+      /* This is a texture sampler variable...
+       * store->File = PROGRAM_SAMPLER
+       * store->Index = sampler number (0..7, typically)
+       * store->Size = texture type index (1D, 2D, 3D, cube, etc)
+       */
+      if (var->initializer) {
+         slang_info_log_error(A->log, "illegal assignment to '%s'", varName);
+         return GL_FALSE;
+      }
+#if FEATURE_es2_glsl /* XXX should use FEATURE_texture_rect */
+      /* disallow rect samplers */
+      if (ctx->API == API_OPENGLES2 &&
+         is_rect_sampler_spec(&var->type.specifier)) {
+         slang_info_log_error(A->log, "invalid sampler type for '%s'", varName);
+         return GL_FALSE;
+      }
+#else
+      (void) is_rect_sampler_spec; /* silence warning */
+      (void) ctx;
+#endif
+      {
+         GLint sampNum = _mesa_add_sampler(prog->Parameters, varName, datatype);
+         store = _slang_new_ir_storage_sampler(sampNum, texIndex, totalSize);
+
+         /* If we have a sampler array, then we need to allocate the 
+         * additional samplers to ensure we don't allocate them elsewhere.
+         * We can't directly use _mesa_add_sampler() as that checks the
+         * varName and gets a match, so we call _mesa_add_parameter()
+         * directly and use the last sampler number from the call above.
+         */
+        if (arrayLen > 0) {
+           GLint a = arrayLen - 1;
+           GLint i;
+           for (i = 0; i < a; i++) {
+               GLfloat value = (GLfloat)(i + sampNum + 1);
+               (void) _mesa_add_parameter(prog->Parameters, PROGRAM_SAMPLER,
+                                 varName, 1, datatype, &value, NULL, 0x0);
+           }
+        }
+      }
+      if (dbg) printf("SAMPLER ");
+   }
+   else if (var->type.qualifier == SLANG_QUAL_UNIFORM) {
+      /* Uniform variable */
+      const GLuint swizzle = _slang_var_swizzle(totalSize, 0);
+
+      if (prog) {
+         /* user-defined uniform */
+         if (datatype == GL_NONE) {
+           if ((var->type.specifier.type == SLANG_SPEC_ARRAY &&
+                var->type.specifier._array->type == SLANG_SPEC_STRUCT) ||
+                (var->type.specifier.type == SLANG_SPEC_STRUCT)) {
+               /* temporary work-around */
+               GLenum datatype = GL_FLOAT;
+               GLint uniformLoc = _mesa_add_uniform(prog->Parameters, varName,
+                                                    totalSize, datatype, NULL);
+               store = _slang_new_ir_storage_swz(PROGRAM_UNIFORM, uniformLoc,
+                                                 totalSize, swizzle);
+        
+              if (arrayLen > 0) {
+                 GLint a = arrayLen - 1;
+                 GLint i;
+                 for (i = 0; i < a; i++) {
+                     GLfloat value = (GLfloat)(i + uniformLoc + 1);
+                     (void) _mesa_add_parameter(prog->Parameters, PROGRAM_UNIFORM,
+                                 varName, 1, datatype, &value, NULL, 0x0);
+                  }
+              }
+
+               /* XXX what we need to do is unroll the struct into its
+                * basic types, creating a uniform variable for each.
+                * For example:
+                * struct foo {
+                *   vec3 a;
+                *   vec4 b;
+                * };
+                * uniform foo f;
+                *
+                * Should produce uniforms:
+                * "f.a"  (GL_FLOAT_VEC3)
+                * "f.b"  (GL_FLOAT_VEC4)
+                */
+
+               if (var->initializer) {
+                  slang_info_log_error(A->log,
+                     "unsupported initializer for uniform '%s'", varName);
+                  return GL_FALSE;
+               }
+            }
+            else {
+               slang_info_log_error(A->log,
+                                    "invalid datatype for uniform variable %s",
+                                    varName);
+               return GL_FALSE;
+            }
+         }
+         else {
+            /* non-struct uniform */
+            if (!_slang_gen_var_decl(A, var, var->initializer))
+               return GL_FALSE;
+            store = var->store;
+         }
+      }
+      else {
+         /* pre-defined uniform, like gl_ModelviewMatrix */
+         /* We know it's a uniform, but don't allocate storage unless
+          * it's really used.
+          */
+         store = _slang_new_ir_storage_swz(PROGRAM_STATE_VAR, -1,
+                                           totalSize, swizzle);
+      }
+      if (dbg) printf("UNIFORM (sz %d) ", totalSize);
+   }
+   else if (var->type.qualifier == SLANG_QUAL_VARYING) {
+      /* varyings must be float, vec or mat */
+      if (!_slang_type_is_float_vec_mat(var->type.specifier.type) &&
+          var->type.specifier.type != SLANG_SPEC_ARRAY) {
+         slang_info_log_error(A->log,
+                              "varying '%s' must be float/vector/matrix",
+                              varName);
+         return GL_FALSE;
+      }
+
+      if (var->initializer) {
+         slang_info_log_error(A->log, "illegal initializer for varying '%s'",
+                              varName);
+         return GL_FALSE;
+      }
+
+      if (prog) {
+         /* user-defined varying */
+         GLbitfield flags;
+         GLint varyingLoc;
+         GLuint swizzle;
+
+         flags = 0x0;
+         if (var->type.centroid == SLANG_CENTROID)
+            flags |= PROG_PARAM_BIT_CENTROID;
+         if (var->type.variant == SLANG_INVARIANT)
+            flags |= PROG_PARAM_BIT_INVARIANT;
+
+         varyingLoc = _mesa_add_varying(prog->Varying, varName,
+                                        totalSize, GL_NONE, flags);
+         swizzle = _slang_var_swizzle(size, 0);
+         store = _slang_new_ir_storage_swz(PROGRAM_VARYING, varyingLoc,
+                                           totalSize, swizzle);
+      }
+      else {
+         /* pre-defined varying, like gl_Color or gl_TexCoord */
+         if (type == SLANG_UNIT_FRAGMENT_BUILTIN) {
+            /* fragment program input */
+            GLuint swizzle;
+            GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB,
+                                             &swizzle, NULL);
+            assert(index >= 0);
+            assert(index < FRAG_ATTRIB_MAX);
+            store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index,
+                                              size, swizzle);
+         } else if (type == SLANG_UNIT_VERTEX_BUILTIN) {
+            /* vertex program output */
+            GLint index = _slang_output_index(varName, GL_VERTEX_PROGRAM_ARB);
+            GLuint swizzle = _slang_var_swizzle(size, 0);
+            assert(index >= 0);
+            assert(index < VERT_RESULT_MAX);
+            assert(type == SLANG_UNIT_VERTEX_BUILTIN);
+            store = _slang_new_ir_storage_swz(PROGRAM_OUTPUT, index,
+                                              size, swizzle);
+         } else {
+            /* geometry program input */
+            GLboolean is_array = GL_FALSE;
+            GLuint swizzle;
+            GLint index = _slang_input_index(varName, MESA_GEOMETRY_PROGRAM,
+                                             &swizzle, &is_array);
+            if (index < 0) {
+               /* geometry program output */
+               index = _slang_output_index(varName, MESA_GEOMETRY_PROGRAM);
+               swizzle = _slang_var_swizzle(size, 0);
+
+               assert(index >= 0);
+               assert(index < GEOM_RESULT_MAX);
+
+               store = _slang_new_ir_storage_swz(PROGRAM_OUTPUT, index,
+                                                 size, swizzle);
+            } else {
+               assert(index >= 0);
+               /* assert(index < GEOM_ATTRIB_MAX); */
+               if (is_array)
+                  store = _slang_new_ir_storage_2d(PROGRAM_INPUT, 0, index,
+                                                   size, swizzle);
+               else
+                  store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index,
+                                                    size, swizzle);
+            }
+         }
+         if (dbg) printf("V/F ");
+      }
+      if (dbg) printf("VARYING ");
+   }
+   else if (var->type.qualifier == SLANG_QUAL_ATTRIBUTE) {
+      GLuint swizzle;
+      GLint index;
+      /* attributes must be float, vec or mat */
+      if (!_slang_type_is_float_vec_mat(var->type.specifier.type)) {
+         slang_info_log_error(A->log,
+                              "attribute '%s' must be float/vector/matrix",
+                              varName);
+         return GL_FALSE;
+      }
+
+      if (prog) {
+         /* user-defined vertex attribute */
+         const GLint attr = -1; /* unknown */
+         swizzle = _slang_var_swizzle(size, 0);
+         index = _mesa_add_attribute(prog->Attributes, varName,
+                                     size, datatype, attr);
+         assert(index >= 0);
+         index = VERT_ATTRIB_GENERIC0 + index;
+      }
+      else {
+         /* pre-defined vertex attrib */
+         index = _slang_input_index(varName, GL_VERTEX_PROGRAM_ARB, &swizzle, NULL);
+         assert(index >= 0);
+      }
+      store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index, size, swizzle);
+      if (dbg) printf("ATTRIB ");
+   }
+   else if (var->type.qualifier == SLANG_QUAL_FIXEDINPUT) {
+      GLuint swizzle = SWIZZLE_XYZW; /* silence compiler warning */
+      if (type == SLANG_UNIT_FRAGMENT_BUILTIN) {
+         GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB,
+                                          &swizzle, NULL);
+         store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index, size, swizzle);
+      } else if (type == SLANG_UNIT_GEOMETRY_BUILTIN) {
+         GLboolean is_array;
+         GLint index = _slang_input_index(varName, MESA_GEOMETRY_PROGRAM,
+                                          &swizzle, &is_array);
+         if (is_array)
+            store = _slang_new_ir_storage_2d(PROGRAM_INPUT, 0, index, size, swizzle);
+         else
+            store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index, size, swizzle);
+      }
+      if (dbg) printf("INPUT ");
+   }
+   else if (var->type.qualifier == SLANG_QUAL_FIXEDOUTPUT) {
+      if (type == SLANG_UNIT_VERTEX_BUILTIN) {
+         GLint index = _slang_output_index(varName, GL_VERTEX_PROGRAM_ARB);
+         store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, size);
+      } else if (type == SLANG_UNIT_FRAGMENT_BUILTIN) {
+         GLint index = _slang_output_index(varName, GL_FRAGMENT_PROGRAM_ARB);
+         GLint specialSize = 4; /* treat all fragment outputs as float[4] */
+         assert(type == SLANG_UNIT_FRAGMENT_BUILTIN);
+         store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, specialSize);
+      } else {
+         GLint index = _slang_output_index(varName, MESA_GEOMETRY_PROGRAM);
+         GLint specialSize = 4; /* treat all fragment outputs as float[4] */
+         assert(type == SLANG_UNIT_GEOMETRY_BUILTIN);
+         store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, specialSize);
+      }
+      if (dbg) printf("OUTPUT ");
+   }
+   else if (var->type.qualifier == SLANG_QUAL_CONST && !prog) {
+      /* pre-defined global constant, like gl_MaxLights */
+      store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, size);
+      if (dbg) printf("CONST ");
+   }
+   else {
+      /* ordinary variable (may be const) */
+      slang_ir_node *n;
+
+      /* IR node to declare the variable */
+      n = _slang_gen_var_decl(A, var, var->initializer);
+
+      /* emit GPU instructions */
+      success = _slang_emit_code(n, A->vartable, A->program, A->pragmas, GL_FALSE, A->log);
+
+      _slang_free_ir_tree(n);
+   }
+
+   if (dbg) printf("GLOBAL VAR %s  idx %d\n", (char*) var->a_name,
+                   store ? store->Index : -2);
+
+   if (store)
+      var->store = store;  /* save var's storage info */
+
+   var->declared = GL_TRUE;
+
+   return success;
+}
+
+
+/**
+ * Produce an IR tree from a function AST (fun->body).
+ * Then call the code emitter to convert the IR tree into gl_program
+ * instructions.
+ */
+GLboolean
+_slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
+{
+   slang_ir_node *n;
+   GLboolean success = GL_TRUE;
+
+   if (strcmp((char *) fun->header.a_name, "main") != 0) {
+      /* we only really generate code for main, all other functions get
+       * inlined or codegen'd upon an actual call.
+       */
+#if 0
+      /* do some basic error checking though */
+      if (fun->header.type.specifier.type != SLANG_SPEC_VOID) {
+         /* check that non-void functions actually return something */
+         slang_operation *op
+            = _slang_find_node_type(fun->body, SLANG_OPER_RETURN);
+         if (!op) {
+            slang_info_log_error(A->log,
+                                 "function \"%s\" has no return statement",
+                                 (char *) fun->header.a_name);
+            printf(
+                   "function \"%s\" has no return statement\n",
+                   (char *) fun->header.a_name);
+            return GL_FALSE;
+         }
+      }
+#endif
+      return GL_TRUE;  /* not an error */
+   }
+
+#if 0
+   printf("\n*********** codegen_function %s\n", (char *) fun->header.a_name);
+   slang_print_function(fun, 1);
+#endif
+
+   /* should have been allocated earlier: */
+   assert(A->program->Parameters );
+   assert(A->program->Varying);
+   assert(A->vartable);
+
+   A->LoopDepth = 0;
+   A->UseReturnFlag = GL_FALSE;
+   A->CurFunction = fun;
+
+   /* fold constant expressions, etc. */
+   _slang_simplify(fun->body, &A->space, A->atoms);
+
+#if 0
+   printf("\n*********** simplified %s\n", (char *) fun->header.a_name);
+   slang_print_function(fun, 1);
+#endif
+
+   /* Create an end-of-function label */
+   A->curFuncEndLabel = _slang_label_new("__endOfFunc__main");
+
+   /* push new vartable scope */
+   _slang_push_var_table(A->vartable);
+
+   /* Generate IR tree for the function body code */
+   n = _slang_gen_operation(A, fun->body);
+   if (n)
+      n = new_node1(IR_SCOPE, n);
+
+   /* pop vartable, restore previous */
+   _slang_pop_var_table(A->vartable);
+
+   if (!n) {
+      /* XXX record error */
+      return GL_FALSE;
+   }
+
+   /* append an end-of-function-label to IR tree */
+   n = new_seq(n, new_label(A->curFuncEndLabel));
+
+   /*_slang_label_delete(A->curFuncEndLabel);*/
+   A->curFuncEndLabel = NULL;
+
+#if 0
+   printf("************* New AST for %s *****\n", (char*)fun->header.a_name);
+   slang_print_function(fun, 1);
+#endif
+#if 0
+   printf("************* IR for %s *******\n", (char*)fun->header.a_name);
+   _slang_print_ir_tree(n, 0);
+#endif
+#if 0
+   printf("************* End codegen function ************\n\n");
+#endif
+
+   if (A->UnresolvedRefs) {
+      /* Can't codegen at this time.
+       * At link time we'll concatenate all the vertex shaders and/or all
+       * the fragment shaders and try recompiling.
+       */
+      return GL_TRUE;
+   }
+
+   /* Emit program instructions */
+   success = _slang_emit_code(n, A->vartable, A->program, A->pragmas, GL_TRUE, A->log);
+   _slang_free_ir_tree(n);
+
+   /* free codegen context */
+   /*
+   free(A->codegen);
+   */
+
+   return success;
+}
+
diff --git a/src/mesa/slang/slang_codegen.h b/src/mesa/slang/slang_codegen.h
new file mode 100644 (file)
index 0000000..461633f
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.3
+ *
+ * Copyright (C) 2005-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.
+ */
+
+
+#ifndef SLANG_CODEGEN_H
+#define SLANG_CODEGEN_H
+
+
+#include "main/imports.h"
+#include "slang_compile.h"
+
+
+#define MAX_LOOP_DEPTH 30
+
+
+typedef struct slang_assemble_ctx_
+{
+   slang_atom_pool *atoms;
+   slang_name_space space;
+   struct gl_program *program;
+   struct gl_sl_pragmas *pragmas;
+   slang_var_table *vartable;
+   slang_info_log *log;
+   GLboolean allow_uniform_initializers;
+
+   /* current loop stack */
+   const slang_operation *LoopOperStack[MAX_LOOP_DEPTH];
+   struct slang_ir_node_ *LoopIRStack[MAX_LOOP_DEPTH];
+   GLuint LoopDepth;
+
+   /* current function */
+   struct slang_function_ *CurFunction;
+   struct slang_label_ *curFuncEndLabel;
+   GLboolean UseReturnFlag;
+
+   GLboolean UnresolvedRefs;
+   GLboolean EmitContReturn;
+} slang_assemble_ctx;
+
+
+extern GLuint
+_slang_sizeof_type_specifier(const slang_type_specifier *spec);
+
+extern GLboolean
+_slang_codegen_function(slang_assemble_ctx *A , struct slang_function_ *fun);
+
+extern GLboolean
+_slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
+                               slang_unit_type type);
+
+
+#endif /* SLANG_CODEGEN_H */
diff --git a/src/mesa/slang/slang_compile.c b/src/mesa/slang/slang_compile.c
new file mode 100644 (file)
index 0000000..12ab466
--- /dev/null
@@ -0,0 +1,3102 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2008 VMware, 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
+ * 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 slang_compile.c
+ * slang front-end compiler
+ * \author Michal Krol
+ */
+
+#include "main/imports.h"
+#include "main/context.h"
+#include "program/program.h"
+#include "program/programopt.h"
+#include "program/prog_optimize.h"
+#include "program/prog_print.h"
+#include "program/prog_parameter.h"
+#include "../../glsl/pp/sl_pp_public.h"
+#include "../../glsl/cl/sl_cl_parse.h"
+#include "slang_codegen.h"
+#include "slang_compile.h"
+#include "slang_storage.h"
+#include "slang_log.h"
+#include "slang_mem.h"
+#include "slang_vartable.h"
+#include "slang_simplify.h"
+
+/*
+ * This is a straightforward implementation of the slang front-end
+ * compiler.  Lots of error-checking functionality is missing but
+ * every well-formed shader source should compile successfully and
+ * execute as expected. However, some semantically ill-formed shaders
+ * may be accepted resulting in undefined behaviour.
+ */
+
+
+/** re-defined below, should be the same though */
+#define TYPE_SPECIFIER_COUNT 36
+
+
+/**
+ * Check if the given identifier is legal.
+ */
+static GLboolean
+legal_identifier(slang_atom name)
+{
+   /* "gl_" is a reserved prefix */
+   if (strncmp((char *) name, "gl_", 3) == 0) {
+      return GL_FALSE;
+   }
+   return GL_TRUE;
+}
+
+
+/*
+ * slang_code_unit
+ */
+
+GLvoid
+_slang_code_unit_ctr(slang_code_unit * self,
+                     struct slang_code_object_ * object)
+{
+   _slang_variable_scope_ctr(&self->vars);
+   _slang_function_scope_ctr(&self->funs);
+   _slang_struct_scope_ctr(&self->structs);
+   self->object = object;
+}
+
+GLvoid
+_slang_code_unit_dtr(slang_code_unit * self)
+{
+   slang_variable_scope_destruct(&self->vars);
+   slang_function_scope_destruct(&self->funs);
+   slang_struct_scope_destruct(&self->structs);
+}
+
+/*
+ * slang_code_object
+ */
+
+GLvoid
+_slang_code_object_ctr(slang_code_object * self)
+{
+   GLuint i;
+
+   for (i = 0; i < SLANG_BUILTIN_TOTAL; i++)
+      _slang_code_unit_ctr(&self->builtin[i], self);
+   _slang_code_unit_ctr(&self->unit, self);
+   slang_atom_pool_construct(&self->atompool);
+}
+
+GLvoid
+_slang_code_object_dtr(slang_code_object * self)
+{
+   GLuint i;
+
+   for (i = 0; i < SLANG_BUILTIN_TOTAL; i++)
+      _slang_code_unit_dtr(&self->builtin[i]);
+   _slang_code_unit_dtr(&self->unit);
+   slang_atom_pool_destruct(&self->atompool);
+}
+
+
+/* slang_parse_ctx */
+
+typedef struct slang_parse_ctx_
+{
+   const unsigned char *I;
+   slang_info_log *L;
+   int parsing_builtin;
+   GLboolean global_scope;   /**< Is object being declared a global? */
+   slang_atom_pool *atoms;
+   slang_unit_type type;     /**< Vertex vs. Fragment */
+   GLuint version;           /**< user-specified (or default) #version */
+} slang_parse_ctx;
+
+/* slang_output_ctx */
+
+typedef struct slang_output_ctx_
+{
+   slang_variable_scope *vars;
+   slang_function_scope *funs;
+   slang_struct_scope *structs;
+   struct gl_program *program;
+   struct gl_sl_pragmas *pragmas;
+   slang_var_table *vartable;
+   GLuint default_precision[TYPE_SPECIFIER_COUNT];
+   GLboolean allow_precision;
+   GLboolean allow_invariant;
+   GLboolean allow_centroid;
+   GLboolean allow_array_types;  /* float[] syntax */
+} slang_output_ctx;
+
+/* _slang_compile() */
+
+
+/* Debugging aid, print file/line where parsing error is detected */
+#define RETURN0 \
+   do { \
+      if (0) \
+         printf("slang error at %s:%d\n", __FILE__, __LINE__); \
+      return 0; \
+   } while (0)
+
+
+static void
+parse_identifier_str(slang_parse_ctx * C, char **id)
+{
+   *id = (char *) C->I;
+   C->I += strlen(*id) + 1;
+}
+
+static slang_atom
+parse_identifier(slang_parse_ctx * C)
+{
+   const char *id;
+
+   id = (const char *) C->I;
+   C->I += strlen(id) + 1;
+   return slang_atom_pool_atom(C->atoms, id);
+}
+
+static int
+is_hex_digit(char c)
+{
+   return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
+}
+
+static int
+parse_general_number(slang_parse_ctx *ctx, float *number)
+{
+   char *flt = NULL;
+
+   if (*ctx->I == '0') {
+      int value = 0;
+      const unsigned char *pi;
+
+      if (ctx->I[1] == 'x' || ctx->I[1] == 'X') {
+         ctx->I += 2;
+         if (!is_hex_digit(*ctx->I)) {
+            return 0;
+         }
+         do {
+            int digit;
+
+            if (*ctx->I >= '0' && *ctx->I <= '9') {
+               digit = (int)(*ctx->I - '0');
+            } else if (*ctx->I >= 'a' && *ctx->I <= 'f') {
+               digit = (int)(*ctx->I - 'a') + 10;
+            } else {
+               digit = (int)(*ctx->I - 'A') + 10;
+            }
+            value = value * 0x10 + digit;
+            ctx->I++;
+         } while (is_hex_digit(*ctx->I));
+         if (*ctx->I != '\0') {
+            return 0;
+         }
+         ctx->I++;
+         *number = (float)value;
+         return 1;
+      }
+
+      pi = ctx->I;
+      pi++;
+      while (*pi >= '0' && *pi <= '7') {
+         int digit;
+
+         digit = (int)(*pi - '0');
+         value = value * 010 + digit;
+         pi++;
+      }
+      if (*pi == '\0') {
+         pi++;
+         ctx->I = pi;
+         *number = (float)value;
+         return 1;
+      }
+   }
+
+   parse_identifier_str(ctx, &flt);
+   flt = _mesa_strdup(flt);
+   if (!flt) {
+      return 0;
+   }
+   if (flt[strlen(flt) - 1] == 'f' || flt[strlen(flt) - 1] == 'F') {
+      flt[strlen(flt) - 1] = '\0';
+   }
+   *number = _mesa_strtof(flt, (char **)NULL);
+   free(flt);
+
+   return 1;
+}
+
+static int
+parse_number(slang_parse_ctx * C, int *number)
+{
+   const int radix = (int) (*C->I++);
+
+   if (radix == 1) {
+      float f = 0.0f;
+
+      parse_general_number(C, &f);
+      *number = (int)f;
+   } else {
+      *number = 0;
+      while (*C->I != '\0') {
+         int digit;
+         if (*C->I >= '0' && *C->I <= '9')
+            digit = (int) (*C->I - '0');
+         else if (*C->I >= 'A' && *C->I <= 'Z')
+            digit = (int) (*C->I - 'A') + 10;
+         else
+            digit = (int) (*C->I - 'a') + 10;
+         *number = *number * radix + digit;
+         C->I++;
+      }
+      C->I++;
+   }
+   if (*number > 65535)
+      slang_info_log_warning(C->L, "%d: literal integer overflow.", *number);
+   return 1;
+}
+
+static int
+parse_float(slang_parse_ctx * C, float *number)
+{
+   if (*C->I == 1) {
+      C->I++;
+      parse_general_number(C, number);
+   } else {
+      char *integral = NULL;
+      char *fractional = NULL;
+      char *exponent = NULL;
+      char *whole = NULL;
+
+      parse_identifier_str(C, &integral);
+      parse_identifier_str(C, &fractional);
+      parse_identifier_str(C, &exponent);
+
+      whole = (char *) _slang_alloc((strlen(integral) +
+                                     strlen(fractional) +
+                                     strlen(exponent) + 3) * sizeof(char));
+      if (whole == NULL) {
+         slang_info_log_memory(C->L);
+         RETURN0;
+      }
+
+      slang_string_copy(whole, integral);
+      slang_string_concat(whole, ".");
+      slang_string_concat(whole, fractional);
+      slang_string_concat(whole, "E");
+      slang_string_concat(whole, exponent);
+
+      *number = _mesa_strtof(whole, (char **) NULL);
+
+      _slang_free(whole);
+   }
+
+   return 1;
+}
+
+/* revision number - increment after each change affecting emitted output */
+#define REVISION 5
+
+static int
+check_revision(slang_parse_ctx * C)
+{
+   if (*C->I != REVISION) {
+      slang_info_log_error(C->L, "Internal compiler error.");
+      RETURN0;
+   }
+   C->I++;
+   return 1;
+}
+
+static int parse_statement(slang_parse_ctx *, slang_output_ctx *,
+                           slang_operation *);
+static int parse_expression(slang_parse_ctx *, slang_output_ctx *,
+                            slang_operation *);
+static int parse_type_specifier(slang_parse_ctx *, slang_output_ctx *,
+                                slang_type_specifier *);
+static int
+parse_type_array_size(slang_parse_ctx *C,
+                      slang_output_ctx *O,
+                      GLint *array_len);
+
+static GLboolean
+parse_array_len(slang_parse_ctx * C, slang_output_ctx * O, GLuint * len)
+{
+   slang_operation array_size;
+   slang_name_space space;
+   GLboolean result;
+
+   if (!slang_operation_construct(&array_size))
+      return GL_FALSE;
+   if (!parse_expression(C, O, &array_size)) {
+      slang_operation_destruct(&array_size);
+      return GL_FALSE;
+   }
+
+   space.funcs = O->funs;
+   space.structs = O->structs;
+   space.vars = O->vars;
+
+   /* evaluate compile-time expression which is array size */
+   _slang_simplify(&array_size, &space, C->atoms);
+
+   if (array_size.type == SLANG_OPER_LITERAL_INT) {
+      result = GL_TRUE;
+      *len = (GLint) array_size.literal[0];
+   } else if (array_size.type == SLANG_OPER_IDENTIFIER) {
+      slang_variable *var = _slang_variable_locate(array_size.locals, array_size.a_id, GL_TRUE);
+      if (!var) {
+         slang_info_log_error(C->L, "undefined variable '%s'",
+                              (char *) array_size.a_id);
+         result = GL_FALSE;
+      } else if (var->type.qualifier == SLANG_QUAL_CONST &&
+                 var->type.specifier.type == SLANG_SPEC_INT) {
+         if (var->initializer &&
+             var->initializer->type == SLANG_OPER_LITERAL_INT) {
+            *len = (GLint) var->initializer->literal[0];
+            result = GL_TRUE;
+         } else {
+            slang_info_log_error(C->L, "unable to parse array size declaration");
+            result = GL_FALSE;
+         }
+      } else {
+         slang_info_log_error(C->L, "unable to parse array size declaration");
+         result = GL_FALSE;
+      }
+   } else {
+      result = GL_FALSE;
+   }
+
+   slang_operation_destruct(&array_size);
+   return result;
+}
+
+static GLboolean
+calculate_var_size(slang_parse_ctx * C, slang_output_ctx * O,
+                   slang_variable * var)
+{
+   slang_storage_aggregate agg;
+
+   if (!slang_storage_aggregate_construct(&agg))
+      return GL_FALSE;
+   if (!_slang_aggregate_variable(&agg, &var->type.specifier, var->array_len,
+                                  O->funs, O->structs, O->vars, C->atoms)) {
+      slang_storage_aggregate_destruct(&agg);
+      return GL_FALSE;
+   }
+   var->size = _slang_sizeof_aggregate(&agg);
+   slang_storage_aggregate_destruct(&agg);
+   return GL_TRUE;
+}
+
+static void
+promote_type_to_array(slang_parse_ctx *C,
+                      slang_fully_specified_type *type,
+                      GLint array_len)
+{
+   slang_type_specifier *baseType =
+      slang_type_specifier_new(type->specifier.type, NULL, NULL);
+
+   type->specifier.type = SLANG_SPEC_ARRAY;
+   type->specifier._array = baseType;
+   type->array_len = array_len;
+}
+
+
+static GLboolean
+convert_to_array(slang_parse_ctx * C, slang_variable * var,
+                 const slang_type_specifier * sp)
+{
+   /* sized array - mark it as array, copy the specifier to the array element
+    * and parse the expression */
+   var->type.specifier.type = SLANG_SPEC_ARRAY;
+   var->type.specifier._array = (slang_type_specifier *)
+      _slang_alloc(sizeof(slang_type_specifier));
+   if (var->type.specifier._array == NULL) {
+      slang_info_log_memory(C->L);
+      return GL_FALSE;
+   }
+   slang_type_specifier_ctr(var->type.specifier._array);
+   return slang_type_specifier_copy(var->type.specifier._array, sp);
+}
+
+/* structure field */
+#define FIELD_NONE 0
+#define FIELD_NEXT 1
+#define FIELD_ARRAY 2
+
+static GLboolean
+parse_struct_field_var(slang_parse_ctx * C, slang_output_ctx * O,
+                       slang_variable * var, slang_atom a_name,
+                       const slang_type_specifier * sp,
+                       GLuint array_len)
+{
+   var->a_name = a_name;
+   if (var->a_name == SLANG_ATOM_NULL)
+      return GL_FALSE;
+
+   switch (*C->I++) {
+   case FIELD_NONE:
+      if (array_len != -1) {
+         if (!convert_to_array(C, var, sp))
+            return GL_FALSE;
+         var->array_len = array_len;
+      }
+      else {
+         if (!slang_type_specifier_copy(&var->type.specifier, sp))
+            return GL_FALSE;
+      }
+      break;
+   case FIELD_ARRAY:
+      if (array_len != -1)
+         return GL_FALSE;
+      if (!convert_to_array(C, var, sp))
+         return GL_FALSE;
+      if (!parse_array_len(C, O, &var->array_len))
+         return GL_FALSE;
+      break;
+   default:
+      return GL_FALSE;
+   }
+
+   return calculate_var_size(C, O, var);
+}
+
+static int
+parse_struct_field(slang_parse_ctx * C, slang_output_ctx * O,
+                   slang_struct * st, slang_type_specifier * sp)
+{
+   slang_output_ctx o = *O;
+   GLint array_len;
+
+   o.structs = st->structs;
+   if (!parse_type_specifier(C, &o, sp))
+      RETURN0;
+   if (!parse_type_array_size(C, &o, &array_len))
+      RETURN0;
+
+   do {
+      slang_atom a_name;
+      slang_variable *var = slang_variable_scope_grow(st->fields);
+      if (!var) {
+         slang_info_log_memory(C->L);
+         RETURN0;
+      }
+      a_name = parse_identifier(C);
+      if (_slang_variable_locate(st->fields, a_name, GL_FALSE)) {
+         slang_info_log_error(C->L, "duplicate field '%s'", (char *) a_name);
+         RETURN0;
+      }
+
+      if (!parse_struct_field_var(C, &o, var, a_name, sp, array_len))
+         RETURN0;
+   }
+   while (*C->I++ != FIELD_NONE);
+
+   return 1;
+}
+
+static int
+parse_struct(slang_parse_ctx * C, slang_output_ctx * O, slang_struct ** st)
+{
+   slang_atom a_name;
+   const char *name;
+
+   /* parse struct name (if any) and make sure it is unique in current scope */
+   a_name = parse_identifier(C);
+   if (a_name == SLANG_ATOM_NULL)
+      RETURN0;
+
+   name = slang_atom_pool_id(C->atoms, a_name);
+   if (name[0] != '\0'
+       && slang_struct_scope_find(O->structs, a_name, 0) != NULL) {
+      slang_info_log_error(C->L, "%s: duplicate type name.", name);
+      RETURN0;
+   }
+
+   /* set-up a new struct */
+   *st = (slang_struct *) _slang_alloc(sizeof(slang_struct));
+   if (*st == NULL) {
+      slang_info_log_memory(C->L);
+      RETURN0;
+   }
+   if (!slang_struct_construct(*st)) {
+      _slang_free(*st);
+      *st = NULL;
+      slang_info_log_memory(C->L);
+      RETURN0;
+   }
+   (**st).a_name = a_name;
+   (**st).structs->outer_scope = O->structs;
+
+   /* parse individual struct fields */
+   do {
+      slang_type_specifier sp;
+
+      slang_type_specifier_ctr(&sp);
+      if (!parse_struct_field(C, O, *st, &sp)) {
+         slang_type_specifier_dtr(&sp);
+         RETURN0;
+      }
+      slang_type_specifier_dtr(&sp);
+   }
+   while (*C->I++ != FIELD_NONE);
+
+   /* if named struct, copy it to current scope */
+   if (name[0] != '\0') {
+      slang_struct *s;
+
+      O->structs->structs =
+         (slang_struct *) _slang_realloc(O->structs->structs,
+                                         O->structs->num_structs
+                                         * sizeof(slang_struct),
+                                         (O->structs->num_structs + 1)
+                                         * sizeof(slang_struct));
+      if (O->structs->structs == NULL) {
+         slang_info_log_memory(C->L);
+         RETURN0;
+      }
+      s = &O->structs->structs[O->structs->num_structs];
+      if (!slang_struct_construct(s))
+         RETURN0;
+      O->structs->num_structs++;
+      if (!slang_struct_copy(s, *st))
+         RETURN0;
+   }
+
+   return 1;
+}
+
+
+/* invariant qualifer */
+#define TYPE_VARIANT    90
+#define TYPE_INVARIANT  91
+
+static int
+parse_type_variant(slang_parse_ctx * C, slang_type_variant *variant)
+{
+   GLuint invariant = *C->I++;
+   switch (invariant) {
+   case TYPE_VARIANT:
+      *variant = SLANG_VARIANT;
+      return 1;
+   case TYPE_INVARIANT:
+      *variant = SLANG_INVARIANT;
+      return 1;
+   default:
+      RETURN0;
+   }
+}
+
+
+/* centroid qualifer */
+#define TYPE_CENTER    95
+#define TYPE_CENTROID  96
+
+static int
+parse_type_centroid(slang_parse_ctx * C, slang_type_centroid *centroid)
+{
+   GLuint c = *C->I++;
+   switch (c) {
+   case TYPE_CENTER:
+      *centroid = SLANG_CENTER;
+      return 1;
+   case TYPE_CENTROID:
+      *centroid = SLANG_CENTROID;
+      return 1;
+   default:
+      RETURN0;
+   }
+}
+
+
+/* Layout qualifiers */
+#define LAYOUT_QUALIFIER_NONE                      0
+#define LAYOUT_QUALIFIER_UPPER_LEFT                1
+#define LAYOUT_QUALIFIER_PIXEL_CENTER_INTEGER      2
+
+static int
+parse_layout_qualifiers(slang_parse_ctx * C, slang_layout_qualifier *layout)
+{
+   *layout = 0x0;
+
+   /* the layout qualifiers come as a list of LAYOUT_QUALIFER_x tokens,
+    * terminated by LAYOUT_QUALIFIER_NONE.
+    */
+   while (1) {
+      GLuint c = *C->I++;
+      switch (c) {
+      case LAYOUT_QUALIFIER_NONE:
+         /* end of list of qualifiers */
+         return 1;
+      case LAYOUT_QUALIFIER_UPPER_LEFT:
+         *layout |= SLANG_LAYOUT_UPPER_LEFT_BIT;
+         break;
+      case LAYOUT_QUALIFIER_PIXEL_CENTER_INTEGER:
+         *layout |= SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT;
+         break;
+      default:
+         assert(0 && "Bad layout qualifier");
+      }
+   }
+}
+
+
+/* type qualifier */
+#define TYPE_QUALIFIER_NONE 0
+#define TYPE_QUALIFIER_CONST 1
+#define TYPE_QUALIFIER_ATTRIBUTE 2
+#define TYPE_QUALIFIER_VARYING 3
+#define TYPE_QUALIFIER_UNIFORM 4
+#define TYPE_QUALIFIER_FIXEDOUTPUT 5
+#define TYPE_QUALIFIER_FIXEDINPUT 6
+
+static int
+parse_type_qualifier(slang_parse_ctx * C, slang_type_qualifier * qual)
+{
+   GLuint qualifier = *C->I++;
+   switch (qualifier) {
+   case TYPE_QUALIFIER_NONE:
+      *qual = SLANG_QUAL_NONE;
+      break;
+   case TYPE_QUALIFIER_CONST:
+      *qual = SLANG_QUAL_CONST;
+      break;
+   case TYPE_QUALIFIER_ATTRIBUTE:
+      *qual = SLANG_QUAL_ATTRIBUTE;
+      break;
+   case TYPE_QUALIFIER_VARYING:
+      *qual = SLANG_QUAL_VARYING;
+      break;
+   case TYPE_QUALIFIER_UNIFORM:
+      *qual = SLANG_QUAL_UNIFORM;
+      break;
+   case TYPE_QUALIFIER_FIXEDOUTPUT:
+      *qual = SLANG_QUAL_FIXEDOUTPUT;
+      break;
+   case TYPE_QUALIFIER_FIXEDINPUT:
+      *qual = SLANG_QUAL_FIXEDINPUT;
+      break;
+   default:
+      RETURN0;
+   }
+   return 1;
+}
+
+/* type specifier */
+#define TYPE_SPECIFIER_VOID 0
+#define TYPE_SPECIFIER_BOOL 1
+#define TYPE_SPECIFIER_BVEC2 2
+#define TYPE_SPECIFIER_BVEC3 3
+#define TYPE_SPECIFIER_BVEC4 4
+#define TYPE_SPECIFIER_INT 5
+#define TYPE_SPECIFIER_IVEC2 6
+#define TYPE_SPECIFIER_IVEC3 7
+#define TYPE_SPECIFIER_IVEC4 8
+#define TYPE_SPECIFIER_FLOAT 9
+#define TYPE_SPECIFIER_VEC2 10
+#define TYPE_SPECIFIER_VEC3 11
+#define TYPE_SPECIFIER_VEC4 12
+#define TYPE_SPECIFIER_MAT2 13
+#define TYPE_SPECIFIER_MAT3 14
+#define TYPE_SPECIFIER_MAT4 15
+#define TYPE_SPECIFIER_SAMPLER1D 16
+#define TYPE_SPECIFIER_SAMPLER2D 17
+#define TYPE_SPECIFIER_SAMPLER3D 18
+#define TYPE_SPECIFIER_SAMPLERCUBE 19
+#define TYPE_SPECIFIER_SAMPLER1DSHADOW 20
+#define TYPE_SPECIFIER_SAMPLER2DSHADOW 21
+#define TYPE_SPECIFIER_SAMPLER2DRECT 22
+#define TYPE_SPECIFIER_SAMPLER2DRECTSHADOW 23
+#define TYPE_SPECIFIER_STRUCT 24
+#define TYPE_SPECIFIER_TYPENAME 25
+#define TYPE_SPECIFIER_MAT23 26
+#define TYPE_SPECIFIER_MAT32 27
+#define TYPE_SPECIFIER_MAT24 28
+#define TYPE_SPECIFIER_MAT42 29
+#define TYPE_SPECIFIER_MAT34 30
+#define TYPE_SPECIFIER_MAT43 31
+#define TYPE_SPECIFIER_SAMPLER_1D_ARRAY 32
+#define TYPE_SPECIFIER_SAMPLER_2D_ARRAY 33
+#define TYPE_SPECIFIER_SAMPLER_1D_ARRAY_SHADOW 34
+#define TYPE_SPECIFIER_SAMPLER_2D_ARRAY_SHADOW 35
+#define TYPE_SPECIFIER_COUNT 36
+
+static int
+parse_type_specifier(slang_parse_ctx * C, slang_output_ctx * O,
+                     slang_type_specifier * spec)
+{
+   int type = *C->I++;
+   switch (type) {
+   case TYPE_SPECIFIER_VOID:
+      spec->type = SLANG_SPEC_VOID;
+      break;
+   case TYPE_SPECIFIER_BOOL:
+      spec->type = SLANG_SPEC_BOOL;
+      break;
+   case TYPE_SPECIFIER_BVEC2:
+      spec->type = SLANG_SPEC_BVEC2;
+      break;
+   case TYPE_SPECIFIER_BVEC3:
+      spec->type = SLANG_SPEC_BVEC3;
+      break;
+   case TYPE_SPECIFIER_BVEC4:
+      spec->type = SLANG_SPEC_BVEC4;
+      break;
+   case TYPE_SPECIFIER_INT:
+      spec->type = SLANG_SPEC_INT;
+      break;
+   case TYPE_SPECIFIER_IVEC2:
+      spec->type = SLANG_SPEC_IVEC2;
+      break;
+   case TYPE_SPECIFIER_IVEC3:
+      spec->type = SLANG_SPEC_IVEC3;
+      break;
+   case TYPE_SPECIFIER_IVEC4:
+      spec->type = SLANG_SPEC_IVEC4;
+      break;
+   case TYPE_SPECIFIER_FLOAT:
+      spec->type = SLANG_SPEC_FLOAT;
+      break;
+   case TYPE_SPECIFIER_VEC2:
+      spec->type = SLANG_SPEC_VEC2;
+      break;
+   case TYPE_SPECIFIER_VEC3:
+      spec->type = SLANG_SPEC_VEC3;
+      break;
+   case TYPE_SPECIFIER_VEC4:
+      spec->type = SLANG_SPEC_VEC4;
+      break;
+   case TYPE_SPECIFIER_MAT2:
+      spec->type = SLANG_SPEC_MAT2;
+      break;
+   case TYPE_SPECIFIER_MAT3:
+      spec->type = SLANG_SPEC_MAT3;
+      break;
+   case TYPE_SPECIFIER_MAT4:
+      spec->type = SLANG_SPEC_MAT4;
+      break;
+   case TYPE_SPECIFIER_MAT23:
+      spec->type = SLANG_SPEC_MAT23;
+      break;
+   case TYPE_SPECIFIER_MAT32:
+      spec->type = SLANG_SPEC_MAT32;
+      break;
+   case TYPE_SPECIFIER_MAT24:
+      spec->type = SLANG_SPEC_MAT24;
+      break;
+   case TYPE_SPECIFIER_MAT42:
+      spec->type = SLANG_SPEC_MAT42;
+      break;
+   case TYPE_SPECIFIER_MAT34:
+      spec->type = SLANG_SPEC_MAT34;
+      break;
+   case TYPE_SPECIFIER_MAT43:
+      spec->type = SLANG_SPEC_MAT43;
+      break;
+   case TYPE_SPECIFIER_SAMPLER1D:
+      spec->type = SLANG_SPEC_SAMPLER_1D;
+      break;
+   case TYPE_SPECIFIER_SAMPLER2D:
+      spec->type = SLANG_SPEC_SAMPLER_2D;
+      break;
+   case TYPE_SPECIFIER_SAMPLER3D:
+      spec->type = SLANG_SPEC_SAMPLER_3D;
+      break;
+   case TYPE_SPECIFIER_SAMPLERCUBE:
+      spec->type = SLANG_SPEC_SAMPLER_CUBE;
+      break;
+   case TYPE_SPECIFIER_SAMPLER2DRECT:
+      spec->type = SLANG_SPEC_SAMPLER_RECT;
+      break;
+   case TYPE_SPECIFIER_SAMPLER1DSHADOW:
+      spec->type = SLANG_SPEC_SAMPLER_1D_SHADOW;
+      break;
+   case TYPE_SPECIFIER_SAMPLER2DSHADOW:
+      spec->type = SLANG_SPEC_SAMPLER_2D_SHADOW;
+      break;
+   case TYPE_SPECIFIER_SAMPLER2DRECTSHADOW:
+      spec->type = SLANG_SPEC_SAMPLER_RECT_SHADOW;
+      break;
+   case TYPE_SPECIFIER_SAMPLER_1D_ARRAY:
+      spec->type = SLANG_SPEC_SAMPLER_1D_ARRAY;
+      break;
+   case TYPE_SPECIFIER_SAMPLER_2D_ARRAY:
+      spec->type = SLANG_SPEC_SAMPLER_2D_ARRAY;
+      break;
+   case TYPE_SPECIFIER_SAMPLER_1D_ARRAY_SHADOW:
+      spec->type = SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW;
+      break;
+   case TYPE_SPECIFIER_SAMPLER_2D_ARRAY_SHADOW:
+      spec->type = SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW;
+      break;
+   case TYPE_SPECIFIER_STRUCT:
+      spec->type = SLANG_SPEC_STRUCT;
+      if (!parse_struct(C, O, &spec->_struct))
+         RETURN0;
+      break;
+   case TYPE_SPECIFIER_TYPENAME:
+      spec->type = SLANG_SPEC_STRUCT;
+      {
+         slang_atom a_name;
+         slang_struct *stru;
+
+         a_name = parse_identifier(C);
+         if (a_name == NULL)
+            RETURN0;
+
+         stru = slang_struct_scope_find(O->structs, a_name, 1);
+         if (stru == NULL) {
+            slang_info_log_error(C->L, "undeclared type name '%s'",
+                                 slang_atom_pool_id(C->atoms, a_name));
+            RETURN0;
+         }
+
+         spec->_struct = (slang_struct *) _slang_alloc(sizeof(slang_struct));
+         if (spec->_struct == NULL) {
+            slang_info_log_memory(C->L);
+            RETURN0;
+         }
+         if (!slang_struct_construct(spec->_struct)) {
+            _slang_free(spec->_struct);
+            spec->_struct = NULL;
+            RETURN0;
+         }
+         if (!slang_struct_copy(spec->_struct, stru))
+            RETURN0;
+      }
+      break;
+   default:
+      RETURN0;
+   }
+   return 1;
+}
+
+#define TYPE_SPECIFIER_NONARRAY 0
+#define TYPE_SPECIFIER_ARRAY    1
+
+static int
+parse_type_array_size(slang_parse_ctx *C,
+                      slang_output_ctx *O,
+                      GLint *array_len)
+{
+   GLuint size;
+
+   switch (*C->I++) {
+   case TYPE_SPECIFIER_NONARRAY:
+      *array_len = -1; /* -1 = not an array */
+      break;
+   case TYPE_SPECIFIER_ARRAY:
+      if (!parse_array_len(C, O, &size))
+         RETURN0;
+      *array_len = (GLint) size;
+      break;
+   default:
+      assert(0);
+      RETURN0;
+   }
+   return 1;
+}
+
+#define PRECISION_DEFAULT 0
+#define PRECISION_LOW     1
+#define PRECISION_MEDIUM  2
+#define PRECISION_HIGH    3
+
+static int
+parse_type_precision(slang_parse_ctx *C,
+                     slang_type_precision *precision)
+{
+   GLint prec = *C->I++;
+   switch (prec) {
+   case PRECISION_DEFAULT:
+      *precision = SLANG_PREC_DEFAULT;
+      return 1;
+   case PRECISION_LOW:
+      *precision = SLANG_PREC_LOW;
+      return 1;
+   case PRECISION_MEDIUM:
+      *precision = SLANG_PREC_MEDIUM;
+      return 1;
+   case PRECISION_HIGH:
+      *precision = SLANG_PREC_HIGH;
+      return 1;
+   default:
+      RETURN0;
+   }
+}
+
+
+/* parameter qualifier */
+#define PARAM_QUALIFIER_IN 0
+#define PARAM_QUALIFIER_OUT 1
+#define PARAM_QUALIFIER_INOUT 2
+#define PARAM_QUALIFIER_NONE 3
+static int
+parse_varying_qualifier(slang_parse_ctx * C, slang_fully_specified_type *type)
+{
+   int param_qual = *C->I++;
+
+   if (type->qualifier != SLANG_QUAL_VARYING &&
+       param_qual != PARAM_QUALIFIER_NONE) {
+      slang_info_log_error(C->L, "Invalid type qualifier.");
+      RETURN0;
+   }
+   switch (param_qual) {
+   case PARAM_QUALIFIER_IN:
+   case PARAM_QUALIFIER_NONE:
+      type->varying_kind = SLANG_VARYING_IN;
+      break;
+   case PARAM_QUALIFIER_OUT:
+      type->varying_kind = SLANG_VARYING_OUT;
+      break;
+   case PARAM_QUALIFIER_INOUT:
+      slang_info_log_error(C->L, "Invalid type qualifier.");
+      RETURN0;
+      break;
+   default:
+      RETURN0;
+   }
+   return 1;
+}
+
+static int
+parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O,
+                           slang_fully_specified_type * type)
+{
+   if (!parse_layout_qualifiers(C, &type->layout))
+      RETURN0;
+
+   if (!parse_type_variant(C, &type->variant))
+      RETURN0;
+
+   if (!parse_type_centroid(C, &type->centroid))
+      RETURN0;
+
+   if (!parse_type_qualifier(C, &type->qualifier))
+      RETURN0;
+
+   if (!parse_varying_qualifier(C, type))
+      RETURN0;
+
+   if (!parse_type_precision(C, &type->precision))
+      RETURN0;
+
+   if (!parse_type_specifier(C, O, &type->specifier))
+      RETURN0;
+
+   if (!parse_type_array_size(C, O, &type->array_len))
+      RETURN0;
+
+   if (!O->allow_invariant && type->variant == SLANG_INVARIANT) {
+      slang_info_log_error(C->L,
+         "'invariant' keyword not allowed (perhaps set #version 120)");
+      RETURN0;
+   }
+
+   if (!O->allow_centroid && type->centroid == SLANG_CENTROID) {
+      slang_info_log_error(C->L,
+         "'centroid' keyword not allowed (perhaps set #version 120)");
+      RETURN0;
+   }
+   else if (type->centroid == SLANG_CENTROID &&
+            type->qualifier != SLANG_QUAL_VARYING) {
+      slang_info_log_error(C->L,
+         "'centroid' keyword only allowed for varying vars");
+      RETURN0;
+   }
+
+
+   /* need this?
+   if (type->qualifier != SLANG_QUAL_VARYING &&
+       type->variant == SLANG_INVARIANT) {
+      slang_info_log_error(C->L,
+                           "invariant qualifer only allowed for varying vars");
+      RETURN0;
+   }
+   */
+
+   if (O->allow_precision) {
+      if (type->precision == SLANG_PREC_DEFAULT) {
+         assert(type->specifier.type < TYPE_SPECIFIER_COUNT);
+         /* use the default precision for this datatype */
+         type->precision = O->default_precision[type->specifier.type];
+      }
+   }
+   else {
+      /* only default is allowed */
+      if (type->precision != SLANG_PREC_DEFAULT) {
+         slang_info_log_error(C->L, "precision qualifiers not allowed");
+         RETURN0;
+      }
+   }
+
+   if (!O->allow_array_types && type->array_len >= 0) {
+      slang_info_log_error(C->L, "first-class array types not allowed");
+      RETURN0;
+   }
+
+   if (type->array_len >= 0) {
+      /* convert type to array type (ex: convert "int" to "array of int" */
+      promote_type_to_array(C, type, type->array_len);
+   }
+
+   return 1;
+}
+
+/* operation */
+#define OP_END 0
+#define OP_BLOCK_BEGIN_NO_NEW_SCOPE 1
+#define OP_BLOCK_BEGIN_NEW_SCOPE 2
+#define OP_DECLARE 3
+#define OP_ASM 4
+#define OP_BREAK 5
+#define OP_CONTINUE 6
+#define OP_DISCARD 7
+#define OP_RETURN 8
+#define OP_EXPRESSION 9
+#define OP_IF 10
+#define OP_WHILE 11
+#define OP_DO 12
+#define OP_FOR 13
+#define OP_PUSH_VOID 14
+#define OP_PUSH_BOOL 15
+#define OP_PUSH_INT 16
+#define OP_PUSH_FLOAT 17
+#define OP_PUSH_IDENTIFIER 18
+#define OP_SEQUENCE 19
+#define OP_ASSIGN 20
+#define OP_ADDASSIGN 21
+#define OP_SUBASSIGN 22
+#define OP_MULASSIGN 23
+#define OP_DIVASSIGN 24
+/*#define OP_MODASSIGN 25*/
+/*#define OP_LSHASSIGN 26*/
+/*#define OP_RSHASSIGN 27*/
+/*#define OP_ORASSIGN 28*/
+/*#define OP_XORASSIGN 29*/
+/*#define OP_ANDASSIGN 30*/
+#define OP_SELECT 31
+#define OP_LOGICALOR 32
+#define OP_LOGICALXOR 33
+#define OP_LOGICALAND 34
+/*#define OP_BITOR 35*/
+/*#define OP_BITXOR 36*/
+/*#define OP_BITAND 37*/
+#define OP_EQUAL 38
+#define OP_NOTEQUAL 39
+#define OP_LESS 40
+#define OP_GREATER 41
+#define OP_LESSEQUAL 42
+#define OP_GREATEREQUAL 43
+/*#define OP_LSHIFT 44*/
+/*#define OP_RSHIFT 45*/
+#define OP_ADD 46
+#define OP_SUBTRACT 47
+#define OP_MULTIPLY 48
+#define OP_DIVIDE 49
+/*#define OP_MODULUS 50*/
+#define OP_PREINCREMENT 51
+#define OP_PREDECREMENT 52
+#define OP_PLUS 53
+#define OP_MINUS 54
+/*#define OP_COMPLEMENT 55*/
+#define OP_NOT 56
+#define OP_SUBSCRIPT 57
+#define OP_CALL 58
+#define OP_FIELD 59
+#define OP_POSTINCREMENT 60
+#define OP_POSTDECREMENT 61
+#define OP_PRECISION 62
+#define OP_METHOD 63
+
+
+/**
+ * When parsing a compound production, this function is used to parse the
+ * children.
+ * For example, a while-loop compound will have two children, the
+ * while condition expression and the loop body.  So, this function will
+ * be called twice to parse those two sub-expressions.
+ * \param C  the parsing context
+ * \param O  the output context
+ * \param oper  the operation we're parsing
+ * \param statement  indicates whether parsing a statement, or expression
+ * \return 1 if success, 0 if error
+ */
+static int
+parse_child_operation(slang_parse_ctx * C, slang_output_ctx * O,
+                      slang_operation * oper, GLboolean statement)
+{
+   slang_operation *ch;
+
+   /* grow child array */
+   ch = slang_operation_grow(&oper->num_children, &oper->children);
+   if (statement)
+      return parse_statement(C, O, ch);
+   return parse_expression(C, O, ch);
+}
+
+static int parse_declaration(slang_parse_ctx * C, slang_output_ctx * O);
+
+static int
+parse_statement(slang_parse_ctx * C, slang_output_ctx * O,
+                slang_operation * oper)
+{
+   int op;
+
+   oper->locals->outer_scope = O->vars;
+
+   op = *C->I++;
+   switch (op) {
+   case OP_BLOCK_BEGIN_NO_NEW_SCOPE:
+      /* parse child statements, do not create new variable scope */
+      oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
+      while (*C->I != OP_END)
+         if (!parse_child_operation(C, O, oper, GL_TRUE))
+            RETURN0;
+      C->I++;
+      break;
+   case OP_BLOCK_BEGIN_NEW_SCOPE:
+      /* parse child statements, create new variable scope */
+      {
+         slang_output_ctx o = *O;
+
+         oper->type = SLANG_OPER_BLOCK_NEW_SCOPE;
+         o.vars = oper->locals;
+         while (*C->I != OP_END)
+            if (!parse_child_operation(C, &o, oper, GL_TRUE))
+               RETURN0;
+         C->I++;
+      }
+      break;
+   case OP_DECLARE:
+      /* local variable declaration, individual declarators are stored as
+       * children identifiers
+       */
+      oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
+      {
+         const unsigned int first_var = O->vars->num_variables;
+
+         /* parse the declaration, note that there can be zero or more
+          * than one declarators
+          */
+         if (!parse_declaration(C, O))
+            RETURN0;
+         if (first_var < O->vars->num_variables) {
+            const unsigned int num_vars = O->vars->num_variables - first_var;
+            unsigned int i;
+            assert(oper->num_children == 0);
+            oper->num_children = num_vars;
+            oper->children = slang_operation_new(num_vars);
+            if (oper->children == NULL) {
+               slang_info_log_memory(C->L);
+               RETURN0;
+            }
+            for (i = first_var; i < O->vars->num_variables; i++) {
+               slang_operation *o = &oper->children[i - first_var];
+               slang_variable *var = O->vars->variables[i];
+               o->type = SLANG_OPER_VARIABLE_DECL;
+               o->locals->outer_scope = O->vars;
+               o->a_id = var->a_name;
+
+               /* new/someday...
+               calculate_var_size(C, O, var);
+               */
+
+               if (!legal_identifier(o->a_id)) {
+                  slang_info_log_error(C->L, "illegal variable name '%s'",
+                                       (char *) o->a_id);
+                  RETURN0;
+               }
+            }
+         }
+      }
+      break;
+   case OP_ASM:
+      /* the __asm statement, parse the mnemonic and all its arguments
+       * as expressions
+       */
+      oper->type = SLANG_OPER_ASM;
+      oper->a_id = parse_identifier(C);
+      if (oper->a_id == SLANG_ATOM_NULL)
+         RETURN0;
+      while (*C->I != OP_END) {
+         if (!parse_child_operation(C, O, oper, GL_FALSE))
+            RETURN0;
+      }
+      C->I++;
+      break;
+   case OP_BREAK:
+      oper->type = SLANG_OPER_BREAK;
+      break;
+   case OP_CONTINUE:
+      oper->type = SLANG_OPER_CONTINUE;
+      break;
+   case OP_DISCARD:
+      oper->type = SLANG_OPER_DISCARD;
+      break;
+   case OP_RETURN:
+      oper->type = SLANG_OPER_RETURN;
+      if (!parse_child_operation(C, O, oper, GL_FALSE))
+         RETURN0;
+      break;
+   case OP_EXPRESSION:
+      oper->type = SLANG_OPER_EXPRESSION;
+      if (!parse_child_operation(C, O, oper, GL_FALSE))
+         RETURN0;
+      break;
+   case OP_IF:
+      oper->type = SLANG_OPER_IF;
+      if (!parse_child_operation(C, O, oper, GL_FALSE))
+         RETURN0;
+      if (!parse_child_operation(C, O, oper, GL_TRUE))
+         RETURN0;
+      if (!parse_child_operation(C, O, oper, GL_TRUE))
+         RETURN0;
+      break;
+   case OP_WHILE:
+      {
+         slang_output_ctx o = *O;
+
+         oper->type = SLANG_OPER_WHILE;
+         o.vars = oper->locals;
+         if (!parse_child_operation(C, &o, oper, GL_TRUE))
+            RETURN0;
+         if (!parse_child_operation(C, &o, oper, GL_TRUE))
+            RETURN0;
+      }
+      break;
+   case OP_DO:
+      oper->type = SLANG_OPER_DO;
+      if (!parse_child_operation(C, O, oper, GL_TRUE))
+         RETURN0;
+      if (!parse_child_operation(C, O, oper, GL_FALSE))
+         RETURN0;
+      break;
+   case OP_FOR:
+      {
+         slang_output_ctx o = *O;
+
+         oper->type = SLANG_OPER_FOR;
+         o.vars = oper->locals;
+         if (!parse_child_operation(C, &o, oper, GL_TRUE))
+            RETURN0;
+         if (!parse_child_operation(C, &o, oper, GL_TRUE))
+            RETURN0;
+         if (!parse_child_operation(C, &o, oper, GL_FALSE))
+            RETURN0;
+         if (!parse_child_operation(C, &o, oper, GL_TRUE))
+            RETURN0;
+      }
+      break;
+   case OP_PRECISION:
+      {
+         /* set default precision for a type in this scope */
+         /* ignored at this time */
+         int prec_qual = *C->I++;
+         int datatype = *C->I++;
+         (void) prec_qual;
+         (void) datatype;
+      }
+      break;
+   default:
+      /*printf("Unexpected operation %d\n", op);*/
+      RETURN0;
+   }
+   return 1;
+}
+
+static int
+handle_nary_expression(slang_parse_ctx * C, slang_operation * op,
+                       slang_operation ** ops, unsigned int *total_ops,
+                       unsigned int n)
+{
+   unsigned int i;
+
+   op->children = slang_operation_new(n);
+   if (op->children == NULL) {
+      slang_info_log_memory(C->L);
+      RETURN0;
+   }
+   op->num_children = n;
+
+   for (i = 0; i < n; i++) {
+      slang_operation_destruct(&op->children[i]);
+      op->children[i] = (*ops)[*total_ops - (n + 1 - i)];
+   }
+
+   (*ops)[*total_ops - (n + 1)] = (*ops)[*total_ops - 1];
+   *total_ops -= n;
+
+   *ops = (slang_operation *)
+      _slang_realloc(*ops,
+                     (*total_ops + n) * sizeof(slang_operation),
+                     *total_ops * sizeof(slang_operation));
+   if (*ops == NULL) {
+      slang_info_log_memory(C->L);
+      RETURN0;
+   }
+   return 1;
+}
+
+static int
+is_constructor_name(const char *name, slang_atom a_name,
+                    slang_struct_scope * structs)
+{
+   if (slang_type_specifier_type_from_string(name) != SLANG_SPEC_VOID)
+      return 1;
+   return slang_struct_scope_find(structs, a_name, 1) != NULL;
+}
+
+#define FUNCTION_CALL_NONARRAY 0
+#define FUNCTION_CALL_ARRAY    1
+
+static int
+parse_expression(slang_parse_ctx * C, slang_output_ctx * O,
+                 slang_operation * oper)
+{
+   slang_operation *ops = NULL;
+   unsigned int num_ops = 0;
+   int number;
+
+   while (*C->I != OP_END) {
+      slang_operation *op;
+      const unsigned int op_code = *C->I++;
+
+      /* allocate default operation, becomes a no-op if not used  */
+      ops = (slang_operation *)
+         _slang_realloc(ops,
+                        num_ops * sizeof(slang_operation),
+                        (num_ops + 1) * sizeof(slang_operation));
+      if (ops == NULL) {
+         slang_info_log_memory(C->L);
+         RETURN0;
+      }
+      op = &ops[num_ops];
+      if (!slang_operation_construct(op)) {
+         slang_info_log_memory(C->L);
+         RETURN0;
+      }
+      num_ops++;
+      op->locals->outer_scope = O->vars;
+
+      switch (op_code) {
+      case OP_PUSH_VOID:
+         op->type = SLANG_OPER_VOID;
+         break;
+      case OP_PUSH_BOOL:
+         op->type = SLANG_OPER_LITERAL_BOOL;
+         if (!parse_number(C, &number))
+            RETURN0;
+         op->literal[0] =
+         op->literal[1] =
+         op->literal[2] =
+         op->literal[3] = (GLfloat) number;
+         op->literal_size = 1;
+         break;
+      case OP_PUSH_INT:
+         op->type = SLANG_OPER_LITERAL_INT;
+         if (!parse_number(C, &number))
+            RETURN0;
+         op->literal[0] =
+         op->literal[1] =
+         op->literal[2] =
+         op->literal[3] = (GLfloat) number;
+         op->literal_size = 1;
+         break;
+      case OP_PUSH_FLOAT:
+         op->type = SLANG_OPER_LITERAL_FLOAT;
+         if (!parse_float(C, &op->literal[0]))
+            RETURN0;
+         op->literal[1] =
+         op->literal[2] =
+         op->literal[3] = op->literal[0];
+         op->literal_size = 1;
+         break;
+      case OP_PUSH_IDENTIFIER:
+         op->type = SLANG_OPER_IDENTIFIER;
+         op->a_id = parse_identifier(C);
+         if (op->a_id == SLANG_ATOM_NULL)
+            RETURN0;
+         break;
+      case OP_SEQUENCE:
+         op->type = SLANG_OPER_SEQUENCE;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+            RETURN0;
+         break;
+      case OP_ASSIGN:
+         op->type = SLANG_OPER_ASSIGN;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+            RETURN0;
+         break;
+      case OP_ADDASSIGN:
+         op->type = SLANG_OPER_ADDASSIGN;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+            RETURN0;
+         break;
+      case OP_SUBASSIGN:
+         op->type = SLANG_OPER_SUBASSIGN;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+            RETURN0;
+         break;
+      case OP_MULASSIGN:
+         op->type = SLANG_OPER_MULASSIGN;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+            RETURN0;
+         break;
+      case OP_DIVASSIGN:
+         op->type = SLANG_OPER_DIVASSIGN;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+            RETURN0;
+         break;
+         /*case OP_MODASSIGN: */
+         /*case OP_LSHASSIGN: */
+         /*case OP_RSHASSIGN: */
+         /*case OP_ORASSIGN: */
+         /*case OP_XORASSIGN: */
+         /*case OP_ANDASSIGN: */
+      case OP_SELECT:
+         op->type = SLANG_OPER_SELECT;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 3))
+            RETURN0;
+         break;
+      case OP_LOGICALOR:
+         op->type = SLANG_OPER_LOGICALOR;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+            RETURN0;
+         break;
+      case OP_LOGICALXOR:
+         op->type = SLANG_OPER_LOGICALXOR;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+            RETURN0;
+         break;
+      case OP_LOGICALAND:
+         op->type = SLANG_OPER_LOGICALAND;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+            RETURN0;
+         break;
+         /*case OP_BITOR: */
+         /*case OP_BITXOR: */
+         /*case OP_BITAND: */
+      case OP_EQUAL:
+         op->type = SLANG_OPER_EQUAL;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+            RETURN0;
+         break;
+      case OP_NOTEQUAL:
+         op->type = SLANG_OPER_NOTEQUAL;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+            RETURN0;
+         break;
+      case OP_LESS:
+         op->type = SLANG_OPER_LESS;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+            RETURN0;
+         break;
+      case OP_GREATER:
+         op->type = SLANG_OPER_GREATER;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+            RETURN0;
+         break;
+      case OP_LESSEQUAL:
+         op->type = SLANG_OPER_LESSEQUAL;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+            RETURN0;
+         break;
+      case OP_GREATEREQUAL:
+         op->type = SLANG_OPER_GREATEREQUAL;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+            RETURN0;
+         break;
+         /*case OP_LSHIFT: */
+         /*case OP_RSHIFT: */
+      case OP_ADD:
+         op->type = SLANG_OPER_ADD;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+            RETURN0;
+         break;
+      case OP_SUBTRACT:
+         op->type = SLANG_OPER_SUBTRACT;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+            RETURN0;
+         break;
+      case OP_MULTIPLY:
+         op->type = SLANG_OPER_MULTIPLY;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+            RETURN0;
+         break;
+      case OP_DIVIDE:
+         op->type = SLANG_OPER_DIVIDE;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+            RETURN0;
+         break;
+         /*case OP_MODULUS: */
+      case OP_PREINCREMENT:
+         op->type = SLANG_OPER_PREINCREMENT;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
+            RETURN0;
+         break;
+      case OP_PREDECREMENT:
+         op->type = SLANG_OPER_PREDECREMENT;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
+            RETURN0;
+         break;
+      case OP_PLUS:
+         op->type = SLANG_OPER_PLUS;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
+            RETURN0;
+         break;
+      case OP_MINUS:
+         op->type = SLANG_OPER_MINUS;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
+            RETURN0;
+         break;
+      case OP_NOT:
+         op->type = SLANG_OPER_NOT;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
+            RETURN0;
+         break;
+         /*case OP_COMPLEMENT: */
+      case OP_SUBSCRIPT:
+         op->type = SLANG_OPER_SUBSCRIPT;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 2))
+            RETURN0;
+         break;
+      case OP_METHOD:
+         op->type = SLANG_OPER_METHOD;
+         op->a_obj = parse_identifier(C);
+         if (op->a_obj == SLANG_ATOM_NULL)
+            RETURN0;
+
+         op->a_id = parse_identifier(C);
+         if (op->a_id == SLANG_ATOM_NULL)
+            RETURN0;
+
+         assert(*C->I == OP_END);
+         C->I++;
+
+         while (*C->I != OP_END)
+            if (!parse_child_operation(C, O, op, GL_FALSE))
+               RETURN0;
+         C->I++;
+#if 0
+         /* don't lookup the method (not yet anyway) */
+         if (!C->parsing_builtin
+             && !slang_function_scope_find_by_name(O->funs, op->a_id, 1)) {
+            const char *id;
+
+            id = slang_atom_pool_id(C->atoms, op->a_id);
+            if (!is_constructor_name(id, op->a_id, O->structs)) {
+               slang_info_log_error(C->L, "%s: undeclared function name.", id);
+               RETURN0;
+            }
+         }
+#endif
+         break;
+      case OP_CALL:
+         {
+            GLboolean array_constructor = GL_FALSE;
+            GLint array_constructor_size = 0;
+
+            op->type = SLANG_OPER_CALL;
+            op->a_id = parse_identifier(C);
+            if (op->a_id == SLANG_ATOM_NULL)
+               RETURN0;
+            switch (*C->I++) {
+            case FUNCTION_CALL_NONARRAY:
+               /* Nothing to do. */
+               break;
+            case FUNCTION_CALL_ARRAY:
+               /* Calling an array constructor. For example:
+                *   float[3](1.1, 2.2, 3.3);
+                */
+               if (!O->allow_array_types) {
+                  slang_info_log_error(C->L,
+                                       "array constructors not allowed "
+                                       "in this GLSL version");
+                  RETURN0;
+               }
+               else {
+                  /* parse the array constructor size */
+                  slang_operation array_size;
+                  array_constructor = GL_TRUE;
+                  slang_operation_construct(&array_size);
+                  if (!parse_expression(C, O, &array_size)) {
+                     slang_operation_destruct(&array_size);
+                     return GL_FALSE;
+                  }
+                  if (array_size.type != SLANG_OPER_LITERAL_INT) {
+                     slang_info_log_error(C->L,
+                        "constructor array size is not an integer");
+                     slang_operation_destruct(&array_size);
+                     RETURN0;
+                  }
+                  array_constructor_size = (int) array_size.literal[0];
+                  op->array_constructor = GL_TRUE;
+                  slang_operation_destruct(&array_size);
+               }
+               break;
+            default:
+               assert(0);
+               RETURN0;
+            }
+            while (*C->I != OP_END)
+               if (!parse_child_operation(C, O, op, GL_FALSE))
+                  RETURN0;
+            C->I++;
+
+            if (array_constructor &&
+                array_constructor_size != op->num_children) {
+               slang_info_log_error(C->L, "number of parameters to array"
+                                    " constructor does not match array size");
+               RETURN0;
+            }
+
+            if (!C->parsing_builtin
+                && !slang_function_scope_find_by_name(O->funs, op->a_id, 1)) {
+               const char *id;
+
+               id = slang_atom_pool_id(C->atoms, op->a_id);
+               if (!is_constructor_name(id, op->a_id, O->structs)) {
+                  slang_info_log_error(C->L, "%s: undeclared function name.", id);
+                  RETURN0;
+               }
+            }
+         }
+         break;
+      case OP_FIELD:
+         op->type = SLANG_OPER_FIELD;
+         op->a_id = parse_identifier(C);
+         if (op->a_id == SLANG_ATOM_NULL)
+            RETURN0;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
+            RETURN0;
+         break;
+      case OP_POSTINCREMENT:
+         op->type = SLANG_OPER_POSTINCREMENT;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
+            RETURN0;
+         break;
+      case OP_POSTDECREMENT:
+         op->type = SLANG_OPER_POSTDECREMENT;
+         if (!handle_nary_expression(C, op, &ops, &num_ops, 1))
+            RETURN0;
+         break;
+      default:
+         RETURN0;
+      }
+   }
+   C->I++;
+
+   slang_operation_destruct(oper);
+   *oper = *ops; /* struct copy */
+   _slang_free(ops);
+
+   return 1;
+}
+
+/* function parameter array presence */
+#define PARAMETER_ARRAY_NOT_PRESENT 0
+#define PARAMETER_ARRAY_PRESENT 1
+
+static int
+parse_parameter_declaration(slang_parse_ctx * C, slang_output_ctx * O,
+                            slang_variable * param)
+{
+   int param_qual, precision_qual;
+
+   /* parse and validate the parameter's type qualifiers (there can be
+    * two at most) because not all combinations are valid
+    */
+   if (!parse_type_qualifier(C, &param->type.qualifier))
+      RETURN0;
+
+   param_qual = *C->I++;
+   switch (param_qual) {
+   case PARAM_QUALIFIER_IN:
+      if (param->type.qualifier != SLANG_QUAL_CONST
+          && param->type.qualifier != SLANG_QUAL_NONE) {
+         slang_info_log_error(C->L, "Invalid type qualifier.");
+         RETURN0;
+      }
+      break;
+   case PARAM_QUALIFIER_OUT:
+      if (param->type.qualifier == SLANG_QUAL_NONE)
+         param->type.qualifier = SLANG_QUAL_OUT;
+      else {
+         slang_info_log_error(C->L, "Invalid type qualifier.");
+         RETURN0;
+      }
+      break;
+   case PARAM_QUALIFIER_INOUT:
+      if (param->type.qualifier == SLANG_QUAL_NONE)
+         param->type.qualifier = SLANG_QUAL_INOUT;
+      else {
+         slang_info_log_error(C->L, "Invalid type qualifier.");
+         RETURN0;
+      }
+      break;
+   case PARAM_QUALIFIER_NONE:
+      /* like IN but doesn't throw error */
+      break;
+   default:
+      RETURN0;
+   }
+
+   /* parse precision qualifier (lowp, mediump, highp */
+   precision_qual = *C->I++;
+   /* ignored at this time */
+   (void) precision_qual;
+
+   /* parse parameter's type specifier and name */
+   if (!parse_type_specifier(C, O, &param->type.specifier))
+      RETURN0;
+   if (!parse_type_array_size(C, O, &param->type.array_len))
+      RETURN0;
+   param->a_name = parse_identifier(C);
+   if (param->a_name == SLANG_ATOM_NULL)
+      RETURN0;
+
+   /* first-class array
+    */
+   if (param->type.array_len >= 0) {
+      slang_type_specifier p;
+
+      slang_type_specifier_ctr(&p);
+      if (!slang_type_specifier_copy(&p, &param->type.specifier)) {
+         slang_type_specifier_dtr(&p);
+         RETURN0;
+      }
+      if (!convert_to_array(C, param, &p)) {
+         slang_type_specifier_dtr(&p);
+         RETURN0;
+      }
+      slang_type_specifier_dtr(&p);
+      param->array_len = param->type.array_len;
+   }
+
+   /* if the parameter is an array, parse its size (the size must be
+    * explicitly defined
+    */
+   if (*C->I++ == PARAMETER_ARRAY_PRESENT) {
+      slang_type_specifier p;
+
+      if (param->type.array_len >= 0) {
+         slang_info_log_error(C->L, "multi-dimensional arrays not allowed");
+         RETURN0;
+      }
+      slang_type_specifier_ctr(&p);
+      if (!slang_type_specifier_copy(&p, &param->type.specifier)) {
+         slang_type_specifier_dtr(&p);
+         RETURN0;
+      }
+      if (!convert_to_array(C, param, &p)) {
+         slang_type_specifier_dtr(&p);
+         RETURN0;
+      }
+      slang_type_specifier_dtr(&p);
+      if (!parse_array_len(C, O, &param->array_len))
+         RETURN0;
+   }
+
+#if 0
+   /* calculate the parameter size */
+   if (!calculate_var_size(C, O, param))
+      RETURN0;
+#endif
+   /* TODO: allocate the local address here? */
+   return 1;
+}
+
+/* function type */
+#define FUNCTION_ORDINARY 0
+#define FUNCTION_CONSTRUCTOR 1
+#define FUNCTION_OPERATOR 2
+
+/* function parameter */
+#define PARAMETER_NONE 0
+#define PARAMETER_NEXT 1
+
+/* operator type */
+#define OPERATOR_ADDASSIGN 1
+#define OPERATOR_SUBASSIGN 2
+#define OPERATOR_MULASSIGN 3
+#define OPERATOR_DIVASSIGN 4
+/*#define OPERATOR_MODASSIGN 5*/
+/*#define OPERATOR_LSHASSIGN 6*/
+/*#define OPERATOR_RSHASSIGN 7*/
+/*#define OPERATOR_ANDASSIGN 8*/
+/*#define OPERATOR_XORASSIGN 9*/
+/*#define OPERATOR_ORASSIGN 10*/
+#define OPERATOR_LOGICALXOR 11
+/*#define OPERATOR_BITOR 12*/
+/*#define OPERATOR_BITXOR 13*/
+/*#define OPERATOR_BITAND 14*/
+#define OPERATOR_LESS 15
+#define OPERATOR_GREATER 16
+#define OPERATOR_LESSEQUAL 17
+#define OPERATOR_GREATEREQUAL 18
+/*#define OPERATOR_LSHIFT 19*/
+/*#define OPERATOR_RSHIFT 20*/
+#define OPERATOR_MULTIPLY 21
+#define OPERATOR_DIVIDE 22
+/*#define OPERATOR_MODULUS 23*/
+#define OPERATOR_INCREMENT 24
+#define OPERATOR_DECREMENT 25
+#define OPERATOR_PLUS 26
+#define OPERATOR_MINUS 27
+/*#define OPERATOR_COMPLEMENT 28*/
+#define OPERATOR_NOT 29
+
+static const struct
+{
+   unsigned int o_code;
+   const char *o_name;
+} operator_names[] = {
+   {OPERATOR_INCREMENT, "++"},
+   {OPERATOR_ADDASSIGN, "+="},
+   {OPERATOR_PLUS, "+"},
+   {OPERATOR_DECREMENT, "--"},
+   {OPERATOR_SUBASSIGN, "-="},
+   {OPERATOR_MINUS, "-"},
+   {OPERATOR_NOT, "!"},
+   {OPERATOR_MULASSIGN, "*="},
+   {OPERATOR_MULTIPLY, "*"},
+   {OPERATOR_DIVASSIGN, "/="},
+   {OPERATOR_DIVIDE, "/"},
+   {OPERATOR_LESSEQUAL, "<="},
+   /*{ OPERATOR_LSHASSIGN, "<<=" }, */
+   /*{ OPERATOR_LSHIFT, "<<" }, */
+   {OPERATOR_LESS, "<"},
+   {OPERATOR_GREATEREQUAL, ">="},
+   /*{ OPERATOR_RSHASSIGN, ">>=" }, */
+   /*{ OPERATOR_RSHIFT, ">>" }, */
+   {OPERATOR_GREATER, ">"},
+   /*{ OPERATOR_MODASSIGN, "%=" }, */
+   /*{ OPERATOR_MODULUS, "%" }, */
+   /*{ OPERATOR_ANDASSIGN, "&=" }, */
+   /*{ OPERATOR_BITAND, "&" }, */
+   /*{ OPERATOR_ORASSIGN, "|=" }, */
+   /*{ OPERATOR_BITOR, "|" }, */
+   /*{ OPERATOR_COMPLEMENT, "~" }, */
+   /*{ OPERATOR_XORASSIGN, "^=" }, */
+   {OPERATOR_LOGICALXOR, "^^"},
+   /*{ OPERATOR_BITXOR, "^" } */
+};
+
+static slang_atom
+parse_operator_name(slang_parse_ctx * C)
+{
+   unsigned int i;
+
+   for (i = 0; i < sizeof(operator_names) / sizeof(*operator_names); i++) {
+      if (operator_names[i].o_code == (unsigned int) (*C->I)) {
+         slang_atom atom =
+            slang_atom_pool_atom(C->atoms, operator_names[i].o_name);
+         if (atom == SLANG_ATOM_NULL) {
+            slang_info_log_memory(C->L);
+            RETURN0;
+         }
+         C->I++;
+         return atom;
+      }
+   }
+   RETURN0;
+}
+
+
+static int
+parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O,
+                         slang_function * func)
+{
+   GLuint functype;
+   /* parse function type and name */
+   if (!parse_fully_specified_type(C, O, &func->header.type))
+      RETURN0;
+
+   functype = *C->I++;
+   switch (functype) {
+   case FUNCTION_ORDINARY:
+      func->kind = SLANG_FUNC_ORDINARY;
+      func->header.a_name = parse_identifier(C);
+      if (func->header.a_name == SLANG_ATOM_NULL)
+         RETURN0;
+      break;
+   case FUNCTION_CONSTRUCTOR:
+      func->kind = SLANG_FUNC_CONSTRUCTOR;
+      if (func->header.type.specifier.type == SLANG_SPEC_STRUCT)
+         RETURN0;
+      func->header.a_name =
+         slang_atom_pool_atom(C->atoms,
+                              slang_type_specifier_type_to_string
+                              (func->header.type.specifier.type));
+      if (func->header.a_name == SLANG_ATOM_NULL) {
+         slang_info_log_memory(C->L);
+         RETURN0;
+      }
+      break;
+   case FUNCTION_OPERATOR:
+      func->kind = SLANG_FUNC_OPERATOR;
+      func->header.a_name = parse_operator_name(C);
+      if (func->header.a_name == SLANG_ATOM_NULL)
+         RETURN0;
+      break;
+   default:
+      RETURN0;
+   }
+
+   if (!legal_identifier(func->header.a_name)) {
+      slang_info_log_error(C->L, "illegal function name '%s'",
+                           (char *) func->header.a_name);
+      RETURN0;
+   }
+
+   /* parse function parameters */
+   while (*C->I++ == PARAMETER_NEXT) {
+      slang_variable *p = slang_variable_scope_grow(func->parameters);
+      if (!p) {
+         slang_info_log_memory(C->L);
+         RETURN0;
+      }
+      if (!parse_parameter_declaration(C, O, p))
+         RETURN0;
+   }
+
+   /* if the function returns a value, append a hidden __retVal 'out'
+    * parameter that corresponds to the return value.
+    */
+   if (_slang_function_has_return_value(func)) {
+      slang_variable *p = slang_variable_scope_grow(func->parameters);
+      slang_atom a_retVal = slang_atom_pool_atom(C->atoms, "__retVal");
+      assert(a_retVal);
+      p->a_name = a_retVal;
+      p->type = func->header.type;
+      p->type.qualifier = SLANG_QUAL_OUT;
+   }
+
+   /* function formal parameters and local variables share the same
+    * scope, so save the information about param count in a seperate
+    * place also link the scope to the global variable scope so when a
+    * given identifier is not found here, the search process continues
+    * in the global space
+    */
+   func->param_count = func->parameters->num_variables;
+   func->parameters->outer_scope = O->vars;
+
+   return 1;
+}
+
+static int
+parse_function_definition(slang_parse_ctx * C, slang_output_ctx * O,
+                          slang_function * func)
+{
+   slang_output_ctx o = *O;
+
+   if (!parse_function_prototype(C, O, func))
+      RETURN0;
+
+   /* create function's body operation */
+   func->body = (slang_operation *) _slang_alloc(sizeof(slang_operation));
+   if (func->body == NULL) {
+      slang_info_log_memory(C->L);
+      RETURN0;
+   }
+   if (!slang_operation_construct(func->body)) {
+      _slang_free(func->body);
+      func->body = NULL;
+      slang_info_log_memory(C->L);
+      RETURN0;
+   }
+
+   /* to parse the body the parse context is modified in order to
+    * capture parsed variables into function's local variable scope
+    */
+   C->global_scope = GL_FALSE;
+   o.vars = func->parameters;
+   if (!parse_statement(C, &o, func->body))
+      RETURN0;
+
+   C->global_scope = GL_TRUE;
+   return 1;
+}
+
+static GLboolean
+initialize_global(slang_assemble_ctx * A, slang_variable * var)
+{
+   slang_operation op_id, op_assign;
+   GLboolean result;
+
+   /* construct the left side of assignment */
+   if (!slang_operation_construct(&op_id))
+      return GL_FALSE;
+   op_id.type = SLANG_OPER_IDENTIFIER;
+   op_id.a_id = var->a_name;
+
+   /* put the variable into operation's scope */
+   op_id.locals->variables =
+      (slang_variable **) _slang_alloc(sizeof(slang_variable *));
+   if (op_id.locals->variables == NULL) {
+      slang_operation_destruct(&op_id);
+      return GL_FALSE;
+   }
+   op_id.locals->num_variables = 1;
+   op_id.locals->variables[0] = var;
+
+   /* construct the assignment expression */
+   if (!slang_operation_construct(&op_assign)) {
+      op_id.locals->num_variables = 0;
+      slang_operation_destruct(&op_id);
+      return GL_FALSE;
+   }
+   op_assign.type = SLANG_OPER_ASSIGN;
+   op_assign.children =
+      (slang_operation *) _slang_alloc(2 * sizeof(slang_operation));
+   if (op_assign.children == NULL) {
+      slang_operation_destruct(&op_assign);
+      op_id.locals->num_variables = 0;
+      slang_operation_destruct(&op_id);
+      return GL_FALSE;
+   }
+   op_assign.num_children = 2;
+   op_assign.children[0] = op_id;
+   op_assign.children[1] = *var->initializer;
+
+   result = 1;
+
+   /* carefully destroy the operations */
+   op_assign.num_children = 0;
+   _slang_free(op_assign.children);
+   op_assign.children = NULL;
+   slang_operation_destruct(&op_assign);
+   op_id.locals->num_variables = 0;
+   slang_operation_destruct(&op_id);
+
+   if (!result)
+      return GL_FALSE;
+
+   return GL_TRUE;
+}
+
+/* init declarator list */
+#define DECLARATOR_NONE 0
+#define DECLARATOR_NEXT 1
+
+/* variable declaration */
+#define VARIABLE_NONE 0
+#define VARIABLE_IDENTIFIER 1
+#define VARIABLE_INITIALIZER 2
+#define VARIABLE_ARRAY_EXPLICIT 3
+#define VARIABLE_ARRAY_UNKNOWN 4
+
+
+/**
+ * Check if it's OK to re-declare a variable with the given new type.
+ * This happens when applying layout qualifiers to gl_FragCoord or
+ * (re)setting an array size.
+ * If redeclaration is OK, return a pointer to the incoming variable
+ * updated with new type info.  Else return NULL;
+ */
+static slang_variable *
+redeclare_variable(slang_variable *var, 
+                   const slang_fully_specified_type *type)
+{
+   if (slang_fully_specified_types_compatible(&var->type, type)) {
+      /* replace orig var layout with new layout */
+      var->type.layout = type->layout;
+
+      /* XXX there may be other type updates in the future here */
+
+      return var;
+   }
+   else
+      return NULL;
+}
+
+
+/**
+ * Parse the initializer for a variable declaration.
+ */
+static int
+parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O,
+                      const slang_fully_specified_type * type)
+{
+   GET_CURRENT_CONTEXT(ctx); /* a hack */
+   slang_variable *var = NULL, *prevDecl;
+   slang_atom a_name;
+
+   /* empty init declatator (without name, e.g. "float ;") */
+   if (*C->I++ == VARIABLE_NONE)
+      return 1;
+
+   a_name = parse_identifier(C);
+
+   /* check if name is already in this scope */
+   prevDecl = _slang_variable_locate(O->vars, a_name, C->global_scope);
+   if (prevDecl) {
+      /* A var with this name has already been declared.
+       * Check if redeclaring the var with a different type/layout is legal.
+       */
+      if (C->global_scope) {
+         var = redeclare_variable(prevDecl, type);
+      }
+      if (!var) {
+         slang_info_log_error(C->L,
+                   "declaration of '%s' conflicts with previous declaration",
+                   (char *) a_name);
+         RETURN0;
+      }
+   }
+
+   if (!var) {
+      /* make room for a new variable and initialize it */
+      var = slang_variable_scope_grow(O->vars);
+      if (!var) {
+         slang_info_log_memory(C->L);
+         RETURN0;
+      }
+
+      /* copy the declarator type qualifier/etc info, parse the identifier */
+      var->type.qualifier = type->qualifier;
+      var->type.centroid = type->centroid;
+      var->type.precision = type->precision;
+      var->type.specifier = type->specifier;/*new*/
+      var->type.variant = type->variant;
+      var->type.layout = type->layout;
+      var->type.array_len = type->array_len;
+      var->type.varying_kind = type->varying_kind;
+      var->a_name = a_name;
+      if (var->a_name == SLANG_ATOM_NULL)
+         RETURN0;
+   }
+
+   switch (*C->I++) {
+   case VARIABLE_NONE:
+      /* simple variable declarator - just copy the specifier */
+      if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier))
+         RETURN0;
+      break;
+   case VARIABLE_INITIALIZER:
+      /* initialized variable - copy the specifier and parse the expression */
+      if (0 && type->array_len >= 0) {
+         /* The type was something like "float[4]" */
+         convert_to_array(C, var, &type->specifier);
+         var->array_len = type->array_len;
+      }
+      else {
+         if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier))
+            RETURN0;
+      }
+      var->initializer =
+         (slang_operation *) _slang_alloc(sizeof(slang_operation));
+      if (var->initializer == NULL) {
+         slang_info_log_memory(C->L);
+         RETURN0;
+      }
+      if (!slang_operation_construct(var->initializer)) {
+         _slang_free(var->initializer);
+         var->initializer = NULL;
+         slang_info_log_memory(C->L);
+         RETURN0;
+      }
+      if (!parse_expression(C, O, var->initializer))
+         RETURN0;
+      break;
+   case VARIABLE_ARRAY_UNKNOWN:
+      /* unsized array - mark it as array and copy the specifier to
+       * the array element
+       */
+      if (type->array_len >= 0) {
+         slang_info_log_error(C->L, "multi-dimensional arrays not allowed");
+         RETURN0;
+      }
+      if (!convert_to_array(C, var, &type->specifier))
+         return GL_FALSE;
+      break;
+   case VARIABLE_ARRAY_EXPLICIT:
+      if (type->array_len >= 0) {
+         /* the user is trying to do something like: float[2] x[3]; */
+         slang_info_log_error(C->L, "multi-dimensional arrays not allowed");
+         RETURN0;
+      }
+      if (!convert_to_array(C, var, &type->specifier))
+         return GL_FALSE;
+      if (!parse_array_len(C, O, &var->array_len))
+         return GL_FALSE;
+      break;
+   default:
+      RETURN0;
+   }
+
+   /* allocate global address space for a variable with a known size */
+   if (C->global_scope
+       && !(var->type.specifier.type == SLANG_SPEC_ARRAY
+            && var->array_len == 0)) {
+      if (!calculate_var_size(C, O, var))
+         return GL_FALSE;
+   }
+
+   /* emit code for global var decl */
+   if (C->global_scope) {
+      slang_assemble_ctx A;
+      memset(&A, 0, sizeof(slang_assemble_ctx));
+      A.allow_uniform_initializers = C->version > 110;
+      A.atoms = C->atoms;
+      A.space.funcs = O->funs;
+      A.space.structs = O->structs;
+      A.space.vars = O->vars;
+      A.program = O->program;
+      A.pragmas = O->pragmas;
+      A.vartable = O->vartable;
+      A.log = C->L;
+      A.curFuncEndLabel = NULL;
+      A.EmitContReturn = ctx->Shader.EmitContReturn;
+      if (!_slang_codegen_global_variable(&A, var, C->type))
+         RETURN0;
+   }
+
+   /* initialize global variable */
+   if (C->global_scope) {
+      if (var->initializer != NULL) {
+         slang_assemble_ctx A;
+         memset(&A, 0, sizeof(slang_assemble_ctx));
+         A.allow_uniform_initializers = C->version > 110;
+         A.atoms = C->atoms;
+         A.space.funcs = O->funs;
+         A.space.structs = O->structs;
+         A.space.vars = O->vars;
+         if (!initialize_global(&A, var))
+            RETURN0;
+      }
+   }
+
+   if (var->type.qualifier == SLANG_QUAL_FIXEDINPUT &&
+       var->a_name == slang_atom_pool_atom(C->atoms, "gl_FragCoord")) {
+      /* set the program's PixelCenterInteger, OriginUpperLeft fields */
+      struct gl_fragment_program *fragProg =
+         (struct gl_fragment_program *) O->program;
+
+      if (var->type.layout & SLANG_LAYOUT_UPPER_LEFT_BIT) {
+         fragProg->OriginUpperLeft = GL_TRUE;
+      }
+      if (var->type.layout & SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT) {
+         fragProg->PixelCenterInteger = GL_TRUE;
+      }
+   }
+
+   return 1;
+}
+
+/**
+ * Parse a list of variable declarations.  Each variable may have an
+ * initializer.
+ */
+static int
+parse_init_declarator_list(slang_parse_ctx * C, slang_output_ctx * O)
+{
+   slang_fully_specified_type type;
+
+   /* parse the fully specified type, common to all declarators */
+   if (!slang_fully_specified_type_construct(&type))
+      RETURN0;
+   if (!parse_fully_specified_type(C, O, &type)) {
+      slang_fully_specified_type_destruct(&type);
+      RETURN0;
+   }
+
+   /* parse declarators, pass-in the parsed type */
+   do {
+      if (!parse_init_declarator(C, O, &type)) {
+         slang_fully_specified_type_destruct(&type);
+         RETURN0;
+      }
+   }
+   while (*C->I++ == DECLARATOR_NEXT);
+
+   slang_fully_specified_type_destruct(&type);
+   return 1;
+}
+
+
+/**
+ * Parse a function definition or declaration.
+ * \param C  parsing context
+ * \param O  output context
+ * \param definition if non-zero expect a definition, else a declaration
+ * \param parsed_func_ret  returns the parsed function
+ * \return GL_TRUE if success, GL_FALSE if failure
+ */
+static GLboolean
+parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition,
+               slang_function ** parsed_func_ret)
+{
+   slang_function parsed_func, *found_func;
+
+   /* parse function definition/declaration */
+   if (!slang_function_construct(&parsed_func))
+      return GL_FALSE;
+   if (definition) {
+      if (!parse_function_definition(C, O, &parsed_func)) {
+         slang_function_destruct(&parsed_func);
+         return GL_FALSE;
+      }
+   }
+   else {
+      if (!parse_function_prototype(C, O, &parsed_func)) {
+         slang_function_destruct(&parsed_func);
+         return GL_FALSE;
+      }
+   }
+
+   /* find a function with a prototype matching the parsed one - only
+    * the current scope is being searched to allow built-in function
+    * overriding
+    */
+   found_func = slang_function_scope_find(O->funs, &parsed_func, 0);
+   if (found_func == NULL) {
+      /* New function, add it to the function list */
+      O->funs->functions =
+         (slang_function *) _slang_realloc(O->funs->functions,
+                                           O->funs->num_functions
+                                           * sizeof(slang_function),
+                                           (O->funs->num_functions + 1)
+                                           * sizeof(slang_function));
+      if (O->funs->functions == NULL) {
+         /* Make sure that there are no functions marked, as the
+          * allocation is currently NULL, in order to avoid
+          * a potental segfault as we clean up later.
+          */
+         O->funs->num_functions = 0;
+
+         slang_info_log_memory(C->L);
+         slang_function_destruct(&parsed_func);
+         return GL_FALSE;
+      }
+      O->funs->functions[O->funs->num_functions] = parsed_func;
+      O->funs->num_functions++;
+
+      /* return the newly parsed function */
+      *parsed_func_ret = &O->funs->functions[O->funs->num_functions - 1];
+   }
+   else {
+      /* previously defined or declared */
+      /* TODO: check function return type qualifiers and specifiers */
+      if (definition) {
+         if (found_func->body != NULL) {
+            slang_info_log_error(C->L, "%s: function already has a body.",
+                                 slang_atom_pool_id(C->atoms,
+                                                    parsed_func.header.
+                                                    a_name));
+            slang_function_destruct(&parsed_func);
+            return GL_FALSE;
+         }
+
+         /* destroy the existing function declaration and replace it
+          * with the new one
+          */
+         slang_function_destruct(found_func);
+         *found_func = parsed_func;
+      }
+      else {
+         /* another declaration of the same function prototype - ignore it */
+         slang_function_destruct(&parsed_func);
+      }
+
+      /* return the found function */
+      *parsed_func_ret = found_func;
+   }
+
+   return GL_TRUE;
+}
+
+/* declaration */
+#define DECLARATION_FUNCTION_PROTOTYPE 1
+#define DECLARATION_INIT_DECLARATOR_LIST 2
+
+static int
+parse_declaration(slang_parse_ctx * C, slang_output_ctx * O)
+{
+   switch (*C->I++) {
+   case DECLARATION_INIT_DECLARATOR_LIST:
+      if (!parse_init_declarator_list(C, O))
+         RETURN0;
+      break;
+   case DECLARATION_FUNCTION_PROTOTYPE:
+      {
+         slang_function *dummy_func;
+
+         if (!parse_function(C, O, 0, &dummy_func))
+            RETURN0;
+      }
+      break;
+   default:
+      RETURN0;
+   }
+   return 1;
+}
+
+static int
+parse_default_precision(slang_parse_ctx * C, slang_output_ctx * O)
+{
+   int precision, type;
+
+   if (!O->allow_precision) {
+      slang_info_log_error(C->L, "syntax error at \"precision\"");
+      RETURN0;
+   }
+
+   precision = *C->I++;
+   switch (precision) {
+   case PRECISION_LOW:
+   case PRECISION_MEDIUM:
+   case PRECISION_HIGH:
+      /* OK */
+      break;
+   default:
+      _mesa_problem(NULL, "unexpected precision %d at %s:%d\n",
+                    precision, __FILE__, __LINE__);
+      RETURN0;
+   }
+
+   type = *C->I++;
+   switch (type) {
+   case TYPE_SPECIFIER_FLOAT:
+   case TYPE_SPECIFIER_INT:
+   case TYPE_SPECIFIER_SAMPLER1D:
+   case TYPE_SPECIFIER_SAMPLER2D:
+   case TYPE_SPECIFIER_SAMPLER3D:
+   case TYPE_SPECIFIER_SAMPLERCUBE:
+   case TYPE_SPECIFIER_SAMPLER1DSHADOW:
+   case TYPE_SPECIFIER_SAMPLER2DSHADOW:
+   case TYPE_SPECIFIER_SAMPLER2DRECT:
+   case TYPE_SPECIFIER_SAMPLER2DRECTSHADOW:
+   case TYPE_SPECIFIER_SAMPLER_1D_ARRAY:
+   case TYPE_SPECIFIER_SAMPLER_2D_ARRAY:
+   case TYPE_SPECIFIER_SAMPLER_1D_ARRAY_SHADOW:
+   case TYPE_SPECIFIER_SAMPLER_2D_ARRAY_SHADOW:
+      /* OK */
+      break;
+   default:
+      _mesa_problem(NULL, "unexpected type %d at %s:%d\n",
+                    type, __FILE__, __LINE__);
+      RETURN0;
+   }
+
+   assert(type < TYPE_SPECIFIER_COUNT);
+   O->default_precision[type] = precision;
+
+   return 1;
+}
+
+
+/**
+ * Initialize the default precision for all types.
+ * XXX this info isn't used yet.
+ */
+static void
+init_default_precision(slang_output_ctx *O, slang_unit_type type)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLuint i;
+   for (i = 0; i < TYPE_SPECIFIER_COUNT; i++) {
+#if FEATURE_es2_glsl
+      if (ctx->API == API_OPENGLES2)
+        O->default_precision[i] = PRECISION_LOW;
+      else
+        O->default_precision[i] = PRECISION_HIGH;
+#else
+      (void) ctx;
+      O->default_precision[i] = PRECISION_HIGH;
+#endif
+   }
+
+   if (type == SLANG_UNIT_VERTEX_SHADER || type == SLANG_UNIT_GEOMETRY_SHADER) {
+      O->default_precision[TYPE_SPECIFIER_FLOAT] = PRECISION_HIGH;
+      O->default_precision[TYPE_SPECIFIER_INT] = PRECISION_HIGH;
+   }
+   else {
+      O->default_precision[TYPE_SPECIFIER_INT] = PRECISION_MEDIUM;
+   }
+}
+
+
+static int
+parse_invariant(slang_parse_ctx * C, slang_output_ctx * O)
+{
+   if (O->allow_invariant) {
+      slang_atom *a = parse_identifier(C);
+      /* XXX not doing anything with this var yet */
+      /*printf("ID: %s\n", (char*) a);*/
+      return a ? 1 : 0;
+   }
+   else {
+      slang_info_log_error(C->L, "syntax error at \"invariant\"");
+      RETURN0;
+   }
+}
+      
+
+/* external declaration or default precision specifier */
+#define EXTERNAL_NULL 0
+#define EXTERNAL_FUNCTION_DEFINITION 1
+#define EXTERNAL_DECLARATION 2
+#define DEFAULT_PRECISION 3
+#define INVARIANT_STMT 4
+
+
+static GLboolean
+parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit,
+                struct gl_shader *shader)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   slang_output_ctx o;
+   GLboolean success;
+   GLuint maxRegs;
+   slang_function *mainFunc = NULL;
+
+   if (unit->type == SLANG_UNIT_FRAGMENT_BUILTIN ||
+       unit->type == SLANG_UNIT_FRAGMENT_SHADER) {
+      maxRegs = ctx->Const.FragmentProgram.MaxTemps;
+   }
+   else if (unit->type == SLANG_UNIT_VERTEX_BUILTIN ||
+            unit->type == SLANG_UNIT_VERTEX_SHADER) {
+      maxRegs = ctx->Const.VertexProgram.MaxTemps;
+   } else {
+      assert(unit->type == SLANG_UNIT_GEOMETRY_BUILTIN ||
+             unit->type == SLANG_UNIT_GEOMETRY_SHADER);
+      maxRegs = ctx->Const.GeometryProgram.MaxTemps;
+   }
+
+   /* setup output context */
+   o.funs = &unit->funs;
+   o.structs = &unit->structs;
+   o.vars = &unit->vars;
+   o.program = shader ? shader->Program : NULL;
+   o.pragmas = shader ? &shader->Pragmas : NULL;
+   o.vartable = _slang_new_var_table(maxRegs);
+   _slang_push_var_table(o.vartable);
+
+   /* allow 'invariant' keyword? */
+#if FEATURE_es2_glsl
+   o.allow_invariant =
+      (ctx->API == API_OPENGLES2 || C->version >= 120) ? GL_TRUE : GL_FALSE;
+#else
+   o.allow_invariant = (C->version >= 120) ? GL_TRUE : GL_FALSE;
+#endif
+
+   /* allow 'centroid' keyword? */
+   o.allow_centroid = (C->version >= 120) ? GL_TRUE : GL_FALSE;
+
+   /* allow 'lowp/mediump/highp' keywords? */
+#if FEATURE_es2_glsl
+   o.allow_precision =
+      (ctx->API == API_OPENGLES2 || C->version >= 120) ? GL_TRUE : GL_FALSE;
+#else
+   o.allow_precision = (C->version >= 120) ? GL_TRUE : GL_FALSE;
+#endif
+   init_default_precision(&o, unit->type);
+
+   /* allow 'float[]' keyword? */
+   o.allow_array_types = (C->version >= 120) ? GL_TRUE : GL_FALSE;
+
+   /* parse individual functions and declarations */
+   while (*C->I != EXTERNAL_NULL) {
+      switch (*C->I++) {
+      case EXTERNAL_FUNCTION_DEFINITION:
+         {
+            slang_function *func;
+            success = parse_function(C, &o, 1, &func);
+            if (success && strcmp((char *) func->header.a_name, "main") == 0) {
+               /* found main() */
+               mainFunc = func;
+            }
+         }
+         break;
+      case EXTERNAL_DECLARATION:
+         success = parse_declaration(C, &o);
+         break;
+      case DEFAULT_PRECISION:
+         success = parse_default_precision(C, &o);
+         break;
+      case INVARIANT_STMT:
+         success = parse_invariant(C, &o);
+         break;
+      default:
+         success = GL_FALSE;
+      }
+
+      if (!success) {
+         /* xxx free codegen */
+         _slang_pop_var_table(o.vartable);
+         return GL_FALSE;
+      }
+   }
+   C->I++;
+
+   if (mainFunc) {
+      /* assemble (generate code) for main() */
+      slang_assemble_ctx A;
+      memset(&A, 0, sizeof(slang_assemble_ctx));
+      A.atoms = C->atoms;
+      A.space.funcs = o.funs;
+      A.space.structs = o.structs;
+      A.space.vars = o.vars;
+      A.program = o.program;
+      A.pragmas = &shader->Pragmas;
+      A.vartable = o.vartable;
+      A.EmitContReturn = ctx->Shader.EmitContReturn;
+      A.log = C->L;
+      A.allow_uniform_initializers = C->version > 110;
+
+      /* main() takes no parameters */
+      if (mainFunc->param_count > 0) {
+         slang_info_log_error(A.log, "main() takes no arguments");
+         return GL_FALSE;
+      }
+
+      _slang_codegen_function(&A, mainFunc);
+
+      shader->Main = GL_TRUE; /* this shader defines main() */
+
+      shader->UnresolvedRefs = A.UnresolvedRefs;
+   }
+
+   _slang_pop_var_table(o.vartable);
+   _slang_delete_var_table(o.vartable);
+
+   return GL_TRUE;
+}
+
+static GLboolean
+compile_binary(const unsigned char * prod, slang_code_unit * unit,
+               GLuint version,
+               slang_unit_type type, slang_info_log * infolog,
+               slang_code_unit * builtin, slang_code_unit * downlink,
+               struct gl_shader *shader)
+{
+   slang_parse_ctx C;
+
+   unit->type = type;
+
+   /* setup parse context */
+   C.I = prod;
+   C.L = infolog;
+   C.parsing_builtin = (builtin == NULL);
+   C.global_scope = GL_TRUE;
+   C.atoms = &unit->object->atompool;
+   C.type = type;
+   C.version = version;
+
+   if (!check_revision(&C))
+      return GL_FALSE;
+
+   if (downlink != NULL) {
+      unit->vars.outer_scope = &downlink->vars;
+      unit->funs.outer_scope = &downlink->funs;
+      unit->structs.outer_scope = &downlink->structs;
+   }
+
+   /* parse translation unit */
+   return parse_code_unit(&C, unit, shader);
+}
+
+static GLboolean
+compile_with_grammar(const char *source,
+                     slang_code_unit *unit,
+                     slang_unit_type type,
+                     slang_info_log *infolog,
+                     slang_code_unit *builtin,
+                     struct gl_shader *shader,
+                     struct gl_sl_pragmas *pragmas,
+                     unsigned int shader_type,
+                     unsigned int parsing_builtin)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct sl_pp_purify_options options;
+   struct sl_pp_context *context;
+   unsigned char *prod;
+   GLuint size;
+   unsigned int version;
+   unsigned int maxVersion;
+   int result;
+   char errmsg[200] = "";
+
+   assert(shader_type == 1 || shader_type == 2);
+
+   memset(&options, 0, sizeof(options));
+
+   context = sl_pp_context_create(source, &options);
+   if (!context) {
+      slang_info_log_error(infolog, "out of memory");
+      return GL_FALSE;
+   }
+
+   if (sl_pp_version(context, &version)) {
+      slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context));
+      sl_pp_context_destroy(context);
+      return GL_FALSE;
+   }
+
+   if (sl_pp_context_add_extension(context, "GL_ARB_draw_buffers") ||
+       sl_pp_context_add_extension(context, "GL_ARB_texture_rectangle")) {
+      slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context));
+      sl_pp_context_destroy(context);
+      return GL_FALSE;
+   }
+
+   if (type == SLANG_UNIT_FRAGMENT_SHADER) {
+      sl_pp_context_add_extension(context, "GL_ARB_fragment_coord_conventions");
+   }
+
+
+#if FEATURE_es2_glsl
+   if (ctx->API == API_OPENGLES2) {
+      if (sl_pp_context_add_predefined(context, "GL_ES", "1") ||
+         sl_pp_context_add_predefined(context, "GL_FRAGMENT_PRECISION_HIGH", "1")) {
+        slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context));
+        sl_pp_context_destroy(context);
+        return GL_FALSE;
+      }
+   }
+#else
+   (void) ctx;
+#endif
+
+#if FEATURE_ARB_shading_language_120
+   maxVersion = 120;
+#elif FEATURE_es2_glsl
+   maxVersion = 100;
+#else
+   maxVersion = 110;
+#endif
+
+   if (version > maxVersion ||
+       (version != 100 && version != 110 && version != 120)) {
+      slang_info_log_error(infolog,
+                           "language version %.2f is not supported.",
+                           version * 0.01);
+      sl_pp_context_destroy(context);
+      return GL_FALSE;
+   }
+
+   /* Finally check the syntax and generate its binary representation. */
+   result = sl_cl_compile(context,
+                          shader_type,
+                          parsing_builtin,
+                          &prod,
+                          &size,
+                          errmsg,
+                          sizeof(errmsg));
+
+   sl_pp_context_destroy(context);
+
+   if (result) {
+      /*GLint pos;*/
+
+      slang_info_log_error(infolog, errmsg);
+      /* syntax error (possibly in library code) */
+#if 0
+      {
+         int line, col;
+         char *s;
+         s = (char *) _mesa_find_line_column((const GLubyte *) source,
+                                             (const GLubyte *) source + pos,
+                                             &line, &col);
+         printf("Error on line %d, col %d: %s\n", line, col, s);
+      }
+#endif
+      return GL_FALSE;
+   }
+
+   /* Syntax is okay - translate it to internal representation. */
+   if (!compile_binary(prod, unit, version, type, infolog, builtin,
+                       &builtin[SLANG_BUILTIN_TOTAL - 1],
+                       shader)) {
+      free(prod);
+      return GL_FALSE;
+   }
+   free(prod);
+   return GL_TRUE;
+}
+
+static const unsigned char slang_core_gc[] = {
+#include "library/slang_core_gc.h"
+};
+
+static const unsigned char slang_120_core_gc[] = {
+#include "library/slang_120_core_gc.h"
+};
+
+static const unsigned char slang_120_fragment_gc[] = {
+#include "library/slang_builtin_120_fragment_gc.h"
+};
+
+static const unsigned char slang_common_builtin_gc[] = {
+#include "library/slang_common_builtin_gc.h"
+};
+
+static const unsigned char slang_fragment_builtin_gc[] = {
+#include "library/slang_fragment_builtin_gc.h"
+};
+
+static const unsigned char slang_vertex_builtin_gc[] = {
+#include "library/slang_vertex_builtin_gc.h"
+};
+
+static const unsigned char slang_geometry_builtin_gc[] = {
+#include "library/slang_geometry_builtin_gc.h"
+};
+
+static GLboolean
+compile_object(const char *source,
+               slang_code_object *object,
+               slang_unit_type type,
+               slang_info_log *infolog,
+               struct gl_shader *shader,
+               struct gl_sl_pragmas *pragmas)
+{
+   slang_code_unit *builtins = NULL;
+   GLuint base_version = 110;
+   unsigned int shader_type;
+   unsigned int parsing_builtin;
+
+   /* set shader type - the syntax is slightly different for different shaders */
+   if (type == SLANG_UNIT_FRAGMENT_SHADER || type == SLANG_UNIT_FRAGMENT_BUILTIN) {
+      shader_type = 1;
+   } else {
+      shader_type = 2;
+   }
+
+   /* enable language extensions */
+   parsing_builtin = 1;
+
+   /* if parsing user-specified shader, load built-in library */
+   if (type == SLANG_UNIT_FRAGMENT_SHADER || type == SLANG_UNIT_VERTEX_SHADER ||
+       type == SLANG_UNIT_GEOMETRY_SHADER) {
+      /* compile core functionality first */
+      if (!compile_binary(slang_core_gc,
+                          &object->builtin[SLANG_BUILTIN_CORE],
+                          base_version,
+                          SLANG_UNIT_FRAGMENT_BUILTIN, infolog,
+                          NULL, NULL, NULL))
+         return GL_FALSE;
+
+#if FEATURE_ARB_shading_language_120
+      if (!compile_binary(slang_120_core_gc,
+                          &object->builtin[SLANG_BUILTIN_120_CORE],
+                          120,
+                          SLANG_UNIT_FRAGMENT_BUILTIN, infolog,
+                          NULL, &object->builtin[SLANG_BUILTIN_CORE], NULL))
+         return GL_FALSE;
+#endif
+
+      /* compile common functions and variables, link to core */
+      if (!compile_binary(slang_common_builtin_gc,
+                          &object->builtin[SLANG_BUILTIN_COMMON],
+#if FEATURE_ARB_shading_language_120
+                          120,
+#else
+                          base_version,
+#endif
+                          SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL,
+#if FEATURE_ARB_shading_language_120
+                          &object->builtin[SLANG_BUILTIN_120_CORE],
+#else
+                          &object->builtin[SLANG_BUILTIN_CORE],
+#endif
+                          NULL))
+         return GL_FALSE;
+
+      /* compile target-specific functions and variables, link to common */
+      if (type == SLANG_UNIT_FRAGMENT_SHADER) {
+         if (!compile_binary(slang_fragment_builtin_gc,
+                             &object->builtin[SLANG_BUILTIN_TARGET],
+                             base_version,
+                             SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL,
+                             &object->builtin[SLANG_BUILTIN_COMMON], NULL))
+            return GL_FALSE;
+#if FEATURE_ARB_shading_language_120
+         if (!compile_binary(slang_120_fragment_gc,
+                             &object->builtin[SLANG_BUILTIN_TARGET],
+                             120,
+                             SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL,
+                             &object->builtin[SLANG_BUILTIN_COMMON], NULL))
+            return GL_FALSE;
+#endif
+      }
+      else if (type == SLANG_UNIT_VERTEX_SHADER) {
+         if (!compile_binary(slang_vertex_builtin_gc,
+                             &object->builtin[SLANG_BUILTIN_TARGET],
+                             base_version,
+                             SLANG_UNIT_VERTEX_BUILTIN, infolog, NULL,
+                             &object->builtin[SLANG_BUILTIN_COMMON], NULL))
+            return GL_FALSE;
+      }
+#if FEATURE_ARB_geometry_shader4
+      else if (type == SLANG_UNIT_GEOMETRY_SHADER) {
+         if (!compile_binary(slang_geometry_builtin_gc,
+                             &object->builtin[SLANG_BUILTIN_TARGET],
+                             base_version,
+                             SLANG_UNIT_GEOMETRY_BUILTIN, infolog, NULL,
+                             &object->builtin[SLANG_BUILTIN_COMMON], NULL))
+            return GL_FALSE;
+      }
+#endif
+
+      /* disable language extensions */
+      parsing_builtin = 0;
+
+      builtins = object->builtin;
+   }
+
+   /* compile the actual shader - pass-in built-in library for external shader */
+   return compile_with_grammar(source,
+                               &object->unit,
+                               type,
+                               infolog,
+                               builtins,
+                               shader,
+                               pragmas,
+                               shader_type,
+                               parsing_builtin);
+}
+
+
+GLboolean
+_slang_compile(GLcontext *ctx, struct gl_shader *shader)
+{
+   GLboolean success;
+   slang_info_log info_log;
+   slang_code_object obj;
+   slang_unit_type type;
+   GLenum progTarget;
+
+   if (shader->Type == GL_VERTEX_SHADER) {
+      type = SLANG_UNIT_VERTEX_SHADER;
+   }
+   else if (shader->Type == GL_FRAGMENT_SHADER) {
+      type = SLANG_UNIT_FRAGMENT_SHADER;
+   } else {
+      assert(shader->Type == GL_GEOMETRY_SHADER_ARB);
+      type = SLANG_UNIT_GEOMETRY_SHADER;
+   }
+
+   if (!shader->Source)
+      return GL_FALSE;
+
+   ctx->Shader.MemPool = _slang_new_mempool(1024*1024);
+
+   shader->Main = GL_FALSE;
+
+   /* free the shader's old instructions, etc */
+   _mesa_reference_program(ctx, &shader->Program, NULL);
+
+   /* allocate new GPU program, parameter lists, etc. */
+   if (shader->Type == GL_VERTEX_SHADER)
+      progTarget = GL_VERTEX_PROGRAM_ARB;
+   else if (shader->Type == GL_FRAGMENT_SHADER)
+      progTarget = GL_FRAGMENT_PROGRAM_ARB;
+   else
+      progTarget = MESA_GEOMETRY_PROGRAM;
+   shader->Program = ctx->Driver.NewProgram(ctx, progTarget, 1);
+   shader->Program->Parameters = _mesa_new_parameter_list();
+   shader->Program->Varying = _mesa_new_parameter_list();
+   shader->Program->Attributes = _mesa_new_parameter_list();
+
+   slang_info_log_construct(&info_log);
+   _slang_code_object_ctr(&obj);
+
+   success = compile_object(shader->Source,
+                            &obj,
+                            type,
+                            &info_log,
+                            shader,
+                            &shader->Pragmas);
+
+   /* free shader's prev info log */
+   if (shader->InfoLog) {
+      free(shader->InfoLog);
+      shader->InfoLog = NULL;
+   }
+
+   if (info_log.text) {
+      /* copy info-log string to shader object */
+      shader->InfoLog = _mesa_strdup(info_log.text);
+   }
+
+   if (info_log.error_flag) {
+      success = GL_FALSE;
+   }
+
+   slang_info_log_destruct(&info_log);
+   _slang_code_object_dtr(&obj);
+
+   _slang_delete_mempool((slang_mempool *) ctx->Shader.MemPool);
+   ctx->Shader.MemPool = NULL;
+
+   /* remove any reads of output registers */
+#if 0
+   printf("Pre-remove output reads:\n");
+   _mesa_print_program(shader->Program);
+#endif
+   _mesa_remove_output_reads(shader->Program, PROGRAM_OUTPUT);
+   if (shader->Type == GL_VERTEX_SHADER) {
+      /* and remove writes to varying vars in vertex programs */
+      _mesa_remove_output_reads(shader->Program, PROGRAM_VARYING);
+   }
+#if 0
+   printf("Post-remove output reads:\n");
+   _mesa_print_program(shader->Program);
+#endif
+
+   shader->CompileStatus = success;
+
+   if (success) {
+      if (shader->Pragmas.Optimize &&
+          (ctx->Shader.Flags & GLSL_NO_OPT) == 0) {
+         _mesa_optimize_program(ctx, shader->Program);
+      }
+      if ((ctx->Shader.Flags & GLSL_NOP_VERT) &&
+          shader->Program->Target == GL_VERTEX_PROGRAM_ARB) {
+         _mesa_nop_vertex_program(ctx,
+                                  (struct gl_vertex_program *) shader->Program);
+      }
+      if ((ctx->Shader.Flags & GLSL_NOP_FRAG) &&
+          shader->Program->Target == GL_FRAGMENT_PROGRAM_ARB) {
+         _mesa_nop_fragment_program(ctx,
+                                (struct gl_fragment_program *) shader->Program);
+      }
+   }
+
+   if (ctx->Shader.Flags & GLSL_LOG) {
+      _mesa_write_shader_to_file(shader);
+   }
+
+   return success;
+}
+
diff --git a/src/mesa/slang/slang_compile.h b/src/mesa/slang/slang_compile.h
new file mode 100644 (file)
index 0000000..71fcaa3
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#if !defined SLANG_COMPILE_H
+#define SLANG_COMPILE_H
+
+#include "main/imports.h"
+#include "main/mtypes.h"
+#include "slang_typeinfo.h"
+#include "slang_compile_variable.h"
+#include "slang_compile_struct.h"
+#include "slang_compile_operation.h"
+#include "slang_compile_function.h"
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+typedef struct slang_name_space_
+{
+   struct slang_function_scope_ *funcs;
+   struct slang_struct_scope_ *structs;
+   struct slang_variable_scope_ *vars;
+} slang_name_space;
+
+typedef enum slang_unit_type_
+{
+   SLANG_UNIT_FRAGMENT_SHADER,
+   SLANG_UNIT_VERTEX_SHADER,
+   SLANG_UNIT_GEOMETRY_SHADER,
+   SLANG_UNIT_FRAGMENT_BUILTIN,
+   SLANG_UNIT_VERTEX_BUILTIN,
+   SLANG_UNIT_GEOMETRY_BUILTIN
+} slang_unit_type;
+
+
+typedef struct slang_code_unit_
+{
+   slang_variable_scope vars;
+   slang_function_scope funs;
+   slang_struct_scope structs;
+   slang_unit_type type;
+   struct slang_code_object_ *object;
+} slang_code_unit;
+
+
+extern GLvoid
+_slang_code_unit_ctr (slang_code_unit *, struct slang_code_object_ *);
+
+extern GLvoid
+_slang_code_unit_dtr (slang_code_unit *);
+
+#define SLANG_BUILTIN_CORE   0
+#define SLANG_BUILTIN_120_CORE   1
+#define SLANG_BUILTIN_COMMON 2
+#define SLANG_BUILTIN_TARGET 3
+
+#define SLANG_BUILTIN_TOTAL  4
+
+typedef struct slang_code_object_
+{
+   slang_code_unit builtin[SLANG_BUILTIN_TOTAL];
+   slang_code_unit unit;
+   slang_atom_pool atompool;
+} slang_code_object;
+
+extern GLvoid
+_slang_code_object_ctr (slang_code_object *);
+
+extern GLvoid
+_slang_code_object_dtr (slang_code_object *);
+
+extern GLboolean
+_slang_compile (GLcontext *ctx, struct gl_shader *shader);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/mesa/slang/slang_compile_function.c b/src/mesa/slang/slang_compile_function.c
new file mode 100644 (file)
index 0000000..4dd8851
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file slang_compile_function.c
+ * slang front-end compiler
+ * \author Michal Krol
+ */
+
+#include "main/imports.h"
+#include "slang_compile.h"
+#include "slang_mem.h"
+
+
+int
+slang_function_construct(slang_function * func)
+{
+   func->kind = SLANG_FUNC_ORDINARY;
+   if (!slang_variable_construct(&func->header))
+      return 0;
+
+   func->parameters = (slang_variable_scope *)
+      _slang_alloc(sizeof(slang_variable_scope));
+   if (func->parameters == NULL) {
+      slang_variable_destruct(&func->header);
+      return 0;
+   }
+
+   _slang_variable_scope_ctr(func->parameters);
+   func->param_count = 0;
+   func->body = NULL;
+   return 1;
+}
+
+void
+slang_function_destruct(slang_function * func)
+{
+   slang_variable_destruct(&func->header);
+   slang_variable_scope_destruct(func->parameters);
+   _slang_free(func->parameters);
+   if (func->body != NULL) {
+      slang_operation_destruct(func->body);
+      _slang_free(func->body);
+   }
+}
+
+
+slang_function *
+slang_function_new(slang_function_kind kind)
+{
+   slang_function *fun = (slang_function *)
+      _slang_alloc(sizeof(slang_function));
+   if (fun) {
+      slang_function_construct(fun);
+      fun->kind = kind;
+   }
+   return fun;
+}
+
+
+/*
+ * slang_function_scope
+ */
+
+GLvoid
+_slang_function_scope_ctr(slang_function_scope * self)
+{
+   self->functions = NULL;
+   self->num_functions = 0;
+   self->outer_scope = NULL;
+}
+
+void
+slang_function_scope_destruct(slang_function_scope * scope)
+{
+   unsigned int i;
+
+   for (i = 0; i < scope->num_functions; i++)
+      slang_function_destruct(scope->functions + i);
+   _slang_free(scope->functions);
+}
+
+
+/**
+ * Does this function have a non-void return value?
+ */
+GLboolean
+_slang_function_has_return_value(const slang_function *fun)
+{
+   return fun->header.type.specifier.type != SLANG_SPEC_VOID;
+}
+
+
+/**
+ * Search a list of functions for a particular function by name.
+ * \param funcs  the list of functions to search
+ * \param a_name  the name to search for
+ * \param all_scopes  if non-zero, search containing scopes too.
+ * \return pointer to found function, or NULL.
+ */
+int
+slang_function_scope_find_by_name(slang_function_scope * funcs,
+                                  slang_atom a_name, int all_scopes)
+{
+   unsigned int i;
+
+   for (i = 0; i < funcs->num_functions; i++)
+      if (a_name == funcs->functions[i].header.a_name)
+         return 1;
+   if (all_scopes && funcs->outer_scope != NULL)
+      return slang_function_scope_find_by_name(funcs->outer_scope, a_name, 1);
+   return 0;
+}
+
+
+/**
+ * Search a list of functions for a particular function (for implementing
+ * function calls.  Matching is done by first comparing the function's name,
+ * then the function's parameter list.
+ *
+ * \param funcs  the list of functions to search
+ * \param fun  the function to search for
+ * \param all_scopes  if non-zero, search containing scopes too.
+ * \return pointer to found function, or NULL.
+ */
+slang_function *
+slang_function_scope_find(slang_function_scope * funcs, slang_function * fun,
+                          int all_scopes)
+{
+   unsigned int i;
+
+   for (i = 0; i < funcs->num_functions; i++) {
+      slang_function *f = &funcs->functions[i];
+      const GLuint haveRetValue = 0;
+#if 0
+         = (f->header.type.specifier.type != SLANG_SPEC_VOID);
+#endif
+      unsigned int j;
+
+      /*
+      printf("Compare name %s to %s  (ret %u, %d, %d)\n",
+             (char *) fun->header.a_name, (char *) f->header.a_name,
+             haveRetValue,
+             fun->param_count, f->param_count);
+      */
+
+      if (fun->header.a_name != f->header.a_name)
+         continue;
+      if (fun->param_count != f->param_count)
+         continue;
+      for (j = haveRetValue; j < fun->param_count; j++) {
+         if (!slang_type_specifier_equal
+             (&fun->parameters->variables[j]->type.specifier,
+              &f->parameters->variables[j]->type.specifier))
+            break;
+      }
+      if (j == fun->param_count) {
+         /*
+         printf("Found match\n");
+         */
+         return f;
+      }
+   }
+   /*
+   printf("Not found\n");
+   */
+   if (all_scopes && funcs->outer_scope != NULL)
+      return slang_function_scope_find(funcs->outer_scope, fun, 1);
+   return NULL;
+}
+
+
+/**
+ * Lookup a function according to name and parameter count/types.
+ */
+slang_function *
+_slang_function_locate(const slang_function_scope * funcs, slang_atom a_name,
+                       slang_operation * args, GLuint num_args,
+                       const slang_name_space * space, slang_atom_pool * atoms,
+                       slang_info_log *log, GLboolean *error)
+{
+   slang_typeinfo arg_ti[100];
+   GLuint i;
+
+   *error = GL_FALSE;
+
+   /* determine type of each argument */
+   assert(num_args < 100);
+   for (i = 0; i < num_args; i++) {
+      if (!slang_typeinfo_construct(&arg_ti[i]))
+         return NULL;
+      if (!_slang_typeof_operation(&args[i], space, &arg_ti[i], atoms, log)) {
+         return NULL;
+      }
+   }
+
+   /* loop over function scopes */
+   while (funcs) {
+
+      /* look for function with matching name and argument/param types */
+      for (i = 0; i < funcs->num_functions; i++) {
+         slang_function *f = &funcs->functions[i];
+         const GLuint haveRetValue = _slang_function_has_return_value(f);
+         GLuint j;
+
+         if (a_name != f->header.a_name)
+            continue;
+         if (f->param_count - haveRetValue != num_args)
+            continue;
+
+         /* compare parameter / argument types */
+         for (j = 0; j < num_args; j++) {
+            if (!slang_type_specifier_compatible(&arg_ti[j].spec,
+                              &f->parameters->variables[j]->type.specifier)) {
+               /* param/arg types don't match */
+               break;
+            }
+
+            /* "out" and "inout" formal parameter requires the actual
+             * argument to be an l-value.
+             */
+            if (!arg_ti[j].can_be_referenced &&
+                (f->parameters->variables[j]->type.qualifier == SLANG_QUAL_OUT ||
+                 f->parameters->variables[j]->type.qualifier == SLANG_QUAL_INOUT)) {
+               /* param is not an lvalue! */
+               *error = GL_TRUE;
+               return NULL;
+            }
+         }
+
+         if (j == num_args) {
+            /* name and args match! */
+            return f;
+         }
+      }
+
+      funcs = funcs->outer_scope;
+   }
+
+   return NULL;
+}
diff --git a/src/mesa/slang/slang_compile_function.h b/src/mesa/slang/slang_compile_function.h
new file mode 100644 (file)
index 0000000..a5445ec
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.2
+ *
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef SLANG_COMPILE_FUNCTION_H
+#define SLANG_COMPILE_FUNCTION_H
+
+
+/**
+ * Types of functions.
+ */
+typedef enum slang_function_kind_
+{
+   SLANG_FUNC_ORDINARY,
+   SLANG_FUNC_CONSTRUCTOR,
+   SLANG_FUNC_OPERATOR
+} slang_function_kind;
+
+
+/**
+ * Description of a compiled shader function.
+ */
+typedef struct slang_function_
+{
+   slang_function_kind kind;
+   slang_variable header;      /**< The function's name and return type */
+   slang_variable_scope *parameters; /**< formal parameters AND local vars */
+   unsigned int param_count;   /**< number of formal params (no locals) */
+   slang_operation *body;      /**< The instruction tree */
+} slang_function;
+
+extern int slang_function_construct(slang_function *);
+extern void slang_function_destruct(slang_function *);
+extern slang_function *slang_function_new(slang_function_kind kind);
+
+extern GLboolean
+_slang_function_has_return_value(const slang_function *fun);
+
+
+/**
+ * Basically, a list of compiled functions.
+ */
+typedef struct slang_function_scope_
+{
+   slang_function *functions;
+   GLuint num_functions;
+   struct slang_function_scope_ *outer_scope;
+} slang_function_scope;
+
+
+extern GLvoid
+_slang_function_scope_ctr(slang_function_scope *);
+
+extern void
+slang_function_scope_destruct(slang_function_scope *);
+
+extern int
+slang_function_scope_find_by_name(slang_function_scope *, slang_atom, int);
+
+extern slang_function *
+slang_function_scope_find(slang_function_scope *, slang_function *, int);
+
+extern struct slang_function_ *
+_slang_function_locate(const struct slang_function_scope_ *funcs,
+                       slang_atom name, struct slang_operation_ *params,
+                       GLuint num_params,
+                       const struct slang_name_space_ *space,
+                       slang_atom_pool *atoms, slang_info_log *log,
+                       GLboolean *error);
+
+
+#endif /* SLANG_COMPILE_FUNCTION_H */
diff --git a/src/mesa/slang/slang_compile_operation.c b/src/mesa/slang/slang_compile_operation.c
new file mode 100644 (file)
index 0000000..5441d60
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.2
+ *
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file slang_compile_operation.c
+ * slang front-end compiler
+ * \author Michal Krol
+ */
+
+#include "main/imports.h"
+#include "slang_compile.h"
+#include "slang_mem.h"
+
+
+/**
+ * Init a slang_operation object
+ */
+GLboolean
+slang_operation_construct(slang_operation * oper)
+{
+   oper->type = SLANG_OPER_NONE;
+   oper->children = NULL;
+   oper->num_children = 0;
+   oper->literal[0] = 0.0;
+   oper->literal_size = 1;
+   oper->array_constructor = GL_FALSE;
+   oper->a_id = SLANG_ATOM_NULL;
+   oper->a_obj = SLANG_ATOM_NULL;
+   oper->locals = _slang_variable_scope_new(NULL);
+   if (oper->locals == NULL)
+      return GL_FALSE;
+   _slang_variable_scope_ctr(oper->locals);
+   oper->fun = NULL;
+   oper->var = NULL;
+   oper->label = NULL;
+   return GL_TRUE;
+}
+
+void
+slang_operation_destruct(slang_operation * oper)
+{
+   GLuint i;
+
+   for (i = 0; i < oper->num_children; i++)
+      slang_operation_destruct(oper->children + i);
+   _slang_free(oper->children);
+   slang_variable_scope_destruct(oper->locals);
+   _slang_free(oper->locals);
+   oper->children = NULL;
+   oper->num_children = 0;
+   oper->locals = NULL;
+}
+
+
+/**
+ * Recursively traverse 'oper', replacing occurances of 'oldScope' with
+ * 'newScope' in the oper->locals->outer_scope field.
+ */
+void
+slang_replace_scope(slang_operation *oper,
+                    slang_variable_scope *oldScope,
+                    slang_variable_scope *newScope)
+{
+   GLuint i;
+
+   if (oper->locals != newScope &&
+       oper->locals->outer_scope == oldScope) {
+      /* found.  replace old w/ new */
+      oper->locals->outer_scope = newScope;
+   }
+
+   if (oper->type == SLANG_OPER_VARIABLE_DECL) {
+      /* search/replace in the initializer */
+      slang_variable *var;
+      var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE);
+      if (var && var->initializer) {
+         slang_replace_scope(var->initializer, oldScope, newScope);
+      }
+   }
+
+   /* search/replace in children */
+   for (i = 0; i < oper->num_children; i++) {
+      slang_replace_scope(&oper->children[i], oldScope, newScope);
+   }
+}
+
+
+/**
+ * Recursively copy a slang_operation node.
+ * \param x  copy target
+ * \param y  copy source
+ * \return GL_TRUE for success, GL_FALSE if failure
+ */
+GLboolean
+slang_operation_copy(slang_operation * x, const slang_operation * y)
+{
+   slang_operation z;
+   GLuint i;
+
+   if (!slang_operation_construct(&z))
+      return GL_FALSE;
+   z.type = y->type;
+   if (y->num_children > 0) {
+      z.children = (slang_operation *)
+         _slang_alloc(y->num_children * sizeof(slang_operation));
+      if (z.children == NULL) {
+         slang_operation_destruct(&z);
+         return GL_FALSE;
+      }
+   }
+   for (z.num_children = 0; z.num_children < y->num_children;
+        z.num_children++) {
+      if (!slang_operation_construct(&z.children[z.num_children])) {
+         slang_operation_destruct(&z);
+         return GL_FALSE;
+      }
+   }
+   for (i = 0; i < z.num_children; i++) {
+      if (!slang_operation_copy(&z.children[i], &y->children[i])) {
+         slang_operation_destruct(&z);
+         return GL_FALSE;
+      }
+   }
+   z.literal[0] = y->literal[0];
+   z.literal[1] = y->literal[1];
+   z.literal[2] = y->literal[2];
+   z.literal[3] = y->literal[3];
+   z.literal_size = y->literal_size;
+   assert(y->literal_size >= 1);
+   assert(y->literal_size <= 4);
+   z.a_id = y->a_id;
+   if (y->locals) {
+      if (!slang_variable_scope_copy(z.locals, y->locals)) {
+         slang_operation_destruct(&z);
+         return GL_FALSE;
+      }
+   }
+
+   /* update scoping for children */
+   for (i = 0; i < y->num_children; i++) {
+      if (y->children[i].locals &&
+          y->children[i].locals->outer_scope == y->locals) {
+         z.children[i].locals->outer_scope = z.locals;
+      }
+   }
+
+#if 0
+   z.var = y->var;
+   z.fun = y->fun;
+#endif
+   slang_operation_destruct(x);
+   *x = z;
+
+   /* If this operation declares a new scope, we need to make sure
+    * all children point to it, not the original operation's scope!
+    */
+   if (x->type == SLANG_OPER_BLOCK_NEW_SCOPE ||
+       x->type == SLANG_OPER_WHILE ||
+       x->type == SLANG_OPER_FOR) {
+      slang_replace_scope(x, y->locals, x->locals);
+   }
+
+   return GL_TRUE;
+}
+
+
+slang_operation *
+slang_operation_new(GLuint count)
+{
+   slang_operation *ops
+       = (slang_operation *) _slang_alloc(count * sizeof(slang_operation));
+   assert(count > 0);
+   if (ops) {
+      GLuint i;
+      for (i = 0; i < count; i++)
+         slang_operation_construct(ops + i);
+   }
+   return ops;
+}
+
+
+/**
+ * Delete operation and all children
+ */
+void
+slang_operation_delete(slang_operation *oper)
+{
+   slang_operation_destruct(oper);
+   _slang_free(oper);
+}
+
+
+void
+slang_operation_free_children(slang_operation *oper)
+{
+   GLuint i;
+   for (i = 0; i < slang_oper_num_children(oper); i++) {
+      slang_operation *child = slang_oper_child(oper, i);
+      slang_operation_destruct(child);
+   }
+   _slang_free(oper->children);
+   oper->children = NULL;
+   oper->num_children = 0;
+}
+
+
+slang_operation *
+slang_operation_grow(GLuint *numChildren, slang_operation **children)
+{
+   slang_operation *ops;
+
+   ops = (slang_operation *)
+      _slang_realloc(*children,
+                     *numChildren * sizeof(slang_operation),
+                     (*numChildren + 1) * sizeof(slang_operation));
+   if (ops) {
+      slang_operation *newOp = ops + *numChildren;
+      if (!slang_operation_construct(newOp)) {
+         _slang_free(ops);
+         *children = NULL;
+         return NULL;
+      }
+      *children = ops;
+      (*numChildren)++;
+      return newOp;
+   }
+   return NULL;
+}
+
+/**
+ * Insert a new slang_operation into an array.
+ * \param numElements  pointer to current array size (in/out)
+ * \param array  address of the array (in/out)
+ * \param pos  position to insert new element
+ * \return  pointer to the new operation/element
+ */
+slang_operation *
+slang_operation_insert(GLuint *numElements, slang_operation **array,
+                       GLuint pos)
+{
+   slang_operation *ops;
+
+   assert(pos <= *numElements);
+
+   ops = (slang_operation *)
+      _slang_alloc((*numElements + 1) * sizeof(slang_operation));
+   if (ops) {
+      slang_operation *newOp;
+      newOp = ops + pos;
+      if (pos > 0)
+         memcpy(ops, *array, pos * sizeof(slang_operation));
+      if (pos < *numElements)
+         memcpy(newOp + 1, (*array) + pos,
+                (*numElements - pos) * sizeof(slang_operation));
+
+      if (!slang_operation_construct(newOp)) {
+         _slang_free(ops);
+         *numElements = 0;
+         *array = NULL;
+         return NULL;
+      }
+      if (*array)
+         _slang_free(*array);
+      *array = ops;
+      (*numElements)++;
+      return newOp;
+   }
+   return NULL;
+}
+
+
+/**
+ * Add/insert new child into given node at given position.
+ * \return pointer to the new child node
+ */
+slang_operation *
+slang_operation_insert_child(slang_operation *oper, GLuint pos)
+{
+   slang_operation *newOp;
+
+   newOp = slang_operation_insert(&oper->num_children,
+                                  &oper->children,
+                                  pos);
+   if (newOp) {
+      newOp->locals->outer_scope = oper->locals;
+   }
+
+   return newOp;
+}
+
+
+void
+_slang_operation_swap(slang_operation *oper0, slang_operation *oper1)
+{
+   slang_operation tmp = *oper0;
+   *oper0 = *oper1;
+   *oper1 = tmp;
+}
+
+
+void
+slang_operation_add_children(slang_operation *oper, GLuint num_children)
+{
+   GLuint i;
+   assert(oper->num_children == 0);
+   assert(oper->children == NULL);
+   oper->num_children = num_children;
+   oper->children = slang_operation_new(num_children);
+   for (i = 0; i < num_children; i++) {
+      oper->children[i].locals = _slang_variable_scope_new(oper->locals);
+   }
+}
+
diff --git a/src/mesa/slang/slang_compile_operation.h b/src/mesa/slang/slang_compile_operation.h
new file mode 100644 (file)
index 0000000..1f15c19
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.2
+ *
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef SLANG_COMPILE_OPERATION_H
+#define SLANG_COMPILE_OPERATION_H
+
+
+/**
+ * Types of slang operations.
+ * These are the types of the AST (abstract syntax tree) nodes.
+ * [foo] indicates a sub-tree or reference to another type of node
+ */
+typedef enum slang_operation_type_
+{
+   SLANG_OPER_NONE,
+   SLANG_OPER_BLOCK_NO_NEW_SCOPE,       /* "{" sequence "}" */
+   SLANG_OPER_BLOCK_NEW_SCOPE,  /* "{" sequence "}" */
+   SLANG_OPER_VARIABLE_DECL,    /* [type] [var] or [var] = [expr] */
+   SLANG_OPER_ASM,
+   SLANG_OPER_BREAK,            /* "break" statement */
+   SLANG_OPER_CONTINUE,         /* "continue" statement */
+   SLANG_OPER_DISCARD,          /* "discard" (kill fragment) statement */
+   SLANG_OPER_RETURN,           /* "return" [expr]  */
+   SLANG_OPER_RETURN_INLINED,   /* "return" [expr] from inlined function  */
+   SLANG_OPER_LABEL,            /* a jump target */
+   SLANG_OPER_EXPRESSION,       /* [expr] */
+   SLANG_OPER_IF,               /* "if" [0] then [1] else [2] */
+   SLANG_OPER_WHILE,            /* "while" [cond] [body] */
+   SLANG_OPER_DO,               /* "do" [body] "while" [cond] */
+   SLANG_OPER_FOR,              /* "for" [init] [while] [incr] [body] */
+   SLANG_OPER_VOID,             /* nop */
+   SLANG_OPER_LITERAL_BOOL,     /* "true" or "false" */
+   SLANG_OPER_LITERAL_INT,      /* integer literal */
+   SLANG_OPER_LITERAL_FLOAT,    /* float literal */
+   SLANG_OPER_IDENTIFIER,       /* var name, func name, etc */
+   SLANG_OPER_SEQUENCE,         /* [expr] "," [expr] "," etc */
+   SLANG_OPER_ASSIGN,           /* [var] "=" [expr] */
+   SLANG_OPER_ADDASSIGN,        /* [var] "+=" [expr] */
+   SLANG_OPER_SUBASSIGN,        /* [var] "-=" [expr] */
+   SLANG_OPER_MULASSIGN,        /* [var] "*=" [expr] */
+   SLANG_OPER_DIVASSIGN,        /* [var] "/=" [expr] */
+   /*SLANG_OPER_MODASSIGN, */
+   /*SLANG_OPER_LSHASSIGN, */
+   /*SLANG_OPER_RSHASSIGN, */
+   /*SLANG_OPER_ORASSIGN, */
+   /*SLANG_OPER_XORASSIGN, */
+   /*SLANG_OPER_ANDASSIGN, */
+   SLANG_OPER_SELECT,           /* [expr] "?" [expr] ":" [expr] */
+   SLANG_OPER_LOGICALOR,        /* [expr] "||" [expr] */
+   SLANG_OPER_LOGICALXOR,       /* [expr] "^^" [expr] */
+   SLANG_OPER_LOGICALAND,       /* [expr] "&&" [expr] */
+   /*SLANG_OPER_BITOR, */
+   /*SLANG_OPER_BITXOR, */
+   /*SLANG_OPER_BITAND, */
+   SLANG_OPER_EQUAL,            /* [expr] "==" [expr] */
+   SLANG_OPER_NOTEQUAL,         /* [expr] "!=" [expr] */
+   SLANG_OPER_LESS,             /* [expr] "<" [expr] */
+   SLANG_OPER_GREATER,          /* [expr] ">" [expr] */
+   SLANG_OPER_LESSEQUAL,        /* [expr] "<=" [expr] */
+   SLANG_OPER_GREATEREQUAL,     /* [expr] ">=" [expr] */
+   /*SLANG_OPER_LSHIFT, */
+   /*SLANG_OPER_RSHIFT, */
+   SLANG_OPER_ADD,              /* [expr] "+" [expr] */
+   SLANG_OPER_SUBTRACT,         /* [expr] "-" [expr] */
+   SLANG_OPER_MULTIPLY,         /* [expr] "*" [expr] */
+   SLANG_OPER_DIVIDE,           /* [expr] "/" [expr] */
+   /*SLANG_OPER_MODULUS, */
+   SLANG_OPER_PREINCREMENT,     /* "++" [var] */
+   SLANG_OPER_PREDECREMENT,     /* "--" [var] */
+   SLANG_OPER_PLUS,             /* "-" [expr] */
+   SLANG_OPER_MINUS,            /* "+" [expr] */
+   /*SLANG_OPER_COMPLEMENT, */
+   SLANG_OPER_NOT,              /* "!" [expr] */
+   SLANG_OPER_SUBSCRIPT,        /* [expr] "[" [expr] "]" */
+   SLANG_OPER_CALL,             /* [func name] [param] [param] [...] */
+   SLANG_OPER_NON_INLINED_CALL, /* a real function call */
+   SLANG_OPER_METHOD,           /* method call, such as  v.length() */
+   SLANG_OPER_FIELD,            /* i.e.: ".next" or ".xzy" or ".xxx" etc */
+   SLANG_OPER_POSTINCREMENT,    /* [var] "++" */
+   SLANG_OPER_POSTDECREMENT     /* [var] "--" */
+} slang_operation_type;
+
+
+/**
+ * A slang_operation is basically a compiled instruction (such as assignment,
+ * a while-loop, a conditional, a multiply, a function call, etc).
+ * The AST (abstract syntax tree) is built from these nodes.
+ * NOTE: This structure could have been implemented as a union of simpler
+ * structs which would correspond to the operation types above.
+ */
+typedef struct slang_operation_
+{
+   slang_operation_type type;
+   struct slang_operation_ *children;
+   GLuint num_children;
+   GLfloat literal[4];           /**< Used for float, int and bool values */
+   GLuint literal_size;          /**< 1, 2, 3, or 4 */
+   slang_atom a_id;              /**< type: asm, identifier, call, field */
+   slang_atom a_obj;             /**< object in a method call */
+   slang_variable_scope *locals; /**< local vars for scope */
+   struct slang_function_ *fun;  /**< If type == SLANG_OPER_CALL */
+   struct slang_variable_ *var;  /**< If type == slang_oper_identier */
+   struct slang_label_ *label;   /**< If type == SLANG_OPER_LABEL */
+   /** If type==SLANG_OPER_CALL and we're calling an array constructor,
+    * for which there's no real function, we need to have a flag to
+    * indicate such.  num_children indicates number of elements.
+    */
+   GLboolean array_constructor;
+} slang_operation;
+
+
+extern GLboolean
+slang_operation_construct(slang_operation *);
+
+extern void
+slang_operation_destruct(slang_operation *);
+
+extern void
+slang_replace_scope(slang_operation *oper,
+                    slang_variable_scope *oldScope,
+                    slang_variable_scope *newScope);
+
+extern GLboolean
+slang_operation_copy(slang_operation *, const slang_operation *);
+
+extern slang_operation *
+slang_operation_new(GLuint count);
+
+extern void
+slang_operation_delete(slang_operation *oper);
+
+extern void
+slang_operation_free_children(slang_operation *oper);
+
+extern slang_operation *
+slang_operation_grow(GLuint *numChildren, slang_operation **children);
+
+extern slang_operation *
+slang_operation_insert(GLuint *numChildren, slang_operation **children,
+                       GLuint pos);
+
+extern slang_operation *
+slang_operation_insert_child(slang_operation *oper, GLuint pos);
+
+extern void
+_slang_operation_swap(slang_operation *oper0, slang_operation *oper1);
+
+
+extern void
+slang_operation_add_children(slang_operation *oper, GLuint num_children);
+
+
+/** Return number of children of given node */
+static INLINE GLuint
+slang_oper_num_children(const slang_operation *oper)
+{
+   return oper->num_children;
+}
+
+/** Return child of given operation node */
+static INLINE slang_operation *
+slang_oper_child(slang_operation *oper, GLuint child)
+{
+   assert(child < oper->num_children);
+   return &oper->children[child];
+}
+
+
+/** Return child of given operation node, const version */
+static INLINE const slang_operation *
+slang_oper_child_const(const slang_operation *oper, GLuint child)
+{
+   assert(child < oper->num_children);
+   return &oper->children[child];
+}
+
+
+/** Init oper to a boolean literal. */
+static INLINE void
+slang_operation_literal_bool(slang_operation *oper, GLboolean value)
+{
+   oper->type = SLANG_OPER_LITERAL_BOOL;
+   oper->literal[0] =
+   oper->literal[1] =
+   oper->literal[2] =
+   oper->literal[3] = (float) value;
+   oper->literal_size = 1;
+}
+
+
+/** Init oper to an int literal. */
+static INLINE void
+slang_operation_literal_int(slang_operation *oper, GLint value)
+{
+   oper->type = SLANG_OPER_LITERAL_INT;
+   oper->literal[0] =
+   oper->literal[1] =
+   oper->literal[2] =
+   oper->literal[3] = (float) value;
+   oper->literal_size = 1;
+}
+
+
+#endif /* SLANG_COMPILE_OPERATION_H */
diff --git a/src/mesa/slang/slang_compile_struct.c b/src/mesa/slang/slang_compile_struct.c
new file mode 100644 (file)
index 0000000..e6c3873
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.3
+ *
+ * Copyright (C) 2005-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 slang_compile_struct.c
+ * slang front-end compiler
+ * \author Michal Krol
+ */
+
+#include "main/imports.h"
+#include "slang_mem.h"
+#include "slang_compile.h"
+
+
+GLvoid
+_slang_struct_scope_ctr(slang_struct_scope * self)
+{
+   self->structs = NULL;
+   self->num_structs = 0;
+   self->outer_scope = NULL;
+}
+
+void
+slang_struct_scope_destruct(slang_struct_scope * scope)
+{
+   GLuint i;
+
+   for (i = 0; i < scope->num_structs; i++)
+      slang_struct_destruct(scope->structs + i);
+   _slang_free(scope->structs);
+   /* do not free scope->outer_scope */
+}
+
+int
+slang_struct_scope_copy(slang_struct_scope * x, const slang_struct_scope * y)
+{
+   slang_struct_scope z;
+   GLuint i;
+
+   _slang_struct_scope_ctr(&z);
+   z.structs = (slang_struct *)
+      _slang_alloc(y->num_structs * sizeof(slang_struct));
+   if (z.structs == NULL) {
+      slang_struct_scope_destruct(&z);
+      return 0;
+   }
+   for (z.num_structs = 0; z.num_structs < y->num_structs; z.num_structs++)
+      if (!slang_struct_construct(&z.structs[z.num_structs])) {
+         slang_struct_scope_destruct(&z);
+         return 0;
+      }
+   for (i = 0; i < z.num_structs; i++)
+      if (!slang_struct_copy(&z.structs[i], &y->structs[i])) {
+         slang_struct_scope_destruct(&z);
+         return 0;
+      }
+   z.outer_scope = y->outer_scope;
+   slang_struct_scope_destruct(x);
+   *x = z;
+   return 1;
+}
+
+slang_struct *
+slang_struct_scope_find(slang_struct_scope * stru, slang_atom a_name,
+                        int all_scopes)
+{
+   GLuint i;
+
+   for (i = 0; i < stru->num_structs; i++)
+      if (a_name == stru->structs[i].a_name)
+         return &stru->structs[i];
+   if (all_scopes && stru->outer_scope != NULL)
+      return slang_struct_scope_find(stru->outer_scope, a_name, 1);
+   return NULL;
+}
+
+/* slang_struct */
+
+int
+slang_struct_construct(slang_struct * stru)
+{
+   stru->a_name = SLANG_ATOM_NULL;
+   stru->fields = (slang_variable_scope *)
+      _slang_alloc(sizeof(slang_variable_scope));
+   if (stru->fields == NULL)
+      return 0;
+   _slang_variable_scope_ctr(stru->fields);
+
+   stru->structs =
+      (slang_struct_scope *) _slang_alloc(sizeof(slang_struct_scope));
+   if (stru->structs == NULL) {
+      slang_variable_scope_destruct(stru->fields);
+      _slang_free(stru->fields);
+      return 0;
+   }
+   _slang_struct_scope_ctr(stru->structs);
+   stru->constructor = NULL;
+   return 1;
+}
+
+void
+slang_struct_destruct(slang_struct * stru)
+{
+   slang_variable_scope_destruct(stru->fields);
+   _slang_free(stru->fields);
+   slang_struct_scope_destruct(stru->structs);
+   _slang_free(stru->structs);
+}
+
+int
+slang_struct_copy(slang_struct * x, const slang_struct * y)
+{
+   slang_struct z;
+
+   if (!slang_struct_construct(&z))
+      return 0;
+   z.a_name = y->a_name;
+   if (!slang_variable_scope_copy(z.fields, y->fields)) {
+      slang_struct_destruct(&z);
+      return 0;
+   }
+   if (!slang_struct_scope_copy(z.structs, y->structs)) {
+      slang_struct_destruct(&z);
+      return 0;
+   }
+   slang_struct_destruct(x);
+   *x = z;
+   return 1;
+}
+
+int
+slang_struct_equal(const slang_struct * x, const slang_struct * y)
+{
+   GLuint i;
+
+   if (x->fields->num_variables != y->fields->num_variables)
+      return 0;
+
+   for (i = 0; i < x->fields->num_variables; i++) {
+      const slang_variable *varx = x->fields->variables[i];
+      const slang_variable *vary = y->fields->variables[i];
+
+      if (varx->a_name != vary->a_name)
+         return 0;
+      if (!slang_type_specifier_equal(&varx->type.specifier,
+                                      &vary->type.specifier))
+         return 0;
+      if (varx->type.specifier.type == SLANG_SPEC_ARRAY)
+         if (varx->array_len != vary->array_len)
+            return GL_FALSE;
+   }
+   return 1;
+}
diff --git a/src/mesa/slang/slang_compile_struct.h b/src/mesa/slang/slang_compile_struct.h
new file mode 100644 (file)
index 0000000..90c5512
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#if !defined SLANG_COMPILE_STRUCT_H
+#define SLANG_COMPILE_STRUCT_H
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+struct slang_function_;
+
+typedef struct slang_struct_scope_
+{
+   struct slang_struct_ *structs;
+   GLuint num_structs;
+   struct slang_struct_scope_ *outer_scope;
+} slang_struct_scope;
+
+extern GLvoid
+_slang_struct_scope_ctr (slang_struct_scope *);
+
+void slang_struct_scope_destruct (slang_struct_scope *);
+int slang_struct_scope_copy (slang_struct_scope *, const slang_struct_scope *);
+struct slang_struct_ *slang_struct_scope_find (slang_struct_scope *, slang_atom, int);
+
+typedef struct slang_struct_
+{
+   slang_atom a_name;
+   struct slang_variable_scope_ *fields;
+   slang_struct_scope *structs;
+   struct slang_function_ *constructor;
+} slang_struct;
+
+int slang_struct_construct (slang_struct *);
+void slang_struct_destruct (slang_struct *);
+int slang_struct_copy (slang_struct *, const slang_struct *);
+int slang_struct_equal (const slang_struct *, const slang_struct *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/mesa/slang/slang_compile_variable.c b/src/mesa/slang/slang_compile_variable.c
new file mode 100644 (file)
index 0000000..23c08a9
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.3
+ *
+ * Copyright (C) 2005-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 slang_compile_variable.c
+ * slang front-end compiler
+ * \author Michal Krol
+ */
+
+#include "main/imports.h"
+#include "slang_compile.h"
+#include "slang_mem.h"
+
+
+static slang_variable *
+slang_variable_new(void)
+{
+   slang_variable *v = (slang_variable *) _slang_alloc(sizeof(slang_variable));
+   if (v) {
+      if (!slang_variable_construct(v)) {
+         _slang_free(v);
+         v = NULL;
+      }
+   }
+   return v;
+}
+
+
+static void
+slang_variable_delete(slang_variable * var)
+{
+   slang_variable_destruct(var);
+   _slang_free(var);
+}
+
+
+/*
+ * slang_variable_scope
+ */
+
+slang_variable_scope *
+_slang_variable_scope_new(slang_variable_scope *parent)
+{
+   slang_variable_scope *s;
+   s = (slang_variable_scope *) _slang_alloc(sizeof(slang_variable_scope));
+   if (s)
+      s->outer_scope = parent;
+   return s;
+}
+
+
+GLvoid
+_slang_variable_scope_ctr(slang_variable_scope * self)
+{
+   self->variables = NULL;
+   self->num_variables = 0;
+   self->outer_scope = NULL;
+}
+
+void
+slang_variable_scope_destruct(slang_variable_scope * scope)
+{
+   unsigned int i;
+
+   if (!scope)
+      return;
+   for (i = 0; i < scope->num_variables; i++) {
+      if (scope->variables[i])
+         slang_variable_delete(scope->variables[i]);
+   }
+   _slang_free(scope->variables);
+   /* do not free scope->outer_scope */
+}
+
+int
+slang_variable_scope_copy(slang_variable_scope * x,
+                          const slang_variable_scope * y)
+{
+   slang_variable_scope z;
+   unsigned int i;
+
+   _slang_variable_scope_ctr(&z);
+   z.variables = (slang_variable **)
+      _slang_alloc(y->num_variables * sizeof(slang_variable *));
+   if (z.variables == NULL) {
+      slang_variable_scope_destruct(&z);
+      return 0;
+   }
+   for (z.num_variables = 0; z.num_variables < y->num_variables;
+        z.num_variables++) {
+      z.variables[z.num_variables] = slang_variable_new();
+      if (!z.variables[z.num_variables]) {
+         slang_variable_scope_destruct(&z);
+         return 0;
+      }
+   }
+   for (i = 0; i < z.num_variables; i++) {
+      if (!slang_variable_copy(z.variables[i], y->variables[i])) {
+         slang_variable_scope_destruct(&z);
+         return 0;
+      }
+   }
+   z.outer_scope = y->outer_scope;
+   slang_variable_scope_destruct(x);
+   *x = z;
+   return 1;
+}
+
+
+/**
+ * Grow the variable list by one.
+ * \return  pointer to space for the new variable (will be initialized)
+ */
+slang_variable *
+slang_variable_scope_grow(slang_variable_scope *scope)
+{
+   const int n = scope->num_variables;
+   scope->variables = (slang_variable **)
+         _slang_realloc(scope->variables,
+                        n * sizeof(slang_variable *),
+                        (n + 1) * sizeof(slang_variable *));
+   if (!scope->variables)
+      return NULL;
+
+   scope->num_variables++;
+
+   scope->variables[n] = slang_variable_new();
+   if (!scope->variables[n])
+      return NULL;
+
+   return scope->variables[n];
+}
+
+
+
+/* slang_variable */
+
+int
+slang_variable_construct(slang_variable * var)
+{
+   if (!slang_fully_specified_type_construct(&var->type))
+      return 0;
+   var->a_name = SLANG_ATOM_NULL;
+   var->array_len = 0;
+   var->initializer = NULL;
+   var->size = 0;
+   var->isTemp = GL_FALSE;
+   var->store = NULL;
+   var->declared = 0;
+   return 1;
+}
+
+
+void
+slang_variable_destruct(slang_variable * var)
+{
+   slang_fully_specified_type_destruct(&var->type);
+   if (var->initializer != NULL) {
+      slang_operation_destruct(var->initializer);
+      _slang_free(var->initializer);
+   }
+#if 0
+   if (var->aux) {
+      free(var->aux);
+   }
+#endif
+}
+
+
+int
+slang_variable_copy(slang_variable * x, const slang_variable * y)
+{
+   slang_variable z;
+
+   if (!slang_variable_construct(&z))
+      return 0;
+   if (!slang_fully_specified_type_copy(&z.type, &y->type)) {
+      slang_variable_destruct(&z);
+      return 0;
+   }
+   z.a_name = y->a_name;
+   z.array_len = y->array_len;
+   if (y->initializer != NULL) {
+      z.initializer
+         = (slang_operation *) _slang_alloc(sizeof(slang_operation));
+      if (z.initializer == NULL) {
+         slang_variable_destruct(&z);
+         return 0;
+      }
+      if (!slang_operation_construct(z.initializer)) {
+         _slang_free(z.initializer);
+         slang_variable_destruct(&z);
+         return 0;
+      }
+      if (!slang_operation_copy(z.initializer, y->initializer)) {
+         slang_variable_destruct(&z);
+         return 0;
+      }
+   }
+   z.size = y->size;
+   slang_variable_destruct(x);
+   *x = z;
+   return 1;
+}
+
+
+/**
+ * Search for named variable in given scope.
+ * \param all  if true, search parent scopes too.
+ */
+slang_variable *
+_slang_variable_locate(const slang_variable_scope * scope,
+                       const slang_atom a_name, GLboolean all)
+{
+   while (scope) {
+      GLuint i;
+      for (i = 0; i < scope->num_variables; i++)
+         if (a_name == scope->variables[i]->a_name)
+            return scope->variables[i];
+      if (all)
+         scope = scope->outer_scope;
+      else
+         scope = NULL;
+   }
+   return NULL;
+}
diff --git a/src/mesa/slang/slang_compile_variable.h b/src/mesa/slang/slang_compile_variable.h
new file mode 100644 (file)
index 0000000..5c9d248
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.2
+ *
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef SLANG_COMPILE_VARIABLE_H
+#define SLANG_COMPILE_VARIABLE_H
+
+
+struct slang_ir_storage_;
+
+
+/**
+ * A shading language program variable.
+ */
+typedef struct slang_variable_
+{
+   slang_fully_specified_type type; /**< Variable's data type */
+   slang_atom a_name;               /**< The variable's name (char *) */
+   GLuint array_len;                /**< only if type == SLANG_SPEC_ARRAy */
+   struct slang_operation_ *initializer; /**< Optional initializer code */
+   GLuint size;                     /**< Variable's size in bytes */
+   GLboolean is_global;
+   GLboolean isTemp;                /**< a named temporary (__resultTmp) */
+   GLboolean declared;              /**< has the var been declared? */
+   struct slang_ir_storage_ *store; /**< Storage for this var */
+} slang_variable;
+
+
+/**
+ * Basically a list of variables, with a pointer to the parent scope.
+ */
+typedef struct slang_variable_scope_
+{
+   slang_variable **variables;  /**< Array [num_variables] of ptrs to vars */
+   GLuint num_variables;
+   struct slang_variable_scope_ *outer_scope;
+} slang_variable_scope;
+
+
+extern slang_variable_scope *
+_slang_variable_scope_new(slang_variable_scope *parent);
+
+extern GLvoid
+_slang_variable_scope_ctr(slang_variable_scope *);
+
+extern void
+slang_variable_scope_destruct(slang_variable_scope *);
+
+extern int
+slang_variable_scope_copy(slang_variable_scope *,
+                          const slang_variable_scope *);
+
+extern slang_variable *
+slang_variable_scope_grow(slang_variable_scope *);
+
+extern int
+slang_variable_construct(slang_variable *);
+
+extern void
+slang_variable_destruct(slang_variable *);
+
+extern int
+slang_variable_copy(slang_variable *, const slang_variable *);
+
+extern slang_variable *
+_slang_variable_locate(const slang_variable_scope *, const slang_atom a_name,
+                       GLboolean all);
+
+
+#endif /* SLANG_COMPILE_VARIABLE_H */
diff --git a/src/mesa/slang/slang_emit.c b/src/mesa/slang/slang_emit.c
new file mode 100644 (file)
index 0000000..a9aa6fe
--- /dev/null
@@ -0,0 +1,2686 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2005-2008  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2008 VMware, 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
+ * 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 slang_emit.c
+ * Emit program instructions (PI code) from IR trees.
+ * \author Brian Paul
+ */
+
+/***
+ *** NOTES
+ ***
+ *** To emit GPU instructions, we basically just do an in-order traversal
+ *** of the IR tree.
+ ***/
+
+
+#include "main/imports.h"
+#include "main/context.h"
+#include "program/program.h"
+#include "program/prog_instruction.h"
+#include "program/prog_parameter.h"
+#include "program/prog_print.h"
+#include "slang_builtin.h"
+#include "slang_emit.h"
+#include "slang_mem.h"
+
+
+#define PEEPHOLE_OPTIMIZATIONS 1
+#define ANNOTATE 0
+
+
+typedef struct
+{
+   slang_info_log *log;
+   slang_var_table *vt;
+   struct gl_program *prog;
+   struct gl_program **Subroutines;
+   GLuint NumSubroutines;
+
+   GLuint MaxInstructions;  /**< size of prog->Instructions[] buffer */
+
+   GLboolean UnresolvedFunctions;
+
+   /* code-gen options */
+   GLboolean EmitHighLevelInstructions;
+   GLboolean EmitCondCodes;
+   GLboolean EmitComments;
+   GLboolean EmitBeginEndSub; /* XXX TEMPORARY */
+} slang_emit_info;
+
+
+
+static struct gl_program *
+new_subroutine(slang_emit_info *emitInfo, GLuint *id)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   const GLuint n = emitInfo->NumSubroutines;
+
+   emitInfo->Subroutines = (struct gl_program **)
+      _mesa_realloc(emitInfo->Subroutines,
+                    n * sizeof(struct gl_program *),
+                    (n + 1) * sizeof(struct gl_program *));
+   emitInfo->Subroutines[n] = ctx->Driver.NewProgram(ctx, emitInfo->prog->Target, 0);
+   emitInfo->Subroutines[n]->Parameters = emitInfo->prog->Parameters;
+   emitInfo->NumSubroutines++;
+   *id = n;
+   return emitInfo->Subroutines[n];
+}
+
+
+/**
+ * Convert a writemask to a swizzle.  Used for testing cond codes because
+ * we only want to test the cond code component(s) that was set by the
+ * previous instruction.
+ */
+static GLuint
+writemask_to_swizzle(GLuint writemask)
+{
+   if (writemask == WRITEMASK_X)
+      return SWIZZLE_XXXX;
+   if (writemask == WRITEMASK_Y)
+      return SWIZZLE_YYYY;
+   if (writemask == WRITEMASK_Z)
+      return SWIZZLE_ZZZZ;
+   if (writemask == WRITEMASK_W)
+      return SWIZZLE_WWWW;
+   return SWIZZLE_XYZW;  /* shouldn't be hit */
+}
+
+
+/**
+ * Convert a swizzle mask to a writemask.
+ * Note that the slang_ir_storage->Swizzle field can represent either a
+ * swizzle mask or a writemask, depending on how it's used.  For example,
+ * when we parse "direction.yz" alone, we don't know whether .yz is a
+ * writemask or a swizzle.  In this case, we encode ".yz" in store->Swizzle
+ * as a swizzle mask (.yz?? actually).  Later, if direction.yz is used as
+ * an R-value, we use store->Swizzle as-is.  Otherwise, if direction.yz is
+ * used as an L-value, we convert it to a writemask.
+ */
+static GLuint
+swizzle_to_writemask(GLuint swizzle)
+{
+   GLuint i, writemask = 0x0;
+   for (i = 0; i < 4; i++) {
+      GLuint swz = GET_SWZ(swizzle, i);
+      if (swz <= SWIZZLE_W) {
+         writemask |= (1 << swz);
+      }
+   }
+   return writemask;
+}
+
+
+/**
+ * Swizzle a swizzle (function composition).
+ * That is, return swz2(swz1), or said another way: swz1.szw2
+ * Example: swizzle_swizzle(".zwxx", ".xxyw") yields ".zzwx"
+ */
+GLuint
+_slang_swizzle_swizzle(GLuint swz1, GLuint swz2)
+{
+   GLuint i, swz, s[4];
+   for (i = 0; i < 4; i++) {
+      GLuint c = GET_SWZ(swz2, i);
+      if (c <= SWIZZLE_W)
+         s[i] = GET_SWZ(swz1, c);
+      else
+         s[i] = c;
+   }
+   swz = MAKE_SWIZZLE4(s[0], s[1], s[2], s[3]);
+   return swz;
+}
+
+
+/**
+ * Return the default swizzle mask for accessing a variable of the
+ * given size (in floats).  If size = 1, comp is used to identify
+ * which component [0..3] of the register holds the variable.
+ */
+GLuint
+_slang_var_swizzle(GLint size, GLint comp)
+{
+   switch (size) {
+   case 1:
+      return MAKE_SWIZZLE4(comp, SWIZZLE_NIL, SWIZZLE_NIL, SWIZZLE_NIL);
+   case 2:
+      return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_NIL, SWIZZLE_NIL);
+   case 3:
+      return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_NIL);
+   default:
+      return SWIZZLE_XYZW;
+   }
+}
+
+
+
+/**
+ * Allocate storage for the given node (if it hasn't already been allocated).
+ *
+ * Typically this is temporary storage for an intermediate result (such as
+ * for a multiply or add, etc).
+ *
+ * If n->Store does not exist it will be created and will be of the size
+ * specified by defaultSize.
+ */
+static GLboolean
+alloc_node_storage(slang_emit_info *emitInfo, slang_ir_node *n,
+                   GLint defaultSize)
+{
+   assert(!n->Var);
+   if (!n->Store) {
+      assert(defaultSize > 0);
+      n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, defaultSize);
+      if (!n->Store) {
+         return GL_FALSE;
+      }
+   }
+
+   /* now allocate actual register(s).  I.e. set n->Store->Index >= 0 */
+   if (n->Store->Index < 0) {
+      if (!_slang_alloc_temp(emitInfo->vt, n->Store)) {
+         slang_info_log_error(emitInfo->log,
+                              "Ran out of registers, too many temporaries");
+         _slang_free(n->Store);
+         n->Store = NULL;
+         return GL_FALSE;
+      }
+   }
+   return GL_TRUE;
+}
+
+
+/**
+ * Free temporary storage, if n->Store is, in fact, temp storage.
+ * Otherwise, no-op.
+ */
+static void
+free_node_storage(slang_var_table *vt, slang_ir_node *n)
+{
+   if (n->Store->File == PROGRAM_TEMPORARY &&
+       n->Store->Index >= 0 &&
+       n->Opcode != IR_SWIZZLE) {
+      if (_slang_is_temp(vt, n->Store)) {
+         _slang_free_temp(vt, n->Store);
+         n->Store->Index = -1;
+         n->Store = NULL; /* XXX this may not be needed */
+      }
+   }
+}
+
+
+/**
+ * Helper function to allocate a short-term temporary.
+ * Free it with _slang_free_temp().
+ */
+static GLboolean
+alloc_local_temp(slang_emit_info *emitInfo, slang_ir_storage *temp, GLint size)
+{
+   assert(size >= 1);
+   assert(size <= 4);
+   memset(temp, 0, sizeof(*temp));
+   temp->Size = size;
+   temp->File = PROGRAM_TEMPORARY;
+   temp->Index = -1;
+   return _slang_alloc_temp(emitInfo->vt, temp);
+}
+
+
+/**
+ * Remove any SWIZZLE_NIL terms from given swizzle mask.
+ * For a swizzle like .z??? generate .zzzz (replicate single component).
+ * Else, for .wx?? generate .wxzw (insert default component for the position).
+ */
+static GLuint
+fix_swizzle(GLuint swizzle)
+{
+   GLuint c0 = GET_SWZ(swizzle, 0),
+      c1 = GET_SWZ(swizzle, 1),
+      c2 = GET_SWZ(swizzle, 2),
+      c3 = GET_SWZ(swizzle, 3);
+   if (c1 == SWIZZLE_NIL && c2 == SWIZZLE_NIL && c3 == SWIZZLE_NIL) {
+      /* smear first component across all positions */
+      c1 = c2 = c3 = c0;
+   }
+   else {
+      /* insert default swizzle components */
+      if (c0 == SWIZZLE_NIL)
+         c0 = SWIZZLE_X;
+      if (c1 == SWIZZLE_NIL)
+         c1 = SWIZZLE_Y;
+      if (c2 == SWIZZLE_NIL)
+         c2 = SWIZZLE_Z;
+      if (c3 == SWIZZLE_NIL)
+         c3 = SWIZZLE_W;
+   }
+   return MAKE_SWIZZLE4(c0, c1, c2, c3);
+}
+
+
+
+/**
+ * Convert IR storage to an instruction dst register.
+ */
+static void
+storage_to_dst_reg(struct prog_dst_register *dst, const slang_ir_storage *st)
+{
+   const GLboolean relAddr = st->RelAddr;
+   const GLint size = st->Size;
+   GLint index = st->Index;
+   GLuint swizzle = st->Swizzle;
+
+   assert(index >= 0);
+   /* if this is storage relative to some parent storage, walk up the tree */
+   while (st->Parent) {
+      st = st->Parent;
+      assert(st->Index >= 0);
+      index += st->Index;
+      swizzle = _slang_swizzle_swizzle(st->Swizzle, swizzle);
+   }
+
+   assert(st->File != PROGRAM_UNDEFINED);
+   dst->File = st->File;
+
+   assert(index >= 0);
+   dst->Index = index;
+
+   assert(size >= 1);
+   assert(size <= 4);
+
+   if (swizzle != SWIZZLE_XYZW) {
+      dst->WriteMask = swizzle_to_writemask(swizzle);
+   }
+   else {
+      switch (size) {
+      case 1:
+         dst->WriteMask = WRITEMASK_X << GET_SWZ(st->Swizzle, 0);
+         break;
+      case 2:
+         dst->WriteMask = WRITEMASK_XY;
+         break;
+      case 3:
+         dst->WriteMask = WRITEMASK_XYZ;
+         break;
+      case 4:
+         dst->WriteMask = WRITEMASK_XYZW;
+         break;
+      default:
+         ; /* error would have been caught above */
+      }
+   }
+
+   dst->RelAddr = relAddr;
+}
+
+
+/**
+ * Convert IR storage to an instruction src register.
+ */
+static void
+storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st)
+{
+   const GLboolean relAddr = st->RelAddr;
+   GLint index = st->Index;
+   GLuint swizzle = st->Swizzle;
+
+   /* if this is storage relative to some parent storage, walk up the tree */
+   assert(index >= 0);
+   while (st->Parent) {
+      st = st->Parent;
+      if (st->Index < 0) {
+         /* an error should have been reported already */
+         return;
+      }
+      assert(st->Index >= 0);
+      index += st->Index;
+      swizzle = _slang_swizzle_swizzle(fix_swizzle(st->Swizzle), swizzle);
+   }
+
+   assert(st->File >= 0);
+#if 1 /* XXX temporary */
+   if (st->File == PROGRAM_UNDEFINED) {
+      slang_ir_storage *st0 = (slang_ir_storage *) st;
+      st0->File = PROGRAM_TEMPORARY;
+   }
+#endif
+   assert(st->File < PROGRAM_FILE_MAX);
+   src->File = st->File;
+
+   assert(index >= 0);
+   src->Index = index;
+
+   swizzle = fix_swizzle(swizzle);
+   assert(GET_SWZ(swizzle, 0) <= SWIZZLE_W);
+   assert(GET_SWZ(swizzle, 1) <= SWIZZLE_W);
+   assert(GET_SWZ(swizzle, 2) <= SWIZZLE_W);
+   assert(GET_SWZ(swizzle, 3) <= SWIZZLE_W);
+   src->Swizzle = swizzle;
+
+   src->HasIndex2 = st->Is2D;
+   src->Index2 = st->Index2;
+
+   src->RelAddr = relAddr;
+}
+
+
+/*
+ * Setup storage pointing to a scalar constant/literal.
+ */
+static void
+constant_to_storage(slang_emit_info *emitInfo,
+                    GLfloat val,
+                    slang_ir_storage *store)
+{
+   GLuint swizzle;
+   GLint reg;
+   GLfloat value[4];
+
+   value[0] = val;
+   reg = _mesa_add_unnamed_constant(emitInfo->prog->Parameters,
+                                        value, 1, &swizzle);
+
+   memset(store, 0, sizeof(*store));
+   store->File = PROGRAM_CONSTANT;
+   store->Index = reg;
+   store->Swizzle = swizzle;
+}
+
+
+/**
+ * Add new instruction at end of given program.
+ * \param prog  the program to append instruction onto
+ * \param opcode  opcode for the new instruction
+ * \return pointer to the new instruction
+ */
+static struct prog_instruction *
+new_instruction(slang_emit_info *emitInfo, gl_inst_opcode opcode)
+{
+   struct gl_program *prog = emitInfo->prog;
+   struct prog_instruction *inst;
+
+#if 0
+   /* print prev inst */
+   if (prog->NumInstructions > 0) {
+      _mesa_print_instruction(prog->Instructions + prog->NumInstructions - 1);
+   }
+#endif
+   assert(prog->NumInstructions <= emitInfo->MaxInstructions);
+
+   if (prog->NumInstructions == emitInfo->MaxInstructions) {
+      /* grow the instruction buffer */
+      emitInfo->MaxInstructions += 20;
+      prog->Instructions =
+         _mesa_realloc_instructions(prog->Instructions,
+                                    prog->NumInstructions,
+                                    emitInfo->MaxInstructions);
+      if (!prog->Instructions) {
+         return NULL;
+      }
+   }
+
+   inst = prog->Instructions + prog->NumInstructions;
+   prog->NumInstructions++;
+   _mesa_init_instructions(inst, 1);
+   inst->Opcode = opcode;
+   inst->BranchTarget = -1; /* invalid */
+   /*
+   printf("New inst %d: %p %s\n", prog->NumInstructions-1,(void*)inst,
+          _mesa_opcode_string(inst->Opcode));
+   */
+   return inst;
+}
+
+
+static struct prog_instruction *
+emit_arl_load(slang_emit_info *emitInfo,
+              gl_register_file file, GLint index, GLuint swizzle)
+{
+   struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_ARL);
+   if (inst) {
+      inst->SrcReg[0].File = file;
+      inst->SrcReg[0].Index = index;
+      inst->SrcReg[0].Swizzle = fix_swizzle(swizzle);
+      inst->DstReg.File = PROGRAM_ADDRESS;
+      inst->DstReg.Index = 0;
+      inst->DstReg.WriteMask = WRITEMASK_X;
+   }
+   return inst;
+}
+
+
+/**
+ * Emit a new instruction with given opcode, operands.
+ * At this point the instruction may have multiple indirect register
+ * loads/stores.  We convert those into ARL loads and address-relative
+ * operands.  See comments inside.
+ * At some point in the future we could directly emit indirectly addressed
+ * registers in Mesa GPU instructions.
+ */
+static struct prog_instruction *
+emit_instruction(slang_emit_info *emitInfo,
+                 gl_inst_opcode opcode,
+                 const slang_ir_storage *dst,
+                 const slang_ir_storage *src0,
+                 const slang_ir_storage *src1,
+                 const slang_ir_storage *src2)
+{
+   struct prog_instruction *inst;
+   GLuint numIndirect = 0;
+   const slang_ir_storage *src[3];
+   slang_ir_storage newSrc[3], newDst;
+   GLuint i;
+   GLboolean isTemp[3];
+
+   isTemp[0] = isTemp[1] = isTemp[2] = GL_FALSE;
+
+   src[0] = src0;
+   src[1] = src1;
+   src[2] = src2;
+
+   /* count up how many operands are indirect loads */
+   for (i = 0; i < 3; i++) {
+      if (src[i] && src[i]->IsIndirect)
+         numIndirect++;
+   }
+   if (dst && dst->IsIndirect)
+      numIndirect++;
+
+   /* Take special steps for indirect register loads.
+    * If we had multiple address registers this would be simpler.
+    * For example, this GLSL code:
+    *    x[i] = y[j] + z[k];
+    * would translate into something like:
+    *    ARL ADDR.x, i;
+    *    ARL ADDR.y, j;
+    *    ARL ADDR.z, k;
+    *    ADD TEMP[ADDR.x+5], TEMP[ADDR.y+9], TEMP[ADDR.z+4];
+    * But since we currently only have one address register we have to do this:
+    *    ARL ADDR.x, i;
+    *    MOV t1, TEMP[ADDR.x+9];
+    *    ARL ADDR.x, j;
+    *    MOV t2, TEMP[ADDR.x+4];
+    *    ARL ADDR.x, k;
+    *    ADD TEMP[ADDR.x+5], t1, t2;
+    * The code here figures this out...
+    */
+   if (numIndirect > 0) {
+      for (i = 0; i < 3; i++) {
+         if (src[i] && src[i]->IsIndirect) {
+            /* load the ARL register with the indirect register */
+            emit_arl_load(emitInfo,
+                          src[i]->IndirectFile,
+                          src[i]->IndirectIndex,
+                          src[i]->IndirectSwizzle);
+
+            if (numIndirect > 1) {
+               /* Need to load src[i] into a temporary register */
+               slang_ir_storage srcRelAddr;
+               alloc_local_temp(emitInfo, &newSrc[i], src[i]->Size);
+               isTemp[i] = GL_TRUE;
+
+               /* set RelAddr flag on src register */
+               srcRelAddr = *src[i];
+               srcRelAddr.RelAddr = GL_TRUE;
+               srcRelAddr.IsIndirect = GL_FALSE; /* not really needed */
+
+               /* MOV newSrc, srcRelAddr; */
+               inst = emit_instruction(emitInfo,
+                                       OPCODE_MOV,
+                                       &newSrc[i],
+                                       &srcRelAddr,
+                                       NULL,
+                                       NULL);
+               if (!inst) {
+                  return NULL;
+               }
+
+               src[i] = &newSrc[i];
+            }
+            else {
+               /* just rewrite the src[i] storage to be ARL-relative */
+               newSrc[i] = *src[i];
+               newSrc[i].RelAddr = GL_TRUE;
+               newSrc[i].IsIndirect = GL_FALSE; /* not really needed */
+               src[i] = &newSrc[i];
+            }
+         }
+      }
+   }
+
+   /* Take special steps for indirect dest register write */
+   if (dst && dst->IsIndirect) {
+      /* load the ARL register with the indirect register */
+      emit_arl_load(emitInfo,
+                    dst->IndirectFile,
+                    dst->IndirectIndex,
+                    dst->IndirectSwizzle);
+      newDst = *dst;
+      newDst.RelAddr = GL_TRUE;
+      newDst.IsIndirect = GL_FALSE;
+      dst = &newDst;
+   }
+
+   /* OK, emit the instruction and its dst, src regs */
+   inst = new_instruction(emitInfo, opcode);
+   if (!inst)
+      return NULL;
+
+   if (dst)
+      storage_to_dst_reg(&inst->DstReg, dst);
+
+   for (i = 0; i < 3; i++) {
+      if (src[i])
+         storage_to_src_reg(&inst->SrcReg[i], src[i]);
+   }
+
+   /* Free any temp registers that we allocated above */
+   for (i = 0; i < 3; i++) {
+      if (isTemp[i])
+         _slang_free_temp(emitInfo->vt, &newSrc[i]);
+   }
+
+   return inst;
+}
+
+
+
+/**
+ * Put a comment on the given instruction.
+ */
+static void
+inst_comment(struct prog_instruction *inst, const char *comment)
+{
+   if (inst)
+      inst->Comment = _mesa_strdup(comment);
+}
+
+
+
+/**
+ * Return pointer to last instruction in program.
+ */
+static struct prog_instruction *
+prev_instruction(slang_emit_info *emitInfo)
+{
+   struct gl_program *prog = emitInfo->prog;
+   if (prog->NumInstructions == 0)
+      return NULL;
+   else
+      return prog->Instructions + prog->NumInstructions - 1;
+}
+
+
+static struct prog_instruction *
+emit(slang_emit_info *emitInfo, slang_ir_node *n);
+
+
+/**
+ * Return an annotation string for given node's storage.
+ */
+static char *
+storage_annotation(const slang_ir_node *n, const struct gl_program *prog)
+{
+#if ANNOTATE
+   const slang_ir_storage *st = n->Store;
+   static char s[100] = "";
+
+   if (!st)
+      return _mesa_strdup("");
+
+   switch (st->File) {
+   case PROGRAM_CONSTANT:
+      if (st->Index >= 0) {
+         const GLfloat *val = prog->Parameters->ParameterValues[st->Index];
+         if (st->Swizzle == SWIZZLE_NOOP)
+            _mesa_snprintf(s, sizeof(s), "{%g, %g, %g, %g}", val[0], val[1], val[2], val[3]);
+         else {
+            _mesa_snprintf(s, sizeof(s), "%g", val[GET_SWZ(st->Swizzle, 0)]);
+         }
+      }
+      break;
+   case PROGRAM_TEMPORARY:
+      if (n->Var)
+         _mesa_snprintf(s, sizeof(s), "%s", (char *) n->Var->a_name);
+      else
+         _mesa_snprintf(s, sizeof(s), "t[%d]", st->Index);
+      break;
+   case PROGRAM_STATE_VAR:
+   case PROGRAM_UNIFORM:
+      _mesa_snprintf(s, sizeof(s), "%s", prog->Parameters->Parameters[st->Index].Name);
+      break;
+   case PROGRAM_VARYING:
+      _mesa_snprintf(s, sizeof(s), "%s", prog->Varying->Parameters[st->Index].Name);
+      break;
+   case PROGRAM_INPUT:
+      _mesa_snprintf(s, sizeof(s), "input[%d]", st->Index);
+      break;
+   case PROGRAM_OUTPUT:
+      _mesa_snprintf(s, sizeof(s), "output[%d]", st->Index);
+      break;
+   default:
+      s[0] = 0;
+   }
+   return _mesa_strdup(s);
+#else
+   return NULL;
+#endif
+}
+
+
+/**
+ * Return an annotation string for an instruction.
+ */
+static char *
+instruction_annotation(gl_inst_opcode opcode, char *dstAnnot,
+                       char *srcAnnot0, char *srcAnnot1, char *srcAnnot2)
+{
+#if ANNOTATE
+   const char *operator;
+   char *s;
+   int len = 50;
+
+   if (dstAnnot)
+      len += strlen(dstAnnot);
+   else
+      dstAnnot = _mesa_strdup("");
+
+   if (srcAnnot0)
+      len += strlen(srcAnnot0);
+   else
+      srcAnnot0 = _mesa_strdup("");
+
+   if (srcAnnot1)
+      len += strlen(srcAnnot1);
+   else
+      srcAnnot1 = _mesa_strdup("");
+
+   if (srcAnnot2)
+      len += strlen(srcAnnot2);
+   else
+      srcAnnot2 = _mesa_strdup("");
+
+   switch (opcode) {
+   case OPCODE_ADD:
+      operator = "+";
+      break;
+   case OPCODE_SUB:
+      operator = "-";
+      break;
+   case OPCODE_MUL:
+      operator = "*";
+      break;
+   case OPCODE_DP2:
+      operator = "DP2";
+      break;
+   case OPCODE_DP3:
+      operator = "DP3";
+      break;
+   case OPCODE_DP4:
+      operator = "DP4";
+      break;
+   case OPCODE_XPD:
+      operator = "XPD";
+      break;
+   case OPCODE_RSQ:
+      operator = "RSQ";
+      break;
+   case OPCODE_SGT:
+      operator = ">";
+      break;
+   default:
+      operator = ",";
+   }
+
+   s = (char *) malloc(len);
+   _mesa_snprintf(s, len, "%s = %s %s %s %s", dstAnnot,
+                  srcAnnot0, operator, srcAnnot1, srcAnnot2);
+
+   free(dstAnnot);
+   free(srcAnnot0);
+   free(srcAnnot1);
+   free(srcAnnot2);
+
+   return s;
+#else
+   return NULL;
+#endif
+}
+
+
+/**
+ * Emit an instruction that's just a comment.
+ */
+static struct prog_instruction *
+emit_comment(slang_emit_info *emitInfo, const char *comment)
+{
+   struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_NOP);
+   if (inst) {
+      inst_comment(inst, comment);
+   }
+   return inst;
+}
+
+
+/**
+ * Generate code for a simple arithmetic instruction.
+ * Either 1, 2 or 3 operands.
+ */
+static struct prog_instruction *
+emit_arith(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   const slang_ir_info *info = _slang_ir_info(n->Opcode);
+   struct prog_instruction *inst;
+   GLuint i;
+
+   assert(info);
+   assert(info->InstOpcode != OPCODE_NOP);
+
+#if PEEPHOLE_OPTIMIZATIONS
+   /* Look for MAD opportunity */
+   if (info->NumParams == 2 &&
+       n->Opcode == IR_ADD && n->Children[0]->Opcode == IR_MUL) {
+      /* found pattern IR_ADD(IR_MUL(A, B), C) */
+      emit(emitInfo, n->Children[0]->Children[0]);  /* A */
+      emit(emitInfo, n->Children[0]->Children[1]);  /* B */
+      emit(emitInfo, n->Children[1]);  /* C */
+      if (!alloc_node_storage(emitInfo, n, -1)) {  /* dest */
+         return NULL;
+      }
+
+      inst = emit_instruction(emitInfo,
+                              OPCODE_MAD,
+                              n->Store,
+                              n->Children[0]->Children[0]->Store,
+                              n->Children[0]->Children[1]->Store,
+                              n->Children[1]->Store);
+
+      free_node_storage(emitInfo->vt, n->Children[0]->Children[0]);
+      free_node_storage(emitInfo->vt, n->Children[0]->Children[1]);
+      free_node_storage(emitInfo->vt, n->Children[1]);
+      return inst;
+   }
+
+   if (info->NumParams == 2 &&
+       n->Opcode == IR_ADD && n->Children[1]->Opcode == IR_MUL) {
+      /* found pattern IR_ADD(A, IR_MUL(B, C)) */
+      emit(emitInfo, n->Children[0]);  /* A */
+      emit(emitInfo, n->Children[1]->Children[0]);  /* B */
+      emit(emitInfo, n->Children[1]->Children[1]);  /* C */
+      if (!alloc_node_storage(emitInfo, n, -1)) {  /* dest */
+         return NULL;
+      }
+
+      inst = emit_instruction(emitInfo,
+                              OPCODE_MAD,
+                              n->Store,
+                              n->Children[1]->Children[0]->Store,
+                              n->Children[1]->Children[1]->Store,
+                              n->Children[0]->Store);
+
+      free_node_storage(emitInfo->vt, n->Children[1]->Children[0]);
+      free_node_storage(emitInfo->vt, n->Children[1]->Children[1]);
+      free_node_storage(emitInfo->vt, n->Children[0]);
+      return inst;
+   }
+#endif
+
+   /* gen code for children, may involve temp allocation */
+   for (i = 0; i < info->NumParams; i++) {
+      emit(emitInfo, n->Children[i]);
+      if (!n->Children[i] || !n->Children[i]->Store) {
+         /* error recovery */
+         return NULL;
+      }
+   }
+
+   /* result storage */
+   if (!alloc_node_storage(emitInfo, n, -1)) {
+      return NULL;
+   }
+
+   inst = emit_instruction(emitInfo,
+                           info->InstOpcode,
+                           n->Store,  /* dest */
+                           (info->NumParams > 0 ? n->Children[0]->Store : NULL),
+                           (info->NumParams > 1 ? n->Children[1]->Store : NULL),
+                           (info->NumParams > 2 ? n->Children[2]->Store : NULL)
+                           );
+
+   /* free temps */
+   for (i = 0; i < info->NumParams; i++)
+      free_node_storage(emitInfo->vt, n->Children[i]);
+
+   return inst;
+}
+
+
+/**
+ * Emit code for == and != operators.  These could normally be handled
+ * by emit_arith() except we need to be able to handle structure comparisons.
+ */
+static struct prog_instruction *
+emit_compare(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   struct prog_instruction *inst = NULL;
+   GLint size;
+
+   assert(n->Opcode == IR_EQUAL || n->Opcode == IR_NOTEQUAL);
+
+   /* gen code for children */
+   emit(emitInfo, n->Children[0]);
+   emit(emitInfo, n->Children[1]);
+
+   if (n->Children[0]->Store->Size != n->Children[1]->Store->Size) {
+      /* XXX this error should have been caught in slang_codegen.c */
+      slang_info_log_error(emitInfo->log, "invalid operands to == or !=");
+      n->Store = NULL;
+      return NULL;
+   }
+
+   /* final result is 1 bool */
+   if (!alloc_node_storage(emitInfo, n, 1))
+      return NULL;
+
+   size = n->Children[0]->Store->Size;
+
+   if (size == 1) {
+      gl_inst_opcode opcode = n->Opcode == IR_EQUAL ? OPCODE_SEQ : OPCODE_SNE;
+      inst =  emit_instruction(emitInfo,
+                               opcode,
+                               n->Store, /* dest */
+                               n->Children[0]->Store,
+                               n->Children[1]->Store,
+                               NULL);
+   }
+   else if (size <= 4) {
+      /* compare two vectors.
+       * Unfortunately, there's no instruction to compare vectors and
+       * return a scalar result.  Do it with some compare and dot product
+       * instructions...
+       */
+      GLuint swizzle;
+      gl_inst_opcode dotOp;
+      slang_ir_storage tempStore;
+
+      if (!alloc_local_temp(emitInfo, &tempStore, 4)) {
+         n->Store = NULL;
+         return NULL;
+         /* out of temps */
+      }
+
+      if (size == 4) {
+         dotOp = OPCODE_DP4;
+         swizzle = SWIZZLE_XYZW;
+      }
+      else if (size == 3) {
+         dotOp = OPCODE_DP3;
+         swizzle = SWIZZLE_XYZW;
+      }
+      else {
+         assert(size == 2);
+         dotOp = OPCODE_DP3; /* XXX use OPCODE_DP2 eventually */
+         swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y);
+      }
+
+      /* Compute inequality (temp = (A != B)) */
+      inst = emit_instruction(emitInfo,
+                              OPCODE_SNE,
+                              &tempStore,
+                              n->Children[0]->Store,
+                              n->Children[1]->Store,
+                              NULL);
+      if (!inst) {
+         return NULL;
+      }
+      inst_comment(inst, "Compare values");
+
+      /* Compute val = DOT(temp, temp)  (reduction) */
+      inst = emit_instruction(emitInfo,
+                              dotOp,
+                              n->Store,
+                              &tempStore,
+                              &tempStore,
+                              NULL);
+      if (!inst) {
+         return NULL;
+      }
+      inst->SrcReg[0].Swizzle = inst->SrcReg[1].Swizzle = swizzle; /*override*/
+      inst_comment(inst, "Reduce vec to bool");
+
+      _slang_free_temp(emitInfo->vt, &tempStore); /* free temp */
+
+      if (n->Opcode == IR_EQUAL) {
+         /* compute val = !val.x  with SEQ val, val, 0; */
+         slang_ir_storage zero;
+         constant_to_storage(emitInfo, 0.0, &zero);
+         inst = emit_instruction(emitInfo,
+                                 OPCODE_SEQ,
+                                 n->Store, /* dest */
+                                 n->Store,
+                                 &zero,
+                                 NULL);
+         if (!inst) {
+            return NULL;
+         }
+         inst_comment(inst, "Invert true/false");
+      }
+   }
+   else {
+      /* size > 4, struct or array compare.
+       * XXX this won't work reliably for structs with padding!!
+       */
+      GLint i, num = (n->Children[0]->Store->Size + 3) / 4;
+      slang_ir_storage accTemp, sneTemp;
+
+      if (!alloc_local_temp(emitInfo, &accTemp, 4))
+         return NULL;
+
+      if (!alloc_local_temp(emitInfo, &sneTemp, 4))
+         return NULL;
+
+      for (i = 0; i < num; i++) {
+         slang_ir_storage srcStore0 = *n->Children[0]->Store;
+         slang_ir_storage srcStore1 = *n->Children[1]->Store;
+         srcStore0.Index += i;
+         srcStore1.Index += i;
+
+         if (i == 0) {
+            /* SNE accTemp, left[i], right[i] */
+            inst = emit_instruction(emitInfo, OPCODE_SNE,
+                                    &accTemp, /* dest */
+                                    &srcStore0,
+                                    &srcStore1,
+                                    NULL);
+            if (!inst) {
+               return NULL;
+            }
+            inst_comment(inst, "Begin struct/array comparison");
+         }
+         else {
+            /* SNE sneTemp, left[i], right[i] */
+            inst = emit_instruction(emitInfo, OPCODE_SNE,
+                                    &sneTemp, /* dest */
+                                    &srcStore0,
+                                    &srcStore1,
+                                    NULL);
+            if (!inst) {
+               return NULL;
+            }
+            /* ADD accTemp, accTemp, sneTemp; # like logical-OR */
+            inst = emit_instruction(emitInfo, OPCODE_ADD,
+                                    &accTemp, /* dest */
+                                    &accTemp,
+                                    &sneTemp,
+                                    NULL);
+            if (!inst) {
+               return NULL;
+            }
+         }
+      }
+
+      /* compute accTemp.x || accTemp.y || accTemp.z || accTemp.w with DOT4 */
+      inst = emit_instruction(emitInfo, OPCODE_DP4,
+                              n->Store,
+                              &accTemp,
+                              &accTemp,
+                              NULL);
+      if (!inst) {
+         return NULL;
+      }
+      inst_comment(inst, "End struct/array comparison");
+
+      if (n->Opcode == IR_EQUAL) {
+         /* compute tmp.x = !tmp.x  via tmp.x = (tmp.x == 0) */
+         slang_ir_storage zero;
+         constant_to_storage(emitInfo, 0.0, &zero);
+         inst = emit_instruction(emitInfo, OPCODE_SEQ,
+                                 n->Store, /* dest */
+                                 n->Store,
+                                 &zero,
+                                 NULL);
+         if (!inst) {
+            return NULL;
+         }
+         inst_comment(inst, "Invert true/false");
+      }
+
+      _slang_free_temp(emitInfo->vt, &accTemp);
+      _slang_free_temp(emitInfo->vt, &sneTemp);
+   }
+
+   /* free temps */
+   free_node_storage(emitInfo->vt, n->Children[0]);
+   free_node_storage(emitInfo->vt, n->Children[1]);
+
+   return inst;
+}
+
+
+
+/**
+ * Generate code for an IR_CLAMP instruction.
+ */
+static struct prog_instruction *
+emit_clamp(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   struct prog_instruction *inst;
+   slang_ir_node tmpNode;
+
+   assert(n->Opcode == IR_CLAMP);
+   /* ch[0] = value
+    * ch[1] = min limit
+    * ch[2] = max limit
+    */
+
+   inst = emit(emitInfo, n->Children[0]);
+
+   /* If lower limit == 0.0 and upper limit == 1.0,
+    *    set prev instruction's SaturateMode field to SATURATE_ZERO_ONE.
+    * Else,
+    *    emit OPCODE_MIN, OPCODE_MAX sequence.
+    */
+#if 0
+   /* XXX this isn't quite finished yet */
+   if (n->Children[1]->Opcode == IR_FLOAT &&
+       n->Children[1]->Value[0] == 0.0 &&
+       n->Children[1]->Value[1] == 0.0 &&
+       n->Children[1]->Value[2] == 0.0 &&
+       n->Children[1]->Value[3] == 0.0 &&
+       n->Children[2]->Opcode == IR_FLOAT &&
+       n->Children[2]->Value[0] == 1.0 &&
+       n->Children[2]->Value[1] == 1.0 &&
+       n->Children[2]->Value[2] == 1.0 &&
+       n->Children[2]->Value[3] == 1.0) {
+      if (!inst) {
+         inst = prev_instruction(prog);
+      }
+      if (inst && inst->Opcode != OPCODE_NOP) {
+         /* and prev instruction's DstReg matches n->Children[0]->Store */
+         inst->SaturateMode = SATURATE_ZERO_ONE;
+         n->Store = n->Children[0]->Store;
+         return inst;
+      }
+   }
+#else
+   (void) inst;
+#endif
+
+   if (!alloc_node_storage(emitInfo, n, n->Children[0]->Store->Size))
+      return NULL;
+
+   emit(emitInfo, n->Children[1]);
+   emit(emitInfo, n->Children[2]);
+
+   /* Some GPUs don't allow reading from output registers.  So if the
+    * dest for this clamp() is an output reg, we can't use that reg for
+    * the intermediate result.  Use a temp register instead.
+    */
+   memset(&tmpNode, 0, sizeof(tmpNode));
+   if (!alloc_node_storage(emitInfo, &tmpNode, n->Store->Size)) {
+      return NULL;
+   }
+
+   /* tmp = max(ch[0], ch[1]) */
+   inst = emit_instruction(emitInfo, OPCODE_MAX,
+                           tmpNode.Store, /* dest */
+                           n->Children[0]->Store,
+                           n->Children[1]->Store,
+                           NULL);
+   if (!inst) {
+      return NULL;
+   }
+
+   /* n->dest = min(tmp, ch[2]) */
+   inst = emit_instruction(emitInfo, OPCODE_MIN,
+                           n->Store, /* dest */
+                           tmpNode.Store,
+                           n->Children[2]->Store,
+                           NULL);
+
+   free_node_storage(emitInfo->vt, &tmpNode);
+
+   return inst;
+}
+
+
+static struct prog_instruction *
+emit_negation(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   /* Implement as MOV dst, -src; */
+   /* XXX we could look at the previous instruction and in some circumstances
+    * modify it to accomplish the negation.
+    */
+   struct prog_instruction *inst;
+
+   emit(emitInfo, n->Children[0]);
+
+   if (!alloc_node_storage(emitInfo, n, n->Children[0]->Store->Size))
+      return NULL;
+
+   inst = emit_instruction(emitInfo,
+                           OPCODE_MOV,
+                           n->Store, /* dest */
+                           n->Children[0]->Store,
+                           NULL,
+                           NULL);
+   if (inst) {
+      inst->SrcReg[0].Negate = NEGATE_XYZW;
+   }
+   return inst;
+}
+
+
+static struct prog_instruction *
+emit_label(slang_emit_info *emitInfo, const slang_ir_node *n)
+{
+   assert(n->Label);
+#if 0
+   /* XXX this fails in loop tail code - investigate someday */
+   assert(_slang_label_get_location(n->Label) < 0);
+   _slang_label_set_location(n->Label, emitInfo->prog->NumInstructions,
+                             emitInfo->prog);
+#else
+   if (_slang_label_get_location(n->Label) < 0)
+      _slang_label_set_location(n->Label, emitInfo->prog->NumInstructions,
+                                emitInfo->prog);
+#endif
+   return NULL;
+}
+
+
+/**
+ * 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_fcall(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   struct gl_program *progSave;
+   struct prog_instruction *inst;
+   GLuint subroutineId;
+   GLuint maxInstSave;
+
+   assert(n->Opcode == IR_CALL);
+   assert(n->Label);
+
+   /* save/push cur program */
+   maxInstSave = emitInfo->MaxInstructions;
+   progSave = emitInfo->prog;
+
+   emitInfo->prog = new_subroutine(emitInfo, &subroutineId);
+   emitInfo->MaxInstructions = emitInfo->prog->NumInstructions;
+
+   _slang_label_set_location(n->Label, emitInfo->prog->NumInstructions,
+                             emitInfo->prog);
+
+   if (emitInfo->EmitBeginEndSub) {
+      /* BGNSUB isn't a real instruction.
+       * We require a label (i.e. "foobar:") though, if we're going to
+       * print the program in the NV format.  The BNGSUB instruction is
+       * really just a NOP to attach the label to.
+       */
+      inst = new_instruction(emitInfo, OPCODE_BGNSUB);
+      if (!inst) {
+         return NULL;
+      }
+      inst_comment(inst, n->Label->Name);
+   }
+
+   /* body of function: */
+   emit(emitInfo, n->Children[0]);
+   n->Store = n->Children[0]->Store;
+
+   /* add RET instruction now, if needed */
+   inst = prev_instruction(emitInfo);
+   if (inst && inst->Opcode != OPCODE_RET) {
+      inst = new_instruction(emitInfo, OPCODE_RET);
+      if (!inst) {
+         return NULL;
+      }
+   }
+
+   if (emitInfo->EmitBeginEndSub) {
+      inst = new_instruction(emitInfo, OPCODE_ENDSUB);
+      if (!inst) {
+         return NULL;
+      }
+      inst_comment(inst, n->Label->Name);
+   }
+
+   /* pop/restore cur program */
+   emitInfo->prog = progSave;
+   emitInfo->MaxInstructions = maxInstSave;
+
+   /* emit the function call */
+   inst = new_instruction(emitInfo, OPCODE_CAL);
+   if (!inst) {
+      return NULL;
+   }
+   /* The branch target is just the subroutine number (changed later) */
+   inst->BranchTarget = subroutineId;
+   inst_comment(inst, n->Label->Name);
+   assert(inst->BranchTarget >= 0);
+
+   return inst;
+}
+
+
+/**
+ * Emit code for a 'return' statement.
+ */
+static struct prog_instruction *
+emit_return(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   struct prog_instruction *inst;
+   assert(n);
+   assert(n->Opcode == IR_RETURN);
+   assert(n->Label);
+   inst = new_instruction(emitInfo, OPCODE_RET);
+   if (inst) {
+      inst->DstReg.CondMask = COND_TR;  /* always return */
+   }
+   return inst;
+}
+
+
+static struct prog_instruction *
+emit_kill(slang_emit_info *emitInfo)
+{
+   struct gl_fragment_program *fp;
+   struct prog_instruction *inst;
+   /* NV-KILL - discard fragment depending on condition code.
+    * Note that ARB-KILL depends on sign of vector operand.
+    */
+   inst = new_instruction(emitInfo, OPCODE_KIL_NV);
+   if (!inst) {
+      return NULL;
+   }
+   inst->DstReg.CondMask = COND_TR;  /* always kill */
+
+   assert(emitInfo->prog->Target == GL_FRAGMENT_PROGRAM_ARB);
+   fp = (struct gl_fragment_program *) emitInfo->prog;
+   fp->UsesKill = GL_TRUE;
+
+   return inst;
+}
+
+
+static struct prog_instruction *
+emit_tex(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   struct prog_instruction *inst;
+   gl_inst_opcode opcode;
+   GLboolean shadow = GL_FALSE;
+
+   switch (n->Opcode) {
+   case IR_TEX:
+      opcode = OPCODE_TEX;
+      break;
+   case IR_TEX_SH:
+      opcode = OPCODE_TEX;
+      shadow = GL_TRUE;
+      break;
+   case IR_TEXB:
+      opcode = OPCODE_TXB;
+      break;
+   case IR_TEXB_SH:
+      opcode = OPCODE_TXB;
+      shadow = GL_TRUE;
+      break;
+   case IR_TEXP:
+      opcode = OPCODE_TXP;
+      break;
+   case IR_TEXP_SH:
+      opcode = OPCODE_TXP;
+      shadow = GL_TRUE;
+      break;
+   default:
+      _mesa_problem(NULL, "Bad IR TEX code");
+      return NULL;
+   }
+
+   if (n->Children[0]->Opcode == IR_ELEMENT) {
+      /* array is the sampler (a uniform which'll indicate the texture unit) */
+      assert(n->Children[0]->Children[0]->Store);
+      assert(n->Children[0]->Children[0]->Store->File == PROGRAM_SAMPLER);
+
+      emit(emitInfo, n->Children[0]);
+
+      n->Children[0]->Var = n->Children[0]->Children[0]->Var;
+   } else {
+      /* this is the sampler (a uniform which'll indicate the texture unit) */
+      assert(n->Children[0]->Store);
+      assert(n->Children[0]->Store->File == PROGRAM_SAMPLER);
+   }
+
+   /* emit code for the texcoord operand */
+   (void) emit(emitInfo, n->Children[1]);
+
+   /* alloc storage for result of texture fetch */
+   if (!alloc_node_storage(emitInfo, n, 4))
+      return NULL;
+
+   /* emit TEX instruction;  Child[1] is the texcoord */
+   inst = emit_instruction(emitInfo,
+                           opcode,
+                           n->Store,
+                           n->Children[1]->Store,
+                           NULL,
+                           NULL);
+   if (!inst) {
+      return NULL;
+   }
+
+   inst->TexShadow = shadow;
+
+   /* Store->Index is the uniform/sampler index */
+   assert(n->Children[0]->Store->Index >= 0);
+   inst->TexSrcUnit = n->Children[0]->Store->Index;
+   inst->TexSrcTarget = n->Children[0]->Store->TexTarget;
+
+   /* mark the sampler as being used */
+   _mesa_use_uniform(emitInfo->prog->Parameters,
+                     (char *) n->Children[0]->Var->a_name);
+
+   return inst;
+}
+
+
+/**
+ * Assignment/copy
+ */
+static struct prog_instruction *
+emit_copy(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   struct prog_instruction *inst;
+
+   assert(n->Opcode == IR_COPY);
+
+   /* lhs */
+   emit(emitInfo, n->Children[0]);
+   if (!n->Children[0]->Store || n->Children[0]->Store->Index < 0) {
+      /* an error should have been already recorded */
+      return NULL;
+   }
+
+   /* rhs */
+   assert(n->Children[1]);
+   inst = emit(emitInfo, n->Children[1]);
+
+   if (!n->Children[1]->Store || n->Children[1]->Store->Index < 0) {
+      if (!emitInfo->log->text && !emitInfo->UnresolvedFunctions) {
+         /* XXX this error should have been caught in slang_codegen.c */
+         slang_info_log_error(emitInfo->log, "invalid assignment");
+      }
+      return NULL;
+   }
+
+   assert(n->Children[1]->Store->Index >= 0);
+
+   /*assert(n->Children[0]->Store->Size == n->Children[1]->Store->Size);*/
+
+   n->Store = n->Children[0]->Store;
+
+   if (n->Store->File == PROGRAM_SAMPLER) {
+      /* no code generated for sampler assignments,
+       * just copy the sampler index/target at compile time.
+       */
+      n->Store->Index = n->Children[1]->Store->Index;
+      n->Store->TexTarget = n->Children[1]->Store->TexTarget;
+      return NULL;
+   }
+
+#if PEEPHOLE_OPTIMIZATIONS
+   if (inst &&
+       (n->Children[1]->Opcode != IR_SWIZZLE) &&
+       _slang_is_temp(emitInfo->vt, n->Children[1]->Store) &&
+       (inst->DstReg.File == n->Children[1]->Store->File) &&
+       (inst->DstReg.Index == n->Children[1]->Store->Index) &&
+       !n->Children[0]->Store->IsIndirect &&
+       n->Children[0]->Store->Size <= 4) {
+      /* Peephole optimization:
+       * The Right-Hand-Side has its results in a temporary place.
+       * Modify the RHS (and the prev instruction) to store its results
+       * in the destination specified by n->Children[0].
+       * Then, this MOVE is a no-op.
+       * Ex:
+       *   MUL tmp, x, y;
+       *   MOV a, tmp;
+       * becomes:
+       *   MUL a, x, y;
+       */
+
+      /* fixup the previous instruction (which stored the RHS result) */
+      assert(n->Children[0]->Store->Index >= 0);
+      storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store);
+      return inst;
+   }
+   else
+#endif
+   {
+      if (n->Children[0]->Store->Size > 4) {
+         /* move matrix/struct etc (block of registers) */
+         slang_ir_storage dstStore = *n->Children[0]->Store;
+         slang_ir_storage srcStore = *n->Children[1]->Store;
+         GLint size = srcStore.Size;
+         ASSERT(n->Children[1]->Store->Swizzle == SWIZZLE_NOOP);
+         dstStore.Size = 4;
+         srcStore.Size = 4;
+         while (size >= 4) {
+            inst = emit_instruction(emitInfo, OPCODE_MOV,
+                                    &dstStore,
+                                    &srcStore,
+                                    NULL,
+                                    NULL);
+            if (!inst) {
+               return NULL;
+            }
+            inst_comment(inst, "IR_COPY block");
+            srcStore.Index++;
+            dstStore.Index++;
+            size -= 4;
+         }
+      }
+      else {
+         /* single register move */
+         char *srcAnnot, *dstAnnot;
+         assert(n->Children[0]->Store->Index >= 0);
+         inst = emit_instruction(emitInfo, OPCODE_MOV,
+                                 n->Children[0]->Store, /* dest */
+                                 n->Children[1]->Store,
+                                 NULL,
+                                 NULL);
+         if (!inst) {
+            return NULL;
+         }
+         dstAnnot = storage_annotation(n->Children[0], emitInfo->prog);
+         srcAnnot = storage_annotation(n->Children[1], emitInfo->prog);
+         inst->Comment = instruction_annotation(inst->Opcode, dstAnnot,
+                                                srcAnnot, NULL, NULL);
+      }
+      free_node_storage(emitInfo->vt, n->Children[1]);
+      return inst;
+   }
+}
+
+
+/**
+ * An IR_COND node wraps a boolean expression which is used by an
+ * IF or WHILE test.  This is where we'll set condition codes, if needed.
+ */
+static struct prog_instruction *
+emit_cond(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   struct prog_instruction *inst;
+
+   assert(n->Opcode == IR_COND);
+
+   if (!n->Children[0])
+      return NULL;
+
+   /* emit code for the expression */
+   inst = emit(emitInfo, n->Children[0]);
+
+   if (!n->Children[0]->Store) {
+      /* error recovery */
+      return NULL;
+   }
+
+   assert(n->Children[0]->Store);
+   /*assert(n->Children[0]->Store->Size == 1);*/
+
+   if (emitInfo->EmitCondCodes) {
+      if (inst &&
+          n->Children[0]->Store &&
+          inst->DstReg.File == n->Children[0]->Store->File &&
+          inst->DstReg.Index == n->Children[0]->Store->Index) {
+         /* The previous instruction wrote to the register who's value
+          * we're testing.  Just fix that instruction so that the
+          * condition codes are computed.
+          */
+         inst->CondUpdate = GL_TRUE;
+         n->Store = n->Children[0]->Store;
+         return inst;
+      }
+      else {
+         /* This'll happen for things like "if (i) ..." where no code
+          * is normally generated for the expression "i".
+          * Generate a move instruction just to set condition codes.
+          */
+         if (!alloc_node_storage(emitInfo, n, 1))
+            return NULL;
+         inst = emit_instruction(emitInfo, OPCODE_MOV,
+                                 n->Store, /* dest */
+                                 n->Children[0]->Store,
+                                 NULL,
+                                 NULL);
+         if (!inst) {
+            return NULL;
+         }
+         inst->CondUpdate = GL_TRUE;
+         inst_comment(inst, "COND expr");
+         _slang_free_temp(emitInfo->vt, n->Store);
+         return inst;
+      }
+   }
+   else {
+      /* No-op: the boolean result of the expression is in a regular reg */
+      n->Store = n->Children[0]->Store;
+      return inst;
+   }
+}
+
+
+/**
+ * Logical-NOT
+ */
+static struct prog_instruction *
+emit_not(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   static const struct {
+      gl_inst_opcode op, opNot;
+   } operators[] = {
+      { OPCODE_SLT, OPCODE_SGE },
+      { OPCODE_SLE, OPCODE_SGT },
+      { OPCODE_SGT, OPCODE_SLE },
+      { OPCODE_SGE, OPCODE_SLT },
+      { OPCODE_SEQ, OPCODE_SNE },
+      { OPCODE_SNE, OPCODE_SEQ },
+      { 0, 0 }
+   };
+   struct prog_instruction *inst;
+   slang_ir_storage zero;
+   GLuint i;
+
+   /* child expr */
+   inst = emit(emitInfo, n->Children[0]);
+
+#if PEEPHOLE_OPTIMIZATIONS
+   if (inst) {
+      /* if the prev instruction was a comparison instruction, invert it */
+      for (i = 0; operators[i].op; i++) {
+         if (inst->Opcode == operators[i].op) {
+            inst->Opcode = operators[i].opNot;
+            n->Store = n->Children[0]->Store;
+            return inst;
+         }
+      }
+   }
+#endif
+
+   /* else, invert using SEQ (v = v == 0) */
+   if (!alloc_node_storage(emitInfo, n, n->Children[0]->Store->Size))
+      return NULL;
+
+   constant_to_storage(emitInfo, 0.0, &zero);
+   inst = emit_instruction(emitInfo,
+                           OPCODE_SEQ,
+                           n->Store,
+                           n->Children[0]->Store,
+                           &zero,
+                           NULL);
+   if (!inst) {
+      return NULL;
+   }
+   inst_comment(inst, "NOT");
+
+   free_node_storage(emitInfo->vt, n->Children[0]);
+
+   return inst;
+}
+
+
+static struct prog_instruction *
+emit_if(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   struct gl_program *prog = emitInfo->prog;
+   GLuint ifInstLoc, elseInstLoc = 0;
+   GLuint condWritemask = 0;
+
+   /* emit condition expression code */
+   {
+      struct prog_instruction *inst;
+      inst = emit(emitInfo, n->Children[0]);
+      if (emitInfo->EmitCondCodes) {
+         if (!inst) {
+            /* error recovery */
+            return NULL;
+         }
+         condWritemask = inst->DstReg.WriteMask;
+      }
+   }
+
+   if (!n->Children[0]->Store)
+      return NULL;
+
+#if 0
+   assert(n->Children[0]->Store->Size == 1); /* a bool! */
+#endif
+
+   ifInstLoc = prog->NumInstructions;
+   if (emitInfo->EmitHighLevelInstructions) {
+      if (emitInfo->EmitCondCodes) {
+         /* IF condcode THEN ... */
+         struct prog_instruction *ifInst = new_instruction(emitInfo, OPCODE_IF);
+         if (!ifInst) {
+            return NULL;
+         }
+         ifInst->DstReg.CondMask = COND_NE;  /* if cond is non-zero */
+         /* only test the cond code (1 of 4) that was updated by the
+          * previous instruction.
+          */
+         ifInst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
+      }
+      else {
+         struct prog_instruction *inst;
+
+         /* IF src[0] THEN ... */
+         inst = emit_instruction(emitInfo, OPCODE_IF,
+                                 NULL, /* dst */
+                                 n->Children[0]->Store, /* op0 */
+                                 NULL,
+                                 NULL);
+         if (!inst) {
+            return NULL;
+         }
+      }
+   }
+   else {
+      /* conditional jump to else, or endif */
+      struct prog_instruction *ifInst = new_instruction(emitInfo, OPCODE_BRA);
+      if (!ifInst) {
+         return NULL;
+      }
+      ifInst->DstReg.CondMask = COND_EQ;  /* BRA if cond is zero */
+      inst_comment(ifInst, "if zero");
+      ifInst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
+   }
+
+   /* if body */
+   emit(emitInfo, n->Children[1]);
+
+   if (n->Children[2]) {
+      /* have else body */
+      elseInstLoc = prog->NumInstructions;
+      if (emitInfo->EmitHighLevelInstructions) {
+         struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_ELSE);
+         if (!inst) {
+            return NULL;
+         }
+         prog->Instructions[ifInstLoc].BranchTarget = prog->NumInstructions - 1;
+      }
+      else {
+         /* jump to endif instruction */
+         struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_BRA);
+         if (!inst) {
+            return NULL;
+         }
+         inst_comment(inst, "else");
+         inst->DstReg.CondMask = COND_TR;  /* always branch */
+         prog->Instructions[ifInstLoc].BranchTarget = prog->NumInstructions;
+      }
+      emit(emitInfo, n->Children[2]);
+   }
+   else {
+      /* no else body */
+      prog->Instructions[ifInstLoc].BranchTarget = prog->NumInstructions;
+   }
+
+   if (emitInfo->EmitHighLevelInstructions) {
+      struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_ENDIF);
+      if (!inst) {
+         return NULL;
+      }
+   }
+
+   if (elseInstLoc) {
+      /* point ELSE instruction BranchTarget at ENDIF */
+      if (emitInfo->EmitHighLevelInstructions) {
+         prog->Instructions[elseInstLoc].BranchTarget = prog->NumInstructions - 1;
+      }
+      else {
+         prog->Instructions[elseInstLoc].BranchTarget = prog->NumInstructions;
+      }
+   }
+   return NULL;
+}
+
+
+static struct prog_instruction *
+emit_loop(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   struct gl_program *prog = emitInfo->prog;
+   struct prog_instruction *endInst;
+   GLuint beginInstLoc, tailInstLoc, endInstLoc;
+   slang_ir_node *ir;
+
+   /* emit OPCODE_BGNLOOP */
+   beginInstLoc = prog->NumInstructions;
+   if (emitInfo->EmitHighLevelInstructions) {
+      struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_BGNLOOP);
+      if (!inst) {
+         return NULL;
+      }
+   }
+
+   /* body */
+   emit(emitInfo, n->Children[0]);
+
+   /* tail */
+   tailInstLoc = prog->NumInstructions;
+   if (n->Children[1]) {
+      if (emitInfo->EmitComments)
+         emit_comment(emitInfo, "Loop tail code:");
+      emit(emitInfo, n->Children[1]);
+   }
+
+   endInstLoc = prog->NumInstructions;
+   if (emitInfo->EmitHighLevelInstructions) {
+      /* emit OPCODE_ENDLOOP */
+      endInst = new_instruction(emitInfo, OPCODE_ENDLOOP);
+      if (!endInst) {
+         return NULL;
+      }
+   }
+   else {
+      /* emit unconditional BRA-nch */
+      endInst = new_instruction(emitInfo, OPCODE_BRA);
+      if (!endInst) {
+         return NULL;
+      }
+      endInst->DstReg.CondMask = COND_TR;  /* always true */
+   }
+   /* ENDLOOP's BranchTarget points to the BGNLOOP inst */
+   endInst->BranchTarget = beginInstLoc;
+
+   if (emitInfo->EmitHighLevelInstructions) {
+      /* BGNLOOP's BranchTarget points to the ENDLOOP inst */
+      prog->Instructions[beginInstLoc].BranchTarget = prog->NumInstructions -1;
+   }
+
+   /* Done emitting loop code.  Now walk over the loop's linked list of
+    * BREAK and CONT nodes, filling in their BranchTarget fields (which
+    * will point to the corresponding ENDLOOP instruction.
+    */
+   for (ir = n->List; ir; ir = ir->List) {
+      struct prog_instruction *inst = prog->Instructions + ir->InstLocation;
+      assert(inst->BranchTarget < 0);
+      if (ir->Opcode == IR_BREAK ||
+          ir->Opcode == IR_BREAK_IF_TRUE) {
+         assert(inst->Opcode == OPCODE_BRK ||
+                inst->Opcode == OPCODE_BRA);
+         /* go to instruction at end of loop */
+         if (emitInfo->EmitHighLevelInstructions) {
+            inst->BranchTarget = endInstLoc;
+         }
+         else {
+            inst->BranchTarget = endInstLoc + 1;
+         }
+      }
+      else {
+         assert(ir->Opcode == IR_CONT ||
+                ir->Opcode == IR_CONT_IF_TRUE);
+         assert(inst->Opcode == OPCODE_CONT ||
+                inst->Opcode == OPCODE_BRA);
+         /* go to instruction at tail of loop */
+         inst->BranchTarget = endInstLoc;
+      }
+   }
+   return NULL;
+}
+
+
+/**
+ * Unconditional "continue" or "break" statement.
+ * Either OPCODE_CONT, OPCODE_BRK or OPCODE_BRA will be emitted.
+ */
+static struct prog_instruction *
+emit_cont_break(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   gl_inst_opcode opcode;
+   struct prog_instruction *inst;
+
+   if (n->Opcode == IR_CONT) {
+      /* we need to execute the loop's tail code before doing CONT */
+      assert(n->Parent);
+      assert(n->Parent->Opcode == IR_LOOP);
+      if (n->Parent->Children[1]) {
+         /* emit tail code */
+         if (emitInfo->EmitComments) {
+            emit_comment(emitInfo, "continue - tail code:");
+         }
+         emit(emitInfo, n->Parent->Children[1]);
+      }
+   }
+
+   /* opcode selection */
+   if (emitInfo->EmitHighLevelInstructions) {
+      opcode = (n->Opcode == IR_CONT) ? OPCODE_CONT : OPCODE_BRK;
+   }
+   else {
+      opcode = OPCODE_BRA;
+   }
+   n->InstLocation = emitInfo->prog->NumInstructions;
+   inst = new_instruction(emitInfo, opcode);
+   if (inst) {
+      inst->DstReg.CondMask = COND_TR;  /* always true */
+   }
+   return inst;
+}
+
+
+/**
+ * Conditional "continue" or "break" statement.
+ * Either OPCODE_CONT, OPCODE_BRK or OPCODE_BRA will be emitted.
+ */
+static struct prog_instruction *
+emit_cont_break_if_true(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   struct prog_instruction *inst;
+
+   assert(n->Opcode == IR_CONT_IF_TRUE ||
+          n->Opcode == IR_BREAK_IF_TRUE);
+
+   /* evaluate condition expr, setting cond codes */
+   inst = emit(emitInfo, n->Children[0]);
+   if (emitInfo->EmitCondCodes) {
+      assert(inst);
+      inst->CondUpdate = GL_TRUE;
+   }
+
+   n->InstLocation = emitInfo->prog->NumInstructions;
+
+   /* opcode selection */
+   if (emitInfo->EmitHighLevelInstructions) {
+      const gl_inst_opcode opcode
+         = (n->Opcode == IR_CONT_IF_TRUE) ? OPCODE_CONT : OPCODE_BRK;
+      if (emitInfo->EmitCondCodes) {
+         /* Get the writemask from the previous instruction which set
+          * the condcodes.  Use that writemask as the CondSwizzle.
+          */
+         const GLuint condWritemask = inst->DstReg.WriteMask;
+         inst = new_instruction(emitInfo, opcode);
+         if (inst) {
+            inst->DstReg.CondMask = COND_NE;
+            inst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
+         }
+         return inst;
+      }
+      else {
+         /* IF reg
+          *    BRK/CONT;
+          * ENDIF
+          */
+         GLint ifInstLoc;
+         ifInstLoc = emitInfo->prog->NumInstructions;
+         inst = emit_instruction(emitInfo, OPCODE_IF,
+                                 NULL, /* dest */
+                                 n->Children[0]->Store,
+                                 NULL,
+                                 NULL);
+         if (!inst) {
+            return NULL;
+         }
+         n->InstLocation = emitInfo->prog->NumInstructions;
+
+         inst = new_instruction(emitInfo, opcode);
+         if (!inst) {
+            return NULL;
+         }
+         inst = new_instruction(emitInfo, OPCODE_ENDIF);
+         if (!inst) {
+            return NULL;
+         }
+
+         emitInfo->prog->Instructions[ifInstLoc].BranchTarget
+            = emitInfo->prog->NumInstructions - 1;
+         return inst;
+      }
+   }
+   else {
+      const GLuint condWritemask = inst->DstReg.WriteMask;
+      assert(emitInfo->EmitCondCodes);
+      inst = new_instruction(emitInfo, OPCODE_BRA);
+      if (inst) {
+         inst->DstReg.CondMask = COND_NE;
+         inst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask);
+      }
+      return inst;
+   }
+}
+
+
+/**
+ * Return the size of a swizzle mask given that some swizzle components
+ * may be NIL/undefined.  For example:
+ *  swizzle_size(".zzxx") = 4
+ *  swizzle_size(".xy??") = 2
+ *  swizzle_size(".w???") = 1
+ */
+static GLuint
+swizzle_size(GLuint swizzle)
+{
+   GLuint i;
+   for (i = 0; i < 4; i++) {
+      if (GET_SWZ(swizzle, i) == SWIZZLE_NIL)
+         return i;
+   }
+   return 4;
+}
+
+
+static struct prog_instruction *
+emit_swizzle(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   struct prog_instruction *inst;
+
+   inst = emit(emitInfo, n->Children[0]);
+
+   if (!n->Store->Parent) {
+      /* this covers a case such as "(b ? p : q).x" */
+      n->Store->Parent = n->Children[0]->Store;
+      assert(n->Store->Parent);
+   }
+
+   {
+      const GLuint swizzle = n->Store->Swizzle;
+      /* new storage is parent storage with updated Swizzle + Size fields */
+      _slang_copy_ir_storage(n->Store, n->Store->Parent);
+      /* Apply this node's swizzle to parent's storage */
+      n->Store->Swizzle = _slang_swizzle_swizzle(n->Store->Swizzle, swizzle);
+      /* Update size */
+      n->Store->Size = swizzle_size(n->Store->Swizzle);
+   }
+
+   assert(!n->Store->Parent);
+   assert(n->Store->Index >= 0);
+
+   return inst;
+}
+
+
+/**
+ * Dereference array element:  element == array[index]
+ * This basically involves emitting code for computing the array index
+ * and updating the node/element's storage info.
+ */
+static struct prog_instruction *
+emit_array_element(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   slang_ir_storage *arrayStore, *indexStore;
+   const int elemSize = n->Store->Size;           /* number of floats */
+   const GLint elemSizeVec = (elemSize + 3) / 4;  /* number of vec4 */
+   struct prog_instruction *inst;
+
+   assert(n->Opcode == IR_ELEMENT);
+   assert(elemSize > 0);
+
+   /* special case for built-in state variables, like light state */
+   {
+      slang_ir_storage *root = n->Store;
+      assert(!root->Parent);
+      while (root->Parent)
+         root = root->Parent;
+
+      if (root->File == PROGRAM_STATE_VAR) {
+         GLboolean direct;
+         GLint index =
+            _slang_alloc_statevar(n, emitInfo->prog->Parameters, &direct);
+         if (index < 0) {
+            /* error */
+            return NULL;
+         }
+         if (direct) {
+            n->Store->Index = index;
+            return NULL; /* all done */
+         }
+      }
+   }
+
+   /* do codegen for array itself */
+   emit(emitInfo, n->Children[0]);
+   arrayStore = n->Children[0]->Store;
+
+   /* The initial array element storage is the array's storage,
+    * then modified below.
+    */
+   _slang_copy_ir_storage(n->Store, arrayStore);
+
+
+   if (n->Children[1]->Opcode == IR_FLOAT) {
+      /* Constant array index */
+      const GLint element = (GLint) n->Children[1]->Value[0];
+
+      /* this element's storage is the array's storage, plus constant offset */
+      n->Store->Index += elemSizeVec * element;
+   }
+   else {
+      /* Variable array index */
+
+      /* do codegen for array index expression */
+      emit(emitInfo, n->Children[1]);
+      indexStore = n->Children[1]->Store;
+
+      if (indexStore->IsIndirect) {
+         /* need to put the array index into a temporary since we can't
+          * directly support a[b[i]] constructs.
+          */
+
+
+         /*indexStore = tempstore();*/
+      }
+
+
+      if (elemSize > 4) {
+         /* need to multiply array index by array element size */
+         struct prog_instruction *inst;
+         slang_ir_storage *indexTemp;
+         slang_ir_storage elemSizeStore;
+
+         /* allocate 1 float indexTemp */
+         indexTemp = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, 1);
+         _slang_alloc_temp(emitInfo->vt, indexTemp);
+
+         /* allocate a constant containing the element size */
+         constant_to_storage(emitInfo, (float) elemSizeVec, &elemSizeStore);
+
+         /* multiply array index by element size */
+         inst = emit_instruction(emitInfo,
+                                 OPCODE_MUL,
+                                 indexTemp, /* dest */
+                                 indexStore, /* the index */
+                                 &elemSizeStore,
+                                 NULL);
+         if (!inst) {
+            return NULL;
+         }
+
+         indexStore = indexTemp;
+      }
+
+      if (arrayStore->IsIndirect) {
+         /* ex: in a[i][j], a[i] (the arrayStore) is indirect */
+         /* Need to add indexStore to arrayStore->Indirect store */
+         slang_ir_storage indirectArray;
+         slang_ir_storage *indexTemp;
+
+         _slang_init_ir_storage(&indirectArray,
+                                arrayStore->IndirectFile,
+                                arrayStore->IndirectIndex,
+                                1,
+                                arrayStore->IndirectSwizzle);
+
+         /* allocate 1 float indexTemp */
+         indexTemp = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, 1);
+         _slang_alloc_temp(emitInfo->vt, indexTemp);
+
+         inst = emit_instruction(emitInfo,
+                                 OPCODE_ADD,
+                                 indexTemp,      /* dest */
+                                 indexStore,     /* the index */
+                                 &indirectArray, /* indirect array base */
+                                 NULL);
+         if (!inst) {
+            return NULL;
+         }
+
+         indexStore = indexTemp;
+      }
+
+      /* update the array element storage info */
+      n->Store->IsIndirect = GL_TRUE;
+      n->Store->IndirectFile = indexStore->File;
+      n->Store->IndirectIndex = indexStore->Index;
+      n->Store->IndirectSwizzle = indexStore->Swizzle;
+   }
+
+   n->Store->Size = elemSize;
+   n->Store->Swizzle = _slang_var_swizzle(elemSize, 0);
+
+   return NULL; /* no instruction */
+}
+
+
+/**
+ * Resolve storage for accessing a structure field.
+ */
+static struct prog_instruction *
+emit_struct_field(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   slang_ir_storage *root = n->Store;
+   GLint fieldOffset, fieldSize;
+
+   assert(n->Opcode == IR_FIELD);
+
+   assert(!root->Parent);
+   while (root->Parent)
+      root = root->Parent;
+
+   /* If this is the field of a state var, allocate constant/uniform
+    * storage for it now if we haven't already.
+    * Note that we allocate storage (uniform/constant slots) for state
+    * variables here rather than at declaration time so we only allocate
+    * space for the ones that we actually use!
+    */
+   if (root->File == PROGRAM_STATE_VAR) {
+      GLboolean direct;
+      GLint index = _slang_alloc_statevar(n, emitInfo->prog->Parameters, &direct);
+      if (index < 0) {
+         slang_info_log_error(emitInfo->log, "Error parsing state variable");
+         return NULL;
+      }
+      if (direct) {
+         root->Index = index;
+         return NULL; /* all done */
+      }
+   }
+
+   /* do codegen for struct */
+   emit(emitInfo, n->Children[0]);
+   assert(n->Children[0]->Store->Index >= 0);
+
+
+   fieldOffset = n->Store->Index;
+   fieldSize = n->Store->Size;
+
+   _slang_copy_ir_storage(n->Store, n->Children[0]->Store);
+
+   n->Store->Index = n->Children[0]->Store->Index + fieldOffset / 4;
+   n->Store->Size = fieldSize;
+
+   switch (fieldSize) {
+   case 1:
+      {
+         GLint swz = fieldOffset % 4;
+         n->Store->Swizzle = MAKE_SWIZZLE4(swz, swz, swz, swz);
+      }
+      break;
+   case 2:
+      n->Store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
+                                        SWIZZLE_NIL, SWIZZLE_NIL);
+      break;
+   case 3:
+      n->Store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y,
+                                        SWIZZLE_Z, SWIZZLE_NIL);
+      break;
+   default:
+      n->Store->Swizzle = SWIZZLE_XYZW;
+   }
+
+   assert(n->Store->Index >= 0);
+
+   return NULL; /* no instruction */
+}
+
+
+/**
+ * Emit code for a variable declaration.
+ * This usually doesn't result in any code generation, but just
+ * memory allocation.
+ */
+static struct prog_instruction *
+emit_var_decl(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   assert(n->Store);
+   assert(n->Store->File != PROGRAM_UNDEFINED);
+   assert(n->Store->Size > 0);
+   /*assert(n->Store->Index < 0);*/
+
+   if (!n->Var || n->Var->isTemp) {
+      /* a nameless/temporary variable, will be freed after first use */
+      /*NEW*/
+      if (n->Store->Index < 0 && !_slang_alloc_temp(emitInfo->vt, n->Store)) {
+         slang_info_log_error(emitInfo->log,
+                              "Ran out of registers, too many temporaries");
+         return NULL;
+      }
+   }
+   else {
+      /* a regular variable */
+      _slang_add_variable(emitInfo->vt, n->Var);
+      if (!_slang_alloc_var(emitInfo->vt, n->Store)) {
+         slang_info_log_error(emitInfo->log,
+                              "Ran out of registers, too many variables");
+         return NULL;
+      }
+      /*
+        printf("IR_VAR_DECL %s %d store %p\n",
+        (char*) n->Var->a_name, n->Store->Index, (void*) n->Store);
+      */
+      assert(n->Var->store == n->Store);
+   }
+   if (emitInfo->EmitComments) {
+      /* emit NOP with comment describing the variable's storage location */
+      char s[1000];
+      _mesa_snprintf(s, sizeof(s), "TEMP[%d]%s = variable %s (size %d)",
+                     n->Store->Index,
+                     _mesa_swizzle_string(n->Store->Swizzle, 0, GL_FALSE), 
+                     (n->Var ? (char *) n->Var->a_name : "anonymous"),
+                     n->Store->Size);
+      emit_comment(emitInfo, s);
+   }
+   return NULL;
+}
+
+
+/**
+ * Emit code for a reference to a variable.
+ * Actually, no code is generated but we may do some memory allocation.
+ * In particular, state vars (uniforms) are allocated on an as-needed basis.
+ */
+static struct prog_instruction *
+emit_var_ref(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   assert(n->Store);
+   assert(n->Store->File != PROGRAM_UNDEFINED);
+
+   if (n->Store->File == PROGRAM_STATE_VAR && n->Store->Index < 0) {
+      GLboolean direct;
+      GLint index = _slang_alloc_statevar(n, emitInfo->prog->Parameters, &direct);
+      if (index < 0) {
+         /* error */
+         char s[100];
+         /* XXX isn't this really an out of memory/resources error? */
+         _mesa_snprintf(s, sizeof(s), "Undefined variable '%s'",
+                 (char *) n->Var->a_name);
+         slang_info_log_error(emitInfo->log, s);
+         return NULL;
+      }
+
+      n->Store->Index = index;
+   }
+   else if (n->Store->File == PROGRAM_UNIFORM ||
+            n->Store->File == PROGRAM_SAMPLER) {
+      /* mark var as used */
+      _mesa_use_uniform(emitInfo->prog->Parameters, (char *) n->Var->a_name);
+   }
+   else if (n->Store->File == PROGRAM_INPUT) {
+      assert(n->Store->Index >= 0);
+      /* geometry shaders have the input index in the second
+       * index */
+      if (emitInfo->prog->Target == MESA_GEOMETRY_PROGRAM &&
+          n->Store->Is2D) {
+         emitInfo->prog->InputsRead |= (1 << n->Store->Index2);
+      } else
+         emitInfo->prog->InputsRead |= (1 << n->Store->Index);
+   }
+
+   if (n->Store->Index < 0) {
+      /* probably ran out of registers */
+      return NULL;
+   }
+   assert(n->Store->Size > 0);
+
+   return NULL;
+}
+
+
+static struct prog_instruction *
+emit(slang_emit_info *emitInfo, slang_ir_node *n)
+{
+   struct prog_instruction *inst;
+   if (!n)
+      return NULL;
+
+   if (emitInfo->log->error_flag) {
+      return NULL;
+   }
+
+   if (n->Comment) {
+      inst = new_instruction(emitInfo, OPCODE_NOP);
+      if (inst) {
+         inst->Comment = _mesa_strdup(n->Comment);
+      }
+      inst = NULL;
+   }
+
+   switch (n->Opcode) {
+   case IR_SEQ:
+      /* sequence of two sub-trees */
+      assert(n->Children[0]);
+      assert(n->Children[1]);
+      emit(emitInfo, n->Children[0]);
+      if (emitInfo->log->error_flag)
+         return NULL;
+      inst = emit(emitInfo, n->Children[1]);
+#if 0
+      assert(!n->Store);
+#endif
+      if (n->Children[1]->Store)
+         n->Store = n->Children[1]->Store;
+      else
+         n->Store = n->Children[0]->Store;
+      return inst;
+
+   case IR_SCOPE:
+      /* new variable scope */
+      _slang_push_var_table(emitInfo->vt);
+      inst = emit(emitInfo, n->Children[0]);
+      _slang_pop_var_table(emitInfo->vt);
+      n->Store = n->Children[0]->Store;
+      return inst;
+
+   case IR_VAR_DECL:
+      /* Variable declaration - allocate a register for it */
+      inst = emit_var_decl(emitInfo, n);
+      return inst;
+
+   case IR_VAR:
+      /* Reference to a variable
+       * Storage should have already been resolved/allocated.
+       */
+      return emit_var_ref(emitInfo, n);
+
+   case IR_ELEMENT:
+      return emit_array_element(emitInfo, n);
+   case IR_FIELD:
+      return emit_struct_field(emitInfo, n);
+   case IR_SWIZZLE:
+      return emit_swizzle(emitInfo, n);
+
+   /* Simple arithmetic */
+   /* unary */
+   case IR_MOVE:
+   case IR_RSQ:
+   case IR_RCP:
+   case IR_FLOOR:
+   case IR_FRAC:
+   case IR_F_TO_I:
+   case IR_I_TO_F:
+   case IR_ABS:
+   case IR_SIN:
+   case IR_COS:
+   case IR_DDX:
+   case IR_DDY:
+   case IR_EXP:
+   case IR_EXP2:
+   case IR_LOG2:
+   case IR_NOISE1:
+   case IR_NOISE2:
+   case IR_NOISE3:
+   case IR_NOISE4:
+   case IR_NRM4:
+   case IR_NRM3:
+   /* binary */
+   case IR_ADD:
+   case IR_SUB:
+   case IR_MUL:
+   case IR_DOT4:
+   case IR_DOT3:
+   case IR_DOT2:
+   case IR_CROSS:
+   case IR_MIN:
+   case IR_MAX:
+   case IR_SEQUAL:
+   case IR_SNEQUAL:
+   case IR_SGE:
+   case IR_SGT:
+   case IR_SLE:
+   case IR_SLT:
+   case IR_POW:
+   /* trinary operators */
+   case IR_LRP:
+   case IR_CMP:
+      return emit_arith(emitInfo, n);
+
+   case IR_EQUAL:
+   case IR_NOTEQUAL:
+      return emit_compare(emitInfo, n);
+
+   case IR_CLAMP:
+      return emit_clamp(emitInfo, n);
+   case IR_TEX:
+   case IR_TEXB:
+   case IR_TEXP:
+   case IR_TEX_SH:
+   case IR_TEXB_SH:
+   case IR_TEXP_SH:
+      return emit_tex(emitInfo, n);
+   case IR_NEG:
+      return emit_negation(emitInfo, n);
+   case IR_FLOAT:
+      /* find storage location for this float constant */
+      n->Store->Index = _mesa_add_unnamed_constant(emitInfo->prog->Parameters,
+                                                   n->Value,
+                                                   n->Store->Size,
+                                                   &n->Store->Swizzle);
+      if (n->Store->Index < 0) {
+         slang_info_log_error(emitInfo->log, "Ran out of space for constants");
+         return NULL;
+      }
+      return NULL;
+
+   case IR_COPY:
+      return emit_copy(emitInfo, n);
+
+   case IR_COND:
+      return emit_cond(emitInfo, n);
+
+   case IR_NOT:
+      return emit_not(emitInfo, n);
+
+   case IR_LABEL:
+      return emit_label(emitInfo, n);
+
+   case IR_KILL:
+      return emit_kill(emitInfo);
+
+   case IR_CALL:
+      /* new variable scope for subroutines/function calls */
+      _slang_push_var_table(emitInfo->vt);
+      inst = emit_fcall(emitInfo, n);
+      _slang_pop_var_table(emitInfo->vt);
+      return inst;
+
+   case IR_IF:
+      return emit_if(emitInfo, n);
+
+   case IR_LOOP:
+      return emit_loop(emitInfo, n);
+   case IR_BREAK_IF_TRUE:
+   case IR_CONT_IF_TRUE:
+      return emit_cont_break_if_true(emitInfo, n);
+   case IR_BREAK:
+      /* fall-through */
+   case IR_CONT:
+      return emit_cont_break(emitInfo, n);
+
+   case IR_BEGIN_SUB:
+      return new_instruction(emitInfo, OPCODE_BGNSUB);
+   case IR_END_SUB:
+      return new_instruction(emitInfo, OPCODE_ENDSUB);
+   case IR_RETURN:
+      return emit_return(emitInfo, n);
+
+   case IR_NOP:
+      return NULL;
+
+   case IR_EMIT_VERTEX:
+      return new_instruction(emitInfo, OPCODE_EMIT_VERTEX);
+   case IR_END_PRIMITIVE:
+      return new_instruction(emitInfo, OPCODE_END_PRIMITIVE);
+
+   default:
+      _mesa_problem(NULL, "Unexpected IR opcode in emit()\n");
+   }
+   return NULL;
+}
+
+
+/**
+ * After code generation, any subroutines will be in separate program
+ * objects.  This function appends all the subroutines onto the main
+ * program and resolves the linking of all the branch/call instructions.
+ * XXX this logic should really be part of the linking process...
+ */
+static void
+_slang_resolve_subroutines(slang_emit_info *emitInfo)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   struct gl_program *mainP = emitInfo->prog;
+   GLuint *subroutineLoc, i, total;
+
+   subroutineLoc
+      = (GLuint *) malloc(emitInfo->NumSubroutines * sizeof(GLuint));
+
+   /* total number of instructions */
+   total = mainP->NumInstructions;
+   for (i = 0; i < emitInfo->NumSubroutines; i++) {
+      subroutineLoc[i] = total;
+      total += emitInfo->Subroutines[i]->NumInstructions;
+   }
+
+   /* adjust BranchTargets within the functions */
+   for (i = 0; i < emitInfo->NumSubroutines; i++) {
+      struct gl_program *sub = emitInfo->Subroutines[i];
+      GLuint j;
+      for (j = 0; j < sub->NumInstructions; j++) {
+         struct prog_instruction *inst = sub->Instructions + j;
+         if (inst->Opcode != OPCODE_CAL && inst->BranchTarget >= 0) {
+            inst->BranchTarget += subroutineLoc[i];
+         }
+      }
+   }
+
+   /* append subroutines' instructions after main's instructions */
+   mainP->Instructions = _mesa_realloc_instructions(mainP->Instructions,
+                                                    mainP->NumInstructions,
+                                                    total);
+   mainP->NumInstructions = total;
+   for (i = 0; i < emitInfo->NumSubroutines; i++) {
+      struct gl_program *sub = emitInfo->Subroutines[i];
+      _mesa_copy_instructions(mainP->Instructions + subroutineLoc[i],
+                              sub->Instructions,
+                              sub->NumInstructions);
+      /* delete subroutine code */
+      sub->Parameters = NULL; /* prevent double-free */
+      _mesa_reference_program(ctx, &emitInfo->Subroutines[i], NULL);
+   }
+
+   /* free subroutine list */
+   if (emitInfo->Subroutines) {
+      free(emitInfo->Subroutines);
+      emitInfo->Subroutines = NULL;
+   }
+   emitInfo->NumSubroutines = 0;
+
+   /* Examine CAL instructions.
+    * 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.
+    */
+   for (i = 0; i < mainP->NumInstructions; i++) {
+      struct prog_instruction *inst = mainP->Instructions + i;
+      if (inst->Opcode == OPCODE_CAL) {
+         const GLuint f = inst->BranchTarget;
+         inst->BranchTarget = subroutineLoc[f];
+      }
+   }
+
+   free(subroutineLoc);
+}
+
+
+
+/**
+ * Convert the IR tree into GPU instructions.
+ * \param n  root of IR tree
+ * \param vt  variable table
+ * \param prog  program to put GPU instructions into
+ * \param pragmas  controls codegen options
+ * \param withEnd  if true, emit END opcode at end
+ * \param log  log for emitting errors/warnings/info
+ */
+GLboolean
+_slang_emit_code(slang_ir_node *n, slang_var_table *vt,
+                 struct gl_program *prog,
+                 const struct gl_sl_pragmas *pragmas,
+                 GLboolean withEnd,
+                 slang_info_log *log)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLboolean success;
+   slang_emit_info emitInfo;
+   GLuint maxUniforms;
+
+   emitInfo.log = log;
+   emitInfo.vt = vt;
+   emitInfo.prog = prog;
+   emitInfo.Subroutines = NULL;
+   emitInfo.NumSubroutines = 0;
+   emitInfo.MaxInstructions = prog->NumInstructions;
+
+   emitInfo.EmitHighLevelInstructions = ctx->Shader.EmitHighLevelInstructions;
+   emitInfo.EmitCondCodes = ctx->Shader.EmitCondCodes;
+   emitInfo.EmitComments = ctx->Shader.EmitComments || pragmas->Debug;
+   emitInfo.EmitBeginEndSub = GL_TRUE;
+
+   if (!emitInfo.EmitCondCodes) {
+      emitInfo.EmitHighLevelInstructions = GL_TRUE;
+   }      
+
+   /* Check uniform/constant limits */
+   if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
+      maxUniforms = ctx->Const.FragmentProgram.MaxUniformComponents / 4;
+   }
+   else if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
+      maxUniforms = ctx->Const.VertexProgram.MaxUniformComponents / 4;
+   } else {
+      assert(prog->Target == MESA_GEOMETRY_PROGRAM);
+      maxUniforms = ctx->Const.GeometryProgram.MaxUniformComponents / 4;
+   }
+   if (prog->Parameters->NumParameters > maxUniforms) {
+      slang_info_log_error(log, "Constant/uniform register limit exceeded "
+                           "(max=%u vec4)", maxUniforms);
+
+      return GL_FALSE;
+   }
+
+   (void) emit(&emitInfo, n);
+
+   /* finish up by adding the END opcode to program */
+   if (withEnd) {
+      struct prog_instruction *inst;
+      inst = new_instruction(&emitInfo, OPCODE_END);
+      if (!inst) {
+         return GL_FALSE;
+      }
+   }
+
+   _slang_resolve_subroutines(&emitInfo);
+
+   success = GL_TRUE;
+
+#if 0
+   printf("*********** End emit code (%u inst):\n", prog->NumInstructions);
+   _mesa_print_program(prog);
+   _mesa_print_program_parameters(ctx,prog);
+#endif
+
+   return success;
+}
diff --git a/src/mesa/slang/slang_emit.h b/src/mesa/slang/slang_emit.h
new file mode 100644 (file)
index 0000000..ab4c202
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.1
+ *
+ * Copyright (C) 2005-2008  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 SLANG_EMIT_H
+#define SLANG_EMIT_H
+
+
+#include "main/imports.h"
+#include "slang_compile.h"
+#include "slang_ir.h"
+#include "main/mtypes.h"
+
+
+extern GLuint
+_slang_swizzle_swizzle(GLuint swz1, GLuint swz2);
+
+
+extern GLuint
+_slang_var_swizzle(GLint size, GLint comp);
+
+
+extern GLboolean
+_slang_emit_code(slang_ir_node *n, slang_var_table *vartable,
+                 struct gl_program *prog,
+                 const struct gl_sl_pragmas *pragmas,
+                 GLboolean withEnd,
+                 slang_info_log *log);
+
+
+#endif /* SLANG_EMIT_H */
diff --git a/src/mesa/slang/slang_ir.c b/src/mesa/slang/slang_ir.c
new file mode 100644 (file)
index 0000000..078c936
--- /dev/null
@@ -0,0 +1,534 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2005-2008  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2009  VMware, 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
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "main/imports.h"
+#include "main/context.h"
+#include "slang_ir.h"
+#include "slang_mem.h"
+#include "program/prog_instruction.h"
+#include "program/prog_print.h"
+
+
+static const slang_ir_info IrInfo[] = {
+   /* binary ops */
+   { IR_ADD, "IR_ADD", OPCODE_ADD, 4, 2 },
+   { IR_SUB, "IR_SUB", OPCODE_SUB, 4, 2 },
+   { IR_MUL, "IR_MUL", OPCODE_MUL, 4, 2 },
+   { IR_DIV, "IR_DIV", OPCODE_NOP, 0, 2 }, /* XXX broke */
+   { IR_DOT4, "IR_DOT4", OPCODE_DP4, 1, 2 },
+   { IR_DOT3, "IR_DOT3", OPCODE_DP3, 1, 2 },
+   { IR_DOT2, "IR_DOT2", OPCODE_DP2, 1, 2 },
+   { IR_NRM4, "IR_NRM4", OPCODE_NRM4, 1, 1 },
+   { IR_NRM3, "IR_NRM3", OPCODE_NRM3, 1, 1 },
+   { IR_CROSS, "IR_CROSS", OPCODE_XPD, 3, 2 },
+   { IR_LRP, "IR_LRP", OPCODE_LRP, 4, 3 },
+   { IR_MIN, "IR_MIN", OPCODE_MIN, 4, 2 },
+   { IR_MAX, "IR_MAX", OPCODE_MAX, 4, 2 },
+   { IR_CLAMP, "IR_CLAMP", OPCODE_NOP, 4, 3 }, /* special case: emit_clamp() */
+   { IR_SEQUAL, "IR_SEQUAL", OPCODE_SEQ, 4, 2 },
+   { IR_SNEQUAL, "IR_SNEQUAL", OPCODE_SNE, 4, 2 },
+   { IR_SGE, "IR_SGE", OPCODE_SGE, 4, 2 },
+   { IR_SGT, "IR_SGT", OPCODE_SGT, 4, 2 },
+   { IR_SLE, "IR_SLE", OPCODE_SLE, 4, 2 },
+   { IR_SLT, "IR_SLT", OPCODE_SLT, 4, 2 },
+   { IR_POW, "IR_POW", OPCODE_POW, 1, 2 },
+   { IR_EQUAL, "IR_EQUAL", OPCODE_NOP, 1, 2 },
+   { IR_NOTEQUAL, "IR_NOTEQUAL", OPCODE_NOP, 1, 2 },
+
+   /* unary ops */
+   { IR_MOVE, "IR_MOVE", OPCODE_MOV, 4, 1 },
+   { IR_I_TO_F, "IR_I_TO_F", OPCODE_MOV, 4, 1 },  /* int[4] to float[4] */
+   { IR_F_TO_I, "IR_F_TO_I", OPCODE_TRUNC, 4, 1 },
+   { IR_EXP, "IR_EXP", OPCODE_EXP, 1, 1 },
+   { IR_EXP2, "IR_EXP2", OPCODE_EX2, 1, 1 },
+   { IR_LOG2, "IR_LOG2", OPCODE_LG2, 1, 1 },
+   { IR_RSQ, "IR_RSQ", OPCODE_RSQ, 1, 1 },
+   { IR_RCP, "IR_RCP", OPCODE_RCP, 1, 1 },
+   { IR_FLOOR, "IR_FLOOR", OPCODE_FLR, 4, 1 },
+   { IR_FRAC, "IR_FRAC", OPCODE_FRC, 4, 1 },
+   { IR_ABS, "IR_ABS", OPCODE_ABS, 4, 1 },
+   { IR_NEG, "IR_NEG", OPCODE_NOP, 4, 1 }, /* special case: emit_negation() */
+   { IR_DDX, "IR_DDX", OPCODE_DDX, 4, 1 },
+   { IR_DDY, "IR_DDY", OPCODE_DDY, 4, 1 },
+   { IR_SIN, "IR_SIN", OPCODE_SIN, 1, 1 },
+   { IR_COS, "IR_COS", OPCODE_COS, 1, 1 },
+   { IR_NOISE1, "IR_NOISE1", OPCODE_NOISE1, 1, 1 },
+   { IR_NOISE2, "IR_NOISE2", OPCODE_NOISE2, 1, 1 },
+   { IR_NOISE3, "IR_NOISE3", OPCODE_NOISE3, 1, 1 },
+   { IR_NOISE4, "IR_NOISE4", OPCODE_NOISE4, 1, 1 },
+
+   /* other */
+   { IR_CMP, "IR_CMP", OPCODE_CMP, 4, 3 },  /* compare/select */
+   { IR_SEQ, "IR_SEQ", OPCODE_NOP, 0, 0 },
+   { IR_SCOPE, "IR_SCOPE", OPCODE_NOP, 0, 0 },
+   { IR_LABEL, "IR_LABEL", OPCODE_NOP, 0, 0 },
+   { IR_IF, "IR_IF", OPCODE_NOP, 0, 0 },
+   { IR_KILL, "IR_KILL", OPCODE_NOP, 0, 0 },
+   { IR_COND, "IR_COND", OPCODE_NOP, 0, 0 },
+   { IR_CALL, "IR_CALL", OPCODE_NOP, 0, 0 },
+   { IR_COPY, "IR_COPY", OPCODE_NOP, 0, 1 },
+   { IR_NOT, "IR_NOT", OPCODE_NOP, 1, 1 },
+   { IR_VAR, "IR_VAR", OPCODE_NOP, 0, 0 },
+   { IR_VAR_DECL, "IR_VAR_DECL", OPCODE_NOP, 0, 0 },
+   { IR_TEX, "IR_TEX", OPCODE_TEX, 4, 1 },
+   { IR_TEXB, "IR_TEXB", OPCODE_TXB, 4, 1 },
+   { IR_TEXP, "IR_TEXP", OPCODE_TXP, 4, 1 },
+   { IR_TEX_SH, "IR_TEX_SH", OPCODE_TEX, 4, 1 },
+   { IR_TEXB_SH, "IR_TEXB_SH", OPCODE_TXB, 4, 1 },
+   { IR_TEXP_SH, "IR_TEXP_SH", OPCODE_TXP, 4, 1 },
+   { IR_FLOAT, "IR_FLOAT", OPCODE_NOP, 0, 0 }, /* float literal */
+   { IR_FIELD, "IR_FIELD", OPCODE_NOP, 0, 0 },
+   { IR_ELEMENT, "IR_ELEMENT", OPCODE_NOP, 0, 0 },
+   { IR_SWIZZLE, "IR_SWIZZLE", OPCODE_NOP, 0, 0 },
+   { IR_NOP, "IR_NOP", OPCODE_NOP, 0, 0 },
+   { IR_EMIT_VERTEX, "IR_EMIT_VERTEX", OPCODE_EMIT_VERTEX, 0, 0 },
+   { IR_END_PRIMITIVE, "IR_END_PRIMITIVE", OPCODE_END_PRIMITIVE, 0, 0 },
+   { 0, NULL, 0, 0, 0 }
+};
+
+
+const slang_ir_info *
+_slang_ir_info(slang_ir_opcode opcode)
+{
+   GLuint i;
+   for (i = 0; IrInfo[i].IrName; i++) {
+      if (IrInfo[i].IrOpcode == opcode) {
+        return IrInfo + i;
+      }
+   }
+   return NULL;
+}
+
+
+void
+_slang_init_ir_storage(slang_ir_storage *st,
+                       gl_register_file file, GLint index, GLint size,
+                       GLuint swizzle)
+{
+   st->File = file;
+   st->Index = index;
+   st->Size = size;
+   st->Swizzle = swizzle;
+   st->Parent = NULL;
+   st->IsIndirect = GL_FALSE;
+   st->Is2D = GL_FALSE;
+   st->Index2 = 0;
+}
+
+
+/**
+ * Return a new slang_ir_storage object.
+ */
+slang_ir_storage *
+_slang_new_ir_storage(gl_register_file file, GLint index, GLint size)
+{
+   slang_ir_storage *st;
+   st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage));
+   if (st) {
+      st->File = file;
+      st->Index = index;
+      st->Size = size;
+      st->Swizzle = SWIZZLE_NOOP;
+      st->Parent = NULL;
+      st->IsIndirect = GL_FALSE;
+      st->Is2D = GL_FALSE;
+      st->Index2 = 0;
+   }
+   return st;
+}
+
+
+/**
+ * Return a new slang_ir_storage object.
+ */
+slang_ir_storage *
+_slang_new_ir_storage_swz(gl_register_file file, GLint index, GLint size,
+                          GLuint swizzle)
+{
+   slang_ir_storage *st;
+   st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage));
+   if (st) {
+      st->File = file;
+      st->Index = index;
+      st->Size = size;
+      st->Swizzle = swizzle;
+      st->Parent = NULL;
+      st->IsIndirect = GL_FALSE;
+      st->Is2D = GL_FALSE;
+      st->Index2 = 0;
+   }
+   return st;
+}
+
+/**
+ * Return a new slang_ir_storage object.
+ */
+slang_ir_storage *
+_slang_new_ir_storage_2d(gl_register_file file,
+                         GLint index, GLint index2,
+                         GLint size, GLuint swizzle)
+{
+   slang_ir_storage *st;
+   st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage));
+   if (st) {
+      st->File = file;
+      st->Index = index;
+      st->Size = size;
+      st->Swizzle = swizzle;
+      st->Parent = NULL;
+      st->IsIndirect = GL_FALSE;
+      st->Is2D = GL_TRUE;
+      st->Index2 = index2;
+   }
+   return st;
+}
+
+
+
+/**
+ * Return a new slang_ir_storage object.
+ */
+slang_ir_storage *
+_slang_new_ir_storage_relative(GLint index, GLint size,
+                               slang_ir_storage *parent)
+{
+   slang_ir_storage *st;
+   st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage));
+   if (st) {
+      st->File = PROGRAM_UNDEFINED;
+      st->Index = index;
+      st->Size = size;
+      st->Swizzle = SWIZZLE_NOOP;
+      st->Parent = parent;
+      st->IsIndirect = GL_FALSE;
+      st->Is2D = GL_FALSE;
+      st->Index2 = 0;
+   }
+   return st;
+}
+
+
+slang_ir_storage *
+_slang_new_ir_storage_indirect(gl_register_file file,
+                               GLint index,
+                               GLint size,
+                               gl_register_file indirectFile,
+                               GLint indirectIndex,
+                               GLuint indirectSwizzle)
+{
+   slang_ir_storage *st;
+   st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage));
+   if (st) {
+      st->File = file;
+      st->Index = index;
+      st->Size = size;
+      st->Swizzle = SWIZZLE_NOOP;
+      st->IsIndirect = GL_TRUE;
+      st->IndirectFile = indirectFile;
+      st->IndirectIndex = indirectIndex;
+      st->IndirectSwizzle = indirectSwizzle;
+      st->Is2D = GL_FALSE;
+      st->Index2 = 0;
+   }
+   return st;
+}
+
+
+/**
+ * Allocate IR storage for a texture sampler.
+ * \param sampNum  the sampler number/index
+ * \param texTarget  one of TEXTURE_x_INDEX values
+ * \param size  number of samplers (in case of sampler array)
+ */
+slang_ir_storage *
+_slang_new_ir_storage_sampler(GLint sampNum, GLuint texTarget, GLint size)
+{
+   slang_ir_storage *st;
+   assert(texTarget < NUM_TEXTURE_TARGETS);
+   st = _slang_new_ir_storage(PROGRAM_SAMPLER, sampNum, size);
+   if (st) {
+      st->TexTarget = texTarget;
+   }
+   return st;
+}
+
+
+
+/* XXX temporary function */
+void
+_slang_copy_ir_storage(slang_ir_storage *dst, const slang_ir_storage *src)
+{
+   *dst = *src;
+   dst->Parent = NULL;
+}
+
+
+
+static const char *
+_slang_ir_name(slang_ir_opcode opcode)
+{
+   return _slang_ir_info(opcode)->IrName;
+}
+
+
+
+#if 0 /* no longer needed with mempool */
+/**
+ * Since many IR nodes might point to the same IR storage info, we need
+ * to be careful when deleting things.
+ * Before deleting an IR tree, traverse it and do refcounting on the
+ * IR storage nodes.  Use the refcount info during delete to free things
+ * properly.
+ */
+static void
+_slang_refcount_storage(slang_ir_node *n)
+{
+   GLuint i;
+   if (!n)
+      return;
+   if (n->Store)
+      n->Store->RefCount++;
+   for (i = 0; i < 3; i++)
+      _slang_refcount_storage(n->Children[i]);
+}
+#endif
+
+
+static void
+_slang_free_ir(slang_ir_node *n)
+{
+   GLuint i;
+   if (!n)
+      return;
+
+#if 0
+   if (n->Store) {
+      n->Store->RefCount--;
+      if (n->Store->RefCount == 0) {
+         _slang_free(n->Store);
+         n->Store = NULL;
+      }
+   }
+#endif
+
+   for (i = 0; i < 3; i++)
+      _slang_free_ir(n->Children[i]);
+   /* Do not free n->List since it's a child elsewhere */
+   _slang_free(n);
+}
+
+
+/**
+ * Recursively free an IR tree.
+ */
+void
+_slang_free_ir_tree(slang_ir_node *n)
+{
+#if 0
+   _slang_refcount_storage(n);
+#endif
+   _slang_free_ir(n);
+}
+
+
+static const char *
+storage_string(const slang_ir_storage *st)
+{
+   static const char *files[] = {
+      "TEMP",
+      "LOCAL_PARAM",
+      "ENV_PARAM",
+      "STATE",
+      "INPUT",
+      "OUTPUT",
+      "NAMED_PARAM",
+      "CONSTANT",
+      "UNIFORM",
+      "VARYING",
+      "WRITE_ONLY",
+      "ADDRESS",
+      "SAMPLER",
+      "UNDEFINED"
+   };
+   static char s[100];
+   assert(Elements(files) == PROGRAM_FILE_MAX);
+#if 0
+   if (st->Size == 1)
+      _mesa_snprintf(s, "%s[%d]", files[st->File], st->Index);
+   else
+      _mesa_snprintf(s, "%s[%d..%d]", files[st->File], st->Index,
+                     st->Index + st->Size - 1);
+#endif
+   assert(st->File < (GLint) (sizeof(files) / sizeof(files[0])));
+   _mesa_snprintf(s, sizeof(s), "%s[%d]", files[st->File], st->Index);
+   return s;
+}
+
+
+static void
+spaces(int n)
+{
+   while (n-- > 0) {
+      printf(" ");
+   }
+}
+
+
+void
+_slang_print_ir_tree(const slang_ir_node *n, int indent)
+{
+#define IND 0
+
+   if (!n)
+      return;
+#if !IND
+   if (n->Opcode != IR_SEQ)
+#else
+      printf("%3d:", indent);
+#endif
+      spaces(indent);
+
+   switch (n->Opcode) {
+   case IR_SEQ:
+#if IND
+      printf("SEQ  at %p\n", (void*) n);
+#endif
+      assert(n->Children[0]);
+      assert(n->Children[1]);
+      _slang_print_ir_tree(n->Children[0], indent + IND);
+      _slang_print_ir_tree(n->Children[1], indent + IND);
+      break;
+   case IR_SCOPE:
+      printf("NEW SCOPE\n");
+      assert(!n->Children[1]);
+      _slang_print_ir_tree(n->Children[0], indent + 3);
+      break;
+   case IR_COPY:
+      printf("COPY\n");
+      _slang_print_ir_tree(n->Children[0], indent+3);
+      _slang_print_ir_tree(n->Children[1], indent+3);
+      break;
+   case IR_LABEL:
+      printf("LABEL: %s\n", n->Label->Name);
+      break;
+   case IR_COND:
+      printf("COND\n");
+      _slang_print_ir_tree(n->Children[0], indent + 3);
+      break;
+
+   case IR_IF:
+      printf("IF \n");
+      _slang_print_ir_tree(n->Children[0], indent+3);
+      spaces(indent);
+      printf("THEN\n");
+      _slang_print_ir_tree(n->Children[1], indent+3);
+      if (n->Children[2]) {
+         spaces(indent);
+         printf("ELSE\n");
+         _slang_print_ir_tree(n->Children[2], indent+3);
+      }
+      spaces(indent);
+      printf("ENDIF\n");
+      break;
+
+   case IR_BEGIN_SUB:
+      printf("BEGIN_SUB\n");
+      break;
+   case IR_END_SUB:
+      printf("END_SUB\n");
+      break;
+   case IR_RETURN:
+      printf("RETURN\n");
+      break;
+   case IR_CALL:
+      printf("CALL %s\n", n->Label->Name);
+      break;
+
+   case IR_LOOP:
+      printf("LOOP\n");
+      _slang_print_ir_tree(n->Children[0], indent+3);
+      if (n->Children[1]) {
+         spaces(indent);
+         printf("TAIL:\n");
+         _slang_print_ir_tree(n->Children[1], indent+3);
+      }
+      spaces(indent);
+      printf("ENDLOOP\n");
+      break;
+   case IR_CONT:
+      printf("CONT\n");
+      break;
+   case IR_BREAK:
+      printf("BREAK\n");
+      break;
+   case IR_BREAK_IF_TRUE:
+      printf("BREAK_IF_TRUE\n");
+      _slang_print_ir_tree(n->Children[0], indent+3);
+      break;
+   case IR_CONT_IF_TRUE:
+      printf("CONT_IF_TRUE\n");
+      _slang_print_ir_tree(n->Children[0], indent+3);
+      break;
+
+   case IR_VAR:
+      printf("VAR %s%s at %s  store %p\n",
+             (n->Var ? (char *) n->Var->a_name : "TEMP"),
+             _mesa_swizzle_string(n->Store->Swizzle, 0, 0),
+             storage_string(n->Store), (void*) n->Store);
+      break;
+   case IR_VAR_DECL:
+      printf("VAR_DECL %s (%p) at %s  store %p\n",
+             (n->Var ? (char *) n->Var->a_name : "TEMP"),
+             (void*) n->Var, storage_string(n->Store),
+             (void*) n->Store);
+      break;
+   case IR_FIELD:
+      printf("FIELD %s of\n", n->Field);
+      _slang_print_ir_tree(n->Children[0], indent+3);
+      break;
+   case IR_FLOAT:
+      printf("FLOAT %g %g %g %g\n",
+             n->Value[0], n->Value[1], n->Value[2], n->Value[3]);
+      break;
+   case IR_I_TO_F:
+      printf("INT_TO_FLOAT\n");
+      _slang_print_ir_tree(n->Children[0], indent+3);
+      break;
+   case IR_F_TO_I:
+      printf("FLOAT_TO_INT\n");
+      _slang_print_ir_tree(n->Children[0], indent+3);
+      break;
+   case IR_SWIZZLE:
+      printf("SWIZZLE %s of  (store %p) \n",
+             _mesa_swizzle_string(n->Store->Swizzle, 0, 0), (void*) n->Store);
+      _slang_print_ir_tree(n->Children[0], indent + 3);
+      break;
+   default:
+      printf("%s (%p, %p)  (store %p)\n", _slang_ir_name(n->Opcode),
+             (void*) n->Children[0], (void*) n->Children[1], (void*) n->Store);
+      _slang_print_ir_tree(n->Children[0], indent+3);
+      _slang_print_ir_tree(n->Children[1], indent+3);
+   }
+}
diff --git a/src/mesa/slang/slang_ir.h b/src/mesa/slang/slang_ir.h
new file mode 100644 (file)
index 0000000..b7a3737
--- /dev/null
@@ -0,0 +1,292 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2005-2008  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2009  VMware, 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
+ * 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 slang_ir.h
+ * Mesa GLSL Intermediate Representation tree types and constants.
+ * \author Brian Paul
+ */
+
+
+#ifndef SLANG_IR_H
+#define SLANG_IR_H
+
+
+#include "main/imports.h"
+#include "slang_compile.h"
+#include "slang_label.h"
+#include "main/mtypes.h"
+
+
+/**
+ * Intermediate Representation opcodes
+ */
+typedef enum
+{
+   IR_NOP = 0,
+   IR_SEQ,     /* sequence (eval left, then right) */
+   IR_SCOPE,   /* new variable scope (one child) */
+
+   IR_LABEL,   /* target of a jump or cjump */
+
+   IR_COND,    /* conditional expression/predicate */
+
+   IR_IF,      /* high-level IF/then/else */
+               /* Children[0] = conditional expression */
+               /* Children[1] = if-true part */
+               /* Children[2] = if-else part, or NULL */
+
+   IR_BEGIN_SUB, /* begin subroutine */
+   IR_END_SUB,   /* end subroutine */
+   IR_RETURN,    /* return from subroutine */
+   IR_CALL,      /* call subroutine */
+
+   IR_LOOP,      /* high-level loop-begin / loop-end */
+                 /* Children[0] = loop body */
+                 /* Children[1] = loop tail code, or NULL */
+
+   IR_CONT,      /* continue loop */
+                 /* n->Parent = ptr to parent IR_LOOP Node */
+   IR_BREAK,     /* break loop */
+
+   IR_BREAK_IF_TRUE, /**< Children[0] = the condition expression */
+   IR_CONT_IF_TRUE,
+
+   IR_COPY,       /**< assignment/copy */
+   IR_MOVE,       /**< assembly MOV instruction */
+
+   /* vector ops: */
+   IR_ADD,        /**< assembly ADD instruction */
+   IR_SUB,
+   IR_MUL,
+   IR_DIV,
+   IR_DOT4,
+   IR_DOT3,
+   IR_DOT2,
+   IR_NRM4,
+   IR_NRM3,
+   IR_CROSS,   /* vec3 cross product */
+   IR_LRP,
+   IR_CLAMP,
+   IR_MIN,
+   IR_MAX,
+   IR_CMP,     /* = (op0 < 0) ? op1 : op2 */
+   IR_SEQUAL,  /* Set if args are equal (vector) */
+   IR_SNEQUAL, /* Set if args are not equal (vector) */
+   IR_SGE,     /* Set if greater or equal (vector) */
+   IR_SGT,     /* Set if greater than (vector) */
+   IR_SLE,     /* Set if less or equal (vector) */
+   IR_SLT,     /* Set if less than (vector) */
+   IR_POW,     /* x^y */
+   IR_EXP,     /* e^x */
+   IR_EXP2,    /* 2^x */
+   IR_LOG2,    /* log base 2 */
+   IR_RSQ,     /* 1/sqrt() */
+   IR_RCP,     /* reciprocol */
+   IR_FLOOR,
+   IR_FRAC,
+   IR_ABS,     /* absolute value */
+   IR_NEG,     /* negate */
+   IR_DDX,     /* derivative w.r.t. X */
+   IR_DDY,     /* derivative w.r.t. Y */
+   IR_SIN,     /* sine */
+   IR_COS,     /* cosine */
+   IR_NOISE1,  /* noise(x) */
+   IR_NOISE2,  /* noise(x, y) */
+   IR_NOISE3,  /* noise(x, y, z) */
+   IR_NOISE4,  /* noise(x, y, z, w) */
+
+   IR_EQUAL,   /* boolean equality */
+   IR_NOTEQUAL,/* boolean inequality */
+   IR_NOT,     /* boolean not */
+
+   IR_VAR,     /* variable reference */
+   IR_VAR_DECL,/* var declaration */
+
+   IR_ELEMENT, /* array element */
+   IR_FIELD,   /* struct field */
+   IR_SWIZZLE, /* swizzled storage access */
+
+   IR_TEX,     /* texture lookup */
+   IR_TEXB,    /* texture lookup with LOD bias */
+   IR_TEXP,    /* texture lookup with projection */
+
+   IR_TEX_SH,     /* texture lookup, shadow compare */
+   IR_TEXB_SH,    /* texture lookup with LOD bias, shadow compare */
+   IR_TEXP_SH,    /* texture lookup with projection, shadow compare */
+
+   IR_FLOAT,
+   IR_I_TO_F,  /* int[4] to float[4] conversion */
+   IR_F_TO_I,  /* float[4] to int[4] conversion */
+
+   IR_KILL,     /* fragment kill/discard */
+
+   IR_EMIT_VERTEX,  /* geometry shader: emit vertex */
+   IR_END_PRIMITIVE /* geometry shader: end primitive */
+} slang_ir_opcode;
+
+
+/**
+ * Describes where data/variables are stored in the various register files.
+ *
+ * In the simple case, the File, Index and Size fields indicate where
+ * a variable is stored.  For example, a vec3 variable may be stored
+ * as (File=PROGRAM_TEMPORARY, Index=6, Size=3).  Or, File[Index].
+ * Or, a program input like color may be stored as
+ * (File=PROGRAM_INPUT,Index=3,Size=4);
+ *
+ * For single-float values, the Swizzle field indicates which component
+ * of the vector contains the float.
+ *
+ * If IsIndirect is set, the storage is accessed through an indirect
+ * register lookup.  The value in question will be located at:
+ *   File[Index + IndirectFile[IndirectIndex]]
+ *
+ * This is primary used for indexing arrays.  For example, consider this
+ * GLSL code:
+ *   uniform int i;
+ *   float a[10];
+ *   float x = a[i];
+ *
+ * here, storage for a[i] would be described by (File=PROGRAM_TEMPORAY,
+ * Index=aPos, IndirectFile=PROGRAM_UNIFORM, IndirectIndex=iPos), which
+ * would mean TEMP[aPos + UNIFORM[iPos]]
+ */
+struct slang_ir_storage_
+{
+   gl_register_file File;  /**< PROGRAM_TEMPORARY, PROGRAM_INPUT, etc */
+   GLint Index;    /**< -1 means unallocated */
+   GLint Size;     /**< number of floats or ints */
+   GLuint Swizzle; /**< Swizzle AND writemask info */
+   GLint RefCount; /**< Used during IR tree delete */
+
+   GLboolean RelAddr; /* we'll remove this eventually */
+
+   GLboolean IsIndirect;
+   gl_register_file IndirectFile;
+   GLint IndirectIndex;
+   GLuint IndirectSwizzle;
+   GLuint TexTarget;  /**< If File==PROGRAM_SAMPLER, one of TEXTURE_x_INDEX */
+
+   /* Is the register two-dimensional and
+    * if so what's the second index */
+   GLboolean Is2D;
+   GLint Index2;
+
+   /** If Parent is non-null, Index is relative to parent.
+    * The other fields are ignored.
+    */
+   struct slang_ir_storage_ *Parent;
+};
+
+typedef struct slang_ir_storage_ slang_ir_storage;
+
+
+/**
+ * Intermediate Representation (IR) tree node
+ * Basically a binary tree, but IR_LRP and IR_CLAMP have three children.
+ */
+typedef struct slang_ir_node_
+{
+   slang_ir_opcode Opcode;
+   struct slang_ir_node_ *Children[3];
+   slang_ir_storage *Store;  /**< location of result of this operation */
+   GLint InstLocation;  /**< Location of instruction emitted for this node */
+
+   /** special fields depending on Opcode: */
+   const char *Field;  /**< If Opcode == IR_FIELD */
+   GLfloat Value[4];    /**< If Opcode == IR_FLOAT */
+   slang_variable *Var;  /**< If Opcode == IR_VAR or IR_VAR_DECL */
+   struct slang_ir_node_ *List;  /**< For various linked lists */
+   struct slang_ir_node_ *Parent;  /**< Pointer to logical parent (ie. loop) */
+   slang_label *Label;  /**< Used for branches */
+   const char *Comment; /**< If Opcode == IR_COMMENT */
+} slang_ir_node;
+
+
+
+/**
+ * Assembly and IR info
+ */
+typedef struct
+{
+   slang_ir_opcode IrOpcode;
+   const char *IrName;
+   gl_inst_opcode InstOpcode;
+   GLuint ResultSize, NumParams;
+} slang_ir_info;
+
+
+
+extern const slang_ir_info *
+_slang_ir_info(slang_ir_opcode opcode);
+
+
+extern void
+_slang_init_ir_storage(slang_ir_storage *st,
+                       gl_register_file file, GLint index, GLint size,
+                       GLuint swizzle);
+
+extern slang_ir_storage *
+_slang_new_ir_storage(gl_register_file file, GLint index, GLint size);
+
+
+extern slang_ir_storage *
+_slang_new_ir_storage_swz(gl_register_file file, GLint index, GLint size,
+                          GLuint swizzle);
+
+extern slang_ir_storage *
+_slang_new_ir_storage_2d(gl_register_file file, GLint index, GLint index2d,
+                         GLint size, GLuint swizzle);
+
+extern slang_ir_storage *
+_slang_new_ir_storage_relative(GLint index, GLint size,
+                               slang_ir_storage *parent);
+
+
+extern slang_ir_storage *
+_slang_new_ir_storage_indirect(gl_register_file file,
+                               GLint index,
+                               GLint size,
+                               gl_register_file indirectFile,
+                               GLint indirectIndex,
+                               GLuint indirectSwizzle);
+
+extern slang_ir_storage *
+_slang_new_ir_storage_sampler(GLint sampNum, GLuint texTarget, GLint size);
+
+
+extern void
+_slang_copy_ir_storage(slang_ir_storage *dst, const slang_ir_storage *src);
+
+
+extern void
+_slang_free_ir_tree(slang_ir_node *n);
+
+
+extern void
+_slang_print_ir_tree(const slang_ir_node *n, int indent);
+
+
+#endif /* SLANG_IR_H */
diff --git a/src/mesa/slang/slang_label.c b/src/mesa/slang/slang_label.c
new file mode 100644 (file)
index 0000000..8e3a8eb
--- /dev/null
@@ -0,0 +1,104 @@
+
+
+/**
+ * Functions for managing instruction labels.
+ * Basically, this is used to manage the problem of forward branches where
+ * we have a branch instruciton but don't know the target address yet.
+ */
+
+
+#include "slang_label.h"
+#include "slang_mem.h"
+
+
+
+slang_label *
+_slang_label_new(const char *name)
+{
+   slang_label *l = (slang_label *) _slang_alloc(sizeof(slang_label));
+   if (l) {
+      l->Name = _slang_strdup(name);
+      l->Location = -1;
+   }
+   return l;
+}
+
+/**
+ * As above, but suffix the name with a unique number.
+ */
+slang_label *
+_slang_label_new_unique(const char *name)
+{
+   static int id = 1;
+   slang_label *l = (slang_label *) _slang_alloc(sizeof(slang_label));
+   if (l) {
+      l->Name = (char *) _slang_alloc(strlen(name) + 10);
+      if (!l->Name) {
+         free(l);
+         return NULL;
+      }
+      _mesa_snprintf(l->Name, strlen(name) + 10, "%s_%d", name, id);
+      id++;
+      l->Location = -1;
+   }
+   return l;
+}
+
+void
+_slang_label_delete(slang_label *l)
+{
+   if (l->Name) {
+      _slang_free(l->Name);
+      l->Name = NULL;
+   }
+   if (l->References) {
+      _slang_free(l->References);
+      l->References = NULL;
+   }
+   _slang_free(l);
+}
+
+
+void
+_slang_label_add_reference(slang_label *l, GLuint inst)
+{
+   const GLuint oldSize = l->NumReferences * sizeof(GLuint);
+   assert(l->Location < 0);
+   l->References = _slang_realloc(l->References,
+                                  oldSize, oldSize + sizeof(GLuint));
+   if (l->References) {
+      l->References[l->NumReferences] = inst;
+      l->NumReferences++;
+   }
+}
+
+
+GLint
+_slang_label_get_location(const slang_label *l)
+{
+   return l->Location;
+}
+
+
+void
+_slang_label_set_location(slang_label *l, GLint location,
+                          struct gl_program *prog)
+{
+   GLuint i;
+
+   assert(l->Location < 0);
+   assert(location >= 0);
+
+   l->Location = location;
+
+   /* for the instructions that were waiting to learn the label's location: */
+   for (i = 0; i < l->NumReferences; i++) {
+      const GLuint j = l->References[i];
+      prog->Instructions[j].BranchTarget = location;
+   }
+
+   if (l->References) {
+      _slang_free(l->References);
+      l->References = NULL;
+   }
+}
diff --git a/src/mesa/slang/slang_label.h b/src/mesa/slang/slang_label.h
new file mode 100644 (file)
index 0000000..4d04df1
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef SLANG_LABEL_H
+#define SLANG_LABEL_H 1
+
+#include "main/imports.h"
+#include "main/mtypes.h"
+#include "program/prog_instruction.h"
+
+
+struct slang_label_
+{
+   char *Name;
+   GLint Location;
+   /**
+    * List of instruction references (numbered starting at zero) which need
+    * their BranchTarget field filled in with the location eventually
+    * assigned to the label.
+    */
+   GLuint NumReferences;
+   GLuint *References;   /** Array [NumReferences] */
+};
+
+typedef struct slang_label_ slang_label;
+
+
+extern slang_label *
+_slang_label_new(const char *name);
+
+extern slang_label *
+_slang_label_new_unique(const char *name);
+
+extern void
+_slang_label_delete(slang_label *l);
+
+extern void
+_slang_label_add_reference(slang_label *l, GLuint inst);
+
+extern GLint
+_slang_label_get_location(const slang_label *l);
+
+extern void
+_slang_label_set_location(slang_label *l, GLint location,
+                          struct gl_program *prog);
+
+
+#endif /* SLANG_LABEL_H */
diff --git a/src/mesa/slang/slang_link.c b/src/mesa/slang/slang_link.c
new file mode 100644 (file)
index 0000000..00c2c13
--- /dev/null
@@ -0,0 +1,1280 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.3
+ *
+ * Copyright (C) 2008  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2009  VMware, 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
+ * 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 slang_link.c
+ * GLSL linker
+ * \author Brian Paul
+ */
+
+#include "main/imports.h"
+#include "main/context.h"
+#include "main/macros.h"
+#include "main/shaderapi.h"
+#include "main/shaderobj.h"
+#include "main/uniforms.h"
+#include "program/program.h"
+#include "program/prog_instruction.h"
+#include "program/prog_parameter.h"
+#include "program/prog_print.h"
+#include "program/prog_statevars.h"
+#include "program/prog_uniform.h"
+#include "slang_builtin.h"
+#include "slang_link.h"
+
+
+/** cast wrapper */
+static struct gl_vertex_program *
+vertex_program(struct gl_program *prog)
+{
+   assert(prog->Target == GL_VERTEX_PROGRAM_ARB);
+   return (struct gl_vertex_program *) prog;
+}
+
+
+/** cast wrapper */
+static struct gl_fragment_program *
+fragment_program(struct gl_program *prog)
+{
+   assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB);
+   return (struct gl_fragment_program *) prog;
+}
+
+static struct gl_geometry_program *
+geometry_program(struct gl_program *prog)
+{
+   assert(prog->Target == MESA_GEOMETRY_PROGRAM);
+   return (struct gl_geometry_program *)prog;
+}
+
+/**
+ * Record a linking error.
+ */
+static void
+link_error(struct gl_shader_program *shProg, const char *msg)
+{
+   if (shProg->InfoLog) {
+      free(shProg->InfoLog);
+   }
+   shProg->InfoLog = _mesa_strdup(msg);
+   shProg->LinkStatus = GL_FALSE;
+}
+
+
+
+/**
+ * Check if the given bit is either set or clear in both bitfields.
+ */
+static GLboolean
+bits_agree(GLbitfield flags1, GLbitfield flags2, GLbitfield bit)
+{
+   return (flags1 & bit) == (flags2 & bit);
+}
+
+
+/**
+ * Examine the outputs/varyings written by the vertex shader and
+ * append the names of those outputs onto the Varyings list.
+ * This will only capture the pre-defined/built-in varyings like
+ * gl_Position, not user-defined varyings.
+ */
+static void
+update_varying_var_list(GLcontext *ctx, struct gl_shader_program *shProg)
+{
+   if (shProg->VertexProgram) {
+      GLbitfield64 written = shProg->VertexProgram->Base.OutputsWritten;
+      GLuint i;
+      for (i = 0; written && i < VERT_RESULT_MAX; i++) {
+         if (written & BITFIELD64_BIT(i)) {
+            const char *name = _slang_vertex_output_name(i);            
+            if (name)
+               _mesa_add_varying(shProg->Varying, name, 1, GL_FLOAT_VEC4, 0x0);
+            written &= ~BITFIELD64_BIT(i);
+         }
+      }
+   }
+   if (shProg->GeometryProgram) {
+      GLbitfield64 written = shProg->GeometryProgram->Base.OutputsWritten;
+      GLuint i;
+      for (i = 0; written && i < GEOM_RESULT_MAX; i++) {
+         if (written & BITFIELD64_BIT(i)) {
+            const char *name = _slang_geometry_output_name(i);
+            if (name)
+               _mesa_add_varying(shProg->Varying, name, 1, GL_FLOAT_VEC4, 0x0);
+            written &= ~BITFIELD64_BIT(i);
+         }
+      }
+   }
+}
+
+
+/**
+ * Do link error checking related to transform feedback.
+ */
+static GLboolean
+link_transform_feedback(GLcontext *ctx, struct gl_shader_program *shProg)
+{
+   GLbitfield varyingMask;
+   GLuint totalComps, maxComps, i;
+
+   if (shProg->TransformFeedback.NumVarying == 0) {
+      /* nothing to do */
+      return GL_TRUE;
+   }
+
+   /* Check that there's a vertex shader */
+   if (shProg->TransformFeedback.NumVarying > 0 &&
+       !shProg->VertexProgram) {
+      link_error(shProg, "Transform feedback without vertex shader");
+      return GL_FALSE;
+   }
+
+   /* Check that all named variables exist, and that none are duplicated.
+    * Also, build a count of the number of varying components to feedback.
+    */
+   totalComps = 0;
+   varyingMask = 0x0;
+   for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
+      const GLchar *name = shProg->TransformFeedback.VaryingNames[i];
+      GLint v = _mesa_lookup_parameter_index(shProg->Varying, -1, name);
+      struct gl_program_parameter *p;
+
+      if (v < 0) {
+         char msg[100];
+         _mesa_snprintf(msg, sizeof(msg),
+                        "vertex shader does not emit %s", name);
+         link_error(shProg, msg);
+         return GL_FALSE;
+      }
+
+      assert(v < MAX_VARYING);
+
+      /* already seen this varying name? */
+      if (varyingMask & (1 << v)) {
+         char msg[100];
+         _mesa_snprintf(msg, sizeof(msg),
+                        "duplicated transform feedback varying name: %s",
+                        name);
+         link_error(shProg, msg);
+         return GL_FALSE;
+      }
+
+      varyingMask |= (1 << v);
+
+      p = &shProg->Varying->Parameters[v];
+      
+      totalComps += _mesa_sizeof_glsl_type(p->DataType);
+   }
+
+   if (shProg->TransformFeedback.BufferMode == GL_INTERLEAVED_ATTRIBS)
+      maxComps = ctx->Const.MaxTransformFeedbackInterleavedComponents;
+   else
+      maxComps = ctx->Const.MaxTransformFeedbackSeparateComponents;
+
+   /* check max varying components against the limit */
+   if (totalComps > maxComps) {
+      char msg[100];
+      _mesa_snprintf(msg, sizeof(msg),
+                     "Too many feedback components: %u, max is %u",
+                     totalComps, maxComps);
+      link_error(shProg, msg);
+      return GL_FALSE;
+   }
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Linking varying vars involves rearranging varying vars so that the
+ * vertex program's output varyings matches the order of the fragment
+ * program's input varyings.
+ * We'll then rewrite instructions to replace PROGRAM_VARYING with either
+ * PROGRAM_INPUT or PROGRAM_OUTPUT depending on whether it's a vertex or
+ * fragment shader.
+ * This is also where we set program Input/OutputFlags to indicate
+ * which inputs are centroid-sampled, invariant, etc.
+ */
+static GLboolean
+link_varying_vars(GLcontext *ctx,
+                  struct gl_shader_program *shProg, struct gl_program *prog)
+{
+   GLuint *map, i, firstSrcVarying, firstDstVarying, newSrcFile, newDstFile;
+   GLbitfield *inOutFlags = NULL;
+
+   map = (GLuint *) malloc(prog->Varying->NumParameters * sizeof(GLuint));
+   if (!map)
+      return GL_FALSE;
+
+   /* Varying variables are treated like other vertex program outputs
+    * (and like other fragment program inputs).  The position of the
+    * first varying differs for vertex/fragment programs...
+    * Also, replace File=PROGRAM_VARYING with File=PROGRAM_INPUT/OUTPUT.
+    */
+   if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
+      firstSrcVarying = firstDstVarying = VERT_RESULT_VAR0;
+      newSrcFile = newDstFile = PROGRAM_OUTPUT;
+      inOutFlags = prog->OutputFlags;
+   }
+   else if (prog->Target == MESA_GEOMETRY_PROGRAM) {
+      firstSrcVarying = GEOM_ATTRIB_VAR0;
+      newSrcFile = PROGRAM_INPUT;
+      firstDstVarying = GEOM_RESULT_VAR0;
+      newDstFile = PROGRAM_OUTPUT;
+   }
+   else {
+      assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB);
+      firstSrcVarying = firstDstVarying = FRAG_ATTRIB_VAR0;
+      newSrcFile = newDstFile = PROGRAM_INPUT;
+      inOutFlags = prog->InputFlags;
+   }
+
+   for (i = 0; i < prog->Varying->NumParameters; i++) {
+      /* see if this varying is in the linked varying list */
+      const struct gl_program_parameter *var = prog->Varying->Parameters + i;
+      GLint j = _mesa_lookup_parameter_index(shProg->Varying, -1, var->Name);
+      if (j >= 0) {
+         /* varying is already in list, do some error checking */
+         const struct gl_program_parameter *v =
+            &shProg->Varying->Parameters[j];
+         if (var->Size != v->Size) {
+            link_error(shProg, "mismatched varying variable types");
+            free(map);
+            return GL_FALSE;
+         }
+         if (!bits_agree(var->Flags, v->Flags, PROG_PARAM_BIT_CENTROID)) {
+            char msg[100];
+            _mesa_snprintf(msg, sizeof(msg),
+                    "centroid modifier mismatch for '%s'", var->Name);
+            link_error(shProg, msg);
+            free(map);
+            return GL_FALSE;
+         }
+         if (!bits_agree(var->Flags, v->Flags, PROG_PARAM_BIT_INVARIANT)) {
+            char msg[100];
+            _mesa_snprintf(msg, sizeof(msg),
+                    "invariant modifier mismatch for '%s'", var->Name);
+            link_error(shProg, msg);
+            free(map);
+            return GL_FALSE;
+         }
+      }
+      else {
+         /* not already in linked list */
+         j = _mesa_add_varying(shProg->Varying, var->Name, var->Size,
+                               var->DataType, var->Flags);
+      }
+
+      if (shProg->Varying->NumParameters > ctx->Const.MaxVarying) {
+         link_error(shProg, "Too many varying variables");
+         free(map);
+         return GL_FALSE;
+      }
+
+      /* Map varying[i] to varying[j].
+       * Note: the loop here takes care of arrays or large (sz>4) vars.
+       */
+      {
+         GLint sz = var->Size;
+         while (sz > 0) {
+            inOutFlags[firstDstVarying + j] = var->Flags;
+            /*printf("Link varying from %d to %d\n", i, j);*/
+            map[i++] = j++;
+            sz -= 4;
+         }
+         i--; /* go back one */
+      }
+   }
+
+
+   /* OK, now scan the program/shader instructions looking for varying vars,
+    * replacing the old index with the new index.
+    */
+   for (i = 0; i < prog->NumInstructions; i++) {
+      struct prog_instruction *inst = prog->Instructions + i;
+      GLuint j;
+
+      if (inst->DstReg.File == PROGRAM_VARYING) {
+         inst->DstReg.File = newDstFile;
+         inst->DstReg.Index = map[ inst->DstReg.Index ] + firstDstVarying;
+      }
+
+      for (j = 0; j < 3; j++) {
+         if (inst->SrcReg[j].File == PROGRAM_VARYING) {
+            inst->SrcReg[j].File = newSrcFile;
+            inst->SrcReg[j].Index = map[ inst->SrcReg[j].Index ] + firstSrcVarying;
+         }
+      }
+   }
+
+   free(map);
+
+   /* these will get recomputed before linking is completed */
+   prog->InputsRead = 0x0;
+   prog->OutputsWritten = 0x0;
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Build the shProg->Uniforms list.
+ * This is basically a list/index of all uniforms found in either/both of
+ * the vertex and fragment shaders.
+ *
+ * About uniforms:
+ * Each uniform has two indexes, one that points into the vertex
+ * program's parameter array and another that points into the fragment
+ * program's parameter array.  When the user changes a uniform's value
+ * we have to change the value in the vertex and/or fragment program's
+ * parameter array.
+ *
+ * This function will be called twice to set up the two uniform->parameter
+ * mappings.
+ *
+ * If a uniform is only present in the vertex program OR fragment program
+ * then the fragment/vertex parameter index, respectively, will be -1.
+ */
+static GLboolean
+link_uniform_vars(GLcontext *ctx,
+                  struct gl_shader_program *shProg,
+                  struct gl_program *prog,
+                  GLuint *numSamplers)
+{
+   GLuint samplerMap[200]; /* max number of samplers declared, not used */
+   GLuint i;
+
+   for (i = 0; i < prog->Parameters->NumParameters; i++) {
+      const struct gl_program_parameter *p = prog->Parameters->Parameters + i;
+
+      /*
+       * XXX FIX NEEDED HERE
+       * We should also be adding a uniform if p->Type == PROGRAM_STATE_VAR.
+       * For example, modelview matrix, light pos, etc.
+       * Also, we need to update the state-var name-generator code to
+       * generate GLSL-style names, like "gl_LightSource[0].position".
+       * Furthermore, we'll need to fix the state-var's size/datatype info.
+       */
+
+      if ((p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER)
+          && p->Used) {
+         /* add this uniform, indexing into the target's Parameters list */
+         struct gl_uniform *uniform =
+            _mesa_append_uniform(shProg->Uniforms, p->Name, prog->Target, i);
+         if (uniform)
+            uniform->Initialized = p->Initialized;
+      }
+
+      /* The samplerMap[] table we build here is used to remap/re-index
+       * sampler references by TEX instructions.
+       */
+      if (p->Type == PROGRAM_SAMPLER && p->Used) {
+         /* Allocate a new sampler index */
+         GLuint oldSampNum = (GLuint) prog->Parameters->ParameterValues[i][0];
+         GLuint newSampNum = *numSamplers;
+         if (newSampNum >= ctx->Const.MaxTextureImageUnits) {
+            char s[100];
+            _mesa_snprintf(s, sizeof(s),
+                           "Too many texture samplers (%u, max is %u)",
+                           newSampNum, ctx->Const.MaxTextureImageUnits);
+            link_error(shProg, s);
+            return GL_FALSE;
+         }
+         /* save old->new mapping in the table */
+         if (oldSampNum < Elements(samplerMap))
+            samplerMap[oldSampNum] = newSampNum;
+         /* update parameter's sampler index */
+         prog->Parameters->ParameterValues[i][0] = (GLfloat) newSampNum;
+         (*numSamplers)++;
+      }
+   }
+
+   /* OK, now scan the program/shader instructions looking for texture
+    * instructions using sampler vars.  Replace old sampler indexes with
+    * new ones.
+    */
+   prog->SamplersUsed = 0x0;
+   for (i = 0; i < prog->NumInstructions; i++) {
+      struct prog_instruction *inst = prog->Instructions + i;
+      if (_mesa_is_tex_instruction(inst->Opcode)) {
+         /* here, inst->TexSrcUnit is really the sampler unit */
+         const GLint oldSampNum = inst->TexSrcUnit;
+
+#if 0
+         printf("====== remap sampler from %d to %d\n",
+                inst->TexSrcUnit, samplerMap[ inst->TexSrcUnit ]);
+#endif
+
+         if (oldSampNum < Elements(samplerMap)) {
+            const GLuint newSampNum = samplerMap[oldSampNum];
+            inst->TexSrcUnit = newSampNum;
+            prog->SamplerTargets[newSampNum] = inst->TexSrcTarget;
+            prog->SamplersUsed |= (1 << newSampNum);
+            if (inst->TexShadow) {
+               prog->ShadowSamplers |= (1 << newSampNum);
+            }
+         }
+      }
+   }
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Resolve binding of generic vertex attributes.
+ * For example, if the vertex shader declared "attribute vec4 foobar" we'll
+ * allocate a generic vertex attribute for "foobar" and plug that value into
+ * the vertex program instructions.
+ * But if the user called glBindAttributeLocation(), those bindings will
+ * have priority.
+ */
+static GLboolean
+_slang_resolve_attributes(struct gl_shader_program *shProg,
+                          const struct gl_program *origProg,
+                          struct gl_program *linkedProg)
+{
+   GLint attribMap[MAX_VERTEX_GENERIC_ATTRIBS];
+   GLuint i, j;
+   GLbitfield usedAttributes; /* generics only, not legacy attributes */
+   GLbitfield inputsRead = 0x0;
+
+   assert(origProg != linkedProg);
+   assert(origProg->Target == GL_VERTEX_PROGRAM_ARB);
+   assert(linkedProg->Target == GL_VERTEX_PROGRAM_ARB);
+
+   if (!shProg->Attributes)
+      shProg->Attributes = _mesa_new_parameter_list();
+
+   if (linkedProg->Attributes) {
+      _mesa_free_parameter_list(linkedProg->Attributes);
+   }
+   linkedProg->Attributes = _mesa_new_parameter_list();
+
+
+   /* Build a bitmask indicating which attribute indexes have been
+    * explicitly bound by the user with glBindAttributeLocation().
+    */
+   usedAttributes = 0x0;
+   for (i = 0; i < shProg->Attributes->NumParameters; i++) {
+      GLint attr = shProg->Attributes->Parameters[i].StateIndexes[0];
+      usedAttributes |= (1 << attr);
+   }
+
+   /* If gl_Vertex is used, that actually counts against the limit
+    * on generic vertex attributes.  This avoids the ambiguity of
+    * whether glVertexAttrib4fv(0, v) sets legacy attribute 0 (vert pos)
+    * or generic attribute[0].  If gl_Vertex is used, we want the former.
+    */
+   if (origProg->InputsRead & VERT_BIT_POS) {
+      usedAttributes |= 0x1;
+   }
+
+   /* initialize the generic attribute map entries to -1 */
+   for (i = 0; i < MAX_VERTEX_GENERIC_ATTRIBS; i++) {
+      attribMap[i] = -1;
+   }
+
+   /*
+    * Scan program for generic attribute references
+    */
+   for (i = 0; i < linkedProg->NumInstructions; i++) {
+      struct prog_instruction *inst = linkedProg->Instructions + i;
+      for (j = 0; j < 3; j++) {
+         if (inst->SrcReg[j].File == PROGRAM_INPUT) {
+            inputsRead |= (1 << inst->SrcReg[j].Index);
+         }
+
+         if (inst->SrcReg[j].File == PROGRAM_INPUT &&
+             inst->SrcReg[j].Index >= VERT_ATTRIB_GENERIC0) {
+            /*
+             * OK, we've found a generic vertex attribute reference.
+             */
+            const GLint k = inst->SrcReg[j].Index - VERT_ATTRIB_GENERIC0;
+
+            GLint attr = attribMap[k];
+
+            if (attr < 0) {
+               /* Need to figure out attribute mapping now.
+                */
+               const char *name = origProg->Attributes->Parameters[k].Name;
+               const GLint size = origProg->Attributes->Parameters[k].Size;
+               const GLenum type =origProg->Attributes->Parameters[k].DataType;
+               GLint index;
+
+               /* See if there's a user-defined attribute binding for
+                * this name.
+                */
+               index = _mesa_lookup_parameter_index(shProg->Attributes,
+                                                    -1, name);
+               if (index >= 0) {
+                  /* Found a user-defined binding */
+                  attr = shProg->Attributes->Parameters[index].StateIndexes[0];
+               }
+               else {
+                  /* No user-defined binding, choose our own attribute number.
+                   * Start at 1 since generic attribute 0 always aliases
+                   * glVertex/position.
+                   */
+                  for (attr = 0; attr < MAX_VERTEX_GENERIC_ATTRIBS; attr++) {
+                     if (((1 << attr) & usedAttributes) == 0)
+                        break;
+                  }
+                  if (attr == MAX_VERTEX_GENERIC_ATTRIBS) {
+                     link_error(shProg, "Too many vertex attributes");
+                     return GL_FALSE;
+                  }
+
+                  /* mark this attribute as used */
+                  usedAttributes |= (1 << attr);
+               }
+
+               attribMap[k] = attr;
+
+               /* Save the final name->attrib binding so it can be queried
+                * with glGetAttributeLocation().
+                */
+               _mesa_add_attribute(linkedProg->Attributes, name,
+                                   size, type, attr);
+            }
+
+            assert(attr >= 0);
+
+            /* update the instruction's src reg */
+            inst->SrcReg[j].Index = VERT_ATTRIB_GENERIC0 + attr;
+         }
+      }
+   }
+
+   /* Handle pre-defined attributes here (gl_Vertex, gl_Normal, etc).
+    * When the user queries the active attributes we need to include both
+    * the user-defined attributes and the built-in ones.
+    */
+   for (i = VERT_ATTRIB_POS; i < VERT_ATTRIB_GENERIC0; i++) {
+      if (inputsRead & (1 << i)) {
+         _mesa_add_attribute(linkedProg->Attributes,
+                             _slang_vert_attrib_name(i),
+                             4, /* size in floats */
+                             _slang_vert_attrib_type(i),
+                             -1 /* attrib/input */);
+      }
+   }
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Scan program instructions to update the program's NumTemporaries field.
+ * Note: this implemenation relies on the code generator allocating
+ * temps in increasing order (0, 1, 2, ... ).
+ */
+static void
+_slang_count_temporaries(struct gl_program *prog)
+{
+   GLuint i, j;
+   GLint maxIndex = -1;
+
+   for (i = 0; i < prog->NumInstructions; i++) {
+      const struct prog_instruction *inst = prog->Instructions + i;
+      const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
+      for (j = 0; j < numSrc; j++) {
+         if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) {
+            if (maxIndex < inst->SrcReg[j].Index)
+               maxIndex = inst->SrcReg[j].Index;
+         }
+         if (inst->DstReg.File == PROGRAM_TEMPORARY) {
+            if (maxIndex < (GLint) inst->DstReg.Index)
+               maxIndex = inst->DstReg.Index;
+         }
+      }
+   }
+
+   prog->NumTemporaries = (GLuint) (maxIndex + 1);
+}
+
+
+/**
+ * If an input attribute is indexed with relative addressing we have
+ * to compute a gl_program::InputsRead bitmask which reflects the fact
+ * that any input may be referenced by array element.  Ex: gl_TexCoord[i].
+ * This function computes the bitmask of potentially read inputs.
+ */
+static GLbitfield
+get_inputs_read_mask(GLenum target, GLuint index, GLboolean relAddr)
+{
+   GLbitfield mask;
+
+   mask = 1 << index;
+
+   if (relAddr) {
+      if (target == GL_VERTEX_PROGRAM_ARB) {
+         switch (index) {
+         case VERT_ATTRIB_TEX0:
+            mask = ((1U << (VERT_ATTRIB_TEX7 + 1)) - 1)
+                 - ((1U << VERT_ATTRIB_TEX0) - 1);
+            break;
+         case VERT_ATTRIB_GENERIC0:
+            /* different code to avoid uint overflow */
+            mask = ~0x0U - ((1U << VERT_ATTRIB_GENERIC0) - 1);
+            break;
+         default:
+            ; /* a non-array input attribute */
+         }
+      }
+      else if (target == GL_FRAGMENT_PROGRAM_ARB) {
+         switch (index) {
+         case FRAG_ATTRIB_TEX0:
+            mask = ((1U << (FRAG_ATTRIB_TEX7 + 1)) - 1)
+                 - ((1U << FRAG_ATTRIB_TEX0) - 1);
+            break;
+         case FRAG_ATTRIB_VAR0:
+            mask = ((1U << (FRAG_ATTRIB_VAR0 + MAX_VARYING)) - 1)
+                 - ((1U << FRAG_ATTRIB_VAR0) - 1);
+            break;
+         default:
+            ; /* a non-array input attribute */
+         }
+      }
+      else if (target == MESA_GEOMETRY_PROGRAM) {
+         switch (index) {
+         case GEOM_ATTRIB_VAR0:
+            mask = ((1ULL << (GEOM_ATTRIB_VAR0 + MAX_VARYING)) - 1)
+                   - ((1ULL << GEOM_ATTRIB_VAR0) - 1);
+            break;
+         default:
+            ; /* a non-array input attribute */
+         }
+      }
+      else {
+         assert(0 && "bad program target");
+      }
+   }
+   else {
+   }
+
+   return mask;
+}
+
+
+/**
+ * If an output attribute is indexed with relative addressing we have
+ * to compute a gl_program::OutputsWritten bitmask which reflects the fact
+ * that any output may be referenced by array element.  Ex: gl_TexCoord[i].
+ * This function computes the bitmask of potentially written outputs.
+ */
+static GLbitfield64
+get_outputs_written_mask(GLenum target, GLuint index, GLboolean relAddr)
+{
+   GLbitfield64 mask;
+
+   mask = BITFIELD64_BIT(index);
+
+   if (relAddr) {
+      if (target == GL_VERTEX_PROGRAM_ARB) {
+         switch (index) {
+         case VERT_RESULT_TEX0:
+            mask = BITFIELD64_RANGE(VERT_RESULT_TEX0,
+                                    (VERT_RESULT_TEX0
+                                     + MAX_TEXTURE_COORD_UNITS - 1));
+            break;
+         case VERT_RESULT_VAR0:
+            mask = BITFIELD64_RANGE(VERT_RESULT_VAR0,
+                                    (VERT_RESULT_VAR0 + MAX_VARYING - 1));
+            break;
+         default:
+            ; /* a non-array output attribute */
+         }
+      }
+      else if (target == GL_FRAGMENT_PROGRAM_ARB) {
+         switch (index) {
+         case FRAG_RESULT_DATA0:
+            mask = BITFIELD64_RANGE(FRAG_RESULT_DATA0,
+                                    (FRAG_RESULT_DATA0
+                                     + MAX_DRAW_BUFFERS - 1));
+            break;
+         default:
+            ; /* a non-array output attribute */
+         }
+      }
+      else if (target == MESA_GEOMETRY_PROGRAM) {
+         switch (index) {
+         case GEOM_RESULT_TEX0:
+            mask = BITFIELD64_RANGE(GEOM_RESULT_TEX0,
+                                    (GEOM_RESULT_TEX0
+                                     + MAX_TEXTURE_COORD_UNITS - 1));
+            break;
+         case GEOM_RESULT_VAR0:
+            mask = BITFIELD64_RANGE(GEOM_RESULT_VAR0,
+                                    (GEOM_RESULT_VAR0 + MAX_VARYING - 1));
+            break;
+         default:
+            ; /* a non-array output attribute */
+         }
+      }
+      else {
+         assert(0 && "bad program target");
+      }
+   }
+
+   return mask;
+}
+
+
+/**
+ * Scan program instructions to update the program's InputsRead and
+ * OutputsWritten fields.
+ */
+static void
+_slang_update_inputs_outputs(struct gl_program *prog)
+{
+   GLuint i, j;
+   GLuint maxAddrReg = 0;
+
+   prog->InputsRead = 0x0;
+   prog->OutputsWritten = 0x0;
+
+   for (i = 0; i < prog->NumInstructions; i++) {
+      const struct prog_instruction *inst = prog->Instructions + i;
+      const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
+      for (j = 0; j < numSrc; j++) {
+         if (inst->SrcReg[j].File == PROGRAM_INPUT) {
+            if (prog->Target == MESA_GEOMETRY_PROGRAM &&
+                inst->SrcReg[j].HasIndex2)
+               prog->InputsRead |= get_inputs_read_mask(prog->Target,
+                                                        inst->SrcReg[j].Index2,
+                                                        inst->SrcReg[j].RelAddr2);
+            else
+               prog->InputsRead |= get_inputs_read_mask(prog->Target,
+                                                        inst->SrcReg[j].Index,
+                                                        inst->SrcReg[j].RelAddr);
+         }
+         else if (inst->SrcReg[j].File == PROGRAM_ADDRESS) {
+            maxAddrReg = MAX2(maxAddrReg, (GLuint) (inst->SrcReg[j].Index + 1));
+         }
+      }
+
+      if (inst->DstReg.File == PROGRAM_OUTPUT) {
+         prog->OutputsWritten |= get_outputs_written_mask(prog->Target,
+                                                          inst->DstReg.Index,
+                                                          inst->DstReg.RelAddr);
+      }
+      else if (inst->DstReg.File == PROGRAM_ADDRESS) {
+         maxAddrReg = MAX2(maxAddrReg, inst->DstReg.Index + 1);
+      }
+   }
+   prog->NumAddressRegs = maxAddrReg;
+}
+
+
+
+/**
+ * Remove extra #version directives from the concatenated source string.
+ * Disable the extra ones by converting first two chars to //, a comment.
+ * This is a bit of hack to work around a preprocessor bug that only
+ * allows one #version directive per source.
+ */
+static void
+remove_extra_version_directives(GLchar *source)
+{
+   GLuint verCount = 0;
+   while (1) {
+      char *ver = strstr(source, "#version");
+      if (ver) {
+         verCount++;
+         if (verCount > 1) {
+            ver[0] = '/';
+            ver[1] = '/';
+         }
+         source += 8;
+      }
+      else {
+         break;
+      }
+   }
+}
+
+/* Returns the number of vertices per geometry shader
+ * input primitive.
+ * XXX: duplicated in Gallium in u_vertices_per_prim
+ * method. Once Mesa core will start using Gallium
+ * this should be removed
+ */
+static int
+vertices_per_prim(int prim)
+{
+   switch (prim) {
+   case GL_POINTS:
+      return 1;
+   case GL_LINES:
+      return 2;
+   case GL_TRIANGLES:
+      return 3;
+   case GL_LINES_ADJACENCY_ARB:
+      return 4;
+   case GL_TRIANGLES_ADJACENCY_ARB:
+      return 6;
+   default:
+      ASSERT(!"Bad primitive");
+      return 3;
+   }
+}
+
+/**
+ * Return a new shader whose source code is the concatenation of
+ * all the shader sources of the given type.
+ */
+static struct gl_shader *
+concat_shaders(struct gl_shader_program *shProg, GLenum shaderType)
+{
+   struct gl_shader *newShader;
+   const struct gl_shader *firstShader = NULL;
+   GLuint *shaderLengths;
+   GLchar *source;
+   GLuint totalLen = 0, len = 0;
+   GLuint i;
+
+   shaderLengths = (GLuint *)malloc(shProg->NumShaders * sizeof(GLuint));
+   if (!shaderLengths) {
+      return NULL;
+   }
+
+   /* compute total size of new shader source code */
+   for (i = 0; i < shProg->NumShaders; i++) {
+      const struct gl_shader *shader = shProg->Shaders[i];
+      if (shader->Type == shaderType) {
+         shaderLengths[i] = strlen(shader->Source);
+         totalLen += shaderLengths[i];
+         if (!firstShader)
+            firstShader = shader;
+      }
+   }
+
+   if (totalLen == 0) {
+      free(shaderLengths);
+      return NULL;
+   }
+
+   /* Geometry shader will inject definition of
+    * const int gl_VerticesIn */
+   if (shaderType == GL_GEOMETRY_SHADER_ARB) {
+      totalLen += 32;
+   }
+
+   source = (GLchar *) malloc(totalLen + 1);
+   if (!source) {
+      free(shaderLengths);
+      return NULL;
+   }
+
+   /* concatenate shaders */
+   for (i = 0; i < shProg->NumShaders; i++) {
+      const struct gl_shader *shader = shProg->Shaders[i];
+      if (shader->Type == shaderType) {
+         memcpy(source + len, shader->Source, shaderLengths[i]);
+         len += shaderLengths[i];
+      }
+   }
+   /* if it's geometry shader we need to inject definition
+    * of "const int gl_VerticesIn = X;" where X is the number
+    * of vertices per input primitive
+    */
+   if (shaderType == GL_GEOMETRY_SHADER_ARB) {
+      GLchar gs_pre[32];
+      GLuint num_verts = vertices_per_prim(shProg->Geom.InputType);
+      _mesa_snprintf(gs_pre, 31,
+                     "const int gl_VerticesIn = %d;\n", num_verts);
+      memcpy(source + len, gs_pre, strlen(gs_pre));
+      len += strlen(gs_pre);
+   }
+   source[len] = '\0';
+   /*
+   printf("---NEW CONCATENATED SHADER---:\n%s\n------------\n", source);
+   */
+
+   free(shaderLengths);
+
+   remove_extra_version_directives(source);
+
+   newShader = CALLOC_STRUCT(gl_shader);
+   if (!newShader) {
+      free(source);
+      return NULL;
+   }
+
+   newShader->Type = shaderType;
+   newShader->Source = source;
+   newShader->Pragmas = firstShader->Pragmas;
+
+   return newShader;
+}
+
+/**
+ * Search the shader program's list of shaders to find the one that
+ * defines main().
+ * This will involve shader concatenation and recompilation if needed.
+ */
+static struct gl_shader *
+get_main_shader(GLcontext *ctx,
+                struct gl_shader_program *shProg, GLenum type)
+{
+   struct gl_shader *shader = NULL;
+   GLuint i;
+
+   /*
+    * Look for a shader that defines main() and has no unresolved references.
+    */
+   for (i = 0; i < shProg->NumShaders; i++) {
+      shader = shProg->Shaders[i];
+      if (shader->Type == type &&
+          shader->Main &&
+          !shader->UnresolvedRefs) {
+         /* All set! */
+         return shader;
+      }
+   }
+
+   /*
+    * There must have been unresolved references during the original
+    * compilation.  Try concatenating all the shaders of the given type
+    * and recompile that.
+    */
+   shader = concat_shaders(shProg, type);
+
+   if (shader) {
+      _slang_compile(ctx, shader);
+
+      /* Finally, check if recompiling failed */
+      if (!shader->CompileStatus ||
+          !shader->Main ||
+          shader->UnresolvedRefs) {
+         link_error(shProg, "Unresolved symbols");
+         ctx->Driver.DeleteShader(ctx, shader);
+         return NULL;
+      }
+   }
+
+   return shader;
+}
+
+
+/**
+ * Shader linker.  Currently:
+ *
+ * 1. The last attached vertex shader and fragment shader are linked.
+ * 2. Varying vars in the two shaders are combined so their locations
+ *    agree between the vertex and fragment stages.  They're treated as
+ *    vertex program output attribs and as fragment program input attribs.
+ * 3. The vertex and fragment programs are cloned and modified to update
+ *    src/dst register references so they use the new, linked varying
+ *    storage locations.
+ */
+void
+_slang_link(GLcontext *ctx,
+            GLhandleARB programObj,
+            struct gl_shader_program *shProg)
+{
+   const struct gl_vertex_program *vertProg = NULL;
+   const struct gl_fragment_program *fragProg = NULL;
+   const struct gl_geometry_program *geomProg = NULL;
+   GLboolean vertNotify = GL_TRUE, fragNotify = GL_TRUE, geomNotify = GL_TRUE;
+   GLuint numSamplers = 0;
+   GLuint i;
+
+   _mesa_clear_shader_program_data(ctx, shProg);
+
+   /* Initialize LinkStatus to "success".  Will be cleared if error. */
+   shProg->LinkStatus = GL_TRUE;
+
+   /* check that all programs compiled successfully */
+   for (i = 0; i < shProg->NumShaders; i++) {
+      if (!shProg->Shaders[i]->CompileStatus) {
+         link_error(shProg, "linking with uncompiled shader\n");
+         return;
+      }
+   }
+
+   shProg->Uniforms = _mesa_new_uniform_list();
+   shProg->Varying = _mesa_new_parameter_list();
+
+   /*
+    * Find the vertex and fragment shaders which define main()
+    */
+   {
+      struct gl_shader *vertShader, *fragShader, *geomShader;
+      vertShader = get_main_shader(ctx, shProg, GL_VERTEX_SHADER);
+      geomShader = get_main_shader(ctx, shProg, GL_GEOMETRY_SHADER_ARB);
+      fragShader = get_main_shader(ctx, shProg, GL_FRAGMENT_SHADER);
+
+      if (vertShader)
+         vertProg = vertex_program(vertShader->Program);
+      if (geomShader)
+         geomProg = geometry_program(geomShader->Program);
+      if (fragShader)
+         fragProg = fragment_program(fragShader->Program);
+      if (!shProg->LinkStatus)
+         return;
+   }
+
+#if FEATURE_es2_glsl
+   /* must have both a vertex and fragment program for ES2 */
+   if (ctx->API == API_OPENGLES2) {
+      if (!vertProg) {
+        link_error(shProg, "missing vertex shader\n");
+        return;
+      }
+      if (!fragProg) {
+        link_error(shProg, "missing fragment shader\n");
+        return;
+      }
+   }
+#endif
+
+   /*
+    * Make copies of the vertex/fragment programs now since we'll be
+    * changing src/dst registers after merging the uniforms and varying vars.
+    */
+   _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
+   if (vertProg) {
+      struct gl_vertex_program *linked_vprog =
+         _mesa_clone_vertex_program(ctx, vertProg);
+      shProg->VertexProgram = linked_vprog; /* refcount OK */
+      /* vertex program ID not significant; just set Id for debugging purposes */
+      shProg->VertexProgram->Base.Id = shProg->Name;
+      ASSERT(shProg->VertexProgram->Base.RefCount == 1);
+   }
+   _mesa_reference_geomprog(ctx, &shProg->GeometryProgram, NULL);
+   if (geomProg) {
+      struct gl_geometry_program *linked_gprog =
+         _mesa_clone_geometry_program(ctx, geomProg);
+      shProg->GeometryProgram = linked_gprog; /* refcount OK */
+      shProg->GeometryProgram->Base.Id = shProg->Name;
+      ASSERT(shProg->GeometryProgram->Base.RefCount == 1);
+   }
+   _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
+   if (fragProg) {
+      struct gl_fragment_program *linked_fprog = 
+         _mesa_clone_fragment_program(ctx, fragProg);
+      shProg->FragmentProgram = linked_fprog; /* refcount OK */
+      /* vertex program ID not significant; just set Id for debugging purposes */
+      shProg->FragmentProgram->Base.Id = shProg->Name;
+      ASSERT(shProg->FragmentProgram->Base.RefCount == 1);
+   }
+
+   /* link varying vars */
+   if (shProg->VertexProgram) {
+      if (!link_varying_vars(ctx, shProg, &shProg->VertexProgram->Base))
+         return;
+   }
+   if (shProg->GeometryProgram) {
+      if (!link_varying_vars(ctx, shProg, &shProg->GeometryProgram->Base))
+         return;
+   }
+   if (shProg->FragmentProgram) {
+      if (!link_varying_vars(ctx, shProg, &shProg->FragmentProgram->Base))
+         return;
+   }
+
+   /* link uniform vars */
+   if (shProg->VertexProgram) {
+      if (!link_uniform_vars(ctx, shProg, &shProg->VertexProgram->Base,
+                             &numSamplers)) {
+         return;
+      }
+   }
+   if (shProg->GeometryProgram) {
+      if (!link_uniform_vars(ctx, shProg, &shProg->GeometryProgram->Base,
+                             &numSamplers)) {
+         return;
+      }
+   }
+   if (shProg->FragmentProgram) {
+      if (!link_uniform_vars(ctx, shProg, &shProg->FragmentProgram->Base,
+                             &numSamplers)) {
+         return;
+      }
+   }
+
+   /*_mesa_print_uniforms(shProg->Uniforms);*/
+
+   if (shProg->VertexProgram) {
+      if (!_slang_resolve_attributes(shProg, &vertProg->Base,
+                                     &shProg->VertexProgram->Base)) {
+         return;
+      }
+   }
+
+   if (shProg->VertexProgram) {
+      _slang_update_inputs_outputs(&shProg->VertexProgram->Base);
+      _slang_count_temporaries(&shProg->VertexProgram->Base);
+      if (!(shProg->VertexProgram->Base.OutputsWritten
+           & BITFIELD64_BIT(VERT_RESULT_HPOS))) {
+         /* the vertex program did not compute a vertex position */
+         link_error(shProg,
+                    "gl_Position was not written by vertex shader\n");
+         return;
+      }
+   }
+   if (shProg->GeometryProgram) {
+      if (!shProg->VertexProgram) {
+         link_error(shProg,
+                    "Geometry shader without a vertex shader is illegal!\n");
+         return;
+      }
+      if (shProg->Geom.VerticesOut == 0) {
+         link_error(shProg,
+                    "GEOMETRY_VERTICES_OUT is zero\n");
+         return;
+      }
+
+      _slang_count_temporaries(&shProg->GeometryProgram->Base);
+      _slang_update_inputs_outputs(&shProg->GeometryProgram->Base);
+   }
+   if (shProg->FragmentProgram) {
+      _slang_count_temporaries(&shProg->FragmentProgram->Base);
+      _slang_update_inputs_outputs(&shProg->FragmentProgram->Base);
+   }
+
+   /* Check that all the varying vars needed by the fragment shader are
+    * actually produced by the vertex shader.
+    */
+   if (shProg->FragmentProgram) {
+      const GLbitfield varyingRead
+         = shProg->FragmentProgram->Base.InputsRead >> FRAG_ATTRIB_VAR0;
+      const GLbitfield64 varyingWritten = shProg->VertexProgram ?
+         shProg->VertexProgram->Base.OutputsWritten >> VERT_RESULT_VAR0 : 0x0;
+      if ((varyingRead & varyingWritten) != varyingRead) {
+         link_error(shProg,
+          "Fragment program using varying vars not written by vertex shader\n");
+         return;
+      }         
+   }
+
+   /* check that gl_FragColor and gl_FragData are not both written to */
+   if (shProg->FragmentProgram) {
+      const GLbitfield64 outputsWritten =
+        shProg->FragmentProgram->Base.OutputsWritten;
+      if ((outputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) &&
+          (outputsWritten >= BITFIELD64_BIT(FRAG_RESULT_DATA0))) {
+         link_error(shProg, "Fragment program cannot write both gl_FragColor"
+                    " and gl_FragData[].\n");
+         return;
+      }         
+   }
+
+   update_varying_var_list(ctx, shProg);
+
+   /* checks related to transform feedback */
+   if (!link_transform_feedback(ctx, shProg)) {
+      return;
+   }
+
+   if (fragProg && shProg->FragmentProgram) {
+      /* Compute initial program's TexturesUsed info */
+      _mesa_update_shader_textures_used(&shProg->FragmentProgram->Base);
+
+      /* notify driver that a new fragment program has been compiled/linked */
+      vertNotify = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
+                                                 &shProg->FragmentProgram->Base);
+      if (ctx->Shader.Flags & GLSL_DUMP) {
+         printf("Mesa pre-link fragment program:\n");
+         _mesa_print_program(&fragProg->Base);
+         _mesa_print_program_parameters(ctx, &fragProg->Base);
+
+         printf("Mesa post-link fragment program:\n");
+         _mesa_print_program(&shProg->FragmentProgram->Base);
+         _mesa_print_program_parameters(ctx, &shProg->FragmentProgram->Base);
+      }
+   }
+
+   if (geomProg && shProg->GeometryProgram) {
+      /* Compute initial program's TexturesUsed info */
+      _mesa_update_shader_textures_used(&shProg->GeometryProgram->Base);
+
+      /* Copy some per-shader-program fields to per-shader object */
+      shProg->GeometryProgram->VerticesOut = shProg->Geom.VerticesOut;
+      shProg->GeometryProgram->InputType = shProg->Geom.InputType;
+      shProg->GeometryProgram->OutputType = shProg->Geom.OutputType;
+
+      /* notify driver that a new fragment program has been compiled/linked */
+      geomNotify = ctx->Driver.ProgramStringNotify(ctx, MESA_GEOMETRY_PROGRAM,
+                                                   &shProg->GeometryProgram->Base);
+      if (ctx->Shader.Flags & GLSL_DUMP) {
+         printf("Mesa pre-link geometry program:\n");
+         _mesa_print_program(&geomProg->Base);
+         _mesa_print_program_parameters(ctx, &geomProg->Base);
+
+         printf("Mesa post-link geometry program:\n");
+         _mesa_print_program(&shProg->GeometryProgram->Base);
+         _mesa_print_program_parameters(ctx, &shProg->GeometryProgram->Base);
+      }
+   }
+
+   if (vertProg && shProg->VertexProgram) {
+      /* Compute initial program's TexturesUsed info */
+      _mesa_update_shader_textures_used(&shProg->VertexProgram->Base);
+
+      /* notify driver that a new vertex program has been compiled/linked */
+      fragNotify = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
+                                                   &shProg->VertexProgram->Base);
+      if (ctx->Shader.Flags & GLSL_DUMP) {
+         printf("Mesa pre-link vertex program:\n");
+         _mesa_print_program(&vertProg->Base);
+         _mesa_print_program_parameters(ctx, &vertProg->Base);
+
+         printf("Mesa post-link vertex program:\n");
+         _mesa_print_program(&shProg->VertexProgram->Base);
+         _mesa_print_program_parameters(ctx, &shProg->VertexProgram->Base);
+      }
+   }
+
+   /* Debug: */
+   if (0) {
+      if (shProg->VertexProgram)
+         _mesa_postprocess_program(ctx, &shProg->VertexProgram->Base);
+      if (shProg->FragmentProgram)
+         _mesa_postprocess_program(ctx, &shProg->FragmentProgram->Base);
+   }
+
+   if (ctx->Shader.Flags & GLSL_DUMP) {
+      printf("Varying vars:\n");
+      _mesa_print_parameter_list(shProg->Varying);
+      if (shProg->InfoLog) {
+         printf("Info Log: %s\n", shProg->InfoLog);
+      }
+   }
+
+   if (!vertNotify || !fragNotify || !geomNotify) {
+      /* driver rejected one/both of the vertex/fragment programs */
+      if (!shProg->InfoLog) {
+        link_error(shProg,
+                   "Vertex, geometry and/or fragment program rejected by driver\n");
+      }
+   }
+   else {
+      shProg->LinkStatus = (shProg->VertexProgram || shProg->FragmentProgram);
+   }
+}
+
diff --git a/src/mesa/slang/slang_link.h b/src/mesa/slang/slang_link.h
new file mode 100644 (file)
index 0000000..2b44d20
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.2
+ *
+ * Copyright (C) 2008  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 SLANG_LINK_H
+#define SLANG_LINK_H 1
+
+#include "slang_compile.h"
+
+
+extern void
+_slang_link(GLcontext *ctx, GLhandleARB h,
+            struct gl_shader_program *shProg);
+
+
+#endif
+
diff --git a/src/mesa/slang/slang_log.c b/src/mesa/slang/slang_log.c
new file mode 100644 (file)
index 0000000..9ff2141
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.3
+ *
+ * Copyright (C) 2005-2007  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2009  VMware, 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
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "main/imports.h"
+#include "slang_log.h"
+#include "slang_utility.h"
+
+
+
+static char *out_of_memory = "Error: Out of memory.\n";
+
+void
+slang_info_log_construct(slang_info_log * log)
+{
+   log->text = NULL;
+   log->dont_free_text = GL_FALSE;
+   log->error_flag = GL_FALSE;
+}
+
+void
+slang_info_log_destruct(slang_info_log * log)
+{
+   if (!log->dont_free_text)
+      free(log->text);
+}
+
+static int
+slang_info_log_message(slang_info_log * log, const char *prefix,
+                       const char *msg)
+{
+   GLuint size;
+
+   if (log->dont_free_text)
+      return 0;
+   size = slang_string_length(msg) + 2;
+   if (prefix != NULL)
+      size += slang_string_length(prefix) + 2;
+   if (log->text != NULL) {
+      GLuint old_len = slang_string_length(log->text);
+      log->text = (char *)
+        _mesa_realloc(log->text, old_len + 1, old_len + size);
+   }
+   else {
+      log->text = (char *) (malloc(size));
+      if (log->text != NULL)
+         log->text[0] = '\0';
+   }
+   if (log->text == NULL)
+      return 0;
+   if (prefix != NULL) {
+      slang_string_concat(log->text, prefix);
+      slang_string_concat(log->text, ": ");
+   }
+   slang_string_concat(log->text, msg);
+   slang_string_concat(log->text, "\n");
+
+   return 1;
+}
+
+int
+slang_info_log_print(slang_info_log * log, const char *msg, ...)
+{
+   va_list va;
+   char buf[1024];
+
+   va_start(va, msg);
+   vsprintf(buf, msg, va);
+   va_end(va);
+   return slang_info_log_message(log, NULL, buf);
+}
+
+int
+slang_info_log_error(slang_info_log * log, const char *msg, ...)
+{
+   va_list va;
+   char buf[1024];
+
+   va_start(va, msg);
+   vsprintf(buf, msg, va);
+   va_end(va);
+   log->error_flag = GL_TRUE;
+   if (slang_info_log_message(log, "Error", buf))
+      return 1;
+   slang_info_log_memory(log);
+   return 0;
+}
+
+int
+slang_info_log_warning(slang_info_log * log, const char *msg, ...)
+{
+   va_list va;
+   char buf[1024];
+
+   va_start(va, msg);
+   vsprintf(buf, msg, va);
+   va_end(va);
+   if (slang_info_log_message(log, "Warning", buf))
+      return 1;
+   slang_info_log_memory(log);
+   return 0;
+}
+
+void
+slang_info_log_memory(slang_info_log * log)
+{
+   if (!slang_info_log_message(log, "Error", "Out of memory.")) {
+      log->dont_free_text = GL_TRUE;
+      log->error_flag = GL_TRUE;
+      log->text = out_of_memory;
+   }
+}
diff --git a/src/mesa/slang/slang_log.h b/src/mesa/slang/slang_log.h
new file mode 100644 (file)
index 0000000..dcaba02
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.3
+ *
+ * Copyright (C) 2005-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.
+ */
+
+
+#ifndef SLANG_LOG_H
+#define SLANG_LOG_H
+
+
+typedef struct slang_info_log_
+{
+   char *text;
+   GLboolean dont_free_text;
+   GLboolean error_flag;
+} slang_info_log;
+
+
+extern void
+slang_info_log_construct(slang_info_log *);
+
+extern void
+slang_info_log_destruct(slang_info_log *);
+
+extern int
+slang_info_log_print(slang_info_log *, const char *, ...);
+
+extern int
+slang_info_log_error(slang_info_log *, const char *, ...);
+
+extern int
+slang_info_log_warning(slang_info_log *, const char *, ...);
+
+extern void
+slang_info_log_memory(slang_info_log *);
+
+
+#endif /* SLANG_LOG_H */
diff --git a/src/mesa/slang/slang_mem.c b/src/mesa/slang/slang_mem.c
new file mode 100644 (file)
index 0000000..5eaa7c4
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.3
+ *
+ * Copyright (C) 2005-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 slang_mem.c
+ *
+ * Memory manager for GLSL compiler.  The general idea is to do all
+ * allocations out of a large pool then just free the pool when done
+ * compiling to avoid intricate malloc/free tracking and memory leaks.
+ *
+ * \author Brian Paul
+ */
+
+#include "main/context.h"
+#include "main/macros.h"
+#include "slang_mem.h"
+
+
+#define GRANULARITY 8
+#define ROUND_UP(B)  ( ((B) + (GRANULARITY - 1)) & ~(GRANULARITY - 1) )
+
+
+/** If 1, use conventional malloc/free.  Helpful for debugging */
+#define USE_MALLOC_FREE 0
+
+
+struct slang_mempool_
+{
+   GLuint Size, Used, Count, Largest;
+   char *Data;
+   struct slang_mempool_ *Next;
+};
+
+
+slang_mempool *
+_slang_new_mempool(GLuint initialSize)
+{
+   slang_mempool *pool = (slang_mempool *) calloc(1, sizeof(slang_mempool));
+   if (pool) {
+      pool->Data = (char *) calloc(1, initialSize);
+      /*printf("ALLOC MEMPOOL %d at %p\n", initialSize, pool->Data);*/
+      if (!pool->Data) {
+         free(pool);
+         return NULL;
+      }
+      pool->Size = initialSize;
+      pool->Used = 0;
+   }
+   return pool;
+}
+
+
+void
+_slang_delete_mempool(slang_mempool *pool)
+{
+   GLuint total = 0;
+   while (pool) {
+      slang_mempool *next = pool->Next;
+      /*
+      printf("DELETE MEMPOOL %u / %u  count=%u largest=%u\n",
+             pool->Used, pool->Size, pool->Count, pool->Largest);
+      */
+      total += pool->Used;
+      free(pool->Data);
+      free(pool);
+      pool = next;
+   }
+   /*printf("TOTAL ALLOCATED: %u\n", total);*/
+}
+
+
+#ifdef DEBUG
+static void
+check_zero(const char *addr, GLuint n)
+{
+   GLuint i;
+   for (i = 0; i < n; i++) {
+      assert(addr[i]==0);
+   }
+}
+#endif
+
+
+#ifdef DEBUG
+static GLboolean
+is_valid_address(const slang_mempool *pool, void *addr)
+{
+   while (pool) {
+      if ((char *) addr >= pool->Data &&
+          (char *) addr < pool->Data + pool->Used)
+         return GL_TRUE;
+
+      pool = pool->Next;
+   }
+   return GL_FALSE;
+}
+#endif
+
+
+/**
+ * Alloc 'bytes' from shader mempool.
+ */
+void *
+_slang_alloc(GLuint bytes)
+{
+#if USE_MALLOC_FREE
+   return calloc(1, bytes);
+#else
+   slang_mempool *pool;
+   GET_CURRENT_CONTEXT(ctx);
+   pool = (slang_mempool *) ctx->Shader.MemPool;
+
+   if (bytes == 0)
+      bytes = 1;
+
+   while (pool) {
+      if (pool->Used + bytes <= pool->Size) {
+         /* found room */
+         void *addr = (void *) (pool->Data + pool->Used);
+#ifdef DEBUG
+         check_zero((char*) addr, bytes);
+#endif
+         pool->Used += ROUND_UP(bytes);
+         pool->Largest = MAX2(pool->Largest, bytes);
+         pool->Count++;
+         /*printf("alloc %u  Used %u\n", bytes, pool->Used);*/
+         return addr;
+      }
+      else if (pool->Next) {
+         /* try next block */
+         pool = pool->Next;
+      }
+      else {
+         /* alloc new pool */
+         const GLuint sz = MAX2(bytes, pool->Size);
+         pool->Next = _slang_new_mempool(sz);
+         if (!pool->Next) {
+            /* we're _really_ out of memory */
+            return NULL;
+         }
+         else {
+            pool = pool->Next;
+            pool->Largest = bytes;
+            pool->Count++;
+            pool->Used = ROUND_UP(bytes);
+#ifdef DEBUG
+            check_zero((char*) pool->Data, bytes);
+#endif
+            return (void *) pool->Data;
+         }
+      }
+   }
+   return NULL;
+#endif
+}
+
+
+void *
+_slang_realloc(void *oldBuffer, GLuint oldSize, GLuint newSize)
+{
+#if USE_MALLOC_FREE
+   return _mesa_realloc(oldBuffer, oldSize, newSize);
+#else
+   GET_CURRENT_CONTEXT(ctx);
+   slang_mempool *pool = (slang_mempool *) ctx->Shader.MemPool;
+   (void) pool;
+
+   if (newSize < oldSize) {
+      return oldBuffer;
+   }
+   else {
+      const GLuint copySize = (oldSize < newSize) ? oldSize : newSize;
+      void *newBuffer = _slang_alloc(newSize);
+
+      if (oldBuffer)
+         ASSERT(is_valid_address(pool, oldBuffer));
+
+      if (newBuffer && oldBuffer && copySize > 0)
+         memcpy(newBuffer, oldBuffer, copySize);
+
+      return newBuffer;
+   }
+#endif
+}
+
+
+/**
+ * Clone string, storing in current mempool.
+ */
+char *
+_slang_strdup(const char *s)
+{
+   if (s) {
+      size_t l = strlen(s);
+      char *s2 = (char *) _slang_alloc(l + 1);
+      if (s2)
+         strcpy(s2, s);
+      return s2;
+   }
+   else {
+      return NULL;
+   }
+}
+
+
+/**
+ * Don't actually free memory, but mark it (for debugging).
+ */
+void
+_slang_free(void *addr)
+{
+#if USE_MALLOC_FREE
+   free(addr);
+#else
+   if (addr) {
+      GET_CURRENT_CONTEXT(ctx);
+      slang_mempool *pool = (slang_mempool *) ctx->Shader.MemPool;
+      (void) pool;
+      ASSERT(is_valid_address(pool, addr));
+   }
+#endif
+}
diff --git a/src/mesa/slang/slang_mem.h b/src/mesa/slang/slang_mem.h
new file mode 100644 (file)
index 0000000..b5bfae2
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.3
+ *
+ * Copyright (C) 2005-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.
+ */
+
+
+#ifndef SLANG_MEM_H
+#define SLANG_MEM_H
+
+
+#include "main/imports.h"
+
+
+typedef struct slang_mempool_ slang_mempool;
+
+
+extern slang_mempool *
+_slang_new_mempool(GLuint initialSize);
+
+extern void
+_slang_delete_mempool(slang_mempool *pool);
+
+extern void *
+_slang_alloc(GLuint bytes);
+
+extern void *
+_slang_realloc(void *oldBuffer, GLuint oldSize, GLuint newSize);
+
+extern char *
+_slang_strdup(const char *s);
+
+extern void
+_slang_free(void *addr);
+
+
+#endif
diff --git a/src/mesa/slang/slang_print.c b/src/mesa/slang/slang_print.c
new file mode 100644 (file)
index 0000000..6b34f39
--- /dev/null
@@ -0,0 +1,883 @@
+
+/**
+ * Dump/print a slang_operation tree
+ */
+
+
+#include "main/imports.h"
+#include "slang_compile.h"
+#include "slang_print.h"
+
+
+static void
+spaces(int n)
+{
+   while (n--)
+      printf(" ");
+}
+
+
+static void
+print_type(const slang_fully_specified_type *t)
+{
+   switch (t->qualifier) {
+   case SLANG_QUAL_NONE:
+      /*printf("");*/
+      break;
+   case SLANG_QUAL_CONST:
+      printf("const ");
+      break;
+   case SLANG_QUAL_ATTRIBUTE:
+      printf("attrib ");
+      break;
+   case SLANG_QUAL_VARYING:
+      printf("varying ");
+      break;
+   case SLANG_QUAL_UNIFORM:
+      printf("uniform ");
+      break;
+   case SLANG_QUAL_OUT:
+      printf("output ");
+      break;
+   case SLANG_QUAL_INOUT:
+      printf("inout ");
+      break;
+   case SLANG_QUAL_FIXEDOUTPUT:
+      printf("fixedoutput");
+      break;
+   case SLANG_QUAL_FIXEDINPUT:
+      printf("fixedinput");
+      break;
+   default:
+      printf("unknown qualifer!");
+   }
+
+   switch (t->specifier.type) {
+   case SLANG_SPEC_VOID:
+      printf("void");
+      break;
+   case SLANG_SPEC_BOOL:
+      printf("bool");
+      break;
+   case SLANG_SPEC_BVEC2:
+      printf("bvec2");
+      break;
+   case SLANG_SPEC_BVEC3:
+      printf("bvec3");
+      break;
+   case SLANG_SPEC_BVEC4:
+      printf("bvec4");
+      break;
+   case SLANG_SPEC_INT:
+      printf("int");
+      break;
+   case SLANG_SPEC_IVEC2:
+      printf("ivec2");
+      break;
+   case SLANG_SPEC_IVEC3:
+      printf("ivec3");
+      break;
+   case SLANG_SPEC_IVEC4:
+      printf("ivec4");
+      break;
+   case SLANG_SPEC_FLOAT:
+      printf("float");
+      break;
+   case SLANG_SPEC_VEC2:
+      printf("vec2");
+      break;
+   case SLANG_SPEC_VEC3:
+      printf("vec3");
+      break;
+   case SLANG_SPEC_VEC4:
+      printf("vec4");
+      break;
+   case SLANG_SPEC_MAT2:
+      printf("mat2");
+      break;
+   case SLANG_SPEC_MAT3:
+      printf("mat3");
+      break;
+   case SLANG_SPEC_MAT4:
+      printf("mat4");
+      break;
+   case SLANG_SPEC_MAT23:
+      printf("mat2x3");
+      break;
+   case SLANG_SPEC_MAT32:
+      printf("mat3x2");
+      break;
+   case SLANG_SPEC_MAT24:
+      printf("mat2x4");
+      break;
+   case SLANG_SPEC_MAT42:
+      printf("mat4x2");
+      break;
+   case SLANG_SPEC_MAT34:
+      printf("mat3x4");
+      break;
+   case SLANG_SPEC_MAT43:
+      printf("mat4x3");
+      break;
+   case SLANG_SPEC_SAMPLER_1D:
+      printf("sampler1D");
+      break;
+   case SLANG_SPEC_SAMPLER_2D:
+      printf("sampler2D");
+      break;
+   case SLANG_SPEC_SAMPLER_3D:
+      printf("sampler3D");
+      break;
+   case SLANG_SPEC_SAMPLER_CUBE:
+      printf("samplerCube");
+      break;
+   case SLANG_SPEC_SAMPLER_1D_SHADOW:
+      printf("sampler1DShadow");
+      break;
+   case SLANG_SPEC_SAMPLER_2D_SHADOW:
+      printf("sampler2DShadow");
+      break;
+   case SLANG_SPEC_STRUCT:
+      printf("struct");
+      break;
+   case SLANG_SPEC_ARRAY:
+      printf("array");
+      break;
+   default:
+      printf("unknown type");
+   }
+   /*printf("\n");*/
+}
+
+
+static void
+print_variable(const slang_variable *v, int indent)
+{
+   spaces(indent);
+   printf("VAR ");
+   print_type(&v->type);
+   printf(" %s (at %p)", (char *) v->a_name, (void *) v);
+   if (v->initializer) {
+      printf(" :=\n");
+      slang_print_tree(v->initializer, indent + 3);
+   }
+   else {
+      printf(";\n");
+   }
+}
+
+
+static void
+print_binary(const slang_operation *op, const char *oper, int indent)
+{
+   assert(op->num_children == 2);
+#if 0
+   printf("binary at %p locals=%p outer=%p\n",
+          (void *) op,
+          (void *) op->locals,
+          (void *) op->locals->outer_scope);
+#endif
+   slang_print_tree(&op->children[0], indent + 3);
+   spaces(indent);
+   printf("%s at %p locals=%p outer=%p\n",
+          oper, (void *) op, (void *) op->locals,
+          (void *) op->locals->outer_scope);
+   slang_print_tree(&op->children[1], indent + 3);
+}
+
+
+static void
+print_generic2(const slang_operation *op, const char *oper,
+               const char *s, int indent)
+{
+   GLuint i;
+   if (oper) {
+      spaces(indent);
+      printf("%s %s at %p locals=%p outer=%p\n",
+             oper, s, (void *) op, (void *) op->locals, 
+             (void *) op->locals->outer_scope);
+   }
+   for (i = 0; i < op->num_children; i++) {
+      spaces(indent);
+      printf("//child %u of %u:\n", i, op->num_children);
+      slang_print_tree(&op->children[i], indent);
+   }
+}
+
+static void
+print_generic(const slang_operation *op, const char *oper, int indent)
+{
+   print_generic2(op, oper, "", indent);
+}
+
+
+static const slang_variable_scope *
+find_scope(const slang_variable_scope *s, slang_atom name)
+{
+   GLuint i;
+   for (i = 0; i < s->num_variables; i++) {
+      if (s->variables[i]->a_name == name)
+         return s;
+   }
+   if (s->outer_scope)
+      return find_scope(s->outer_scope, name);
+   else
+      return NULL;
+}
+
+static const slang_variable *
+find_var(const slang_variable_scope *s, slang_atom name)
+{
+   GLuint i;
+   for (i = 0; i < s->num_variables; i++) {
+      if (s->variables[i]->a_name == name)
+         return s->variables[i];
+   }
+   if (s->outer_scope)
+      return find_var(s->outer_scope, name);
+   else
+      return NULL;
+}
+
+
+void
+slang_print_tree(const slang_operation *op, int indent)
+{
+   GLuint i;
+
+   switch (op->type) {
+
+   case SLANG_OPER_NONE:
+      spaces(indent);
+      printf("SLANG_OPER_NONE\n");
+      break;
+
+   case SLANG_OPER_BLOCK_NO_NEW_SCOPE:
+      spaces(indent);
+      printf("{ locals=%p  outer=%p\n", (void*)op->locals, (void*)op->locals->outer_scope);
+      print_generic(op, NULL, indent+3);
+      spaces(indent);
+      printf("}\n");
+      break;
+
+   case SLANG_OPER_BLOCK_NEW_SCOPE:
+   case SLANG_OPER_NON_INLINED_CALL:
+      spaces(indent);
+      printf("{{ // new scope  locals=%p outer=%p: ",
+             (void *) op->locals,
+             (void *) op->locals->outer_scope);
+      for (i = 0; i < op->locals->num_variables; i++) {
+         printf("%s ", (char *) op->locals->variables[i]->a_name);
+      }
+      printf("\n");
+      print_generic(op, NULL, indent+3);
+      spaces(indent);
+      printf("}}\n");
+      break;
+
+   case SLANG_OPER_VARIABLE_DECL:
+      assert(op->num_children == 0 || op->num_children == 1);
+      {
+         slang_variable *v;
+         v = _slang_variable_locate(op->locals, op->a_id, GL_TRUE);
+         if (v) {
+            const slang_variable_scope *scope;
+            spaces(indent);
+            printf("DECL (locals=%p outer=%p) ", (void*)op->locals, (void*) op->locals->outer_scope);
+            print_type(&v->type);
+            printf(" %s (%p)", (char *) op->a_id,
+                   (void *) find_var(op->locals, op->a_id));
+
+            scope = find_scope(op->locals, op->a_id);
+            printf(" (in scope %p) ", (void *) scope);
+            assert(scope);
+            if (op->num_children == 1) {
+               printf(" :=\n");
+               slang_print_tree(&op->children[0], indent + 3);
+            }
+            else if (v->initializer) {
+               printf(" := INITIALIZER\n");
+               slang_print_tree(v->initializer, indent + 3);
+            }
+            else {
+               printf(";\n");
+            }
+            /*
+            spaces(indent);
+            printf("TYPE: ");
+            print_type(&v->type);
+            spaces(indent);
+            printf("ADDR: %d  size: %d\n", v->address, v->size);
+            */
+         }
+         else {
+            spaces(indent);
+            printf("DECL %s (anonymous variable!!!!)\n", (char *) op->a_id);
+         }
+      }
+      break;
+
+   case SLANG_OPER_ASM:
+      spaces(indent);
+      printf("ASM: %s at %p locals=%p outer=%p\n",
+             (char *) op->a_id,
+             (void *) op,
+             (void *) op->locals,
+             (void *) op->locals->outer_scope);
+      print_generic(op, "ASM", indent+3);
+      break;
+
+   case SLANG_OPER_BREAK:
+      spaces(indent);
+      printf("BREAK\n");
+      break;
+
+   case SLANG_OPER_CONTINUE:
+      spaces(indent);
+      printf("CONTINUE\n");
+      break;
+
+   case SLANG_OPER_DISCARD:
+      spaces(indent);
+      printf("DISCARD\n");
+      break;
+
+   case SLANG_OPER_RETURN:
+      spaces(indent);
+      printf("RETURN\n");
+      if (op->num_children > 0)
+         slang_print_tree(&op->children[0], indent + 3);
+      break;
+
+   case SLANG_OPER_RETURN_INLINED:
+      spaces(indent);
+      printf("RETURN_INLINED\n");
+      if (op->num_children > 0)
+         slang_print_tree(&op->children[0], indent + 3);
+      break;
+
+   case SLANG_OPER_LABEL:
+      spaces(indent);
+      printf("LABEL %s\n", (char *) op->a_id);
+      break;
+
+   case SLANG_OPER_EXPRESSION:
+      spaces(indent);
+      printf("EXPR:  locals=%p outer=%p\n",
+             (void *) op->locals,
+             (void *) op->locals->outer_scope);
+      /*print_generic(op, "SLANG_OPER_EXPRESSION", indent);*/
+      slang_print_tree(&op->children[0], indent + 3);
+      break;
+
+   case SLANG_OPER_IF:
+      spaces(indent);
+      printf("IF\n");
+      slang_print_tree(&op->children[0], indent + 3);
+      spaces(indent);
+      printf("THEN\n");
+      slang_print_tree(&op->children[1], indent + 3);
+      spaces(indent);
+      printf("ELSE\n");
+      slang_print_tree(&op->children[2], indent + 3);
+      spaces(indent);
+      printf("ENDIF\n");
+      break;
+
+   case SLANG_OPER_WHILE:
+      assert(op->num_children == 2);
+      spaces(indent);
+      printf("WHILE LOOP: locals = %p\n", (void *) op->locals);
+      indent += 3;
+      spaces(indent);
+      printf("WHILE cond:\n");
+      slang_print_tree(&op->children[0], indent + 3);
+      spaces(indent);
+      printf("WHILE body:\n");
+      slang_print_tree(&op->children[1], indent + 3);
+      indent -= 3;
+      spaces(indent);
+      printf("END WHILE LOOP\n");
+      break;
+
+   case SLANG_OPER_DO:
+      spaces(indent);
+      printf("DO LOOP: locals = %p\n", (void *) op->locals);
+      indent += 3;
+      spaces(indent);
+      printf("DO body:\n");
+      slang_print_tree(&op->children[0], indent + 3);
+      spaces(indent);
+      printf("DO cond:\n");
+      slang_print_tree(&op->children[1], indent + 3);
+      indent -= 3;
+      spaces(indent);
+      printf("END DO LOOP\n");
+      break;
+
+   case SLANG_OPER_FOR:
+      spaces(indent);
+      printf("FOR LOOP: locals = %p\n", (void *) op->locals);
+      indent += 3;
+      spaces(indent);
+      printf("FOR init:\n");
+      slang_print_tree(&op->children[0], indent + 3);
+      spaces(indent);
+      printf("FOR condition:\n");
+      slang_print_tree(&op->children[1], indent + 3);
+      spaces(indent);
+      printf("FOR step:\n");
+      slang_print_tree(&op->children[2], indent + 3);
+      spaces(indent);
+      printf("FOR body:\n");
+      slang_print_tree(&op->children[3], indent + 3);
+      indent -= 3;
+      spaces(indent);
+      printf("ENDFOR\n");
+      /*
+      print_generic(op, "FOR", indent + 3);
+      */
+      break;
+
+   case SLANG_OPER_VOID:
+      spaces(indent);
+      printf("(oper-void)\n");
+      break;
+
+   case SLANG_OPER_LITERAL_BOOL:
+      spaces(indent);
+      printf("LITERAL (");
+      for (i = 0; i < op->literal_size; i++)
+         printf("%s ", op->literal[0] ? "TRUE" : "FALSE");
+      printf(")\n");
+
+      break;
+
+   case SLANG_OPER_LITERAL_INT:
+      spaces(indent);
+      printf("LITERAL (");
+      for (i = 0; i < op->literal_size; i++)
+         printf("%d ", (int) op->literal[i]);
+      printf(")\n");
+      break;
+
+   case SLANG_OPER_LITERAL_FLOAT:
+      spaces(indent);
+      printf("LITERAL (");
+      for (i = 0; i < op->literal_size; i++)
+         printf("%f ", op->literal[i]);
+      printf(")\n");
+      break;
+
+   case SLANG_OPER_IDENTIFIER:
+      {
+         const slang_variable_scope *scope;
+         spaces(indent);
+         if (op->var && op->var->a_name) {
+            scope = find_scope(op->locals, op->var->a_name);
+            printf("VAR %s  (in scope %p)\n", (char *) op->var->a_name,
+                   (void *) scope);
+            assert(scope);
+         }
+         else {
+            scope = find_scope(op->locals, op->a_id);
+            printf("VAR' %s  (in scope %p) locals=%p outer=%p\n",
+                   (char *) op->a_id,
+                   (void *) scope,
+                   (void *) op->locals,
+                   (void *) op->locals->outer_scope);
+            /*assert(scope);*/
+         }
+      }
+      break;
+
+   case SLANG_OPER_SEQUENCE:
+      print_generic(op, "COMMA-SEQ", indent+3);
+      break;
+
+   case SLANG_OPER_ASSIGN:
+      spaces(indent);
+      printf("ASSIGNMENT  locals=%p outer=%p\n",
+             (void *) op->locals,
+             (void *) op->locals->outer_scope);
+      print_binary(op, ":=", indent);
+      break;
+
+   case SLANG_OPER_ADDASSIGN:
+      spaces(indent);
+      printf("ASSIGN\n");
+      print_binary(op, "+=", indent);
+      break;
+
+   case SLANG_OPER_SUBASSIGN:
+      spaces(indent);
+      printf("ASSIGN\n");
+      print_binary(op, "-=", indent);
+      break;
+
+   case SLANG_OPER_MULASSIGN:
+      spaces(indent);
+      printf("ASSIGN\n");
+      print_binary(op, "*=", indent);
+      break;
+
+   case SLANG_OPER_DIVASSIGN:
+      spaces(indent);
+      printf("ASSIGN\n");
+      print_binary(op, "/=", indent);
+      break;
+
+       /*SLANG_OPER_MODASSIGN,*/
+       /*SLANG_OPER_LSHASSIGN,*/
+       /*SLANG_OPER_RSHASSIGN,*/
+       /*SLANG_OPER_ORASSIGN,*/
+       /*SLANG_OPER_XORASSIGN,*/
+       /*SLANG_OPER_ANDASSIGN,*/
+   case SLANG_OPER_SELECT:
+      spaces(indent);
+      printf("SLANG_OPER_SELECT n=%d\n", op->num_children);
+      assert(op->num_children == 3);
+      slang_print_tree(&op->children[0], indent+3);
+      spaces(indent);
+      printf("?\n");
+      slang_print_tree(&op->children[1], indent+3);
+      spaces(indent);
+      printf(":\n");
+      slang_print_tree(&op->children[2], indent+3);
+      break;
+
+   case SLANG_OPER_LOGICALOR:
+      print_binary(op, "||", indent);
+      break;
+
+   case SLANG_OPER_LOGICALXOR:
+      print_binary(op, "^^", indent);
+      break;
+
+   case SLANG_OPER_LOGICALAND:
+      print_binary(op, "&&", indent);
+      break;
+
+   /*SLANG_OPER_BITOR*/
+   /*SLANG_OPER_BITXOR*/
+   /*SLANG_OPER_BITAND*/
+   case SLANG_OPER_EQUAL:
+      print_binary(op, "==", indent);
+      break;
+
+   case SLANG_OPER_NOTEQUAL:
+      print_binary(op, "!=", indent);
+      break;
+
+   case SLANG_OPER_LESS:
+      print_binary(op, "<", indent);
+      break;
+
+   case SLANG_OPER_GREATER:
+      print_binary(op, ">", indent);
+      break;
+
+   case SLANG_OPER_LESSEQUAL:
+      print_binary(op, "<=", indent);
+      break;
+
+   case SLANG_OPER_GREATEREQUAL:
+      print_binary(op, ">=", indent);
+      break;
+
+   /*SLANG_OPER_LSHIFT*/
+   /*SLANG_OPER_RSHIFT*/
+   case SLANG_OPER_ADD:
+      print_binary(op, "+", indent);
+      break;
+
+   case SLANG_OPER_SUBTRACT:
+      print_binary(op, "-", indent);
+      break;
+
+   case SLANG_OPER_MULTIPLY:
+      print_binary(op, "*", indent);
+      break;
+
+   case SLANG_OPER_DIVIDE:
+      print_binary(op, "/", indent);
+      break;
+
+   /*SLANG_OPER_MODULUS*/
+   case SLANG_OPER_PREINCREMENT:
+      spaces(indent);
+      printf("PRE++\n");
+      slang_print_tree(&op->children[0], indent+3);
+      break;
+
+   case SLANG_OPER_PREDECREMENT:
+      spaces(indent);
+      printf("PRE--\n");
+      slang_print_tree(&op->children[0], indent+3);
+      break;
+
+   case SLANG_OPER_PLUS:
+      spaces(indent);
+      printf("SLANG_OPER_PLUS\n");
+      break;
+
+   case SLANG_OPER_MINUS:
+      spaces(indent);
+      printf("SLANG_OPER_MINUS\n");
+      break;
+
+   /*SLANG_OPER_COMPLEMENT*/
+   case SLANG_OPER_NOT:
+      spaces(indent);
+      printf("NOT\n");
+      slang_print_tree(&op->children[0], indent+3);
+      break;
+
+   case SLANG_OPER_SUBSCRIPT:
+      spaces(indent);
+      printf("SLANG_OPER_SUBSCRIPT locals=%p outer=%p\n",
+             (void *) op->locals,
+             (void *) op->locals->outer_scope);
+      print_generic(op, NULL, indent+3);
+      break;
+
+   case SLANG_OPER_CALL:
+#if 0
+         slang_function *fun
+            = _slang_function_locate(A->space.funcs, oper->a_id,
+                                     oper->children,
+                                     oper->num_children, &A->space, A->atoms);
+#endif
+      spaces(indent);
+      printf("CALL %s(\n", (char *) op->a_id);
+      for (i = 0; i < op->num_children; i++) {
+         slang_print_tree(&op->children[i], indent+3);
+         if (i + 1 < op->num_children) {
+            spaces(indent + 3);
+            printf(",\n");
+         }
+      }
+      spaces(indent);
+      printf(")\n");
+      break;
+
+   case SLANG_OPER_METHOD:
+      spaces(indent);
+      printf("METHOD CALL %s.%s\n", (char *) op->a_obj, (char *) op->a_id);
+      break;
+
+   case SLANG_OPER_FIELD:
+      spaces(indent);
+      printf("FIELD %s of\n", (char*) op->a_id);
+      slang_print_tree(&op->children[0], indent+3);
+      break;
+
+   case SLANG_OPER_POSTINCREMENT:
+      spaces(indent);
+      printf("POST++\n");
+      slang_print_tree(&op->children[0], indent+3);
+      break;
+
+   case SLANG_OPER_POSTDECREMENT:
+      spaces(indent);
+      printf("POST--\n");
+      slang_print_tree(&op->children[0], indent+3);
+      break;
+
+   default:
+      printf("unknown op->type %d\n", (int) op->type);
+   }
+
+}
+
+
+
+void
+slang_print_function(const slang_function *f, GLboolean body)
+{
+   GLuint i;
+
+#if 0
+   if (strcmp((char *) f->header.a_name, "main") != 0)
+     return;
+#endif
+
+   printf("FUNCTION %s ( scope=%p\n",
+          (char *) f->header.a_name, (void *) f->parameters);
+
+   for (i = 0; i < f->param_count; i++) {
+      print_variable(f->parameters->variables[i], 3);
+   }
+
+   printf(") param scope = %p\n", (void *) f->parameters);
+
+   if (body && f->body)
+      slang_print_tree(f->body, 0);
+}
+
+
+
+
+
+const char *
+slang_type_qual_string(slang_type_qualifier q)
+{
+   switch (q) {
+   case SLANG_QUAL_NONE:
+      return "none";
+   case SLANG_QUAL_CONST:
+      return "const";
+   case SLANG_QUAL_ATTRIBUTE:
+      return "attribute";
+   case SLANG_QUAL_VARYING:
+      return "varying";
+   case SLANG_QUAL_UNIFORM:
+      return "uniform";
+   case SLANG_QUAL_OUT:
+      return "out";
+   case SLANG_QUAL_INOUT:
+      return "inout";
+   case SLANG_QUAL_FIXEDOUTPUT:
+      return "fixedoutput";
+   case SLANG_QUAL_FIXEDINPUT:
+      return "fixedinputk";
+   default:
+      return "qual?";
+   }
+}
+
+
+static const char *
+slang_type_string(slang_type_specifier_type t)
+{
+   switch (t) {
+   case SLANG_SPEC_VOID:
+      return "void";
+   case SLANG_SPEC_BOOL:
+      return "bool";
+   case SLANG_SPEC_BVEC2:
+      return "bvec2";
+   case SLANG_SPEC_BVEC3:
+      return "bvec3";
+   case SLANG_SPEC_BVEC4:
+      return "bvec4";
+   case SLANG_SPEC_INT:
+      return "int";
+   case SLANG_SPEC_IVEC2:
+      return "ivec2";
+   case SLANG_SPEC_IVEC3:
+      return "ivec3";
+   case SLANG_SPEC_IVEC4:
+      return "ivec4";
+   case SLANG_SPEC_FLOAT:
+      return "float";
+   case SLANG_SPEC_VEC2:
+      return "vec2";
+   case SLANG_SPEC_VEC3:
+      return "vec3";
+   case SLANG_SPEC_VEC4:
+      return "vec4";
+   case SLANG_SPEC_MAT2:
+      return "mat2";
+   case SLANG_SPEC_MAT3:
+      return "mat3";
+   case SLANG_SPEC_MAT4:
+      return "mat4";
+   case SLANG_SPEC_SAMPLER_1D:
+      return "sampler1D";
+   case SLANG_SPEC_SAMPLER_2D:
+      return "sampler2D";
+   case SLANG_SPEC_SAMPLER_3D:
+      return "sampler3D";
+   case SLANG_SPEC_SAMPLER_CUBE:
+      return "samplerCube";
+   case SLANG_SPEC_SAMPLER_1D_SHADOW:
+      return "sampler1DShadow";
+   case SLANG_SPEC_SAMPLER_2D_SHADOW:
+      return "sampler2DShadow";
+   case SLANG_SPEC_SAMPLER_RECT:
+      return "sampler2DRect";
+   case SLANG_SPEC_SAMPLER_RECT_SHADOW:
+      return "sampler2DRectShadow";
+   case SLANG_SPEC_STRUCT:
+      return "struct";
+   case SLANG_SPEC_ARRAY:
+      return "array";
+   default:
+      return "type?";
+   }
+}
+
+
+static const char *
+slang_fq_type_string(const slang_fully_specified_type *t)
+{
+   static char str[1000];
+   _mesa_snprintf(str, sizeof(str), "%s %s", slang_type_qual_string(t->qualifier),
+      slang_type_string(t->specifier.type));
+   return str;
+}
+
+
+void
+slang_print_type(const slang_fully_specified_type *t)
+{
+   printf("%s %s", slang_type_qual_string(t->qualifier),
+      slang_type_string(t->specifier.type));
+}
+
+
+#if 0
+static char *
+slang_var_string(const slang_variable *v)
+{
+   static char str[1000];
+   _mesa_snprintf(str, sizeof(str), "%s : %s",
+                  (char *) v->a_name,
+                  slang_fq_type_string(&v->type));
+   return str;
+}
+#endif
+
+
+void
+slang_print_variable(const slang_variable *v)
+{
+   printf("Name: %s\n", (char *) v->a_name);
+   printf("Type: %s\n", slang_fq_type_string(&v->type));
+}
+
+
+void
+_slang_print_var_scope(const slang_variable_scope *vars, int indent)
+{
+   GLuint i;
+
+   spaces(indent);
+   printf("Var scope %p  %d vars:\n", (void *) vars, vars->num_variables);
+   for (i = 0; i < vars->num_variables; i++) {
+      spaces(indent + 3);
+      printf("%s (at %p)\n", (char *) vars->variables[i]->a_name, (void*) (vars->variables + i));
+   }
+   spaces(indent + 3);
+   printf("outer_scope = %p\n", (void*) vars->outer_scope);
+
+   if (vars->outer_scope) {
+      /*spaces(indent + 3);*/
+      _slang_print_var_scope(vars->outer_scope, indent + 3);
+   }
+}
+
+
+
+int
+slang_checksum_tree(const slang_operation *op)
+{
+   int s = op->num_children;
+   GLuint i;
+
+   for (i = 0; i < op->num_children; i++) {
+      s += slang_checksum_tree(&op->children[i]);
+   }
+   return s;
+}
diff --git a/src/mesa/slang/slang_print.h b/src/mesa/slang/slang_print.h
new file mode 100644 (file)
index 0000000..46605c8
--- /dev/null
@@ -0,0 +1,29 @@
+
+
+#ifndef SLANG_PRINT
+#define SLANG_PRINT
+
+extern void
+slang_print_function(const slang_function *f, GLboolean body);
+
+extern void
+slang_print_tree(const slang_operation *op, int indent);
+
+extern const char *
+slang_type_qual_string(slang_type_qualifier q);
+
+extern void
+slang_print_type(const slang_fully_specified_type *t);
+
+extern void
+slang_print_variable(const slang_variable *v);
+
+extern void
+_slang_print_var_scope(const slang_variable_scope *s, int indent);
+
+
+extern int
+slang_checksum_tree(const slang_operation *op);
+
+#endif /* SLANG_PRINT */
+
diff --git a/src/mesa/slang/slang_simplify.c b/src/mesa/slang/slang_simplify.c
new file mode 100644 (file)
index 0000000..13b9ca3
--- /dev/null
@@ -0,0 +1,527 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.1
+ *
+ * Copyright (C) 2005-2008  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.
+ */
+
+/**
+ * Functions for constant folding, built-in constant lookup, and function
+ * call casting.
+ */
+
+
+#include "main/imports.h"
+#include "main/macros.h"
+#include "main/get.h"
+#include "slang_compile.h"
+#include "slang_codegen.h"
+#include "slang_simplify.h"
+#include "slang_print.h"
+
+
+#ifndef GL_MAX_FRAGMENT_UNIFORM_VECTORS
+#define GL_MAX_FRAGMENT_UNIFORM_VECTORS     0x8DFD
+#endif
+#ifndef GL_MAX_VERTEX_UNIFORM_VECTORS
+#define GL_MAX_VERTEX_UNIFORM_VECTORS       0x8DFB
+#endif
+#ifndef GL_MAX_VARYING_VECTORS
+#define GL_MAX_VARYING_VECTORS              0x8DFC
+#endif
+
+
+/**
+ * Lookup the value of named constant, such as gl_MaxLights.
+ * \return value of constant, or -1 if unknown
+ */
+GLint
+_slang_lookup_constant(const char *name)
+{
+   struct constant_info {
+      const char *Name;
+      const GLenum Token;
+   };
+   static const struct constant_info info[] = {
+      { "gl_MaxClipPlanes", GL_MAX_CLIP_PLANES },
+      { "gl_MaxCombinedTextureImageUnits", GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS },
+      { "gl_MaxDrawBuffers", GL_MAX_DRAW_BUFFERS },
+      { "gl_MaxFragmentUniformComponents", GL_MAX_FRAGMENT_UNIFORM_COMPONENTS },
+      { "gl_MaxLights", GL_MAX_LIGHTS },
+      { "gl_MaxTextureUnits", GL_MAX_TEXTURE_UNITS },
+      { "gl_MaxTextureCoords", GL_MAX_TEXTURE_COORDS },
+      { "gl_MaxVertexAttribs", GL_MAX_VERTEX_ATTRIBS },
+      { "gl_MaxVertexUniformComponents", GL_MAX_VERTEX_UNIFORM_COMPONENTS },
+      { "gl_MaxVaryingFloats", GL_MAX_VARYING_FLOATS },
+      { "gl_MaxVertexTextureImageUnits", GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS },
+      { "gl_MaxTextureImageUnits", GL_MAX_TEXTURE_IMAGE_UNITS },
+#if FEATURE_es2_glsl
+      { "gl_MaxVertexUniformVectors", GL_MAX_VERTEX_UNIFORM_VECTORS },
+      { "gl_MaxVaryingVectors", GL_MAX_VARYING_VECTORS },
+      { "gl_MaxFragmentUniformVectors", GL_MAX_FRAGMENT_UNIFORM_VECTORS },
+#endif
+      { NULL, 0 }
+   };
+   GLuint i;
+
+   for (i = 0; info[i].Name; i++) {
+      if (strcmp(info[i].Name, name) == 0) {
+         /* found */
+         GLint values[16];
+         values[0] = -1;
+         _mesa_GetIntegerv(info[i].Token, values);
+         ASSERT(values[0] >= 0);  /* sanity check that glGetFloatv worked */
+         return values[0];
+      }
+   }
+   return -1;
+}
+
+
+static slang_operation_type
+literal_type(slang_operation_type t1, slang_operation_type t2)
+{
+   if (t1 == SLANG_OPER_LITERAL_FLOAT || t2 == SLANG_OPER_LITERAL_FLOAT)
+      return SLANG_OPER_LITERAL_FLOAT;
+   else
+      return SLANG_OPER_LITERAL_INT;
+}
+
+
+/**
+ * Recursively traverse an AST tree, applying simplifications wherever
+ * possible.
+ * At the least, we do constant folding.  We need to do that much so that
+ * compile-time expressions can be evaluated for things like array
+ * declarations.  I.e.:  float foo[3 + 5];
+ */
+void
+_slang_simplify(slang_operation *oper,
+                const slang_name_space * space,
+                slang_atom_pool * atoms)
+{
+   GLboolean isFloat[4];
+   GLboolean isBool[4];
+   GLuint i, n;
+
+   if (oper->type == SLANG_OPER_IDENTIFIER) {
+      /* see if it's a named constant */
+      GLint value = _slang_lookup_constant((char *) oper->a_id);
+      /*printf("value[%s] = %d\n", (char*) oper->a_id, value);*/
+      if (value >= 0) {
+         oper->literal[0] =
+         oper->literal[1] =
+         oper->literal[2] =
+         oper->literal[3] = (GLfloat) value;
+         oper->type = SLANG_OPER_LITERAL_INT;
+         return;
+      }
+      /* look for user-defined constant */
+      {
+         slang_variable *var;
+         var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE);
+         if (var) {
+            if (var->type.qualifier == SLANG_QUAL_CONST &&
+                var->initializer &&
+                (var->initializer->type == SLANG_OPER_LITERAL_INT ||
+                 var->initializer->type == SLANG_OPER_LITERAL_FLOAT)) {
+               oper->literal[0] = var->initializer->literal[0];
+               oper->literal[1] = var->initializer->literal[1];
+               oper->literal[2] = var->initializer->literal[2];
+               oper->literal[3] = var->initializer->literal[3];
+               oper->literal_size = var->initializer->literal_size;
+               oper->type = var->initializer->type;
+               /*
+               printf("value[%s] = %f\n",
+                      (char*) oper->a_id, oper->literal[0]);
+               */
+               return;
+            }
+         }
+      }
+   }
+
+   /* first, simplify children */
+   for (i = 0; i < oper->num_children; i++) {
+      _slang_simplify(&oper->children[i], space, atoms);
+   }
+
+   /* examine children */
+   n = MIN2(oper->num_children, 4);
+   for (i = 0; i < n; i++) {
+      isFloat[i] = (oper->children[i].type == SLANG_OPER_LITERAL_FLOAT ||
+                   oper->children[i].type == SLANG_OPER_LITERAL_INT);
+      isBool[i] = (oper->children[i].type == SLANG_OPER_LITERAL_BOOL);
+   }
+                              
+   if (oper->num_children == 2 && isFloat[0] && isFloat[1]) {
+      /* probably simple arithmetic */
+      switch (oper->type) {
+      case SLANG_OPER_ADD:
+         for (i = 0; i < 4; i++) {
+            oper->literal[i]
+               = oper->children[0].literal[i] + oper->children[1].literal[i];
+         }
+         oper->literal_size = oper->children[0].literal_size;
+         oper->type = literal_type(oper->children[0].type, 
+                                   oper->children[1].type);
+         slang_operation_destruct(oper);  /* frees unused children */
+         return;
+      case SLANG_OPER_SUBTRACT:
+         for (i = 0; i < 4; i++) {
+            oper->literal[i]
+               = oper->children[0].literal[i] - oper->children[1].literal[i];
+         }
+         oper->literal_size = oper->children[0].literal_size;
+         oper->type = literal_type(oper->children[0].type, 
+                                   oper->children[1].type);
+         slang_operation_destruct(oper);
+         return;
+      case SLANG_OPER_MULTIPLY:
+         for (i = 0; i < 4; i++) {
+            oper->literal[i]
+               = oper->children[0].literal[i] * oper->children[1].literal[i];
+         }
+         oper->literal_size = oper->children[0].literal_size;
+         oper->type = literal_type(oper->children[0].type, 
+                                   oper->children[1].type);
+         slang_operation_destruct(oper);
+         return;
+      case SLANG_OPER_DIVIDE:
+         for (i = 0; i < 4; i++) {
+            oper->literal[i]
+               = oper->children[0].literal[i] / oper->children[1].literal[i];
+         }
+         oper->literal_size = oper->children[0].literal_size;
+         oper->type = literal_type(oper->children[0].type, 
+                                   oper->children[1].type);
+         slang_operation_destruct(oper);
+         return;
+      default:
+         ; /* nothing */
+      }
+   }
+
+   if (oper->num_children == 1 && isFloat[0]) {
+      switch (oper->type) {
+      case SLANG_OPER_MINUS:
+         for (i = 0; i < 4; i++) {
+            oper->literal[i] = -oper->children[0].literal[i];
+         }
+         oper->literal_size = oper->children[0].literal_size;
+         slang_operation_destruct(oper);
+         oper->type = SLANG_OPER_LITERAL_FLOAT;
+         return;
+      case SLANG_OPER_PLUS:
+         COPY_4V(oper->literal, oper->children[0].literal);
+         oper->literal_size = oper->children[0].literal_size;
+         slang_operation_destruct(oper);
+         oper->type = SLANG_OPER_LITERAL_FLOAT;
+         return;
+      default:
+         ; /* nothing */
+      }
+   }
+
+   if (oper->num_children == 2 && isBool[0] && isBool[1]) {
+      /* simple boolean expression */
+      switch (oper->type) {
+      case SLANG_OPER_LOGICALAND:
+         for (i = 0; i < 4; i++) {
+            const GLint a = oper->children[0].literal[i] ? 1 : 0;
+            const GLint b = oper->children[1].literal[i] ? 1 : 0;
+            oper->literal[i] = (GLfloat) (a && b);
+         }
+         oper->literal_size = oper->children[0].literal_size;
+         slang_operation_destruct(oper);
+         oper->type = SLANG_OPER_LITERAL_BOOL;
+         return;
+      case SLANG_OPER_LOGICALOR:
+         for (i = 0; i < 4; i++) {
+            const GLint a = oper->children[0].literal[i] ? 1 : 0;
+            const GLint b = oper->children[1].literal[i] ? 1 : 0;
+            oper->literal[i] = (GLfloat) (a || b);
+         }
+         oper->literal_size = oper->children[0].literal_size;
+         slang_operation_destruct(oper);
+         oper->type = SLANG_OPER_LITERAL_BOOL;
+         return;
+      case SLANG_OPER_LOGICALXOR:
+         for (i = 0; i < 4; i++) {
+            const GLint a = oper->children[0].literal[i] ? 1 : 0;
+            const GLint b = oper->children[1].literal[i] ? 1 : 0;
+            oper->literal[i] = (GLfloat) (a ^ b);
+         }
+         oper->literal_size = oper->children[0].literal_size;
+         slang_operation_destruct(oper);
+         oper->type = SLANG_OPER_LITERAL_BOOL;
+         return;
+      default:
+         ; /* nothing */
+      }
+   }
+
+   if (oper->num_children == 4
+       && isFloat[0] && isFloat[1] && isFloat[2] && isFloat[3]) {
+      /* vec4(flt, flt, flt, flt) constructor */
+      if (oper->type == SLANG_OPER_CALL) {
+         if (strcmp((char *) oper->a_id, "vec4") == 0) {
+            oper->literal[0] = oper->children[0].literal[0];
+            oper->literal[1] = oper->children[1].literal[0];
+            oper->literal[2] = oper->children[2].literal[0];
+            oper->literal[3] = oper->children[3].literal[0];
+            oper->literal_size = 4;
+            slang_operation_destruct(oper);
+            oper->type = SLANG_OPER_LITERAL_FLOAT;
+            return;
+         }
+      }
+   }
+
+   if (oper->num_children == 3 && isFloat[0] && isFloat[1] && isFloat[2]) {
+      /* vec3(flt, flt, flt) constructor */
+      if (oper->type == SLANG_OPER_CALL) {
+         if (strcmp((char *) oper->a_id, "vec3") == 0) {
+            oper->literal[0] = oper->children[0].literal[0];
+            oper->literal[1] = oper->children[1].literal[0];
+            oper->literal[2] = oper->children[2].literal[0];
+            oper->literal[3] = oper->literal[2];
+            oper->literal_size = 3;
+            slang_operation_destruct(oper);
+            oper->type = SLANG_OPER_LITERAL_FLOAT;
+            return;
+         }
+      }
+   }
+
+   if (oper->num_children == 2 && isFloat[0] && isFloat[1]) {
+      /* vec2(flt, flt) constructor */
+      if (oper->type == SLANG_OPER_CALL) {
+         if (strcmp((char *) oper->a_id, "vec2") == 0) {
+            oper->literal[0] = oper->children[0].literal[0];
+            oper->literal[1] = oper->children[1].literal[0];
+            oper->literal[2] = oper->literal[1];
+            oper->literal[3] = oper->literal[1];
+            oper->literal_size = 2;
+            slang_operation_destruct(oper); /* XXX oper->locals goes NULL! */
+            oper->type = SLANG_OPER_LITERAL_FLOAT;
+            assert(oper->num_children == 0);
+            return;
+         }
+      }
+   }
+
+   if (oper->num_children == 1 && isFloat[0]) {
+      /* vec2/3/4(flt, flt) constructor */
+      if (oper->type == SLANG_OPER_CALL) {
+         const char *func = (const char *) oper->a_id;
+         if (strncmp(func, "vec", 3) == 0 && func[3] >= '2' && func[3] <= '4') {
+            oper->literal[0] =
+            oper->literal[1] =
+            oper->literal[2] =
+            oper->literal[3] = oper->children[0].literal[0];
+            oper->literal_size = func[3] - '0';
+            assert(oper->literal_size >= 2);
+            assert(oper->literal_size <= 4);
+            slang_operation_destruct(oper); /* XXX oper->locals goes NULL! */
+            oper->type = SLANG_OPER_LITERAL_FLOAT;
+            assert(oper->num_children == 0);
+            return;
+         }
+      }
+   }
+}
+
+
+
+/**
+ * Insert casts to try to adapt actual parameters to formal parameters for a
+ * function call when an exact match for the parameter types is not found.
+ * Example:
+ *   void foo(int i, bool b) {}
+ *   x = foo(3.15, 9);
+ * Gets translated into:
+ *   x = foo(int(3.15), bool(9))
+ */
+GLboolean
+_slang_cast_func_params(slang_operation *callOper, const slang_function *fun,
+                        const slang_name_space * space,
+                        slang_atom_pool * atoms, slang_info_log *log)
+{
+   const GLboolean haveRetValue = _slang_function_has_return_value(fun);
+   const int numParams = fun->param_count - haveRetValue;
+   int i;
+   int dbg = 0;
+
+   if (dbg)
+      printf("Adapt call of %d args to func %s (%d params)\n",
+             callOper->num_children, (char*) fun->header.a_name, numParams);
+
+   for (i = 0; i < numParams; i++) {
+      slang_typeinfo argType;
+      slang_variable *paramVar = fun->parameters->variables[i];
+
+      /* Get type of arg[i] */
+      if (!slang_typeinfo_construct(&argType))
+         return GL_FALSE;
+      if (!_slang_typeof_operation(&callOper->children[i], space,
+                                    &argType, atoms, log)) {
+         slang_typeinfo_destruct(&argType);
+         return GL_FALSE;
+      }
+
+      /* see if arg type matches parameter type */
+      if (!slang_type_specifier_equal(&argType.spec,
+                                      &paramVar->type.specifier)) {
+         /* need to adapt arg type to match param type */
+         const char *constructorName =
+            slang_type_specifier_type_to_string(paramVar->type.specifier.type);
+         slang_operation *child = slang_operation_new(1);
+
+         if (dbg)
+            printf("Need to adapt types of arg %d\n", i);
+
+         slang_operation_copy(child, &callOper->children[i]);
+         child->locals->outer_scope = callOper->children[i].locals;
+
+#if 0
+         if (_slang_sizeof_type_specifier(&argType.spec) >
+             _slang_sizeof_type_specifier(&paramVar->type.specifier)) {
+         }
+#endif
+
+         callOper->children[i].type = SLANG_OPER_CALL;
+         callOper->children[i].a_id = slang_atom_pool_atom(atoms, constructorName);
+         callOper->children[i].num_children = 1;
+         callOper->children[i].children = child;
+      }
+
+      slang_typeinfo_destruct(&argType);
+   }
+
+   if (dbg) {
+      printf("===== New call to %s with cast arguments ===============\n",
+             (char*) fun->header.a_name);
+      slang_print_tree(callOper, 5);
+   }
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Adapt the arguments for a function call to match the parameters of
+ * the given function.
+ * This is for:
+ * 1. converting/casting argument types to match parameters
+ * 2. breaking up vector/matrix types into individual components to
+ *    satisfy constructors.
+ */
+GLboolean
+_slang_adapt_call(slang_operation *callOper, const slang_function *fun,
+                  const slang_name_space * space,
+                  slang_atom_pool * atoms, slang_info_log *log)
+{
+   const GLboolean haveRetValue = _slang_function_has_return_value(fun);
+   const int numParams = fun->param_count - haveRetValue;
+   int i;
+   int dbg = 0;
+
+   if (dbg)
+      printf("Adapt %d args to %d parameters for %s\n",
+             callOper->num_children, numParams, (char *) fun->header.a_name);
+
+   /* Only try adapting for constructors */
+   if (fun->kind != SLANG_FUNC_CONSTRUCTOR)
+      return GL_FALSE;
+
+   if (callOper->num_children != numParams) {
+      /* number of arguments doesn't match number of parameters */
+
+      /* For constructor calls, we can try to unroll vector/matrix args
+       * into individual floats/ints and try to match the function params.
+       */
+      for (i = 0; i < numParams; i++) {
+         slang_typeinfo argType;
+         GLint argSz, j;
+
+         /* Get type of arg[i] */
+         if (!slang_typeinfo_construct(&argType))
+            return GL_FALSE;
+         if (!_slang_typeof_operation(&callOper->children[i], space,
+                                       &argType, atoms, log)) {
+            slang_typeinfo_destruct(&argType);
+            return GL_FALSE;
+         }
+
+         /*
+           paramSz = _slang_sizeof_type_specifier(&paramVar->type.specifier);
+           assert(paramSz == 1);
+         */
+         argSz = _slang_sizeof_type_specifier(&argType.spec);
+         if (argSz > 1) {
+            slang_operation origArg;
+            /* break up arg[i] into components */
+            if (dbg)
+               printf("Break up arg %d from 1 to %d elements\n", i, argSz);
+
+            slang_operation_construct(&origArg);
+            slang_operation_copy(&origArg, &callOper->children[i]);
+
+            /* insert argSz-1 new children/args */
+            for (j = 0; j < argSz - 1; j++) {
+               (void) slang_operation_insert(&callOper->num_children,
+                                             &callOper->children, i);
+            }
+
+            /* replace arg[i+j] with subscript/index oper */
+            for (j = 0; j < argSz; j++) {
+               callOper->children[i + j].type = SLANG_OPER_SUBSCRIPT;
+               callOper->children[i + j].locals = _slang_variable_scope_new(callOper->locals);
+               callOper->children[i + j].num_children = 2;
+               callOper->children[i + j].children = slang_operation_new(2);
+               slang_operation_copy(&callOper->children[i + j].children[0],
+                                    &origArg);
+               callOper->children[i + j].children[1].type
+                  = SLANG_OPER_LITERAL_INT;
+               callOper->children[i + j].children[1].literal[0] = (GLfloat) j;
+            }
+         }
+      }
+   }
+
+   if (callOper->num_children < (GLuint) numParams) {
+      /* still not enough args for all params */
+      return GL_FALSE;
+   }
+   else if (callOper->num_children > (GLuint) numParams) {
+      /* now too many arguments */
+      /* just truncate */
+      callOper->num_children = (GLuint) numParams;
+   }
+
+   if (dbg) {
+      printf("===== New call to %s with adapted arguments ===============\n",
+             (char*) fun->header.a_name);
+      slang_print_tree(callOper, 5);
+   }
+
+   return GL_TRUE;
+}
diff --git a/src/mesa/slang/slang_simplify.h b/src/mesa/slang/slang_simplify.h
new file mode 100644 (file)
index 0000000..8689c23
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.1
+ *
+ * Copyright (C) 2005-2008  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 SLANG_SIMPLIFY_H
+#define SLANG_SIMPLIFY_H
+
+
+extern GLint
+_slang_lookup_constant(const char *name);
+
+
+extern void
+_slang_simplify(slang_operation *oper,
+                const slang_name_space * space,
+                slang_atom_pool * atoms);
+
+
+extern GLboolean
+_slang_cast_func_params(slang_operation *callOper, const slang_function *fun,
+                        const slang_name_space * space,
+                        slang_atom_pool * atoms, slang_info_log *log);
+
+extern GLboolean
+_slang_adapt_call(slang_operation *callOper, const slang_function *fun,
+                  const slang_name_space * space,
+                  slang_atom_pool * atoms, slang_info_log *log);
+
+
+#endif /* SLANG_SIMPLIFY_H */
diff --git a/src/mesa/slang/slang_storage.c b/src/mesa/slang/slang_storage.c
new file mode 100644 (file)
index 0000000..656e156
--- /dev/null
@@ -0,0 +1,321 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file slang_storage.c
+ * slang variable storage
+ * \author Michal Krol
+ */
+
+#include "main/imports.h"
+#include "slang_storage.h"
+#include "slang_mem.h"
+
+/* slang_storage_array */
+
+GLboolean
+slang_storage_array_construct(slang_storage_array * arr)
+{
+   arr->type = SLANG_STORE_AGGREGATE;
+   arr->aggregate = NULL;
+   arr->length = 0;
+   return GL_TRUE;
+}
+
+GLvoid
+slang_storage_array_destruct(slang_storage_array * arr)
+{
+   if (arr->aggregate != NULL) {
+      slang_storage_aggregate_destruct(arr->aggregate);
+      _slang_free(arr->aggregate);
+   }
+}
+
+/* slang_storage_aggregate */
+
+GLboolean
+slang_storage_aggregate_construct(slang_storage_aggregate * agg)
+{
+   agg->arrays = NULL;
+   agg->count = 0;
+   return GL_TRUE;
+}
+
+GLvoid
+slang_storage_aggregate_destruct(slang_storage_aggregate * agg)
+{
+   GLuint i;
+
+   for (i = 0; i < agg->count; i++)
+      slang_storage_array_destruct(agg->arrays + i);
+   _slang_free(agg->arrays);
+}
+
+static slang_storage_array *
+slang_storage_aggregate_push_new(slang_storage_aggregate * agg)
+{
+   slang_storage_array *arr = NULL;
+
+   agg->arrays = (slang_storage_array *)
+      _slang_realloc(agg->arrays,
+                     agg->count * sizeof(slang_storage_array),
+                     (agg->count + 1) * sizeof(slang_storage_array));
+   if (agg->arrays != NULL) {
+      arr = agg->arrays + agg->count;
+      if (!slang_storage_array_construct(arr))
+         return NULL;
+      agg->count++;
+   }
+   return arr;
+}
+
+/* _slang_aggregate_variable() */
+
+static GLboolean
+aggregate_vector(slang_storage_aggregate * agg, slang_storage_type basic_type,
+                 GLuint row_count)
+{
+   slang_storage_array *arr = slang_storage_aggregate_push_new(agg);
+   if (arr == NULL)
+      return GL_FALSE;
+   arr->type = basic_type;
+   arr->length = row_count;
+   return GL_TRUE;
+}
+
+static GLboolean
+aggregate_matrix(slang_storage_aggregate * agg, slang_storage_type basic_type,
+                 GLuint columns, GLuint rows)
+{
+   slang_storage_array *arr = slang_storage_aggregate_push_new(agg);
+   if (arr == NULL)
+      return GL_FALSE;
+   arr->type = SLANG_STORE_AGGREGATE;
+   arr->length = columns;
+   arr->aggregate = (slang_storage_aggregate *)
+      _slang_alloc(sizeof(slang_storage_aggregate));
+   if (arr->aggregate == NULL)
+      return GL_FALSE;
+   if (!slang_storage_aggregate_construct(arr->aggregate)) {
+      _slang_free(arr->aggregate);
+      arr->aggregate = NULL;
+      return GL_FALSE;
+   }
+   if (!aggregate_vector(arr->aggregate, basic_type, rows))
+      return GL_FALSE;
+   return GL_TRUE;
+}
+
+
+static GLboolean
+aggregate_variables(slang_storage_aggregate * agg,
+                    slang_variable_scope * vars, slang_function_scope * funcs,
+                    slang_struct_scope * structs,
+                    slang_variable_scope * globals,
+                    slang_atom_pool * atoms)
+{
+   GLuint i;
+
+   for (i = 0; i < vars->num_variables; i++)
+      if (!_slang_aggregate_variable(agg, &vars->variables[i]->type.specifier,
+                                     vars->variables[i]->array_len, funcs,
+                                     structs, globals, atoms))
+         return GL_FALSE;
+   return GL_TRUE;
+}
+
+
+GLboolean
+_slang_aggregate_variable(slang_storage_aggregate * agg,
+                          slang_type_specifier * spec, GLuint array_len,
+                          slang_function_scope * funcs,
+                          slang_struct_scope * structs,
+                          slang_variable_scope * vars,
+                          slang_atom_pool * atoms)
+{
+   switch (spec->type) {
+   case SLANG_SPEC_BOOL:
+      return aggregate_vector(agg, SLANG_STORE_BOOL, 1);
+   case SLANG_SPEC_BVEC2:
+      return aggregate_vector(agg, SLANG_STORE_BOOL, 2);
+   case SLANG_SPEC_BVEC3:
+      return aggregate_vector(agg, SLANG_STORE_BOOL, 3);
+   case SLANG_SPEC_BVEC4:
+      return aggregate_vector(agg, SLANG_STORE_BOOL, 4);
+   case SLANG_SPEC_INT:
+      return aggregate_vector(agg, SLANG_STORE_INT, 1);
+   case SLANG_SPEC_IVEC2:
+      return aggregate_vector(agg, SLANG_STORE_INT, 2);
+   case SLANG_SPEC_IVEC3:
+      return aggregate_vector(agg, SLANG_STORE_INT, 3);
+   case SLANG_SPEC_IVEC4:
+      return aggregate_vector(agg, SLANG_STORE_INT, 4);
+   case SLANG_SPEC_FLOAT:
+      return aggregate_vector(agg, SLANG_STORE_FLOAT, 1);
+   case SLANG_SPEC_VEC2:
+      return aggregate_vector(agg, SLANG_STORE_FLOAT, 2);
+   case SLANG_SPEC_VEC3:
+      return aggregate_vector(agg, SLANG_STORE_FLOAT, 3);
+   case SLANG_SPEC_VEC4:
+      return aggregate_vector(agg, SLANG_STORE_FLOAT, 4);
+   case SLANG_SPEC_MAT2:
+      return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2, 2);
+   case SLANG_SPEC_MAT3:
+      return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 3);
+   case SLANG_SPEC_MAT4:
+      return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 4);
+
+   case SLANG_SPEC_MAT23:
+      return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2, 3);
+   case SLANG_SPEC_MAT32:
+      return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 2);
+   case SLANG_SPEC_MAT24:
+      return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2, 4);
+   case SLANG_SPEC_MAT42:
+      return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 2);
+   case SLANG_SPEC_MAT34:
+      return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 4);
+   case SLANG_SPEC_MAT43:
+      return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 3);
+
+   case SLANG_SPEC_SAMPLER_1D:
+   case SLANG_SPEC_SAMPLER_2D:
+   case SLANG_SPEC_SAMPLER_3D:
+   case SLANG_SPEC_SAMPLER_CUBE:
+   case SLANG_SPEC_SAMPLER_1D_SHADOW:
+   case SLANG_SPEC_SAMPLER_2D_SHADOW:
+   case SLANG_SPEC_SAMPLER_RECT:
+   case SLANG_SPEC_SAMPLER_RECT_SHADOW:
+   case SLANG_SPEC_SAMPLER_1D_ARRAY:
+   case SLANG_SPEC_SAMPLER_2D_ARRAY:
+   case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW:
+   case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW:
+
+      return aggregate_vector(agg, SLANG_STORE_INT, 1);
+   case SLANG_SPEC_STRUCT:
+      return aggregate_variables(agg, spec->_struct->fields, funcs, structs,
+                                 vars, atoms);
+   case SLANG_SPEC_ARRAY:
+      {
+         slang_storage_array *arr;
+
+         arr = slang_storage_aggregate_push_new(agg);
+         if (arr == NULL)
+            return GL_FALSE;
+         arr->type = SLANG_STORE_AGGREGATE;
+         arr->aggregate = (slang_storage_aggregate *)
+            _slang_alloc(sizeof(slang_storage_aggregate));
+         if (arr->aggregate == NULL)
+            return GL_FALSE;
+         if (!slang_storage_aggregate_construct(arr->aggregate)) {
+            _slang_free(arr->aggregate);
+            arr->aggregate = NULL;
+            return GL_FALSE;
+         }
+         if (!_slang_aggregate_variable(arr->aggregate, spec->_array, 0,
+                                        funcs, structs, vars, atoms))
+            return GL_FALSE;
+         arr->length = array_len;
+         /* TODO: check if 0 < arr->length <= 65535 */
+      }
+      return GL_TRUE;
+   default:
+      return GL_FALSE;
+   }
+}
+
+
+GLuint
+_slang_sizeof_type(slang_storage_type type)
+{
+   if (type == SLANG_STORE_AGGREGATE)
+      return 0;
+   if (type == SLANG_STORE_VEC4)
+      return 4 * sizeof(GLfloat);
+   return sizeof(GLfloat);
+}
+
+
+GLuint
+_slang_sizeof_aggregate(const slang_storage_aggregate * agg)
+{
+   GLuint i, size = 0;
+
+   for (i = 0; i < agg->count; i++) {
+      slang_storage_array *arr = &agg->arrays[i];
+      GLuint element_size;
+
+      if (arr->type == SLANG_STORE_AGGREGATE)
+         element_size = _slang_sizeof_aggregate(arr->aggregate);
+      else
+         element_size = _slang_sizeof_type(arr->type);
+      size += element_size * arr->length;
+   }
+   return size;
+}
+
+
+#if 0
+GLboolean
+_slang_flatten_aggregate(slang_storage_aggregate * flat,
+                         const slang_storage_aggregate * agg)
+{
+   GLuint i;
+
+   for (i = 0; i < agg->count; i++) {
+      GLuint j;
+
+      for (j = 0; j < agg->arrays[i].length; j++) {
+         if (agg->arrays[i].type == SLANG_STORE_AGGREGATE) {
+            if (!_slang_flatten_aggregate(flat, agg->arrays[i].aggregate))
+               return GL_FALSE;
+         }
+         else {
+            GLuint k, count;
+            slang_storage_type type;
+
+            if (agg->arrays[i].type == SLANG_STORE_VEC4) {
+               count = 4;
+               type = SLANG_STORE_FLOAT;
+            }
+            else {
+               count = 1;
+               type = agg->arrays[i].type;
+            }
+
+            for (k = 0; k < count; k++) {
+               slang_storage_array *arr;
+
+               arr = slang_storage_aggregate_push_new(flat);
+               if (arr == NULL)
+                  return GL_FALSE;
+               arr->type = type;
+               arr->length = 1;
+            }
+         }
+      }
+   }
+   return GL_TRUE;
+}
+#endif
diff --git a/src/mesa/slang/slang_storage.h b/src/mesa/slang/slang_storage.h
new file mode 100644 (file)
index 0000000..1876a36
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef SLANG_STORAGE_H
+#define SLANG_STORAGE_H
+
+#include "slang_compile.h"
+
+
+/*
+ * Program variable data storage is kept completely transparent to the
+ * front-end compiler. It is up to the back-end how the data is
+ * actually allocated. The slang_storage_type enum provides the basic
+ * information about how the memory is interpreted. This abstract
+ * piece of memory is called a data slot. A data slot of a particular
+ * type has a fixed size.
+ *
+ * For now, only the three basic types are supported, that is bool,
+ * int and float. Other built-in types like vector or matrix can
+ * easily be decomposed into a series of basic types.
+ *
+ * If the vec4 module is enabled, 4-component vectors of floats are
+ * used when possible. 4x4 matrices are constructed of 4 vec4 slots.
+ */
+typedef enum slang_storage_type_
+{
+   /* core */
+   SLANG_STORE_AGGREGATE,
+   SLANG_STORE_BOOL,
+   SLANG_STORE_INT,
+   SLANG_STORE_FLOAT,
+   /* vec4 */
+   SLANG_STORE_VEC4
+} slang_storage_type;
+
+
+/**
+ * The slang_storage_array structure groups data slots of the same
+ * type into an array. This array has a fixed length. Arrays are
+ * required to have a size equal to the sum of sizes of its
+ * elements. They are also required to support indirect
+ * addressing. That is, if B references first data slot in the array,
+ * S is the size of the data slot and I is the integral index that is
+ * not known at compile time, B+I*S references I-th data slot.
+ *
+ * This structure is also used to break down built-in data types that
+ * are not supported directly.  Vectors, like vec3, are constructed
+ * from arrays of their basic types. Matrices are formed of an array
+ * of column vectors, which are in turn processed as other vectors.
+ */
+typedef struct slang_storage_array_
+{
+   slang_storage_type type;
+   struct slang_storage_aggregate_ *aggregate;
+   GLuint length;
+} slang_storage_array;
+
+GLboolean slang_storage_array_construct (slang_storage_array *);
+GLvoid slang_storage_array_destruct (slang_storage_array *);
+
+
+/**
+ * The slang_storage_aggregate structure relaxes the indirect
+ * addressing requirement for slang_storage_array
+ * structure. Aggregates are always accessed statically - its member
+ * addresses are well-known at compile time. For example, user-defined
+ * types are implemented as aggregates. Aggregates can collect data of
+ * a different type.
+ */
+typedef struct slang_storage_aggregate_
+{
+   slang_storage_array *arrays;
+   GLuint count;
+} slang_storage_aggregate;
+
+GLboolean slang_storage_aggregate_construct (slang_storage_aggregate *);
+GLvoid slang_storage_aggregate_destruct (slang_storage_aggregate *);
+
+
+extern GLboolean
+_slang_aggregate_variable(slang_storage_aggregate *agg,
+                          slang_type_specifier *spec,
+                          GLuint array_len,
+                          slang_function_scope *funcs,
+                          slang_struct_scope *structs,
+                          slang_variable_scope *vars,
+                          slang_atom_pool *atoms);
+
+/*
+ * Returns the size (in machine units) of the given storage type.
+ * It is an error to pass-in SLANG_STORE_AGGREGATE.
+ * Returns 0 on error.
+ */
+extern GLuint
+_slang_sizeof_type (slang_storage_type);
+
+
+/**
+ * Returns total size (in machine units) of the given aggregate.
+ * Returns 0 on error.
+ */
+extern GLuint
+_slang_sizeof_aggregate (const slang_storage_aggregate *);
+
+
+#if 0
+/**
+ * Converts structured aggregate to a flat one, with arrays of generic
+ * type being one-element long.  Returns GL_TRUE on success.  Returns
+ * GL_FALSE otherwise.
+ */
+extern GLboolean
+_slang_flatten_aggregate (slang_storage_aggregate *,
+                          const slang_storage_aggregate *);
+
+#endif
+
+#endif /* SLANG_STORAGE_H */
diff --git a/src/mesa/slang/slang_typeinfo.c b/src/mesa/slang/slang_typeinfo.c
new file mode 100644 (file)
index 0000000..d039a12
--- /dev/null
@@ -0,0 +1,1177 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file slang_typeinfo.c
+ * slang type info
+ * \author Michal Krol
+ */
+
+#include "main/imports.h"
+#include "program/prog_instruction.h"
+#include "slang_typeinfo.h"
+#include "slang_compile.h"
+#include "slang_log.h"
+#include "slang_mem.h"
+
+
+/**
+ * Checks if a field selector is a general swizzle (an r-value swizzle
+ * with replicated components or an l-value swizzle mask) for a
+ * vector.  Returns GL_TRUE if this is the case, <swz> is filled with
+ * swizzle information.  Returns GL_FALSE otherwise.
+ */
+GLboolean
+_slang_is_swizzle(const char *field, GLuint rows, slang_swizzle * swz)
+{
+   GLuint i;
+   GLboolean xyzw = GL_FALSE, rgba = GL_FALSE, stpq = GL_FALSE;
+
+   /* init to undefined.
+    * We rely on undefined/nil values to distinguish between
+    * regular swizzles and writemasks.
+    * For example, the swizzle ".xNNN" is the writemask ".x".
+    * That's different than the swizzle ".xxxx".
+    */
+   for (i = 0; i < 4; i++)
+      swz->swizzle[i] = SWIZZLE_NIL;
+
+   /* the swizzle can be at most 4-component long */
+   swz->num_components = slang_string_length(field);
+   if (swz->num_components > 4)
+      return GL_FALSE;
+
+   for (i = 0; i < swz->num_components; i++) {
+      /* mark which swizzle group is used */
+      switch (field[i]) {
+      case 'x':
+      case 'y':
+      case 'z':
+      case 'w':
+         xyzw = GL_TRUE;
+         break;
+      case 'r':
+      case 'g':
+      case 'b':
+      case 'a':
+         rgba = GL_TRUE;
+         break;
+      case 's':
+      case 't':
+      case 'p':
+      case 'q':
+         stpq = GL_TRUE;
+         break;
+      default:
+         return GL_FALSE;
+      }
+
+      /* collect swizzle component */
+      switch (field[i]) {
+      case 'x':
+      case 'r':
+      case 's':
+         swz->swizzle[i] = 0;
+         break;
+      case 'y':
+      case 'g':
+      case 't':
+         swz->swizzle[i] = 1;
+         break;
+      case 'z':
+      case 'b':
+      case 'p':
+         swz->swizzle[i] = 2;
+         break;
+      case 'w':
+      case 'a':
+      case 'q':
+         swz->swizzle[i] = 3;
+         break;
+      }
+
+      /* check if the component is valid for given vector's row count */
+      if (rows <= swz->swizzle[i])
+         return GL_FALSE;
+   }
+
+   /* only one swizzle group can be used */
+   if ((xyzw && rgba) || (xyzw && stpq) || (rgba && stpq))
+      return GL_FALSE;
+
+   return GL_TRUE;
+}
+
+
+
+/**
+ * Checks if a general swizzle is an l-value swizzle - these swizzles
+ * do not have duplicated fields.  Returns GL_TRUE if this is a
+ * swizzle mask.  Returns GL_FALSE otherwise
+ */
+static GLboolean
+_slang_is_swizzle_mask(const slang_swizzle * swz, GLuint rows)
+{
+   GLuint i, c = 0;
+
+   /* the swizzle may not be longer than the vector dim */
+   if (swz->num_components > rows)
+      return GL_FALSE;
+
+   /* the swizzle components cannot be duplicated */
+   for (i = 0; i < swz->num_components; i++) {
+      if ((c & (1 << swz->swizzle[i])) != 0)
+         return GL_FALSE;
+      c |= 1 << swz->swizzle[i];
+   }
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Combines (multiplies) two swizzles to form single swizzle.
+ * Example: "vec.wzyx.yx" --> "vec.zw".
+ */
+static void
+_slang_multiply_swizzles(slang_swizzle * dst, const slang_swizzle * left,
+                         const slang_swizzle * right)
+{
+   GLuint i;
+
+   dst->num_components = right->num_components;
+   for (i = 0; i < right->num_components; i++)
+      dst->swizzle[i] = left->swizzle[right->swizzle[i]];
+}
+
+
+typedef struct
+{
+   const char *name;
+   slang_type_specifier_type type;
+} type_specifier_type_name;
+
+static const type_specifier_type_name type_specifier_type_names[] = {
+   {"void", SLANG_SPEC_VOID},
+   {"bool", SLANG_SPEC_BOOL},
+   {"bvec2", SLANG_SPEC_BVEC2},
+   {"bvec3", SLANG_SPEC_BVEC3},
+   {"bvec4", SLANG_SPEC_BVEC4},
+   {"int", SLANG_SPEC_INT},
+   {"ivec2", SLANG_SPEC_IVEC2},
+   {"ivec3", SLANG_SPEC_IVEC3},
+   {"ivec4", SLANG_SPEC_IVEC4},
+   {"float", SLANG_SPEC_FLOAT},
+   {"vec2", SLANG_SPEC_VEC2},
+   {"vec3", SLANG_SPEC_VEC3},
+   {"vec4", SLANG_SPEC_VEC4},
+   {"mat2", SLANG_SPEC_MAT2},
+   {"mat3", SLANG_SPEC_MAT3},
+   {"mat4", SLANG_SPEC_MAT4},
+   {"mat2x3", SLANG_SPEC_MAT23},
+   {"mat3x2", SLANG_SPEC_MAT32},
+   {"mat2x4", SLANG_SPEC_MAT24},
+   {"mat4x2", SLANG_SPEC_MAT42},
+   {"mat3x4", SLANG_SPEC_MAT34},
+   {"mat4x3", SLANG_SPEC_MAT43},
+   {"sampler1D", SLANG_SPEC_SAMPLER_1D},
+   {"sampler2D", SLANG_SPEC_SAMPLER_2D},
+   {"sampler3D", SLANG_SPEC_SAMPLER_3D},
+   {"samplerCube", SLANG_SPEC_SAMPLER_CUBE},
+   {"sampler1DShadow", SLANG_SPEC_SAMPLER_1D_SHADOW},
+   {"sampler2DShadow", SLANG_SPEC_SAMPLER_2D_SHADOW},
+   {"sampler2DRect", SLANG_SPEC_SAMPLER_RECT},
+   {"sampler2DRectShadow", SLANG_SPEC_SAMPLER_RECT_SHADOW},
+   {"sampler1DArray", SLANG_SPEC_SAMPLER_1D_ARRAY},
+   {"sampler2DArray", SLANG_SPEC_SAMPLER_2D_ARRAY},
+   {"sampler1DArrayShadow", SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW},
+   {"sampler2DArrayShadow", SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW},
+   {NULL, SLANG_SPEC_VOID}
+};
+
+slang_type_specifier_type
+slang_type_specifier_type_from_string(const char *name)
+{
+   const type_specifier_type_name *p = type_specifier_type_names;
+   while (p->name != NULL) {
+      if (slang_string_compare(p->name, name) == 0)
+         break;
+      p++;
+   }
+   return p->type;
+}
+
+const char *
+slang_type_specifier_type_to_string(slang_type_specifier_type type)
+{
+   const type_specifier_type_name *p = type_specifier_type_names;
+   while (p->name != NULL) {
+      if (p->type == type)
+         break;
+      p++;
+   }
+   return p->name;
+}
+
+/* slang_fully_specified_type */
+
+int
+slang_fully_specified_type_construct(slang_fully_specified_type * type)
+{
+   type->qualifier = SLANG_QUAL_NONE;
+   slang_type_specifier_ctr(&type->specifier);
+   return 1;
+}
+
+void
+slang_fully_specified_type_destruct(slang_fully_specified_type * type)
+{
+   slang_type_specifier_dtr(&type->specifier);
+}
+
+int
+slang_fully_specified_type_copy(slang_fully_specified_type * x,
+                                const slang_fully_specified_type * y)
+{
+   slang_fully_specified_type z;
+
+   if (!slang_fully_specified_type_construct(&z))
+      return 0;
+   z.qualifier = y->qualifier;
+   z.precision = y->precision;
+   z.variant = y->variant;
+   z.centroid = y->centroid;
+   z.layout = y->layout;
+   z.array_len = y->array_len;
+   if (!slang_type_specifier_copy(&z.specifier, &y->specifier)) {
+      slang_fully_specified_type_destruct(&z);
+      return 0;
+   }
+   slang_fully_specified_type_destruct(x);
+   *x = z;
+   return 1;
+}
+
+
+/**
+ * Test if two fully specified types are compatible.  This is a bit
+ * looser than testing for equality.  We don't check the precision,
+ * variant, centroid, etc. information.
+ * XXX this may need some tweaking.
+ */
+GLboolean
+slang_fully_specified_types_compatible(const slang_fully_specified_type * x,
+                                       const slang_fully_specified_type * y)
+{
+   if (!slang_type_specifier_equal(&x->specifier, &y->specifier))
+      return GL_FALSE;
+
+   if (x->qualifier == SLANG_QUAL_FIXEDINPUT &&
+       y->qualifier == SLANG_QUAL_VARYING)
+      ; /* ok */
+   else if (x->qualifier != y->qualifier)
+      return GL_FALSE;
+
+   /* Note: don't compare precision, variant, centroid */
+
+   /* XXX array length? */
+
+   return GL_TRUE;
+}
+
+
+GLvoid
+slang_type_specifier_ctr(slang_type_specifier * self)
+{
+   self->type = SLANG_SPEC_VOID;
+   self->_struct = NULL;
+   self->_array = NULL;
+}
+
+GLvoid
+slang_type_specifier_dtr(slang_type_specifier * self)
+{
+   if (self->_struct != NULL) {
+      slang_struct_destruct(self->_struct);
+      _slang_free(self->_struct);
+   }
+   if (self->_array != NULL) {
+      slang_type_specifier_dtr(self->_array);
+      _slang_free(self->_array);
+   }
+}
+
+slang_type_specifier *
+slang_type_specifier_new(slang_type_specifier_type type,
+                         struct slang_struct_ *_struct,
+                         struct slang_type_specifier_ *_array)
+{
+   slang_type_specifier *spec =
+      (slang_type_specifier *) _slang_alloc(sizeof(slang_type_specifier));
+   if (spec) {
+      spec->type = type;
+      spec->_struct = _struct;
+      spec->_array = _array;
+   }
+   return spec;
+}
+
+GLboolean
+slang_type_specifier_copy(slang_type_specifier * x,
+                          const slang_type_specifier * y)
+{
+   slang_type_specifier z;
+
+   slang_type_specifier_ctr(&z);
+   z.type = y->type;
+   if (z.type == SLANG_SPEC_STRUCT) {
+      z._struct = (slang_struct *) _slang_alloc(sizeof(slang_struct));
+      if (z._struct == NULL) {
+         slang_type_specifier_dtr(&z);
+         return GL_FALSE;
+      }
+      if (!slang_struct_construct(z._struct)) {
+         _slang_free(z._struct);
+         slang_type_specifier_dtr(&z);
+         return GL_FALSE;
+      }
+      if (!slang_struct_copy(z._struct, y->_struct)) {
+         slang_type_specifier_dtr(&z);
+         return GL_FALSE;
+      }
+   }
+   else if (z.type == SLANG_SPEC_ARRAY) {
+      z._array = (slang_type_specifier *)
+         _slang_alloc(sizeof(slang_type_specifier));
+      if (z._array == NULL) {
+         slang_type_specifier_dtr(&z);
+         return GL_FALSE;
+      }
+      slang_type_specifier_ctr(z._array);
+      if (!slang_type_specifier_copy(z._array, y->_array)) {
+         slang_type_specifier_dtr(&z);
+         return GL_FALSE;
+      }
+   }
+   slang_type_specifier_dtr(x);
+   *x = z;
+   return GL_TRUE;
+}
+
+
+/**
+ * Test if two types are equal.
+ */
+GLboolean
+slang_type_specifier_equal(const slang_type_specifier * x,
+                           const slang_type_specifier * y)
+{
+   if (x->type != y->type)
+      return GL_FALSE;
+   if (x->type == SLANG_SPEC_STRUCT)
+      return slang_struct_equal(x->_struct, y->_struct);
+   if (x->type == SLANG_SPEC_ARRAY)
+      return slang_type_specifier_equal(x->_array, y->_array);
+   return GL_TRUE;
+}
+
+
+/**
+ * As above, but allow float/int casting.
+ */
+GLboolean
+slang_type_specifier_compatible(const slang_type_specifier * x,
+                                const slang_type_specifier * y)
+{
+   /* special case: float == int */
+   if (x->type == SLANG_SPEC_INT && y->type == SLANG_SPEC_FLOAT) {
+      return GL_TRUE;
+   }
+   /* XXX may need to add bool/int compatibility, etc */
+
+   if (x->type != y->type)
+      return GL_FALSE;
+   if (x->type == SLANG_SPEC_STRUCT)
+      return slang_struct_equal(x->_struct, y->_struct);
+   if (x->type == SLANG_SPEC_ARRAY)
+      return slang_type_specifier_compatible(x->_array, y->_array);
+   return GL_TRUE;
+}
+
+
+GLboolean
+slang_typeinfo_construct(slang_typeinfo * ti)
+{
+   memset(ti, 0, sizeof(*ti));
+   slang_type_specifier_ctr(&ti->spec);
+   ti->array_len = 0;
+   return GL_TRUE;
+}
+
+GLvoid
+slang_typeinfo_destruct(slang_typeinfo * ti)
+{
+   slang_type_specifier_dtr(&ti->spec);
+}
+
+
+
+/**
+ * Determine the return type of a function.
+ * \param a_name  the function name
+ * \param param  function parameters (overloading)
+ * \param num_params  number of parameters to function
+ * \param space  namespace to search
+ * \param spec  returns the type
+ * \param funFound  returns pointer to the function, or NULL if not found.
+ * \return GL_TRUE for success, GL_FALSE if failure (bad function name)
+ */
+static GLboolean
+_slang_typeof_function(slang_atom a_name,
+                       slang_operation * params, GLuint num_params,
+                       const slang_name_space * space,
+                       slang_type_specifier * spec,
+                       slang_function **funFound,
+                       slang_atom_pool *atoms, slang_info_log *log)
+{
+   GLboolean error;
+
+   *funFound = _slang_function_locate(space->funcs, a_name, params,
+                                      num_params, space, atoms, log, &error);
+   if (error)
+      return GL_FALSE;
+
+   if (!*funFound)
+      return GL_TRUE;  /* yes, not false */
+
+   return slang_type_specifier_copy(spec, &(*funFound)->header.type.specifier);
+}
+
+
+/**
+ * Determine the type of a math function.
+ * \param name  name of the operator, one of +,-,*,/ or unary -
+ * \param params  array of function parameters
+ * \param num_params  number of parameters
+ * \param space  namespace to use
+ * \param spec  returns the function's type
+ * \param atoms  atom pool
+ * \return GL_TRUE for success, GL_FALSE if failure
+ */
+static GLboolean
+typeof_math_call(const char *name, slang_operation *call,
+                 const slang_name_space * space,
+                 slang_type_specifier * spec,
+                 slang_atom_pool * atoms,
+                 slang_info_log *log)
+{
+   if (call->fun) {
+      /* we've previously resolved this function call */
+      slang_type_specifier_copy(spec, &call->fun->header.type.specifier);
+      return GL_TRUE;
+   }
+   else {
+      slang_atom atom;
+      slang_function *fun;
+
+      /* number of params: */
+      assert(call->num_children == 1 || call->num_children == 2);
+
+      atom = slang_atom_pool_atom(atoms, name);
+      if (!_slang_typeof_function(atom, call->children, call->num_children,
+                                  space, spec, &fun, atoms, log))
+         return GL_FALSE;
+
+      if (fun) {
+         /* Save pointer to save time in future */
+         call->fun = fun;
+         return GL_TRUE;
+      }
+      return GL_FALSE;
+   }
+}
+
+
+/**
+ * Determine the return type of an operation.
+ * \param op  the operation node
+ * \param space  the namespace to use
+ * \param ti  the returned type
+ * \param atoms  atom pool
+ * \return GL_TRUE for success, GL_FALSE if failure
+ */
+GLboolean
+_slang_typeof_operation(slang_operation * op,
+                         const slang_name_space * space,
+                         slang_typeinfo * ti,
+                         slang_atom_pool * atoms,
+                         slang_info_log *log)
+{
+   ti->can_be_referenced = GL_FALSE;
+   ti->is_swizzled = GL_FALSE;
+
+   switch (op->type) {
+   case SLANG_OPER_BLOCK_NO_NEW_SCOPE:
+   case SLANG_OPER_BLOCK_NEW_SCOPE:
+   case SLANG_OPER_ASM:
+   case SLANG_OPER_BREAK:
+   case SLANG_OPER_CONTINUE:
+   case SLANG_OPER_DISCARD:
+   case SLANG_OPER_RETURN:
+   case SLANG_OPER_IF:
+   case SLANG_OPER_WHILE:
+   case SLANG_OPER_DO:
+   case SLANG_OPER_FOR:
+   case SLANG_OPER_VOID:
+      ti->spec.type = SLANG_SPEC_VOID;
+      break;
+   case SLANG_OPER_EXPRESSION:
+   case SLANG_OPER_ASSIGN:
+   case SLANG_OPER_ADDASSIGN:
+   case SLANG_OPER_SUBASSIGN:
+   case SLANG_OPER_MULASSIGN:
+   case SLANG_OPER_DIVASSIGN:
+   case SLANG_OPER_PREINCREMENT:
+   case SLANG_OPER_PREDECREMENT:
+      if (!_slang_typeof_operation(op->children, space, ti, atoms, log))
+         return GL_FALSE;
+      break;
+   case SLANG_OPER_LITERAL_BOOL:
+      if (op->literal_size == 1)
+         ti->spec.type = SLANG_SPEC_BOOL;
+      else if (op->literal_size == 2)
+         ti->spec.type = SLANG_SPEC_BVEC2;
+      else if (op->literal_size == 3)
+         ti->spec.type = SLANG_SPEC_BVEC3;
+      else if (op->literal_size == 4)
+         ti->spec.type = SLANG_SPEC_BVEC4;
+      else {
+         _mesa_problem(NULL,
+               "Unexpected bool literal_size %d in _slang_typeof_operation()",
+               op->literal_size);
+         ti->spec.type = SLANG_SPEC_BOOL;
+      }
+      break;
+   case SLANG_OPER_LOGICALOR:
+   case SLANG_OPER_LOGICALXOR:
+   case SLANG_OPER_LOGICALAND:
+   case SLANG_OPER_EQUAL:
+   case SLANG_OPER_NOTEQUAL:
+   case SLANG_OPER_LESS:
+   case SLANG_OPER_GREATER:
+   case SLANG_OPER_LESSEQUAL:
+   case SLANG_OPER_GREATEREQUAL:
+   case SLANG_OPER_NOT:
+      ti->spec.type = SLANG_SPEC_BOOL;
+      break;
+   case SLANG_OPER_LITERAL_INT:
+      if (op->literal_size == 1)
+         ti->spec.type = SLANG_SPEC_INT;
+      else if (op->literal_size == 2)
+         ti->spec.type = SLANG_SPEC_IVEC2;
+      else if (op->literal_size == 3)
+         ti->spec.type = SLANG_SPEC_IVEC3;
+      else if (op->literal_size == 4)
+         ti->spec.type = SLANG_SPEC_IVEC4;
+      else {
+         _mesa_problem(NULL,
+               "Unexpected int literal_size %d in _slang_typeof_operation()",
+               op->literal_size);
+         ti->spec.type = SLANG_SPEC_INT;
+      }
+      break;
+   case SLANG_OPER_LITERAL_FLOAT:
+      if (op->literal_size == 1)
+         ti->spec.type = SLANG_SPEC_FLOAT;
+      else if (op->literal_size == 2)
+         ti->spec.type = SLANG_SPEC_VEC2;
+      else if (op->literal_size == 3)
+         ti->spec.type = SLANG_SPEC_VEC3;
+      else if (op->literal_size == 4)
+         ti->spec.type = SLANG_SPEC_VEC4;
+      else {
+         _mesa_problem(NULL,
+               "Unexpected float literal_size %d in _slang_typeof_operation()",
+               op->literal_size);
+         ti->spec.type = SLANG_SPEC_FLOAT;
+      }
+      break;
+   case SLANG_OPER_IDENTIFIER:
+   case SLANG_OPER_VARIABLE_DECL:
+      {
+         slang_variable *var;
+         var = _slang_variable_locate(op->locals, op->a_id, GL_TRUE);
+         if (!var) {
+            slang_info_log_error(log, "undefined variable '%s'",
+                                 (char *) op->a_id);
+            return GL_FALSE;
+         }
+         if (!slang_type_specifier_copy(&ti->spec, &var->type.specifier)) {
+            slang_info_log_memory(log);
+            return GL_FALSE;
+         }
+         ti->can_be_referenced = GL_TRUE;
+         if (var->type.specifier.type == SLANG_SPEC_ARRAY &&
+             var->type.array_len >= 1) {
+            /* the datatype is an array, ex: float[3] x; */
+            ti->array_len = var->type.array_len;
+         }
+         else {
+            /* the variable is an array, ex: float x[3]; */
+            ti->array_len = var->array_len;
+         }
+      }
+      break;
+   case SLANG_OPER_SEQUENCE:
+      /* TODO: check [0] and [1] if they match */
+      if (!_slang_typeof_operation(&op->children[1], space, ti, atoms, log)) {
+         return GL_FALSE;
+      }
+      ti->can_be_referenced = GL_FALSE;
+      ti->is_swizzled = GL_FALSE;
+      break;
+      /*case SLANG_OPER_MODASSIGN: */
+      /*case SLANG_OPER_LSHASSIGN: */
+      /*case SLANG_OPER_RSHASSIGN: */
+      /*case SLANG_OPER_ORASSIGN: */
+      /*case SLANG_OPER_XORASSIGN: */
+      /*case SLANG_OPER_ANDASSIGN: */
+   case SLANG_OPER_SELECT:
+      /* TODO: check [1] and [2] if they match */
+      if (!_slang_typeof_operation(&op->children[1], space, ti, atoms, log)) {
+         return GL_FALSE;
+      }
+      ti->can_be_referenced = GL_FALSE;
+      ti->is_swizzled = GL_FALSE;
+      break;
+      /*case SLANG_OPER_BITOR: */
+      /*case SLANG_OPER_BITXOR: */
+      /*case SLANG_OPER_BITAND: */
+      /*case SLANG_OPER_LSHIFT: */
+      /*case SLANG_OPER_RSHIFT: */
+   case SLANG_OPER_ADD:
+      assert(op->num_children == 2);
+      if (!typeof_math_call("+", op, space, &ti->spec, atoms, log))
+         return GL_FALSE;
+      break;
+   case SLANG_OPER_SUBTRACT:
+      assert(op->num_children == 2);
+      if (!typeof_math_call("-", op, space, &ti->spec, atoms, log))
+         return GL_FALSE;
+      break;
+   case SLANG_OPER_MULTIPLY:
+      assert(op->num_children == 2);
+      if (!typeof_math_call("*", op, space, &ti->spec, atoms, log))
+         return GL_FALSE;
+      break;
+   case SLANG_OPER_DIVIDE:
+      assert(op->num_children == 2);
+      if (!typeof_math_call("/", op, space, &ti->spec, atoms, log))
+         return GL_FALSE;
+      break;
+   /*case SLANG_OPER_MODULUS: */
+   case SLANG_OPER_PLUS:
+      if (!_slang_typeof_operation(op->children, space, ti, atoms, log))
+         return GL_FALSE;
+      ti->can_be_referenced = GL_FALSE;
+      ti->is_swizzled = GL_FALSE;
+      break;
+   case SLANG_OPER_MINUS:
+      assert(op->num_children == 1);
+      if (!typeof_math_call("-", op, space, &ti->spec, atoms, log))
+         return GL_FALSE;
+      break;
+      /*case SLANG_OPER_COMPLEMENT: */
+   case SLANG_OPER_SUBSCRIPT:
+      {
+         slang_typeinfo _ti;
+
+         if (!slang_typeinfo_construct(&_ti))
+            return GL_FALSE;
+         if (!_slang_typeof_operation(op->children, space, &_ti, atoms, log)) {
+            slang_typeinfo_destruct(&_ti);
+            return GL_FALSE;
+         }
+         ti->can_be_referenced = _ti.can_be_referenced;
+         if (_ti.spec.type == SLANG_SPEC_ARRAY) {
+            if (!slang_type_specifier_copy(&ti->spec, _ti.spec._array)) {
+               slang_typeinfo_destruct(&_ti);
+               return GL_FALSE;
+            }
+         }
+         else {
+            if (!_slang_type_is_vector(_ti.spec.type)
+                && !_slang_type_is_matrix(_ti.spec.type)) {
+               slang_typeinfo_destruct(&_ti);
+               slang_info_log_error(log, "cannot index a non-array type");
+               return GL_FALSE;
+            }
+            ti->spec.type = _slang_type_base(_ti.spec.type);
+         }
+         slang_typeinfo_destruct(&_ti);
+      }
+      break;
+   case SLANG_OPER_CALL:
+      if (op->array_constructor) {
+         /* build array typeinfo */
+         ti->spec.type = SLANG_SPEC_ARRAY;
+         ti->spec._array = (slang_type_specifier *)
+            _slang_alloc(sizeof(slang_type_specifier));
+         slang_type_specifier_ctr(ti->spec._array);
+
+         ti->spec._array->type =
+            slang_type_specifier_type_from_string((char *) op->a_id);
+         ti->array_len = op->num_children;
+      }
+      else if (op->fun) {
+         /* we've resolved this call before */
+         slang_type_specifier_copy(&ti->spec, &op->fun->header.type.specifier);
+      }
+      else {
+         slang_function *fun;
+         if (!_slang_typeof_function(op->a_id, op->children, op->num_children,
+                                     space, &ti->spec, &fun, atoms, log))
+            return GL_FALSE;
+         if (fun) {
+            /* save result for future use */
+            op->fun = fun;
+         }
+         else {
+            slang_struct *s =
+               slang_struct_scope_find(space->structs, op->a_id, GL_TRUE);
+            if (s) {
+               /* struct initializer */
+               ti->spec.type = SLANG_SPEC_STRUCT;
+               ti->spec._struct =
+                  (slang_struct *) _slang_alloc(sizeof(slang_struct));
+               if (ti->spec._struct == NULL)
+                  return GL_FALSE;
+               if (!slang_struct_construct(ti->spec._struct)) {
+                  _slang_free(ti->spec._struct);
+                  ti->spec._struct = NULL;
+                  return GL_FALSE;
+               }
+               if (!slang_struct_copy(ti->spec._struct, s))
+                  return GL_FALSE;
+            }
+            else {
+               /* float, int, vec4, mat3, etc. constructor? */
+               const char *name;
+               slang_type_specifier_type type;
+
+               name = slang_atom_pool_id(atoms, op->a_id);
+               type = slang_type_specifier_type_from_string(name);
+               if (type == SLANG_SPEC_VOID) {
+                  slang_info_log_error(log, "undefined function '%s'", name);
+                  return GL_FALSE;
+               }
+               ti->spec.type = type;
+            }
+         }
+      }
+      break;
+   case SLANG_OPER_METHOD:
+      /* at this time, GLSL 1.20 only has one method: array.length()
+       * which returns an integer.
+       */
+      ti->spec.type = SLANG_SPEC_INT;
+      break;
+   case SLANG_OPER_FIELD:
+      {
+         slang_typeinfo _ti;
+
+         if (!slang_typeinfo_construct(&_ti))
+            return GL_FALSE;
+         if (!_slang_typeof_operation(op->children, space, &_ti, atoms, log)) {
+            slang_typeinfo_destruct(&_ti);
+            return GL_FALSE;
+         }
+         if (_ti.spec.type == SLANG_SPEC_STRUCT) {
+            slang_variable *field;
+
+            field = _slang_variable_locate(_ti.spec._struct->fields, op->a_id,
+                                           GL_FALSE);
+            if (field == NULL) {
+               slang_typeinfo_destruct(&_ti);
+               return GL_FALSE;
+            }
+            if (!slang_type_specifier_copy(&ti->spec, &field->type.specifier)) {
+               slang_typeinfo_destruct(&_ti);
+               return GL_FALSE;
+            }
+            ti->can_be_referenced = _ti.can_be_referenced;
+            ti->array_len = field->array_len;
+         }
+         else {
+            GLuint rows;
+            const char *swizzle;
+            slang_type_specifier_type base;
+
+            /* determine the swizzle of the field expression */
+            if (!_slang_type_is_vector(_ti.spec.type)) {
+               slang_typeinfo_destruct(&_ti);
+               slang_info_log_error(log, "Can't swizzle scalar expression");
+               return GL_FALSE;
+            }
+            rows = _slang_type_dim(_ti.spec.type);
+            swizzle = slang_atom_pool_id(atoms, op->a_id);
+            if (!_slang_is_swizzle(swizzle, rows, &ti->swz)) {
+               slang_typeinfo_destruct(&_ti);
+               slang_info_log_error(log, "bad swizzle '%s'", swizzle);
+               return GL_FALSE;
+            }
+            ti->is_swizzled = GL_TRUE;
+            ti->can_be_referenced = _ti.can_be_referenced
+               && _slang_is_swizzle_mask(&ti->swz, rows);
+            if (_ti.is_swizzled) {
+               slang_swizzle swz;
+
+               /* swizzle the swizzle */
+               _slang_multiply_swizzles(&swz, &_ti.swz, &ti->swz);
+               ti->swz = swz;
+            }
+            base = _slang_type_base(_ti.spec.type);
+            switch (ti->swz.num_components) {
+            case 1:
+               ti->spec.type = base;
+               break;
+            case 2:
+               switch (base) {
+               case SLANG_SPEC_FLOAT:
+                  ti->spec.type = SLANG_SPEC_VEC2;
+                  break;
+               case SLANG_SPEC_INT:
+                  ti->spec.type = SLANG_SPEC_IVEC2;
+                  break;
+               case SLANG_SPEC_BOOL:
+                  ti->spec.type = SLANG_SPEC_BVEC2;
+                  break;
+               default:
+                  break;
+               }
+               break;
+            case 3:
+               switch (base) {
+               case SLANG_SPEC_FLOAT:
+                  ti->spec.type = SLANG_SPEC_VEC3;
+                  break;
+               case SLANG_SPEC_INT:
+                  ti->spec.type = SLANG_SPEC_IVEC3;
+                  break;
+               case SLANG_SPEC_BOOL:
+                  ti->spec.type = SLANG_SPEC_BVEC3;
+                  break;
+               default:
+                  break;
+               }
+               break;
+            case 4:
+               switch (base) {
+               case SLANG_SPEC_FLOAT:
+                  ti->spec.type = SLANG_SPEC_VEC4;
+                  break;
+               case SLANG_SPEC_INT:
+                  ti->spec.type = SLANG_SPEC_IVEC4;
+                  break;
+               case SLANG_SPEC_BOOL:
+                  ti->spec.type = SLANG_SPEC_BVEC4;
+                  break;
+               default:
+                  break;
+               }
+               break;
+            default:
+               break;
+            }
+         }
+         slang_typeinfo_destruct(&_ti);
+      }
+      break;
+   case SLANG_OPER_POSTINCREMENT:
+   case SLANG_OPER_POSTDECREMENT:
+      if (!_slang_typeof_operation(op->children, space, ti, atoms, log))
+         return GL_FALSE;
+      ti->can_be_referenced = GL_FALSE;
+      ti->is_swizzled = GL_FALSE;
+      break;
+   default:
+      return GL_FALSE;
+   }
+
+   return GL_TRUE;
+}
+
+
+/**
+ * Determine if a type is a matrix.
+ * \return GL_TRUE if is a matrix, GL_FALSE otherwise.
+ */
+GLboolean
+_slang_type_is_matrix(slang_type_specifier_type ty)
+{
+   switch (ty) {
+   case SLANG_SPEC_MAT2:
+   case SLANG_SPEC_MAT3:
+   case SLANG_SPEC_MAT4:
+   case SLANG_SPEC_MAT23:
+   case SLANG_SPEC_MAT32:
+   case SLANG_SPEC_MAT24:
+   case SLANG_SPEC_MAT42:
+   case SLANG_SPEC_MAT34:
+   case SLANG_SPEC_MAT43:
+      return GL_TRUE;
+   default:
+      return GL_FALSE;
+   }
+}
+
+
+/**
+ * Determine if a type is a vector.
+ * \return GL_TRUE if is a vector, GL_FALSE otherwise.
+ */
+GLboolean
+_slang_type_is_vector(slang_type_specifier_type ty)
+{
+   switch (ty) {
+   case SLANG_SPEC_VEC2:
+   case SLANG_SPEC_VEC3:
+   case SLANG_SPEC_VEC4:
+   case SLANG_SPEC_IVEC2:
+   case SLANG_SPEC_IVEC3:
+   case SLANG_SPEC_IVEC4:
+   case SLANG_SPEC_BVEC2:
+   case SLANG_SPEC_BVEC3:
+   case SLANG_SPEC_BVEC4:
+      return GL_TRUE;
+   default:
+      return GL_FALSE;
+   }
+}
+
+
+/**
+ * Determine if a type is a float, float vector or float matrix.
+ * \return GL_TRUE if so, GL_FALSE otherwise
+ */
+GLboolean
+_slang_type_is_float_vec_mat(slang_type_specifier_type ty)
+{
+   switch (ty) {
+   case SLANG_SPEC_FLOAT:
+   case SLANG_SPEC_VEC2:
+   case SLANG_SPEC_VEC3:
+   case SLANG_SPEC_VEC4:
+   case SLANG_SPEC_MAT2:
+   case SLANG_SPEC_MAT3:
+   case SLANG_SPEC_MAT4:
+   case SLANG_SPEC_MAT23:
+   case SLANG_SPEC_MAT32:
+   case SLANG_SPEC_MAT24:
+   case SLANG_SPEC_MAT42:
+   case SLANG_SPEC_MAT34:
+   case SLANG_SPEC_MAT43:
+      return GL_TRUE;
+   default:
+      return GL_FALSE;
+   }
+}
+
+
+/**
+ * Given a vector type, return the type of the vector's elements.
+ * For a matrix, return the type of the columns.
+ */
+slang_type_specifier_type
+_slang_type_base(slang_type_specifier_type ty)
+{
+   switch (ty) {
+   case SLANG_SPEC_FLOAT:
+   case SLANG_SPEC_VEC2:
+   case SLANG_SPEC_VEC3:
+   case SLANG_SPEC_VEC4:
+      return SLANG_SPEC_FLOAT;
+   case SLANG_SPEC_INT:
+   case SLANG_SPEC_IVEC2:
+   case SLANG_SPEC_IVEC3:
+   case SLANG_SPEC_IVEC4:
+      return SLANG_SPEC_INT;
+   case SLANG_SPEC_BOOL:
+   case SLANG_SPEC_BVEC2:
+   case SLANG_SPEC_BVEC3:
+   case SLANG_SPEC_BVEC4:
+      return SLANG_SPEC_BOOL;
+   case SLANG_SPEC_MAT2:
+      return SLANG_SPEC_VEC2;
+   case SLANG_SPEC_MAT3:
+      return SLANG_SPEC_VEC3;
+   case SLANG_SPEC_MAT4:
+      return SLANG_SPEC_VEC4;
+   case SLANG_SPEC_MAT23:
+      return SLANG_SPEC_VEC3;
+   case SLANG_SPEC_MAT32:
+      return SLANG_SPEC_VEC2;
+   case SLANG_SPEC_MAT24:
+      return SLANG_SPEC_VEC4;
+   case SLANG_SPEC_MAT42:
+      return SLANG_SPEC_VEC2;
+   case SLANG_SPEC_MAT34:
+      return SLANG_SPEC_VEC4;
+   case SLANG_SPEC_MAT43:
+      return SLANG_SPEC_VEC3;
+   default:
+      return SLANG_SPEC_VOID;
+   }
+}
+
+
+/**
+ * Return the dimensionality of a vector, or for a matrix, return number
+ * of columns.
+ */
+GLuint
+_slang_type_dim(slang_type_specifier_type ty)
+{
+   switch (ty) {
+   case SLANG_SPEC_FLOAT:
+   case SLANG_SPEC_INT:
+   case SLANG_SPEC_BOOL:
+      return 1;
+   case SLANG_SPEC_VEC2:
+   case SLANG_SPEC_IVEC2:
+   case SLANG_SPEC_BVEC2:
+   case SLANG_SPEC_MAT2:
+      return 2;
+   case SLANG_SPEC_VEC3:
+   case SLANG_SPEC_IVEC3:
+   case SLANG_SPEC_BVEC3:
+   case SLANG_SPEC_MAT3:
+      return 3;
+   case SLANG_SPEC_VEC4:
+   case SLANG_SPEC_IVEC4:
+   case SLANG_SPEC_BVEC4:
+   case SLANG_SPEC_MAT4:
+      return 4;
+
+   case SLANG_SPEC_MAT23:
+      return 2;
+   case SLANG_SPEC_MAT32:
+      return 3;
+   case SLANG_SPEC_MAT24:
+      return 2;
+   case SLANG_SPEC_MAT42:
+      return 4;
+   case SLANG_SPEC_MAT34:
+      return 3;
+   case SLANG_SPEC_MAT43:
+      return 4;
+
+   default:
+      return 0;
+   }
+}
+
+
+/**
+ * Return the GL_* type that corresponds to a SLANG_SPEC_* type.
+ */
+GLenum
+_slang_gltype_from_specifier(const slang_type_specifier *type)
+{
+   switch (type->type) {
+   case SLANG_SPEC_BOOL:
+      return GL_BOOL;
+   case SLANG_SPEC_BVEC2:
+      return GL_BOOL_VEC2;
+   case SLANG_SPEC_BVEC3:
+      return GL_BOOL_VEC3;
+   case SLANG_SPEC_BVEC4:
+      return GL_BOOL_VEC4;
+   case SLANG_SPEC_INT:
+      return GL_INT;
+   case SLANG_SPEC_IVEC2:
+      return GL_INT_VEC2;
+   case SLANG_SPEC_IVEC3:
+      return GL_INT_VEC3;
+   case SLANG_SPEC_IVEC4:
+      return GL_INT_VEC4;
+   case SLANG_SPEC_FLOAT:
+      return GL_FLOAT;
+   case SLANG_SPEC_VEC2:
+      return GL_FLOAT_VEC2;
+   case SLANG_SPEC_VEC3:
+      return GL_FLOAT_VEC3;
+   case SLANG_SPEC_VEC4:
+      return GL_FLOAT_VEC4;
+   case SLANG_SPEC_MAT2:
+      return GL_FLOAT_MAT2;
+   case SLANG_SPEC_MAT3:
+      return GL_FLOAT_MAT3;
+   case SLANG_SPEC_MAT4:
+      return GL_FLOAT_MAT4;
+   case SLANG_SPEC_MAT23:
+      return GL_FLOAT_MAT2x3;
+   case SLANG_SPEC_MAT32:
+      return GL_FLOAT_MAT3x2;
+   case SLANG_SPEC_MAT24:
+      return GL_FLOAT_MAT2x4;
+   case SLANG_SPEC_MAT42:
+      return GL_FLOAT_MAT4x2;
+   case SLANG_SPEC_MAT34:
+      return GL_FLOAT_MAT3x4;
+   case SLANG_SPEC_MAT43:
+      return GL_FLOAT_MAT4x3;
+   case SLANG_SPEC_SAMPLER_1D:
+      return GL_SAMPLER_1D;
+   case SLANG_SPEC_SAMPLER_2D:
+      return GL_SAMPLER_2D;
+   case SLANG_SPEC_SAMPLER_3D:
+      return GL_SAMPLER_3D;
+   case SLANG_SPEC_SAMPLER_CUBE:
+      return GL_SAMPLER_CUBE;
+   case SLANG_SPEC_SAMPLER_1D_SHADOW:
+      return GL_SAMPLER_1D_SHADOW;
+   case SLANG_SPEC_SAMPLER_2D_SHADOW:
+      return GL_SAMPLER_2D_SHADOW;
+   case SLANG_SPEC_SAMPLER_RECT:
+      return GL_SAMPLER_2D_RECT_ARB;
+   case SLANG_SPEC_SAMPLER_RECT_SHADOW:
+      return GL_SAMPLER_2D_RECT_SHADOW_ARB;
+   case SLANG_SPEC_SAMPLER_1D_ARRAY:
+      return GL_SAMPLER_1D_ARRAY_EXT;
+   case SLANG_SPEC_SAMPLER_2D_ARRAY:
+      return GL_SAMPLER_2D_ARRAY_EXT;
+   case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW:
+      return GL_SAMPLER_1D_ARRAY_SHADOW_EXT;
+   case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW:
+      return GL_SAMPLER_2D_ARRAY_SHADOW_EXT;
+   case SLANG_SPEC_ARRAY:
+      return _slang_gltype_from_specifier(type->_array);
+   case SLANG_SPEC_STRUCT:
+      /* fall-through */
+   default:
+      return GL_NONE;
+   }
+}
+
diff --git a/src/mesa/slang/slang_typeinfo.h b/src/mesa/slang/slang_typeinfo.h
new file mode 100644 (file)
index 0000000..2251b06
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5
+ *
+ * Copyright (C) 2005-2006  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef SLANG_TYPEINFO_H
+#define SLANG_TYPEINFO_H 1
+
+#include "main/imports.h"
+#include "main/mtypes.h"
+#include "slang_log.h"
+#include "slang_utility.h"
+#include "slang_vartable.h"
+
+
+struct slang_operation_;
+
+struct slang_name_space_;
+
+
+
+/**
+ * Holds complete information about vector swizzle - the <swizzle>
+ * array contains vector component source indices, where 0 is "x", 1
+ * is "y", 2 is "z" and 3 is "w".
+ * Example: "xwz" --> { 3, { 0, 3, 2, not used } }.
+ */
+typedef struct slang_swizzle_
+{
+   GLuint num_components;
+   GLuint swizzle[4];
+} slang_swizzle;
+
+extern GLboolean
+_slang_is_swizzle(const char *field, GLuint rows, slang_swizzle *swz);
+
+
+typedef enum slang_type_variant_
+{
+   SLANG_VARIANT,    /* the default */
+   SLANG_INVARIANT   /* indicates the "invariant" keyword */
+} slang_type_variant;
+
+
+typedef enum slang_type_centroid_
+{
+   SLANG_CENTER,    /* the default */
+   SLANG_CENTROID   /* indicates the "centroid" keyword */
+} slang_type_centroid;
+
+
+/**
+ * These only apply to gl_FragCoord, but other layout qualifiers may
+ * appear in the future.
+ */
+typedef enum slang_layout_qualifier_
+{
+   SLANG_LAYOUT_NONE                      = 0x0,
+   SLANG_LAYOUT_UPPER_LEFT_BIT            = 0x1,
+   SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT  = 0x2
+} slang_layout_qualifier;
+
+
+typedef enum slang_type_qualifier_
+{
+   SLANG_QUAL_NONE,
+   SLANG_QUAL_CONST,
+   SLANG_QUAL_ATTRIBUTE,
+   SLANG_QUAL_VARYING,
+   SLANG_QUAL_UNIFORM,
+   SLANG_QUAL_OUT,
+   SLANG_QUAL_INOUT,
+   SLANG_QUAL_FIXEDOUTPUT,      /* internal */
+   SLANG_QUAL_FIXEDINPUT        /* internal */
+} slang_type_qualifier;
+
+typedef enum slang_varying_kind_
+{
+   SLANG_VARYING_IN,
+   SLANG_VARYING_OUT,
+} slang_varying_kind;
+
+typedef enum slang_type_precision_
+{
+   SLANG_PREC_DEFAULT,
+   SLANG_PREC_LOW,
+   SLANG_PREC_MEDIUM,
+   SLANG_PREC_HIGH
+} slang_type_precision;
+
+
+/**
+ * The basic shading language types (float, vec4, mat3, etc)
+ */
+typedef enum slang_type_specifier_type_
+{
+   SLANG_SPEC_VOID,
+   SLANG_SPEC_BOOL,
+   SLANG_SPEC_BVEC2,
+   SLANG_SPEC_BVEC3,
+   SLANG_SPEC_BVEC4,
+   SLANG_SPEC_INT,
+   SLANG_SPEC_IVEC2,
+   SLANG_SPEC_IVEC3,
+   SLANG_SPEC_IVEC4,
+   SLANG_SPEC_FLOAT,
+   SLANG_SPEC_VEC2,
+   SLANG_SPEC_VEC3,
+   SLANG_SPEC_VEC4,
+   SLANG_SPEC_MAT2,
+   SLANG_SPEC_MAT3,
+   SLANG_SPEC_MAT4,
+   SLANG_SPEC_MAT23,
+   SLANG_SPEC_MAT32,
+   SLANG_SPEC_MAT24,
+   SLANG_SPEC_MAT42,
+   SLANG_SPEC_MAT34,
+   SLANG_SPEC_MAT43,
+   SLANG_SPEC_SAMPLER_1D,
+   SLANG_SPEC_SAMPLER_2D,
+   SLANG_SPEC_SAMPLER_3D,
+   SLANG_SPEC_SAMPLER_CUBE,
+   SLANG_SPEC_SAMPLER_RECT,
+   SLANG_SPEC_SAMPLER_1D_SHADOW,
+   SLANG_SPEC_SAMPLER_2D_SHADOW,
+   SLANG_SPEC_SAMPLER_RECT_SHADOW,
+   SLANG_SPEC_SAMPLER_1D_ARRAY,
+   SLANG_SPEC_SAMPLER_2D_ARRAY,
+   SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW,
+   SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW,
+   SLANG_SPEC_STRUCT,
+   SLANG_SPEC_ARRAY
+} slang_type_specifier_type;
+
+
+extern slang_type_specifier_type
+slang_type_specifier_type_from_string(const char *);
+
+extern const char *
+slang_type_specifier_type_to_string(slang_type_specifier_type);
+
+
+/**
+ * Describes more sophisticated types, like structs and arrays.
+ */
+typedef struct slang_type_specifier_
+{
+   slang_type_specifier_type type;
+   struct slang_struct_ *_struct;         /**< if type == SLANG_SPEC_STRUCT */
+   struct slang_type_specifier_ *_array;  /**< if type == SLANG_SPEC_ARRAY */
+} slang_type_specifier;
+
+
+extern GLvoid
+slang_type_specifier_ctr(slang_type_specifier *);
+
+extern GLvoid
+slang_type_specifier_dtr(slang_type_specifier *);
+
+extern slang_type_specifier *
+slang_type_specifier_new(slang_type_specifier_type type,
+                         struct slang_struct_ *_struct,
+                         struct slang_type_specifier_ *_array);
+
+
+extern GLboolean
+slang_type_specifier_copy(slang_type_specifier *, const slang_type_specifier *);
+
+extern GLboolean
+slang_type_specifier_equal(const slang_type_specifier *,
+                           const slang_type_specifier *);
+
+
+extern GLboolean
+slang_type_specifier_compatible(const slang_type_specifier *x,
+                                const slang_type_specifier *y);
+
+
+typedef struct slang_fully_specified_type_
+{
+   slang_type_qualifier qualifier;
+   slang_type_specifier specifier;
+   slang_type_precision precision;
+   slang_type_variant variant;
+   slang_type_centroid centroid;
+   slang_layout_qualifier layout;
+   GLint array_len;           /**< -1 if not an array type */
+   slang_varying_kind varying_kind;
+} slang_fully_specified_type;
+
+extern int
+slang_fully_specified_type_construct(slang_fully_specified_type *);
+
+extern void
+slang_fully_specified_type_destruct(slang_fully_specified_type *);
+
+extern int
+slang_fully_specified_type_copy(slang_fully_specified_type *,
+                               const slang_fully_specified_type *);
+
+GLboolean
+slang_fully_specified_types_compatible(const slang_fully_specified_type * x,
+                                       const slang_fully_specified_type * y);
+
+
+typedef struct slang_typeinfo_
+{
+   GLboolean can_be_referenced;
+   GLboolean is_swizzled;
+   slang_swizzle swz;
+   slang_type_specifier spec;
+   GLuint array_len;
+} slang_typeinfo;
+
+extern GLboolean
+slang_typeinfo_construct(slang_typeinfo *);
+
+extern GLvoid
+slang_typeinfo_destruct(slang_typeinfo *);
+
+
+extern GLboolean
+_slang_typeof_operation(struct slang_operation_ *,
+                         const struct slang_name_space_ *,
+                         slang_typeinfo *, slang_atom_pool *,
+                         slang_info_log *log);
+
+extern GLboolean
+_slang_type_is_matrix(slang_type_specifier_type);
+
+extern GLboolean
+_slang_type_is_vector(slang_type_specifier_type);
+
+extern GLboolean
+_slang_type_is_float_vec_mat(slang_type_specifier_type);
+
+extern slang_type_specifier_type
+_slang_type_base(slang_type_specifier_type);
+
+extern GLuint
+_slang_type_dim(slang_type_specifier_type);
+
+extern GLenum
+_slang_gltype_from_specifier(const slang_type_specifier *type);
+
+#endif
diff --git a/src/mesa/slang/slang_utility.c b/src/mesa/slang/slang_utility.c
new file mode 100644 (file)
index 0000000..c1d5740
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.3
+ *
+ * Copyright (C) 2005-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 slang_utility.c
+ * slang utilities
+ * \author Michal Krol
+ */
+
+#include "main/imports.h"
+#include "slang_utility.h"
+#include "slang_mem.h"
+
+char *
+slang_string_concat (char *dst, const char *src)
+{
+   return strcpy (dst + strlen (dst), src);
+}
+
+
+/* slang_string */
+
+GLvoid
+slang_string_init (slang_string *self)
+{
+   self->data = NULL;
+   self->capacity = 0;
+   self->length = 0;
+   self->fail = GL_FALSE;
+}
+
+GLvoid
+slang_string_free (slang_string *self)
+{
+   if (self->data != NULL)
+      free(self->data);
+}
+
+GLvoid
+slang_string_reset (slang_string *self)
+{
+   self->length = 0;
+   self->fail = GL_FALSE;
+}
+
+static GLboolean
+grow (slang_string *self, GLuint size)
+{
+   if (self->fail)
+      return GL_FALSE;
+   if (size > self->capacity) {
+      /* do not overflow 32-bit range */
+      assert (size < 0x80000000);
+
+      self->data = (char *) (_mesa_realloc (self->data, self->capacity, size * 2));
+      self->capacity = size * 2;
+      if (self->data == NULL) {
+         self->capacity = 0;
+         self->fail = GL_TRUE;
+         return GL_FALSE;
+      }
+   }
+   return GL_TRUE;
+}
+
+GLvoid
+slang_string_push (slang_string *self, const slang_string *str)
+{
+   if (str->fail) {
+      self->fail = GL_TRUE;
+      return;
+   }
+   if (grow (self, self->length + str->length)) {
+      memcpy (&self->data[self->length], str->data, str->length);
+      self->length += str->length;
+   }
+}
+
+GLvoid
+slang_string_pushc (slang_string *self, const char c)
+{
+   if (grow (self, self->length + 1)) {
+      self->data[self->length] = c;
+      self->length++;
+   }
+}
+
+GLvoid
+slang_string_pushs (slang_string *self, const char *cstr, GLuint len)
+{
+   if (grow (self, self->length + len)) {
+      memcpy (&self->data[self->length], cstr, len);
+      self->length += len;
+   }
+}
+
+GLvoid
+slang_string_pushi (slang_string *self, GLint i)
+{
+   char buffer[12];
+
+   _mesa_snprintf (buffer, sizeof(buffer), "%d", i);
+   slang_string_pushs (self, buffer, strlen (buffer));
+}
+
+const char *
+slang_string_cstr (slang_string *self)
+{
+   if (grow (self, self->length + 1))
+      self->data[self->length] = '\0';
+   return self->data;
+}
+
+/* slang_atom_pool */
+
+void
+slang_atom_pool_construct(slang_atom_pool * pool)
+{
+   GLuint i;
+
+   for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++)
+      pool->entries[i] = NULL;
+}
+
+void
+slang_atom_pool_destruct (slang_atom_pool * pool)
+{
+   GLuint i;
+
+   for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++) {
+      slang_atom_entry * entry;
+               
+      entry = pool->entries[i];
+      while (entry != NULL) {
+         slang_atom_entry *next = entry->next;
+         _slang_free(entry->id);
+         _slang_free(entry);
+         entry = next;
+      }
+   }
+}
+
+/*
+ * Search the atom pool for an atom with a given name.
+ * If atom is not found, create and add it to the pool.
+ * Returns ATOM_NULL if the atom was not found and the function failed
+ * to create a new atom.
+ */
+slang_atom
+slang_atom_pool_atom(slang_atom_pool * pool, const char * id)
+{
+   GLuint hash;
+   const char * p = id;
+   slang_atom_entry ** entry;
+
+   /* Hash a given string to a number in the range [0, ATOM_POOL_SIZE). */
+   hash = 0;
+   while (*p != '\0') {
+      GLuint g;
+
+      hash = (hash << 4) + (GLuint) (*p++);
+      g = hash & 0xf0000000;
+      if (g != 0)
+         hash ^= g >> 24;
+      hash &= ~g;
+   }
+   hash %= SLANG_ATOM_POOL_SIZE;
+
+   /* Now the hash points to a linked list of atoms with names that
+    * have the same hash value.  Search the linked list for a given
+    * name.
+    */
+   entry = &pool->entries[hash];
+   while (*entry != NULL) {
+      /* If the same, return the associated atom. */
+      if (slang_string_compare((**entry).id, id) == 0)
+         return (slang_atom) (**entry).id;
+      /* Grab the next atom in the linked list. */
+      entry = &(**entry).next;
+   }
+
+   /* Okay, we have not found an atom. Create a new entry for it.
+    * Note that the <entry> points to the last entry's <next> field.
+    */
+   *entry = (slang_atom_entry *) _slang_alloc(sizeof(slang_atom_entry));
+   if (*entry == NULL)
+      return SLANG_ATOM_NULL;
+
+   /* Initialize a new entry. Because we'll need the actual name of
+    * the atom, we use the pointer to this string as an actual atom's
+    * value.
+    */
+   (**entry).next = NULL;
+   (**entry).id = _slang_strdup(id);
+   if ((**entry).id == NULL)
+      return SLANG_ATOM_NULL;
+   return (slang_atom) (**entry).id;
+}
+
+/**
+ * Return the name of a given atom.
+ */
+const char *
+slang_atom_pool_id(slang_atom_pool * pool, slang_atom atom)
+{
+   return (const char *) (atom);
+}
diff --git a/src/mesa/slang/slang_utility.h b/src/mesa/slang/slang_utility.h
new file mode 100644 (file)
index 0000000..2c0d0bc
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.5.3
+ *
+ * Copyright (C) 2005-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.
+ */
+
+#ifndef SLANG_UTILITY_H
+#define SLANG_UTILITY_H
+
+
+/* Compile-time assertions.  If the expression is zero, try to declare an
+ * array of size [-1] to cause compilation error.
+ */
+#define static_assert(expr) do { int _array[(expr) ? 1 : -1]; (void) _array[0]; } while (0)
+
+
+#define slang_string_compare(str1, str2) strcmp (str1, str2)
+#define slang_string_copy(dst, src) strcpy (dst, src)
+#define slang_string_length(str) strlen (str)
+
+char *slang_string_concat (char *, const char *);
+
+/* slang_string */
+
+typedef struct
+{
+   char *data;
+   GLuint length;
+   GLuint capacity;
+   GLboolean fail;
+} slang_string;
+
+GLvoid
+slang_string_init (slang_string *);
+
+GLvoid
+slang_string_free (slang_string *);
+
+GLvoid
+slang_string_reset (slang_string *);
+
+GLvoid
+slang_string_push (slang_string *, const slang_string *);
+
+GLvoid
+slang_string_pushc (slang_string *, const char);
+
+GLvoid
+slang_string_pushs (slang_string *, const char *, GLuint);
+
+GLvoid
+slang_string_pushi (slang_string *, GLint);
+
+const char *
+slang_string_cstr (slang_string *);
+
+/* slang_atom */
+
+typedef GLvoid *slang_atom;
+
+#define SLANG_ATOM_NULL ((slang_atom) 0)
+
+typedef struct slang_atom_entry_
+{
+       char *id;
+       struct slang_atom_entry_ *next;
+} slang_atom_entry;
+
+#define SLANG_ATOM_POOL_SIZE 1023
+
+typedef struct slang_atom_pool_
+{
+       slang_atom_entry *entries[SLANG_ATOM_POOL_SIZE];
+} slang_atom_pool;
+
+GLvoid slang_atom_pool_construct (slang_atom_pool *);
+GLvoid slang_atom_pool_destruct (slang_atom_pool *);
+slang_atom slang_atom_pool_atom (slang_atom_pool *, const char *);
+const char *slang_atom_pool_id (slang_atom_pool *, slang_atom);
+
+
+#endif
diff --git a/src/mesa/slang/slang_vartable.c b/src/mesa/slang/slang_vartable.c
new file mode 100644 (file)
index 0000000..8371631
--- /dev/null
@@ -0,0 +1,362 @@
+
+#include "main/imports.h"
+#include "program/program.h"
+#include "program/prog_print.h"
+#include "slang_compile.h"
+#include "slang_compile_variable.h"
+#include "slang_emit.h"
+#include "slang_mem.h"
+#include "slang_vartable.h"
+#include "slang_ir.h"
+
+
+static int dbg = 0;
+
+
+typedef enum {
+   FREE,
+   VAR,
+   TEMP
+} TempState;
+
+
+/**
+ * Variable/register info for one variable scope.
+ */
+struct table
+{
+   int Level;
+   int NumVars;
+   slang_variable **Vars;  /* array [NumVars] */
+
+   TempState Temps[MAX_PROGRAM_TEMPS * 4];  /* per-component state */
+   int ValSize[MAX_PROGRAM_TEMPS * 4];     /**< For debug only */
+
+   struct table *Parent;  /** Parent scope table */
+};
+
+
+/**
+ * A variable table is a stack of tables, one per scope.
+ */
+struct slang_var_table_
+{
+   GLint CurLevel;
+   GLuint MaxRegisters;
+   struct table *Top;  /**< Table at top of stack */
+};
+
+
+
+slang_var_table *
+_slang_new_var_table(GLuint maxRegisters)
+{
+   slang_var_table *vt
+      = (slang_var_table *) _slang_alloc(sizeof(slang_var_table));
+   if (vt) {
+      vt->MaxRegisters = maxRegisters;
+   }
+   return vt;
+}
+
+
+void
+_slang_delete_var_table(slang_var_table *vt)
+{
+   if (vt->Top) {
+      _mesa_problem(NULL, "non-empty var table in _slang_delete_var_table()");
+      return;
+   }
+   _slang_free(vt);
+}
+
+
+
+/**
+ * Create new table on top of vartable stack.
+ * Used when we enter a {} block.
+ */
+void
+_slang_push_var_table(slang_var_table *vt)
+{
+   struct table *t = (struct table *) _slang_alloc(sizeof(struct table));
+   if (t) {
+      t->Level = vt->CurLevel++;
+      t->Parent = vt->Top;
+      if (t->Parent) {
+         /* copy the info indicating which temp regs are in use */
+         memcpy(t->Temps, t->Parent->Temps, sizeof(t->Temps));
+         memcpy(t->ValSize, t->Parent->ValSize, sizeof(t->ValSize));
+      }
+      vt->Top = t;
+      if (dbg) printf("Pushing level %d\n", t->Level);
+   }
+}
+
+
+/**
+ * Pop top entry from variable table.
+ * Used when we leave a {} block.
+ */
+void
+_slang_pop_var_table(slang_var_table *vt)
+{
+   struct table *t = vt->Top;
+   int i;
+
+   if (dbg) printf("Popping level %d\n", t->Level);
+
+   /* free the storage allocated for each variable */
+   for (i = 0; i < t->NumVars; i++) {
+      slang_ir_storage *store = t->Vars[i]->store;
+      GLint j;
+      GLuint comp;
+      if (dbg) printf("  Free var %s, size %d at %d.%s\n",
+                      (char*) t->Vars[i]->a_name, store->Size,
+                      store->Index,
+                      _mesa_swizzle_string(store->Swizzle, 0, 0));
+
+      if (store->File == PROGRAM_SAMPLER) {
+         /* samplers have no storage */
+         continue;
+      }
+
+      if (store->Size == 1)
+         comp = GET_SWZ(store->Swizzle, 0);
+      else
+         comp = 0;
+
+      /* store->Index may be -1 if we run out of registers */
+      if (store->Index >= 0) {
+         for (j = 0; j < store->Size; j++) {
+            assert(t->Temps[store->Index * 4 + j + comp] == VAR);
+            t->Temps[store->Index * 4 + j + comp] = FREE;
+         }
+      }
+      store->Index = -1;
+   }
+   if (t->Parent) {
+      /* just verify that any remaining allocations in this scope 
+       * were for temps
+       */
+      for (i = 0; i < (int) vt->MaxRegisters * 4; i++) {
+         if (t->Temps[i] != FREE && t->Parent->Temps[i] == FREE) {
+            if (dbg) printf("  Free reg %d\n", i/4);
+            assert(t->Temps[i] == TEMP);
+         }
+      }
+   }
+
+   if (t->Vars) {
+      _slang_free(t->Vars);
+      t->Vars = NULL;
+   }
+
+   vt->Top = t->Parent;
+   _slang_free(t);
+   vt->CurLevel--;
+}
+
+
+/**
+ * Add a new variable to the given var/symbol table.
+ */
+void
+_slang_add_variable(slang_var_table *vt, slang_variable *v)
+{
+   struct table *t;
+   assert(vt);
+   t = vt->Top;
+   assert(t);
+   if (dbg) printf("Adding var %s, store %p\n", (char *) v->a_name, (void *) v->store);
+   t->Vars = (slang_variable **)
+      _slang_realloc(t->Vars,
+                     t->NumVars * sizeof(slang_variable *),
+                     (t->NumVars + 1) * sizeof(slang_variable *));
+   t->Vars[t->NumVars] = v;
+   t->NumVars++;
+}
+
+
+/**
+ * Look for variable by name in given table.
+ * If not found, Parent table will be searched.
+ */
+slang_variable *
+_slang_find_variable(const slang_var_table *vt, slang_atom name)
+{
+   struct table *t = vt->Top;
+   while (1) {
+      int i;
+      for (i = 0; i < t->NumVars; i++) {
+         if (t->Vars[i]->a_name == name)
+            return t->Vars[i];
+      }
+      if (t->Parent)
+         t = t->Parent;
+      else
+         return NULL;
+   }
+}
+
+
+/**
+ * Allocation helper.
+ * \param size  var size in floats
+ * \return  position for var, measured in floats
+ */
+static GLint
+alloc_reg(slang_var_table *vt, GLint size, GLboolean isTemp)
+{
+   struct table *t = vt->Top;
+   /* if size == 1, allocate anywhere, else, pos must be multiple of 4 */
+   const GLuint step = (size == 1) ? 1 : 4;
+   GLuint i, j;
+   assert(size > 0); /* number of floats */
+
+   for (i = 0; i <= vt->MaxRegisters * 4 - size; i += step) {
+      GLuint found = 0;
+      for (j = 0; j < (GLuint) size; j++) {
+         assert(i + j < 4 * MAX_PROGRAM_TEMPS);
+         if (i + j < vt->MaxRegisters * 4 && t->Temps[i + j] == FREE) {
+            found++;
+         }
+         else {
+            break;
+         }
+      }
+      if (found == size) {
+         /* found block of size free regs */
+         if (size > 1)
+            assert(i % 4 == 0);
+         for (j = 0; j < (GLuint) size; j++) {
+            assert(i + j < 4 * MAX_PROGRAM_TEMPS);
+            t->Temps[i + j] = isTemp ? TEMP : VAR;
+         }
+         assert(i < MAX_PROGRAM_TEMPS * 4);
+         t->ValSize[i] = size;
+         return i;
+      }
+   }
+
+   /* if we get here, we ran out of registers */
+   return -1;
+}
+
+
+/**
+ * Allocate temp register(s) for storing a variable.
+ * \param size  size needed, in floats
+ * \param swizzle  returns swizzle mask for accessing var in register
+ * \return  register allocated, or -1
+ */
+GLboolean
+_slang_alloc_var(slang_var_table *vt, slang_ir_storage *store)
+{
+   struct table *t = vt->Top;
+   int i;
+
+   if (store->File == PROGRAM_SAMPLER) {
+      /* don't really allocate storage */
+      store->Index = 0;
+      return GL_TRUE;
+   }
+
+   i = alloc_reg(vt, store->Size, GL_FALSE);
+   if (i < 0)
+      return GL_FALSE;
+
+   store->Index = i / 4;
+   store->Swizzle = _slang_var_swizzle(store->Size, i % 4);
+
+   if (dbg)
+      printf("Alloc var storage sz %d at %d.%s (level %d) store %p\n",
+             store->Size, store->Index,
+             _mesa_swizzle_string(store->Swizzle, 0, 0),
+             t->Level,
+             (void*) store);
+
+   return GL_TRUE;
+}
+
+
+
+/**
+ * Allocate temp register(s) for storing an unnamed intermediate value.
+ */
+GLboolean
+_slang_alloc_temp(slang_var_table *vt, slang_ir_storage *store)
+{
+   struct table *t = vt->Top;
+   const int i = alloc_reg(vt, store->Size, GL_TRUE);
+   if (i < 0)
+      return GL_FALSE;
+
+   assert(store->Index < 0);
+
+   store->Index = i / 4;
+   store->Swizzle = _slang_var_swizzle(store->Size, i % 4);
+
+   if (dbg) printf("Alloc temp sz %d at %d.%s (level %d) store %p\n",
+                   store->Size, store->Index,
+                   _mesa_swizzle_string(store->Swizzle, 0, 0), t->Level,
+                   (void *) store);
+
+   return GL_TRUE;
+}
+
+
+void
+_slang_free_temp(slang_var_table *vt, slang_ir_storage *store)
+{
+   struct table *t = vt->Top;
+   GLuint i;
+   GLint r = store->Index;
+   assert(store->Size > 0);
+   assert(r >= 0);
+   assert((GLuint)r + store->Size <= vt->MaxRegisters * 4);
+   if (dbg) printf("Free temp sz %d at %d.%s (level %d) store %p\n",
+                   store->Size, r,
+                   _mesa_swizzle_string(store->Swizzle, 0, 0),
+                   t->Level, (void *) store);
+   if (store->Size == 1) {
+      const GLuint comp = GET_SWZ(store->Swizzle, 0);
+      /* we can actually fail some of these assertions because of the
+       * troublesome IR_SWIZZLE handling.
+       */
+#if 0
+      assert(store->Swizzle == MAKE_SWIZZLE4(comp, comp, comp, comp));
+      assert(comp < 4);
+      assert(t->ValSize[r * 4 + comp] == 1);
+#endif
+      assert(t->Temps[r * 4 + comp] == TEMP);
+      t->Temps[r * 4 + comp] = FREE;
+   }
+   else {
+      /*assert(store->Swizzle == SWIZZLE_NOOP);*/
+      assert(t->ValSize[r*4] == store->Size);
+      for (i = 0; i < (GLuint) store->Size; i++) {
+         assert(t->Temps[r * 4 + i] == TEMP);
+         t->Temps[r * 4 + i] = FREE;
+      }
+   }
+}
+
+
+GLboolean
+_slang_is_temp(const slang_var_table *vt, const slang_ir_storage *store)
+{
+   struct table *t = vt->Top;
+   GLuint comp;
+   assert(store->Index >= 0);
+   assert(store->Index < (int) vt->MaxRegisters);
+   if (store->Swizzle == SWIZZLE_NOOP)
+      comp = 0;
+   else
+      comp = GET_SWZ(store->Swizzle, 0);
+
+   if (t->Temps[store->Index * 4 + comp] == TEMP)
+      return GL_TRUE;
+   else
+      return GL_FALSE;
+}
diff --git a/src/mesa/slang/slang_vartable.h b/src/mesa/slang/slang_vartable.h
new file mode 100644 (file)
index 0000000..94bcd63
--- /dev/null
@@ -0,0 +1,42 @@
+
+#ifndef SLANG_VARTABLE_H
+#define SLANG_VARTABLE_H
+
+struct slang_ir_storage_;
+
+typedef struct slang_var_table_ slang_var_table;
+
+struct slang_variable_;
+
+extern slang_var_table *
+_slang_new_var_table(GLuint maxRegisters);
+
+extern void
+_slang_delete_var_table(slang_var_table *vt);
+
+extern void
+_slang_push_var_table(slang_var_table *parent);
+
+extern void
+_slang_pop_var_table(slang_var_table *t);
+
+extern void
+_slang_add_variable(slang_var_table *t, struct slang_variable_ *v);
+
+extern struct slang_variable_ *
+_slang_find_variable(const slang_var_table *t, slang_atom name);
+
+extern GLboolean
+_slang_alloc_var(slang_var_table *t, struct slang_ir_storage_ *store);
+
+extern GLboolean
+_slang_alloc_temp(slang_var_table *t, struct slang_ir_storage_ *store);
+
+extern void
+_slang_free_temp(slang_var_table *t, struct slang_ir_storage_ *store);
+
+extern GLboolean
+_slang_is_temp(const slang_var_table *t, const struct slang_ir_storage_ *store);
+
+
+#endif /* SLANG_VARTABLE_H */
index 117b3f3d2b9e6fd58800b12722a74278a0e2955a..373f1b50d0592b54e725c32920e94b1fb46bfff1 100644 (file)
@@ -12,6 +12,8 @@ MAIN_SOURCES = \
        main/api_noop.c \
        main/api_validate.c \
        main/accum.c \
+       main/arbprogram.c \
+       main/atifragshader.c \
        main/attrib.c \
        main/arrayobj.c \
        main/blend.c \
@@ -55,6 +57,7 @@ MAIN_SOURCES = \
        main/mipmap.c \
        main/mm.c \
        main/multisample.c \
+       main/nvprogram.c \
        main/pixel.c \
        main/pixelstore.c \
        main/points.c \
@@ -66,7 +69,8 @@ MAIN_SOURCES = \
        main/remap.c \
        main/renderbuffer.c \
        main/scissor.c \
-       main/shaders.c \
+       main/shaderapi.c \
+       main/shaderobj.c \
        main/shared.c \
        main/state.c \
        main/stencil.c \
@@ -88,6 +92,7 @@ MAIN_SOURCES = \
        main/texstate.c \
        main/texstore.c \
        main/transformfeedback.c \
+       main/uniforms.c \
        main/varray.c \
        main/version.c \
        main/viewport.c \
@@ -223,56 +228,51 @@ STATETRACKER_SOURCES = \
        state_tracker/st_program.c \
        state_tracker/st_texture.c
 
-SHADER_SOURCES = \
-       shader/arbprogparse.c \
-       shader/arbprogram.c \
-       shader/atifragshader.c \
-       shader/hash_table.c \
-       shader/lex.yy.c \
-       shader/nvfragparse.c \
-       shader/nvprogram.c \
-       shader/nvvertparse.c \
-       shader/program.c \
-       shader/program_parse.tab.c \
-       shader/program_parse_extra.c \
-       shader/prog_cache.c \
-       shader/prog_execute.c \
-       shader/prog_instruction.c \
-       shader/prog_noise.c \
-       shader/prog_optimize.c \
-       shader/prog_parameter.c \
-       shader/prog_parameter_layout.c \
-       shader/prog_print.c \
-       shader/prog_statevars.c \
-       shader/prog_uniform.c \
-       shader/programopt.c \
-       shader/symbol_table.c \
-       shader/shader_api.c \
-       shader/uniforms.c
+PROGRAM_SOURCES = \
+       program/arbprogparse.c \
+       program/hash_table.c \
+       program/lex.yy.c \
+       program/nvfragparse.c \
+       program/nvvertparse.c \
+       program/program.c \
+       program/program_parse.tab.c \
+       program/program_parse_extra.c \
+       program/prog_cache.c \
+       program/prog_execute.c \
+       program/prog_instruction.c \
+       program/prog_noise.c \
+       program/prog_optimize.c \
+       program/prog_parameter.c \
+       program/prog_parameter_layout.c \
+       program/prog_print.c \
+       program/prog_statevars.c \
+       program/prog_uniform.c \
+       program/programopt.c \
+       program/symbol_table.c
 
 SHADER_CXX_SOURCES = \
-       shader/ir_to_mesa.cpp
+       program/ir_to_mesa.cpp
 
 SLANG_SOURCES =        \
-       shader/slang/slang_builtin.c    \
-       shader/slang/slang_codegen.c    \
-       shader/slang/slang_compile.c    \
-       shader/slang/slang_compile_function.c   \
-       shader/slang/slang_compile_operation.c  \
-       shader/slang/slang_compile_struct.c     \
-       shader/slang/slang_compile_variable.c   \
-       shader/slang/slang_emit.c       \
-       shader/slang/slang_ir.c \
-       shader/slang/slang_label.c      \
-       shader/slang/slang_link.c       \
-       shader/slang/slang_log.c        \
-       shader/slang/slang_mem.c        \
-       shader/slang/slang_print.c      \
-       shader/slang/slang_simplify.c   \
-       shader/slang/slang_storage.c    \
-       shader/slang/slang_typeinfo.c   \
-       shader/slang/slang_vartable.c   \
-       shader/slang/slang_utility.c
+       slang/slang_builtin.c   \
+       slang/slang_codegen.c   \
+       slang/slang_compile.c   \
+       slang/slang_compile_function.c  \
+       slang/slang_compile_operation.c \
+       slang/slang_compile_struct.c    \
+       slang/slang_compile_variable.c  \
+       slang/slang_emit.c      \
+       slang/slang_ir.c        \
+       slang/slang_label.c     \
+       slang/slang_link.c      \
+       slang/slang_log.c       \
+       slang/slang_mem.c       \
+       slang/slang_print.c     \
+       slang/slang_simplify.c  \
+       slang/slang_storage.c   \
+       slang/slang_typeinfo.c  \
+       slang/slang_vartable.c  \
+       slang/slang_utility.c
 
 ASM_C_SOURCES =        \
        x86/common_x86.c \
@@ -323,7 +323,7 @@ MESA_SOURCES = \
        $(MATH_XFORM_SOURCES)   \
        $(VBO_SOURCES)          \
        $(TNL_SOURCES)          \
-       $(SHADER_SOURCES)       \
+       $(PROGRAM_SOURCES)      \
        $(SWRAST_SOURCES)       \
        $(SWRAST_SETUP_SOURCES) \
        $(COMMON_DRIVER_SOURCES)\
@@ -338,7 +338,7 @@ MESA_GALLIUM_SOURCES = \
        $(MATH_SOURCES)         \
        $(VBO_SOURCES)          \
        $(STATETRACKER_SOURCES) \
-       $(SHADER_SOURCES)       \
+       $(PROGRAM_SOURCES)      \
        ppc/common_ppc.c        \
        x86/common_x86.c
 
index 6f293128d3acb865269f98e4874ac2f469bc6132..e389e57346bd83dd6592fca0d72cdcefad73e27f 100644 (file)
@@ -47,6 +47,7 @@ static const struct st_tracked_state *atoms[] =
 
    &st_finalize_textures,
    &st_update_fp,
+   &st_update_gp,
    &st_update_vp,
 
    &st_update_rasterizer,
@@ -59,6 +60,7 @@ static const struct st_tracked_state *atoms[] =
    &st_update_framebuffer,
    &st_update_msaa,
    &st_update_vs_constants,
+   &st_update_gs_constants,
    &st_update_fs_constants,
    &st_update_pixel_transfer
 };
@@ -115,6 +117,8 @@ static void check_program_state( struct st_context *st )
    if (ctx->FragmentProgram._Current != &st->fp->Base)
       st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
 
+   if (ctx->GeometryProgram._Current != &st->gp->Base)
+      st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM;
 }
 
 
index 0c25269e0a42c7f9ab7a13525927a379f3a15b7d..1f0fef63df573562711cee7315e948d2d1bb29c1 100644 (file)
@@ -48,6 +48,7 @@ extern const struct st_tracked_state st_update_framebuffer;
 extern const struct st_tracked_state st_update_clip;
 extern const struct st_tracked_state st_update_depth_stencil_alpha;
 extern const struct st_tracked_state st_update_fp;
+extern const struct st_tracked_state st_update_gp;
 extern const struct st_tracked_state st_update_vp;
 extern const struct st_tracked_state st_update_rasterizer;
 extern const struct st_tracked_state st_update_polygon_stipple;
@@ -59,6 +60,7 @@ extern const struct st_tracked_state st_update_sampler;
 extern const struct st_tracked_state st_update_texture;
 extern const struct st_tracked_state st_finalize_textures;
 extern const struct st_tracked_state st_update_fs_constants;
+extern const struct st_tracked_state st_update_gs_constants;
 extern const struct st_tracked_state st_update_vs_constants;
 extern const struct st_tracked_state st_update_pixel_transfer;
 
index 80c0e921398396f62ecc5ae11af4d958900a667b..16f7aaae6f41bf0cd704d2c0fa8225d21a5a2b03 100644 (file)
@@ -55,6 +55,8 @@ static void update_clip( struct st_context *st )
         clip.nr++;
       }
    }
+
+   clip.depth_clamp = st->ctx->Transform.DepthClamp != GL_FALSE;
       
    if (memcmp(&clip, &st->state.clip, sizeof(clip)) != 0) {
       st->state.clip = clip;
index 28439103b23c0d39a8de4007a2301fce3cc81df1..6f9d71e845b2909ba6b36bc9e76e4414812da1ae 100644 (file)
@@ -32,8 +32,8 @@
  */
 
 #include "main/imports.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_print.h"
+#include "program/prog_parameter.h"
+#include "program/prog_print.h"
 
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
@@ -59,7 +59,8 @@ void st_upload_constants( struct st_context *st,
    struct pipe_resource **cbuf = &st->state.constants[shader_type];
 
    assert(shader_type == PIPE_SHADER_VERTEX ||
-          shader_type == PIPE_SHADER_FRAGMENT);
+          shader_type == PIPE_SHADER_FRAGMENT ||
+          shader_type == PIPE_SHADER_GEOMETRY);
 
    /* update constants */
    if (params && params->NumParameters) {
@@ -139,3 +140,24 @@ const struct st_tracked_state st_update_fs_constants = {
    update_fs_constants                                 /* update */
 };
 
+/* Geometry shader:
+ */
+static void update_gs_constants(struct st_context *st )
+{
+   struct st_geometry_program *gp = st->gp;
+   struct gl_program_parameter_list *params;
+
+   if (gp) {
+      params = gp->Base.Base.Parameters;
+      st_upload_constants( st, params, PIPE_SHADER_GEOMETRY );
+   }
+}
+
+const struct st_tracked_state st_update_gs_constants = {
+   "st_update_gs_constants",                           /* name */
+   {                                                   /* dirty */
+      (_NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS),          /* mesa */
+      ST_NEW_GEOMETRY_PROGRAM,                         /* st */
+   },
+   update_gs_constants                                 /* update */
+};
index b8644faaf8375ebeee0f707fcd1a1570ad7bf8ab..b88c74fa03af6ad7f0fed2324a0c776b50dc31ad 100644 (file)
 #include "main/imports.h"
 #include "main/image.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 "program/program.h"
+#include "program/prog_instruction.h"
+#include "program/prog_parameter.h"
+#include "program/prog_print.h"
 
 #include "st_context.h"
 #include "st_format.h"
index 92fe72d4df60ba947a2694cccf80b90d5c61e43e..f147d76808469dcf86affa59d20bd90b179ae2e8 100644 (file)
@@ -199,7 +199,8 @@ update_samplers(struct st_context *st)
          if (sampler->min_lod < texobj->BaseLevel)
             sampler->min_lod = texobj->BaseLevel;
 
-         sampler->max_lod = MIN2((GLfloat) texobj->MaxLevel, texobj->MaxLod);
+         sampler->max_lod = MIN2((GLfloat) texobj->MaxLevel,
+                                 (texobj->MaxLod + texobj->BaseLevel));
          if (sampler->max_lod < sampler->min_lod) {
             /* The GL spec doesn't seem to specify what to do in this case.
              * Swap the values.
index ad151edf3bdc2575dacf75b55573babc3795bd6c..cebaad5f000f35a513f1ff7bbf418a12488d6085 100644 (file)
@@ -37,7 +37,7 @@
 
 #include "main/imports.h"
 #include "main/mtypes.h"
-#include "shader/program.h"
+#include "program/program.h"
 
 #include "pipe/p_context.h"
 #include "pipe/p_shader_tokens.h"
@@ -66,7 +66,19 @@ translate_fp(struct st_context *st,
    }
 }
 
+/*
+ * Translate geometry program if needed.
+ */
+static void
+translate_gp(struct st_context *st,
+             struct st_geometry_program *stgp)
+{
+   if (!stgp->tgsi.tokens) {
+      assert(stgp->Base.Base.NumInstructions > 1);
 
+      st_translate_geometry_program(st, stgp);
+   }
+}
 
 /**
  * Find a translated vertex program that corresponds to stvp and
@@ -222,3 +234,33 @@ const struct st_tracked_state st_update_vp = {
    },
    update_vp                                   /* update */
 };
+
+static void
+update_gp( struct st_context *st )
+{
+
+   struct st_geometry_program *stgp;
+
+   if (!st->ctx->GeometryProgram._Current) {
+      cso_set_geometry_shader_handle(st->cso_context, NULL);
+      return;
+   }
+
+   stgp = st_geometry_program(st->ctx->GeometryProgram._Current);
+   assert(stgp->Base.Base.Target == MESA_GEOMETRY_PROGRAM);
+
+   translate_gp(st, stgp);
+
+   st_reference_geomprog(st, &st->gp, stgp);
+
+   cso_set_geometry_shader_handle(st->cso_context, stgp->driver_shader);
+}
+
+const struct st_tracked_state st_update_gp = {
+   "st_update_gp",                                     /* name */
+   {                                                   /* dirty */
+      0,                                               /* mesa */
+      ST_NEW_GEOMETRY_PROGRAM                           /* st */
+   },
+   update_gp                                   /* update */
+};
index 895681cb230cfa26e84d8ddd502401bb3b96526a..981129621c745d954c29262d99d4842ee6ceeda0 100644 (file)
@@ -33,7 +33,7 @@
  
 
 #include "main/macros.h"
-#include "shader/prog_instruction.h"
+#include "program/prog_instruction.h"
 
 #include "st_context.h"
 #include "st_atom.h"
 #include "st_format.h"
 #include "st_cb_texture.h"
 #include "pipe/p_context.h"
+#include "util/u_format.h"
 #include "util/u_inlines.h"
 #include "cso_cache/cso_context.h"
 
+/**
+ * Combine depth texture mode with "swizzle" so that depth mode swizzling
+ * takes place before texture swizzling, and return the resulting swizzle.
+ * If the format is not a depth format, return "swizzle" unchanged.
+ *
+ * \param format     PIPE_FORMAT_*.
+ * \param swizzle    Texture swizzle, a bitmask computed using MAKE_SWIZZLE4.
+ * \param depthmode  One of GL_LUMINANCE, GL_INTENSITY, GL_ALPHA.
+ */
+static GLuint apply_depthmode(enum pipe_format format,
+                              GLuint swizzle, GLenum depthmode)
+{
+   const struct util_format_description *desc =
+         util_format_description(format);
+   unsigned char swiz[4];
+   unsigned i;
+
+   if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS ||
+       desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_NONE) {
+      /* Not a depth format. */
+      return swizzle;
+   }
+
+   for (i = 0; i < 4; i++)
+      swiz[i] = GET_SWZ(swizzle, i);
+
+   switch (depthmode) {
+      case GL_LUMINANCE:
+         /* Rewrite reads from W to ONE, and reads from XYZ to XXX. */
+         for (i = 0; i < 4; i++)
+            if (swiz[i] == SWIZZLE_W)
+               swiz[i] = SWIZZLE_ONE;
+            else if (swiz[i] < SWIZZLE_W)
+               swiz[i] = SWIZZLE_X;
+         break;
+
+      case GL_INTENSITY:
+         /* Rewrite reads from XYZW to XXXX. */
+         for (i = 0; i < 4; i++)
+            if (swiz[i] <= SWIZZLE_W)
+               swiz[i] = SWIZZLE_X;
+         break;
+
+      case GL_ALPHA:
+         /* Rewrite reads from W to X, and reads from XYZ to 000. */
+         for (i = 0; i < 4; i++)
+            if (swiz[i] == SWIZZLE_W)
+               swiz[i] = SWIZZLE_X;
+            else if (swiz[i] < SWIZZLE_W)
+               swiz[i] = SWIZZLE_ZERO;
+         break;
+   }
+
+   return MAKE_SWIZZLE4(swiz[0], swiz[1], swiz[2], swiz[3]);
+}
+
+/**
+ * Return TRUE if the swizzling described by "swizzle" and
+ * "depthmode" (for depth textures only) is different from the swizzling
+ * set in the given sampler view.
+ *
+ * \param sv         A sampler view.
+ * \param swizzle    Texture swizzle, a bitmask computed using MAKE_SWIZZLE4.
+ * \param depthmode  One of GL_LUMINANCE, GL_INTENSITY, GL_ALPHA.
+ */
 static boolean check_sampler_swizzle(struct pipe_sampler_view *sv,
-                                  uint32_t _swizzle)
+                                     GLuint swizzle, GLenum depthmode)
 {
-   if ((sv->swizzle_r != GET_SWZ(_swizzle, 0)) ||
-       (sv->swizzle_g != GET_SWZ(_swizzle, 1)) ||
-       (sv->swizzle_b != GET_SWZ(_swizzle, 2)) ||
-       (sv->swizzle_a != GET_SWZ(_swizzle, 3)))
+   swizzle = apply_depthmode(sv->texture->format, swizzle, depthmode);
+
+   if ((sv->swizzle_r != GET_SWZ(swizzle, 0)) ||
+       (sv->swizzle_g != GET_SWZ(swizzle, 1)) ||
+       (sv->swizzle_b != GET_SWZ(swizzle, 2)) ||
+       (sv->swizzle_a != GET_SWZ(swizzle, 3)))
       return true;
    return false;
 }
@@ -62,16 +130,19 @@ st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe,
                                          
 {
    struct pipe_sampler_view templ;
+   GLuint swizzle = apply_depthmode(stObj->pt->format,
+                                    stObj->base._Swizzle,
+                                    stObj->base.DepthMode);
 
    u_sampler_view_default_template(&templ,
                                    stObj->pt,
                                    format);
 
-   if (stObj->base._Swizzle != SWIZZLE_NOOP) {
-      templ.swizzle_r = GET_SWZ(stObj->base._Swizzle, 0);
-      templ.swizzle_g = GET_SWZ(stObj->base._Swizzle, 1);
-      templ.swizzle_b = GET_SWZ(stObj->base._Swizzle, 2);
-      templ.swizzle_a = GET_SWZ(stObj->base._Swizzle, 3);
+   if (swizzle != SWIZZLE_NOOP) {
+      templ.swizzle_r = GET_SWZ(swizzle, 0);
+      templ.swizzle_g = GET_SWZ(swizzle, 1);
+      templ.swizzle_b = GET_SWZ(swizzle, 2);
+      templ.swizzle_a = GET_SWZ(swizzle, 3);
    }
 
    return pipe->create_sampler_view(pipe, stObj->pt, &templ);
@@ -150,7 +221,10 @@ update_textures(struct st_context *st)
 
         /* if sampler view has changed dereference it */
         if (stObj->sampler_view)
-           if (check_sampler_swizzle(stObj->sampler_view, stObj->base._Swizzle) || (st_view_format != stObj->sampler_view->format))
+            if (check_sampler_swizzle(stObj->sampler_view,
+                                      stObj->base._Swizzle,
+                                      stObj->base.DepthMode) ||
+                (st_view_format != stObj->sampler_view->format))
               pipe_sampler_view_reference(&stObj->sampler_view, NULL);
 
          sampler_view = st_get_texture_sampler_view_from_stobj(stObj, pipe, st_view_format);
index 5aca1105eeb7a26c05cf6b9791112d1d9d1e5540..ba600ccef6d5ddd62a574956496ae755edfc4730 100644 (file)
@@ -34,8 +34,8 @@
 #include "main/image.h"
 #include "main/bufferobj.h"
 #include "main/macros.h"
-#include "shader/program.h"
-#include "shader/prog_print.h"
+#include "program/program.h"
+#include "program/prog_print.h"
 
 #include "st_context.h"
 #include "st_atom.h"
@@ -49,7 +49,7 @@
 #include "util/u_inlines.h"
 #include "util/u_draw_quad.h"
 #include "util/u_simple_shaders.h"
-#include "shader/prog_instruction.h"
+#include "program/prog_instruction.h"
 #include "cso_cache/cso_context.h"
 
 
index b15792504af8b8c66389fef00fd6552382346937..ea2414c4a002b9997173f419369b547f92fb5195 100644 (file)
@@ -36,7 +36,7 @@
 #include "main/glheader.h"
 #include "main/formats.h"
 #include "main/macros.h"
-#include "shader/prog_instruction.h"
+#include "program/prog_instruction.h"
 #include "st_context.h"
 #include "st_atom.h"
 #include "st_cb_accum.h"
index f74d8cd42d046cb98e832efae13208171f4b5e00..69a3dd45e80a49558e869f2c7f2ae9035211e9e5 100644 (file)
@@ -36,8 +36,8 @@
 #include "main/macros.h"
 #include "main/texformat.h"
 #include "main/texstore.h"
-#include "shader/program.h"
-#include "shader/prog_print.h"
+#include "program/program.h"
+#include "program/prog_print.h"
 
 #include "st_debug.h"
 #include "st_context.h"
@@ -58,7 +58,7 @@
 #include "util/u_draw_quad.h"
 #include "util/u_format.h"
 #include "util/u_math.h"
-#include "shader/prog_instruction.h"
+#include "program/prog_instruction.h"
 #include "cso_cache/cso_context.h"
 
 
index 3d99d6c8a11dc41d2de0bc594524105a60caddad..b191a7f890253cb9c026fbed31ce65360596c645 100644 (file)
@@ -16,8 +16,8 @@
 #include "main/image.h"
 #include "main/bufferobj.h"
 #include "main/macros.h"
-#include "shader/program.h"
-#include "shader/prog_print.h"
+#include "program/program.h"
+#include "program/prog_print.h"
 
 #include "st_context.h"
 #include "st_atom.h"
index 46f27ced6c38537c868d68c2e916f7cd47381ba3..13119ce2037fb6510fca0debec4507589809c830 100644 (file)
@@ -458,25 +458,37 @@ st_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
 {
    struct st_context *st = st_context(ctx);
    struct pipe_screen *screen = st->pipe->screen;
-   const struct gl_renderbuffer *depthRb =
-      fb->Attachment[BUFFER_DEPTH].Renderbuffer;
-   const struct gl_renderbuffer *stencilRb =
-      fb->Attachment[BUFFER_STENCIL].Renderbuffer;
+   const struct gl_renderbuffer_attachment *depth =
+         &fb->Attachment[BUFFER_DEPTH];
+   const struct gl_renderbuffer_attachment *stencil =
+         &fb->Attachment[BUFFER_STENCIL];
    GLuint i;
 
-   if (stencilRb && depthRb && stencilRb != depthRb) {
+   if (depth->Type && stencil->Type && depth->Type != stencil->Type) {
+      fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
+      return;
+   }
+   if (depth->Type == GL_RENDERBUFFER_EXT &&
+       stencil->Type == GL_RENDERBUFFER_EXT &&
+       depth->Renderbuffer != stencil->Renderbuffer) {
+      fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
+      return;
+   }
+   if (depth->Type == GL_TEXTURE &&
+       stencil->Type == GL_TEXTURE &&
+       depth->Texture != stencil->Texture) {
       fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
       return;
    }
 
    if (!st_validate_attachment(screen,
-                              &fb->Attachment[BUFFER_DEPTH],
+                               depth,
                               PIPE_BIND_DEPTH_STENCIL)) {
       fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
       return;
    }
    if (!st_validate_attachment(screen,
-                              &fb->Attachment[BUFFER_STENCIL],
+                               stencil,
                               PIPE_BIND_DEPTH_STENCIL)) {
       fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
       return;
index 2361b2eddfeaedca69423a1a60946b8e902ebe87..6aa7e79af950c24c3674864a4f85ceb712b6088b 100644 (file)
 #include "main/glheader.h"
 #include "main/macros.h"
 #include "main/enums.h"
-#include "shader/prog_instruction.h"
-#include "shader/prog_parameter.h"
-#include "shader/program.h"
-#include "shader/shader_api.h"
+#include "main/shaderapi.h"
+#include "program/prog_instruction.h"
+#include "program/program.h"
 
 #include "cso_cache/cso_context.h"
 #include "draw/draw_context.h"
@@ -67,6 +66,9 @@ static void st_bind_program( GLcontext *ctx,
    case GL_FRAGMENT_PROGRAM_ARB:
       st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
       break;
+   case MESA_GEOMETRY_PROGRAM:
+      st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM;
+      break;
    }
 }
 
@@ -75,15 +77,13 @@ static void st_bind_program( GLcontext *ctx,
  * Called via ctx->Driver.UseProgram() to bind a linked GLSL program
  * (vertex shader + fragment shader).
  */
-static void st_use_program( GLcontext *ctx,
-                           GLuint program )
+static void st_use_program( GLcontext *ctx, struct gl_shader_program *shProg)
 {
    struct st_context *st = st_context(ctx);
 
    st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
    st->dirty.st |= ST_NEW_VERTEX_PROGRAM;
-
-   _mesa_use_program(ctx, program);
+   st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM;
 }
 
 
@@ -120,6 +120,17 @@ static struct gl_program *st_new_program( GLcontext *ctx,
                                          id );
    }
 
+   case MESA_GEOMETRY_PROGRAM: {
+      struct st_geometry_program *prog = ST_CALLOC_STRUCT(st_geometry_program);
+
+      prog->serialNo = SerialNo++;
+
+      return _mesa_init_geometry_program( ctx,
+                                          &prog->Base,
+                                          target,
+                                          id );
+   }
+
    default:
       assert(0);
       return NULL;
@@ -139,6 +150,21 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog)
          st_vp_release_varients( st, stvp );
       }
       break;
+   case MESA_GEOMETRY_PROGRAM:
+      {
+         struct st_geometry_program *stgp = (struct st_geometry_program *) prog;
+
+         if (stgp->driver_shader) {
+            cso_delete_geometry_shader(st->cso_context, stgp->driver_shader);
+            stgp->driver_shader = NULL;
+         }
+
+         if (stgp->tgsi.tokens) {
+            st_free_tokens((void *) stgp->tgsi.tokens);
+            stgp->tgsi.tokens = NULL;
+         }
+      }
+      break;
    case GL_FRAGMENT_PROGRAM_ARB:
       {
          struct st_fragment_program *stfp = (struct st_fragment_program *) prog;
@@ -201,6 +227,24 @@ static GLboolean st_program_string_notify( GLcontext *ctx,
       if (st->fp == stfp)
         st->dirty.st |= ST_NEW_FRAGMENT_PROGRAM;
    }
+   else if (target == MESA_GEOMETRY_PROGRAM) {
+      struct st_geometry_program *stgp = (struct st_geometry_program *) prog;
+
+      stgp->serialNo++;
+
+      if (stgp->driver_shader) {
+         cso_delete_geometry_shader(st->cso_context, stgp->driver_shader);
+         stgp->driver_shader = NULL;
+      }
+
+      if (stgp->tgsi.tokens) {
+         st_free_tokens((void *) stgp->tgsi.tokens);
+         stgp->tgsi.tokens = NULL;
+      }
+
+      if (st->gp == stgp)
+        st->dirty.st |= ST_NEW_GEOMETRY_PROGRAM;
+   }
    else if (target == GL_VERTEX_PROGRAM_ARB) {
       struct st_vertex_program *stvp = (struct st_vertex_program *) prog;
 
index 8f7ebeed9767234e0b3f364932cc1a3f4939b48c..4c3e3688dd89720e80373c0db6212c03f5dfc137 100644 (file)
@@ -112,7 +112,7 @@ st_NewTextureObject(GLcontext * ctx, GLuint name, GLenum target)
    return &obj->base;
 }
 
-/** called via ctx->Driver.DeleteTextureImage() */
+/** called via ctx->Driver.DeleteTextureObject() */
 static void 
 st_DeleteTextureObject(GLcontext *ctx,
                        struct gl_texture_object *texObj)
index 0bf030e98763d550ffdbd7fb1afd56b46fe48a4c..7eb5f32611d7f1363382caca793c1cf45bc3dfee 100644 (file)
@@ -27,8 +27,8 @@
 
 #include "main/imports.h"
 #include "main/context.h"
+#include "main/shaderobj.h"
 #include "vbo/vbo.h"
-#include "shader/shader_api.h"
 #include "glapi/glapi.h"
 #include "st_context.h"
 #include "st_debug.h"
@@ -153,7 +153,7 @@ st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe )
 }
 
 
-struct st_context *st_create_context(struct pipe_context *pipe,
+struct st_context *st_create_context(gl_api api, struct pipe_context *pipe,
                                      const __GLcontextModes *visual,
                                      struct st_context *share)
 {
@@ -164,16 +164,7 @@ struct st_context *st_create_context(struct pipe_context *pipe,
    memset(&funcs, 0, sizeof(funcs));
    st_init_driver_functions(&funcs);
 
-#if FEATURE_GL
-   ctx = _mesa_create_context_for_api(API_OPENGL,
-                                     visual, shareCtx, &funcs, NULL);
-#elif FEATURE_ES1
-   ctx = _mesa_create_context_for_api(API_OPENGLES,
-                                     visual, shareCtx, &funcs, NULL);
-#elif FEATURE_ES2
-   ctx = _mesa_create_context_for_api(API_OPENGLES2,
-                                     visual, shareCtx, &funcs, NULL);
-#endif
+   ctx = _mesa_create_context_for_api(api, visual, shareCtx, &funcs, NULL);
 
    /* XXX: need a capability bit in gallium to query if the pipe
     * driver prefers DP4 or MUL/MAD for vertex transformation.
@@ -254,7 +245,7 @@ void st_destroy_context( struct st_context *st )
 
 void st_init_driver_functions(struct dd_function_table *functions)
 {
-   _mesa_init_glsl_driver_functions(functions);
+   _mesa_init_shader_object_functions(functions);
 
    st_init_accum_functions(functions);
    st_init_blit_functions(functions);
index efff55a9057346fa8f5b02de5c0df1d79f7bca38..a147a021176e1c688af9964ab4b26ecfb8c686d4 100644 (file)
@@ -29,7 +29,7 @@
 #define ST_CONTEXT_H
 
 #include "main/mtypes.h"
-#include "shader/prog_cache.h"
+#include "program/prog_cache.h"
 #include "pipe/p_state.h"
 #include "state_tracker/st_api.h"
 
@@ -51,6 +51,7 @@ struct bitmap_cache;
 #define ST_NEW_VERTEX_PROGRAM          0x4
 #define ST_NEW_FRAMEBUFFER             0x8
 #define ST_NEW_EDGEFLAGS_DATA          0x10
+#define ST_NEW_GEOMETRY_PROGRAM        0x20
 
 
 struct st_state_flags {
@@ -95,7 +96,7 @@ struct st_context
       struct pipe_sampler_state             samplers[PIPE_MAX_SAMPLERS];
       struct pipe_sampler_state             *sampler_list[PIPE_MAX_SAMPLERS];
       struct pipe_clip_state clip;
-      struct pipe_resource *constants[2];
+      struct pipe_resource *constants[PIPE_SHADER_TYPES];
       struct pipe_framebuffer_state framebuffer;
       struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
       struct pipe_scissor_state scissor;
@@ -130,6 +131,7 @@ struct st_context
 
    struct st_vertex_program *vp;    /**< Currently bound vertex program */
    struct st_fragment_program *fp;  /**< Currently bound fragment program */
+   struct st_geometry_program *gp;  /**< Currently bound geometry program */
 
    struct st_vp_varient *vp_varient;
 
@@ -259,7 +261,8 @@ extern int
 st_get_msaa(void);
 
 extern struct st_context *
-st_create_context(struct pipe_context *pipe, const __GLcontextModes *visual,
+st_create_context(gl_api api, struct pipe_context *pipe,
+                  const __GLcontextModes *visual,
                   struct st_context *share);
 
 extern void
index 0b3768341efa04d0612bd7fad708867b9c9d488a..ebf6ec6e7e20083304609fad90f8ceccb3512f1b 100644 (file)
@@ -27,7 +27,7 @@
 
 
 #include "main/context.h"
-#include "shader/prog_print.h"
+#include "program/prog_print.h"
 
 #include "pipe/p_state.h"
 #include "pipe/p_shader_tokens.h"
index eb2e5b2bbf77334112082961517bf658edcd14b0..5821da4889d3c9f9a8e21a3994a629aa94223a8c 100644 (file)
@@ -43,7 +43,7 @@
 #include "main/imports.h"
 #include "main/image.h"
 #include "main/macros.h"
-#include "shader/prog_uniform.h"
+#include "program/prog_uniform.h"
 
 #include "vbo/vbo.h"
 
@@ -57,6 +57,7 @@
 #include "pipe/p_defines.h"
 #include "util/u_inlines.h"
 #include "util/u_format.h"
+#include "util/u_prim.h"
 #include "draw/draw_context.h"
 #include "cso_cache/cso_context.h"
 
@@ -517,10 +518,21 @@ check_uniforms(GLcontext *ctx)
 }
 
 
-static unsigned translate_prim( GLcontext *ctx,
-                                unsigned prim )
+/**
+ * Translate OpenGL primtive type (GL_POINTS, GL_TRIANGLE_STRIP, etc) to
+ * the corresponding Gallium type.
+ */
+static unsigned
+translate_prim(const GLcontext *ctx, unsigned prim)
 {
+   /* GL prims should match Gallium prims, spot-check a few */
+   assert(GL_POINTS == PIPE_PRIM_POINTS);
+   assert(GL_QUADS == PIPE_PRIM_QUADS);
+   assert(GL_TRIANGLE_STRIP_ADJACENCY == PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY);
+
    /* Avoid quadstrips if it's easy to do so:
+    * Note: it's imporant to do the correct trimming if we change the prim type!
+    * We do that wherever this function is called.
     */
    if (prim == GL_QUAD_STRIP &&
        ctx->Light.ShadeModel != GL_FLAT &&
@@ -531,6 +543,8 @@ static unsigned translate_prim( GLcontext *ctx,
    return prim;
 }
 
+
+
 /**
  * This function gets plugged into the VBO module and is called when
  * we have something to render.
@@ -639,7 +653,6 @@ st_draw_vbo(GLcontext *ctx,
       struct gl_buffer_object *bufobj = ib->obj;
       struct pipe_resource *indexBuf = NULL;
       unsigned indexSize, indexOffset, i;
-      unsigned prim;
 
       switch (ib->type) {
       case GL_UNSIGNED_INT:
@@ -678,27 +691,41 @@ st_draw_vbo(GLcontext *ctx,
           * need a bit of work...
           */
          for (i = 0; i < nr_prims; i++) {
-            prim = translate_prim( ctx, prims[i].mode );
-
-            pipe->draw_range_elements(pipe, indexBuf, indexSize, 0,
-                                      min_index, max_index, prim,
-                                      prims[i].start + indexOffset, prims[i].count);
+            unsigned vcount = prims[i].count;
+            unsigned prim = translate_prim(ctx, prims[i].mode);
+
+            if (u_trim_pipe_prim(prims[i].mode, &vcount)) {
+               pipe->draw_range_elements(pipe, indexBuf, indexSize,
+                                         prims[i].basevertex,
+                                         min_index, max_index, prim,
+                                         prims[i].start + indexOffset, vcount);
+            }
          }
       }
       else {
          for (i = 0; i < nr_prims; i++) {
-            prim = translate_prim( ctx, prims[i].mode );
+            unsigned vcount = prims[i].count;
+            unsigned prim = translate_prim(ctx, prims[i].mode);
             
-            if (prims[i].num_instances == 1) {
-               pipe->draw_elements(pipe, indexBuf, indexSize, 0, prim,
-                                   prims[i].start + indexOffset,
-                                   prims[i].count);
-            }
-            else {
-               pipe->draw_elements_instanced(pipe, indexBuf, indexSize, 0, prim,
-                                             prims[i].start + indexOffset,
-                                             prims[i].count,
-                                             0, prims[i].num_instances);
+            if (u_trim_pipe_prim(prims[i].mode, &vcount)) {
+               if (prims[i].num_instances == 1) {
+                  pipe->draw_elements(pipe, indexBuf,
+                                      indexSize,
+                                      prims[i].basevertex,
+                                      prim,
+                                      prims[i].start + indexOffset,
+                                      vcount);
+               }
+               else {
+                  pipe->draw_elements_instanced(pipe, indexBuf,
+                                                indexSize,
+                                                prims[i].basevertex,
+                                                prim,
+                                                prims[i].start + indexOffset,
+                                                vcount,
+                                                0, /* startInstance */
+                                                prims[i].num_instances);
+               }
             }
          }
       }
@@ -708,18 +735,22 @@ st_draw_vbo(GLcontext *ctx,
    else {
       /* non-indexed */
       GLuint i;
-      GLuint prim;
 
       for (i = 0; i < nr_prims; i++) {
-         prim = translate_prim( ctx, prims[i].mode );
+         unsigned vcount = prims[i].count;
+         unsigned prim = translate_prim(ctx, prims[i].mode);
 
-         if (prims[i].num_instances == 1) {
-            pipe->draw_arrays(pipe, prim, prims[i].start, prims[i].count);
-         }
-         else {
-            pipe->draw_arrays_instanced(pipe, prim, prims[i].start,
-                                        prims[i].count,
-                                        0, prims[i].num_instances);
+         if (u_trim_pipe_prim(prims[i].mode, &vcount)) {
+            if (prims[i].num_instances == 1) {
+               pipe->draw_arrays(pipe, prim, prims[i].start, vcount);
+            }
+            else {
+               pipe->draw_arrays_instanced(pipe, prim,
+                                           prims[i].start,
+                                           vcount,
+                                           0, /* startInstance */
+                                           prims[i].num_instances);
+            }
          }
       }
    }
index d0ea89f4f4f23a6058005c84535c2111c59dafbe..90e78679e472c20101d6df14014cceab1f46db77 100644 (file)
@@ -180,6 +180,7 @@ void st_init_extensions(struct st_context *st)
     * Extensions that are supported by all Gallium drivers:
     */
    ctx->Extensions.ARB_copy_buffer = GL_TRUE;
+   ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE;
    ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE;
    ctx->Extensions.ARB_fragment_program = GL_TRUE;
    ctx->Extensions.ARB_map_buffer_range = GL_TRUE;
@@ -392,4 +393,12 @@ void st_init_extensions(struct st_context *st)
       ctx->Extensions.ARB_draw_buffers_blend = GL_TRUE;
    }
 #endif
+
+   if (screen->get_param(screen, PIPE_CAP_GEOMETRY_SHADER4)) {
+      ctx->Extensions.ARB_geometry_shader4 = GL_TRUE;
+   }
+
+   if (screen->get_param(screen, PIPE_CAP_DEPTH_CLAMP)) {
+      ctx->Extensions.ARB_depth_clamp = GL_TRUE;
+   }
 }
index 52c3fa0b417645c6dea362d9a983d350aea9e42c..fe1aec207ea2d6b7daa21d1e02d717f5344af28e 100644 (file)
@@ -4,6 +4,8 @@
 
 #include "state_tracker/st_api.h"
 
-struct st_api * st_gl_api_create(void);
+struct st_api *st_gl_api_create(void);
+struct st_api *st_gl_api_create_es1(void);
+struct st_api *st_gl_api_create_es2(void);
 
 #endif
index ccfb1f4a5204773d9741e555bf77ea90c116118e..2afc682e0b142167a2a505ba84f9826345a40e69 100644 (file)
 #include "st_context.h"
 #include "st_format.h"
 #include "st_cb_fbo.h"
+#include "st_cb_flush.h"
 #include "st_manager.h"
 
-/* these functions are defined in st_context.c */
-struct st_context *
-st_create_context(struct pipe_context *pipe,
-                  const __GLcontextModes *visual,
-                  struct st_context *share);
-void st_destroy_context(struct st_context *st);
-void st_flush(struct st_context *st, uint pipeFlushFlags,
-              struct pipe_fence_handle **fence);
-
 /**
  * Cast wrapper to convert a GLframebuffer to an st_framebuffer.
  * Return NULL if the GLframebuffer is a user-created framebuffer.
@@ -603,9 +595,9 @@ st_context_destroy(struct st_context_iface *stctxi)
 }
 
 static struct st_context_iface *
-st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
-                      const struct st_visual *visual,
-                      struct st_context_iface *shared_stctxi)
+create_context(gl_api api, struct st_manager *smapi,
+               const struct st_visual *visual,
+               struct st_context_iface *shared_stctxi)
 {
    struct st_context *shared_ctx = (struct st_context *) shared_stctxi;
    struct st_context *st;
@@ -617,7 +609,7 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
       return NULL;
 
    st_visual_to_context_mode(visual, &mode);
-   st = st_create_context(pipe, &mode, shared_ctx);
+   st = st_create_context(api, pipe, &mode, shared_ctx);
    if (!st) {
       pipe->destroy(pipe);
       return NULL;
@@ -637,6 +629,30 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
    return &st->iface;
 }
 
+static struct st_context_iface *
+st_api_create_context(struct st_api *stapi, struct st_manager *smapi,
+                      const struct st_visual *visual,
+                      struct st_context_iface *shared_stctxi)
+{
+   return create_context(API_OPENGL, smapi, visual, shared_stctxi);
+}
+
+static struct st_context_iface *
+st_api_create_context_es1(struct st_api *stapi, struct st_manager *smapi,
+                          const struct st_visual *visual,
+                          struct st_context_iface *shared_stctxi)
+{
+   return create_context(API_OPENGLES, smapi, visual, shared_stctxi);
+}
+
+static struct st_context_iface *
+st_api_create_context_es2(struct st_api *stapi, struct st_manager *smapi,
+                          const struct st_visual *visual,
+                          struct st_context_iface *shared_stctxi)
+{
+   return create_context(API_OPENGLES2, smapi, visual, shared_stctxi);
+}
+
 static boolean
 st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi,
                     struct st_framebuffer_iface *stdrawi,
@@ -707,13 +723,6 @@ st_api_get_current(struct st_api *stapi)
    return (st) ? &st->iface : NULL;
 }
 
-static boolean
-st_api_is_visual_supported(struct st_api *stapi,
-                           const struct st_visual *visual)
-{
-   return TRUE;
-}
-
 static st_proc_t
 st_api_get_proc_address(struct st_api *stapi, const char *procname)
 {
@@ -819,22 +828,60 @@ st_manager_add_color_renderbuffer(struct st_context *st, GLframebuffer *fb,
    return TRUE;
 }
 
-struct st_api st_gl_api = {
+static const struct st_api st_gl_api = {
    st_api_destroy,
    st_api_get_proc_address,
-   st_api_is_visual_supported,
    st_api_create_context,
    st_api_make_current,
    st_api_get_current,
 };
 
-/**
- * Return the st_api for this state tracker. This might either be GL, GLES1,
- * GLES2 that mostly depends on the build and link options. But these
- * functions remain the same either way.
- */
+static const struct st_api st_gl_api_es1 = {
+   st_api_destroy,
+   st_api_get_proc_address,
+   st_api_create_context_es1,
+   st_api_make_current,
+   st_api_get_current,
+};
+
+static const struct st_api st_gl_api_es2 = {
+   st_api_destroy,
+   st_api_get_proc_address,
+   st_api_create_context_es2,
+   st_api_make_current,
+   st_api_get_current,
+};
+
 struct st_api *
 st_gl_api_create(void)
 {
-   return &st_gl_api;
+   (void) st_gl_api;
+   (void) st_gl_api_es1;
+   (void) st_gl_api_es2;
+
+#if FEATURE_GL
+   return (struct st_api *) &st_gl_api;
+#else
+   return NULL;
+#endif
+}
+
+struct st_api *
+st_gl_api_create_es1(void)
+{
+#if FEATURE_ES1
+   return (struct st_api *) &st_gl_api_es1;
+#else
+   return NULL;
+#endif
+}
+
+struct st_api *
+st_gl_api_create_es2(void)
+{
+#if FEATURE_ES2
+   return (struct st_api *) &st_gl_api_es2;
+#else
+   return NULL;
+#endif
 }
index dabede4d64aaf3cbb2930e1d65154d166672cbd6..cd2887b1e0f4809c8db74f662057d44b66cdf213 100644 (file)
@@ -46,7 +46,4 @@ boolean
 st_manager_add_color_renderbuffer(struct st_context *st, GLframebuffer *fb,
                                   gl_buffer_index idx);
 
-struct st_api *
-st_manager_create_api(void);
-
 #endif /* ST_MANAGER_H */
index 35016d80e6b23d27b80baf6310b7907965e12de1..97186f8dadf155be1e847460501382026877ca43 100644 (file)
@@ -38,8 +38,8 @@
 #include "tgsi/tgsi_ureg.h"
 #include "st_mesa_to_tgsi.h"
 #include "st_context.h"
-#include "shader/prog_instruction.h"
-#include "shader/prog_parameter.h"
+#include "program/prog_instruction.h"
+#include "program/prog_parameter.h"
 #include "util/u_debug.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
@@ -176,7 +176,7 @@ dst_register( struct st_translate *t,
       else if (t->procType == TGSI_PROCESSOR_FRAGMENT)
          assert(index < FRAG_RESULT_MAX);
       else
-         assert(0 && "geom shaders not handled in dst_register() yet");
+         assert(index < GEOM_RESULT_MAX);
 
       assert(t->outputMapping[index] < Elements(t->outputs));
 
@@ -305,6 +305,15 @@ translate_src( struct st_translate *t,
 {
    struct ureg_src src = src_register( t, SrcReg->File, SrcReg->Index );
 
+   if (t->procType == TGSI_PROCESSOR_GEOMETRY && SrcReg->HasIndex2) {
+      src = src_register( t, SrcReg->File, SrcReg->Index2 );
+      if (SrcReg->RelAddr2)
+         src = ureg_src_dimension_indirect( src, ureg_src(t->address[0]),
+                                            SrcReg->Index);
+      else
+         src = ureg_src_dimension( src, SrcReg->Index);
+   }
+
    src = ureg_swizzle( src,
                        GET_SWZ( SrcReg->Swizzle, 0 ) & 0x3,
                        GET_SWZ( SrcReg->Swizzle, 1 ) & 0x3,
@@ -522,6 +531,10 @@ translate_opcode( unsigned op )
       return TGSI_OPCODE_DST;
    case OPCODE_ELSE:
       return TGSI_OPCODE_ELSE;
+   case OPCODE_EMIT_VERTEX:
+      return TGSI_OPCODE_EMIT;
+   case OPCODE_END_PRIMITIVE:
+      return TGSI_OPCODE_ENDPRIM;
    case OPCODE_ENDIF:
       return TGSI_OPCODE_ENDIF;
    case OPCODE_ENDLOOP:
@@ -725,9 +738,11 @@ emit_adjusted_wpos( struct st_translate *t,
    struct ureg_dst wpos_temp = ureg_DECL_temporary(ureg);
    struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]];
 
-   ureg_ADD(ureg,
-            ureg_writemask(wpos_temp, TGSI_WRITEMASK_X | TGSI_WRITEMASK_Y),
-            wpos_input, ureg_imm1f(ureg, value));
+   /* Note that we bias X and Y and pass Z and W through unchanged.
+    * The shader might also use gl_FragCoord.w and .z.
+    */
+   ureg_ADD(ureg, wpos_temp, wpos_input,
+            ureg_imm4f(ureg, value, value, 0.0f, 0.0f));
 
    t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp);
 }
@@ -918,6 +933,9 @@ st_translate_mesa_program(
    unsigned i;
    enum pipe_error ret = PIPE_OK;
 
+   assert(numInputs <= Elements(t->inputs));
+   assert(numOutputs <= Elements(t->outputs));
+
    t = &translate;
    memset(t, 0, sizeof *t);
 
@@ -985,7 +1003,23 @@ st_translate_mesa_program(
          }
       }
    }
+   else if (procType == TGSI_PROCESSOR_GEOMETRY) {
+      for (i = 0; i < numInputs; i++) {
+         t->inputs[i] = ureg_DECL_gs_input(ureg,
+                                           i,
+                                           inputSemanticName[i],
+                                           inputSemanticIndex[i]);
+      }
+
+      for (i = 0; i < numOutputs; i++) {
+         t->outputs[i] = ureg_DECL_output( ureg,
+                                           outputSemanticName[i],
+                                           outputSemanticIndex[i] );
+      }
+   }
    else {
+      assert(procType == TGSI_PROCESSOR_VERTEX);
+
       for (i = 0; i < numInputs; i++) {
          t->inputs[i] = ureg_DECL_vs_input(ureg, i);
       }
index 3c865028a7abc4c3e5ae3362d7feab38de2b48f8..6f3ecdbce110227a35c6549630e7fc810d5e14fb 100644 (file)
@@ -33,8 +33,8 @@
 
 #include "main/imports.h"
 #include "main/mtypes.h"
-#include "shader/prog_print.h"
-#include "shader/programopt.h"
+#include "program/prog_print.h"
+#include "program/programopt.h"
 
 #include "pipe/p_context.h"
 #include "pipe/p_defines.h"
@@ -459,6 +459,247 @@ st_translate_fragment_program(struct st_context *st,
    }
 }
 
+void
+st_translate_geometry_program(struct st_context *st,
+                              struct st_geometry_program *stgp)
+{
+   GLuint inputMapping[GEOM_ATTRIB_MAX];
+   GLuint outputMapping[GEOM_RESULT_MAX];
+   struct pipe_context *pipe = st->pipe;
+   enum pipe_error error;
+   GLuint attr;
+   const GLbitfield inputsRead = stgp->Base.Base.InputsRead;
+   GLuint vslot = 0;
+   GLuint num_generic = 0;
+
+   uint gs_num_inputs = 0;
+   uint gs_builtin_inputs = 0;
+   uint gs_array_offset = 0;
+
+   ubyte gs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS];
+   ubyte gs_output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
+   uint gs_num_outputs = 0;
+
+   GLint i;
+   GLuint maxSlot = 0;
+   struct ureg_program *ureg;
+
+   ureg = ureg_create( TGSI_PROCESSOR_GEOMETRY );
+   if (ureg == NULL) {
+      return;
+   }
+
+   /* which vertex output goes to the first geometry input */
+   vslot = 0;
+
+   memset(inputMapping, 0, sizeof(inputMapping));
+   memset(outputMapping, 0, sizeof(outputMapping));
+
+   /*
+    * Convert Mesa program inputs to TGSI input register semantics.
+    */
+   for (attr = 0; attr < GEOM_ATTRIB_MAX; attr++) {
+      if (inputsRead & (1 << attr)) {
+         const GLuint slot = gs_num_inputs;
+
+         gs_num_inputs++;
+
+         inputMapping[attr] = slot;
+
+         stgp->input_map[slot + gs_array_offset] = vslot - gs_builtin_inputs;
+         stgp->input_to_index[attr] = vslot;
+         stgp->index_to_input[vslot] = attr;
+         ++vslot;
+
+         if (attr != GEOM_ATTRIB_PRIMITIVE_ID) {
+            gs_array_offset += 2;
+         } else
+            ++gs_builtin_inputs;
+
+#if 1
+         debug_printf("input map at %d = %d\n",
+                      slot + gs_array_offset, stgp->input_map[slot + gs_array_offset]);
+#endif
+
+         switch (attr) {
+         case GEOM_ATTRIB_PRIMITIVE_ID:
+            stgp->input_semantic_name[slot] = TGSI_SEMANTIC_PRIMID;
+            stgp->input_semantic_index[slot] = 0;
+            break;
+         case GEOM_ATTRIB_POSITION:
+            stgp->input_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
+            stgp->input_semantic_index[slot] = 0;
+            break;
+         case GEOM_ATTRIB_COLOR0:
+            stgp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+            stgp->input_semantic_index[slot] = 0;
+            break;
+         case GEOM_ATTRIB_COLOR1:
+            stgp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+            stgp->input_semantic_index[slot] = 1;
+            break;
+         case GEOM_ATTRIB_FOG_FRAG_COORD:
+            stgp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
+            stgp->input_semantic_index[slot] = 0;
+            break;
+         case GEOM_ATTRIB_TEX_COORD:
+            stgp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+            stgp->input_semantic_index[slot] = num_generic++;
+            break;
+         case GEOM_ATTRIB_VAR0:
+            /* fall-through */
+         default:
+            stgp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+            stgp->input_semantic_index[slot] = num_generic++;
+         }
+      }
+   }
+
+   /* initialize output semantics to defaults */
+   for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
+      gs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC;
+      gs_output_semantic_index[i] = 0;
+   }
+
+   num_generic = 0;
+   /*
+    * Determine number of outputs, the (default) output register
+    * mapping and the semantic information for each output.
+    */
+   for (attr = 0; attr < GEOM_RESULT_MAX; attr++) {
+      if (stgp->Base.Base.OutputsWritten & (1 << attr)) {
+         GLuint slot;
+
+         slot = gs_num_outputs;
+         gs_num_outputs++;
+         outputMapping[attr] = slot;
+
+         switch (attr) {
+         case GEOM_RESULT_POS:
+            assert(slot == 0);
+            gs_output_semantic_name[slot] = TGSI_SEMANTIC_POSITION;
+            gs_output_semantic_index[slot] = 0;
+            break;
+         case GEOM_RESULT_COL0:
+            gs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+            gs_output_semantic_index[slot] = 0;
+            break;
+         case GEOM_RESULT_COL1:
+            gs_output_semantic_name[slot] = TGSI_SEMANTIC_COLOR;
+            gs_output_semantic_index[slot] = 1;
+            break;
+         case GEOM_RESULT_SCOL0:
+            gs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
+            gs_output_semantic_index[slot] = 0;
+            break;
+         case GEOM_RESULT_SCOL1:
+            gs_output_semantic_name[slot] = TGSI_SEMANTIC_BCOLOR;
+            gs_output_semantic_index[slot] = 1;
+            break;
+         case GEOM_RESULT_FOGC:
+            gs_output_semantic_name[slot] = TGSI_SEMANTIC_FOG;
+            gs_output_semantic_index[slot] = 0;
+            break;
+         case GEOM_RESULT_PSIZ:
+            gs_output_semantic_name[slot] = TGSI_SEMANTIC_PSIZE;
+            gs_output_semantic_index[slot] = 0;
+            break;
+         case GEOM_RESULT_TEX0:
+         case GEOM_RESULT_TEX1:
+         case GEOM_RESULT_TEX2:
+         case GEOM_RESULT_TEX3:
+         case GEOM_RESULT_TEX4:
+         case GEOM_RESULT_TEX5:
+         case GEOM_RESULT_TEX6:
+         case GEOM_RESULT_TEX7:
+            /* fall-through */
+         case GEOM_RESULT_VAR0:
+            /* fall-through */
+         default:
+            assert(slot < Elements(gs_output_semantic_name));
+            /* use default semantic info */
+            gs_output_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+            gs_output_semantic_index[slot] = num_generic++;
+         }
+      }
+   }
+
+   assert(gs_output_semantic_name[0] == TGSI_SEMANTIC_POSITION);
+
+   /* find max output slot referenced to compute gs_num_outputs */
+   for (attr = 0; attr < GEOM_RESULT_MAX; attr++) {
+      if (outputMapping[attr] != ~0 && outputMapping[attr] > maxSlot)
+         maxSlot = outputMapping[attr];
+   }
+   gs_num_outputs = maxSlot + 1;
+
+#if 0 /* debug */
+   {
+      GLuint i;
+      printf("outputMapping? %d\n", outputMapping ? 1 : 0);
+      if (outputMapping) {
+         printf("attr -> slot\n");
+         for (i = 0; i < 16;  i++) {
+            printf(" %2d       %3d\n", i, outputMapping[i]);
+         }
+      }
+      printf("slot    sem_name  sem_index\n");
+      for (i = 0; i < gs_num_outputs; i++) {
+         printf(" %2d         %d         %d\n",
+                i,
+                gs_output_semantic_name[i],
+                gs_output_semantic_index[i]);
+      }
+   }
+#endif
+
+   /* free old shader state, if any */
+   if (stgp->tgsi.tokens) {
+      st_free_tokens(stgp->tgsi.tokens);
+      stgp->tgsi.tokens = NULL;
+   }
+   if (stgp->driver_shader) {
+      cso_delete_geometry_shader(st->cso_context, stgp->driver_shader);
+      stgp->driver_shader = NULL;
+   }
+
+   ureg_property_gs_input_prim(ureg, stgp->Base.InputType);
+   ureg_property_gs_output_prim(ureg, stgp->Base.OutputType);
+   ureg_property_gs_max_vertices(ureg, stgp->Base.VerticesOut);
+
+   error  = st_translate_mesa_program(st->ctx,
+                                      TGSI_PROCESSOR_GEOMETRY,
+                                      ureg,
+                                      &stgp->Base.Base,
+                                      /* inputs */
+                                      gs_num_inputs,
+                                      inputMapping,
+                                      stgp->input_semantic_name,
+                                      stgp->input_semantic_index,
+                                      NULL,
+                                      /* outputs */
+                                      gs_num_outputs,
+                                      outputMapping,
+                                      gs_output_semantic_name,
+                                      gs_output_semantic_index,
+                                      FALSE);
+
+
+   stgp->num_inputs = gs_num_inputs;
+   stgp->tgsi.tokens = ureg_get_tokens( ureg, NULL );
+   ureg_destroy( ureg );
+   stgp->driver_shader = pipe->create_gs_state(pipe, &stgp->tgsi);
+
+   if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) {
+      _mesa_print_program(&stgp->Base.Base);
+      debug_printf("\n");
+   }
+
+   if (ST_DEBUG & DEBUG_TGSI) {
+      tgsi_dump(stgp->tgsi.tokens, 0);
+      debug_printf("\n");
+   }
+}
 
 /**
  * Debug- print current shader text
index 1b3f75ca27cebfae834e73e9c4e8dec6b56fb400..d779d5a6dde3a9ed2d9da81bf5d323312635ee3b 100644 (file)
 #define ST_PROGRAM_H
 
 #include "main/mtypes.h"
-#include "shader/program.h"
+#include "program/program.h"
 #include "pipe/p_shader_tokens.h"
 
 
 struct cso_fragment_shader;
 struct cso_vertex_shader;
-struct translated_vertex_program;
 
 
 /**
@@ -99,8 +98,6 @@ struct st_vp_varient
 };
 
 
-
-
 /**
  * Derived from Mesa gl_fragment_program:
  */
@@ -126,6 +123,33 @@ struct st_vertex_program
    struct st_vp_varient *varients;
 };
 
+/**
+ * Derived from Mesa gl_geometry_program:
+ */
+struct st_geometry_program
+{
+   struct gl_geometry_program Base;  /**< The Mesa geometry program */
+   GLuint serialNo;
+
+   /** map GP input back to VP output */
+   GLuint input_map[PIPE_MAX_SHADER_INPUTS];
+
+   /** maps a Mesa GEOM_ATTRIB_x to a packed TGSI input index */
+   GLuint input_to_index[GEOM_ATTRIB_MAX];
+   /** maps a TGSI input index back to a Mesa GEOM_ATTRIB_x */
+   GLuint index_to_input[PIPE_MAX_SHADER_INPUTS];
+
+   GLuint num_inputs;
+
+   GLuint input_to_slot[GEOM_ATTRIB_MAX];  /**< Maps GEOM_ATTRIB_x to slot */
+   GLuint num_input_slots;
+
+   ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS];
+   ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS];
+
+   struct pipe_shader_state tgsi;
+   void *driver_shader;
+};
 
 static INLINE struct st_fragment_program *
 st_fragment_program( struct gl_fragment_program *fp )
@@ -140,6 +164,11 @@ st_vertex_program( struct gl_vertex_program *vp )
    return (struct st_vertex_program *)vp;
 }
 
+static INLINE struct st_geometry_program *
+st_geometry_program( struct gl_geometry_program *vp )
+{
+   return (struct st_geometry_program *)vp;
+}
 
 static INLINE void
 st_reference_vertprog(struct st_context *st,
@@ -151,6 +180,16 @@ st_reference_vertprog(struct st_context *st,
                            (struct gl_program *) prog);
 }
 
+static INLINE void
+st_reference_geomprog(struct st_context *st,
+                      struct st_geometry_program **ptr,
+                      struct st_geometry_program *prog)
+{
+   _mesa_reference_program(st->ctx,
+                           (struct gl_program **) ptr,
+                           (struct gl_program *) prog);
+}
+
 static INLINE void
 st_reference_fragprog(struct st_context *st,
                       struct st_fragment_program **ptr,
@@ -166,6 +205,9 @@ extern void
 st_translate_fragment_program(struct st_context *st,
                               struct st_fragment_program *fp);
 
+extern void
+st_translate_geometry_program(struct st_context *st,
+                              struct st_geometry_program *stgp);
 
 /* Called after program string change, discard all previous
  * compilation results.
index 0f06cdf9f9d4c57fd33cddff493937e6b968659c..fa280e72e4064fa23048e2e1264d38699e5fedd3 100644 (file)
@@ -23,7 +23,7 @@
 #include "main/colormac.h"
 #include "main/context.h"
 #include "main/macros.h"
-#include "shader/atifragshader.h"
+#include "main/atifragshader.h"
 #include "swrast/s_atifragshader.h"
 
 
index 751966348b1f2802efb8259fb1ea8e3f1e1ce344..6d2d17c61d96ca492e5219575e9e63d6e7597b21 100644 (file)
@@ -32,8 +32,8 @@
 #include "main/colormac.h"
 #include "main/mtypes.h"
 #include "main/teximage.h"
-#include "shader/prog_parameter.h"
-#include "shader/prog_statevars.h"
+#include "program/prog_parameter.h"
+#include "program/prog_statevars.h"
 #include "swrast.h"
 #include "s_blend.h"
 #include "s_context.h"
index 9059f9b5ecbf27c1353f87392477ba3e04216896..c9755e6da183c0d7f56cfb1b6008f1c289f6525a 100644 (file)
@@ -44,7 +44,7 @@
 #define S_CONTEXT_H
 
 #include "main/mtypes.h"
-#include "shader/prog_execute.h"
+#include "program/prog_execute.h"
 #include "swrast.h"
 #include "s_span.h"
 
index 7c1de62e878b54eb40acf12317e2acb706925c06..413f136cd59b4ac70adafc21b69d409dcd1f4f37 100644 (file)
@@ -25,7 +25,7 @@
 #include "main/glheader.h"
 #include "main/colormac.h"
 #include "main/context.h"
-#include "shader/prog_instruction.h"
+#include "program/prog_instruction.h"
 
 #include "s_fragprog.h"
 #include "s_span.h"
index f322663ad41a226e9e0e409141fe3e996769c266..2ac0aaa246dae362a5b2557f5b41c0c501c305de 100644 (file)
@@ -29,7 +29,7 @@
 #include "main/colormac.h"
 #include "main/image.h"
 #include "main/imports.h"
-#include "shader/prog_instruction.h"
+#include "program/prog_instruction.h"
 
 #include "s_context.h"
 #include "s_texcombine.h"
index 812dddf15c6fedce53cc8982e3ff295af5b5bef8..d1b369bcdf0b9fa8c0fd9d62e0ab8c3e8bac5255 100644 (file)
@@ -35,7 +35,7 @@
 #include "main/imports.h"
 #include "main/macros.h"
 #include "main/texformat.h"
-#include "shader/prog_instruction.h"
+#include "program/prog_instruction.h"
 
 #include "s_aatriangle.h"
 #include "s_context.h"
index 0137e52fc40989206c77f71dba165cede756b9ce..614c67d05eb8aeba874234692e167b8eabe30d82 100644 (file)
@@ -36,9 +36,9 @@
 #include "main/context.h"
 #include "main/macros.h"
 #include "main/imports.h"
-#include "shader/prog_instruction.h"
-#include "shader/prog_statevars.h"
-#include "shader/prog_execute.h"
+#include "program/prog_instruction.h"
+#include "program/prog_statevars.h"
+#include "program/prog_execute.h"
 #include "swrast/s_context.h"
 
 #include "tnl/tnl.h"
index 365419d44fad7730567a42c29b3bc160cb844047..9df75a840657db6d23d30ddd6be0841613c50c10 100644 (file)
@@ -969,7 +969,10 @@ _vbo_Materialfv(GLenum face, GLenum pname, const GLfloat *params)
 void GLAPIENTRY
 _vbo_Materialf(GLenum face, GLenum pname, GLfloat param)
 {
-   vbo_Materialfv(face, pname, &param);
+   GLfloat p[4];
+   p[0] = param;
+   p[1] = p[2] = p[3] = 0.0F;
+   vbo_Materialfv(face, pname, p);
 }